From cb2c00fd93dec7ce2d8cf36a468d11e204148c5f Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Fri, 29 Nov 2024 16:15:37 +0100 Subject: [PATCH] [IMP] stock_storage_type: condition context Give in evaluation context what is being moved --- stock_storage_type/models/stock_location.py | 8 ++- .../models/stock_storage_location_sequence.py | 7 ++- .../stock_storage_location_sequence_cond.py | 62 +++++++++++++++++-- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/stock_storage_type/models/stock_location.py b/stock_storage_type/models/stock_location.py index 72d2de071cd..50dc18fd274 100644 --- a/stock_storage_type/models/stock_location.py +++ b/stock_storage_type/models/stock_location.py @@ -1,5 +1,5 @@ -# Copyright 2019-2021 Camptocamp SA -# Copyright 2019-2021 Jacques-Etienne Baudoux (BCIM) +# Copyright 2019 Camptocamp SA +# Copyright 2019 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) import logging @@ -419,7 +419,9 @@ def _get_package_type_putaway_strategy( return dest_location for package_sequence in package_locations: - if not package_sequence.can_be_applied(putaway_location, quants, product): + if not package_sequence.can_be_applied( + putaway_location, quants, package, product, quantity + ): continue pref_loc = package_sequence.location_id storage_locations = pref_loc.get_storage_locations(products=product) diff --git a/stock_storage_type/models/stock_storage_location_sequence.py b/stock_storage_type/models/stock_storage_location_sequence.py index 1dabc98d14a..5539bb4b5c9 100644 --- a/stock_storage_type/models/stock_storage_location_sequence.py +++ b/stock_storage_type/models/stock_storage_location_sequence.py @@ -1,4 +1,5 @@ # Copyright 2019 Camptocamp SA +# Copyright 2024 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) from odoo import _, fields, models @@ -83,10 +84,12 @@ def button_show_locations(self): ] return action - def can_be_applied(self, putaway_location, quant, product): + def can_be_applied(self, putaway_location, quant, package, product, quantity): """Check if conditions are met.""" self.ensure_one() for cond in self.location_sequence_cond_ids: - if not cond.evaluate(self, putaway_location, quant, product): + if not cond.evaluate( + self, putaway_location, quant, package, product, quantity + ): return False return True diff --git a/stock_storage_type/models/stock_storage_location_sequence_cond.py b/stock_storage_type/models/stock_storage_location_sequence_cond.py index f155c2048db..d190a74043c 100644 --- a/stock_storage_type/models/stock_storage_location_sequence_cond.py +++ b/stock_storage_type/models/stock_storage_location_sequence_cond.py @@ -1,4 +1,5 @@ # Copyright 2022 ACSONE SA/NV +# Copyright 2024 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging @@ -28,7 +29,9 @@ def _default_code_snippet_docs(self): * condition * putaway_location * quant (recordset) + * package * product + * quantity * env * datetime * dateutil @@ -41,7 +44,13 @@ def _default_code_snippet_docs(self): """ def _get_code_snippet_eval_context( - self, storage_location_sequence, putaway_location, quant, product + self, + storage_location_sequence, + putaway_location, + quant, + package, + product, + quantity, ): """Prepare the context used when evaluating python code :returns: dict -- evaluation context given to safe_eval @@ -53,7 +62,9 @@ def _get_code_snippet_eval_context( "condition": self, "putaway_location": putaway_location, "quant": quant, + "package": package, "product": product, + "quantity": quantity, "datetime": safe_eval.datetime, "dateutil": safe_eval.dateutil, "time": safe_eval.time, @@ -63,12 +74,25 @@ def _get_code_snippet_eval_context( ), } - def _exec_code(self, storage_location_sequence, putaway_location, quant, product): + def _exec_code( + self, + storage_location_sequence, + putaway_location, + quant, + package, + product, + quantity, + ): self.ensure_one() if not self._code_snippet_valued(): return False eval_ctx = self._get_code_snippet_eval_context( - storage_location_sequence, putaway_location, quant, product + storage_location_sequence, + putaway_location, + quant, + package, + product, + quantity, ) snippet = self.code_snippet safe_eval.safe_eval(snippet, eval_ctx, mode="exec", nocopy=True) @@ -83,22 +107,50 @@ def _exec_code(self, storage_location_sequence, putaway_location, quant, product "* putaway sequence: %s\n" "* putaway location: %s\n" "* quants: %s\n" + "* package: %s\n" "* product: %s\n" + "* quantity: %s\n" % ( self.name, storage_location_sequence.id, putaway_location.name, quant.ids, + package.display_name, product.display_name, + quantity, ) ) return result - def evaluate(self, storage_location_sequence, putaway_location, quant, product): + def _code_snippet_valued(self): + self.ensure_one() + snippet = self.code_snippet or "" + return bool( + [ + not line.startswith("#") + for line in (snippet.splitlines()) + if line.strip("") + ] + ) + + def evaluate( + self, + storage_location_sequence, + putaway_location, + quant, + package, + product, + quantity, + ): self.ensure_one() if self.condition_type == "code": return self._exec_code( - storage_location_sequence, putaway_location, quant, product + storage_location_sequence, + putaway_location, + quant, + package, + product, + quantity, ) condition_type = self.condition_type raise exceptions.UserError(