[IMP] account: allow unknown fields in chart template.

Problem
---------
In most cases, default deferred accounts and journal need to be set up
for localizations. This is normally done in the enterprise report module
for that localization. However, in some cases, the localization does not
have special report formats. In such situation, a localization report
module that sets up very few default values for the data company is
defined. This is way overkill.

Objective
---------
Allow the community company template to have 'unknown fields' defined.
Doing so, allows for the default deferred accounts and journal to be
defined without entreprise module to exists. Currently, this raises an
error.

Solution
---------
In the pre-processing of the chart template values, we skip all the keys
in the company data that are not company fields.

We add a context value which, when True, revert that behavior back to
before this commit and checks that all fields in the company template
are actual company fields (this will be used in the standalone test for
l10n modules).

We also update the standalone test for l10n modules so that:
 1. it reports errors in all l10n modules at once.
 2. it uses the context value described above and checks that all fields
 in the company chart template are correct company field.

closes odoo/odoo#138937

Related: odoo/enterprise#50305
Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
Josse Colpaert
2023-12-14 19:06:06 +00:00
committed by Antoine Boonen
parent 9e1326fbe9
commit 0664155bff
3 changed files with 53 additions and 2 deletions
+7
View File
@@ -398,6 +398,13 @@ class AccountChartTemplate(models.AbstractModel):
if model in data:
data[model] = data.pop(model)
# Remove data of unknown fields present in the company template
company_data = data.get('res.company')
if company_data and not self.env.context.get('l10n_check_fields_complete'):
for fname in list(company_data.get(company.id)):
if fname not in company._fields:
del data['res.company'][company.id][fname]
return data
def _load_data(self, data):
+22 -2
View File
@@ -2,6 +2,8 @@
import logging
from odoo.tests import standalone
from odoo.addons.account.models.chart_template import AccountChartTemplate
from unittest.mock import patch
_logger = logging.getLogger(__name__)
@@ -13,6 +15,14 @@ def test_all_l10n(env):
As the module install is not yet fully transactional, the modules will
remain installed after the test.
"""
try_loading = type(env['account.chart.template']).try_loading
def try_loading_patch(self, template_code, company, install_demo=True):
self = self.with_context(l10n_check_fields_complete=True)
return try_loading(self, template_code, company, install_demo)
# Ensure the presence of demo data, to see if they can be correctly installed
assert env.ref('base.module_account').demo, "Need the demo to test with data"
@@ -21,7 +31,17 @@ def test_all_l10n(env):
('name', '=like', 'l10n%'),
('state', '=', 'uninstalled'),
])
l10n_mods.button_immediate_install()
with patch.object(AccountChartTemplate, 'try_loading', try_loading_patch):
l10n_mods.button_immediate_install()
# In all_l10n tests we need to verify demo data
demo_failures = env['ir.demo_failure'].search([])
if demo_failures:
_logger.warning("Error while testing demo data for all_l10n tests.")
for failure in demo_failures:
_logger.warning("Demo data of module %s has failed: %s",
failure.module_id.name, failure.error)
env.reset() # clear the set of environments
env = env() # get an environment that refers to the new registry
@@ -47,6 +67,6 @@ def test_all_l10n(env):
_logger.info('Testing COA: %s (company: %s)', template_code, company.name)
try:
with env.cr.savepoint():
env['account.chart.template'].try_loading(template_code, company, install_demo=True)
env['account.chart.template'].with_context(l10n_check_fields_complete=True).try_loading(template_code, company, install_demo=True)
except Exception:
_logger.error("Error when creating COA %s", template_code, exc_info=True)
@@ -462,3 +462,27 @@ class TestChartTemplate(TransactionCase):
for model in TEMPLATE_MODELS + sub_models:
data_after = self.env[model].search(get_domain(model))
self.assertEqual(data_before[model], data_after)
def test_unknown_company_fields(self):
""" Tests that if a key is not known in the company template data when the
context value 'l10n_check_fields_complete' is set, an error is raised. If a
key is not known in the company template data but the context value is not
set, that key is skipped and no error is raised."""
def local_get_data(self, template_code):
data = test_get_data(self, template_code)
data['res.company'][company.id]['unknown_company_key'] = 'unknown_company_value'
return data
company = self.company_1
with patch.object(AccountChartTemplate, '_get_chart_template_data', side_effect=local_get_data, autospec=True):
# hard fail the loading if the context key is set to ensure `test_all_l10n` works as expected
with (
self.assertRaisesRegex(ValueError, 'unknown_company_key'),
self.env.cr.savepoint(),
):
self.env['account.chart.template'].with_context(l10n_check_fields_complete=True).try_loading('test', company=company, install_demo=False)
# silently ignore if the field doesn't exist (yet)
self.env['account.chart.template'].try_loading('test', company=company, install_demo=False)