diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2025-06-03 14:04:36 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2025-06-03 14:04:36 +0700 |
| commit | 50054732da991bdd966f4fba879c33ee853879ff (patch) | |
| tree | 9a2ec4f03eecbb87cb97fe5e697a8ada3b9a7812 | |
| parent | bd521743ac81103979ab5835e99ffb3df3693998 (diff) | |
create receipt after invoice paid and schema invoice
| -rwxr-xr-x | fixco_api/models/invoice.py | 2 | ||||
| -rwxr-xr-x | fixco_custom/__manifest__.py | 1 | ||||
| -rwxr-xr-x | fixco_custom/models/detail_order.py | 8 | ||||
| -rw-r--r-- | fixco_custom/models/upload_payments.py | 120 | ||||
| -rwxr-xr-x | fixco_custom/security/ir.model.access.csv | 3 | ||||
| -rw-r--r-- | fixco_custom/views/ir_sequence.xml | 14 | ||||
| -rw-r--r-- | fixco_custom/views/upload_payments.xml | 28 |
7 files changed, 122 insertions, 54 deletions
diff --git a/fixco_api/models/invoice.py b/fixco_api/models/invoice.py index dc21fd3..33d74fa 100755 --- a/fixco_api/models/invoice.py +++ b/fixco_api/models/invoice.py @@ -17,7 +17,7 @@ class Invoice(models.Model): 'partner_id': invoice.partner_id.id, 'amount': invoice.amount_residual, 'date': invoice.invoice_date, - 'journal_id': invoice.partner_id.ginee_journal_id.id, + 'journal_id': invoice.partner_id.ginee_journal_id.id or 24, 'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id, 'ref': invoice.name, # 'communication': invoice.name, diff --git a/fixco_custom/__manifest__.py b/fixco_custom/__manifest__.py index bf30d01..62a199e 100755 --- a/fixco_custom/__manifest__.py +++ b/fixco_custom/__manifest__.py @@ -21,6 +21,7 @@ 'views/sale_order_multi_invoices.xml', 'views/account_move.xml', 'views/upload_payments.xml', + 'views/ir_sequence.xml', ], 'demo': [], 'css': [], diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py index 28e48ab..e3dc7d7 100755 --- a/fixco_custom/models/detail_order.py +++ b/fixco_custom/models/detail_order.py @@ -139,10 +139,16 @@ class DetailOrder(models.Model): self.env.cr.rollback() self.env.cr.commit() + + def get_partner(self, shop_id): + partner = self.env['res.partner'].search([('ginee_shop_id', '=', shop_id)], limit=1) + if not partner: + raise UserError(_("Partner not found for Shop ID: %s") % shop_id) + return partner.id def prepare_data_so(self, json_data): data = { - 'partner_id': 45, + 'partner_id': self.get_partner(json_data.get('data', {})[0].get('shopId')), 'client_order_ref': json_data.get('data', {})[0].get('orderId'), 'warehouse_id': 4, 'picking_policy': 'direct', diff --git a/fixco_custom/models/upload_payments.py b/fixco_custom/models/upload_payments.py index 0473997..e7599a7 100644 --- a/fixco_custom/models/upload_payments.py +++ b/fixco_custom/models/upload_payments.py @@ -1,58 +1,94 @@ -from odoo import models, fields, api +from odoo import models, fields, api, _ from odoo.exceptions import ValidationError +from datetime import datetime +import base64 +import xlrd class UploadPayments(models.Model): _name = "upload.payments" _description = "Upload Payments" + _order = "create_date desc" - no_invoice = fields.Char('Invoice Number', required=True) - date_invoice = fields.Date('Invoice Date', required=True) - move_id = fields.Many2one('account.move', string='Invoice') - payment_id = fields.Many2one('account.payment', string='Created Payment') + payments_lines = fields.One2many('upload.payments.line', 'upload_payments_id', string='Upload Payments Lines', auto_join=True, copy=False) + number = fields.Char('Number', copy=False) + date_upload = fields.Date('Upload Date', copy=False, default=fields.Date.context_today) + user_id = fields.Many2one('res.users', string='Created By', copy=False, default=lambda self: self.env.user.id) + excel_file = fields.Binary('Excel File', attachment=True) + filename = fields.Char('File Name') @api.model def create(self, vals): - record = super(UploadPayments, self).create(vals) - - record._create_payment_from_invoice() - - return record + vals['number'] = self.env['ir.sequence'].next_by_code('upload.payments') or '/' + return super(UploadPayments, self).create(vals) - def _create_payment_from_invoice(self): + def action_import_excel(self): self.ensure_one() - # Find the invoice based on the marketplace number - invoice = self.env['account.move'].search([ - ('invoice_marketplace', '=', self.no_invoice) - ], limit=1) + if not self.excel_file: + raise ValidationError(_("Please upload an Excel file first.")) - if not invoice: - raise ValidationError(f"No invoice found with marketplace number {self.no_invoice}") - - self.move_id = invoice.id - - # Create payment - payment_vals = { - 'payment_type': 'inbound' if invoice.move_type in ('out_invoice', 'out_refund') else 'outbound', - 'partner_id': invoice.partner_id.id, - 'amount': invoice.amount_residual, - 'date': self.date_invoice or fields.Date.today(), - 'ref': invoice.name, - 'journal_id': invoice.journal_id.id, - 'currency_id': invoice.currency_id.id, - } + try: + file_content = base64.b64decode(self.excel_file) + workbook = xlrd.open_workbook(file_contents=file_content) + sheet = workbook.sheet_by_index(0) + except: + raise ValidationError(_("Invalid Excel file format.")) - payment = self.env['account.payment'].create(payment_vals) - payment.action_post() + # Process Excel rows (skip header row if exists) + line_vals_list = [] + for row in range(1, sheet.nrows): + try: + no_invoice = str(sheet.cell(row, 0).value).strip() + date_invoice = xlrd.xldate.xldate_as_datetime(sheet.cell(row, 1).value, workbook.datemode).date() + + line_vals = { + 'no_invoice': no_invoice, + 'date_invoice': date_invoice, + } + line_vals_list.append((0, 0, line_vals)) + except: + continue - # Reconcile with invoice - lines_to_reconcile = invoice.line_ids.filtered( - lambda line: line.account_id.account_type in ('asset_receivable', 'liability_payable') - ) - payment_lines = payment.line_ids.filtered( - lambda line: line.account_id.account_type in ('asset_receivable', 'liability_payable') - ) + # Update current record with lines + self.write({ + 'payments_lines': line_vals_list, + }) - (lines_to_reconcile + payment_lines).reconcile() + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': _('Success'), + 'message': _('Imported %s lines from Excel.') % len(line_vals_list), + 'sticky': False, + 'next': {'type': 'ir.actions.act_window_close'}, + } + } + + def action_create_payments(self): + """Membuat payment untuk semua lines yang belum memiliki payment""" + self.ensure_one() + created_payments = [] - self.payment_id = payment.id - return payment
\ No newline at end of file + for line in self.payments_lines.filtered(lambda l: not l.payment_id): + # Cari invoice berdasarkan invoice_marketplace + invoice = self.env['account.move'].search([ + ('invoice_marketplace', '=', line.no_invoice), + ('state', '=', 'posted'), + ('payment_state', '!=', 'paid'), + ]) + + for move in invoice: + move._register_payment_automatically() + + + +class UploadPaymentsLine(models.Model): + _name = "upload.payments.line" + _description = "Upload Payments Line" + _inherit = ['mail.thread'] + + upload_payments_id = fields.Many2one('upload.payments', string='Upload Payments') + no_invoice = fields.Char('Invoice Number', required=True) + date_invoice = fields.Date('Invoice Date', required=True) + move_id = fields.Many2one('account.move', string='Invoice') + payment_id = fields.Many2one('account.payment', string='Created Payment')
\ No newline at end of file diff --git a/fixco_custom/security/ir.model.access.csv b/fixco_custom/security/ir.model.access.csv index 80759e6..3556565 100755 --- a/fixco_custom/security/ir.model.access.csv +++ b/fixco_custom/security/ir.model.access.csv @@ -7,4 +7,5 @@ access_barcoding_product,access.barcoding.product,model_barcoding_product,,1,1,1 access_barcoding_product_line,access.barcoding.product.line,model_barcoding_product_line,,1,1,1,1 access_sale_order_multi_invoices,access.sale.order.multi_invoices,model_sale_order_multi_invoices,,1,1,1,1 access_account_move,access.account.move,model_account_move,,1,1,1,1 -access_upload_payments,access.upload.payments,model_upload_payments,,1,1,1,1
\ No newline at end of file +access_upload_payments,access.upload.payments,model_upload_payments,,1,1,1,1 +access_upload_payments_line,access.upload.payments.line,model_upload_payments_line,,1,1,1,1
\ No newline at end of file diff --git a/fixco_custom/views/ir_sequence.xml b/fixco_custom/views/ir_sequence.xml new file mode 100644 index 0000000..b89b3de --- /dev/null +++ b/fixco_custom/views/ir_sequence.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<odoo> + <data noupdate="1"> + <record id="sequence_upload_payments" model="ir.sequence"> + <field name="name">Upload Payments</field> + <field name="code">upload.payments</field> + <field name="active">TRUE</field> + <field name="prefix">UP/%(year)s/</field> + <field name="padding">5</field> + <field name="number_next">1</field> + <field name="number_increment">1</field> + </record> + </data> +</odoo>
\ No newline at end of file diff --git a/fixco_custom/views/upload_payments.xml b/fixco_custom/views/upload_payments.xml index 0bfbccd..3c83cb5 100644 --- a/fixco_custom/views/upload_payments.xml +++ b/fixco_custom/views/upload_payments.xml @@ -6,28 +6,38 @@ <field name="model">upload.payments</field> <field name="arch" type="xml"> <tree default_order="create_date desc"> - <field name="no_invoice"/> - <field name="date_invoice"/> - <field name="move_id"/> - <field name="payment_id"/> + <field name="number"/> + <field name="date_upload"/> + <field name="user_id"/> </tree> </field> </record> - <record id="upload_payments_form" model="ir.ui.view"> + <record id="view_upload_payments_form" model="ir.ui.view"> <field name="name">upload.payments.form</field> <field name="model">upload.payments</field> <field name="arch" type="xml"> - <form > + <form string="Upload Payments"> + <header> + <button name="action_import_excel" string="Import Excel" type="object" class="oe_highlight"/> + <button name="action_create_payments" string="Create Payments" type="object" class="oe_highlight"/> + <field name="number" widget="field_no_edit" options="{'no_open': True}"/> + <field name="date_upload"/> + <field name="user_id" widget="field_no_edit" options="{'no_open': True}"/> + </header> <sheet> <group> - <group> + <field name="excel_file" filename="filename"/> + <field name="filename" invisible="1"/> + </group> + <field name="payments_lines"> + <tree editable="bottom"> <field name="no_invoice"/> <field name="date_invoice"/> <field name="move_id"/> <field name="payment_id"/> - </group> - </group> + </tree> + </field> </sheet> </form> </field> |
