account/tests/test_multivat.py

251 lines
12 KiB
Python
Raw Permalink Normal View History

from unittest.mock import patch
from odoo import Command
from odoo.addons.account.models.chart_template import AccountChartTemplate
from odoo.addons.account.tests.common import instantiate_accountman
from odoo.tests import tagged
from odoo.tests.common import TransactionCase
def _get_chart_template_mapping(self, get_all=False):
return {
'local': {
'name': 'local',
'country_id': self.env.ref("base.be").id,
'country_code': 'be',
'modules': ['account'],
'parent': None,
'installed': True,
},
'foreign': {
'name': 'foreign',
'country_id': self.env.ref("base.fr").id,
'country_code': 'fr',
'modules': ['account'],
'parent': None,
'installed': True,
},
}
def data_method_provider(chart_template_name, country_code):
country = f"base.{country_code}"
# this is used to simulated differences between xml_ids
external_id_prefix = '' if chart_template_name == 'local' else f"{chart_template_name}_"
def test_data_getter(self, template_code):
return {
'template_data': {
'code_digits': 6,
'currency_id': 'base.EUR',
'property_account_income_categ_id': f'{external_id_prefix}test_account_income_template',
'property_account_expense_categ_id': f'{external_id_prefix}test_account_expense_template',
},
'res.company': {
self.env.company.id: {
'bank_account_code_prefix': '1000',
'cash_account_code_prefix': '2000',
'transfer_account_code_prefix': '3000',
},
},
'account.account': {
f'{external_id_prefix}test_account_tax_recoverable_template': {
'name': f'{external_id_prefix}tax recoverable',
'code': '411000',
'account_type': 'asset_current',
},
f'{external_id_prefix}test_account_tax_receivable_template': {
'name': f'{external_id_prefix}tax recoverable',
'code': '411200',
'account_type': 'asset_current',
},
f'{external_id_prefix}test_account_advance_payment_tax_template': {
'name': f'{external_id_prefix}advance tax payment',
'code': '411900',
'account_type': 'asset_current',
},
f'{external_id_prefix}test_account_tax_payable_template': {
'name': f'{external_id_prefix}tax recoverable',
'code': '451200',
'account_type': 'liability_current',
},
f'{external_id_prefix}test_account_cash_basis_transition_account_id': {
'name': f'{external_id_prefix}cash basis transition account',
'code': '451500',
'account_type': 'liability_current',
},
f'{external_id_prefix}test_account_income_template': {
'name': f'{external_id_prefix}income',
'code': '600000',
'account_type': 'income',
},
f'{external_id_prefix}test_account_expense_template': {
'name': f'{external_id_prefix}expense',
'code': '700000',
'account_type': 'expense',
},
},
'account.journal': self._get_account_journal(template_code),
'account.tax.group': {
'tax_group_taxes': {
'name': f"{external_id_prefix}Taxes",
'sequence': 0,
'country_id': country,
'tax_payable_account_id': f'{external_id_prefix}test_account_tax_payable_template',
'tax_receivable_account_id': f'{external_id_prefix}test_account_tax_receivable_template',
'advance_tax_payment_account_id': f'{external_id_prefix}test_account_advance_payment_tax_template',
},
},
'account.tax': {
**{
xmlid: _tax_vals(name, amount, external_id_prefix)
for name, xmlid, amount in (
('Tax 1', 'test_tax_1_template', 15),
('Tax 2', 'test_tax_2_template', 0),
)
},
'test_composite_tax_template': {
'name': 'Tax Grouped',
'amount_type': 'group',
'type_tax_use': 'purchase',
'tax_group_id': 'tax_group_taxes',
'children_tax_ids': 'test_tax_1_template,test_tax_2_template',
}
},
}
return test_data_getter
def _tax_vals(name, amount, external_id_prefix):
return {
'name': name,
'amount': amount,
'type_tax_use': 'purchase',
'tax_group_id': 'tax_group_taxes',
'cash_basis_transition_account_id': f'{external_id_prefix}test_account_cash_basis_transition_account_id',
'repartition_line_ids': [
Command.create({'document_type': 'invoice', 'factor_percent': 100, 'repartition_type': 'base'}),
Command.create({'document_type': 'invoice', 'factor_percent': 100, 'repartition_type': 'tax',
'account_id': f'{external_id_prefix}test_account_tax_recoverable_template'}),
Command.create({'document_type': 'refund', 'factor_percent': 100, 'repartition_type': 'base'}),
Command.create({'document_type': 'refund', 'factor_percent': 100, 'repartition_type': 'tax',
'account_id': f'{external_id_prefix}test_account_tax_recoverable_template'}),
]
}
@tagged('post_install', '-at_install')
@patch.object(AccountChartTemplate, '_get_chart_template_mapping', _get_chart_template_mapping)
class TestMultiVAT(TransactionCase):
@classmethod
@patch.object(AccountChartTemplate, '_get_chart_template_mapping', _get_chart_template_mapping)
def setUpClass(cls):
"""
Setups a company with a custom chart template, containing a tax and a fiscal position.
We need to add xml_ids to the templates because they are loaded from their xml_ids
"""
super().setUpClass()
instantiate_accountman(cls)
cls.company_1 = cls.env['res.company'].create({
'name': 'TestCompany1',
'country_id': cls.env.ref('base.be').id,
})
cls.user.write({
'company_ids': [Command.set(cls.company_1.ids)],
'company_id': cls.company_1.id,
})
test_get_data = data_method_provider("local", "be")
with patch.object(AccountChartTemplate, '_get_chart_template_data', side_effect=test_get_data, autospec=True):
cls.env['account.chart.template'].try_loading('local', company=cls.company_1, install_demo=False)
foreign_country = cls.env.ref("base.fr")
cls.foreign_vat_fpos = cls.env["account.fiscal.position"].create({
"name": "FR foreign VAT",
"auto_apply": True,
"country_id": foreign_country.id,
"foreign_vat": "FR23334175221",
})
test_get_data = data_method_provider("foreign", "fr")
with patch.object(AccountChartTemplate, '_get_chart_template_data', side_effect=test_get_data, autospec=True):
cls.foreign_vat_fpos.action_create_foreign_taxes()
def test_tax_and_tax_group_should_be_reachable_using_standard_api(self):
# Ensure local and foreign tax is reachable using the custom ref api
for xml_id in (
# tax group
'tax_group_taxes',
'foreign_tax_group_taxes',
# tax
'test_tax_1_template',
'test_tax_2_template',
'test_composite_tax_template',
'foreign_test_tax_1_template',
'foreign_test_tax_2_template',
'foreign_test_composite_tax_template'
):
with self.subTest(xml_id=xml_id):
record = self.env["account.chart.template"].ref(xml_id, raise_if_not_found=False)
self.assertTrue(record, "We should be able to retrieve the record")
def test_tax_group_data(self):
# Ensure the correct country is set on tax group
for xml_id, country_code in (('tax_group_taxes', 'BE'), ('foreign_tax_group_taxes', 'FR')):
tax_group = self.env["account.chart.template"].ref(xml_id)
with self.subTest(xml_id=xml_id, country_code=country_code):
self.assertEqual(tax_group.country_id.code, country_code)
local_tax_group = self.env["account.chart.template"].ref('tax_group_taxes')
foreign_tax_group = self.env["account.chart.template"].ref('foreign_tax_group_taxes')
for field in ('tax_payable_account_id', 'tax_receivable_account_id', 'advance_tax_payment_account_id'):
with self.subTest(field=field):
self.assertTrue(foreign_tax_group[field], "This account should have been set")
self.assertNotEqual(foreign_tax_group[field], local_tax_group[field],
"A copy of the local tax group account should have been created and set")
def test_tax_data_should_be_consistent(self):
# Ensure the correct country is set
for xml_id, country_code in (
# tax
('test_tax_1_template', 'BE'),
('test_tax_2_template', 'BE'),
('foreign_test_tax_1_template', 'FR'),
('foreign_test_tax_2_template', 'FR'),
):
model = self.env["account.chart.template"].ref(xml_id)
with self.subTest(xml_id=xml_id, country_code=country_code):
self.assertEqual(model.country_id.code, country_code)
tax = self.env["account.chart.template"].ref('foreign_test_tax_1_template')
self.assertEqual(tax.country_id.code, 'FR')
self.assertEqual(tax.cash_basis_transition_account_id.code, '451501')
_base_line, tax_line = tax.invoice_repartition_line_ids
self.assertEqual(tax_line.account_id.code, '411001',
"The foreign tax account should be a new account with a code close to the local tax account code")
tax = self.env["account.chart.template"].ref('foreign_test_tax_2_template')
self.assertEqual(tax.country_id.code, 'FR')
self.assertEqual(tax.cash_basis_transition_account_id.code, '451501')
_base_line, tax_line = tax.invoice_repartition_line_ids
self.assertEqual(tax_line.account_id.code, '411001',
"The previously created tax account should be reused for similar tax")
def test_children_taxes(self):
# Ensure that group-type taxes are correctly linked to their children
composite_taxes = ['test_composite_tax_template', 'foreign_test_composite_tax_template']
children_taxes = {
'test_composite_tax_template': ['test_tax_1_template', 'test_tax_2_template'],
'foreign_test_composite_tax_template': ['foreign_test_tax_1_template', 'foreign_test_tax_2_template'],
}
for xml_id in composite_taxes:
with self.subTest(xml_id=xml_id):
record = self.env["account.chart.template"].ref(xml_id, raise_if_not_found=False)
for i, child in enumerate(record.children_tax_ids):
child_tax = self.env["account.chart.template"].ref(children_taxes[xml_id][i], raise_if_not_found=False)
self.assertEqual(child.id, child_tax.id)