diff --git a/onchange_helper/README.rst b/onchange_helper/README.rst new file mode 100644 index 00000000000..772fe2b8aad --- /dev/null +++ b/onchange_helper/README.rst @@ -0,0 +1,151 @@ +=============== +Onchange Helper +=============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:f99de3ee6c925e95e76870bbc84e80cfeb2842ff3e1e71af1f2bd17deeb935b6 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/18.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-18-0/server-tools-18-0-onchange_helper + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=18.0 + :alt: Try me on Runboat + +|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 +===== + +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 +------------ + +- Guewen Baconnier +- Florian da Costa +- Andrea Stirpe +- Souheil Bejaoui +- Kevin Khao +- Thien Vo + +Other credits +------------- + +The migration of this module from 17.0 to 18.0 was financially supported +by Camptocamp. + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. diff --git a/onchange_helper/__init__.py b/onchange_helper/__init__.py new file mode 100644 index 00000000000..fba73faa98f --- /dev/null +++ b/onchange_helper/__init__.py @@ -0,0 +1,3 @@ +# License LGPL-3 or later (https://www.gnu.org/licenses/agpl). + +from . import models diff --git a/onchange_helper/__manifest__.py b/onchange_helper/__manifest__.py new file mode 100644 index 00000000000..1da3b552682 --- /dev/null +++ b/onchange_helper/__manifest__.py @@ -0,0 +1,14 @@ +# Copyright 2016-2017 Akretion (http://www.akretion.com) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Onchange Helper", + "version": "18.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": "LGPL-3", + "category": "Generic Modules", + "depends": ["web"], + "installable": True, +} diff --git a/onchange_helper/i18n/cs_CZ.po b/onchange_helper/i18n/cs_CZ.po new file mode 100644 index 00000000000..d9750ed0d0c --- /dev/null +++ b/onchange_helper/i18n/cs_CZ.po @@ -0,0 +1,28 @@ +# 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" +"Language: cs_CZ\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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 "" + +#~ msgid "base" +#~ msgstr "základny" diff --git a/onchange_helper/i18n/de.po b/onchange_helper/i18n/de.po new file mode 100644 index 00000000000..d95365cec5e --- /dev/null +++ b/onchange_helper/i18n/de.po @@ -0,0 +1,27 @@ +# 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" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: onchange_helper +#: 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 new file mode 100644 index 00000000000..ffe5b496010 --- /dev/null +++ b/onchange_helper/i18n/es.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +# Translators: +# enjolras , 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: 2023-09-03 00:15+0000\n" +"Last-Translator: Ivorra78 \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" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_base +msgid "Base" +msgstr "Base" + +#~ msgid "base" +#~ msgstr "base" diff --git a/onchange_helper/i18n/es_AR.po b/onchange_helper/i18n/es_AR.po new file mode 100644 index 00000000000..b53c529833f --- /dev/null +++ b/onchange_helper/i18n/es_AR.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-09-04 06:07+0000\n" +"Last-Translator: Ignacio Buioli \n" +"Language-Team: none\n" +"Language: es_AR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: onchange_helper +#: 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 00000000000..62e00a1e8a5 --- /dev/null +++ b/onchange_helper/i18n/fr.po @@ -0,0 +1,27 @@ +# 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" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_base +msgid "Base" +msgstr "" + +#~ msgid "base" +#~ msgstr "base" diff --git a/onchange_helper/i18n/hr.po b/onchange_helper/i18n/hr.po new file mode 100644 index 00000000000..00153b1ea8d --- /dev/null +++ b/onchange_helper/i18n/hr.po @@ -0,0 +1,28 @@ +# 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" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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_base +msgid "Base" +msgstr "" + +#~ msgid "ir.rule" +#~ msgstr "ir.rule" diff --git a/onchange_helper/i18n/it.po b/onchange_helper/i18n/it.po new file mode 100644 index 00000000000..35694b0478e --- /dev/null +++ b/onchange_helper/i18n/it.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-02 16:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_base +msgid "Base" +msgstr "Base" diff --git a/onchange_helper/i18n/onchange_helper.pot b/onchange_helper/i18n/onchange_helper.pot new file mode 100644 index 00000000000..718920f908d --- /dev/null +++ b/onchange_helper/i18n/onchange_helper.pot @@ -0,0 +1,19 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.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 new file mode 100644 index 00000000000..89fa577492e --- /dev/null +++ b/onchange_helper/i18n/sl.po @@ -0,0 +1,28 @@ +# 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" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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_base +msgid "Base" +msgstr "" + +#~ msgid "ir.rule" +#~ msgstr "ir.rule" diff --git a/onchange_helper/i18n/zh_CN.po b/onchange_helper/i18n/zh_CN.po new file mode 100644 index 00000000000..96db974b061 --- /dev/null +++ b/onchange_helper/i18n/zh_CN.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * onchange_helper +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-08-31 06:18+0000\n" +"Last-Translator: 黎伟杰 <674416404@qq.com>\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.8\n" + +#. module: onchange_helper +#: model:ir.model,name:onchange_helper.model_base +msgid "Base" +msgstr "基础" diff --git a/onchange_helper/models/__init__.py b/onchange_helper/models/__init__.py new file mode 100644 index 00000000000..13153347d37 --- /dev/null +++ b/onchange_helper/models/__init__.py @@ -0,0 +1,3 @@ +# License LGPL-3 or later (https://www.gnu.org/licenses/agpl). + +from . import base diff --git a/onchange_helper/models/base.py b/onchange_helper/models/base.py new file mode 100644 index 00000000000..7f99640f164 --- /dev/null +++ b/onchange_helper/models/base.py @@ -0,0 +1,73 @@ +# Copyright 2016-2017 Akretion (http://www.akretion.com) +# Copyright 2016-2017 Camptocamp (http://www.camptocamp.com/) +# License LGPL-3 or later (https://www.gnu.org/licenses/agpl). + +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.items(): + if fieldname not in record: + column = self._fields[fieldname] + if value and column.type == "many2one": + value = value["id"] + new_values[fieldname] = value + return new_values + + @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 + onchange_specs = self._get_fields_spec() + 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( + { + field_name: self[field_name] + for field_name, field in self._fields.items() + } + ) + else: + # 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) + + new_values = {} + for field in [ + field for field in onchange_fields if field in self._onchange_methods + ]: + 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 not self._fields[f].inverse + and self._fields[f].readonly + ) + and (f in values or f in new_values or f in onchange_fields) + } diff --git a/onchange_helper/pyproject.toml b/onchange_helper/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/onchange_helper/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/onchange_helper/readme/CONTRIBUTORS.md b/onchange_helper/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..12d1c0ae40d --- /dev/null +++ b/onchange_helper/readme/CONTRIBUTORS.md @@ -0,0 +1,6 @@ +- Guewen Baconnier \<\> +- Florian da Costa \<\> +- Andrea Stirpe \<\> +- Souheil Bejaoui \<\> +- Kevin Khao \<\> +- Thien Vo \<\> diff --git a/onchange_helper/readme/CREDITS.md b/onchange_helper/readme/CREDITS.md new file mode 100644 index 00000000000..83b3ec91f7d --- /dev/null +++ b/onchange_helper/readme/CREDITS.md @@ -0,0 +1 @@ +The migration of this module from 17.0 to 18.0 was financially supported by Camptocamp. diff --git a/onchange_helper/readme/DESCRIPTION.md b/onchange_helper/readme/DESCRIPTION.md new file mode 100644 index 00000000000..a82344a3c5c --- /dev/null +++ b/onchange_helper/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This is a technical module. Its goal is to ease the play of onchange +method directly called from Python code. diff --git a/onchange_helper/readme/ROADMAP.md b/onchange_helper/readme/ROADMAP.md new file mode 100644 index 00000000000..9d7a6909dcb --- /dev/null +++ b/onchange_helper/readme/ROADMAP.md @@ -0,0 +1,4 @@ +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. diff --git a/onchange_helper/readme/USAGE.md b/onchange_helper/readme/USAGE.md new file mode 100644 index 00000000000..8caac08e458 --- /dev/null +++ b/onchange_helper/readme/USAGE.md @@ -0,0 +1,50 @@ +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. diff --git a/onchange_helper/static/description/icon.png b/onchange_helper/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/onchange_helper/static/description/icon.png differ diff --git a/onchange_helper/static/description/index.html b/onchange_helper/static/description/index.html new file mode 100644 index 00000000000..a9b805520be --- /dev/null +++ b/onchange_helper/static/description/index.html @@ -0,0 +1,492 @@ + + + + + +Onchange Helper + + + +
+

Onchange Helper

+ + +

Beta License: LGPL-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

+ +
+
+

Other credits

+

The migration of this module from 17.0 to 18.0 was financially supported +by Camptocamp.

+
+
+

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.

+
+
+
+ + diff --git a/onchange_helper/tests/__init__.py b/onchange_helper/tests/__init__.py new file mode 100644 index 00000000000..d0c83108e78 --- /dev/null +++ b/onchange_helper/tests/__init__.py @@ -0,0 +1,3 @@ +# License LGPL-3 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 00000000000..f1c8610bd08 --- /dev/null +++ b/onchange_helper/tests/test_onchange_helper.py @@ -0,0 +1,32 @@ +# Copyright 2017 Onestein () +# License LGPL-3 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(parent_id=main_partner.id, type="contact") + updated_vals = self.env["res.partner"].play_onchanges(input_vals, ["parent_id"]) + 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 = {"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)