From 28a4a6082423cf5b63cfdfb35d2eb180380dd997 Mon Sep 17 00:00:00 2001 From: sergio-teruel Date: Mon, 2 Nov 2020 21:38:55 +0100 Subject: [PATCH] [IMP + FIX] stock_move_location: Display reserved quantity in wizard lines. Reassign reserved quantities for quants moved. --- stock_move_location/i18n/es.po | 42 ++++++------------ .../i18n/stock_move_location.pot | 6 +++ .../tests/test_move_location.py | 33 ++++++++++++++ .../wizard/stock_move_location.py | 44 +++++++++++++++++-- .../wizard/stock_move_location.xml | 5 +++ .../wizard/stock_move_location_line.py | 3 ++ 6 files changed, 102 insertions(+), 31 deletions(-) diff --git a/stock_move_location/i18n/es.po b/stock_move_location/i18n/es.po index ba44e2e63..2feee6714 100644 --- a/stock_move_location/i18n/es.po +++ b/stock_move_location/i18n/es.po @@ -6,16 +6,16 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-02-03 17:47+0000\n" -"PO-Revision-Date: 2020-02-03 18:48+0100\n" -"Last-Translator: Enric Tobella \n" +"POT-Creation-Date: 2020-11-02 20:30+0000\n" +"PO-Revision-Date: 2020-11-02 21:37+0100\n" +"Last-Translator: Sergio Teruel \n" "Language-Team: none\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 2.0.6\n" +"X-Generator: Poedit 2.3\n" #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__apply_putaway_strategy @@ -62,9 +62,8 @@ msgstr "Ubicación de destino" #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__destination_location_disable -#, fuzzy msgid "Destination Location Disable" -msgstr "Ubicación de destino" +msgstr "Ubicación de destino desactivada" #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__display_name @@ -75,7 +74,6 @@ msgstr "Nombre mostrado" #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__edit_locations #: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location -#, fuzzy msgid "Edit Locations" msgstr "(editar)" @@ -130,9 +128,8 @@ msgstr "Líneas de movimiento de Ubicación" #. module: stock_move_location #: model_terms:ir.ui.view,arch_db:stock_move_location.stock_picking_type_kanban -#, fuzzy msgid "Move On Hand" -msgstr " Disponible" +msgstr "Disponible" #. module: stock_move_location #: model:ir.actions.act_window,name:stock_move_location.wiz_stock_move_location_action @@ -153,9 +150,8 @@ msgstr "La cantidad movida no puede superar la cantidad máxima o ser negativo" #. module: stock_move_location #: model:ir.actions.act_window,name:stock_move_location.wiz_stock_quant_location_action -#, fuzzy msgid "Move to location..." -msgstr "Mover desde ubicación..." +msgstr "Mover a ubicación..." #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__origin_location_id @@ -165,9 +161,8 @@ msgstr "Ubicación de origen" #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__origin_location_disable -#, fuzzy msgid "Origin Location Disable" -msgstr "Ubicación de origen" +msgstr "Ubicación origen desactivada" #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_stock_move__location_move @@ -177,7 +172,6 @@ msgstr "Parte de un movimiento entre ubicaciones" #. module: stock_move_location #: model:ir.model,name:stock_move_location.model_stock_picking_type #: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__picking_type_id -#, fuzzy msgid "Picking Type" msgstr "Tipo de operación" @@ -201,11 +195,15 @@ msgstr "Unidad de medida" msgid "Quantity to move" msgstr "Cantidad a mover" +#. module: stock_move_location +#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__reserved_quantity +msgid "Reserved quantity" +msgstr "Cantidad Reservada" + #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_stock_picking_type__show_move_onhand -#, fuzzy msgid "Show Move On hand stock" -msgstr "Stock On Hand" +msgstr "Mostrar cantidad disponible" #. module: stock_move_location #: model:ir.model.fields,help:stock_move_location.field_stock_picking_type__show_move_onhand @@ -250,15 +248,3 @@ msgstr "" #: model:ir.model.fields,help:stock_move_location.field_wiz_stock_move_location__origin_location_disable msgid "technical field to disable the edition of origin location." msgstr "" - -#~ msgid "Add all" -#~ msgstr "Añadir todo" - -#~ msgid "Clear all" -#~ msgstr "Limpiar todo" - -#~ msgid "wiz.stock.move.location" -#~ msgstr "wiz.stock.move.location" - -#~ msgid "wiz.stock.move.location.line" -#~ msgstr "wiz.stock.move.location.line" diff --git a/stock_move_location/i18n/stock_move_location.pot b/stock_move_location/i18n/stock_move_location.pot index d688414e3..2306bf9d7 100644 --- a/stock_move_location/i18n/stock_move_location.pot +++ b/stock_move_location/i18n/stock_move_location.pot @@ -140,6 +140,7 @@ msgstr "" #. module: stock_move_location #: code:addons/stock_move_location/wizard/stock_move_location_line.py:0 +#: code:addons/stock_move_location/wizard/stock_move_location_line.py:0 #, python-format msgid "Move quantity can not exceed max quantity or be negative" msgstr "" @@ -191,6 +192,11 @@ msgstr "" msgid "Quantity to move" msgstr "" +#. module: stock_move_location +#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__reserved_quantity +msgid "Reserved quantity" +msgstr "" + #. module: stock_move_location #: model:ir.model.fields,field_description:stock_move_location.field_stock_picking_type__show_move_onhand msgid "Show Move On hand stock" diff --git a/stock_move_location/tests/test_move_location.py b/stock_move_location/tests/test_move_location.py index e9b65a455..357cce30d 100644 --- a/stock_move_location/tests/test_move_location.py +++ b/stock_move_location/tests/test_move_location.py @@ -132,3 +132,36 @@ class TestMoveLocation(TestsCommon): self.assertEqual( putaway_line.destination_location_id, self.internal_loc_2_shelf ) + + def test_inmediate_transfer_reserved_quantity(self): + """ + Unreserve quantities in old location and reserve the same items on + new location + """ + # Create some quants + self.set_product_amount( + self.product_lots, self.internal_loc_1, 100, lot_id=self.lot1 + ) + # Reserve some quantities + stock_move = self.env["stock.move"].create( + { + "name": "Move for test", + "product_id": self.product_lots.id, + "product_uom_qty": 20.0, + "product_uom": self.product_lots.uom_id.id, + "location_id": self.internal_loc_1.id, + "location_dest_id": self.internal_loc_2.id, + } + ) + stock_move._action_confirm() + stock_move._action_assign() + # Move all quantities to other location + wizard = self._create_wizard(self.internal_loc_1, self.internal_loc_2_shelf) + wizard.onchange_origin_location() + wizard.action_move_location() + # The old reserved quantities must be in new location after confirm wizard + self.assertEqual(len(stock_move.move_line_ids), 1) + self.assertEqual(stock_move.move_line_ids.product_uom_qty, 20.0) + self.assertEqual( + stock_move.move_line_ids.location_id, self.internal_loc_2_shelf + ) diff --git a/stock_move_location/wizard/stock_move_location.py b/stock_move_location/wizard/stock_move_location.py index c236ea53d..f6461ed59 100644 --- a/stock_move_location/wizard/stock_move_location.py +++ b/stock_move_location/wizard/stock_move_location.py @@ -90,6 +90,7 @@ class StockMoveLocationWizard(models.TransientModel): "product_id": quant.product_id.id, "move_quantity": quant.quantity, "max_quantity": quant.quantity, + "reserved_quantity": quant.reserved_quantity, "origin_location_id": quant.location_id.id, "lot_id": quant.lot_id.id, "product_uom_id": quant.product_uom_id.id, @@ -174,12 +175,46 @@ class StockMoveLocationWizard(models.TransientModel): line.create_move_lines(picking, move) return move + def _unreserve_moves(self): + """ + Try to unreserve moves that they has reserved quantity before user + moves products from a location to other one and change move origin + location to the new location to assign later. + :return moves unreserved + """ + moves_to_reassign = self.env["stock.move"] + lines_to_ckeck_reverve = self.stock_move_location_line_ids.filtered( + lambda l: ( + l.move_quantity > l.max_quantity - l.reserved_quantity + and not l.origin_location_id.should_bypass_reservation() + ) + ) + for line in lines_to_ckeck_reverve: + move_lines = self.env["stock.move.line"].search( + [ + ("state", "=", "assigned"), + ("product_id", "=", line.product_id.id), + ("location_id", "=", line.origin_location_id.id), + ("lot_id", "=", line.lot_id.id), + ("product_uom_qty", ">", 0.0), + ] + ) + moves_to_unreserve = move_lines.mapped("move_id") + # Unreserve in old location + moves_to_unreserve._do_unreserve() + # Change location in move with the new one + moves_to_unreserve.write({"location_id": line.destination_location_id.id}) + moves_to_reassign |= moves_to_unreserve + return moves_to_reassign + def action_move_location(self): self.ensure_one() picking = self._create_picking() self._create_moves(picking) if not self.env.context.get("planned"): + moves_to_reassign = self._unreserve_moves() picking.button_validate() + moves_to_reassign._action_assign() else: picking.action_confirm() picking.action_assign() @@ -199,7 +234,8 @@ 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) + SELECT product_id, lot_id, SUM(quantity) AS quantity, + SUM(reserved_quantity) AS reserved_quantity FROM stock_quant WHERE location_id = %s GROUP BY product_id, lot_id @@ -221,8 +257,9 @@ class StockMoveLocationWizard(models.TransientModel): product_data.append( { "product_id": product.id, - "move_quantity": group.get("sum"), - "max_quantity": group.get("sum"), + "move_quantity": group.get("quantity"), + "max_quantity": group.get("quantity"), + "reserved_quantity": group.get("reserved_quantity"), "origin_location_id": self.origin_location_id.id, "destination_location_id": location_dest_id, # cursor returns None instead of False @@ -249,6 +286,7 @@ class StockMoveLocationWizard(models.TransientModel): continue line = line_model.create(line_val) line.max_quantity = line.get_max_quantity() + line.reserved_quantity = line.reserved_quantity lines.append(line) self.update( {"stock_move_location_line_ids": [(6, 0, [line.id for line in lines])]} diff --git a/stock_move_location/wizard/stock_move_location.xml b/stock_move_location/wizard/stock_move_location.xml index 66b63f035..97beb3a01 100644 --- a/stock_move_location/wizard/stock_move_location.xml +++ b/stock_move_location/wizard/stock_move_location.xml @@ -84,6 +84,11 @@ attrs="{'readonly': [('custom', '!=', True)]}" force_save="1" /> + diff --git a/stock_move_location/wizard/stock_move_location_line.py b/stock_move_location/wizard/stock_move_location_line.py index f8e3bfc69..527343d9d 100644 --- a/stock_move_location/wizard/stock_move_location_line.py +++ b/stock_move_location/wizard/stock_move_location_line.py @@ -41,6 +41,9 @@ class StockMoveLocationWizardLine(models.TransientModel): max_quantity = fields.Float( string="Maximum available quantity", digits="Product Unit of Measure" ) + reserved_quantity = fields.Float( + string="Reserved quantity", digits="Product Unit of Measure" + ) custom = fields.Boolean(string="Custom line", default=True) @staticmethod