diff --git a/addons/account/models/account_payment_term.py b/addons/account/models/account_payment_term.py index 218f3498540..8c23d76fb09 100644 --- a/addons/account/models/account_payment_term.py +++ b/addons/account/models/account_payment_term.py @@ -184,39 +184,35 @@ class AccountPaymentTerm(models.Model): pay_term['discount_balance'] = company_currency.round(total_amount * (1 - discount_percentage)) pay_term['discount_amount_currency'] = currency.round(total_amount_currency * (1 - discount_percentage)) - # Remove all fixed amounts. rate = abs(total_amount_currency / total_amount) if total_amount else 0.0 - for line in self.line_ids: - if line.value == 'fixed': - total_amount_currency -= line.value_amount - total_amount -= currency.round(line.value_amount / rate) if rate else 0.0 - residual_amount = total_amount residual_amount_currency = total_amount_currency - #We sort by the last line of a term - term_lines = self.line_ids.sorted(lambda l: l == self.line_ids[-1]) - last_percent_line = term_lines.filtered(lambda l: l.value == 'percent')[-1:] - for line in self.line_ids.sorted(lambda l: l == self.line_ids[-1]): + for i, line in enumerate(self.line_ids): term_vals = { 'date': line._get_due_date(date_ref), 'company_amount': 0, 'foreign_amount': 0, } - if line.value == 'fixed': - term_vals['company_amount'] = sign * company_currency.round(line.value_amount / rate) if rate else 0.0 - term_vals['foreign_amount'] = sign * currency.round(line.value_amount) - elif line == last_percent_line: + + if i == len(self.line_ids) - 1: + # The last line is always the balance, no matter the type term_vals['company_amount'] = residual_amount term_vals['foreign_amount'] = residual_amount_currency + elif line.value == 'fixed': + # Fixed amounts + term_vals['company_amount'] = sign * company_currency.round(line.value_amount / rate) if rate else 0.0 + term_vals['foreign_amount'] = sign * currency.round(line.value_amount) else: + # Percentage amounts line_amount = company_currency.round(total_amount * (line.value_amount / 100.0)) line_amount_currency = currency.round(total_amount_currency * (line.value_amount / 100.0)) term_vals['company_amount'] = line_amount term_vals['foreign_amount'] = line_amount_currency - residual_amount -= line_amount - residual_amount_currency -= line_amount_currency - pay_term["line_ids"].append(term_vals) + + residual_amount -= term_vals['company_amount'] + residual_amount_currency -= term_vals['foreign_amount'] + pay_term['line_ids'].append(term_vals) return pay_term diff --git a/addons/account/tests/test_payment_term.py b/addons/account/tests/test_payment_term.py index 158333e40fe..4589a3d0d47 100644 --- a/addons/account/tests/test_payment_term.py +++ b/addons/account/tests/test_payment_term.py @@ -240,7 +240,7 @@ class TestAccountPaymentTerms(AccountTestInvoicingCommon): ) for l in computed_term['line_ids'] ], - [(0.035, 0.02), (0.035, 0.01), (0.02, 0.01)], + [(0.045, 0.02), (0.045, 0.02), (0.0, 0.0)], ) def test_payment_term_residual_amount_on_last_line(self): @@ -268,3 +268,104 @@ class TestAccountPaymentTerms(AccountTestInvoicingCommon): [self.env.company.currency_id.round(l['foreign_amount']) for l in computed_term['line_ids']], [0.02, 0.01], ) + + def test_payment_term_last_balance_line_with_fixed(self): + pay_term = self.env['account.payment.term'].create({ + 'name': 'test_payment_term_last_balance_line_with_fixed', + 'line_ids': [ + Command.create({ + 'value_amount': 70, + 'value': 'percent', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 200, + 'value': 'fixed', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 30, + 'value': 'percent', + 'nb_days': 0, + }), + ] + }) + + computed_term = pay_term._compute_terms( + fields.Date.from_string('2016-01-01'), self.env.company.currency_id, self.env.company, + 0.0, 0.0, 1.0, 1000.0, 1000.0, + ) + + self.assertEqual( + [self.env.company.currency_id.round(l['foreign_amount']) for l in computed_term['line_ids']], + [700.0, 200.0, 100.0], + ) + + def test_payment_term_last_balance_line_with_fixed_negative(self): + pay_term = self.env['account.payment.term'].create({ + 'name': 'test_payment_term_last_balance_line_with_fixed_negative', + 'line_ids': [ + Command.create({ + 'value_amount': 70, + 'value': 'percent', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 500, + 'value': 'fixed', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 30, + 'value': 'percent', + 'nb_days': 0, + }), + ] + }) + + computed_term = pay_term._compute_terms( + fields.Date.from_string('2016-01-01'), self.env.company.currency_id, self.env.company, + 0.0, 0.0, 1.0, 1000.0, 1000.0, + ) + + self.assertEqual( + [self.env.company.currency_id.round(l['foreign_amount']) for l in computed_term['line_ids']], + [700.0, 500.0, -200.0], + ) + + def test_payment_term_last_balance_line_with_fixed_negative_fixed(self): + pay_term = self.env['account.payment.term'].create({ + 'name': 'test_payment_term_last_balance_line_with_fixed_negative_fixed', + 'line_ids': [ + Command.create({ + 'value_amount': 70, + 'value': 'percent', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 500, + 'value': 'fixed', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 30, + 'value': 'percent', + 'nb_days': 0, + }), + Command.create({ + 'value_amount': 200, + 'value': 'fixed', + 'nb_days': 0, + }), + ] + }) + + computed_term = pay_term._compute_terms( + fields.Date.from_string('2016-01-01'), self.env.company.currency_id, self.env.company, + 0.0, 0.0, 1.0, 1000.0, 1000.0, + ) + + self.assertEqual( + [self.env.company.currency_id.round(l['foreign_amount']) for l in computed_term['line_ids']], + [700.0, 500.0, 300.0, -500.0], + ) diff --git a/addons/account/views/account_payment_term_views.xml b/addons/account/views/account_payment_term_views.xml index 1658dbfaacd..d62c7eb331b 100644 --- a/addons/account/views/account_payment_term_views.xml +++ b/addons/account/views/account_payment_term_views.xml @@ -74,7 +74,9 @@
- Example: $ 1000 on + Example: + + on