From dd7c11b80ca3a564bc4c997f33c911c076689867 Mon Sep 17 00:00:00 2001 From: Daniel Reis Date: Thu, 28 Dec 2023 08:38:02 +0000 Subject: [PATCH] [FIX] sale_invoice_plan: invoiced amount could be different from the plan amount --- sale_invoice_plan/models/__init__.py | 1 + sale_invoice_plan/models/sale_invoice_plan.py | 17 +++++++++++------ sale_invoice_plan/models/sale_order_line.py | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 sale_invoice_plan/models/sale_order_line.py diff --git a/sale_invoice_plan/models/__init__.py b/sale_invoice_plan/models/__init__.py index 669fdb833cbb..7f7ce4106985 100644 --- a/sale_invoice_plan/models/__init__.py +++ b/sale_invoice_plan/models/__init__.py @@ -1,4 +1,5 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) from . import sale +from . import sale_order_line from . import sale_invoice_plan diff --git a/sale_invoice_plan/models/sale_invoice_plan.py b/sale_invoice_plan/models/sale_invoice_plan.py index b61496d30234..c2c9ccec2882 100644 --- a/sale_invoice_plan/models/sale_invoice_plan.py +++ b/sale_invoice_plan/models/sale_invoice_plan.py @@ -93,22 +93,27 @@ def _compute_no_edit(self): @api.depends("percent") def _compute_amount(self): + """Amount to be invoiced""" for rec in self: - amount_untaxed = rec.sale_id._origin.amount_untaxed + amount_untaxed = rec.sale_id.amount_untaxed # With invoice already created, no recompute if rec.invoiced: rec.amount = rec.amount_invoiced - rec.percent = rec.amount / amount_untaxed * 100 - continue # For last line, amount is the left over - if rec.last: + elif rec.last: installments = rec.sale_id.invoice_plan_ids.filtered( lambda l: l.invoice_type == "installment" ) prev_amount = sum((installments - rec).mapped("amount")) rec.amount = amount_untaxed - prev_amount - continue - rec.amount = rec.percent * amount_untaxed / 100 + else: + # Simulate the amount to be invoiced, as close as possible + # For this, round quantities on each order line + rec.amount = sum( + sol._get_installment_invoice_amount(rec.percent) + for sol in rec.sale_id.order_line + ) + rec.percent = rec.amount / amount_untaxed * 100 @api.onchange("amount", "percent") def _inverse_amount(self): diff --git a/sale_invoice_plan/models/sale_order_line.py b/sale_invoice_plan/models/sale_order_line.py new file mode 100644 index 000000000000..63905591176a --- /dev/null +++ b/sale_invoice_plan/models/sale_order_line.py @@ -0,0 +1,16 @@ +# Copyright 2023 Open Source Integrators +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from odoo import models +from odoo.tools.float_utils import float_round + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + def _get_installment_invoice_amount(self, percent): + """Simulate the invoice lime amount, after applying a percentage to it""" + prec = self.env["decimal.precision"].precision_get("Product Unit of Measure") + quantity = float_round(self.product_uom_qty * percent / 100, prec) + invoice_amount = self.currency_id.round(self.price_unit * quantity) + return invoice_amount