diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py
index 3de35a4ae74..535ed4e3847 100644
--- a/addons/base_action_rule/base_action_rule.py
+++ b/addons/base_action_rule/base_action_rule.py
@@ -51,6 +51,7 @@ class base_action_rule(osv.osv):
('on_write', 'On Update'),
('on_create_or_write', 'On Creation & Update'),
('on_unlink', 'On Deletion'),
+ ('on_change', 'Based on Form Modification'),
('on_time', 'Based on Timed Condition')],
string='When to Run'),
'trg_date_id': fields.many2one('ir.model.fields', string='Trigger Date',
@@ -83,6 +84,7 @@ class base_action_rule(osv.osv):
help="If present, this condition must be satisfied before executing the action rule."),
'filter_domain': fields.char(string='Domain', help="If present, this condition must be satisfied before executing the action rule."),
'last_run': fields.datetime('Last Run', readonly=1, copy=False),
+ 'on_change_field_ids' : fields.many2many('ir.model.fields', domain="[('model_id', '=', model_id)]", string="On Change Fields Trigger"),
}
_defaults = {
@@ -148,6 +150,29 @@ class base_action_rule(osv.osv):
return True
+ @openerp.api.multi
+ def _register_onchange(self):
+ def make_onchange(action_rule_id):
+ def base_action_rule_onchange(self):
+ action_rule = self.env['base.action.rule'].search([('id', '=', action_rule_id)])
+ if not action_rule:
+ return
+ server_actions = action_rule.server_action_ids.with_context(active_model=self._name, onchange_self=self)
+ vals = {}
+ for server_action in server_actions:
+ res = server_action.run()
+ vals.update(res and res.get('value') or {})
+ vals.pop('id', None)
+ self.update(self._convert_to_cache(vals, validate=False))
+ return base_action_rule_onchange
+
+ for action_rule in self:
+ if action_rule.kind != 'on_change':
+ continue
+ model = self.env[action_rule.model_id.model]
+ for field in action_rule.on_change_field_ids:
+ model._onchange_methods[field.name].append(make_onchange(action_rule.id))
+
def _register_hook(self, cr, ids=None):
""" Wrap the methods `create` and `write` of the models specified by
the rules given by `ids` (or all existing rules if `ids` is `None`.)
@@ -256,6 +281,7 @@ class base_action_rule(osv.osv):
updated = False
if ids is None:
ids = self.search(cr, SUPERUSER_ID, [])
+ self._register_onchange(cr, SUPERUSER_ID, ids)
for action_rule in self.browse(cr, SUPERUSER_ID, ids):
model = action_rule.model_id.model
model_obj = self.pool.get(model)
@@ -278,6 +304,15 @@ class base_action_rule(osv.osv):
return cron.toggle(model=self._name, domain=[('kind', '=', 'on_time')])
+ @openerp.api.one
+ def _purge_custom_onchange(self):
+ if self.kind != 'on_change':
+ return
+ model = self.env[self.model_id.model]
+ for field in self.on_change_field_ids:
+ if model._onchange_methods.get(field.name):
+ model._onchange_methods[field.name] = [method for method in model._onchange_methods[field.name] if method.func_name != 'base_action_rule_onchange']
+
def create(self, cr, uid, vals, context=None):
res_id = super(base_action_rule, self).create(cr, uid, vals, context=context)
if self._register_hook(cr, [res_id]):
@@ -288,6 +323,7 @@ class base_action_rule(osv.osv):
def write(self, cr, uid, ids, vals, context=None):
if isinstance(ids, (int, long)):
ids = [ids]
+ self._purge_custom_onchange(cr, uid, ids, context=context)
super(base_action_rule, self).write(cr, uid, ids, vals, context=context)
if self._register_hook(cr, ids):
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
@@ -300,7 +336,7 @@ class base_action_rule(osv.osv):
return res
def onchange_model_id(self, cr, uid, ids, model_id, context=None):
- data = {'model': False, 'filter_pre_id': False, 'filter_id': False}
+ data = {'model': False, 'filter_pre_id': False, 'filter_id': False, 'on_change_field_ids': False}
if model_id:
model = self.pool.get('ir.model').browse(cr, uid, model_id, context=context)
data.update({'model': model.model})
diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml
index 8e5ac4a651c..71f3137006d 100644
--- a/addons/base_action_rule/base_action_rule_view.xml
+++ b/addons/base_action_rule/base_action_rule_view.xml
@@ -46,6 +46,8 @@
class="oe_inline" context="{'default_model_id': model}"
on_change="onchange_filter_id(filter_id, context)"/>
+