From 7e5db103b6fe3e19140f4f8a486d637eb31b921e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Tue, 12 Jun 2018 00:06:37 +0200 Subject: [PATCH] [REF] migrate to new api, inherit base class instead of patching, add test and make improve play_onchange --- onchange_helper/models/__init__.py | 2 +- onchange_helper/models/ir_rule.py | 55 -------------------------- onchange_helper/models/models.py | 51 ++++++++++++++++++++++++ onchange_helper/tests/__init__.py | 6 +++ onchange_helper/tests/test_onchange.py | 24 +++++++++++ 5 files changed, 82 insertions(+), 56 deletions(-) delete mode 100644 onchange_helper/models/ir_rule.py create mode 100644 onchange_helper/models/models.py create mode 100644 onchange_helper/tests/__init__.py create mode 100644 onchange_helper/tests/test_onchange.py diff --git a/onchange_helper/models/__init__.py b/onchange_helper/models/__init__.py index 0f0f860f3..cde864bae 100644 --- a/onchange_helper/models/__init__.py +++ b/onchange_helper/models/__init__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -from . import ir_rule +from . import models diff --git a/onchange_helper/models/ir_rule.py b/onchange_helper/models/ir_rule.py deleted file mode 100644 index 675cd6435..000000000 --- a/onchange_helper/models/ir_rule.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2016-2017 Akretion (http://www.akretion.com) -# © 2016-2017 Camptocamp (http://www.camptocamp.com/) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import api, models - - -def get_new_values(model, record, on_change_result): - vals = on_change_result.get('value', {}) - new_values = {} - for fieldname, value in vals.iteritems(): - if fieldname not in record: - column = model._fields[fieldname] - if value and column.type == 'many2one': - value = value[0] # many2one are tuple (id, name) - new_values[fieldname] = value - return new_values - - -@api.model -def play_onchanges(self, values, onchange_fields): - onchange_specs = self._onchange_spec() - # we need all fields in the dict even the empty ones - # otherwise 'onchange()' will not apply changes to them - all_values = values.copy() - for field in self._fields: - if field not in all_values: - # If self is a record (play onchange on existing record) - # we take the value of the field - # If self is an empty record we will have an empty value - all_values[field] = self[field] - - # we work on a temporary record - new_record = self.new(all_values) - - new_values = {} - for field in onchange_fields: - onchange_values = new_record.onchange(all_values, - field, onchange_specs) - new_values.update(get_new_values(self, values, onchange_values)) - all_values.update(new_values) - - res = {f: v for f, v in all_values.iteritems() - if not self._fields[f].compute and (f in values or f in new_values)} - return res - - -class IrRule(models.Model): - _inherit = 'ir.rule' - - def _setup_complete(self): - if not hasattr(models.BaseModel, 'play_onchanges'): - setattr(models.BaseModel, 'play_onchanges', play_onchanges) - return super(IrRule, self)._setup_complete() diff --git a/onchange_helper/models/models.py b/onchange_helper/models/models.py new file mode 100644 index 000000000..f66a5716e --- /dev/null +++ b/onchange_helper/models/models.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# © 2016-2017 Akretion (http://www.akretion.com) +# © 2016-2017 Camptocamp (http://www.camptocamp.com/) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, models + + +class Base(models.AbstractModel): + _inherit = 'base' + + @api.model + def _get_new_values(self, record, on_change_result): + vals = on_change_result.get('value', {}) + new_values = {} + for fieldname, value in vals.iteritems(): + if fieldname not in record: + column = self._fields[fieldname] + if value and column.type == 'many2one': + value = value[0] # many2one are tuple (id, name) + new_values[fieldname] = value + return new_values + + def play_onchanges(self, values, onchange_fields): + onchange_specs = self._onchange_spec() + # we need all fields in the dict even the empty ones + # otherwise 'onchange()' will not apply changes to them + all_values = values.copy() + + # If self is a record (play onchange on existing record) + # we take the value of the field + # If self is an empty record we will have an empty value + if self: + self.ensure_one() + record_values = self.read()[0] + else: + record_values = {} + for field in self._fields: + if field not in all_values: + all_values[field] = record_values.get(field, False) + + new_values = {} + for field in onchange_fields: + onchange_values = self.onchange(all_values, field, onchange_specs) + new_values.update(self._get_new_values(values, onchange_values)) + all_values.update(new_values) + + return { + f: v for f, v in all_values.iteritems() + if not self._fields[f].compute + and (f in values or f in new_values)} diff --git a/onchange_helper/tests/__init__.py b/onchange_helper/tests/__init__.py new file mode 100644 index 000000000..27ca25d37 --- /dev/null +++ b/onchange_helper/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_onchange diff --git a/onchange_helper/tests/test_onchange.py b/onchange_helper/tests/test_onchange.py new file mode 100644 index 000000000..d52b6a57d --- /dev/null +++ b/onchange_helper/tests/test_onchange.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 Akretion (http://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import openerp.tests.common as common + + +class TestOnchange(common.TransactionCase): + + def test_playing_onchange_on_model(self): + result = self.env['res.partner'].play_onchanges({ + 'company_type': 'company', + }, ['company_type']) + self.assertEqual(result['is_company'], True) + + def test_playing_onchange_on_record(self): + result = self.env.ref('base.main_company').play_onchanges({ + 'email': 'contact@akretion.com'}, + ['email']) + self.assertEqual( + result['rml_footer'], + u'Phone: +1 555 123 8069 | Email: contact@akretion.com | ' + u'Website: http://www.example.com')