from odoo.tests import tagged from odoo.addons.account.tests.common import TestTaxCommon @tagged('post_install', '-at_install') class TestTaxesBaseLinesTaxDetails(TestTaxCommon): @classmethod def setUpClass(cls): super().setUpClass() cls.env.company.tax_calculation_rounding_method = 'round_globally' def test_dispatch_delta_on_base_lines(self): """ Make sure that the base line delta is dispatched evenly on base lines. Needed for BIS3 rule PEPPOL-EN16931-R120. """ tax_21 = self.percent_tax(21.0) document = self.populate_document(self.init_document( lines=[ {'price_unit': 10.04, 'discount': 10, 'tax_ids': tax_21}, ] + [ {'price_unit': 1.04, 'discount': 10, 'tax_ids': tax_21}, ] * 10, )) line_1_expected_values = { 'total_excluded': 9.04, 'total_excluded_currency': 9.04, 'total_included': 10.94, 'total_included_currency': 10.94, 'delta_total_excluded': 0.0, 'delta_total_excluded_currency': 0.0, 'manual_total_excluded': None, 'manual_total_excluded_currency': None, 'manual_tax_amounts': None, 'taxes_data': [ { 'tax_id': tax_21.id, 'tax_amount': 1.8699999999999999, 'tax_amount_currency': 1.8699999999999999, 'base_amount': 9.01, 'base_amount_currency': 9.01, } ], } line_2_expected_values = { 'total_excluded': 0.94, 'total_excluded_currency': 0.94, 'total_included': 1.14, 'total_included_currency': 1.14, 'delta_total_excluded': 0.0, 'delta_total_excluded_currency': 0.0, 'manual_total_excluded': None, 'manual_total_excluded_currency': None, 'manual_tax_amounts': None, 'taxes_data': [ { 'tax_id': tax_21.id, 'tax_amount': 0.2, 'tax_amount_currency': 0.2, 'base_amount': 0.94, 'base_amount_currency': 0.94, } ], } expected_values = { 'base_lines_tax_details': [ { **line_1_expected_values, 'delta_total_excluded': -0.03, 'delta_total_excluded_currency': -0.03, }, { **line_2_expected_values, 'delta_total_excluded': -0.01, 'delta_total_excluded_currency': -0.01, 'taxes_data': [ { 'tax_id': tax_21.id, 'tax_amount': 0.19, 'tax_amount_currency': 0.19, 'base_amount': 0.9299999999999999, 'base_amount_currency': 0.9299999999999999, } ], }, line_2_expected_values, line_2_expected_values, line_2_expected_values, line_2_expected_values, line_2_expected_values, line_2_expected_values, line_2_expected_values, line_2_expected_values, line_2_expected_values, ] } self.assert_base_lines_tax_details(document, expected_values) self._run_js_tests() def test_dispatch_delta_on_net_zero_tax(self): """Check that the base line delta still is dispatched if net tax is zero.""" def get_expected_values(base_values, tax): expected_tax_total = sum(values[2] for values in base_expected_values) self.assertTrue( tax.company_id.currency_id.is_zero(expected_tax_total), "Expected taxes should add up to zero.", ) return { 'base_lines_tax_details': [{ 'delta_total_excluded': 0.0, 'delta_total_excluded_currency': 0.0, 'manual_tax_amounts': None, 'manual_total_excluded': None, 'manual_total_excluded_currency': None, 'taxes_data': [{ 'base_amount': total_excluded, 'base_amount_currency': total_excluded, 'tax_amount': tax_amount, 'tax_amount_currency': tax_amount, 'tax_id': tax.id, }], 'total_excluded': total_excluded, 'total_excluded_currency': total_excluded, 'total_included': total_included, 'total_included_currency': total_included, } for total_excluded, total_included, tax_amount in base_values], } with self.subTest("19.99% tax, 100% global discount"): tax_19_99 = self.percent_tax(19.99) lines_vals = [{ 'price_unit': price, 'quantity': 1, 'tax_ids': tax_19_99, } for price in (19.99, 19.99, -39.98)] document = self.populate_document(self.init_document(lines_vals)) base_expected_values = [ # (total_excluded, total_included, tax_amount), (19.99, 23.99, 4.0), (19.99, 23.99, 4.0), (-39.98, -47.97, -8.0), ] expected_values = get_expected_values(base_expected_values, tax_19_99) self.assert_base_lines_tax_details(document, expected_values) self._run_js_tests() with self.subTest("7% tax, 30% line discount, 100% global discount"): tax_7 = self.percent_tax(7.0) lines_vals = [{ 'price_unit': price, 'quantity': 4, 'discount': 30, 'tax_ids': tax_7, } for price in (1068, 46, 46, 298, 5)] lines_vals.append({'price_unit': -4096.4, 'tax_ids': tax_7}) # 100% discount document = self.populate_document(self.init_document(lines_vals)) base_expected_values = [ # (total_excluded, total_included, tax_amount), (2990.4, 3199.73, 209.33), (128.8, 137.82000000000002, 9.02), (128.8, 137.82000000000002, 9.02), (834.4, 892.81, 58.41), (14.0, 14.98, 0.98), (-4096.4, -4383.15, -286.76), ] expected_values = get_expected_values(base_expected_values, tax_7) self.assert_base_lines_tax_details(document, expected_values) self._run_js_tests()