1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171 |
- # -*- coding: utf-8 -*-
- from odoo.addons.account.tests.common import AccountTestInvoicingCommon
- from odoo.tests import tagged
- class TestTaxCommon(AccountTestInvoicingCommon):
- @classmethod
- def setUpClass(cls, chart_template_ref=None):
- super().setUpClass(chart_template_ref=chart_template_ref)
- # Setup another company having a rounding of 1.0.
- cls.currency_data['currency'].rounding = 1.0
- cls.currency_no_decimal = cls.currency_data['currency']
- cls.company_data_2 = cls.setup_company_data('company_2', currency_id=cls.currency_no_decimal.id)
- cls.env.user.company_id = cls.company_data['company']
- cls.fixed_tax = cls.env['account.tax'].create({
- 'name': "Fixed tax",
- 'amount_type': 'fixed',
- 'amount': 10,
- 'sequence': 1,
- })
- cls.fixed_tax_bis = cls.env['account.tax'].create({
- 'name': "Fixed tax bis",
- 'amount_type': 'fixed',
- 'amount': 15,
- 'sequence': 2,
- })
- cls.percent_tax = cls.env['account.tax'].create({
- 'name': "Percent tax",
- 'amount_type': 'percent',
- 'amount': 10,
- 'sequence': 3,
- })
- cls.percent_tax_bis = cls.env['account.tax'].create({
- 'name': "Percent tax bis",
- 'amount_type': 'percent',
- 'amount': 10,
- 'sequence': 4,
- })
- cls.division_tax = cls.env['account.tax'].create({
- 'name': "Division tax",
- 'amount_type': 'division',
- 'amount': 10,
- 'sequence': 4,
- })
- cls.group_tax = cls.env['account.tax'].create({
- 'name': "Group tax",
- 'amount_type': 'group',
- 'amount': 0,
- 'sequence': 5,
- 'children_tax_ids': [
- (4, cls.fixed_tax.id, 0),
- (4, cls.percent_tax.id, 0)
- ]
- })
- cls.group_tax_bis = cls.env['account.tax'].create({
- 'name': "Group tax bis",
- 'amount_type': 'group',
- 'amount': 0,
- 'sequence': 6,
- 'children_tax_ids': [
- (4, cls.fixed_tax.id, 0),
- (4, cls.percent_tax.id, 0)
- ]
- })
- cls.group_tax_percent = cls.env['account.tax'].create({
- 'name': "Group tax percent",
- 'amount_type': 'group',
- 'amount': 0,
- 'sequence': 6,
- 'children_tax_ids': [
- (4, cls.percent_tax.id, 0),
- (4, cls.percent_tax_bis.id, 0)
- ]
- })
- cls.group_of_group_tax = cls.env['account.tax'].create({
- 'name': "Group of group tax",
- 'amount_type': 'group',
- 'amount': 0,
- 'sequence': 7,
- 'children_tax_ids': [
- (4, cls.group_tax.id, 0),
- (4, cls.group_tax_bis.id, 0)
- ]
- })
- cls.tax_with_no_account = cls.env['account.tax'].create({
- 'name': "Tax with no account",
- 'amount_type': 'fixed',
- 'amount': 0,
- 'sequence': 8,
- })
- some_account = cls.env['account.account'].search([], limit=1)
- cls.tax_with_account = cls.env['account.tax'].create({
- 'name': "Tax with account",
- 'amount_type': 'fixed',
- 'amount': 0,
- 'sequence': 8,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base'}),
- (0, 0, {
- 'repartition_type': 'tax',
- 'account_id': some_account.id,
- }),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base'}),
- (0, 0, {
- 'repartition_type': 'tax',
- 'account_id': some_account.id,
- }),
- ],
- })
- cls.tax_0_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
- 'name': "test_0_percent",
- 'amount_type': 'percent',
- 'amount': 0,
- })
- cls.tax_5_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
- 'name': "test_5_percent",
- 'amount_type': 'percent',
- 'amount': 5,
- })
- cls.tax_8_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
- 'name': "test_8_percent",
- 'amount_type': 'percent',
- 'amount': 8,
- })
- cls.tax_12_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
- 'name': "test_12_percent",
- 'amount_type': 'percent',
- 'amount': 12,
- })
- cls.tax_19_percent = cls.env['account.tax'].with_company(cls.company_data_2['company']).create({
- 'name': "test_19_percent",
- 'amount_type': 'percent',
- 'amount': 19,
- })
- cls.tax_21_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
- 'name': "test_21_percent",
- 'amount_type': 'percent',
- 'amount': 19,
- })
- cls.tax_21_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
- 'name': "test_rounding_methods_2",
- 'amount_type': 'percent',
- 'amount': 21,
- })
- cls.bank_journal = cls.company_data['default_journal_bank']
- cls.bank_account = cls.bank_journal.default_account_id
- cls.expense_account = cls.company_data['default_account_expense']
- def _check_compute_all_results(self, total_included, total_excluded, taxes, res):
- self.assertAlmostEqual(res['total_included'], total_included)
- self.assertAlmostEqual(res['total_excluded'], total_excluded)
- for i in range(0, len(taxes)):
- self.assertAlmostEqual(res['taxes'][i]['base'], taxes[i][0])
- self.assertAlmostEqual(res['taxes'][i]['amount'], taxes[i][1])
- @tagged('post_install', '-at_install')
- class TestTax(TestTaxCommon):
- @classmethod
- def setUpClass(cls):
- super(TestTax, cls).setUpClass()
- def test_tax_group_of_group_tax(self):
- self.fixed_tax.include_base_amount = True
- res = self.group_of_group_tax.compute_all(200.0)
- self._check_compute_all_results(
- 263, # 'total_included'
- 200, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (200.0, 10.0), # | 1 | 10 | | t
- (210.0, 21.0), # | 3 | 10% | |
- (210.0, 10.0), # | 1 | 10 | | t
- (220.0, 22.0), # | 3 | 10% | |
- # ---------------------------------------------------
- ],
- res
- )
- def test_tax_group(self):
- res = self.group_tax.compute_all(200.0)
- self._check_compute_all_results(
- 230, # 'total_included'
- 200, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (200.0, 10.0), # | 1 | 10 | |
- (200.0, 20.0), # | 3 | 10% | |
- # ---------------------------------------------------
- ],
- res
- )
- def test_tax_group_percent(self):
- res = self.group_tax_percent.with_context({'force_price_include':True}).compute_all(100.0)
- self._check_compute_all_results(
- 100, # 'total_included'
- 83.33, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (83.33, 8.33), # | 1 | 10% | |
- (83.33, 8.34), # | 2 | 10% | |
- # ---------------------------------------------------
- ],
- res
- )
- def test_tax_percent_division(self):
- self.division_tax.price_include = True
- self.division_tax.include_base_amount = True
- res_division = self.division_tax.compute_all(200.0)
- self._check_compute_all_results(
- 200, # 'total_included'
- 180, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (180.0, 20.0), # | 4 | 10/ | t | t
- # ---------------------------------------------------
- ],
- res_division
- )
- self.percent_tax.price_include = False
- self.percent_tax.include_base_amount = False
- res_percent = self.percent_tax.compute_all(100.0)
- self._check_compute_all_results(
- 110, # 'total_included'
- 100, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (100.0, 10.0), # | 3 | 10% | |
- # ---------------------------------------------------
- ],
- res_percent
- )
- self.division_tax.price_include = False
- self.division_tax.include_base_amount = False
- res_division = self.division_tax.compute_all(180.0)
- self._check_compute_all_results(
- 200, # 'total_included'
- 180, # 'total_excluded'
- [
- # base, amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (180.0, 20.0), # | 4 | 10/ | |
- # ---------------------------------------------------
- ],
- res_division
- )
- self.percent_tax.price_include = True
- self.percent_tax.include_base_amount = True
- res_percent = self.percent_tax.compute_all(110.0)
- self._check_compute_all_results(
- 110, # 'total_included'
- 100, # 'total_excluded'
- [
- # base, amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (100.0, 10.0), # | 3 | 10% | t | t
- # ---------------------------------------------------
- ],
- res_percent
- )
- self.percent_tax_bis.price_include = True
- self.percent_tax_bis.include_base_amount = True
- self.percent_tax_bis.amount = 21
- res_percent = self.percent_tax_bis.compute_all(7.0)
- self._check_compute_all_results(
- 7.0, # 'total_included'
- 5.79, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (5.79, 1.21), # | 3 | 21% | t | t
- # ---------------------------------------------------
- ],
- res_percent
- )
- def test_tax_sequence_normalized_set(self):
- self.division_tax.sequence = 1
- self.fixed_tax.sequence = 2
- self.percent_tax.sequence = 3
- taxes_set = (self.group_tax | self.division_tax)
- res = taxes_set.compute_all(200.0)
- self._check_compute_all_results(
- 252.22, # 'total_included'
- 200, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (200.0, 22.22), # | 1 | 10/ | |
- (200.0, 10.0), # | 2 | 10 | |
- (200.0, 20.0), # | 3 | 10% | |
- # ---------------------------------------------------
- ],
- res
- )
- def test_fixed_tax_include_base_amount(self):
- self.fixed_tax.include_base_amount = True
- res = self.group_tax.compute_all(200.0)
- self._check_compute_all_results(
- 231, # 'total_included'
- 200, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (200.0, 10.0), # | 1 | 10 | | t
- (210.0, 21.0), # | 3 | 10% | |
- # ---------------------------------------------------
- ],
- res
- )
- self.fixed_tax.price_include = True
- self.fixed_tax.include_base_amount = False
- res = self.fixed_tax.compute_all(100.0, quantity=2.0)
- self._check_compute_all_results(
- 200, # 'total_included'
- 180, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (180.0, 20.0), # | 1 | 20 | | t
- # ---------------------------------------------------
- ],
- res
- )
- def test_percent_tax_include_base_amount(self):
- self.percent_tax.price_include = True
- self.percent_tax.amount = 21.0
- res = self.percent_tax.compute_all(7.0)
- self._check_compute_all_results(
- 7.0, # 'total_included'
- 5.79, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (5.79, 1.21), # | 3 | 21% | t |
- # ---------------------------------------------------
- ],
- res
- )
- self.percent_tax.price_include = True
- self.percent_tax.amount = 20.0
- res = self.percent_tax.compute_all(399.99)
- self._check_compute_all_results(
- 399.99, # 'total_included'
- 333.33, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (333.33, 66.66), # | 3 | 20% | t |
- # ---------------------------------------------------
- ],
- res
- )
- def test_tax_decimals(self):
- """Test the rounding of taxes up to 6 decimals (maximum decimals places allowed for currencies)"""
- self.env.user.company_id.currency_id.rounding = 0.000001
- self.percent_tax.price_include = True
- self.percent_tax.amount = 21.0
- res = self.percent_tax.compute_all(7.0)
- self._check_compute_all_results(
- 7.0, # 'total_included'
- 5.785124, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # --------------------------------------------------------
- (5.785124, 1.214876), # | 3 | 21% | t |
- # --------------------------------------------------------
- ],
- res
- )
- self.percent_tax.price_include = True
- self.percent_tax.amount = 20.0
- res = self.percent_tax.compute_all(399.999999)
- self._check_compute_all_results(
- 399.999999, # 'total_included'
- 333.333333, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # -----------------------------------------------------------
- (333.333333, 66.666666), # | 3 | 20% | t |
- # -----------------------------------------------------------
- ],
- res
- )
- def test_advanced_taxes_computation_0(self):
- '''Test more advanced taxes computation (see issue 34471).'''
- tax_1 = self.env['account.tax'].create({
- 'name': 'test_advanced_taxes_computation_0_1',
- 'amount_type': 'percent',
- 'amount': 10,
- 'price_include': True,
- 'include_base_amount': True,
- 'sequence': 1,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- })
- tax_2 = self.env['account.tax'].create({
- 'name': 'test_advanced_taxes_computation_0_2',
- 'amount_type': 'percent',
- 'amount': 10,
- 'sequence': 2,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- })
- tax_3 = self.env['account.tax'].create({
- 'name': 'test_advanced_taxes_computation_0_3',
- 'amount_type': 'percent',
- 'amount': 10,
- 'price_include': True,
- 'sequence': 3,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- })
- tax_4 = self.env['account.tax'].create({
- 'name': 'test_advanced_taxes_computation_0_4',
- 'amount_type': 'percent',
- 'amount': 10,
- 'sequence': 4,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- })
- tax_5 = self.env['account.tax'].create({
- 'name': 'test_advanced_taxes_computation_0_5',
- 'amount_type': 'percent',
- 'amount': 10,
- 'price_include': True,
- 'sequence': 5,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- })
- taxes = tax_1 + tax_2 + tax_3 + tax_4 + tax_5
- # Test with positive amount.
- self._check_compute_all_results(
- 154, # 'total_included'
- 100, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (100.0, 5.0), # | 1 | 10% | t | t
- (100.0, 5.0), # | 1 | 10% | t | t
- (110.0, 5.5), # | 2 | 10% | |
- (110.0, 5.5), # | 2 | 10% | |
- (110.0, 5.5), # | 3 | 10% | t |
- (110.0, 5.5), # | 3 | 10% | t |
- (110.0, 5.5), # | 4 | 10% | |
- (110.0, 5.5), # | 4 | 10% | |
- (110.0, 5.5), # | 5 | 10% | t |
- (110.0, 5.5), # | 5 | 10% | t |
- # ---------------------------------------------------
- ],
- taxes.compute_all(132.0)
- )
- # Test with negative amount.
- self._check_compute_all_results(
- -154, # 'total_included'
- -100, # 'total_excluded'
- [
- # base , amount | seq | amount | incl | incl_base
- # ---------------------------------------------------
- (-100.0, -5.0), # | 1 | 10% | t | t
- (-100.0, -5.0), # | 1 | 10% | t | t
- (-110.0, -5.5), # | 2 | 10% | |
- (-110.0, -5.5), # | 2 | 10% | |
- (-110.0, -5.5), # | 3 | 10% | t |
- (-110.0, -5.5), # | 3 | 10% | t |
- (-110.0, -5.5), # | 4 | 10% | |
- (-110.0, -5.5), # | 4 | 10% | |
- (-110.0, -5.5), # | 5 | 10% | t |
- (-110.0, -5.5), # | 5 | 10% | t |
- # ---------------------------------------------------
- ],
- taxes.compute_all(-132.0)
- )
- def test_intracomm_taxes_computation_0(self):
- ''' Test usage of intracomm taxes having e.g.+100%, -100% as repartition lines. '''
- intracomm_tax = self.env['account.tax'].create({
- 'name': 'test_intracomm_taxes_computation_0_1',
- 'amount_type': 'percent',
- 'amount': 21,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -100.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -100.0}),
- ],
- })
- # Test with positive amount.
- self._check_compute_all_results(
- 100, # 'total_included'
- 100, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (100.0, 21.0),
- (100.0, -21.0),
- # ---------------
- ],
- intracomm_tax.compute_all(100.0)
- )
- # Test with negative amount.
- self._check_compute_all_results(
- -100, # 'total_included'
- -100, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (-100.0, -21.0),
- (-100.0, 21.0),
- # ---------------
- ],
- intracomm_tax.compute_all(-100.0)
- )
- def test_rounding_issues_0(self):
- ''' Test taxes having a complex setup of repartition lines. '''
- tax = self.env['account.tax'].create({
- 'name': 'test_rounding_issues_0',
- 'amount_type': 'percent',
- 'amount': 3,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- ],
- })
- # Test with positive amount.
- self._check_compute_all_results(
- 1.09, # 'total_included'
- 1, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (1.0, 0.01),
- (1.0, 0.01),
- (1.0, 0.01),
- (1.0, 0.02),
- (1.0, 0.02),
- (1.0, 0.02),
- # ---------------
- ],
- tax.compute_all(1.0)
- )
- # Test with negative amount.
- self._check_compute_all_results(
- -1.09, # 'total_included'
- -1, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (-1.0, -0.01),
- (-1.0, -0.01),
- (-1.0, -0.01),
- (-1.0, -0.02),
- (-1.0, -0.02),
- (-1.0, -0.02),
- # ---------------
- ],
- tax.compute_all(-1.0)
- )
- def test_rounding_issues_1(self):
- ''' Test taxes having a complex setup of repartition lines. '''
- tax = self.env['account.tax'].create({
- 'name': 'test_advanced_taxes_repartition_lines_computation_1',
- 'amount_type': 'percent',
- 'amount': 3,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -50.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}),
- (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}),
- ],
- })
- # Test with positive amount.
- self._check_compute_all_results(
- 1, # 'total_included'
- 1, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (1.0, 0.02),
- (1.0, -0.02),
- (1.0, 0.01),
- (1.0, 0.01),
- (1.0, -0.01),
- (1.0, -0.01),
- # ---------------
- ],
- tax.compute_all(1.0)
- )
- # Test with negative amount.
- self._check_compute_all_results(
- -1, # 'total_included'
- -1, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (-1.0, -0.02),
- (-1.0, 0.02),
- (-1.0, -0.01),
- (-1.0, -0.01),
- (-1.0, 0.01),
- (-1.0, 0.01),
- # ---------------
- ],
- tax.compute_all(-1.0)
- )
- def test_rounding_tax_excluded_round_per_line_01(self):
- ''' Test the rounding of a 19% price excluded tax in an invoice having 22689 and 9176 as lines.
- The decimal precision is set to zero.
- The computation must be similar to round(22689 * 0.19) + round(9176 * 0.19).
- '''
- self.tax_19_percent.company_id.currency_id.rounding = 1.0
- self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_per_line'
- res1 = self.tax_19_percent.compute_all(22689)
- self._check_compute_all_results(
- 27000, # 'total_included'
- 22689, # 'total_excluded'
- [
- # base, amount
- # ---------------
- (22689, 4311),
- # ---------------
- ],
- res1
- )
- res2 = self.tax_19_percent.compute_all(9176)
- self._check_compute_all_results(
- 10919, # 'total_included'
- 9176, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (9176, 1743),
- # ---------------
- ],
- res2
- )
- def test_rounding_tax_excluded_round_globally(self):
- ''' Test the rounding of a 19% price excluded tax in an invoice having 22689 and 9176 as lines.
- The decimal precision is set to zero.
- The computation must be similar to round((22689 + 9176) * 0.19).
- '''
- self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_globally'
- res1 = self.tax_19_percent.compute_all(22689)
- self._check_compute_all_results(
- 27000, # 'total_included'
- 22689, # 'total_excluded'
- [
- # base, amount
- # ---------------
- (22689, 4310.91),
- # ---------------
- ],
- res1
- )
- res2 = self.tax_19_percent.compute_all(9176)
- self._check_compute_all_results(
- 10919, # 'total_included'
- 9176, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (9176, 1743.44),
- # ---------------
- ],
- res2
- )
- def test_rounding_tax_included_round_per_line_01(self):
- ''' Test the rounding of a 19% price included tax in an invoice having 27000 and 10920 as lines.
- The decimal precision is set to zero.
- The computation must be similar to round(27000 / 1.19) + round(10920 / 1.19).
- '''
- self.tax_19_percent.price_include = True
- self.tax_19_percent.company_id.currency_id.rounding = 1.0
- self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_per_line'
- res1 = self.tax_19_percent.compute_all(27000)
- self._check_compute_all_results(
- 27000, # 'total_included'
- 22689, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (22689, 4311),
- # ---------------
- ],
- res1
- )
- res2 = self.tax_19_percent.compute_all(10920)
- self._check_compute_all_results(
- 10920, # 'total_included'
- 9176, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (9176, 1744),
- # ---------------
- ],
- res2
- )
- def test_rounding_tax_included_round_per_line_02(self):
- ''' Test the rounding of a 12% price included tax in an invoice having 52.50 as line.
- The decimal precision is set to 2.
- '''
- self.tax_12_percent.price_include = True
- self.tax_12_percent.company_id.currency_id.rounding = 0.01
- res1 = self.tax_12_percent.compute_all(52.50)
- self._check_compute_all_results(
- 52.50, # 'total_included'
- 46.88, # 'total_excluded'
- [
- # base , amount
- # -------------
- (46.88, 5.62),
- # -------------
- ],
- res1
- )
- def test_rounding_tax_included_round_per_line_03(self):
- ''' Test the rounding of a 8% and 0% price included tax in an invoice having 8 * 15.55 as line.
- The decimal precision is set to 2.
- '''
- self.tax_0_percent.company_id.currency_id.rounding = 0.01
- self.tax_0_percent.price_include = True
- self.tax_8_percent.price_include = True
- self.group_tax.children_tax_ids = [(6, 0, self.tax_0_percent.ids)]
- self.group_tax_bis.children_tax_ids = [(6, 0, self.tax_8_percent.ids)]
- res1 = (self.tax_8_percent | self.tax_0_percent).compute_all(15.55, quantity=8.0)
- self._check_compute_all_results(
- 124.40, # 'total_included'
- 115.19, # 'total_excluded'
- [
- # base , amount
- # -------------
- (115.19, 9.21),
- (115.19, 0.00),
- # -------------
- ],
- res1
- )
- res2 = (self.tax_0_percent | self.tax_8_percent).compute_all(15.55, quantity=8.0)
- self._check_compute_all_results(
- 124.40, # 'total_included'
- 115.19, # 'total_excluded'
- [
- # base , amount
- # -------------
- (115.19, 0.00),
- (115.19, 9.21),
- # -------------
- ],
- res2
- )
- def test_rounding_tax_included_round_per_line_04(self):
- ''' Test the rounding of a 5% price included tax.
- The decimal precision is set to 0.05.
- '''
- self.tax_5_percent.price_include = True
- self.tax_5_percent.company_id.currency_id.rounding = 0.05
- self.tax_5_percent.company_id.tax_calculation_rounding_method = 'round_per_line'
- res1 = self.tax_5_percent.compute_all(5)
- self._check_compute_all_results(
- 5, # 'total_included'
- 4.75, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (4.75, 0.25),
- # ---------------
- ],
- res1
- )
- res2 = self.tax_5_percent.compute_all(10)
- self._check_compute_all_results(
- 10, # 'total_included'
- 9.5, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (9.5, 0.5),
- # ---------------
- ],
- res2
- )
- res3 = self.tax_5_percent.compute_all(50)
- self._check_compute_all_results(
- 50, # 'total_included'
- 47.6, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (47.6, 2.4),
- # ---------------
- ],
- res3
- )
- def test_rounding_tax_included_round_globally_01(self):
- ''' Test the rounding of a 19% price included tax in an invoice having 27000 and 10920 as lines.
- The decimal precision is set to zero.
- The computation must be similar to round((27000 + 10920) / 1.19).
- '''
- self.tax_19_percent.price_include = True
- self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_globally'
- res1 = self.tax_19_percent.compute_all(27000)
- self._check_compute_all_results(
- 27000, # 'total_included'
- 22689, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (22689, 4311),
- # ---------------
- ],
- res1
- )
- res2 = self.tax_19_percent.compute_all(10920)
- self._check_compute_all_results(
- 10920, # 'total_included'
- 9176, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (9176, 1744),
- # ---------------
- ],
- res2
- )
- def test_rounding_tax_included_round_globally_02(self):
- ''' Test the rounding of a 21% price included tax in an invoice having 11.90 and 2.80 as lines.
- The decimal precision is set to 2.
- '''
- self.tax_21_percent.price_include = True
- self.tax_21_percent.company_id.currency_id.rounding = 0.01
- self.tax_21_percent.company_id.tax_calculation_rounding_method = 'round_globally'
- res1 = self.tax_21_percent.compute_all(11.90)
- self._check_compute_all_results(
- 11.90, # 'total_included'
- 9.83, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (9.83, 2.07),
- # ---------------
- ],
- res1
- )
- res2 = self.tax_21_percent.compute_all(2.80)
- self._check_compute_all_results(
- 2.80, # 'total_included'
- 2.31, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (2.31, 0.49),
- # ---------------
- ],
- res2
- )
- def test_rounding_tax_included_round_globally_03(self):
- ''' Test the rounding of a 5% price included tax.
- The decimal precision is set to 0.05.
- '''
- self.tax_5_percent.price_include = True
- self.tax_5_percent.company_id.currency_id.rounding = 0.05
- self.tax_5_percent.company_id.tax_calculation_rounding_method = 'round_globally'
- res1 = self.tax_5_percent.compute_all(5)
- self._check_compute_all_results(
- 5, # 'total_included'
- 4.75, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (4.75, 0.25),
- # ---------------
- ],
- res1
- )
- res2 = self.tax_5_percent.compute_all(10)
- self._check_compute_all_results(
- 10, # 'total_included'
- 9.5, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (9.50, 0.50),
- # ---------------
- ],
- res2
- )
- res3 = self.tax_5_percent.compute_all(50)
- self._check_compute_all_results(
- 50, # 'total_included'
- 47.6, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (47.60, 2.40),
- # ---------------
- ],
- res3
- )
- def test_is_base_affected(self):
- taxes = self.env['account.tax'].create([{
- 'name': 'test_is_base_affected%s' % i,
- 'amount_type': 'percent',
- 'amount': amount,
- 'include_base_amount': include_base_amount,
- 'is_base_affected': is_base_affected,
- 'sequence': i,
- } for i, amount, include_base_amount, is_base_affected in [
- (0, 6, True, True),
- (1, 6, True, False),
- (2, 10, False, True),
- ]])
- compute_all_results = taxes.compute_all(100.0)
- # Check the balance of the generated move lines
- self._check_compute_all_results(
- 123.2, # 'total_included'
- 100.0, # 'total_excluded'
- [
- # base, amount
- # -------------------------
- (100.0, 6.0),
- (100.0, 6.0),
- (112.0, 11.2),
- # -------------------------
- ],
- compute_all_results,
- )
- # Check the tax_ids on tax lines
- expected_tax_ids_list = [taxes[2].ids, taxes[2].ids, []]
- tax_ids_list = [tax_line['tax_ids'] for tax_line in compute_all_results['taxes']]
- self.assertEqual(tax_ids_list, expected_tax_ids_list, "Only a tax affected by previous taxes should have tax_ids set on its tax line when used after an 'include_base_amount' tax.")
- def test_mixing_price_included_excluded_with_affect_base(self):
- tax_10_fix = self.env['account.tax'].create({
- 'name': "tax_10_fix",
- 'amount_type': 'fixed',
- 'amount': 10.0,
- 'include_base_amount': True,
- })
- tax_21 = self.env['account.tax'].create({
- 'name': "tax_21",
- 'amount_type': 'percent',
- 'amount': 21.0,
- 'price_include': True,
- 'include_base_amount': True,
- })
- self._check_compute_all_results(
- 1222.1, # 'total_included'
- 1000.0, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (1000.0, 10.0),
- (1010.0, 212.1),
- # ---------------
- ],
- (tax_10_fix + tax_21).compute_all(1210),
- )
- def test_price_included_repartition_sum_0(self):
- """ Tests the case where a tax with a non-zero value has a sum
- of tax repartition factors of zero and is included in price. It
- shouldn't behave in the same way as a 0% tax.
- """
- test_tax = self.env['account.tax'].create({
- 'name': "Definitely not a 0% tax",
- 'amount_type': 'percent',
- 'amount': 42,
- 'price_include': True,
- 'invoice_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base'}),
- (0, 0, {'repartition_type': 'tax'}),
- (0, 0, {
- 'factor_percent': -100,
- 'repartition_type': 'tax',
- }),
- ],
- 'refund_repartition_line_ids': [
- (0, 0, {'repartition_type': 'base'}),
- (0, 0, {'repartition_type': 'tax'}),
- (0, 0, {
- 'factor_percent': -100,
- 'repartition_type': 'tax',
- }),
- ],
- })
- compute_all_res = test_tax.compute_all(100)
- self._check_compute_all_results(
- 100, # 'total_included'
- 100, # 'total_excluded'
- [
- # base , amount
- # ---------------
- (100, 42),
- (100, -42),
- # ---------------
- ],
- compute_all_res
- )
- def test_parse_name_search(self):
- list_ten_fixed_tax = self.env["account.tax"]
- ten_fixed_tax = self.env["account.tax"].create(
- {"name": "Ten Fixed tax", "amount_type": "fixed", "amount": 10}
- )
- list_ten_fixed_tax |= ten_fixed_tax
- ten_fixed_tax_tix = self.env["account.tax"].create(
- {"name": "Ten Fixed tax tix", "amount_type": "fixed", "amount": 10}
- )
- list_ten_fixed_tax |= ten_fixed_tax_tix
- self.assertListEqual(
- [x[0] for x in self.env["account.tax"].name_search("tix")],
- list_ten_fixed_tax.ids,
- )
- self.assertListEqual(
- [x[0] for x in self.env["account.tax"].name_search("\"tix\"")],
- ten_fixed_tax_tix.ids,
- )
- self.assertListEqual(
- [x[0] for x in self.env["account.tax"].name_search("Ten \"tix\"")],
- ten_fixed_tax_tix.ids,
- )
|