diff --git a/stock_packaging_calculator/models/product.py b/stock_packaging_calculator/models/product.py index 68907d2a4..d5dca58e1 100644 --- a/stock_packaging_calculator/models/product.py +++ b/stock_packaging_calculator/models/product.py @@ -1,9 +1,14 @@ # Copyright 2020 Camptocamp SA # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from collections import namedtuple + from odoo import models from odoo.tools import float_compare +# Unify records as we mix up w/ UoM +Packaging = namedtuple("Packaging", "id name qty") + class Product(models.Model): _inherit = "product.product" @@ -16,23 +21,29 @@ class Product(models.Model): Limitation: fractional quantities are lost. :prod_qty: total qty to satisfy. - :returns: list of tuple in the form [(qty_per_package, package_name)] + :with_subpackaging: include calculation of contained packagings. + eg: 1 pallet contains 4 big boxes and 6 little boxes. + :returns: list of dict in the form + [{id: 1, qty: qty_per_package, name: package_name}] """ - packagings = [(x.qty, x.name) for x in self.packaging_ids] + packagings = [Packaging(x.id, x.name, x.qty) for x in self.packaging_ids] # Add minimal unit - packagings.append((self.uom_id.factor, self.uom_id.name)) + packagings.append( + Packaging(self.uom_id.id, self.uom_id.name, self.uom_id.factor) + ) return self._product_qty_by_packaging( - sorted(packagings, reverse=True), prod_qty + sorted(packagings, reverse=True, key=lambda x: x.qty), prod_qty, ) def _product_qty_by_packaging(self, pkg_by_qty, qty): - """Produce a list of tuple of packaging qty and packaging name.""" + """Produce a list of dictionaries of packaging info.""" # TODO: refactor to handle fractional quantities (eg: 0.5 Kg) res = [] - for pkg_qty, pkg in pkg_by_qty: - qty_per_pkg, qty = self._qty_by_pkg(pkg_qty, qty) + for pkg in pkg_by_qty: + qty_per_pkg, qty = self._qty_by_pkg(pkg.qty, qty) if qty_per_pkg: - res.append((qty_per_pkg, pkg)) + value = {"id": pkg.id, "qty": qty_per_pkg, "name": pkg.name} + res.append(value) if not qty: break return res diff --git a/stock_packaging_calculator/tests/test_packaging_calc.py b/stock_packaging_calculator/tests/test_packaging_calc.py index af1c11541..b25d8cb9c 100644 --- a/stock_packaging_calculator/tests/test_packaging_calc.py +++ b/stock_packaging_calculator/tests/test_packaging_calc.py @@ -30,24 +30,33 @@ class TestCalc(SavepointCase): def test_calc_1(self): """Test easy behavior 1.""" - self.assertEqual( - self.product_a.product_qty_by_packaging(2655), - [(1, "Pallet"), (3, "Big Box"), (1, "Box"), (5, self.uom_unit.name)], - ) + expected = [ + {"id": self.pkg_pallet.id, "qty": 1, "name": self.pkg_pallet.name}, + {"id": self.pkg_big_box.id, "qty": 3, "name": self.pkg_big_box.name}, + {"id": self.pkg_box.id, "qty": 1, "name": self.pkg_box.name}, + {"id": self.uom_unit.id, "qty": 5, "name": self.uom_unit.name}, + ] + self.assertEqual(self.product_a.product_qty_by_packaging(2655), expected) def test_calc_2(self): """Test easy behavior 2.""" - self.assertEqual( - self.product_a.product_qty_by_packaging(350), [(1, "Big Box"), (3, "Box")] - ) + expected = [ + {"id": self.pkg_big_box.id, "qty": 1, "name": self.pkg_big_box.name}, + {"id": self.pkg_box.id, "qty": 3, "name": self.pkg_box.name}, + ] + self.assertEqual(self.product_a.product_qty_by_packaging(350), expected) def test_calc_3(self): """Test easy behavior 3.""" - self.assertEqual( - self.product_a.product_qty_by_packaging(80), - [(1, "Box"), (30, self.uom_unit.name)], - ) + expected = [ + {"id": self.pkg_box.id, "qty": 1, "name": self.pkg_box.name}, + {"id": self.uom_unit.id, "qty": 30, "name": self.uom_unit.name}, + ] + self.assertEqual(self.product_a.product_qty_by_packaging(80), expected) def test_calc_6(self): """Test fractional qty is lost.""" - self.assertEqual(self.product_a.product_qty_by_packaging(50.5), [(1, "Box")]) + expected = [ + {"id": self.pkg_box.id, "qty": 1, "name": self.pkg_box.name}, + ] + self.assertEqual(self.product_a.product_qty_by_packaging(50.5), expected)