From 9dbff9816dc7f97590e49976149a4c0734e8d31b Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Sat, 22 Sep 2018 03:28:30 +0200 Subject: [PATCH] [IMP] account_chart_update: Include field selection With this option, you can select which fields do you want to compare for updating. Use case: you have specific accounts in taxes, and you don't want to lose them, but you want to update their groups through the wizard. Before this, the update was all or nothing. Now, you have total control! --- account_chart_update/__init__.py | 4 +- account_chart_update/__manifest__.py | 2 +- account_chart_update/models/__init__.py | 4 + .../models/ir_model_fields.py | 20 +++++ .../tests/test_account_chart_update.py | 40 +++++++++- .../wizard/wizard_chart_update.py | 69 +++++++++++++++++- .../wizard/wizard_chart_update_view.xml | 73 ++++++++++++++----- 7 files changed, 187 insertions(+), 25 deletions(-) create mode 100644 account_chart_update/models/__init__.py create mode 100644 account_chart_update/models/ir_model_fields.py diff --git a/account_chart_update/__init__.py b/account_chart_update/__init__.py index bdf9279b4..4d7a49b5e 100644 --- a/account_chart_update/__init__.py +++ b/account_chart_update/__init__.py @@ -1,6 +1,4 @@ -# © 2010 Zikzakmedia S.L. (http://www.zikzakmedia.com) -# © 2010 Pexego Sistemas Informáticos S.L.(http://www.pexego.es) -# © 2016 Jairo Llopis # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from . import models from . import wizard diff --git a/account_chart_update/__manifest__.py b/account_chart_update/__manifest__.py index 54aa9588f..07708d619 100644 --- a/account_chart_update/__manifest__.py +++ b/account_chart_update/__manifest__.py @@ -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.0.1", + 'version': "11.0.1.1.0", 'author': "Tecnativa, " "BCIM, " "Okia, " diff --git a/account_chart_update/models/__init__.py b/account_chart_update/models/__init__.py new file mode 100644 index 000000000..66c44ea1a --- /dev/null +++ b/account_chart_update/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import ir_model_fields diff --git a/account_chart_update/models/ir_model_fields.py b/account_chart_update/models/ir_model_fields.py new file mode 100644 index 000000000..54aa76646 --- /dev/null +++ b/account_chart_update/models/ir_model_fields.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class IrModelFields(models.Model): + _inherit = 'ir.model.fields' + + def name_get(self): + """Return special label when showing fields in chart update wizard.""" + if self.env.context.get('account_chart_update'): + res = [] + for record in self: + res.append((record.id, "%s (%s)" % ( + record.field_description, record.name, + ))) + return res + return super(IrModelFields, self).name_get() diff --git a/account_chart_update/tests/test_account_chart_update.py b/account_chart_update/tests/test_account_chart_update.py index 553be153b..7b2c4b63d 100644 --- a/account_chart_update/tests/test_account_chart_update.py +++ b/account_chart_update/tests/test_account_chart_update.py @@ -135,9 +135,21 @@ class TestAccountChartUpdate(common.HttpCase): @mute_logger('odoo.sql_db') def test_chart_update(self): - # Test no changes wizard = self.wizard_obj.create(self.wizard_vals) wizard.action_find_records() + # Test ir.model.fields name_get + field = wizard.fp_field_ids[:1] + name = field.with_context(account_chart_update=True).name_get()[0] + self.assertEqual(name[0], field.id) + self.assertEqual( + name[1], "%s (%s)" % (field.field_description, field.name), + ) + name = field.name_get()[0] + self.assertEqual(name[0], field.id) + self.assertEqual( + name[1], "%s (%s)" % (field.field_description, field.model), + ) + # Test no changes self.assertEqual(wizard.state, 'ready') self.assertFalse(wizard.tax_ids) self.assertFalse(wizard.account_ids) @@ -254,6 +266,32 @@ class TestAccountChartUpdate(common.HttpCase): self.assertEqual(self.fp.account_ids.account_dest_id, new_account) self.assertEqual(self.fp.tax_ids.tax_dest_id, self.tax) wizard.unlink() + # Exclude fields from check + self.tax_template.description = "Test description 2" + self.account_template.name = "Other name 2" + self.fp_template.note = "Test note 2" + wizard = self.wizard_obj.create(self.wizard_vals) + wizard.action_find_records() + wizard.tax_field_ids -= self.env['ir.model.fields'].search([ + ('model', '=', 'account.tax.template'), + ('name', '=', 'description'), + ]) + wizard.account_field_ids -= self.env['ir.model.fields'].search([ + ('model', '=', 'account.account.template'), + ('name', '=', 'name'), + ]) + wizard.fp_field_ids -= self.env['ir.model.fields'].search([ + ('model', '=', 'account.fiscal.position.template'), + ('name', '=', 'note'), + ]) + wizard.action_find_records() + self.assertFalse(wizard.tax_ids) + self.assertFalse(wizard.account_ids) + self.assertFalse(wizard.fiscal_position_ids) + self.tax_template.description = "Test description" + self.account_template.name = "Other name" + self.fp_template.note = "Test note" + wizard.unlink() # Remove objects new_tax_tmpl.unlink() wizard = self.wizard_obj.create(self.wizard_vals) diff --git a/account_chart_update/wizard/wizard_chart_update.py b/account_chart_update/wizard/wizard_chart_update.py index c164ec127..f5693b477 100644 --- a/account_chart_update/wizard/wizard_chart_update.py +++ b/account_chart_update/wizard/wizard_chart_update.py @@ -96,6 +96,57 @@ class WizardUpdateChartsAccounts(models.TransientModel): string='Deactivated taxes', compute="_compute_deleted_taxes_count") log = fields.Text(string='Messages and Errors', readonly=True) + tax_field_ids = fields.Many2many( + comodel_name="ir.model.fields", + relation="wizard_update_charts_tax_fields_rel", + string="Tax fields", + domain=lambda self: self._domain_tax_field_ids(), + default=lambda self: self._default_tax_field_ids(), + ) + account_field_ids = fields.Many2many( + comodel_name="ir.model.fields", + relation="wizard_update_charts_account_fields_rel", + string="Account fields", + domain=lambda self: self._domain_account_field_ids(), + default=lambda self: self._default_account_field_ids(), + ) + fp_field_ids = fields.Many2many( + comodel_name="ir.model.fields", + relation="wizard_update_charts_fp_fields_rel", + string="Fiscal position fields", + domain=lambda self: self._domain_fp_field_ids(), + default=lambda self: self._default_fp_field_ids(), + ) + + def _domain_per_name(self, name): + return [ + ('model', '=', name), + ('name', 'not in', tuple(self.fields_to_ignore(name))), + ] + + def _domain_tax_field_ids(self): + return self._domain_per_name('account.tax.template') + + def _domain_account_field_ids(self): + return self._domain_per_name('account.account.template') + + def _domain_fp_field_ids(self): + return self._domain_per_name('account.fiscal.position.template') + + def _default_tax_field_ids(self): + return [(4, x.id) for x in self.env['ir.model.fields'].search( + self._domain_tax_field_ids() + )] + + def _default_account_field_ids(self): + return [(4, x.id) for x in self.env['ir.model.fields'].search( + self._domain_account_field_ids() + )] + + def _default_fp_field_ids(self): + return [(4, x.id) for x in self.env['ir.model.fields'].search( + self._domain_fp_field_ids() + )] @api.model def _get_lang_selection_options(self): @@ -355,7 +406,7 @@ class WizardUpdateChartsAccounts(models.TransientModel): @api.model @tools.ormcache("name") - def fields_to_ignore(self, template, name): + def fields_to_ignore(self, name): """Get fields that will not be used when checking differences. :param str template: A template record. @@ -364,11 +415,16 @@ class WizardUpdateChartsAccounts(models.TransientModel): """ specials_mapping = { "account.tax.template": { + "chart_template_id", "children_tax_ids", }, "account.account.template": { + "chart_template_id", "code", }, + "account.fiscal.position.template": { + "chart_template_id", + }, } specials = ({"display_name", "__last_update", "company_id"} | specials_mapping.get(name, set())) @@ -387,9 +443,16 @@ class WizardUpdateChartsAccounts(models.TransientModel): Fields that are different in both records, and the expected value. """ result = dict() - ignore = self.fields_to_ignore(template, template._name) + ignore = self.fields_to_ignore(template._name) + to_include = [] + if template._name == 'account.tax.template': + to_include = self.tax_field_ids.mapped('name') + elif template._name == 'account.account.template': + to_include = self.account_field_ids.mapped('name') + elif template._name == 'account.fiscal.position.template': + to_include = self.fp_field_ids.mapped('name') for key, field in template._fields.items(): - if key in ignore: + if key in ignore or key not in to_include: continue expected = t = None # Translate template records to reals for comparison diff --git a/account_chart_update/wizard/wizard_chart_update_view.xml b/account_chart_update/wizard/wizard_chart_update_view.xml index a9fc794c1..94bf2c595 100644 --- a/account_chart_update/wizard/wizard_chart_update_view.xml +++ b/account_chart_update/wizard/wizard_chart_update_view.xml @@ -32,23 +32,62 @@ /> - - - - - - - - - - - - -
-

If you leave these options set, the wizard will not just create new records, but also update records with changes (i.e. different tax amount)

-

Note: Only the changed fields are updated.

-
-
+ + + + + + + + + + + + + +
+

If you leave these options set, the wizard will not just create new records, but also update records with changes (i.e. different tax amount)

+

Note: Only the changed fields are updated.

+
+
+
+ +

+

Here you can select the fields you want to check if they have been updated in the templates.

+

+ + + + + + + + + + + +
+