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 |
| 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 |
| 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 |
| Filters channels on sales based on selected carrier.
-[shopfloor](shopfloor/) | 16.0.2.16.2 |
| manage warehouse operations with barcode scanners
+[shopfloor](shopfloor/) | 16.0.2.16.3 |
| manage warehouse operations with barcode scanners
[shopfloor_base](shopfloor_base/) | 16.0.1.2.1 |
| Core module for creating mobile apps
[shopfloor_batch_automatic_creation](shopfloor_batch_automatic_creation/) | 16.0.1.1.0 |
| Create batch transfers for Cluster Picking
[shopfloor_mobile](shopfloor_mobile/) | 16.0.1.4.1 |
| Mobile frontend for WMS Shopfloor app
[shopfloor_mobile_base](shopfloor_mobile_base/) | 16.0.1.2.0 |
| 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 |
| Reception scenario for shopfloor
-[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.2 |
| Scenario for receiving products
+[shopfloor_reception](shopfloor_reception/) | 16.0.1.6.8 |
| Reception scenario for shopfloor
+[shopfloor_reception_mobile](shopfloor_reception_mobile/) | 16.0.1.1.3 |
| Scenario for receiving products
[shopfloor_reception_refund_return](shopfloor_reception_refund_return/) | 16.0.1.0.0 |
| Mark created return as to refund
[shopfloor_rest_log](shopfloor_rest_log/) | 16.0.1.0.0 |
| 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 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 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 @@
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 = {