From 884dd0c020a483242efbd62b869c7943ebe7220f Mon Sep 17 00:00:00 2001 From: Yoshi Tashiro Date: Wed, 13 Jan 2021 17:05:18 +0800 Subject: [PATCH 1/2] [IMP] stock_quant_manual_assign: make qty_done fill optional There are cases where auto-filling of qty_done of stock move line is not desirable. e.g. you assign quants manually for some of the moves in a picking and not the others, in such case you need to go over all the moves in the picking to either remove qty_done or fill it in to proceed with the validation of the entire moves. Auto-fill behavior is also troublesome when this function is used in a manufacturing order. i.e. having qty_done of the component move live messes up the outcome of the production. --- stock_quant_manual_assign/__init__.py | 1 + stock_quant_manual_assign/__manifest__.py | 6 +++++- stock_quant_manual_assign/models/__init__.py | 1 + .../models/stock_picking_type.py | 14 ++++++++++++++ .../readme/CONFIGURATION.rst | 3 +++ .../tests/test_stock_quant_manual_assign.py | 18 ++++++++++++++++++ .../views/stock_picking_type_views.xml | 16 ++++++++++++++++ .../wizard/assign_manual_quants.py | 7 ++++--- 8 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 stock_quant_manual_assign/models/__init__.py create mode 100644 stock_quant_manual_assign/models/stock_picking_type.py create mode 100644 stock_quant_manual_assign/readme/CONFIGURATION.rst create mode 100644 stock_quant_manual_assign/views/stock_picking_type_views.xml diff --git a/stock_quant_manual_assign/__init__.py b/stock_quant_manual_assign/__init__.py index 40272379f..9b4296142 100644 --- a/stock_quant_manual_assign/__init__.py +++ b/stock_quant_manual_assign/__init__.py @@ -1 +1,2 @@ +from . import models from . import wizard diff --git a/stock_quant_manual_assign/__manifest__.py b/stock_quant_manual_assign/__manifest__.py index 1e77d165f..9da43f4df 100644 --- a/stock_quant_manual_assign/__manifest__.py +++ b/stock_quant_manual_assign/__manifest__.py @@ -17,6 +17,10 @@ "Odoo Community Association (OCA)", "website": "https://github.com/OCA/stock-logistics-warehouse", "depends": ["stock"], - "data": ["wizard/assign_manual_quants_view.xml", "views/stock_move_view.xml"], + "data": [ + "wizard/assign_manual_quants_view.xml", + "views/stock_move_view.xml", + "views/stock_picking_type_views.xml", + ], "installable": True, } diff --git a/stock_quant_manual_assign/models/__init__.py b/stock_quant_manual_assign/models/__init__.py new file mode 100644 index 000000000..576c033a6 --- /dev/null +++ b/stock_quant_manual_assign/models/__init__.py @@ -0,0 +1 @@ +from . import stock_picking_type diff --git a/stock_quant_manual_assign/models/stock_picking_type.py b/stock_quant_manual_assign/models/stock_picking_type.py new file mode 100644 index 000000000..013c0d9b2 --- /dev/null +++ b/stock_quant_manual_assign/models/stock_picking_type.py @@ -0,0 +1,14 @@ +# Copyright 2021 Quartile Limited +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class StockPickingType(models.Model): + _inherit = "stock.picking.type" + + auto_fill_qty_done = fields.Boolean( + "Auto-fill Quantity Done", + help="Select this in case done quantity of the stock move line should " + "be auto-filled when quants are manually assigned.", + ) diff --git a/stock_quant_manual_assign/readme/CONFIGURATION.rst b/stock_quant_manual_assign/readme/CONFIGURATION.rst new file mode 100644 index 000000000..1fc9e85c3 --- /dev/null +++ b/stock_quant_manual_assign/readme/CONFIGURATION.rst @@ -0,0 +1,3 @@ +In case you would like to auto-fill the done quantity of the stock move line +with manual assignment of a quant, go to *Invenory > Configuration > Warehouse Management > Operation Types*, +and select 'Auto-fill Quantity Done' for concerned types. diff --git a/stock_quant_manual_assign/tests/test_stock_quant_manual_assign.py b/stock_quant_manual_assign/tests/test_stock_quant_manual_assign.py index ed1fd61d0..e3d64c763 100644 --- a/stock_quant_manual_assign/tests/test_stock_quant_manual_assign.py +++ b/stock_quant_manual_assign/tests/test_stock_quant_manual_assign.py @@ -9,6 +9,7 @@ class TestStockQuantManualAssign(TransactionCase): def setUp(self): super(TestStockQuantManualAssign, self).setUp() self.quant_model = self.env["stock.quant"] + self.picking_model = self.env["stock.picking"] self.location_model = self.env["stock.location"] self.move_model = self.env["stock.move"] self.quant_assign_wizard = self.env["assign.manual.quants"] @@ -38,6 +39,7 @@ class TestStockQuantManualAssign(TransactionCase): "location_id": self.location_src.id, } ) + self.picking_type = self.env.ref("stock.picking_type_out") self.quant1 = self.quant_model.sudo().create( { "product_id": self.product.id, @@ -67,6 +69,7 @@ class TestStockQuantManualAssign(TransactionCase): "product_uom": self.product.uom_id.id, "location_id": self.location_src.id, "location_dest_id": self.location_dst.id, + "picking_type_id": self.picking_type.id, } ) self.move._action_confirm() @@ -134,6 +137,21 @@ class TestStockQuantManualAssign(TransactionCase): self.assertAlmostEqual( len(self.move.move_line_ids), len(wizard.quants_lines.filtered("selected")) ) + self.assertFalse(self.move.picking_type_id.auto_fill_qty_done) + self.assertEqual(sum(self.move.move_line_ids.mapped("qty_done")), 0.0) + + def test_quant_manual_assign_auto_fill_qty_done(self): + wizard = self.quant_assign_wizard.with_context(active_id=self.move.id).create( + {} + ) + wizard.quants_lines[0].write({"selected": True}) + wizard.quants_lines[0]._onchange_selected() + wizard.quants_lines[1].write({"selected": True, "qty": 50.0}) + self.assertEqual(wizard.lines_qty, 150.0) + self.picking_type.auto_fill_qty_done = True + wizard.assign_quants() + self.assertTrue(self.move.picking_type_id.auto_fill_qty_done) + self.assertEqual(sum(self.move.move_line_ids.mapped("qty_done")), 150.0) def test_quant_assign_wizard_after_availability_check(self): self.move._action_assign() diff --git a/stock_quant_manual_assign/views/stock_picking_type_views.xml b/stock_quant_manual_assign/views/stock_picking_type_views.xml new file mode 100644 index 000000000..8c1d40511 --- /dev/null +++ b/stock_quant_manual_assign/views/stock_picking_type_views.xml @@ -0,0 +1,16 @@ + + + + Operation Types + stock.picking.type + + + + + + + + diff --git a/stock_quant_manual_assign/wizard/assign_manual_quants.py b/stock_quant_manual_assign/wizard/assign_manual_quants.py index dad9e9d5d..6aeaafcd3 100644 --- a/stock_quant_manual_assign/wizard/assign_manual_quants.py +++ b/stock_quant_manual_assign/wizard/assign_manual_quants.py @@ -58,9 +58,10 @@ class AssignManualQuants(models.TransientModel): move._do_unreserve() for line in self.quants_lines: line._assign_quant_line() - # Auto-fill all lines as done - for ml in move.move_line_ids: - ml.qty_done = ml.product_qty + if move.picking_type_id.auto_fill_qty_done: + # Auto-fill all lines as done + for ml in move.move_line_ids: + ml.qty_done = ml.product_qty move._recompute_state() move.mapped("picking_id")._compute_state() return {} From a1ddbe73b5f5450fcd868020190233104d4768fa Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Tue, 27 Jul 2021 10:38:51 +0200 Subject: [PATCH 2/2] [IMP] stock_quant_manual_assign: add prepare lines method --- .../wizard/assign_manual_quants.py | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/stock_quant_manual_assign/wizard/assign_manual_quants.py b/stock_quant_manual_assign/wizard/assign_manual_quants.py index 6aeaafcd3..9e600a446 100644 --- a/stock_quant_manual_assign/wizard/assign_manual_quants.py +++ b/stock_quant_manual_assign/wizard/assign_manual_quants.py @@ -79,32 +79,37 @@ class AssignManualQuants(models.TransientModel): ) quants_lines = [] for quant in available_quants: - line = { - "quant_id": quant.id, - "on_hand": quant.quantity, - "location_id": quant.location_id.id, - "lot_id": quant.lot_id.id, - "package_id": quant.package_id.id, - "owner_id": quant.owner_id.id, - "selected": False, - } - move_lines = move.move_line_ids.filtered( - lambda ml: ( - ml.location_id == quant.location_id - and ml.lot_id == quant.lot_id - and ml.owner_id == quant.owner_id - and ml.package_id == quant.package_id - ) - ) - line["qty"] = sum(move_lines.mapped("product_uom_qty")) - line["selected"] = bool(line["qty"]) - line["reserved"] = quant.reserved_quantity - line["qty"] + line = self._prepare_wizard_line(move, quant) quants_lines.append(line) res.update( {"quants_lines": [(0, 0, x) for x in quants_lines], "move_id": move.id} ) return res + @api.model + def _prepare_wizard_line(self, move, quant): + line = { + "quant_id": quant.id, + "on_hand": quant.quantity, + "location_id": quant.location_id.id, + "lot_id": quant.lot_id.id, + "package_id": quant.package_id.id, + "owner_id": quant.owner_id.id, + "selected": False, + } + move_lines = move.move_line_ids.filtered( + lambda ml: ( + ml.location_id == quant.location_id + and ml.lot_id == quant.lot_id + and ml.owner_id == quant.owner_id + and ml.package_id == quant.package_id + ) + ) + line["qty"] = sum(move_lines.mapped("product_uom_qty")) + line["selected"] = bool(line["qty"]) + line["reserved"] = quant.reserved_quantity - line["qty"] + return line + class AssignManualQuantsLines(models.TransientModel): _name = "assign.manual.quants.lines"