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)