# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com) # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). from odoo import _, fields, models, tools from odoo.exceptions import UserError from odoo.osv import expression from odoo.tools.safe_eval import safe_eval class DdmrpWarningDefinition(models.Model): _name = "ddmrp.warning.definition" _description = "DDMRP Warning Definition" name = fields.Char( string="Description", ) python_code = fields.Text( string="Warning Expression", help="Write Python code that defines when this warning should " "raise. The result of executing the expression must be " "a boolean.", default="""# Available locals:\n# - buffer: A buffer record\nTrue""", ) severity = fields.Selection( selection=[("1_low", "Low"), ("2_mid", "Medium"), ("3_high", "High")], default="2_mid", ) active = fields.Boolean(default=True) warning_domain = fields.Char( string="Buffer Applicable Domain", default="[]", help="Domain based on Stock Buffer, to define if the " "warning is applicable or not.", ) ddmrp_warning_item_ids = fields.One2many( comodel_name="ddmrp.warning.item", inverse_name="warning_definition_id", readonly=True, ) def _eval_warning_domain(self, buffer, domain): buffer_domain = [("id", "=", buffer.id)] return bool( self.env["stock.buffer"].search_count( expression.AND([buffer_domain, domain]) ) ) def _is_warning_applicable(self, buffer): domain = safe_eval(self.warning_domain) or [] if domain: return self._eval_warning_domain(buffer, domain) return True def evaluate_definition(self, buffer): self.ensure_one() try: res = safe_eval( self.python_code, globals_dict={ "buffer": buffer, "time": tools.safe_eval.time, "datetime": tools.safe_eval.datetime, "dateutil": tools.safe_eval.dateutil, }, ) except Exception as error: raise UserError( _("Error evaluating %(name)s.\n %(error)s") % ({"name": self._name, "error": error}) ) from error return res def write(self, vals): # Unlink warning items when definition is archived res = super().write(vals) if "active" in vals and not vals.get("active"): self.ddmrp_warning_item_ids.unlink() return res