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,343 @@
1
+ # Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
+
4
+ from .test_location_content_transfer_base import LocationContentTransferCommonCase
5
+
6
+ # pylint: disable=missing-return
7
+
8
+
9
+ class LocationContentTransferSetDestinationAllCase(LocationContentTransferCommonCase):
10
+ """Tests for endpoint used from scan_destination_all
11
+
12
+ * /set_destination_all
13
+ * /go_to_single
14
+
15
+ """
16
+
17
+ # TODO see what can be common
18
+ @classmethod
19
+ def setUpClassBaseData(cls):
20
+ super().setUpClassBaseData()
21
+ products = cls.product_a + cls.product_b + cls.product_c + cls.product_d
22
+ for product in products:
23
+ cls.env["stock.putaway.rule"].sudo().create(
24
+ {
25
+ "product_id": product.id,
26
+ "location_in_id": cls.stock_location.id,
27
+ "location_out_id": cls.shelf1.id,
28
+ }
29
+ )
30
+
31
+ cls.picking1 = picking1 = cls._create_picking(
32
+ lines=[(cls.product_a, 10), (cls.product_b, 10)]
33
+ )
34
+ cls.picking2 = picking2 = cls._create_picking(
35
+ lines=[(cls.product_c, 10), (cls.product_d, 10)]
36
+ )
37
+ cls.pickings = picking1 | picking2
38
+ cls._fill_stock_for_moves(
39
+ picking1.move_ids, in_package=True, location=cls.content_loc
40
+ )
41
+ cls._fill_stock_for_moves(picking2.move_ids, location=cls.content_loc)
42
+ cls.pickings.action_assign()
43
+ cls._simulate_pickings_selected(cls.pickings)
44
+
45
+ def assert_all_done(self, destination):
46
+ self.assertRecordValues(self.pickings, [{"state": "done"}, {"state": "done"}])
47
+ self.assertRecordValues(
48
+ self.pickings.move_line_ids,
49
+ [
50
+ {"qty_done": 10.0, "state": "done", "location_dest_id": destination.id},
51
+ {"qty_done": 10.0, "state": "done", "location_dest_id": destination.id},
52
+ {"qty_done": 10.0, "state": "done", "location_dest_id": destination.id},
53
+ {"qty_done": 10.0, "state": "done", "location_dest_id": destination.id},
54
+ ],
55
+ )
56
+ self.assertRecordValues(
57
+ self.picking1.package_level_ids,
58
+ [{"is_done": True, "state": "done", "location_dest_id": destination.id}],
59
+ )
60
+
61
+ def test_set_destination_all_dest_location_ok(self):
62
+ """Scanned destination location valid, moves set to done accepted"""
63
+ sub_shelf1 = (
64
+ self.env["stock.location"]
65
+ .sudo()
66
+ .create(
67
+ {
68
+ "name": "Sub Shelf 1",
69
+ "barcode": "subshelf1",
70
+ "location_id": self.shelf1.id,
71
+ }
72
+ )
73
+ )
74
+ response = self.service.dispatch(
75
+ "set_destination_all",
76
+ params={"location_id": self.content_loc.id, "barcode": sub_shelf1.barcode},
77
+ )
78
+ self.assert_response_start(
79
+ response,
80
+ message=self.service.msg_store.location_content_transfer_complete(
81
+ self.content_loc, sub_shelf1
82
+ ),
83
+ )
84
+ self.assert_all_done(sub_shelf1)
85
+
86
+ def test_set_destination_all_with_partially_available_move_without_ancestor(self):
87
+ """Scanned destination location valid, but one of the move to process
88
+ is partially available and has no ancestor move.
89
+
90
+ In such case, normal backorder is created with the remaining qty while
91
+ the current pickings is validated.
92
+ """
93
+ # Put a partial quantity for 'product_d' to get a partially available move
94
+ self.picking2.do_unreserve()
95
+ self._update_qty_in_location(self.content_loc, self.product_d, 5)
96
+ self.picking2.action_assign()
97
+ self._simulate_pickings_selected(self.picking2)
98
+ move_d = self.picking2.move_ids.filtered(
99
+ lambda m: m.product_id == self.product_d
100
+ )
101
+
102
+ sub_shelf1 = (
103
+ self.env["stock.location"]
104
+ .sudo()
105
+ .create(
106
+ {
107
+ "name": "Sub Shelf 1",
108
+ "barcode": "subshelf1",
109
+ "location_id": self.shelf1.id,
110
+ }
111
+ )
112
+ )
113
+ response = self.service.dispatch(
114
+ "set_destination_all",
115
+ params={"location_id": self.content_loc.id, "barcode": sub_shelf1.barcode},
116
+ )
117
+ self.assert_response_start(
118
+ response,
119
+ message=self.service.msg_store.location_content_transfer_complete(
120
+ self.content_loc, sub_shelf1
121
+ ),
122
+ )
123
+ # As we have no ancestor move in progress, a normal backorder is created
124
+ # with the remaining qties
125
+ self.assertEqual(self.picking2.state, "done")
126
+ self.assertEqual(move_d.state, "done")
127
+ self.assertEqual(move_d.product_qty, 5)
128
+ self.assertTrue(self.picking2.backorder_ids)
129
+ self.assertNotEqual(self.picking2.backorder_ids.state, "done")
130
+ self.assertFalse(self.picking2.backorder_ids.user_id)
131
+ self.assertEqual(self.picking2.backorder_ids.move_ids.product_qty, 5)
132
+
133
+ def test_set_destination_all_with_partially_available_move_with_ancestor(self):
134
+ """Scanned destination location valid, but one of the move to process
135
+ is partially available and has an unprocessed ancestor move.
136
+
137
+ In such case, new picking is created to validate the moves, and the
138
+ remaining qties stay in their current picking.
139
+ """
140
+ # Put a partial quantity for 'product_d' to get a partially available move
141
+ self.picking2.do_unreserve()
142
+ self._update_qty_in_location(self.content_loc, self.product_d, 5)
143
+ self.picking2.action_assign()
144
+ self._simulate_pickings_selected(self.picking2)
145
+ # Set an ancestor move on the partially available move
146
+ move_d = self.picking2.move_ids.filtered(
147
+ lambda m: m.product_id == self.product_d
148
+ )
149
+ move_d.move_orig_ids |= move_d.copy({"picking_id": False})
150
+
151
+ sub_shelf1 = (
152
+ self.env["stock.location"]
153
+ .sudo()
154
+ .create(
155
+ {
156
+ "name": "Sub Shelf 1",
157
+ "barcode": "subshelf1",
158
+ "location_id": self.shelf1.id,
159
+ }
160
+ )
161
+ )
162
+ response = self.service.dispatch(
163
+ "set_destination_all",
164
+ params={"location_id": self.content_loc.id, "barcode": sub_shelf1.barcode},
165
+ )
166
+ self.assert_response_start(
167
+ response,
168
+ message=self.service.msg_store.location_content_transfer_complete(
169
+ self.content_loc, sub_shelf1
170
+ ),
171
+ )
172
+ # The current picking with the remaining qties is waiting (because of the
173
+ # ancestor move), and other moves are validated in a new one.
174
+ self.assertEqual(self.picking2.state, "waiting")
175
+ self.assertEqual(self.picking2.move_ids.state, "waiting")
176
+ self.assertEqual(self.picking2.move_ids.product_qty, 5)
177
+ self.assertEqual(self.picking2.backorder_ids.state, "done")
178
+ self.assertEqual(move_d.state, "done")
179
+ self.assertEqual(move_d.product_qty, 5)
180
+
181
+ def test_set_destination_all_dest_location_ok_with_completion_info(self):
182
+ """Scanned destination location valid, moves set to done accepted
183
+ and completion info is returned as the next transfer is ready.
184
+ """
185
+ move = self.picking1.move_ids[0]
186
+ next_move = move.copy(
187
+ {
188
+ "location_id": move.location_dest_id.id,
189
+ "location_dest_id": self.customer_location.id,
190
+ "move_orig_ids": [(6, 0, move.ids)],
191
+ }
192
+ )
193
+ next_move._action_confirm(merge=False)
194
+ next_move._assign_picking()
195
+ self.assertEqual(next_move.state, "waiting")
196
+ sub_shelf1 = (
197
+ self.env["stock.location"]
198
+ .sudo()
199
+ .create(
200
+ {
201
+ "name": "Sub Shelf 1",
202
+ "barcode": "subshelf1",
203
+ "location_id": self.shelf1.id,
204
+ }
205
+ )
206
+ )
207
+ move_lines = self.service._find_transfer_move_lines(self.content_loc)
208
+ response = self.service.dispatch(
209
+ "set_destination_all",
210
+ params={"location_id": self.content_loc.id, "barcode": sub_shelf1.barcode},
211
+ )
212
+ self.assertEqual(next_move.state, "assigned")
213
+ completion_info = self.service._actions_for("completion.info")
214
+ completion_info_popup = completion_info.popup(move_lines)
215
+ self.assert_response_start(
216
+ response,
217
+ message=self.service.msg_store.location_content_transfer_complete(
218
+ self.content_loc, sub_shelf1
219
+ ),
220
+ popup=completion_info_popup,
221
+ )
222
+
223
+ def test_set_destination_all_dest_location_not_found(self):
224
+ """Barcode scanned for destination location is not found"""
225
+ response = self.service.dispatch(
226
+ "set_destination_all",
227
+ params={"location_id": self.content_loc.id, "barcode": "NOT_FOUND"},
228
+ )
229
+ self.assert_response_scan_destination_all(
230
+ response, self.pickings, message=self.service.msg_store.barcode_not_found()
231
+ )
232
+
233
+ def test_set_destination_all_dest_location_need_confirm(self):
234
+ """Scanned dest. location != child but in picking type location
235
+
236
+ So it needs confirmation.
237
+ """
238
+ response = self.service.dispatch(
239
+ "set_destination_all",
240
+ params={
241
+ "location_id": self.content_loc.id,
242
+ # expected location was shelf1, but shelf2 is valid as still in the
243
+ # picking type's default dest location, ask confirmation (second scan)
244
+ # from the user
245
+ "barcode": self.shelf2.barcode,
246
+ },
247
+ )
248
+ self.assert_response_scan_destination_all(
249
+ response,
250
+ self.pickings,
251
+ message=self.service.msg_store.need_confirmation(),
252
+ confirmation_required=True,
253
+ )
254
+
255
+ def test_set_destination_all_dest_location_confirmation(self):
256
+ """Scanned dest. location != child but in picking type location: confirm
257
+
258
+ use the confirmation flag to confirm
259
+ """
260
+ response = self.service.dispatch(
261
+ "set_destination_all",
262
+ params={
263
+ "location_id": self.content_loc.id,
264
+ # expected location was shelf1, but shelf2 is valid as still in the
265
+ # picking type's default dest location, ask confirmation (second scan)
266
+ # from the user
267
+ "barcode": self.shelf2.barcode,
268
+ "confirmation": True,
269
+ },
270
+ )
271
+ self.assert_response_start(
272
+ response,
273
+ message=self.service.msg_store.location_content_transfer_complete(
274
+ self.content_loc, self.shelf2
275
+ ),
276
+ )
277
+ self.assert_all_done(self.shelf2)
278
+
279
+ def test_set_destination_all_dest_location_invalid(self):
280
+ """The scanned destination location is not in the menu's picking types"""
281
+ response = self.service.dispatch(
282
+ "set_destination_all",
283
+ params={
284
+ "location_id": self.content_loc.id,
285
+ "barcode": self.dispatch_location.barcode,
286
+ },
287
+ )
288
+ self.assert_response_scan_destination_all(
289
+ response,
290
+ self.pickings,
291
+ message=self.service.msg_store.dest_location_not_allowed(),
292
+ )
293
+
294
+ def test_set_destination_all_dest_location_move_invalid(self):
295
+ """The scanned destination location is not in the picking and move's
296
+ dest location
297
+ """
298
+ # if we have at least one move which does not match the scanned
299
+ # location
300
+ # we forbid the action
301
+ self.pickings.move_ids[0].location_dest_id = self.shelf1
302
+ self.pickings[0].location_dest_id = self.shelf1
303
+ response = self.service.dispatch(
304
+ "set_destination_all",
305
+ params={
306
+ "location_id": self.content_loc.id,
307
+ "barcode": self.shelf2.barcode,
308
+ },
309
+ )
310
+ self.assert_response_scan_destination_all(
311
+ response,
312
+ self.pickings,
313
+ message=self.service.msg_store.dest_location_not_allowed(),
314
+ )
315
+
316
+ def test_go_to_single(self):
317
+ """User used to 'split by lines' button to process line per line"""
318
+ response = self.service.dispatch(
319
+ "go_to_single", params={"location_id": self.content_loc.id}
320
+ )
321
+ self.assert_response_start_single(response, self.pickings)
322
+
323
+
324
+ class LocationContentTransferSetDestinationAllSpecialCase(
325
+ LocationContentTransferCommonCase
326
+ ):
327
+ """Tests for endpoint used from scan_destination_all (special cases without setup)
328
+
329
+ * /set_destination_all
330
+ * /go_to_single
331
+
332
+ """
333
+
334
+ def test_go_to_single_no_lines_to_process(self):
335
+ """User used to 'split by lines' button to process line per line,
336
+ but no lines to process.
337
+ """
338
+ response = self.service.dispatch(
339
+ "go_to_single", params={"location_id": self.content_loc.id}
340
+ )
341
+ self.assert_response_start(
342
+ response, message=self.service.msg_store.no_lines_to_process()
343
+ )