[FIX] base_automation: check server actions model match rule model

New implementation of automated rules does not check if rule model matches
models of its children server actions. This can easily lead to updating
records of another model which have nothing in common with the automation
rule.

Also better write the reset when changing model.

Task-3527758 (Base Automation Refactor Fiximp)
Part of Task-3527752 (Mail: The Pre-Major Freeze FixImpLint)

Part-of: odoo/odoo#137133
This commit is contained in:
Thibault Delavallée
2023-10-02 06:54:38 +00:00
parent a92e88d547
commit a8b08b8e92
2 changed files with 34 additions and 3 deletions
@@ -8,7 +8,7 @@ from collections import defaultdict
from dateutil.relativedelta import relativedelta
from odoo import _, api, Command, exceptions, fields, models
from odoo import _, api, exceptions, fields, models
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
from odoo.tools import safe_eval
@@ -177,6 +177,19 @@ class BaseAutomation(models.Model):
CRITICAL_FIELDS = ['model_id', 'active', 'trigger', 'on_change_field_ids']
RANGE_FIELDS = ['trg_date_range', 'trg_date_range_type']
@api.constrains('model_id', 'action_server_ids')
def _check_action_server_model(self):
for rule in self:
failing_actions = rule.action_server_ids.filtered(
lambda action: action.model_id != rule.model_id
)
if failing_actions:
raise exceptions.ValidationError(
_('Target model of actions %(action_names)s are different from rule model.',
action_names=', '.join(failing_actions.mapped('name'))
)
)
@api.constrains('trigger', 'action_server_ids')
def _check_trigger_state(self):
for record in self:
@@ -196,7 +209,14 @@ class BaseAutomation(models.Model):
@api.depends('model_id')
def _compute_action_server_ids(self):
self.action_server_ids = [Command.clear()]
""" When changing / setting model, remove actions that are not targeting
the same model anymore. """
for rule in self.filtered('model_id'):
actions_to_remove = rule.action_server_ids.filtered(
lambda action: action.model_id != rule.model_id
)
if actions_to_remove:
rule.action_server_ids = [(3, action.id) for action in actions_to_remove]
@api.depends('trigger', 'trigger_field_ids')
def _compute_trg_date_id(self):
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
from odoo import api, exceptions, fields, models, _
class ServerAction(models.Model):
@@ -11,3 +11,14 @@ class ServerAction(models.Model):
('base_automation', 'Automation Rule')
], ondelete={'base_automation': 'cascade'})
base_automation_id = fields.Many2one('base.automation', string='Automation Rule', ondelete='cascade')
@api.constrains('model_id', 'base_automation_id')
def _check_model_coherency_with_automation(self):
for action in self.filtered('base_automation_id'):
if action.model_id != action.base_automation_id.model_id:
raise exceptions.ValidationError(
_("Model of action %(action_name)s should match the one from automated rule %(rule_name)s.",
action_name=action.name,
rule_name=action.base_automation_id.name
)
)