odoo-addon-shopfloor 16.0.1.0.0.24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. odoo/addons/shopfloor/README.rst +160 -0
  2. odoo/addons/shopfloor/__init__.py +4 -0
  3. odoo/addons/shopfloor/__manifest__.py +65 -0
  4. odoo/addons/shopfloor/actions/__init__.py +15 -0
  5. odoo/addons/shopfloor/actions/change_package_lot.py +164 -0
  6. odoo/addons/shopfloor/actions/completion_info.py +42 -0
  7. odoo/addons/shopfloor/actions/data.py +329 -0
  8. odoo/addons/shopfloor/actions/data_detail.py +154 -0
  9. odoo/addons/shopfloor/actions/inventory.py +150 -0
  10. odoo/addons/shopfloor/actions/location_content_transfer_sorter.py +89 -0
  11. odoo/addons/shopfloor/actions/message.py +846 -0
  12. odoo/addons/shopfloor/actions/move_line_search.py +119 -0
  13. odoo/addons/shopfloor/actions/packaging.py +59 -0
  14. odoo/addons/shopfloor/actions/savepoint.py +44 -0
  15. odoo/addons/shopfloor/actions/schema.py +182 -0
  16. odoo/addons/shopfloor/actions/schema_detail.py +98 -0
  17. odoo/addons/shopfloor/actions/search.py +187 -0
  18. odoo/addons/shopfloor/actions/stock.py +239 -0
  19. odoo/addons/shopfloor/actions/stock_unreserve.py +66 -0
  20. odoo/addons/shopfloor/components/__init__.py +5 -0
  21. odoo/addons/shopfloor/components/scan_handler_location.py +26 -0
  22. odoo/addons/shopfloor/components/scan_handler_lot.py +26 -0
  23. odoo/addons/shopfloor/components/scan_handler_package.py +26 -0
  24. odoo/addons/shopfloor/components/scan_handler_product.py +26 -0
  25. odoo/addons/shopfloor/components/scan_handler_transfer.py +26 -0
  26. odoo/addons/shopfloor/data/shopfloor_scenario_data.xml +73 -0
  27. odoo/addons/shopfloor/demo/shopfloor_app_demo.xml +12 -0
  28. odoo/addons/shopfloor/demo/shopfloor_menu_demo.xml +64 -0
  29. odoo/addons/shopfloor/demo/shopfloor_profile_demo.xml +8 -0
  30. odoo/addons/shopfloor/demo/stock_picking_type_demo.xml +93 -0
  31. odoo/addons/shopfloor/docs/checkout_diag_seq.plantuml +61 -0
  32. odoo/addons/shopfloor/docs/checkout_diag_seq.png +0 -0
  33. odoo/addons/shopfloor/docs/cluster_picking_diag_seq.plantuml +112 -0
  34. odoo/addons/shopfloor/docs/cluster_picking_diag_seq.png +0 -0
  35. odoo/addons/shopfloor/docs/delivery_diag_seq.plantuml +56 -0
  36. odoo/addons/shopfloor/docs/delivery_diag_seq.png +0 -0
  37. odoo/addons/shopfloor/docs/location_content_transfer_diag_seq.plantuml +66 -0
  38. odoo/addons/shopfloor/docs/location_content_transfer_diag_seq.png +0 -0
  39. odoo/addons/shopfloor/docs/oca_logo.png +0 -0
  40. odoo/addons/shopfloor/docs/single_pack_transfer_diag_seq.plantuml +36 -0
  41. odoo/addons/shopfloor/docs/single_pack_transfer_diag_seq.png +0 -0
  42. odoo/addons/shopfloor/docs/zone_picking_diag_seq.plantuml +85 -0
  43. odoo/addons/shopfloor/docs/zone_picking_diag_seq.png +0 -0
  44. odoo/addons/shopfloor/exceptions.py +6 -0
  45. odoo/addons/shopfloor/i18n/ca.po +1802 -0
  46. odoo/addons/shopfloor/i18n/de.po +1791 -0
  47. odoo/addons/shopfloor/i18n/es_AR.po +2147 -0
  48. odoo/addons/shopfloor/i18n/pt_BR.po +1791 -0
  49. odoo/addons/shopfloor/i18n/shopfloor.pot +1877 -0
  50. odoo/addons/shopfloor/models/__init__.py +12 -0
  51. odoo/addons/shopfloor/models/priority_postpone_mixin.py +41 -0
  52. odoo/addons/shopfloor/models/shopfloor_app.py +9 -0
  53. odoo/addons/shopfloor/models/shopfloor_menu.py +436 -0
  54. odoo/addons/shopfloor/models/stock_location.py +76 -0
  55. odoo/addons/shopfloor/models/stock_move.py +119 -0
  56. odoo/addons/shopfloor/models/stock_move_line.py +307 -0
  57. odoo/addons/shopfloor/models/stock_package_level.py +50 -0
  58. odoo/addons/shopfloor/models/stock_picking.py +118 -0
  59. odoo/addons/shopfloor/models/stock_picking_batch.py +41 -0
  60. odoo/addons/shopfloor/models/stock_picking_type.py +26 -0
  61. odoo/addons/shopfloor/models/stock_quant.py +31 -0
  62. odoo/addons/shopfloor/models/stock_quant_package.py +101 -0
  63. odoo/addons/shopfloor/readme/CONTRIBUTORS.rst +18 -0
  64. odoo/addons/shopfloor/readme/CREDITS.rst +5 -0
  65. odoo/addons/shopfloor/readme/DESCRIPTION.rst +17 -0
  66. odoo/addons/shopfloor/readme/HISTORY.rst +4 -0
  67. odoo/addons/shopfloor/readme/ROADMAP.rst +4 -0
  68. odoo/addons/shopfloor/readme/USAGE.rst +6 -0
  69. odoo/addons/shopfloor/security/groups.xml +17 -0
  70. odoo/addons/shopfloor/services/__init__.py +16 -0
  71. odoo/addons/shopfloor/services/checkout.py +1763 -0
  72. odoo/addons/shopfloor/services/cluster_picking.py +1628 -0
  73. odoo/addons/shopfloor/services/delivery.py +828 -0
  74. odoo/addons/shopfloor/services/forms/__init__.py +1 -0
  75. odoo/addons/shopfloor/services/forms/picking_form.py +78 -0
  76. odoo/addons/shopfloor/services/location_content_transfer.py +1194 -0
  77. odoo/addons/shopfloor/services/menu.py +60 -0
  78. odoo/addons/shopfloor/services/picking_batch.py +126 -0
  79. odoo/addons/shopfloor/services/service.py +101 -0
  80. odoo/addons/shopfloor/services/single_pack_transfer.py +366 -0
  81. odoo/addons/shopfloor/services/zone_picking.py +1938 -0
  82. odoo/addons/shopfloor/static/description/icon.png +0 -0
  83. odoo/addons/shopfloor/static/description/index.html +500 -0
  84. odoo/addons/shopfloor/tests/__init__.py +83 -0
  85. odoo/addons/shopfloor/tests/common.py +324 -0
  86. odoo/addons/shopfloor/tests/models.py +29 -0
  87. odoo/addons/shopfloor/tests/test_actions_change_package_lot.py +1175 -0
  88. odoo/addons/shopfloor/tests/test_actions_data.py +376 -0
  89. odoo/addons/shopfloor/tests/test_actions_data_base.py +244 -0
  90. odoo/addons/shopfloor/tests/test_actions_data_detail.py +322 -0
  91. odoo/addons/shopfloor/tests/test_actions_search.py +248 -0
  92. odoo/addons/shopfloor/tests/test_actions_stock.py +48 -0
  93. odoo/addons/shopfloor/tests/test_checkout_auto_post.py +67 -0
  94. odoo/addons/shopfloor/tests/test_checkout_base.py +81 -0
  95. odoo/addons/shopfloor/tests/test_checkout_cancel_line.py +154 -0
  96. odoo/addons/shopfloor/tests/test_checkout_change_packaging.py +184 -0
  97. odoo/addons/shopfloor/tests/test_checkout_done.py +133 -0
  98. odoo/addons/shopfloor/tests/test_checkout_list_delivery_packaging.py +131 -0
  99. odoo/addons/shopfloor/tests/test_checkout_list_package.py +327 -0
  100. odoo/addons/shopfloor/tests/test_checkout_new_package.py +88 -0
  101. odoo/addons/shopfloor/tests/test_checkout_no_package.py +95 -0
  102. odoo/addons/shopfloor/tests/test_checkout_scan.py +174 -0
  103. odoo/addons/shopfloor/tests/test_checkout_scan_line.py +377 -0
  104. odoo/addons/shopfloor/tests/test_checkout_scan_line_base.py +25 -0
  105. odoo/addons/shopfloor/tests/test_checkout_scan_line_no_prefill_qty.py +91 -0
  106. odoo/addons/shopfloor/tests/test_checkout_scan_package_action.py +451 -0
  107. odoo/addons/shopfloor/tests/test_checkout_scan_package_action_no_prefill_qty.py +107 -0
  108. odoo/addons/shopfloor/tests/test_checkout_select.py +74 -0
  109. odoo/addons/shopfloor/tests/test_checkout_select_line.py +130 -0
  110. odoo/addons/shopfloor/tests/test_checkout_select_package_base.py +64 -0
  111. odoo/addons/shopfloor/tests/test_checkout_set_qty.py +257 -0
  112. odoo/addons/shopfloor/tests/test_checkout_summary.py +69 -0
  113. odoo/addons/shopfloor/tests/test_cluster_picking_base.py +83 -0
  114. odoo/addons/shopfloor/tests/test_cluster_picking_batch.py +109 -0
  115. odoo/addons/shopfloor/tests/test_cluster_picking_change_pack_lot.py +111 -0
  116. odoo/addons/shopfloor/tests/test_cluster_picking_is_zero.py +98 -0
  117. odoo/addons/shopfloor/tests/test_cluster_picking_scan_destination.py +376 -0
  118. odoo/addons/shopfloor/tests/test_cluster_picking_scan_destination_no_prefill_qty.py +115 -0
  119. odoo/addons/shopfloor/tests/test_cluster_picking_scan_line.py +402 -0
  120. odoo/addons/shopfloor/tests/test_cluster_picking_scan_line_location_or_pack_first.py +114 -0
  121. odoo/addons/shopfloor/tests/test_cluster_picking_scan_line_no_prefill_qty.py +70 -0
  122. odoo/addons/shopfloor/tests/test_cluster_picking_select.py +387 -0
  123. odoo/addons/shopfloor/tests/test_cluster_picking_skip.py +90 -0
  124. odoo/addons/shopfloor/tests/test_cluster_picking_stock_issue.py +364 -0
  125. odoo/addons/shopfloor/tests/test_cluster_picking_unload.py +911 -0
  126. odoo/addons/shopfloor/tests/test_delivery_base.py +155 -0
  127. odoo/addons/shopfloor/tests/test_delivery_done.py +108 -0
  128. odoo/addons/shopfloor/tests/test_delivery_list_stock_picking.py +49 -0
  129. odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_line.py +119 -0
  130. odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_pack.py +107 -0
  131. odoo/addons/shopfloor/tests/test_delivery_scan_deliver.py +557 -0
  132. odoo/addons/shopfloor/tests/test_delivery_select.py +38 -0
  133. odoo/addons/shopfloor/tests/test_delivery_set_qty_done_line.py +91 -0
  134. odoo/addons/shopfloor/tests/test_delivery_set_qty_done_pack.py +135 -0
  135. odoo/addons/shopfloor/tests/test_delivery_sublocation.py +180 -0
  136. odoo/addons/shopfloor/tests/test_location_content_transfer_base.py +136 -0
  137. odoo/addons/shopfloor/tests/test_location_content_transfer_get_work.py +125 -0
  138. odoo/addons/shopfloor/tests/test_location_content_transfer_mix.py +509 -0
  139. odoo/addons/shopfloor/tests/test_location_content_transfer_putaway.py +143 -0
  140. odoo/addons/shopfloor/tests/test_location_content_transfer_scan_location.py +34 -0
  141. odoo/addons/shopfloor/tests/test_location_content_transfer_set_destination_all.py +343 -0
  142. odoo/addons/shopfloor/tests/test_location_content_transfer_set_destination_package_or_line.py +1074 -0
  143. odoo/addons/shopfloor/tests/test_location_content_transfer_single.py +748 -0
  144. odoo/addons/shopfloor/tests/test_location_content_transfer_start.py +359 -0
  145. odoo/addons/shopfloor/tests/test_menu_base.py +261 -0
  146. odoo/addons/shopfloor/tests/test_menu_counters.py +61 -0
  147. odoo/addons/shopfloor/tests/test_misc.py +25 -0
  148. odoo/addons/shopfloor/tests/test_move_action_assign.py +87 -0
  149. odoo/addons/shopfloor/tests/test_openapi.py +21 -0
  150. odoo/addons/shopfloor/tests/test_picking_form.py +62 -0
  151. odoo/addons/shopfloor/tests/test_scan_anything.py +49 -0
  152. odoo/addons/shopfloor/tests/test_single_pack_transfer.py +1121 -0
  153. odoo/addons/shopfloor/tests/test_single_pack_transfer_base.py +32 -0
  154. odoo/addons/shopfloor/tests/test_single_pack_transfer_putaway.py +104 -0
  155. odoo/addons/shopfloor/tests/test_stock_split.py +204 -0
  156. odoo/addons/shopfloor/tests/test_user.py +42 -0
  157. odoo/addons/shopfloor/tests/test_zone_picking_base.py +608 -0
  158. odoo/addons/shopfloor/tests/test_zone_picking_change_pack_lot.py +140 -0
  159. odoo/addons/shopfloor/tests/test_zone_picking_select_line.py +723 -0
  160. odoo/addons/shopfloor/tests/test_zone_picking_select_line_first_scan_location.py +207 -0
  161. odoo/addons/shopfloor/tests/test_zone_picking_select_line_first_scan_location.py.bak +202 -0
  162. odoo/addons/shopfloor/tests/test_zone_picking_select_line_no_prefill_qty.py +107 -0
  163. odoo/addons/shopfloor/tests/test_zone_picking_select_picking_type.py +26 -0
  164. odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination.py +643 -0
  165. odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_no_prefill_qty.py +146 -0
  166. odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_pick_pack.py +241 -0
  167. odoo/addons/shopfloor/tests/test_zone_picking_start.py +206 -0
  168. odoo/addons/shopfloor/tests/test_zone_picking_stock_issue.py +121 -0
  169. odoo/addons/shopfloor/tests/test_zone_picking_unload_all.py +353 -0
  170. odoo/addons/shopfloor/tests/test_zone_picking_unload_buffer_lines.py +113 -0
  171. odoo/addons/shopfloor/tests/test_zone_picking_unload_set_destination.py +374 -0
  172. odoo/addons/shopfloor/tests/test_zone_picking_unload_single.py +123 -0
  173. odoo/addons/shopfloor/tests/test_zone_picking_zero_check.py +43 -0
  174. odoo/addons/shopfloor/utils.py +13 -0
  175. odoo/addons/shopfloor/views/shopfloor_menu.xml +167 -0
  176. odoo/addons/shopfloor/views/stock_location.xml +20 -0
  177. odoo/addons/shopfloor/views/stock_move_line.xml +52 -0
  178. odoo/addons/shopfloor/views/stock_picking_type.xml +19 -0
  179. odoo_addon_shopfloor-16.0.1.0.0.24.dist-info/METADATA +192 -0
  180. odoo_addon_shopfloor-16.0.1.0.0.24.dist-info/RECORD +182 -0
  181. odoo_addon_shopfloor-16.0.1.0.0.24.dist-info/WHEEL +5 -0
  182. odoo_addon_shopfloor-16.0.1.0.0.24.dist-info/top_level.txt +1 -0
@@ -0,0 +1,121 @@
1
+ # Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
+ from .test_zone_picking_base import ZonePickingCommonCase
4
+
5
+
6
+ # pylint: disable=missing-return
7
+ class ZonePickingStockIssueCase(ZonePickingCommonCase):
8
+ """Tests for endpoint used from stock_issue
9
+
10
+ * /stock_issue
11
+
12
+ """
13
+
14
+ def setUp(self):
15
+ super().setUp()
16
+ self.service.work.current_picking_type = self.picking1.picking_type_id
17
+
18
+ def test_stock_issue_wrong_parameters(self):
19
+ response = self.service.dispatch(
20
+ "stock_issue",
21
+ params={"move_line_id": 1234567890},
22
+ )
23
+ self.assert_response_start(
24
+ response,
25
+ message=self.service.msg_store.record_not_found(),
26
+ )
27
+
28
+ def test_stock_issue_no_more_reservation(self):
29
+ zone_location = self.zone_location
30
+ picking_type = self.picking1.picking_type_id
31
+ move_line = self.picking1.move_line_ids[0]
32
+ move = move_line.move_id
33
+ response = self.service.dispatch(
34
+ "stock_issue",
35
+ params={"move_line_id": move_line.id},
36
+ )
37
+ self.assertFalse(move_line.exists())
38
+ self.assertFalse(move.move_line_ids)
39
+ move_lines = self.service._find_location_move_lines()
40
+ self.assert_response_select_line(
41
+ response,
42
+ zone_location,
43
+ picking_type,
44
+ move_lines,
45
+ )
46
+
47
+ def test_stock_issue1(self):
48
+ """Once the stock issue is done, the move can't be reserved anymore."""
49
+ zone_location = self.zone_location
50
+ picking_type = self.picking1.picking_type_id
51
+ move_line = self.picking1.move_line_ids[0]
52
+ move = move_line.move_id
53
+ response = self.service.dispatch(
54
+ "stock_issue",
55
+ params={"move_line_id": move_line.id},
56
+ )
57
+ self.assertFalse(move_line.exists())
58
+ self.assertFalse(move.move_line_ids)
59
+ move_lines = self.service._find_location_move_lines()
60
+ self.assert_response_select_line(
61
+ response,
62
+ zone_location,
63
+ picking_type,
64
+ move_lines,
65
+ )
66
+
67
+ def test_stock_issue2(self):
68
+ """Once the stock issue is done, the move has been reserved again."""
69
+ zone_location = self.zone_location
70
+ picking_type = self.picking1.picking_type_id
71
+ move_line = self.picking1.move_line_ids[0]
72
+ location = move_line.location_id
73
+ move = move_line.move_id
74
+ quants_before = self.env["stock.quant"].search(
75
+ [("location_id", "=", location.id), ("product_id", "=", move.product_id.id)]
76
+ )
77
+ # Increase the quantity in the current location
78
+ self._update_qty_in_location(location, move.product_id, 100)
79
+ response = self.service.dispatch(
80
+ "stock_issue",
81
+ params={"move_line_id": move_line.id},
82
+ )
83
+ self.assertFalse(move_line.exists())
84
+ self.assertTrue(move.move_line_ids)
85
+ self.assertEqual(move.move_line_ids.location_id, location)
86
+ self.assert_response_set_line_destination(
87
+ response,
88
+ zone_location,
89
+ picking_type,
90
+ move.move_line_ids,
91
+ )
92
+ # Check the inventory
93
+ quants_after = self.env["stock.quant"].search(
94
+ [("location_id", "=", location.id), ("product_id", "=", move.product_id.id)]
95
+ )
96
+ inventory_quant = quants_after - quants_before
97
+ self.assertTrue(inventory_quant)
98
+
99
+ def test_stock_issue3(self):
100
+ """Once the stock issue is done, the move has been reserved again
101
+ but from another location.
102
+ """
103
+ zone_location = self.zone_location
104
+ picking_type = self.picking1.picking_type_id
105
+ move_line = self.picking1.move_line_ids[0]
106
+ move = move_line.move_id
107
+ # Put some quantity in another location to get a new reservations from there
108
+ self._update_qty_in_location(self.zone_sublocation2, move.product_id, 10)
109
+ response = self.service.dispatch(
110
+ "stock_issue",
111
+ params={"move_line_id": move_line.id},
112
+ )
113
+ self.assertFalse(move_line.exists())
114
+ self.assertTrue(move.move_line_ids)
115
+ self.assertEqual(move.move_line_ids.location_id, self.zone_sublocation2)
116
+ self.assert_response_set_line_destination(
117
+ response,
118
+ zone_location,
119
+ picking_type,
120
+ move.move_line_ids,
121
+ )
@@ -0,0 +1,353 @@
1
+ # Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
+ from .test_zone_picking_base import ZonePickingCommonCase
4
+
5
+
6
+ # pylint: disable=missing-return
7
+ class ZonePickingUnloadAllCase(ZonePickingCommonCase):
8
+ """Tests for endpoint used from unload_all
9
+
10
+ * /set_destination_all
11
+ * /unload_split
12
+
13
+ """
14
+
15
+ def setUp(self):
16
+ super().setUp()
17
+ self.service.work.current_picking_type = self.picking1.picking_type_id
18
+
19
+ def test_set_destination_all_different_destination(self):
20
+ zone_location = self.zone_location
21
+ picking_type = self.picking1.picking_type_id
22
+ move_line1 = self.picking5.move_line_ids[0]
23
+ move_line2 = self.picking5.move_line_ids[1]
24
+ another_package = self.env["stock.quant.package"].create(
25
+ {"name": "ANOTHER_PACKAGE"}
26
+ )
27
+ # change the destination location of one move line
28
+ move_line2.location_dest_id = self.zone_sublocation3
29
+ # set the destination package on lines
30
+ self.service._set_destination_package(
31
+ move_line1,
32
+ move_line1.reserved_uom_qty,
33
+ self.free_package,
34
+ )
35
+ self.service._set_destination_package(
36
+ move_line2,
37
+ move_line2.reserved_uom_qty,
38
+ another_package,
39
+ )
40
+ # set destination location for all lines in the buffer
41
+ response = self.service.dispatch(
42
+ "set_destination_all",
43
+ params={"barcode": self.packing_location.barcode},
44
+ )
45
+ # check response
46
+ buffer_lines = self.service._find_buffer_move_lines()
47
+ self.assert_response_unload_all(
48
+ response,
49
+ zone_location,
50
+ picking_type,
51
+ buffer_lines,
52
+ message=self.service.msg_store.lines_different_dest_location(),
53
+ )
54
+
55
+ def test_set_destination_all_confirm_destination(self):
56
+ zone_location = self.zone_location
57
+ picking_type = self.picking1.picking_type_id
58
+ move_line1 = self.picking5.move_line_ids[0]
59
+ move_line2 = self.picking5.move_line_ids[1]
60
+ another_package = self.env["stock.quant.package"].create(
61
+ {"name": "ANOTHER_PACKAGE"}
62
+ )
63
+ packing_sublocation1 = (
64
+ self.env["stock.location"]
65
+ .sudo()
66
+ .create(
67
+ {
68
+ "name": "Packing sublocation-1",
69
+ "location_id": self.packing_location.id,
70
+ "barcode": "PACKING_SUBLOCATION_1",
71
+ }
72
+ )
73
+ )
74
+ packing_sublocation2 = (
75
+ self.env["stock.location"]
76
+ .sudo()
77
+ .create(
78
+ {
79
+ "name": "Packing sublocation-2",
80
+ "location_id": self.packing_location.id,
81
+ "barcode": "PACKING_SUBLOCATION_2",
82
+ }
83
+ )
84
+ )
85
+ # set the destination package on lines
86
+ self.service._set_destination_package(
87
+ move_line1,
88
+ move_line1.reserved_uom_qty,
89
+ self.free_package,
90
+ )
91
+ self.service._set_destination_package(
92
+ move_line2,
93
+ move_line2.reserved_uom_qty,
94
+ another_package,
95
+ )
96
+ # set an allowed destination location (inside the picking type default
97
+ # destination location) for all lines in the buffer with a non-expected
98
+ # one, meaning a destination which is not a child of the current buffer
99
+ # lines destination
100
+ (move_line1 | move_line2).location_dest_id = packing_sublocation1
101
+ response = self.service.dispatch(
102
+ "set_destination_all",
103
+ params={"barcode": packing_sublocation2.barcode},
104
+ )
105
+ # check response: this destination needs the user confirmation
106
+ buffer_lines = self.service._find_buffer_move_lines()
107
+ self.assert_response_unload_all(
108
+ response,
109
+ zone_location,
110
+ picking_type,
111
+ buffer_lines,
112
+ message=self.service.msg_store.confirm_location_changed(
113
+ packing_sublocation1,
114
+ packing_sublocation2,
115
+ ),
116
+ confirmation_required=True,
117
+ )
118
+ # set an allowed destination location (inside the picking type default
119
+ # destination location) for all lines in the buffer with an expected one
120
+ # meaning a destination which is a child of the current buffer lines
121
+ # destination
122
+ response = self.service.dispatch(
123
+ "set_destination_all",
124
+ params={"barcode": packing_sublocation1.barcode},
125
+ )
126
+ # check response: OK
127
+ move_lines = self.service._find_location_move_lines()
128
+ self.assert_response_select_line(
129
+ response,
130
+ zone_location,
131
+ picking_type,
132
+ move_lines,
133
+ message=self.service.msg_store.buffer_complete(),
134
+ )
135
+
136
+ def test_set_destination_all_ok(self):
137
+ zone_location = self.zone_location
138
+ picking_type = self.picking1.picking_type_id
139
+ move_line1 = self.picking5.move_line_ids[0]
140
+ move_line2 = self.picking5.move_line_ids[1]
141
+ another_package = self.env["stock.quant.package"].create(
142
+ {"name": "ANOTHER_PACKAGE"}
143
+ )
144
+ # set the destination package on lines
145
+ self.service._set_destination_package(
146
+ move_line1,
147
+ move_line1.reserved_uom_qty,
148
+ self.free_package,
149
+ )
150
+ self.service._set_destination_package(
151
+ move_line2,
152
+ move_line2.reserved_uom_qty,
153
+ another_package,
154
+ )
155
+ # set destination location for all lines in the buffer
156
+ response = self.service.dispatch(
157
+ "set_destination_all",
158
+ params={"barcode": self.packing_location.barcode},
159
+ )
160
+ # check data
161
+ self.assertEqual(self.picking5.state, "done")
162
+ # buffer should be empty
163
+ buffer_lines = self.service._find_buffer_move_lines()
164
+ self.assertFalse(buffer_lines)
165
+ # check response
166
+ move_lines = self.service._find_location_move_lines()
167
+ self.assert_response_select_line(
168
+ response,
169
+ zone_location,
170
+ picking_type,
171
+ move_lines,
172
+ message=self.service.msg_store.buffer_complete(),
173
+ )
174
+
175
+ def test_set_destination_all_partial_qty_done_ok(self):
176
+ zone_location = self.zone_location
177
+ picking_type = self.picking6.picking_type_id
178
+ move_g = self.picking6.move_ids.filtered(
179
+ lambda m: m.product_id == self.product_g
180
+ )
181
+ move_h = self.picking6.move_ids.filtered(
182
+ lambda m: m.product_id == self.product_h
183
+ )
184
+ self.assertEqual(move_g.state, "assigned")
185
+ self.assertEqual(move_h.state, "partially_available")
186
+ move_line_g = move_g.move_line_ids
187
+ move_line_h = move_h.move_line_ids
188
+ another_package = self.env["stock.quant.package"].create(
189
+ {"name": "ANOTHER_PACKAGE"}
190
+ )
191
+ # set the destination package on lines
192
+ self.service._set_destination_package(
193
+ move_line_g,
194
+ move_line_g.reserved_uom_qty,
195
+ self.free_package,
196
+ )
197
+ self.service._set_destination_package(
198
+ move_line_h,
199
+ move_line_h.reserved_uom_qty,
200
+ another_package, # partial qty
201
+ )
202
+ # set destination location for all lines in the buffer
203
+ response = self.service.dispatch(
204
+ "set_destination_all",
205
+ params={"barcode": self.packing_location.barcode},
206
+ )
207
+ # check data
208
+ # picking validated
209
+ self.assertEqual(move_line_g.state, "done")
210
+ self.assertEqual(move_line_g.picking_id.state, "done")
211
+ self.assertEqual(move_line_g.qty_done, 6)
212
+ self.assertEqual(move_line_h.state, "done")
213
+ self.assertEqual(move_line_h.picking_id.state, "done")
214
+ self.assertEqual(move_line_h.qty_done, 3)
215
+ # current picking (backorder)
216
+ backorder = (move_line_g | move_line_h).picking_id.backorder_id
217
+ self.assertEqual(backorder, self.picking6)
218
+ self.assertEqual(backorder.state, "confirmed")
219
+ self.assertEqual(backorder.move_ids.product_id, self.product_h)
220
+ self.assertEqual(backorder.move_ids.product_uom_qty, 3)
221
+ self.assertFalse(backorder.move_line_ids)
222
+ # buffer should be empty
223
+ buffer_lines = self.service._find_buffer_move_lines()
224
+ self.assertFalse(buffer_lines)
225
+ # check response
226
+ move_lines = self.service._find_location_move_lines()
227
+ self.assert_response_select_line(
228
+ response,
229
+ zone_location,
230
+ picking_type,
231
+ move_lines,
232
+ message=self.service.msg_store.buffer_complete(),
233
+ )
234
+
235
+ def test_set_destination_all_location_not_allowed(self):
236
+ zone_location = self.zone_location
237
+ picking_type = self.picking1.picking_type_id
238
+ move_line = self.picking1.move_line_ids
239
+ # set the destination package on lines
240
+ self.service._set_destination_package(
241
+ move_line,
242
+ move_line.reserved_uom_qty,
243
+ self.free_package,
244
+ )
245
+ response = self.service.dispatch(
246
+ "set_destination_all",
247
+ params={"barcode": self.customer_location.barcode},
248
+ )
249
+ # check response
250
+ buffer_lines = self.service._find_buffer_move_lines()
251
+ self.assert_response_unload_all(
252
+ response,
253
+ zone_location,
254
+ picking_type,
255
+ buffer_lines,
256
+ message=self.service.msg_store.location_not_allowed(),
257
+ )
258
+
259
+ def test_set_destination_all_location_not_found(self):
260
+ zone_location = self.zone_location
261
+ picking_type = self.picking1.picking_type_id
262
+ move_line = self.picking1.move_line_ids
263
+ # set the destination package on lines
264
+ self.service._set_destination_package(
265
+ move_line,
266
+ move_line.reserved_uom_qty,
267
+ self.free_package,
268
+ )
269
+ response = self.service.dispatch(
270
+ "set_destination_all",
271
+ params={"barcode": "UNKNOWN"},
272
+ )
273
+ # check response
274
+ buffer_lines = self.service._find_buffer_move_lines()
275
+ self.assert_response_unload_all(
276
+ response,
277
+ zone_location,
278
+ picking_type,
279
+ buffer_lines,
280
+ message=self.service.msg_store.no_location_found(),
281
+ )
282
+
283
+ def test_unload_split_buffer_empty(self):
284
+ zone_location = self.zone_location
285
+ picking_type = self.picking1.picking_type_id
286
+ response = self.service.dispatch(
287
+ "unload_split",
288
+ params={},
289
+ )
290
+ # check response
291
+ move_lines = self.service._find_location_move_lines()
292
+ self.assert_response_select_line(
293
+ response,
294
+ zone_location,
295
+ picking_type,
296
+ move_lines,
297
+ message=self.service.msg_store.buffer_complete(),
298
+ )
299
+
300
+ def test_unload_split_buffer_one_line(self):
301
+ zone_location = self.zone_location
302
+ picking_type = self.picking1.picking_type_id
303
+ move_line = self.picking1.move_line_ids
304
+ # put one line in the buffer
305
+ self.service._set_destination_package(
306
+ move_line,
307
+ move_line.reserved_uom_qty,
308
+ self.free_package,
309
+ )
310
+ response = self.service.dispatch(
311
+ "unload_split",
312
+ params={},
313
+ )
314
+ # check response
315
+ buffer_lines = self.service._find_buffer_move_lines()
316
+ self.assert_response_unload_set_destination(
317
+ response,
318
+ zone_location,
319
+ picking_type,
320
+ buffer_lines,
321
+ )
322
+
323
+ def test_unload_split_buffer_multi_lines(self):
324
+ zone_location = self.zone_location
325
+ picking_type = self.picking5.picking_type_id
326
+ move_line = self.picking5.move_line_ids
327
+ # put several lines in the buffer
328
+ self.another_package = self.env["stock.quant.package"].create(
329
+ {"name": "ANOTHER_PACKAGE"}
330
+ )
331
+ for move_line, package_dest in zip(
332
+ self.picking5.move_line_ids, self.free_package | self.another_package
333
+ ):
334
+ self.service._set_destination_package(
335
+ move_line,
336
+ move_line.reserved_uom_qty,
337
+ package_dest,
338
+ )
339
+ response = self.service.dispatch(
340
+ "unload_split",
341
+ params={},
342
+ )
343
+ # check response
344
+ buffer_lines = self.service._find_buffer_move_lines()
345
+ completion_info = self.service._actions_for("completion.info")
346
+ completion_info_popup = completion_info.popup(buffer_lines)
347
+ self.assert_response_unload_single(
348
+ response,
349
+ zone_location,
350
+ picking_type,
351
+ buffer_lines[0],
352
+ popup=completion_info_popup,
353
+ )
@@ -0,0 +1,113 @@
1
+ # Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
+ from .test_zone_picking_base import ZonePickingCommonCase
4
+
5
+
6
+ # pylint: disable=missing-return
7
+ class ZonePickingUnloadBufferLinesCase(ZonePickingCommonCase):
8
+ """Tests buffer lines to unload are retrieved properly.
9
+
10
+ Buffer lines are the lines processed during zone picking work.
11
+ At the end of her/his work, the user can unload all processed lines
12
+ in one or more destination.
13
+
14
+ Here we make sure all the lines are processable.
15
+ """
16
+
17
+ def setUp(self):
18
+ super().setUp()
19
+ self.service.work.current_picking_type = self.picking1.picking_type_id
20
+
21
+ def test_find_buffer_lines1(self):
22
+ move_lines = (
23
+ self.picking1.move_line_ids
24
+ | self.picking2.move_line_ids
25
+ | self.picking3.move_line_ids
26
+ | self.picking4.move_line_ids
27
+ )
28
+ zones = move_lines.mapped("location_id")
29
+ # we work on lines coming from 4 different locations
30
+ self.assertEqual(len(zones), 4)
31
+ # Process them all (simulate)
32
+ for i, line in enumerate(move_lines):
33
+ dest_package = self.env["stock.quant.package"].create(
34
+ {"name": f"TEST PKG {i}"}
35
+ )
36
+ self.service._set_destination_package(
37
+ line,
38
+ line.reserved_uom_qty,
39
+ dest_package,
40
+ )
41
+
42
+ # We can unload all the lines no matter which zone we are before unload
43
+ for zone in zones:
44
+ self.service.work.current_zone_location = zone
45
+ self.assertEqual(self.service._find_buffer_move_lines(), move_lines)
46
+
47
+ def test_find_buffer_lines2(self):
48
+ # Skip lines from picking1
49
+ move_lines = (
50
+ self.picking2.move_line_ids
51
+ | self.picking3.move_line_ids
52
+ | self.picking4.move_line_ids
53
+ )
54
+ zones = move_lines.mapped("location_id")
55
+ # we work on lines coming from 3 different locations
56
+ self.assertEqual(len(zones), 3)
57
+ # Process them all (simulate)
58
+ for i, line in enumerate(move_lines):
59
+ dest_package = self.env["stock.quant.package"].create(
60
+ {"name": f"TEST PKG {i}"}
61
+ )
62
+ self.service._set_destination_package(
63
+ line,
64
+ line.reserved_uom_qty,
65
+ dest_package,
66
+ )
67
+
68
+ # We can unload all the lines no matter which zone we are before unload
69
+ for zone in zones:
70
+ self.service.work.current_zone_location = zone
71
+ self.assertEqual(self.service._find_buffer_move_lines(), move_lines)
72
+ self.assertNotIn(
73
+ self.picking1.move_line_ids, self.service._find_buffer_move_lines()
74
+ )
75
+
76
+ def test_find_buffer_lines3(self):
77
+ move_lines = (
78
+ self.picking2.move_line_ids
79
+ | self.picking3.move_line_ids
80
+ | self.picking4.move_line_ids
81
+ )
82
+ zones = move_lines.mapped("location_id")
83
+ # we work on lines coming from 4 different locations
84
+ self.assertEqual(len(zones), 3)
85
+ # Process them all (simulate)
86
+ for i, line in enumerate(move_lines):
87
+ dest_package = self.env["stock.quant.package"].create(
88
+ {"name": f"TEST PKG {i}"}
89
+ )
90
+ self.service._set_destination_package(
91
+ line,
92
+ line.reserved_uom_qty,
93
+ dest_package,
94
+ )
95
+ # Simulate line from picking1 processed by another user
96
+ for i, line in enumerate(self.picking1.move_line_ids):
97
+ dest_package = self.env["stock.quant.package"].create(
98
+ {"name": f"TEST PKG 1 {i}"}
99
+ )
100
+ self.service._actions_for("stock").mark_move_line_as_picked(
101
+ line,
102
+ line.reserved_uom_qty,
103
+ dest_package,
104
+ user=self.env.ref("base.user_admin"),
105
+ )
106
+
107
+ # We can unload all the lines no matter which zone we are before unload
108
+ for zone in zones:
109
+ self.service.work.current_zone_location = zone
110
+ self.assertEqual(self.service._find_buffer_move_lines(), move_lines)
111
+ self.assertNotIn(
112
+ self.picking1.move_line_ids, self.service._find_buffer_move_lines()
113
+ )