From 0d9c44bf9c30f6e0a32c6ead6801878f7b88235f Mon Sep 17 00:00:00 2001 From: Florian da Costa Date: Fri, 4 Nov 2016 19:15:35 +0100 Subject: [PATCH 01/45] Add onchange_helper module --- onchange_helper/README.rst | 67 ++++++++++++++++++++++++++++++ onchange_helper/__init__.py | 4 ++ onchange_helper/__openerp__.py | 15 +++++++ onchange_helper/models/__init__.py | 4 ++ onchange_helper/models/ir_rule.py | 50 ++++++++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 onchange_helper/README.rst create mode 100644 onchange_helper/__init__.py create mode 100644 onchange_helper/__openerp__.py create mode 100644 onchange_helper/models/__init__.py create mode 100644 onchange_helper/models/ir_rule.py diff --git a/onchange_helper/README.rst b/onchange_helper/README.rst new file mode 100644 index 000000000..3af53e567 --- /dev/null +++ b/onchange_helper/README.rst @@ -0,0 +1,67 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=============== +Onchange Helper +=============== + +This is a technical module. Its goal is to ease the play of onchange method directly called from python file. + +Usage +===== + +To use this module, you need to: + +* depend on this module +* call `yourmodel.play_onchanges(values, ['field'])` + +Example if you want to create a sale order and you want to get the values relative to partner_id field (as if you fill the field from UI) + + `vals = {'partner_id: 1'}` + + `vals = self.env['sale.order'].play_onchange(vals, ['partner_id'])` + +Then, `vals` will be updated with partner_invoice_id, partner_shipping_id, pricelist_id, etc... + +For further information, please visit: + +* https://www.odoo.com/forum/help-1 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Guewen Baconnier +* Florian da Costa + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. + diff --git a/onchange_helper/__init__.py b/onchange_helper/__init__.py new file mode 100644 index 000000000..8d0394448 --- /dev/null +++ b/onchange_helper/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# © 2016 Akretion (http://www.akretion.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import models diff --git a/onchange_helper/__openerp__.py b/onchange_helper/__openerp__.py new file mode 100644 index 000000000..abf6e1e85 --- /dev/null +++ b/onchange_helper/__openerp__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# © 2016 Akretion (http://www.akretion.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{'name': 'Onchange Helper', + 'version': '9.0.1.0.0', + 'author': 'Akretion,Camp2camp,Odoo Community Association (OCA)', + 'website': 'www.akretion.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': [ + 'base', + ], + 'installable': True, + } diff --git a/onchange_helper/models/__init__.py b/onchange_helper/models/__init__.py new file mode 100644 index 000000000..25bec87f2 --- /dev/null +++ b/onchange_helper/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# © 2016 Akretion (http://www.akretion.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import ir_rule diff --git a/onchange_helper/models/ir_rule.py b/onchange_helper/models/ir_rule.py new file mode 100644 index 000000000..ec751bc28 --- /dev/null +++ b/onchange_helper/models/ir_rule.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# © 2016 Akretion (http://www.akretion.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from openerp 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 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: + all_values[field] = False + + # 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 f in values or f in new_values} + return res + + +class IrRule(models.Model): + _inherit = 'ir.rule' + + def _setup_complete(self, cr, uid): + if not hasattr(models.BaseModel, 'play_onchanges'): + setattr(models.BaseModel, 'play_onchanges', play_onchanges) + return super(IrRule, self)._setup_complete(cr, uid) From f52ed79d2e44a842bd5a480a6f2dd39f33b19098 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Mon, 27 Feb 2017 14:11:58 +0100 Subject: [PATCH 02/45] [MIG] module onchange_helper to v10.0 --- onchange_helper/README.rst | 8 ++------ onchange_helper/__init__.py | 3 +-- onchange_helper/__manifest__.py | 14 ++++++++++++++ onchange_helper/__openerp__.py | 15 --------------- onchange_helper/models/__init__.py | 3 +-- onchange_helper/models/ir_rule.py | 10 ++++++---- 6 files changed, 24 insertions(+), 29 deletions(-) create mode 100644 onchange_helper/__manifest__.py delete mode 100644 onchange_helper/__openerp__.py diff --git a/onchange_helper/README.rst b/onchange_helper/README.rst index 3af53e567..48cca771e 100644 --- a/onchange_helper/README.rst +++ b/onchange_helper/README.rst @@ -6,7 +6,7 @@ Onchange Helper =============== -This is a technical module. Its goal is to ease the play of onchange method directly called from python file. +This is a technical module. Its goal is to ease the play of onchange method directly called from Python code. Usage ===== @@ -20,14 +20,10 @@ Example if you want to create a sale order and you want to get the values relati `vals = {'partner_id: 1'}` - `vals = self.env['sale.order'].play_onchange(vals, ['partner_id'])` + `vals = self.env['sale.order'].play_onchanges(vals, ['partner_id'])` Then, `vals` will be updated with partner_invoice_id, partner_shipping_id, pricelist_id, etc... -For further information, please visit: - -* https://www.odoo.com/forum/help-1 - Bug Tracker =========== diff --git a/onchange_helper/__init__.py b/onchange_helper/__init__.py index 8d0394448..cde864bae 100644 --- a/onchange_helper/__init__.py +++ b/onchange_helper/__init__.py @@ -1,4 +1,3 @@ # -*- coding: utf-8 -*- -# © 2016 Akretion (http://www.akretion.com) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from . import models diff --git a/onchange_helper/__manifest__.py b/onchange_helper/__manifest__.py new file mode 100644 index 000000000..0d1b9b6a1 --- /dev/null +++ b/onchange_helper/__manifest__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# © 2016-2017 Akretion (http://www.akretion.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{'name': 'Onchange Helper', + 'version': '10.0.1.0.0', + 'summary': 'Technical module that ease execution of onchange in Python code', + 'author': 'Akretion,Camptocamp,Odoo Community Association (OCA)', + 'website': 'http://www.akretion.com', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['base'], + 'installable': True, + } diff --git a/onchange_helper/__openerp__.py b/onchange_helper/__openerp__.py deleted file mode 100644 index abf6e1e85..000000000 --- a/onchange_helper/__openerp__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2016 Akretion (http://www.akretion.com) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -{'name': 'Onchange Helper', - 'version': '9.0.1.0.0', - 'author': 'Akretion,Camp2camp,Odoo Community Association (OCA)', - 'website': 'www.akretion.com', - 'license': 'AGPL-3', - 'category': 'Generic Modules', - 'depends': [ - 'base', - ], - 'installable': True, - } diff --git a/onchange_helper/models/__init__.py b/onchange_helper/models/__init__.py index 25bec87f2..0f0f860f3 100644 --- a/onchange_helper/models/__init__.py +++ b/onchange_helper/models/__init__.py @@ -1,4 +1,3 @@ # -*- coding: utf-8 -*- -# © 2016 Akretion (http://www.akretion.com) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from . import ir_rule diff --git a/onchange_helper/models/ir_rule.py b/onchange_helper/models/ir_rule.py index ec751bc28..4a20ef0dc 100644 --- a/onchange_helper/models/ir_rule.py +++ b/onchange_helper/models/ir_rule.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- -# © 2016 Akretion (http://www.akretion.com) +# © 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 openerp import api, models + +from odoo import api, models def get_new_values(model, record, on_change_result): @@ -44,7 +46,7 @@ def play_onchanges(self, values, onchange_fields): class IrRule(models.Model): _inherit = 'ir.rule' - def _setup_complete(self, cr, uid): + def _setup_complete(self): if not hasattr(models.BaseModel, 'play_onchanges'): setattr(models.BaseModel, 'play_onchanges', play_onchanges) - return super(IrRule, self)._setup_complete(cr, uid) + return super(IrRule, self)._setup_complete() From 5a9a6818a1d170eb66577800acde0b093f515745 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Tue, 28 Feb 2017 09:01:00 +0100 Subject: [PATCH 03/45] [FIX] avoid a crash when value is False for a M2O field --- onchange_helper/models/ir_rule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onchange_helper/models/ir_rule.py b/onchange_helper/models/ir_rule.py index 4a20ef0dc..b4f67af16 100644 --- a/onchange_helper/models/ir_rule.py +++ b/onchange_helper/models/ir_rule.py @@ -12,7 +12,7 @@ def get_new_values(model, record, on_change_result): for fieldname, value in vals.iteritems(): if fieldname not in record: column = model._fields[fieldname] - if column.type == 'many2one': + if value and column.type == 'many2one': value = value[0] # many2one are tuple (id, name) new_values[fieldname] = value return new_values From cedc6508a4405d963c9b32e59c3da2efec735009 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sat, 3 Jun 2017 09:44:44 +0200 Subject: [PATCH 04/45] OCA Transbot updated translations from Transifex --- onchange_helper/i18n/de.po | 24 ++++++++++++++++++++++++ onchange_helper/i18n/es.po | 24 ++++++++++++++++++++++++ onchange_helper/i18n/hr.po | 24 ++++++++++++++++++++++++ onchange_helper/i18n/sl.po | 24 ++++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 onchange_helper/i18n/de.po create mode 100644 onchange_helper/i18n/es.po create mode 100644 onchange_helper/i18n/hr.po create mode 100644 onchange_helper/i18n/sl.po diff --git a/onchange_helper/i18n/de.po b/onchange_helper/i18n/de.po new file mode 100644 index 000000000..e47759dbe --- /dev/null +++ b/onchange_helper/i18n/de.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +# Translators: +# Niki Waibel , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-01 14:59+0000\n" +"PO-Revision-Date: 2017-06-01 14:59+0000\n" +"Last-Translator: Niki Waibel , 2017\n" +"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_ir_rule +msgid "ir.rule" +msgstr "ir.rule" diff --git a/onchange_helper/i18n/es.po b/onchange_helper/i18n/es.po new file mode 100644 index 000000000..cf06c4ea0 --- /dev/null +++ b/onchange_helper/i18n/es.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +# Translators: +# Fernando Lara , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-01 14:59+0000\n" +"PO-Revision-Date: 2017-06-01 14:59+0000\n" +"Last-Translator: Fernando Lara , 2017\n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_ir_rule +msgid "ir.rule" +msgstr "ir.regla" diff --git a/onchange_helper/i18n/hr.po b/onchange_helper/i18n/hr.po new file mode 100644 index 000000000..b6c316ce2 --- /dev/null +++ b/onchange_helper/i18n/hr.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-01 14:59+0000\n" +"PO-Revision-Date: 2017-06-01 14:59+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: hr\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_ir_rule +msgid "ir.rule" +msgstr "ir.rule" diff --git a/onchange_helper/i18n/sl.po b/onchange_helper/i18n/sl.po new file mode 100644 index 000000000..3b8f6692f --- /dev/null +++ b/onchange_helper/i18n/sl.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +# Translators: +# OCA Transbot , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-01 14:59+0000\n" +"PO-Revision-Date: 2017-06-01 14:59+0000\n" +"Last-Translator: OCA Transbot , 2017\n" +"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: sl\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_ir_rule +msgid "ir.rule" +msgstr "ir.rule" From ff0d2b051d420c0c9544505e0563e8c92cf12a8b Mon Sep 17 00:00:00 2001 From: Andrea Date: Sun, 14 Jan 2018 12:24:54 +0100 Subject: [PATCH 05/45] [11.0][MIG] onchange_helper + add tests --- onchange_helper/README.rst | 10 +++---- onchange_helper/__init__.py | 2 +- onchange_helper/__manifest__.py | 9 +++--- onchange_helper/models/__init__.py | 4 +-- .../models/{ir_rule.py => base.py} | 17 ++++++----- onchange_helper/tests/__init__.py | 3 ++ onchange_helper/tests/test_onchange_helper.py | 28 +++++++++++++++++++ 7 files changed, 51 insertions(+), 22 deletions(-) rename onchange_helper/models/{ir_rule.py => base.py} (77%) create mode 100644 onchange_helper/tests/__init__.py create mode 100644 onchange_helper/tests/test_onchange_helper.py diff --git a/onchange_helper/README.rst b/onchange_helper/README.rst index 48cca771e..622fbe8dd 100644 --- a/onchange_helper/README.rst +++ b/onchange_helper/README.rst @@ -1,5 +1,5 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: https://www.gnu.org/licenses/agpl :alt: License: AGPL-3 =============== @@ -18,7 +18,7 @@ To use this module, you need to: Example if you want to create a sale order and you want to get the values relative to partner_id field (as if you fill the field from UI) - `vals = {'partner_id: 1'}` + `vals = {'partner_id': 1}` `vals = self.env['sale.order'].play_onchanges(vals, ['partner_id'])` @@ -38,13 +38,14 @@ Credits Images ------ -* Odoo Community Association: `Icon `_. +* Odoo Community Association: `Icon `_. Contributors ------------ * Guewen Baconnier * Florian da Costa +* Andrea Stirpe Maintainer ---------- @@ -60,4 +61,3 @@ mission is to support the collaborative development of Odoo features and promote its widespread use. To contribute to this module, please visit https://odoo-community.org. - diff --git a/onchange_helper/__init__.py b/onchange_helper/__init__.py index cde864bae..31660d6a9 100644 --- a/onchange_helper/__init__.py +++ b/onchange_helper/__init__.py @@ -1,3 +1,3 @@ -# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from . import models diff --git a/onchange_helper/__manifest__.py b/onchange_helper/__manifest__.py index 0d1b9b6a1..82f03bcc1 100644 --- a/onchange_helper/__manifest__.py +++ b/onchange_helper/__manifest__.py @@ -1,12 +1,11 @@ -# -*- coding: utf-8 -*- -# © 2016-2017 Akretion (http://www.akretion.com) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# Copyright 2016-2017 Akretion (http://www.akretion.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). {'name': 'Onchange Helper', - 'version': '10.0.1.0.0', + 'version': '11.0.1.0.0', 'summary': 'Technical module that ease execution of onchange in Python code', 'author': 'Akretion,Camptocamp,Odoo Community Association (OCA)', - 'website': 'http://www.akretion.com', + 'website': 'https://github.com/OCA/server-tools', 'license': 'AGPL-3', 'category': 'Generic Modules', 'depends': ['base'], diff --git a/onchange_helper/models/__init__.py b/onchange_helper/models/__init__.py index 0f0f860f3..08f5a5618 100644 --- a/onchange_helper/models/__init__.py +++ b/onchange_helper/models/__init__.py @@ -1,3 +1,3 @@ -# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from . import ir_rule +from . import base diff --git a/onchange_helper/models/ir_rule.py b/onchange_helper/models/base.py similarity index 77% rename from onchange_helper/models/ir_rule.py rename to onchange_helper/models/base.py index b4f67af16..fdc0457a3 100644 --- a/onchange_helper/models/ir_rule.py +++ b/onchange_helper/models/base.py @@ -1,7 +1,6 @@ -# -*- 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). +# Copyright 2016-2017 Akretion (http://www.akretion.com) +# Copyright 2016-2017 Camptocamp (http://www.camptocamp.com/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import api, models @@ -9,7 +8,7 @@ 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(): + for fieldname, value in vals.items(): if fieldname not in record: column = model._fields[fieldname] if value and column.type == 'many2one': @@ -38,15 +37,15 @@ def play_onchanges(self, values, onchange_fields): 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() + res = {f: v for f, v in all_values.items() if f in values or f in new_values} return res -class IrRule(models.Model): - _inherit = 'ir.rule' +class Base(models.AbstractModel): + _inherit = 'base' def _setup_complete(self): if not hasattr(models.BaseModel, 'play_onchanges'): setattr(models.BaseModel, 'play_onchanges', play_onchanges) - return super(IrRule, self)._setup_complete() + return super(Base, self)._setup_complete() diff --git a/onchange_helper/tests/__init__.py b/onchange_helper/tests/__init__.py new file mode 100644 index 000000000..806c1a0d6 --- /dev/null +++ b/onchange_helper/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_onchange_helper diff --git a/onchange_helper/tests/test_onchange_helper.py b/onchange_helper/tests/test_onchange_helper.py new file mode 100644 index 000000000..adcff2c1a --- /dev/null +++ b/onchange_helper/tests/test_onchange_helper.py @@ -0,0 +1,28 @@ +# Copyright 2017 Onestein () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests.common import TransactionCase + + +class TestOnchangeHelper(TransactionCase): + + def test01_partner_parent(self): + main_partner = self.env.ref('base.main_partner') + input_vals = dict(partner_id=main_partner.id) + updated_vals = self.env['res.partner'].play_onchanges( + input_vals, + ['parent_id'] + ) + self.assertIn('commercial_partner_id', updated_vals) + self.assertIn('display_name', updated_vals) + self.assertIn('partner_id', updated_vals) + + def test02_partner_country(self): + partner_demo = self.env.ref('base.partner_demo') + input_vals = {'partner_id': partner_demo.id} + updated_vals = self.env['res.partner'].play_onchanges( + input_vals, + ['country_id'] + ) + self.assertIn('contact_address', updated_vals) + self.assertIn('partner_id', updated_vals) From a21c8f8e0d79769f142ea854c62abddbbb54e5f3 Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Sat, 3 Mar 2018 13:37:30 +0100 Subject: [PATCH 06/45] OCA Transbot updated translations from Transifex --- onchange_helper/i18n/cs_CZ.po | 24 ++++++++++++++++++++++++ onchange_helper/i18n/es.po | 16 ++++++++-------- onchange_helper/i18n/fr.po | 24 ++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 onchange_helper/i18n/cs_CZ.po create mode 100644 onchange_helper/i18n/fr.po diff --git a/onchange_helper/i18n/cs_CZ.po b/onchange_helper/i18n/cs_CZ.po new file mode 100644 index 000000000..ad91d04fb --- /dev/null +++ b/onchange_helper/i18n/cs_CZ.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +# Translators: +# Lukáš Spurný , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-03-03 10:08+0000\n" +"PO-Revision-Date: 2018-03-03 10:08+0000\n" +"Last-Translator: Lukáš Spurný , 2018\n" +"Language-Team: Czech (Czech Republic) (https://www.transifex.com/oca/teams/23907/cs_CZ/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: cs_CZ\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_base +msgid "base" +msgstr "základny" diff --git a/onchange_helper/i18n/es.po b/onchange_helper/i18n/es.po index cf06c4ea0..da27dcc96 100644 --- a/onchange_helper/i18n/es.po +++ b/onchange_helper/i18n/es.po @@ -3,14 +3,14 @@ # * onchange_helper # # Translators: -# Fernando Lara , 2017 +# enjolras , 2018 msgid "" msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" +"Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-01 14:59+0000\n" -"PO-Revision-Date: 2017-06-01 14:59+0000\n" -"Last-Translator: Fernando Lara , 2017\n" +"POT-Creation-Date: 2018-03-03 10:08+0000\n" +"PO-Revision-Date: 2018-03-03 10:08+0000\n" +"Last-Translator: enjolras , 2018\n" "Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,6 +19,6 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: onchange_helper -#: model:ir.model,name:onchange_helper.model_ir_rule -msgid "ir.rule" -msgstr "ir.regla" +#: model:ir.model,name:onchange_helper.model_base +msgid "base" +msgstr "base" diff --git a/onchange_helper/i18n/fr.po b/onchange_helper/i18n/fr.po new file mode 100644 index 000000000..7b7765b65 --- /dev/null +++ b/onchange_helper/i18n/fr.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +# Translators: +# Quentin THEURET , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-03-03 10:08+0000\n" +"PO-Revision-Date: 2018-03-03 10:08+0000\n" +"Last-Translator: Quentin THEURET , 2018\n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_base +msgid "base" +msgstr "base" From 696ae8776c840740deeb13bfedda0795d3ba2879 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Sun, 17 Jun 2018 20:50:53 +0000 Subject: [PATCH 07/45] [UPD] Update onchange_helper.pot --- onchange_helper/i18n/cs_CZ.po | 7 ++++--- onchange_helper/i18n/de.po | 13 ++++++++----- onchange_helper/i18n/es.po | 4 ++-- onchange_helper/i18n/fr.po | 4 ++-- onchange_helper/i18n/hr.po | 16 ++++++++++------ onchange_helper/i18n/onchange_helper.pot | 20 ++++++++++++++++++++ onchange_helper/i18n/sl.po | 16 ++++++++++------ 7 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 onchange_helper/i18n/onchange_helper.pot diff --git a/onchange_helper/i18n/cs_CZ.po b/onchange_helper/i18n/cs_CZ.po index ad91d04fb..cadc8d529 100644 --- a/onchange_helper/i18n/cs_CZ.po +++ b/onchange_helper/i18n/cs_CZ.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * onchange_helper -# +# # Translators: # Lukáš Spurný , 2018 msgid "" @@ -11,11 +11,12 @@ msgstr "" "POT-Creation-Date: 2018-03-03 10:08+0000\n" "PO-Revision-Date: 2018-03-03 10:08+0000\n" "Last-Translator: Lukáš Spurný , 2018\n" -"Language-Team: Czech (Czech Republic) (https://www.transifex.com/oca/teams/23907/cs_CZ/)\n" +"Language-Team: Czech (Czech Republic) (https://www.transifex.com/oca/" +"teams/23907/cs_CZ/)\n" +"Language: cs_CZ\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: cs_CZ\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #. module: onchange_helper diff --git a/onchange_helper/i18n/de.po b/onchange_helper/i18n/de.po index e47759dbe..b68ea6efa 100644 --- a/onchange_helper/i18n/de.po +++ b/onchange_helper/i18n/de.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * onchange_helper -# +# # Translators: # Niki Waibel , 2017 msgid "" @@ -12,13 +12,16 @@ msgstr "" "PO-Revision-Date: 2017-06-01 14:59+0000\n" "Last-Translator: Niki Waibel , 2017\n" "Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" +"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: onchange_helper -#: model:ir.model,name:onchange_helper.model_ir_rule -msgid "ir.rule" -msgstr "ir.rule" +#: model:ir.model,name:onchange_helper.model_base +msgid "base" +msgstr "" + +#~ msgid "ir.rule" +#~ msgstr "ir.rule" diff --git a/onchange_helper/i18n/es.po b/onchange_helper/i18n/es.po index da27dcc96..36b629cc9 100644 --- a/onchange_helper/i18n/es.po +++ b/onchange_helper/i18n/es.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * onchange_helper -# +# # Translators: # enjolras , 2018 msgid "" @@ -12,10 +12,10 @@ msgstr "" "PO-Revision-Date: 2018-03-03 10:08+0000\n" "Last-Translator: enjolras , 2018\n" "Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. module: onchange_helper diff --git a/onchange_helper/i18n/fr.po b/onchange_helper/i18n/fr.po index 7b7765b65..56625a21d 100644 --- a/onchange_helper/i18n/fr.po +++ b/onchange_helper/i18n/fr.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * onchange_helper -# +# # Translators: # Quentin THEURET , 2018 msgid "" @@ -12,10 +12,10 @@ msgstr "" "PO-Revision-Date: 2018-03-03 10:08+0000\n" "Last-Translator: Quentin THEURET , 2018\n" "Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. module: onchange_helper diff --git a/onchange_helper/i18n/hr.po b/onchange_helper/i18n/hr.po index b6c316ce2..f05aade44 100644 --- a/onchange_helper/i18n/hr.po +++ b/onchange_helper/i18n/hr.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * onchange_helper -# +# # Translators: # OCA Transbot , 2017 msgid "" @@ -12,13 +12,17 @@ msgstr "" "PO-Revision-Date: 2017-06-01 14:59+0000\n" "Last-Translator: OCA Transbot , 2017\n" "Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n" +"Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: hr\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" #. module: onchange_helper -#: model:ir.model,name:onchange_helper.model_ir_rule -msgid "ir.rule" -msgstr "ir.rule" +#: model:ir.model,name:onchange_helper.model_base +msgid "base" +msgstr "" + +#~ msgid "ir.rule" +#~ msgstr "ir.rule" diff --git a/onchange_helper/i18n/onchange_helper.pot b/onchange_helper/i18n/onchange_helper.pot new file mode 100644 index 000000000..720754925 --- /dev/null +++ b/onchange_helper/i18n/onchange_helper.pot @@ -0,0 +1,20 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_base +msgid "base" +msgstr "" + diff --git a/onchange_helper/i18n/sl.po b/onchange_helper/i18n/sl.po index 3b8f6692f..dafa549a7 100644 --- a/onchange_helper/i18n/sl.po +++ b/onchange_helper/i18n/sl.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * onchange_helper -# +# # Translators: # OCA Transbot , 2017 msgid "" @@ -12,13 +12,17 @@ msgstr "" "PO-Revision-Date: 2017-06-01 14:59+0000\n" "Last-Translator: OCA Transbot , 2017\n" "Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" +"Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Language: sl\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" +"%100==4 ? 2 : 3);\n" #. module: onchange_helper -#: model:ir.model,name:onchange_helper.model_ir_rule -msgid "ir.rule" -msgstr "ir.rule" +#: model:ir.model,name:onchange_helper.model_base +msgid "base" +msgstr "" + +#~ msgid "ir.rule" +#~ msgstr "ir.rule" From 0a110c033e4d3cf7951f96823e38e695e4e98ea9 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 17 Dec 2018 15:42:03 +0100 Subject: [PATCH 08/45] [12.0][MIG] - onchange_helper migration to 12.0 --- onchange_helper/__manifest__.py | 2 +- onchange_helper/readme/CONTRIBUTORS.rst | 3 +++ onchange_helper/readme/DESCRIPTION.rst | 1 + onchange_helper/readme/USAGE.rst | 12 ++++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 onchange_helper/readme/CONTRIBUTORS.rst create mode 100644 onchange_helper/readme/DESCRIPTION.rst create mode 100644 onchange_helper/readme/USAGE.rst diff --git a/onchange_helper/__manifest__.py b/onchange_helper/__manifest__.py index 82f03bcc1..993f7bc7b 100644 --- a/onchange_helper/__manifest__.py +++ b/onchange_helper/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). {'name': 'Onchange Helper', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'summary': 'Technical module that ease execution of onchange in Python code', 'author': 'Akretion,Camptocamp,Odoo Community Association (OCA)', 'website': 'https://github.com/OCA/server-tools', diff --git a/onchange_helper/readme/CONTRIBUTORS.rst b/onchange_helper/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..85d5fd7e1 --- /dev/null +++ b/onchange_helper/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Guewen Baconnier +* Florian da Costa +* Andrea Stirpe \ No newline at end of file diff --git a/onchange_helper/readme/DESCRIPTION.rst b/onchange_helper/readme/DESCRIPTION.rst new file mode 100644 index 000000000..012f36c6f --- /dev/null +++ b/onchange_helper/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This is a technical module. Its goal is to ease the play of onchange method directly called from Python code. \ No newline at end of file diff --git a/onchange_helper/readme/USAGE.rst b/onchange_helper/readme/USAGE.rst new file mode 100644 index 000000000..183b6e728 --- /dev/null +++ b/onchange_helper/readme/USAGE.rst @@ -0,0 +1,12 @@ +To use this module, you need to: + +* depend on this module +* call `yourmodel.play_onchanges(values, ['field'])` + +Example if you want to create a sale order and you want to get the values relative to partner_id field (as if you fill the field from UI) + + `vals = {'partner_id': 1}` + + `vals = self.env['sale.order'].play_onchanges(vals, ['partner_id'])` + +Then, `vals` will be updated with partner_invoice_id, partner_shipping_id, pricelist_id, etc... From cdaa68725c724960dde3ec7ca0501255b1871735 Mon Sep 17 00:00:00 2001 From: sebastienbeau Date: Mon, 17 Dec 2018 18:31:30 +0100 Subject: [PATCH 09/45] [FWP] - Forward porting changes from #1253 --- onchange_helper/__manifest__.py | 21 ++--- onchange_helper/models/base.py | 82 +++++++++---------- onchange_helper/readme/USAGE.rst | 10 +++ onchange_helper/tests/test_onchange_helper.py | 25 ++++-- 4 files changed, 82 insertions(+), 56 deletions(-) diff --git a/onchange_helper/__manifest__.py b/onchange_helper/__manifest__.py index 993f7bc7b..d220bd481 100644 --- a/onchange_helper/__manifest__.py +++ b/onchange_helper/__manifest__.py @@ -1,13 +1,14 @@ # Copyright 2016-2017 Akretion (http://www.akretion.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -{'name': 'Onchange Helper', - 'version': '12.0.1.0.0', - 'summary': 'Technical module that ease execution of onchange in Python code', - 'author': 'Akretion,Camptocamp,Odoo Community Association (OCA)', - 'website': 'https://github.com/OCA/server-tools', - 'license': 'AGPL-3', - 'category': 'Generic Modules', - 'depends': ['base'], - 'installable': True, - } +{ + 'name': 'Onchange Helper', + 'version': '12.0.1.0.0', + 'summary': 'Technical module that ease execution of onchange in Python code', + 'author': 'Akretion,Camptocamp,Odoo Community Association (OCA)', + 'website': 'https://github.com/OCA/server-tools', + 'license': 'AGPL-3', + 'category': 'Generic Modules', + 'depends': ['base'], + 'installable': True, +} diff --git a/onchange_helper/models/base.py b/onchange_helper/models/base.py index fdc0457a3..d0823dbb0 100644 --- a/onchange_helper/models/base.py +++ b/onchange_helper/models/base.py @@ -5,47 +5,47 @@ 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.items(): - 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: - all_values[field] = False - - # 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.items() - if f in values or f in new_values} - return res - - class Base(models.AbstractModel): _inherit = 'base' - def _setup_complete(self): - if not hasattr(models.BaseModel, 'play_onchanges'): - setattr(models.BaseModel, 'play_onchanges', play_onchanges) - return super(Base, self)._setup_complete() + @api.model + def _get_new_values(self, record, on_change_result): + vals = on_change_result.get('value', {}) + new_values = {} + for fieldname, value in vals.items(): + 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 + + @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() + # 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._convert_to_write(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.items() + if not self._fields[f].compute and (f in values or f in new_values) + } diff --git a/onchange_helper/readme/USAGE.rst b/onchange_helper/readme/USAGE.rst index 183b6e728..82a4c163f 100644 --- a/onchange_helper/readme/USAGE.rst +++ b/onchange_helper/readme/USAGE.rst @@ -10,3 +10,13 @@ Example if you want to create a sale order and you want to get the values relati `vals = self.env['sale.order'].play_onchanges(vals, ['partner_id'])` Then, `vals` will be updated with partner_invoice_id, partner_shipping_id, pricelist_id, etc... + +You can also use it on existing record for example: + + `vals = {'partner_shipping_id': 1}` + + `vals = sale.play_onchanges(vals, ['partner_shipping_id'])` + +Then the onchange will be played with the vals passed and the existing vals of the sale. `vals` will be updated with partner_invoice_id, pricelist_id, etc.. + +Behind the scene, `play_onchanges` will execute **all the methods** registered for the list of changed fields, so you do not have to call manually each onchange. To avoid performance issue when the method is called on a record, the record will be transformed into a memory record before calling the registered methods to avoid to trigger SQL updates command when values are assigned to the record by the onchange diff --git a/onchange_helper/tests/test_onchange_helper.py b/onchange_helper/tests/test_onchange_helper.py index adcff2c1a..848da864c 100644 --- a/onchange_helper/tests/test_onchange_helper.py +++ b/onchange_helper/tests/test_onchange_helper.py @@ -5,13 +5,11 @@ from odoo.tests.common import TransactionCase class TestOnchangeHelper(TransactionCase): - def test01_partner_parent(self): main_partner = self.env.ref('base.main_partner') input_vals = dict(partner_id=main_partner.id) updated_vals = self.env['res.partner'].play_onchanges( - input_vals, - ['parent_id'] + input_vals, ['parent_id'] ) self.assertIn('commercial_partner_id', updated_vals) self.assertIn('display_name', updated_vals) @@ -21,8 +19,25 @@ class TestOnchangeHelper(TransactionCase): partner_demo = self.env.ref('base.partner_demo') input_vals = {'partner_id': partner_demo.id} updated_vals = self.env['res.partner'].play_onchanges( - input_vals, - ['country_id'] + input_vals, ['country_id'] ) self.assertIn('contact_address', updated_vals) self.assertIn('partner_id', updated_vals) + + 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): + company = self.env.ref('base.main_company') + result = 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', + ) + self.assertEqual(company.email, u'info@yourcompany.example.com') From 5ca2ca87b1c3e7c5f99577fcc0cf1da373de817a Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 17 Dec 2018 18:58:25 +0100 Subject: [PATCH 10/45] [IMP] - Adapt unit tests --- onchange_helper/tests/test_onchange_helper.py | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/onchange_helper/tests/test_onchange_helper.py b/onchange_helper/tests/test_onchange_helper.py index 848da864c..9e746b6b1 100644 --- a/onchange_helper/tests/test_onchange_helper.py +++ b/onchange_helper/tests/test_onchange_helper.py @@ -7,37 +7,30 @@ from odoo.tests.common import TransactionCase class TestOnchangeHelper(TransactionCase): def test01_partner_parent(self): main_partner = self.env.ref('base.main_partner') - input_vals = dict(partner_id=main_partner.id) + input_vals = dict(parent_id=main_partner.id, type='contact') updated_vals = self.env['res.partner'].play_onchanges( input_vals, ['parent_id'] ) - self.assertIn('commercial_partner_id', updated_vals) - self.assertIn('display_name', updated_vals) - self.assertIn('partner_id', updated_vals) + self.assertIn('country_id', updated_vals) + self.assertIn('state_id', updated_vals) + self.assertIn('street', updated_vals) + self.assertIn('zip', updated_vals) + + self.assertEqual( + updated_vals['country_id'], main_partner.country_id.id + ) + self.assertEqual(updated_vals['state_id'], main_partner.state_id.id) + self.assertEqual(updated_vals['street'], main_partner.street) + self.assertEqual(updated_vals['zip'], main_partner.zip) def test02_partner_country(self): partner_demo = self.env.ref('base.partner_demo') - input_vals = {'partner_id': partner_demo.id} - updated_vals = self.env['res.partner'].play_onchanges( - input_vals, ['country_id'] - ) - self.assertIn('contact_address', updated_vals) - self.assertIn('partner_id', updated_vals) + input_vals = {'country_id': self.env.ref('base.us').id} + updated_vals = partner_demo.play_onchanges(input_vals, ['country_id']) + self.assertIn('country_id', updated_vals) 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): - company = self.env.ref('base.main_company') - result = 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', - ) - self.assertEqual(company.email, u'info@yourcompany.example.com') From 66701ea24fd9120643ce873af22463f4b08d84fb Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 17 Dec 2018 19:29:54 +0100 Subject: [PATCH 11/45] [IMP] - read may be harmful to performance --- onchange_helper/__manifest__.py | 3 ++- onchange_helper/models/base.py | 7 ++++++- onchange_helper/readme/CONTRIBUTORS.rst | 2 +- onchange_helper/readme/DESCRIPTION.rst | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/onchange_helper/__manifest__.py b/onchange_helper/__manifest__.py index d220bd481..386ae237e 100644 --- a/onchange_helper/__manifest__.py +++ b/onchange_helper/__manifest__.py @@ -4,7 +4,8 @@ { 'name': 'Onchange Helper', 'version': '12.0.1.0.0', - 'summary': 'Technical module that ease execution of onchange in Python code', + 'summary': 'Technical module that ease execution' + ' of onchange in Python code', 'author': 'Akretion,Camptocamp,Odoo Community Association (OCA)', 'website': 'https://github.com/OCA/server-tools', 'license': 'AGPL-3', diff --git a/onchange_helper/models/base.py b/onchange_helper/models/base.py index d0823dbb0..00d888bb8 100644 --- a/onchange_helper/models/base.py +++ b/onchange_helper/models/base.py @@ -31,7 +31,12 @@ class Base(models.AbstractModel): # If self is an empty record we will have an empty value if self: self.ensure_one() - record_values = self._convert_to_write(self.read()[0]) + record_values = self._convert_to_write( + { + field_name: self[field_name] + for field_name, field in self._fields.items() + } + ) else: record_values = {} for field in self._fields: diff --git a/onchange_helper/readme/CONTRIBUTORS.rst b/onchange_helper/readme/CONTRIBUTORS.rst index 85d5fd7e1..f4084e979 100644 --- a/onchange_helper/readme/CONTRIBUTORS.rst +++ b/onchange_helper/readme/CONTRIBUTORS.rst @@ -1,3 +1,3 @@ * Guewen Baconnier * Florian da Costa -* Andrea Stirpe \ No newline at end of file +* Andrea Stirpe diff --git a/onchange_helper/readme/DESCRIPTION.rst b/onchange_helper/readme/DESCRIPTION.rst index 012f36c6f..23c01a8ef 100644 --- a/onchange_helper/readme/DESCRIPTION.rst +++ b/onchange_helper/readme/DESCRIPTION.rst @@ -1 +1 @@ -This is a technical module. Its goal is to ease the play of onchange method directly called from Python code. \ No newline at end of file +This is a technical module. Its goal is to ease the play of onchange method directly called from Python code. From 9d58c5cd85121271c7bda45c4e5960866928c0e5 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Tue, 18 Dec 2018 17:29:51 +0100 Subject: [PATCH 12/45] [IMP] - get default values for non record onchange call other improvement: set onchange_specs to all fields as _onchange_spec() retrun onchange fields for default view return field value if it's set in onchange_fields (usuful to get default value for a field) --- onchange_helper/models/base.py | 11 ++++++++--- onchange_helper/readme/CONTRIBUTORS.rst | 1 + onchange_helper/readme/USAGE.rst | 11 +++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/onchange_helper/models/base.py b/onchange_helper/models/base.py index 00d888bb8..ad685aad2 100644 --- a/onchange_helper/models/base.py +++ b/onchange_helper/models/base.py @@ -22,9 +22,12 @@ class Base(models.AbstractModel): @api.model def play_onchanges(self, values, onchange_fields): - onchange_specs = self._onchange_spec() + # _onchange_spec() will return onchange fields from the default view # we need all fields in the dict even the empty ones # otherwise 'onchange()' will not apply changes to them + onchange_specs = { + field_name: '1' for field_name, field in self._fields.items() + } all_values = values.copy() # If self is a record (play onchange on existing record) # we take the value of the field @@ -38,7 +41,8 @@ class Base(models.AbstractModel): } ) else: - record_values = {} + # We get default values, they may be used in onchange + record_values = self.default_get(self._fields.keys()) for field in self._fields: if field not in all_values: all_values[field] = record_values.get(field, False) @@ -52,5 +56,6 @@ class Base(models.AbstractModel): return { f: v for f, v in all_values.items() - if not self._fields[f].compute and (f in values or f in new_values) + if not self._fields[f].compute + and (f in values or f in new_values or f in onchange_fields) } diff --git a/onchange_helper/readme/CONTRIBUTORS.rst b/onchange_helper/readme/CONTRIBUTORS.rst index f4084e979..47a0cfe24 100644 --- a/onchange_helper/readme/CONTRIBUTORS.rst +++ b/onchange_helper/readme/CONTRIBUTORS.rst @@ -1,3 +1,4 @@ * Guewen Baconnier * Florian da Costa * Andrea Stirpe +* Souheil Bejaoui diff --git a/onchange_helper/readme/USAGE.rst b/onchange_helper/readme/USAGE.rst index 82a4c163f..e8b5a738c 100644 --- a/onchange_helper/readme/USAGE.rst +++ b/onchange_helper/readme/USAGE.rst @@ -11,6 +11,17 @@ Example if you want to create a sale order and you want to get the values relati Then, `vals` will be updated with partner_invoice_id, partner_shipping_id, pricelist_id, etc... +Default values will be used to process onchange methods, if respective fields are not set in `vals`. +You can get them if you pass fields name in the list of fields. + + + `vals = {'partner_id': 1}` + + `vals = self.env['sale.order'].play_onchanges(vals, ['partner_id', 'date_order'])` + +`vals` will contain, in addition to the changed values, the default value for `date_order` + + You can also use it on existing record for example: `vals = {'partner_shipping_id': 1}` From c920e0e02cad3dd0dbc967337d340e85a28eecd7 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Wed, 19 Dec 2018 16:03:13 +0100 Subject: [PATCH 13/45] [UPD] - Update documentation --- onchange_helper/models/base.py | 8 ++++++++ onchange_helper/readme/USAGE.rst | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/onchange_helper/models/base.py b/onchange_helper/models/base.py index ad685aad2..3863e4424 100644 --- a/onchange_helper/models/base.py +++ b/onchange_helper/models/base.py @@ -22,6 +22,14 @@ class Base(models.AbstractModel): @api.model def play_onchanges(self, values, onchange_fields): + """ + :param values: dict of input value that + :param onchange_fields: fields for which onchange methods will be + played + Order in onchange_fields is very important as onchanges methods will + be played in that order. + :return: changed values + """ # _onchange_spec() will return onchange fields from the default view # we need all fields in the dict even the empty ones # otherwise 'onchange()' will not apply changes to them diff --git a/onchange_helper/readme/USAGE.rst b/onchange_helper/readme/USAGE.rst index e8b5a738c..52da81375 100644 --- a/onchange_helper/readme/USAGE.rst +++ b/onchange_helper/readme/USAGE.rst @@ -31,3 +31,9 @@ You can also use it on existing record for example: Then the onchange will be played with the vals passed and the existing vals of the sale. `vals` will be updated with partner_invoice_id, pricelist_id, etc.. Behind the scene, `play_onchanges` will execute **all the methods** registered for the list of changed fields, so you do not have to call manually each onchange. To avoid performance issue when the method is called on a record, the record will be transformed into a memory record before calling the registered methods to avoid to trigger SQL updates command when values are assigned to the record by the onchange + + +Notes: + +- Order in onchange_fields is very important as onchanges methods will be played in that order. +- If you use memory object in `vals`, be award that onchange method in base model call `self.invalidate_cache()` that reset it. From 396e584f67013d64fdcfe9f58aaf4204bce47ee9 Mon Sep 17 00:00:00 2001 From: Benoit Date: Mon, 21 Jan 2019 14:06:40 +0100 Subject: [PATCH 14/45] [FIX] don't remove computed fields with inverse method of the onchange values --- onchange_helper/models/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onchange_helper/models/base.py b/onchange_helper/models/base.py index 3863e4424..4cc24ca2b 100644 --- a/onchange_helper/models/base.py +++ b/onchange_helper/models/base.py @@ -64,6 +64,6 @@ class Base(models.AbstractModel): return { f: v for f, v in all_values.items() - if not self._fields[f].compute + if not (self._fields[f].compute and not self._fields[f].inverse) and (f in values or f in new_values or f in onchange_fields) } From edba54888ad62e7524015e0dd9adf2804193e006 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 14 May 2019 07:21:16 +0000 Subject: [PATCH 15/45] [UPD] README.rst --- onchange_helper/README.rst | 91 +++- onchange_helper/static/description/index.html | 457 ++++++++++++++++++ 2 files changed, 531 insertions(+), 17 deletions(-) create mode 100644 onchange_helper/static/description/index.html diff --git a/onchange_helper/README.rst b/onchange_helper/README.rst index 622fbe8dd..6912994bf 100644 --- a/onchange_helper/README.rst +++ b/onchange_helper/README.rst @@ -1,13 +1,37 @@ -.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png - :target: https://www.gnu.org/licenses/agpl - :alt: License: AGPL-3 - =============== Onchange Helper =============== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/12.0/onchange_helper + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-12-0/server-tools-12-0-onchange_helper + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/149/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + This is a technical module. Its goal is to ease the play of onchange method directly called from Python code. +**Table of contents** + +.. contents:: + :local: + Usage ===== @@ -24,40 +48,73 @@ Example if you want to create a sale order and you want to get the values relati Then, `vals` will be updated with partner_invoice_id, partner_shipping_id, pricelist_id, etc... +Default values will be used to process onchange methods, if respective fields are not set in `vals`. +You can get them if you pass fields name in the list of fields. + + + `vals = {'partner_id': 1}` + + `vals = self.env['sale.order'].play_onchanges(vals, ['partner_id', 'date_order'])` + +`vals` will contain, in addition to the changed values, the default value for `date_order` + + +You can also use it on existing record for example: + + `vals = {'partner_shipping_id': 1}` + + `vals = sale.play_onchanges(vals, ['partner_shipping_id'])` + +Then the onchange will be played with the vals passed and the existing vals of the sale. `vals` will be updated with partner_invoice_id, pricelist_id, etc.. + +Behind the scene, `play_onchanges` will execute **all the methods** registered for the list of changed fields, so you do not have to call manually each onchange. To avoid performance issue when the method is called on a record, the record will be transformed into a memory record before calling the registered methods to avoid to trigger SQL updates command when values are assigned to the record by the onchange + + +Notes: + +- Order in onchange_fields is very important as onchanges methods will be played in that order. +- If you use memory object in `vals`, be award that onchange method in base model call `self.invalidate_cache()` that reset it. + Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. In case of trouble, please -check there if your issue has already been reported. If you spotted it first, -help us smashing it by providing a detailed and welcomed feedback. +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= -Images ------- +Authors +~~~~~~~ -* Odoo Community Association: `Icon `_. +* Akretion +* Camptocamp Contributors ------------- +~~~~~~~~~~~~ * Guewen Baconnier * Florian da Costa * Andrea Stirpe +* Souheil Bejaoui -Maintainer ----------- +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/onchange_helper/static/description/index.html b/onchange_helper/static/description/index.html new file mode 100644 index 000000000..17f76257b --- /dev/null +++ b/onchange_helper/static/description/index.html @@ -0,0 +1,457 @@ + + + + + + +Onchange Helper + + + +
+

Onchange Helper

+ + +

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

This is a technical module. Its goal is to ease the play of onchange method directly called from Python code.

+

Table of contents

+ +
+

Usage

+

To use this module, you need to:

+
    +
  • depend on this module
  • +
  • call yourmodel.play_onchanges(values, [‘field’])
  • +
+

Example if you want to create a sale order and you want to get the values relative to partner_id field (as if you fill the field from UI)

+
+

vals = {‘partner_id’: 1}

+

vals = self.env[‘sale.order’].play_onchanges(vals, [‘partner_id’])

+
+

Then, vals will be updated with partner_invoice_id, partner_shipping_id, pricelist_id, etc…

+

Default values will be used to process onchange methods, if respective fields are not set in vals. +You can get them if you pass fields name in the list of fields.

+
+

vals = {‘partner_id’: 1}

+

vals = self.env[‘sale.order’].play_onchanges(vals, [‘partner_id’, ‘date_order’])

+
+

vals will contain, in addition to the changed values, the default value for date_order

+

You can also use it on existing record for example:

+
+

vals = {‘partner_shipping_id’: 1}

+

vals = sale.play_onchanges(vals, [‘partner_shipping_id’])

+
+

Then the onchange will be played with the vals passed and the existing vals of the sale. vals will be updated with partner_invoice_id, pricelist_id, etc..

+

Behind the scene, play_onchanges will execute all the methods registered for the list of changed fields, so you do not have to call manually each onchange. To avoid performance issue when the method is called on a record, the record will be transformed into a memory record before calling the registered methods to avoid to trigger SQL updates command when values are assigned to the record by the onchange

+

Notes:

+
    +
  • Order in onchange_fields is very important as onchanges methods will be played in that order.
  • +
  • If you use memory object in vals, be award that onchange method in base model call self.invalidate_cache() that reset it.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/server-tools project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + From 72b9548af18e136c19781b9222244d099abcab7b Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 14 May 2019 07:21:16 +0000 Subject: [PATCH 16/45] [ADD] icon.png --- onchange_helper/static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 onchange_helper/static/description/icon.png diff --git a/onchange_helper/static/description/icon.png b/onchange_helper/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From 9f2e4223f269504b9a20e28241c5164daae592c7 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Tue, 14 May 2019 07:27:39 +0000 Subject: [PATCH 17/45] [UPD] Update onchange_helper.pot --- onchange_helper/i18n/onchange_helper.pot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onchange_helper/i18n/onchange_helper.pot b/onchange_helper/i18n/onchange_helper.pot index 720754925..e6fdd889e 100644 --- a/onchange_helper/i18n/onchange_helper.pot +++ b/onchange_helper/i18n/onchange_helper.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 11.0\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: <>\n" "Language-Team: \n" @@ -15,6 +15,6 @@ msgstr "" #. module: onchange_helper #: model:ir.model,name:onchange_helper.model_base -msgid "base" +msgid "Base" msgstr "" From 570c6bccd65c54e16edbc910514c6a9c2057991e Mon Sep 17 00:00:00 2001 From: OCA Transbot Date: Mon, 20 May 2019 21:01:47 +0000 Subject: [PATCH 18/45] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: server-tools-12.0/server-tools-12.0-onchange_helper Translate-URL: https://translation.odoo-community.org/projects/server-tools-12-0/server-tools-12-0-onchange_helper/ --- onchange_helper/i18n/cs_CZ.po | 7 +++++-- onchange_helper/i18n/de.po | 2 +- onchange_helper/i18n/es.po | 7 +++++-- onchange_helper/i18n/fr.po | 7 +++++-- onchange_helper/i18n/hr.po | 2 +- onchange_helper/i18n/sl.po | 2 +- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/onchange_helper/i18n/cs_CZ.po b/onchange_helper/i18n/cs_CZ.po index cadc8d529..d9750ed0d 100644 --- a/onchange_helper/i18n/cs_CZ.po +++ b/onchange_helper/i18n/cs_CZ.po @@ -21,5 +21,8 @@ msgstr "" #. module: onchange_helper #: model:ir.model,name:onchange_helper.model_base -msgid "base" -msgstr "základny" +msgid "Base" +msgstr "" + +#~ msgid "base" +#~ msgstr "základny" diff --git a/onchange_helper/i18n/de.po b/onchange_helper/i18n/de.po index b68ea6efa..d95365cec 100644 --- a/onchange_helper/i18n/de.po +++ b/onchange_helper/i18n/de.po @@ -20,7 +20,7 @@ msgstr "" #. module: onchange_helper #: model:ir.model,name:onchange_helper.model_base -msgid "base" +msgid "Base" msgstr "" #~ msgid "ir.rule" diff --git a/onchange_helper/i18n/es.po b/onchange_helper/i18n/es.po index 36b629cc9..0f9a1126a 100644 --- a/onchange_helper/i18n/es.po +++ b/onchange_helper/i18n/es.po @@ -20,5 +20,8 @@ msgstr "" #. module: onchange_helper #: model:ir.model,name:onchange_helper.model_base -msgid "base" -msgstr "base" +msgid "Base" +msgstr "" + +#~ msgid "base" +#~ msgstr "base" diff --git a/onchange_helper/i18n/fr.po b/onchange_helper/i18n/fr.po index 56625a21d..62e00a1e8 100644 --- a/onchange_helper/i18n/fr.po +++ b/onchange_helper/i18n/fr.po @@ -20,5 +20,8 @@ msgstr "" #. module: onchange_helper #: model:ir.model,name:onchange_helper.model_base -msgid "base" -msgstr "base" +msgid "Base" +msgstr "" + +#~ msgid "base" +#~ msgstr "base" diff --git a/onchange_helper/i18n/hr.po b/onchange_helper/i18n/hr.po index f05aade44..00153b1ea 100644 --- a/onchange_helper/i18n/hr.po +++ b/onchange_helper/i18n/hr.po @@ -21,7 +21,7 @@ msgstr "" #. module: onchange_helper #: model:ir.model,name:onchange_helper.model_base -msgid "base" +msgid "Base" msgstr "" #~ msgid "ir.rule" diff --git a/onchange_helper/i18n/sl.po b/onchange_helper/i18n/sl.po index dafa549a7..89fa57749 100644 --- a/onchange_helper/i18n/sl.po +++ b/onchange_helper/i18n/sl.po @@ -21,7 +21,7 @@ msgstr "" #. module: onchange_helper #: model:ir.model,name:onchange_helper.model_base -msgid "base" +msgid "Base" msgstr "" #~ msgid "ir.rule" From 7a3682596802838b3b4302e701040b30a95e0854 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 29 Jul 2019 03:39:11 +0000 Subject: [PATCH 19/45] [UPD] README.rst --- onchange_helper/static/description/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onchange_helper/static/description/index.html b/onchange_helper/static/description/index.html index 17f76257b..f26fb43ad 100644 --- a/onchange_helper/static/description/index.html +++ b/onchange_helper/static/description/index.html @@ -3,7 +3,7 @@ - + Onchange Helper - - -
-

Onchange Helper

- - -

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

-

This is a technical module. Its goal is to ease the play of onchange -method directly called from Python code.

-

Table of contents

- -
-

Usage

-

To use this module, you need to:

-
    -
  • depend on this module
  • -
  • call yourmodel.play_onchanges(values, [‘field’])
  • -
-

Example if you want to create a sale order and you want to get the -values relative to partner_id field (as if you fill the field from UI)

-
-

vals = {‘partner_id’: 1}

-

vals = self.env[‘sale.order’].play_onchanges(vals, [‘partner_id’])

-
-

Then, vals will be updated with partner_invoice_id, partner_shipping_id, -pricelist_id, etc…

-

Default values will be used to process onchange methods, if respective -fields are not set in vals. You can get them if you pass fields name in -the list of fields.

-
-

vals = {‘partner_id’: 1}

-

vals = self.env[‘sale.order’].play_onchanges(vals, [‘partner_id’, -‘date_order’])

-
-

vals will contain, in addition to the changed values, the default value -for date_order

-

You can also use it on existing record for example:

-
-

vals = {‘partner_shipping_id’: 1}

-

vals = sale.play_onchanges(vals, [‘partner_shipping_id’])

-
-

Then the onchange will be played with the vals passed and the existing -vals of the sale. vals will be updated with partner_invoice_id, -pricelist_id, etc..

-

Behind the scene, play_onchanges will execute all the methods -registered for the list of changed fields, so you do not have to call -manually each onchange. To avoid performance issue when the method is -called on a record, the record will be transformed into a memory record -before calling the registered methods to avoid to trigger SQL updates -command when values are assigned to the record by the onchange

-

Notes:

-
    -
  • Order in onchange_fields is very important as onchanges methods will -be played in that order.
  • -
  • If you use memory object in vals, be award that onchange method in -base model call self.invalidate_cache() that reset it.
  • -
-
-
-

Known issues / Roadmap

-

Note that onchanges tend to disappear due to the introduction of -‘computed stored readonly False fields’ in most cases. When migrating, -it is best to prefer changing it to that way instead of using this -module.

-
-
-

Bug Tracker

-

Bugs are tracked on GitHub Issues. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

-

Do not contact contributors directly about support or help with technical issues.

-
-
-

Credits

-
-

Authors

-
    -
  • Akretion
  • -
  • Camptocamp
  • -
-
-
-

Contributors

- -
-
-

Maintainers

-

This module is maintained by the OCA.

-Odoo Community Association -

OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use.

-

This module is part of the OCA/server-tools project on GitHub.

-

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
-
-
- + + + + Onchange Helper + + + +
+

Onchange Helper

+ + +

+ + Beta + + + License: AGPL-3 + + + OCA/server-tools + + + Translate me on Weblate + + + Try me on Runboat + +

+

This is a technical module. Its goal is to ease the play of onchange + method directly called from Python code. +

+

+ Table of contents +

+
+ +
+
+

+ Usage +

+

To use this module, you need to:

+
    +
  • depend on this module
  • +
  • call yourmodel.play_onchanges(values, [‘field’])
  • +
+

Example if you want to create a sale order and you want to get the + values relative to partner_id field (as if you fill the field from UI) +

+
+

vals = {‘partner_id’: 1}

+

vals = self.env[‘sale.order’].play_onchanges(vals, [‘partner_id’])

+
+

Then, vals will be updated with partner_invoice_id, partner_shipping_id, + pricelist_id, etc… +

+

Default values will be used to process onchange methods, if respective + fields are not set in vals. You can get them if you pass fields name in + the list of fields. +

+
+

vals = {‘partner_id’: 1}

+

vals = self.env[‘sale.order’].play_onchanges(vals, [‘partner_id’, + ‘date_order’]) +

+
+

vals will contain, in addition to the changed values, the default value + for date_order +

+

You can also use it on existing record for example:

+
+

vals = {‘partner_shipping_id’: 1}

+

vals = sale.play_onchanges(vals, [‘partner_shipping_id’])

+
+

Then the onchange will be played with the vals passed and the existing + vals of the sale. vals will be updated with partner_invoice_id, + pricelist_id, etc.. +

+

Behind the scene, play_onchanges will execute + all the methods + registered for the list of changed fields, so you do not have to call + manually each onchange. To avoid performance issue when the method is + called on a record, the record will be transformed into a memory record + before calling the registered methods to avoid to trigger SQL updates + command when values are assigned to the record by the onchange +

+

Notes:

+
    +
  • Order in onchange_fields is very important as onchanges methods will + be played in that order. +
  • +
  • If you use memory object in vals, be award that onchange method in + base model call self.invalidate_cache() that reset it. +
  • +
+
+
+

+ Known issues / Roadmap +

+

Note that onchanges tend to disappear due to the introduction of + ‘computed stored readonly False fields’ in most cases. When migrating, + it is best to prefer changing it to that way instead of using this + module. +

+
+
+

+ Bug Tracker +

+

Bugs are tracked on + GitHub Issues. + In case of trouble, please check there if your issue has already been reported. + If you spotted it first, help us to smash it by providing a detailed and welcomed + + feedback. +

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

+ Credits +

+
+

+ Authors +

+
    +
  • Akretion
  • +
  • Camptocamp
  • +
+
+
+

+ Contributors +

+ +
+
+

+ Maintainers +

+

This module is maintained by the OCA.

+ + Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose + mission is to support the collaborative development of Odoo features and + promote its widespread use. +

+

This module is part of the + OCA/server-tools + + project on GitHub. +

+

You are welcome to contribute. To learn how please visit + https://odoo-community.org/page/Contribute. +

+
+
+
+