account_chart_update: allows to set the matching value order
It allows to set the order of matching for Account, Taxes and Fiscal position.
This commit is contained in:
parent
0fc24c8a74
commit
203c45b253
@ -8,7 +8,7 @@
|
||||
{
|
||||
'name': "Detect changes and update the Account Chart from a template",
|
||||
"summary": "Wizard to update a company's account chart from a template",
|
||||
'version': "11.0.1.1.0",
|
||||
'version': "11.0.2.1.0",
|
||||
'author': "Tecnativa, "
|
||||
"BCIM, "
|
||||
"Okia, "
|
||||
|
@ -396,8 +396,10 @@ positions that got modified on the template.</li>
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h1><a class="toc-backref" href="#id1">Usage</a></h1>
|
||||
<p>The wizard, accesible from <em>Accounting > Settings > Update chart of accounts</em>,
|
||||
lets the user select what kind of objects must be checked/updated, and whether
|
||||
<p>The wizard, accessible from
|
||||
<em>Accounting > Configuration > Settings > Update chart template</em>,
|
||||
lets the user select what kind of objects must be checked/updated, allows to
|
||||
set the order of fields matching to be checked/updated and whether
|
||||
old records must be checked for changes and updates.</p>
|
||||
<p>It will display all the objects to be created / updated / deactivated with some
|
||||
information about the detected differences, and allow the user to exclude
|
||||
|
@ -46,6 +46,12 @@ class TestAccountChartUpdate(common.HttpCase):
|
||||
self._create_xml_id(record)
|
||||
return record
|
||||
|
||||
def _get_model_data(self, record):
|
||||
return self.env['ir.model.data'].search([
|
||||
('model', '=', record._name),
|
||||
('res_id', '=', record.id),
|
||||
])
|
||||
|
||||
def setUp(self):
|
||||
super(TestAccountChartUpdate, self).setUp()
|
||||
# Make sure user is in English
|
||||
@ -355,3 +361,124 @@ class TestAccountChartUpdate(common.HttpCase):
|
||||
self.assertEqual(wizard.rejected_new_account_number, 1)
|
||||
self.assertEqual(wizard.new_accounts, 0)
|
||||
wizard.unlink()
|
||||
|
||||
def test_matching(self):
|
||||
# Test XML-ID matching
|
||||
self.tax_template.name = "Test 1 tax name changed"
|
||||
self.tax_template.description = "Test tax 1 description changed"
|
||||
self.account_template.code = "200000"
|
||||
self.fp_template.name = "Test 1 fp name changed"
|
||||
wizard = self.wizard_obj.create(self.wizard_vals)
|
||||
wizard.action_find_records()
|
||||
self.assertEqual(wizard.tax_ids.tax_id, self.tax_template)
|
||||
self.assertEqual(wizard.tax_ids.type, 'updated')
|
||||
self.assertEqual(wizard.account_ids.account_id, self.account_template)
|
||||
self.assertEqual(wizard.account_ids.type, 'updated')
|
||||
self.assertTrue(wizard.fiscal_position_ids.type, 'updated')
|
||||
self.assertEqual(wizard.fiscal_position_ids.fiscal_position_id,
|
||||
self.fp_template)
|
||||
wizard.action_update_records()
|
||||
self.assertEqual(wizard.updated_taxes, 1)
|
||||
self.assertEqual(wizard.updated_accounts, 1)
|
||||
self.assertEqual(wizard.updated_fps, 1)
|
||||
self.assertEqual(self.tax.name, self.tax_template.name)
|
||||
self.assertEqual(self.tax.description, self.tax_template.description)
|
||||
self.assertEqual(self.account.code, self.account_template.code)
|
||||
self.assertEqual(self.fp.name, self.fp_template.name)
|
||||
wizard.unlink()
|
||||
|
||||
# Test match by another field, there is no match by XML-ID
|
||||
self._get_model_data(self.tax).unlink()
|
||||
self._get_model_data(self.account).unlink()
|
||||
self._get_model_data(self.fp).unlink()
|
||||
self.tax_template.description = "Test 2 tax description changed"
|
||||
self.account_template.name = "Test 2 account name changed"
|
||||
self.fp_template.note = "Test 2 fp note changed"
|
||||
wizard = self.wizard_obj.create(self.wizard_vals)
|
||||
wizard.action_find_records()
|
||||
self.assertEqual(wizard.tax_ids.tax_id, self.tax_template)
|
||||
self.assertEqual(wizard.tax_ids.type, 'updated')
|
||||
self.assertEqual(wizard.account_ids.account_id, self.account_template)
|
||||
self.assertEqual(wizard.account_ids.type, 'updated')
|
||||
self.assertTrue(wizard.fiscal_position_ids.type, 'updated')
|
||||
self.assertEqual(wizard.fiscal_position_ids.fiscal_position_id,
|
||||
self.fp_template)
|
||||
wizard.action_update_records()
|
||||
self.assertEqual(wizard.updated_taxes, 1)
|
||||
self.assertEqual(wizard.updated_accounts, 1)
|
||||
self.assertEqual(wizard.updated_fps, 1)
|
||||
self.assertEqual(self.tax.description, self.tax_template.description)
|
||||
self.assertEqual(self.account.name, self.account_template.name)
|
||||
self.assertEqual(self.fp.note, self.fp_template.note)
|
||||
wizard.unlink()
|
||||
|
||||
# Test match by name, there is no match by XML-ID or by code
|
||||
self.account_template.code = "300000"
|
||||
wizard = self.wizard_obj.create(self.wizard_vals)
|
||||
wizard.action_find_records()
|
||||
self.assertEqual(wizard.account_ids.account_id, self.account_template)
|
||||
self.assertEqual(wizard.account_ids.type, 'updated')
|
||||
wizard.action_update_records()
|
||||
self.assertEqual(wizard.updated_accounts, 1)
|
||||
self.assertEqual(self.account.code, self.account_template.code)
|
||||
wizard.unlink()
|
||||
|
||||
# Test 1 recreate XML-ID
|
||||
self.tax_template.description = "Test 4 tax description changed"
|
||||
self.account_template.name = "Test 4 account name changed"
|
||||
self.fp_template.note = "Test 4 fp note changed"
|
||||
self.wizard_vals.update(recreate_xml_ids=True)
|
||||
wizard = self.wizard_obj.create(self.wizard_vals)
|
||||
wizard.action_find_records()
|
||||
self.assertEqual(wizard.tax_ids.tax_id, self.tax_template)
|
||||
self.assertEqual(wizard.tax_ids.type, 'updated')
|
||||
self.assertEqual(wizard.account_ids.account_id, self.account_template)
|
||||
self.assertEqual(wizard.account_ids.type, 'updated')
|
||||
self.assertTrue(wizard.fiscal_position_ids.type, 'updated')
|
||||
self.assertEqual(wizard.fiscal_position_ids.fiscal_position_id,
|
||||
self.fp_template)
|
||||
# There is no XML-ID
|
||||
self.assertFalse(list(self.tax.get_xml_id().values())[0])
|
||||
self.assertFalse(list(self.account.get_xml_id().values())[0])
|
||||
self.assertFalse(list(self.fp.get_xml_id().values())[0])
|
||||
# Update for recreating XML-ID
|
||||
wizard.action_update_records()
|
||||
self.assertEqual(wizard.updated_taxes, 1)
|
||||
self.assertEqual(wizard.updated_accounts, 1)
|
||||
self.assertEqual(wizard.updated_fps, 1)
|
||||
self.assertEqual(self.tax.description, self.tax_template.description)
|
||||
self.assertEqual(self.account.name, self.account_template.name)
|
||||
self.assertEqual(self.fp.note, self.fp_template.note)
|
||||
# There is XML-ID now
|
||||
self.assertTrue(list(self.tax.get_xml_id().values())[0])
|
||||
self.assertTrue(list(self.account.get_xml_id().values())[0])
|
||||
self.assertTrue(list(self.fp.get_xml_id().values())[0])
|
||||
wizard.unlink()
|
||||
|
||||
# Test 2 recreate XML-ID
|
||||
self._get_model_data(self.tax).unlink()
|
||||
self._get_model_data(self.account).unlink()
|
||||
self._get_model_data(self.fp).unlink()
|
||||
wizard = self.wizard_obj.create(self.wizard_vals)
|
||||
wizard.action_find_records()
|
||||
self.assertEqual(wizard.tax_ids.tax_id, self.tax_template)
|
||||
self.assertEqual(wizard.tax_ids.type, 'updated')
|
||||
self.assertEqual(wizard.account_ids.account_id, self.account_template)
|
||||
self.assertEqual(wizard.account_ids.type, 'updated')
|
||||
self.assertTrue(wizard.fiscal_position_ids.type, 'updated')
|
||||
self.assertEqual(wizard.fiscal_position_ids.fiscal_position_id,
|
||||
self.fp_template)
|
||||
# There is no XML-ID
|
||||
self.assertFalse(list(self.tax.get_xml_id().values())[0])
|
||||
self.assertFalse(list(self.account.get_xml_id().values())[0])
|
||||
self.assertFalse(list(self.fp.get_xml_id().values())[0])
|
||||
# Update for recreating XML-ID
|
||||
wizard.action_update_records()
|
||||
self.assertEqual(wizard.updated_taxes, 1)
|
||||
self.assertEqual(wizard.updated_accounts, 1)
|
||||
self.assertEqual(wizard.updated_fps, 1)
|
||||
# There is XML-ID now
|
||||
self.assertTrue(list(self.tax.get_xml_id().values())[0])
|
||||
self.assertTrue(list(self.account.get_xml_id().values())[0])
|
||||
self.assertTrue(list(self.fp.get_xml_id().values())[0])
|
||||
wizard.unlink()
|
||||
|
@ -62,6 +62,9 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
string="Continue on errors", default=False,
|
||||
help="If set, the wizard will continue to the next step even if "
|
||||
"there are minor errors.")
|
||||
recreate_xml_ids = fields.Boolean(
|
||||
string="Recreate missing XML-IDs",
|
||||
)
|
||||
tax_ids = fields.One2many(
|
||||
comodel_name='wizard.update.charts.accounts.tax', ondelete='cascade',
|
||||
inverse_name='update_chart_wizard_id', string='Taxes')
|
||||
@ -117,6 +120,24 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
domain=lambda self: self._domain_fp_field_ids(),
|
||||
default=lambda self: self._default_fp_field_ids(),
|
||||
)
|
||||
tax_matching_ids = fields.One2many(
|
||||
comodel_name="wizard.tax.matching",
|
||||
inverse_name="update_chart_wizard_id",
|
||||
string="Taxes matching",
|
||||
default=lambda self: self._default_tax_matching_ids(),
|
||||
)
|
||||
account_matching_ids = fields.One2many(
|
||||
comodel_name="wizard.account.matching",
|
||||
inverse_name="update_chart_wizard_id",
|
||||
string="Taxes matching",
|
||||
default=lambda self: self._default_account_matching_ids(),
|
||||
)
|
||||
fp_matching_ids = fields.One2many(
|
||||
comodel_name="wizard.fp.matching",
|
||||
inverse_name="update_chart_wizard_id",
|
||||
string="Taxes matching",
|
||||
default=lambda self: self._default_fp_matching_ids(),
|
||||
)
|
||||
|
||||
def _domain_per_name(self, name):
|
||||
return [
|
||||
@ -148,6 +169,32 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
self._domain_fp_field_ids()
|
||||
)]
|
||||
|
||||
def _get_matching_ids(self, model_name, ordered_opts):
|
||||
vals = []
|
||||
for seq, opt in enumerate(ordered_opts, 1):
|
||||
vals.append((0, False, {'sequence': seq, 'matching_value': opt}))
|
||||
|
||||
all_options = self.env[model_name]._get_matching_selection()
|
||||
all_options = map(lambda x: x[0], all_options)
|
||||
all_options = list(set(all_options) - set(ordered_opts))
|
||||
|
||||
for seq, opt in enumerate(all_options, len(ordered_opts) + 1):
|
||||
vals.append((0, False, {'sequence': seq, 'matching_value': opt}))
|
||||
|
||||
return vals
|
||||
|
||||
def _default_fp_matching_ids(self):
|
||||
ordered_opts = ['xml_id', 'name']
|
||||
return self._get_matching_ids('wizard.fp.matching', ordered_opts)
|
||||
|
||||
def _default_tax_matching_ids(self):
|
||||
ordered_opts = ['xml_id', 'description', 'name']
|
||||
return self._get_matching_ids('wizard.tax.matching', ordered_opts)
|
||||
|
||||
def _default_account_matching_ids(self):
|
||||
ordered_opts = ['xml_id', 'code', 'name']
|
||||
return self._get_matching_ids('wizard.account.matching', ordered_opts)
|
||||
|
||||
@api.model
|
||||
def _get_lang_selection_options(self):
|
||||
"""Gets the available languages for the selection."""
|
||||
@ -298,33 +345,41 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
self.state = 'done'
|
||||
return self._reopen()
|
||||
|
||||
def _get_real_xml_name(self, template):
|
||||
[external_id] = template.get_external_id().values()
|
||||
(name, module) = external_id.split('.')
|
||||
return "%s.%d_%s" % (name, self.company_id.id, module)
|
||||
|
||||
@api.multi
|
||||
@tools.ormcache("templates")
|
||||
def find_tax_by_templates(self, templates):
|
||||
"""Find a tax that matches the template."""
|
||||
# search inactive taxes too, to avoid re-creating
|
||||
# taxes that have been deactivated before
|
||||
Tax = self.env['account.tax'].with_context(active_test=False)
|
||||
result = Tax
|
||||
tax_model = self.env['account.tax'].with_context(active_test=False)
|
||||
for template in templates:
|
||||
single = Tax
|
||||
criteria = (
|
||||
("name", "=", template.name),
|
||||
("description", "=", template.name),
|
||||
("name", "=", template.description),
|
||||
("description", "=", template.description),
|
||||
)
|
||||
for domain in criteria:
|
||||
if single:
|
||||
break
|
||||
if domain[2]:
|
||||
single = Tax.search(
|
||||
[domain,
|
||||
("company_id", "=", self.company_id.id),
|
||||
("type_tax_use", "=", template.type_tax_use)],
|
||||
limit=1)
|
||||
result |= single
|
||||
return result[:1].id
|
||||
for matching in self.tax_matching_ids.sorted('sequence'):
|
||||
if matching.matching_value == 'xml_id':
|
||||
real = self.env.ref(self._get_real_xml_name(template),
|
||||
raise_if_not_found=False)
|
||||
if not real:
|
||||
continue
|
||||
criteria = ('id', '=', real.id)
|
||||
else:
|
||||
field_name = matching.matching_value
|
||||
if not template[field_name]:
|
||||
continue
|
||||
criteria = (field_name, '=', template[field_name])
|
||||
|
||||
result = tax_model.search([
|
||||
criteria,
|
||||
("company_id", "=", self.company_id.id),
|
||||
("type_tax_use", "=", template.type_tax_use),
|
||||
], limit=1)
|
||||
if result:
|
||||
return result.id
|
||||
|
||||
return False
|
||||
|
||||
@api.model
|
||||
@tools.ormcache("code")
|
||||
@ -336,19 +391,69 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
@tools.ormcache("templates")
|
||||
def find_account_by_templates(self, templates):
|
||||
"""Find an account that matches the template."""
|
||||
return self.env['account.account'].search(
|
||||
[('code', 'in',
|
||||
list(map(self.padded_code, templates.mapped("code")))),
|
||||
('company_id', '=', self.company_id.id)],
|
||||
).id
|
||||
account_model = self.env['account.account']
|
||||
for matching in self.account_matching_ids.sorted('sequence'):
|
||||
if matching.matching_value == 'xml_id':
|
||||
real = self.env['account.account']
|
||||
for template in templates:
|
||||
try:
|
||||
real |= self.env.ref(self._get_real_xml_name(template))
|
||||
except:
|
||||
pass
|
||||
|
||||
if not real:
|
||||
continue
|
||||
criteria = ('id', 'in', real.ids)
|
||||
elif matching.matching_value == 'code':
|
||||
codes = templates.mapped("code")
|
||||
if not codes:
|
||||
continue
|
||||
criteria = ('code', 'in', list(map(self.padded_code, codes)))
|
||||
else:
|
||||
field_name = matching.matching_value
|
||||
field_values = templates.mapped(field_name)
|
||||
if not field_values:
|
||||
continue
|
||||
criteria = (field_name, 'in', field_values)
|
||||
|
||||
result = account_model.search(
|
||||
[criteria, ('company_id', '=', self.company_id.id)])
|
||||
if result:
|
||||
return result.id
|
||||
|
||||
return False
|
||||
|
||||
@api.multi
|
||||
@tools.ormcache("templates")
|
||||
def find_fp_by_templates(self, templates):
|
||||
"""Find a real fiscal position from a template."""
|
||||
return self.env['account.fiscal.position'].search(
|
||||
[('name', 'in', templates.mapped("name")),
|
||||
('company_id', '=', self.company_id.id)], limit=1).id
|
||||
fp_model = self.env['account.fiscal.position']
|
||||
for matching in self.fp_matching_ids.sorted('sequence'):
|
||||
if matching.matching_value == 'xml_id':
|
||||
real = self.env['account.fiscal.position']
|
||||
for template in templates:
|
||||
try:
|
||||
real |= self.env.ref(self._get_real_xml_name(template))
|
||||
except:
|
||||
pass
|
||||
|
||||
if not real:
|
||||
continue
|
||||
criteria = ('id', 'in', real.ids)
|
||||
else:
|
||||
field_name = matching.matching_value
|
||||
field_values = templates.mapped(field_name)
|
||||
if not field_values:
|
||||
continue
|
||||
criteria = (field_name, 'in', field_values)
|
||||
|
||||
result = fp_model.search([
|
||||
criteria, ('company_id', '=', self.company_id.id)
|
||||
], limit=1)
|
||||
if result:
|
||||
return result.id
|
||||
|
||||
return False
|
||||
|
||||
@api.multi
|
||||
@tools.ormcache("templates", "current_fp_accounts")
|
||||
@ -420,7 +525,6 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
},
|
||||
"account.account.template": {
|
||||
"chart_template_id",
|
||||
"code",
|
||||
},
|
||||
"account.fiscal.position.template": {
|
||||
"chart_template_id",
|
||||
@ -483,8 +587,13 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
if expected is not None:
|
||||
if expected != [] and expected != real[key]:
|
||||
result[key] = expected
|
||||
elif template[key] != real[key]:
|
||||
result[key] = template[key]
|
||||
else:
|
||||
template_value = template[key]
|
||||
if template._name == "account.account.template" \
|
||||
and key == 'code':
|
||||
template_value = self.padded_code(template['code'])
|
||||
if template_value != real[key]:
|
||||
result[key] = template_value
|
||||
# Avoid to cache recordset references
|
||||
if isinstance(real._fields[key], fields.Many2many):
|
||||
result[key] = [(6, 0, result[key].ids)]
|
||||
@ -521,6 +630,13 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
result.append(_("Tax is disabled."))
|
||||
return "\n".join(result)
|
||||
|
||||
def missing_xml_id(self, real_obj):
|
||||
return not self.env['ir.model.data'].search([
|
||||
('res_id', '=', real_obj.id),
|
||||
('model', '=', real_obj._name),
|
||||
('module', '!=', '__export__'),
|
||||
])
|
||||
|
||||
@api.multi
|
||||
def _find_taxes(self):
|
||||
"""Search for, and load, tax templates to create/update/delete."""
|
||||
@ -544,6 +660,10 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
# Check the tax for changes
|
||||
tax = self.env['account.tax'].browse(tax_id)
|
||||
notes = self.diff_notes(template, tax)
|
||||
|
||||
if self.recreate_xml_ids and self.missing_xml_id(tax):
|
||||
notes += (notes and "\n" or "") + _("Missing XML-ID.")
|
||||
|
||||
if notes:
|
||||
# Tax to be updated
|
||||
self.tax_ids.create({
|
||||
@ -586,6 +706,10 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
# Check the account for changes
|
||||
account = self.env['account.account'].browse(account_id)
|
||||
notes = self.diff_notes(template, account)
|
||||
|
||||
if self.recreate_xml_ids and self.missing_xml_id(account):
|
||||
notes += (notes and "\n" or "") + _("Missing XML-ID.")
|
||||
|
||||
if notes:
|
||||
# Account to be updated
|
||||
self.account_ids.create({
|
||||
@ -620,6 +744,10 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
# Check the fiscal position for changes
|
||||
fp = self.env['account.fiscal.position'].browse(fp_id)
|
||||
notes = self.diff_notes(template, fp)
|
||||
|
||||
if self.recreate_xml_ids and self.missing_xml_id(fp):
|
||||
notes += (notes and "\n" or "") + _("Missing XML-ID.")
|
||||
|
||||
if notes:
|
||||
# Fiscal position template to be updated
|
||||
wiz_fp.create({
|
||||
@ -630,6 +758,27 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
'notes': notes,
|
||||
})
|
||||
|
||||
def recreate_xml_id(self, template, real_obj):
|
||||
ir_model_data = self.env['ir.model.data']
|
||||
template_xmlid = ir_model_data.search([
|
||||
('model', '=', template._name),
|
||||
('res_id', '=', template.id),
|
||||
])
|
||||
new_xml_id = "%d_%s" % (self.company_id.id, template_xmlid.name)
|
||||
|
||||
real_xmlid = ir_model_data.search([
|
||||
('model', '=', real_obj._name),
|
||||
('res_id', '=', real_obj.id),
|
||||
], limit=1)
|
||||
if real_xmlid:
|
||||
real_xmlid.unlink()
|
||||
template_xmlid.copy({
|
||||
'model': real_obj._name,
|
||||
'res_id': real_obj.id,
|
||||
'name': new_xml_id,
|
||||
'noupdate': True,
|
||||
})
|
||||
|
||||
@api.multi
|
||||
def _update_taxes(self):
|
||||
"""Process taxes to create/update/deactivate."""
|
||||
@ -651,7 +800,11 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
if key in {'account_id', 'refund_account_id'}:
|
||||
continue
|
||||
tax[key] = value
|
||||
_logger.info(_("Updated tax %s."), "'%s'" % template.name)
|
||||
_logger.info(_("Updated tax %s."), "'%s'" % template.name)
|
||||
if self.recreate_xml_ids and self.missing_xml_id(tax):
|
||||
self.recreate_xml_id(template, tax)
|
||||
_logger.info(_("Updated tax %s. (Recreated XML-IDs)"),
|
||||
"'%s'" % template.name)
|
||||
|
||||
@api.multi
|
||||
def _update_accounts(self):
|
||||
@ -701,6 +854,14 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
_("Updated account %s."),
|
||||
"'%s - %s'" % (account.code, account.name),
|
||||
)
|
||||
if self.recreate_xml_ids \
|
||||
and self.missing_xml_id(account):
|
||||
self.recreate_xml_id(template, account)
|
||||
_logger.info(
|
||||
_("Updated account %s. (Recreated XML-ID)"),
|
||||
"'%s - %s'" % (account.code, account.name),
|
||||
)
|
||||
|
||||
except Exception:
|
||||
self.rejected_updated_account_number += 1
|
||||
if config['test_enable']:
|
||||
@ -772,13 +933,22 @@ class WizardUpdateChartsAccounts(models.TransientModel):
|
||||
self.company_id, template, 'account.fiscal.position',
|
||||
self._prepare_fp_vals(template),
|
||||
)
|
||||
_logger.info(
|
||||
_("Created fiscal position %s."),
|
||||
"'%s'" % template.name,
|
||||
)
|
||||
else:
|
||||
# Update the given fiscal position
|
||||
for key, value in self.diff_fields(template, fp).items():
|
||||
fp[key] = value
|
||||
_logger.info(
|
||||
_("Created or updated fiscal position %s."),
|
||||
"'%s'" % template.name)
|
||||
_logger.info(_("Updated fiscal position %s."),
|
||||
"'%s'" % template.name)
|
||||
|
||||
if self.recreate_xml_ids and self.missing_xml_id(fp):
|
||||
self.recreate_xml_id(template, fp)
|
||||
_logger.info(
|
||||
_("Updated fiscal position %s. (Recreated XML-ID)"),
|
||||
"'%s'" % template.name,
|
||||
)
|
||||
|
||||
|
||||
class WizardUpdateChartsAccountsTax(models.TransientModel):
|
||||
@ -850,3 +1020,66 @@ class WizardUpdateChartsAccountsFiscalPosition(models.TransientModel):
|
||||
comodel_name='account.fiscal.position', required=False,
|
||||
string='Fiscal position to update', ondelete='set null')
|
||||
notes = fields.Text('Notes', readonly=True)
|
||||
|
||||
|
||||
class WizardMatching(models.TransientModel):
|
||||
_name = 'wizard.matching'
|
||||
_order = 'sequence'
|
||||
|
||||
update_chart_wizard_id = fields.Many2one(
|
||||
comodel_name='wizard.update.charts.accounts',
|
||||
string='Update chart wizard',
|
||||
required=True,
|
||||
ondelete='cascade',
|
||||
)
|
||||
sequence = fields.Integer(
|
||||
required=True,
|
||||
default=1,
|
||||
)
|
||||
matching_value = fields.Selection(
|
||||
selection="_get_matching_selection",
|
||||
)
|
||||
|
||||
def _get_matching_selection(self):
|
||||
return [('xml_id', 'XML-ID')]
|
||||
|
||||
def _selection_from_files(self, model_name, field_opts):
|
||||
result = []
|
||||
for opt in field_opts:
|
||||
model = self.env[model_name]
|
||||
desc = model._fields[opt].get_description(self.env)["string"]
|
||||
result.append((opt, "%s (%s)" % (desc, opt)))
|
||||
return result
|
||||
|
||||
|
||||
class WizardTaxMatching(models.TransientModel):
|
||||
_name = "wizard.tax.matching"
|
||||
_inherit = "wizard.matching"
|
||||
|
||||
def _get_matching_selection(self):
|
||||
vals = super(WizardTaxMatching, self)._get_matching_selection()
|
||||
vals += self._selection_from_files('account.tax.template',
|
||||
['description', 'name'])
|
||||
return vals
|
||||
|
||||
|
||||
class WizardAccountMatching(models.TransientModel):
|
||||
_name = "wizard.account.matching"
|
||||
_inherit = "wizard.matching"
|
||||
|
||||
def _get_matching_selection(self):
|
||||
vals = super(WizardAccountMatching, self)._get_matching_selection()
|
||||
vals += self._selection_from_files('account.account.template',
|
||||
['code', 'name'])
|
||||
return vals
|
||||
|
||||
|
||||
class WizardFpMatching(models.TransientModel):
|
||||
_name = 'wizard.fp.matching'
|
||||
_inherit = "wizard.matching"
|
||||
|
||||
def _get_matching_selection(self):
|
||||
vals = super(WizardFpMatching, self)._get_matching_selection()
|
||||
vals += self._selection_from_files('account.fiscal.position.template',
|
||||
['name'])
|
||||
return vals
|
||||
|
@ -42,6 +42,7 @@
|
||||
</group>
|
||||
<group string="Other options" attrs="{'invisible':[('state','!=','init')]}">
|
||||
<field name="continue_on_errors" />
|
||||
<field name="recreate_xml_ids" />
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
@ -87,6 +88,57 @@
|
||||
</page>
|
||||
</notebook>
|
||||
</page>
|
||||
<page string="Matching"
|
||||
attrs="{'invisible': [('update_tax', '=', False), ('update_account', '=', False), ('update_fiscal_position', '=', False)]}"
|
||||
>
|
||||
<h3>
|
||||
<p>Here you can set the matching order.</p>
|
||||
</h3>
|
||||
<notebook>
|
||||
<page string="Taxes"
|
||||
name="page_matching_taxes"
|
||||
attrs="{'invisible': [('update_tax', '=', False)]}"
|
||||
>
|
||||
<field name="tax_matching_ids">
|
||||
<tree create="false" edit="false" default_order="sequence">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="matching_value"/>
|
||||
</tree>
|
||||
<form>
|
||||
<field name="matching_value" readonly="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Accounts"
|
||||
name="page_matching_accounts"
|
||||
attrs="{'invisible': [('update_account', '=', False)]}"
|
||||
>
|
||||
<field name="account_matching_ids">
|
||||
<tree create="false" edit="false" default_order="sequence">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="matching_value"/>
|
||||
</tree>
|
||||
<form>
|
||||
<field name="matching_value" readonly="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Fiscal positions"
|
||||
name="page_matching_fps"
|
||||
attrs="{'invisible': [('update_fiscal_position', '=', False)]}"
|
||||
>
|
||||
<field name="fp_matching_ids">
|
||||
<tree create="false" edit="false" default_order="sequence">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="matching_value"/>
|
||||
</tree>
|
||||
<form>
|
||||
<field name="matching_value" readonly="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</page>
|
||||
</notebook>
|
||||
<group attrs="{'invisible':[('state','!=','ready'),]}"
|
||||
string="Records to create/update">
|
||||
|
Loading…
Reference in New Issue
Block a user