diff --git a/README.md b/README.md index 17cbc0d29f3..485ebe3bf98 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ addon | version | maintainers | summary [sale_stock_release_channel_delivery_date](sale_stock_release_channel_delivery_date/) | 16.0.1.1.2 | jbaudoux | Compute expected date based on available release channels [sale_stock_release_channel_partner_by_date](sale_stock_release_channel_partner_by_date/) | 16.0.1.1.0 | sebalix | Release channels integration with Sales [sale_stock_release_channel_partner_by_date_delivery](sale_stock_release_channel_partner_by_date_delivery/) | 16.0.1.1.1 | sebalix | Filters channels on sales based on selected carrier. -[shopfloor](shopfloor/) | 16.0.2.16.2 | guewen simahawk sebalix | manage warehouse operations with barcode scanners +[shopfloor](shopfloor/) | 16.0.2.16.3 | guewen simahawk sebalix | manage warehouse operations with barcode scanners [shopfloor_base](shopfloor_base/) | 16.0.1.2.1 | guewen simahawk sebalix | Core module for creating mobile apps [shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 | guewen | Create batch transfers for Cluster Picking [shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.1 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.2.0 | simahawk | Mobile frontend for WMS Shopfloor app [shopfloor_mobile_base_auth_api_key](shopfloor_mobile_base_auth_api_key/) | 16.0.1.0.0 | | Provides authentication via API key to Shopfloor base mobile app -[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.7 | mmequignon JuMiSanAr | Reception scenario for shopfloor -[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 | JuMiSanAr | Scenario for receiving products +[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.8 | mmequignon JuMiSanAr | Reception scenario for shopfloor +[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.3 | JuMiSanAr | Scenario for receiving products [shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 | mmequignon | Mark created return as to refund [shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 | simahawk | Integrate rest_log into Shopfloor app [shopfloor_workstation](shopfloor_workstation/) | 16.0.1.0.0 | | Manage warehouse workstation with barcode scanners diff --git a/shopfloor/README.rst b/shopfloor/README.rst index 21d9f05f19d..8fba5a6686f 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -11,7 +11,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:cdba7e2cc373fe847373edb11404381cbae37c91bf1cc810d257ba2602aa4ae7 + !! source digest: sha256:22f8e5b0353c5637d5aea9d6f6ae884fd29d5d25e456451b5d76e0926b14b45c !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 2c56784d5f1..551ff614db9 100644 --- a/shopfloor/__manifest__.py +++ b/shopfloor/__manifest__.py @@ -6,7 +6,7 @@ { "name": "Shopfloor", "summary": "manage warehouse operations with barcode scanners", - "version": "16.0.2.16.2", + "version": "16.0.2.16.3", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor/actions/stock.py b/shopfloor/actions/stock.py index 6c661d84ea5..2f8825c1c86 100644 --- a/shopfloor/actions/stock.py +++ b/shopfloor/actions/stock.py @@ -152,32 +152,35 @@ def mark_move_line_as_picked( lines.write(values_assigned) move_lines.picking_id.filtered(lambda p: p.user_id != user).user_id = user.id - def unmark_move_line_as_picked(self, move_lines): + def unmark_move_line_as_picked(self, move_lines, split=True): """Reverse the change from `mark_move_line_as_picked`.""" move_lines.write( { "shopfloor_user_id": False, "qty_done": 0, "result_package_id": False, + "lot_id": False, } ) pickings = move_lines.picking_id for picking in pickings: - lines_still_assigned = picking.move_line_ids.filtered( - lambda x: x.shopfloor_user_id - ) - if lines_still_assigned: - # Because there is other lines in the picking still assigned - # The picking has to be split - unmark_lines = picking.move_line_ids & move_lines - unmark_lines._extract_in_split_order(default={"user_id": False}) - else: - pickings.write( + still_assigned_users = picking.move_line_ids.shopfloor_user_id + if not still_assigned_users: + picking.write( { "user_id": False, "printed": False, } ) + else: + # Decide what to do if there are other lines in the picking still assigned + if split: + unmarked_lines = picking.move_line_ids & move_lines + unmarked_lines._extract_in_split_order( + default={"user_id": False, "printed": False} + ) + else: + picking.user_id = still_assigned_users[0] def validate_moves(self, moves): """Validate moves in different ways depending on several criterias: diff --git a/shopfloor/static/description/index.html b/shopfloor/static/description/index.html index 1986edf98c7..6ebeeaeef14 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:cdba7e2cc373fe847373edb11404381cbae37c91bf1cc810d257ba2602aa4ae7 +!! source digest: sha256:22f8e5b0353c5637d5aea9d6f6ae884fd29d5d25e456451b5d76e0926b14b45c !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

diff --git a/shopfloor/tests/test_actions_stock.py b/shopfloor/tests/test_actions_stock.py index 00524458c2e..819dc135ad3 100644 --- a/shopfloor/tests/test_actions_stock.py +++ b/shopfloor/tests/test_actions_stock.py @@ -23,6 +23,17 @@ def setUpClass(cls): cls._fill_stock_for_moves(cls.move1) cls.picking.action_assign() + cls.other_user = ( + cls.env["res.users"] + .sudo() + .create( + { + "name": "Other user", + "login": "other_user", + } + ) + ) + @classmethod def setUpClassVars(cls): super().setUpClassVars() @@ -46,3 +57,43 @@ def test_unmark_move_line_as_picked(self): self.assertTrue(self.picking.move_line_ids.shopfloor_user_id) self.assertFalse(picking_not_assigned.move_line_ids.shopfloor_user_id) self.assertFalse(picking_not_assigned.user_id) + + def test_unmark_move_line_as_picked_nosplit_full_picking(self): + lines = self.picking.move_line_ids + self.stock.mark_move_line_as_picked(lines) + self.assertEqual(self.picking.user_id, self.env.user) + + self.stock.unmark_move_line_as_picked(lines, split=False) + self.assertFalse(lines.shopfloor_user_id) + self.assertEqual(lines.picking_id, self.picking) + self.assertFalse(self.picking.user_id) + + def test_unmark_move_line_as_picked_nosplit_partial_picking_same_user(self): + lines = self.picking.move_line_ids + self.stock.mark_move_line_as_picked(lines) + self.assertEqual(self.picking.user_id, self.env.user) + + line_unpicked = lines[0] + self.stock.unmark_move_line_as_picked(line_unpicked, split=False) + self.assertFalse(line_unpicked.shopfloor_user_id) + self.assertEqual(line_unpicked.picking_id, self.picking) + self.assertEqual(self.picking.user_id, self.env.user) + + def test_unmark_move_line_as_picked_nosplit_partial_picking_different_user(self): + lines = self.picking.move_line_ids + self.stock.mark_move_line_as_picked(lines[0], user=self.env.user, split=False) + self.stock.mark_move_line_as_picked(lines[1], user=self.other_user, split=False) + + user_line = lines.filtered(lambda line: line.shopfloor_user_id == self.env.user) + other_line = lines.filtered( + lambda line: line.shopfloor_user_id == self.other_user + ) + self.assertEqual(self.picking.user_id, self.other_user) + self.assertEqual(len(user_line), 1) + self.assertEqual(len(other_line), 1) + + self.stock.unmark_move_line_as_picked(other_line, split=False) + self.assertFalse(other_line.shopfloor_user_id) + self.assertEqual(user_line.shopfloor_user_id, self.env.user) + self.assertEqual(lines.picking_id, self.picking) + self.assertEqual(self.picking.user_id, self.env.user) diff --git a/shopfloor_reception/README.rst b/shopfloor_reception/README.rst index f425cbb9070..ccd148f33ad 100644 --- a/shopfloor_reception/README.rst +++ b/shopfloor_reception/README.rst @@ -11,7 +11,7 @@ Shopfloor Reception !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f4ad59cbe1f5457c033cdeb6f33a81adc81c40e2ba2e87cf1b12c9ffbc9cf3e3 + !! source digest: sha256:4a5cae1dea64b85f2f987a26658f70b634462808055727f8e4475218e37783a8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception/__manifest__.py b/shopfloor_reception/__manifest__.py index 9949f22c53d..fcd3c221c62 100644 --- a/shopfloor_reception/__manifest__.py +++ b/shopfloor_reception/__manifest__.py @@ -1,7 +1,7 @@ { "name": "Shopfloor Reception", "summary": "Reception scenario for shopfloor", - "version": "16.0.1.6.7", + "version": "16.0.1.6.8", "development_status": "Beta", "category": "Inventory", "website": "https://github.com/OCA/wms", diff --git a/shopfloor_reception/services/reception.py b/shopfloor_reception/services/reception.py index d44c368cdfd..ba9e5ec8f01 100644 --- a/shopfloor_reception/services/reception.py +++ b/shopfloor_reception/services/reception.py @@ -1324,7 +1324,7 @@ def set_quantity__cancel_action(self, picking_id, selected_line_id): if selected_line.exists(): if selected_line.reserved_uom_qty: stock = self._actions_for("stock") - stock.unmark_move_line_as_picked(selected_line) + stock.unmark_move_line_as_picked(selected_line, split=False) else: selected_line.unlink() return self._response_for_select_move(picking) diff --git a/shopfloor_reception/static/description/index.html b/shopfloor_reception/static/description/index.html index 5ff155b6605..030780eb904 100644 --- a/shopfloor_reception/static/description/index.html +++ b/shopfloor_reception/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor Reception

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:f4ad59cbe1f5457c033cdeb6f33a81adc81c40e2ba2e87cf1b12c9ffbc9cf3e3 +!! source digest: sha256:4a5cae1dea64b85f2f987a26658f70b634462808055727f8e4475218e37783a8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor implementation of the reception scenario. diff --git a/shopfloor_reception/tests/test_set_quantity_action.py b/shopfloor_reception/tests/test_set_quantity_action.py index a7bf4b4b897..cceb476a373 100644 --- a/shopfloor_reception/tests/test_set_quantity_action.py +++ b/shopfloor_reception/tests/test_set_quantity_action.py @@ -80,10 +80,10 @@ def test_process_without_package(self): ) self.assertFalse(self.selected_move_line.result_package_id) - def test_cancel_action(self): - picking = self._create_picking() + def test_cancel_action_concurrent(self): + picking = self.picking move_product_a = picking.move_ids.filtered( - lambda l: l.product_id == self.product_a + lambda m: m.product_id == self.product_a ) # User 1 and 2 selects the same picking service_user_1 = self.service @@ -169,3 +169,52 @@ def test_cancel_action(self): ) # This line has been created by shopfloor, therefore, we unlinked it self.assertFalse(move_line_user_2.exists()) + + def test_cancel_action_no_backorder(self): + picking = self.picking + move_line = self.selected_move_line + move = self.selected_move_line.move_id + + self.service.dispatch( + "process_without_pack", + params={ + "picking_id": picking.id, + "selected_line_id": move_line.id, + "quantity": 2, + }, + ) + self.assertEqual(move.quantity_done, 2) + self.assertEqual(len(move.move_line_ids), 2) + + new_move_line = move.move_line_ids - move_line + self.assertEqual(new_move_line.reserved_qty, 8) + + # Make some modifications on the new move line + self.service.dispatch( + "set_quantity", + params={ + "picking_id": picking.id, + "selected_line_id": new_move_line.id, + "quantity": 3, + }, + ) + new_move_line.lot_id = self._create_lot() + self.assertTrue(new_move_line.lot_id) + self.assertTrue(new_move_line.qty_done) + + # cancel modifications on new move line + self.service.dispatch( + "set_quantity__cancel_action", + params={ + "picking_id": picking.id, + "selected_line_id": new_move_line.id, + }, + ) + self.assertTrue(new_move_line.exists()) + self.assertEqual(new_move_line.reserved_qty, 8) + self.assertFalse(new_move_line.lot_id) + self.assertEqual( + new_move_line.picking_id, + move_line.picking_id, + "Cancelling the move line should not move it into a backorder", + ) diff --git a/shopfloor_reception_mobile/README.rst b/shopfloor_reception_mobile/README.rst index 08644d8a2b7..c31048cc289 100644 --- a/shopfloor_reception_mobile/README.rst +++ b/shopfloor_reception_mobile/README.rst @@ -11,7 +11,7 @@ Shopfloor reception mobile !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e6e5bdb9f20c104e11b2d9c6c67bdf6b418ca342dd36317955c679a68d278ca4 + !! source digest: sha256:379f4cd0674b8cebf272d622ff9e2103d9cc92fdf9bb6c0b3c685d57aaa10f49 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor_reception_mobile/__manifest__.py b/shopfloor_reception_mobile/__manifest__.py index 88acd316c1d..3511b01fe03 100644 --- a/shopfloor_reception_mobile/__manifest__.py +++ b/shopfloor_reception_mobile/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Shopfloor reception mobile", "summary": "Scenario for receiving products", - "version": "16.0.1.1.2", + "version": "16.0.1.1.3", "development_status": "Beta", "depends": ["shopfloor_mobile_base", "shopfloor_mobile", "shopfloor_reception"], "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/shopfloor_reception_mobile/static/description/index.html b/shopfloor_reception_mobile/static/description/index.html index 97f13521bbf..d7c48940536 100644 --- a/shopfloor_reception_mobile/static/description/index.html +++ b/shopfloor_reception_mobile/static/description/index.html @@ -372,7 +372,7 @@

Shopfloor reception mobile

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:e6e5bdb9f20c104e11b2d9c6c67bdf6b418ca342dd36317955c679a68d278ca4 +!! source digest: sha256:379f4cd0674b8cebf272d622ff9e2103d9cc92fdf9bb6c0b3c685d57aaa10f49 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Frontend for the reception scenario in shopfloor. diff --git a/shopfloor_reception_mobile/static/src/scenario/reception.js b/shopfloor_reception_mobile/static/src/scenario/reception.js index ce2117091a5..135091ccb0a 100644 --- a/shopfloor_reception_mobile/static/src/scenario/reception.js +++ b/shopfloor_reception_mobile/static/src/scenario/reception.js @@ -155,7 +155,7 @@ const Reception = { - +