From abe7fb51235dc3d47e6352505065fcd15100b21b Mon Sep 17 00:00:00 2001 From: Paul Stroobant Date: Wed, 14 Feb 2024 16:57:59 +0100 Subject: [PATCH] [FIX] account: restrict bypass in early discount eligiblity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce issue: 1. Create Draft invoice with no Invoice Date 2. Set payment terms with multiple due dates (e.g.: "30% Now, Balance 60 Days) 3. Make sure "Show installment dates" is ticked in the payment terms form 4. Print invoice 5. Receive traceback with main message: > odoo.addons.base.models.ir_qweb.QWebException: Error while render the template > ValueError: The value send to monetary field is not a number. > Template: account.report_invoice_document > Path: /t/t/div[2]/div/div[3]/div[2]/t/div/div/t[1]/td/span[1] > Node: Explanation: `_is_eligible_for_early_payment_discount` will normally return `True` only if every condition is fulfilled. In previous fix odoo@9b20af823d3d2d8c3c70fd016d71448caa039958, we bypassed all of them if `reference_date` had no value. https://github.com/odoo/odoo/blob/4b744c82c3f902448a5c89c4711eccfeb1b548b8/addons/account/models/account_move.py#L1910-L1918 The method is called here, leading to the field that triggers the traceback. https://github.com/odoo/odoo/blob/8f3c0b218eb9ea725995d716e97999556ce74578/addons/account/views/report_invoice.xml#L230-L236 The reason it only blocks with multiple due dates is because of the first line: `payment_term_details` is true when there are multiple due dates or an early discount, the latter being the concern of the previous fix. The second one is true if "Show installment dates" is ticked. Suggested fix: `reference_date` should not take priority. Therefore, we will only override its own condition when it has no value. opw-3726968 closes odoo/odoo#154736 X-original-commit: 16cdd4226de5f731a80599df0599d6d7cbcd2186 Signed-off-by: de Wouters de Bouchout Jean-BenoƮt (jbw) Signed-off-by: Stroobant Paul (stpa) --- addons/account/models/account_move.py | 4 +--- .../tests/test_early_payment_discount.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 7794ae6f197..6193b818ebd 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -1968,12 +1968,10 @@ class AccountMove(models.Model): # ------------------------------------------------------------------------- def _is_eligible_for_early_payment_discount(self, currency, reference_date): self.ensure_one() - if not reference_date: - return True return self.currency_id == currency \ and self.move_type in ('out_invoice', 'out_receipt', 'in_invoice', 'in_receipt') \ and self.invoice_payment_term_id.early_discount \ - and reference_date <= self.invoice_payment_term_id._get_last_discount_date(self.invoice_date)\ + and (not reference_date or reference_date <= self.invoice_payment_term_id._get_last_discount_date(self.invoice_date)) \ and self.payment_state == 'not_paid' # ------------------------------------------------------------------------- diff --git a/addons/account/tests/test_early_payment_discount.py b/addons/account/tests/test_early_payment_discount.py index bc1dfa74c37..e3b838646ab 100644 --- a/addons/account/tests/test_early_payment_discount.py +++ b/addons/account/tests/test_early_payment_discount.py @@ -35,6 +35,22 @@ class TestAccountEarlyPaymentDiscount(AccountTestInvoicingCommon): ], }) + cls.pay_30_percents_now_balance_60_days = cls.env['account.payment.term'].create({ + 'name': '30% Now, Balance 60 Days', + 'line_ids': [ + Command.create({ + 'value_amount': 30, + 'value': 'percent', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 70, + 'value': 'percent', + 'nb_days': 60, + }) + ] + }) + def assert_tax_totals(self, document, expected_values): main_keys_to_ignore = { 'formatted_amount_total', 'formatted_amount_untaxed', 'display_tax_base', 'subtotals_order'} @@ -93,6 +109,11 @@ class TestAccountEarlyPaymentDiscount(AccountTestInvoicingCommon): report = self.env['ir.actions.report'].with_context(force_report_rendering=True)._render_qweb_pdf('account.account_invoices', res_ids=out_invoice.id) self.assertTrue(report) + #Test for invoices with multiple due dates and no early discount + out_invoice.invoice_payment_term_id = self.pay_30_percents_now_balance_60_days + new_report = self.env['ir.actions.report']._render_qweb_pdf('account.account_invoices', res_ids=out_invoice.id) + self.assertTrue(new_report) + # ========================== Tests Taxes Amounts ============================= def test_fixed_tax_amount_discounted_payment_mixed(self): fixed_tax = self.env['account.tax'].create({