Files
public/directive_layer/models/directive_policy.py

124 lines
4.0 KiB
Python

from odoo import api, fields, models
import logging
_logger = logging.getLogger(__name__)
class DirectivePolicy(models.Model):
_name = "directive.policy"
_description = "Directive Policy"
_order = "sequence, id"
name = fields.Char(required=True)
active = fields.Boolean(default=True)
sequence = fields.Integer(default=10)
origin_model = fields.Char(
string="Origin model",
required=True,
index=True,
help="Техническое имя модели источника, например 'project.task'",
)
event = fields.Selection(
[
("manual", "Manual"),
("on_create", "On Create"),
("on_write", "On Write"),
("on_stage", "On Stage Change"),
("on_cron", "On Cron"),
("on_callback", "При вызове метода (on_callback)"),
],
required=True,
index=True,
default="manual",
)
mode = fields.Selection(
[
("create_once", "Create once"),
("create_each_time", "Create each time"),
],
required=True,
default="create_once",
)
use_record_template_group = fields.Boolean(
default=True,
help="Если включено, группа берётся из поля записи-источника directive_template_group_id.",
)
template_group_id = fields.Many2one(
"directive.template.group",
string="Fixed template group",
help="Если указано и use_record_template_group=False — будет использоваться эта группа.",
)
trigger_field = fields.Char(
help="Имя поля источника, например 'stage_id'."
)
trigger_value_int = fields.Integer(
help="Для Many2one/Integer: ожидаемое значение (например ID стадии)."
)
def _policy_should_fire(self, record, payload: dict | None = None) -> bool:
self.ensure_one()
# Для on_callback факт вызова метода - это уже триггер.
if self.event == 'on_callback':
return True
if not self.trigger_field:
return True
value = getattr(record, self.trigger_field, False)
if hasattr(value, "id"):
match = bool(value and value.id == self.trigger_value_int)
if not match:
_logger.debug("[directive.policy] ID mismatch: expected %s, got %s", self.trigger_value_int, value.id)
return match
try:
match = (value == self.trigger_value_int)
if not match:
_logger.debug("[directive.policy] Value mismatch: expected %s, got %s", self.trigger_value_int, value)
return match
except Exception as e:
_logger.error("[directive.policy] Error comparing values: %s", e)
return False
def _resolve_template_group(self, record):
self.ensure_one()
if self.use_record_template_group:
return record.directive_template_group_id
return self.template_group_id
def apply_to_records(self, records, payload: dict | None = None):
self.ensure_one()
if not records:
return 0
created_total = 0
for rec in records:
if rec._name != self.origin_model:
continue
if not self._policy_should_fire(rec, payload=payload):
continue
group = self._resolve_template_group(rec)
if not group:
continue
if self.mode == "create_once":
existing = rec.env["directive.directive"].search_count([
("origin_id", "=", rec.directive_origin_id.id),
("policy_id", "=", self.id),
])
if existing:
continue
rec._directive_create_from_group(group, policy=self)
created_total += 1
return created_total