From 50054732da991bdd966f4fba879c33ee853879ff Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 3 Jun 2025 14:04:36 +0700 Subject: create receipt after invoice paid and schema invoice --- fixco_custom/__manifest__.py | 1 + fixco_custom/models/detail_order.py | 8 +- fixco_custom/models/upload_payments.py | 120 +++++++++++++++++++----------- fixco_custom/security/ir.model.access.csv | 3 +- fixco_custom/views/ir_sequence.xml | 14 ++++ fixco_custom/views/upload_payments.xml | 28 ++++--- 6 files changed, 121 insertions(+), 53 deletions(-) create mode 100644 fixco_custom/views/ir_sequence.xml (limited to 'fixco_custom') 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 @@ + + + + + Upload Payments + upload.payments + TRUE + UP/%(year)s/ + 5 + 1 + 1 + + + \ 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 @@ upload.payments - - - - + + + - + upload.payments.form upload.payments -
+ +
+
- + + + + + - - + +
-- cgit v1.2.3