diff --git a/nfu_sale_order_batch_packaging/README.rst b/nfu_sale_order_batch_packaging/README.rst index 9d14fd3..eb03fa7 100644 --- a/nfu_sale_order_batch_packaging/README.rst +++ b/nfu_sale_order_batch_packaging/README.rst @@ -25,6 +25,8 @@ NFU Sale Order Batch Packaging This module adds a minium and a maximum order quantity field to Sale Orders and adds a packaging default to sale order batch. +It adds an autosplitting methode that respects the maximum ordered qty for every order and spreads the open packeges evenly over all orders. + **Table of contents** .. contents:: diff --git a/nfu_sale_order_batch_packaging/i18n/de.po b/nfu_sale_order_batch_packaging/i18n/de.po index ab39287..f6ff8d0 100644 --- a/nfu_sale_order_batch_packaging/i18n/de.po +++ b/nfu_sale_order_batch_packaging/i18n/de.po @@ -93,6 +93,11 @@ msgstr "Anzeigename" msgid "Fill Packages" msgstr "Pakete befüllen" +#. module: nfu_sale_order_batch_packaging +#: model_terms:ir.ui.view,arch_db:nfu_sale_order_batch_packaging.view_order_batch_form +msgid "Open Products" +msgstr "Offene Produkte" + #. module: nfu_sale_order_batch_packaging #: model:ir.model.fields.selection,name:nfu_sale_order_batch_packaging.selection__sale_order_batch_product__open_packaging_state__full msgid "Full" diff --git a/nfu_sale_order_batch_packaging/models/sale_order_batch.py b/nfu_sale_order_batch_packaging/models/sale_order_batch.py index f28d741..45c14c5 100644 --- a/nfu_sale_order_batch_packaging/models/sale_order_batch.py +++ b/nfu_sale_order_batch_packaging/models/sale_order_batch.py @@ -1,5 +1,7 @@ from odoo import api, fields, models +from odoo.addons.sale_order_batch.models.sale_order_batch import READONLY_FIELD_STATES + class SaleOrderBatch(models.Model): _inherit = "sale.order.batch" @@ -10,6 +12,12 @@ class SaleOrderBatch(models.Model): has_fillable_packages = fields.Boolean( compute="_compute_has_fillable_packages", ) + open_product_ids = fields.Many2many( + comodel_name="sale.order.batch.product", + compute="_compute_open_product_ids", + inverse="_inverse_open_product_ids", + states=READONLY_FIELD_STATES, + ) @api.depends( "sale_order_line_ids.product_uom_qty", @@ -29,6 +37,16 @@ class SaleOrderBatch(models.Model): p.open_packaging_qty > 0 for p in batch.product_ids ) + @api.depends("product_ids.open_packaging_qty") + def _compute_open_product_ids(self): + for batch in self: + batch.open_product_ids = batch.product_ids.filtered( + lambda p: p.open_packaging_qty > 0 + ) + + def _inverse_open_product_ids(self): + pass + def action_restore_ordered_qty(self): self.ensure_one() lines = self.sale_order_line_ids.filtered( diff --git a/nfu_sale_order_batch_packaging/models/sale_order_batch_product.py b/nfu_sale_order_batch_packaging/models/sale_order_batch_product.py index a8ce5e6..a69ad9e 100644 --- a/nfu_sale_order_batch_packaging/models/sale_order_batch_product.py +++ b/nfu_sale_order_batch_packaging/models/sale_order_batch_product.py @@ -96,6 +96,32 @@ class SaleOrderBatchProduct(models.Model): for line in product.sale_order_line_ids ) + def action_fill_packages(self): + self.ensure_one() + if self.open_packaging_qty > 0 and self.open_packaging_max_qty == 0.0: + line_ids = [(0, 0, {"batch_product_id": self.id})] + zero_line_ids = [] + elif self.open_packaging_qty > 0 and self.open_packaging_max_qty != 0.0: + line_ids = [] + zero_line_ids = [(0, 0, {"batch_product_id": self.id})] + else: + return + wizard = self.env["sale.order.batch.packaging.fill"].create( + { + "batch_id": self.batch_id.id, + "line_ids": line_ids, + "zero_line_ids": zero_line_ids, + } + ) + return { + "type": "ir.actions.act_window", + "name": "Fill Open Packages", + "res_model": "sale.order.batch.packaging.fill", + "res_id": wizard.id, + "view_mode": "form", + "target": "new", + } + def action_restore_ordered_qty(self): self.ensure_one() lines = self.sale_order_line_ids.filtered( @@ -128,7 +154,11 @@ class SaleOrderBatchProduct(models.Model): fair_share = float_round(remaining / n, precision_rounding=rounding) addition = min(room, fair_share) if addition > 0: - line.write({"product_uom_qty": line.product_uom_qty + addition}) + new_qty = float_round( + line.product_uom_qty + addition, precision_rounding=rounding + ) + new_qty = min(new_qty, line.product_uom_max_qty) + line.write({"product_uom_qty": new_qty}) distributed += addition last_line = line n -= 1 @@ -137,7 +167,11 @@ class SaleOrderBatchProduct(models.Model): # Attach any sub-rounding remainder directly to the last eligible line remainder = target - distributed if remainder > 1e-9 and last_line: - last_line.write({"product_uom_qty": last_line.product_uom_qty + remainder}) + new_qty = float_round( + last_line.product_uom_qty + remainder, precision_rounding=rounding + ) + new_qty = min(new_qty, last_line.product_uom_max_qty) + last_line.write({"product_uom_qty": new_qty}) def _zero_packaging(self): self.ensure_one() diff --git a/nfu_sale_order_batch_packaging/models/sale_order_line.py b/nfu_sale_order_batch_packaging/models/sale_order_line.py index 10c7bd7..bdb5b34 100644 --- a/nfu_sale_order_batch_packaging/models/sale_order_line.py +++ b/nfu_sale_order_batch_packaging/models/sale_order_line.py @@ -1,5 +1,6 @@ from odoo import _, api, fields, models from odoo.exceptions import UserError +from odoo.tools import float_round class SaleOrderLine(models.Model): @@ -21,7 +22,13 @@ class SaleOrderLine(models.Model): @api.constrains("product_uom_qty", "product_uom_max_qty") def _check_product_uom_qty(self): for order_line in self: - if order_line.product_uom_qty > order_line.product_uom_max_qty: + if ( + float_round( + order_line.product_uom_max_qty - order_line.product_uom_qty, + precision_rounding=order_line.product_uom.rounding, + ) + < 0 + ): raise UserError( _( f"{order_line.order_id.name}, {order_line.product_id.name}: " diff --git a/nfu_sale_order_batch_packaging/readme/DESCRIPTION.rst b/nfu_sale_order_batch_packaging/readme/DESCRIPTION.rst index 3bd5ae9..4e43c7c 100644 --- a/nfu_sale_order_batch_packaging/readme/DESCRIPTION.rst +++ b/nfu_sale_order_batch_packaging/readme/DESCRIPTION.rst @@ -1,2 +1,4 @@ This module adds a minium and a maximum order quantity field to Sale Orders -and adds a packaging default to sale order batch. \ No newline at end of file +and adds a packaging default to sale order batch. + +It adds an autosplitting methode that respects the maximum ordered qty for every order and spreads the open packeges evenly over all orders. \ No newline at end of file diff --git a/nfu_sale_order_batch_packaging/static/description/index.html b/nfu_sale_order_batch_packaging/static/description/index.html index 1dee347..4660f7e 100644 --- a/nfu_sale_order_batch_packaging/static/description/index.html +++ b/nfu_sale_order_batch_packaging/static/description/index.html @@ -372,6 +372,7 @@ ul.auto-toc {
This module adds a minium and a maximum order quantity field to Sale Orders and adds a packaging default to sale order batch.
+It adds an autosplitting methode that respects the maximum ordered qty for every order and spreads the open packeges evenly over all orders.
Table of contents