[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:
Raphael Collet
2019-10-28 12:38:45 +00:00
committed by fw-bot
parent 6c1340bb6f
commit fa991061ee
2 changed files with 20 additions and 8 deletions
@@ -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)
+15 -5
View File
@@ -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"