[FIX] base_automation: actions triggered by a field computed with other fields
The issue is the following: if both fields F1 and F2 are computed by the same compute method, actions based on changes on F1 may not be triggered when F2 forces their recomputation. This is caused by the API of the method `_compute_field_value` that takes as parameter the field that triggered the recomputation. The method must consider all the fields computed by the method. closes odoo/odoo#39440 X-original-commit: ceddb710a17e552061b9ad3cbc2647d7eae6567d Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
@@ -285,9 +285,11 @@ class BaseAutomation(models.Model):
|
||||
# Note: This is to catch updates made by field recomputations.
|
||||
#
|
||||
def _compute_field_value(self, field):
|
||||
# retrieve the action rules to possibly execute
|
||||
if not field.store:
|
||||
# determine fields that may trigger an action
|
||||
stored_fields = [f for f in self._field_computed[field] if f.store]
|
||||
if not any(stored_fields):
|
||||
return _compute_field_value.origin(self, field)
|
||||
# retrieve the action rules to possibly execute
|
||||
actions = self.env['base.automation']._get_actions(self, ['on_write', 'on_create_or_write'])
|
||||
records = self.filtered('id').with_env(actions.env)
|
||||
# check preconditions on records
|
||||
@@ -295,7 +297,7 @@ class BaseAutomation(models.Model):
|
||||
# read old values before the update
|
||||
old_values = {
|
||||
old_vals.pop('id'): old_vals
|
||||
for old_vals in (records.read([field.name]))
|
||||
for old_vals in (records.read([f.name for f in stored_fields]))
|
||||
}
|
||||
# call original method
|
||||
_compute_field_value.origin(self, field)
|
||||
|
||||
@@ -17,20 +17,30 @@ class LeadTest(models.Model):
|
||||
active = fields.Boolean(default=True)
|
||||
partner_id = fields.Many2one('res.partner', string='Partner')
|
||||
date_action_last = fields.Datetime(string='Last Action', readonly=True)
|
||||
employee = fields.Boolean(related='partner_id.employee', readonly=True, store=True)
|
||||
employee = fields.Boolean(compute='_compute_employee_deadline', store=True)
|
||||
line_ids = fields.One2many('base.automation.line.test', 'lead_id')
|
||||
|
||||
priority = fields.Boolean()
|
||||
deadline = fields.Boolean(compute='_compute_deadline', store=True)
|
||||
deadline = fields.Boolean(compute='_compute_employee_deadline', store=True)
|
||||
is_assigned_to_admin = fields.Boolean(string='Assigned to admin user')
|
||||
|
||||
@api.depends('priority')
|
||||
def _compute_deadline(self):
|
||||
@api.depends('partner_id.employee', 'priority')
|
||||
def _compute_employee_deadline(self):
|
||||
# this method computes two fields on purpose; don't split it
|
||||
for record in self:
|
||||
record.employee = record.partner_id.employee
|
||||
if not record.priority:
|
||||
record.deadline = False
|
||||
else:
|
||||
record.deadline = fields.Datetime.from_string(record.create_date) + relativedelta.relativedelta(days=3)
|
||||
record.deadline = record.create_date + relativedelta.relativedelta(days=3)
|
||||
|
||||
def write(self, vals):
|
||||
result = super().write(vals)
|
||||
# force recomputation of field 'deadline' via 'employee': the action
|
||||
# based on 'deadline' must be triggered
|
||||
self.mapped('employee')
|
||||
return result
|
||||
|
||||
|
||||
class LineTest(models.Model):
|
||||
_name = "base.automation.line.test"
|
||||
|
||||
Reference in New Issue
Block a user