From 419a2d374ad6910e7a7e200193a5aab947b0c7a1 Mon Sep 17 00:00:00 2001 From: Abraham Anes Date: Thu, 28 Jul 2022 12:31:59 +0200 Subject: [PATCH 1/2] [14.0][IMP] stock_move_location: packages support --- stock_move_location/readme/CONTRIBUTORS.rst | 1 + stock_move_location/tests/test_common.py | 34 +++++++++++++++---- .../tests/test_move_location.py | 12 +++++-- .../wizard/stock_move_location.py | 18 ++++++---- .../wizard/stock_move_location.xml | 5 +++ .../wizard/stock_move_location_line.py | 15 ++++++++ 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/stock_move_location/readme/CONTRIBUTORS.rst b/stock_move_location/readme/CONTRIBUTORS.rst index 81ce82850..54eeb74a1 100644 --- a/stock_move_location/readme/CONTRIBUTORS.rst +++ b/stock_move_location/readme/CONTRIBUTORS.rst @@ -11,3 +11,4 @@ * Jacques-Etienne Baudoux * Iryna Vyshnevska * Alexei Rivera +* Abraham Anes diff --git a/stock_move_location/tests/test_common.py b/stock_move_location/tests/test_common.py index 797f84d18..5deba076d 100644 --- a/stock_move_location/tests/test_common.py +++ b/stock_move_location/tests/test_common.py @@ -69,6 +69,17 @@ class TestsCommon(common.TransactionCase): "company_id": cls.company.id, } ) + cls.lot4 = cls.env["stock.lot"].create( + { + "name": "lot4", + "product_id": cls.product_package.id, + "company_id": cls.company.id, + } + ) + cls.product_package = product_obj.create( + {"name": "Orange", "type": "product", "tracking": "lot"} + ) + cls.package = cls.env["stock.quant.package"].create({}) def setup_product_amounts(self): self.set_product_amount(self.product_no_lots, self.internal_loc_1, 123) @@ -81,16 +92,27 @@ class TestsCommon(common.TransactionCase): self.set_product_amount( self.product_lots, self.internal_loc_1, 1.0, lot_id=self.lot3 ) - - def set_product_amount(self, product, location, amount, lot_id=None): - self.env["stock.quant"]._update_available_quantity( - product, location, amount, lot_id=lot_id + self.set_product_amount( + self.product_package, + self.internal_loc_1, + 1.0, + lot_id=self.lot4, + package_id=self.package, ) - def check_product_amount(self, product, location, amount, lot_id=None): + def set_product_amount( + self, product, location, amount, lot_id=None, package_id=None + ): + self.env["stock.quant"]._update_available_quantity( + product, location, amount, lot_id=lot_id, package_id=package_id + ) + + def check_product_amount( + self, product, location, amount, lot_id=None, package_id=None + ): self.assertEqual( self.env["stock.quant"]._get_available_quantity( - product, location, lot_id=lot_id + product, location, lot_id=lot_id, package_id=package_id ), amount, ) diff --git a/stock_move_location/tests/test_move_location.py b/stock_move_location/tests/test_move_location.py index cc94fcb85..09f850819 100644 --- a/stock_move_location/tests/test_move_location.py +++ b/stock_move_location/tests/test_move_location.py @@ -21,10 +21,16 @@ class TestMoveLocation(TestsCommon): self.check_product_amount(self.product_lots, self.internal_loc_1, 0, self.lot1) self.check_product_amount(self.product_lots, self.internal_loc_1, 0, self.lot2) self.check_product_amount(self.product_lots, self.internal_loc_1, 0, self.lot3) + self.check_product_amount( + self.product_package, self.internal_loc_1, 0, self.lot4, self.package + ) self.check_product_amount(self.product_no_lots, self.internal_loc_2, 123) self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot1) self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot2) self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot3) + self.check_product_amount( + self.product_package, self.internal_loc_2, 1, self.lot4, self.package + ) def test_move_location_wizard_amount(self): """Can't move more than exists.""" @@ -54,9 +60,9 @@ class TestMoveLocation(TestsCommon): """Test lines getting cleared properly.""" wizard = self._create_wizard(self.internal_loc_1, self.internal_loc_2) wizard.onchange_origin_location() - self.assertEqual(len(wizard.stock_move_location_line_ids), 4) + self.assertEqual(len(wizard.stock_move_location_line_ids), 5) wizard._onchange_destination_location_id() - self.assertEqual(len(wizard.stock_move_location_line_ids), 4) + self.assertEqual(len(wizard.stock_move_location_line_ids), 5) dest_location_line = wizard.stock_move_location_line_ids.mapped( "destination_location_id" ) @@ -96,7 +102,7 @@ class TestMoveLocation(TestsCommon): wizard.action_move_location() picking = wizard.picking_id self.assertEqual(picking.state, "assigned") - self.assertEqual(len(picking.move_line_ids), 4) + self.assertEqual(len(picking.move_line_ids), 5) self.assertEqual( sorted(picking.move_line_ids.mapped("reserved_uom_qty")), [1, 1, 1, 123] ) diff --git a/stock_move_location/wizard/stock_move_location.py b/stock_move_location/wizard/stock_move_location.py index 3dc97a3dc..fa2ea53b1 100644 --- a/stock_move_location/wizard/stock_move_location.py +++ b/stock_move_location/wizard/stock_move_location.py @@ -102,6 +102,7 @@ class StockMoveLocationWizard(models.TransientModel): "max_quantity": quant.quantity, "origin_location_id": quant.location_id.id, "lot_id": quant.lot_id.id, + "package_id": quant.package_id.id, "product_uom_id": quant.product_uom_id.id, "custom": False, }, @@ -128,6 +129,7 @@ class StockMoveLocationWizard(models.TransientModel): "max_quantity": qty, "origin_location_id": quant.location_id.id, "lot_id": quant.lot_id.id, + "package_id": quant.package_id.id, "product_uom_id": quant.product_uom_id.id, "custom": False, }, @@ -229,7 +231,8 @@ class StockMoveLocationWizard(models.TransientModel): ("product_id", "=", line.product_id.id), ("location_id", "=", line.origin_location_id.id), ("lot_id", "=", line.lot_id.id), - ("qty_done", ">", 0.0), + ("package_id", "=", line.package_id.id), + ("product_uom_qty", ">", 0.0), ] ) moves_to_unreserve = move_lines.mapped("move_id") @@ -255,11 +258,13 @@ class StockMoveLocationWizard(models.TransientModel): self.picking_id = picking return self._get_picking_action(picking.id) - def _get_picking_action(self, pickinig_id): - action = self.env.ref("stock.action_picking_tree_all").read()[0] + def _get_picking_action(self, picking_id): + action = self.env["ir.actions.act_window"]._for_xml_id( + "stock.action_picking_tree_all" + ) form_view = self.env.ref("stock.view_picking_form").id action.update( - {"view_mode": "form", "views": [(form_view, "form")], "res_id": pickinig_id} + {"view_mode": "form", "views": [(form_view, "form")], "res_id": picking_id} ) return action @@ -268,11 +273,11 @@ class StockMoveLocationWizard(models.TransientModel): # Using sql as search_group doesn't support aggregation functions # leading to overhead in queries to DB query = """ - SELECT product_id, lot_id, SUM(quantity) AS quantity, + SELECT product_id, lot_id, package_id, SUM(quantity) AS quantity, SUM(reserved_quantity) AS reserved_quantity FROM stock_quant WHERE location_id = %s - GROUP BY product_id, lot_id + GROUP BY product_id, lot_id, package_id """ self.env.cr.execute(query, (location_id.id,)) return self.env.cr.dictfetchall() @@ -298,6 +303,7 @@ class StockMoveLocationWizard(models.TransientModel): "destination_location_id": location_dest_id, # cursor returns None instead of False "lot_id": group.get("lot_id") or False, + "package_id": group.get("package_id") or False, "product_uom_id": product.uom_id.id, "custom": False, } diff --git a/stock_move_location/wizard/stock_move_location.xml b/stock_move_location/wizard/stock_move_location.xml index fd4b27006..887eb587f 100644 --- a/stock_move_location/wizard/stock_move_location.xml +++ b/stock_move_location/wizard/stock_move_location.xml @@ -76,6 +76,11 @@ groups="stock.group_production_lot" options="{'no_create': True}" /> + Date: Thu, 3 Nov 2022 16:57:02 +0100 Subject: [PATCH 2/2] [14.0][IMP] stock_move_location: owner support --- stock_move_location/tests/test_common.py | 49 ++++++++++++++++--- .../tests/test_move_location.py | 31 ++++++++++-- .../wizard/stock_move_location.py | 10 ++-- .../wizard/stock_move_location.xml | 1 + .../wizard/stock_move_location_line.py | 10 ++++ 5 files changed, 88 insertions(+), 13 deletions(-) diff --git a/stock_move_location/tests/test_common.py b/stock_move_location/tests/test_common.py index 5deba076d..e476f7281 100644 --- a/stock_move_location/tests/test_common.py +++ b/stock_move_location/tests/test_common.py @@ -15,6 +15,7 @@ class TestsCommon(common.TransactionCase): cls.wizard_obj = cls.env["wiz.stock.move.location"] cls.quant_obj = cls.env["stock.quant"] cls.company = cls.env.ref("base.main_company") + cls.partner = cls.env.ref("base.res_partner_category_0") cls.internal_loc_1 = cls.location_obj.create( { @@ -48,6 +49,9 @@ class TestsCommon(common.TransactionCase): cls.product_lots = product_obj.create( {"name": "Apple", "type": "product", "tracking": "lot"} ) + cls.product_package = product_obj.create( + {"name": "Orange", "type": "product", "tracking": "lot"} + ) cls.lot1 = cls.env["stock.lot"].create( { "name": "lot1", @@ -69,6 +73,9 @@ class TestsCommon(common.TransactionCase): "company_id": cls.company.id, } ) + cls.product_package = product_obj.create( + {"name": "Orange", "type": "product", "tracking": "lot"} + ) cls.lot4 = cls.env["stock.lot"].create( { "name": "lot4", @@ -76,10 +83,16 @@ class TestsCommon(common.TransactionCase): "company_id": cls.company.id, } ) - cls.product_package = product_obj.create( - {"name": "Orange", "type": "product", "tracking": "lot"} + cls.lot5 = cls.env["stock.lot"].create( + { + "name": "lot5", + "product_id": cls.product_package.id, + "company_id": cls.company.id, + } ) cls.package = cls.env["stock.quant.package"].create({}) + cls.package1 = cls.env["stock.quant.package"].create({}) + cls.package2 = cls.env["stock.quant.package"].create({}) def setup_product_amounts(self): self.set_product_amount(self.product_no_lots, self.internal_loc_1, 123) @@ -99,20 +112,44 @@ class TestsCommon(common.TransactionCase): lot_id=self.lot4, package_id=self.package, ) + self.set_product_amount( + self.product_package, + self.internal_loc_1, + 1.0, + lot_id=self.lot4, + package_id=self.package1, + ) + self.set_product_amount( + self.product_package, + self.internal_loc_1, + 1.0, + lot_id=self.lot5, + package_id=self.package2, + owner_id=self.partner, + ) def set_product_amount( - self, product, location, amount, lot_id=None, package_id=None + self, product, location, amount, lot_id=None, package_id=None, owner_id=None ): self.env["stock.quant"]._update_available_quantity( - product, location, amount, lot_id=lot_id, package_id=package_id + product, + location, + amount, + lot_id=lot_id, + package_id=package_id, + owner_id=owner_id, ) def check_product_amount( - self, product, location, amount, lot_id=None, package_id=None + self, product, location, amount, lot_id=None, package_id=None, owner_id=None ): self.assertEqual( self.env["stock.quant"]._get_available_quantity( - product, location, lot_id=lot_id, package_id=package_id + product, + location, + lot_id=lot_id, + package_id=package_id, + owner_id=owner_id, ), amount, ) diff --git a/stock_move_location/tests/test_move_location.py b/stock_move_location/tests/test_move_location.py index 09f850819..606a414de 100644 --- a/stock_move_location/tests/test_move_location.py +++ b/stock_move_location/tests/test_move_location.py @@ -24,6 +24,17 @@ class TestMoveLocation(TestsCommon): self.check_product_amount( self.product_package, self.internal_loc_1, 0, self.lot4, self.package ) + self.check_product_amount( + self.product_package, self.internal_loc_1, 0, self.lot4, self.package1 + ) + self.check_product_amount( + self.product_package, + self.internal_loc_1, + 0, + self.lot5, + self.package2, + self.partner, + ) self.check_product_amount(self.product_no_lots, self.internal_loc_2, 123) self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot1) self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot2) @@ -31,6 +42,17 @@ class TestMoveLocation(TestsCommon): self.check_product_amount( self.product_package, self.internal_loc_2, 1, self.lot4, self.package ) + self.check_product_amount( + self.product_package, self.internal_loc_2, 1, self.lot4, self.package1 + ) + self.check_product_amount( + self.product_package, + self.internal_loc_2, + 1, + self.lot5, + self.package2, + self.partner, + ) def test_move_location_wizard_amount(self): """Can't move more than exists.""" @@ -60,9 +82,9 @@ class TestMoveLocation(TestsCommon): """Test lines getting cleared properly.""" wizard = self._create_wizard(self.internal_loc_1, self.internal_loc_2) wizard.onchange_origin_location() - self.assertEqual(len(wizard.stock_move_location_line_ids), 5) + self.assertEqual(len(wizard.stock_move_location_line_ids), 7) wizard._onchange_destination_location_id() - self.assertEqual(len(wizard.stock_move_location_line_ids), 5) + self.assertEqual(len(wizard.stock_move_location_line_ids), 7) dest_location_line = wizard.stock_move_location_line_ids.mapped( "destination_location_id" ) @@ -102,9 +124,10 @@ class TestMoveLocation(TestsCommon): wizard.action_move_location() picking = wizard.picking_id self.assertEqual(picking.state, "assigned") - self.assertEqual(len(picking.move_line_ids), 5) + self.assertEqual(len(picking.move_line_ids), 7) self.assertEqual( - sorted(picking.move_line_ids.mapped("reserved_uom_qty")), [1, 1, 1, 123] + sorted(picking.move_line_ids.mapped("reserved_uom_qty")), + [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 123.0], ) def test_quant_transfer(self): diff --git a/stock_move_location/wizard/stock_move_location.py b/stock_move_location/wizard/stock_move_location.py index fa2ea53b1..69a621c64 100644 --- a/stock_move_location/wizard/stock_move_location.py +++ b/stock_move_location/wizard/stock_move_location.py @@ -103,6 +103,7 @@ class StockMoveLocationWizard(models.TransientModel): "origin_location_id": quant.location_id.id, "lot_id": quant.lot_id.id, "package_id": quant.package_id.id, + "owner_id": quant.owner_id.id, "product_uom_id": quant.product_uom_id.id, "custom": False, }, @@ -130,6 +131,7 @@ class StockMoveLocationWizard(models.TransientModel): "origin_location_id": quant.location_id.id, "lot_id": quant.lot_id.id, "package_id": quant.package_id.id, + "owner_id": quant.owner_id.id, "product_uom_id": quant.product_uom_id.id, "custom": False, }, @@ -232,7 +234,8 @@ class StockMoveLocationWizard(models.TransientModel): ("location_id", "=", line.origin_location_id.id), ("lot_id", "=", line.lot_id.id), ("package_id", "=", line.package_id.id), - ("product_uom_qty", ">", 0.0), + ("owner_id", "=", line.owner_id.id), + ("qty_done", ">", 0.0), ] ) moves_to_unreserve = move_lines.mapped("move_id") @@ -273,11 +276,11 @@ class StockMoveLocationWizard(models.TransientModel): # Using sql as search_group doesn't support aggregation functions # leading to overhead in queries to DB query = """ - SELECT product_id, lot_id, package_id, SUM(quantity) AS quantity, + SELECT product_id, lot_id, package_id, owner_id, SUM(quantity) AS quantity, SUM(reserved_quantity) AS reserved_quantity FROM stock_quant WHERE location_id = %s - GROUP BY product_id, lot_id, package_id + GROUP BY product_id, lot_id, package_id, owner_id """ self.env.cr.execute(query, (location_id.id,)) return self.env.cr.dictfetchall() @@ -304,6 +307,7 @@ class StockMoveLocationWizard(models.TransientModel): # cursor returns None instead of False "lot_id": group.get("lot_id") or False, "package_id": group.get("package_id") or False, + "owner_id": group.get("owner_id") or False, "product_uom_id": product.uom_id.id, "custom": False, } diff --git a/stock_move_location/wizard/stock_move_location.xml b/stock_move_location/wizard/stock_move_location.xml index 887eb587f..060504d38 100644 --- a/stock_move_location/wizard/stock_move_location.xml +++ b/stock_move_location/wizard/stock_move_location.xml @@ -81,6 +81,7 @@ domain="[('location_id', '=', origin_location_id)]" options="{'no_create': True}" /> +