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,207 @@
1
+ # Copyright 2023 Camptocamp SA (http://www.camptocamp.com)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
+
4
+ from .test_zone_picking_base import ZonePickingCommonCase
5
+
6
+ # pylint: disable=missing-return
7
+
8
+
9
+ class ZonePickingSelectLineFirstScanLocationCase(ZonePickingCommonCase):
10
+ """Tests for endpoint used from select_line with option 'First scan location'
11
+
12
+ * /scan_source
13
+
14
+ """
15
+
16
+ def setUp(self):
17
+ super().setUp()
18
+ self.service.work.current_picking_type = self.picking1.picking_type_id
19
+ self.menu.sudo().scan_location_or_pack_first = True
20
+
21
+ def test_scan_source_first_the_product_not_ok(self):
22
+ """Check first scanning a product barcode is not allowed."""
23
+ response = self.service.dispatch(
24
+ "scan_source",
25
+ params={"barcode": self.product_a.barcode},
26
+ )
27
+ move_lines = self.service._find_location_move_lines(
28
+ locations=self.zone_location,
29
+ package=False,
30
+ )
31
+ self.assertTrue(response.get("data").get("select_line"))
32
+ self.assert_response_select_line(
33
+ response,
34
+ zone_location=self.zone_location,
35
+ picking_type=self.picking_type,
36
+ message=self.service.msg_store.barcode_not_found(),
37
+ move_lines=move_lines,
38
+ location_first=True,
39
+ )
40
+
41
+ def test_scan_source_scan_location_then_product_ok(self):
42
+ """Check scanning location and then product is fine."""
43
+ # Have the same product multiple time in sublocation 2
44
+ pickingA = self._create_picking(
45
+ lines=[(self.product_b, 12), (self.product_c, 13)]
46
+ )
47
+ self._fill_stock_for_moves(
48
+ pickingA.move_ids, in_lot=True, location=self.zone_sublocation2
49
+ )
50
+ pickingA.action_assign()
51
+ # Scan product B, send sublocation to simulate a previous scan for a location
52
+ response = self.service.dispatch(
53
+ "scan_source",
54
+ params={
55
+ "barcode": self.product_b.barcode,
56
+ "sublocation_id": self.zone_sublocation2.id,
57
+ },
58
+ )
59
+ move_lines = self.service._find_location_move_lines(
60
+ locations=self.zone_sublocation2, product=self.product_b
61
+ )
62
+ self.assert_response_select_line(
63
+ response,
64
+ zone_location=self.zone_location,
65
+ picking_type=self.picking_type,
66
+ message=self.service.msg_store.several_move_with_different_lot(),
67
+ move_lines=move_lines,
68
+ product=self.product_b,
69
+ sublocation=self.zone_sublocation2,
70
+ location_first=True,
71
+ )
72
+
73
+ def test_scan_source_can_not_select_line_with_package(self):
74
+ """Do not allow to scan product with package without scanning pack first."""
75
+ # Picking 1 with one product in a package is already in sub location 1
76
+ pickingA = self._create_picking(lines=[(self.product_a, 13)])
77
+ self._fill_stock_for_moves(
78
+ pickingA.move_ids[0], in_package=True, location=self.zone_sublocation1
79
+ )
80
+ pickingA.action_assign()
81
+ # Scanning a product after having scan a location (sublocation_id)
82
+ response = self.service.dispatch(
83
+ "scan_source",
84
+ params={
85
+ "barcode": self.product_a.barcode,
86
+ "sublocation_id": self.zone_sublocation1.id,
87
+ },
88
+ )
89
+ self.assertEqual(response["next_state"], "select_line")
90
+ move_lines = self.service._find_location_move_lines(
91
+ locations=self.zone_sublocation1, package=False, product=self.product_a
92
+ )
93
+ self.assert_response_select_line(
94
+ response,
95
+ zone_location=self.zone_location,
96
+ sublocation=self.zone_sublocation1,
97
+ picking_type=self.picking_type,
98
+ message=self.service.msg_store.product_not_found_in_pickings(),
99
+ move_lines=move_lines,
100
+ location_first=True,
101
+ )
102
+
103
+ def test_scan_source_scan_location_no_lines_without_package(self):
104
+ """Check list of lines when first scanning location.
105
+
106
+ With the scan_location_or_pack_first option on. When scanning first the
107
+ location and no lines without package exist, ask to scan a package.
108
+
109
+ """
110
+ # Picking 1 with one product in a package is already in sub location 1
111
+ pickingA = self._create_picking(lines=[(self.product_a, 13)])
112
+ self._fill_stock_for_moves(
113
+ pickingA.move_ids[0], in_package=True, location=self.zone_sublocation1
114
+ )
115
+ pickingA.action_assign()
116
+ response = self.service.dispatch(
117
+ "scan_source",
118
+ params={
119
+ "barcode": self.zone_sublocation1.barcode,
120
+ },
121
+ )
122
+ move_lines = self.service._find_location_move_lines(
123
+ locations=self.zone_sublocation1, package=False
124
+ )
125
+ self.assert_response_select_line(
126
+ response,
127
+ zone_location=self.zone_location,
128
+ sublocation=self.zone_sublocation1,
129
+ picking_type=self.picking_type,
130
+ message=self.service.msg_store.several_packs_in_location(
131
+ self.zone_sublocation1
132
+ ),
133
+ move_lines=move_lines,
134
+ location_first=True,
135
+ )
136
+
137
+ def test_scan_source_scan_package_first_with_two_product(self):
138
+ """Scan a package with two product and then scan a product."""
139
+ pickingA = self._create_picking(
140
+ lines=[(self.product_a, 13), (self.product_b, 5)]
141
+ )
142
+ self._fill_stock_for_moves(
143
+ pickingA.move_ids, in_package=True, location=self.zone_sublocation1
144
+ )
145
+ pickingA.action_assign()
146
+ package = pickingA.package_level_ids[0].package_id
147
+ response = self.service.dispatch(
148
+ "scan_source",
149
+ params={
150
+ "barcode": package.name,
151
+ },
152
+ )
153
+ move_lines = self.service._find_location_move_lines(
154
+ locations=self.zone_sublocation1, package=package
155
+ )
156
+ self.assertTrue(len(move_lines), 2)
157
+ self.assert_response_select_line(
158
+ response,
159
+ zone_location=self.zone_location,
160
+ picking_type=self.picking_type,
161
+ message=self.service.msg_store.several_products_in_package(package),
162
+ move_lines=move_lines,
163
+ location_first=True,
164
+ package=package,
165
+ )
166
+ response = self.service.dispatch(
167
+ "scan_source",
168
+ params={"barcode": self.product_a.barcode, "package_id": package.id},
169
+ )
170
+ move_line = pickingA.move_line_ids[0]
171
+ self.assert_response_set_line_destination(
172
+ response,
173
+ zone_location=self.zone_location,
174
+ picking_type=self.picking_type,
175
+ move_line=move_line,
176
+ qty_done=13.0,
177
+ )
178
+
179
+ def test_scan_source_scan_product_message_product_has_package(self):
180
+ """"""
181
+ # Picking 1 with one product in a package is already in sub location 1
182
+ pickingA = self._create_picking(lines=[(self.product_a, 13)])
183
+ self._fill_stock_for_moves(
184
+ pickingA.move_ids[0], in_package=True, location=self.zone_sublocation1
185
+ )
186
+ pickingA.action_assign()
187
+ # Scanning a product after having scan a location (sublocation_id)
188
+ response = self.service.dispatch(
189
+ "scan_source",
190
+ params={
191
+ "barcode": self.product_a.barcode,
192
+ "sublocation_id": self.zone_sublocation1.id,
193
+ },
194
+ )
195
+ self.assertEqual(response["next_state"], "select_line")
196
+ move_lines = self.service._find_location_move_lines(
197
+ locations=self.zone_sublocation1, package=False, product=self.product_a
198
+ )
199
+ self.assert_response_select_line(
200
+ response,
201
+ zone_location=self.zone_location,
202
+ sublocation=self.zone_sublocation1,
203
+ picking_type=self.picking_type,
204
+ message=self.service.msg_store.product_not_found_in_pickings(),
205
+ move_lines=move_lines,
206
+ location_first=True,
207
+ )
@@ -0,0 +1,202 @@
1
+ # Copyright 2023 Camptocamp SA (http://www.camptocamp.com)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
+
4
+ from .test_zone_picking_base import ZonePickingCommonCase
5
+
6
+
7
+ class ZonePickingSelectLineFirstScanLocationCase(ZonePickingCommonCase):
8
+ """Tests for endpoint used from select_line with option 'First scan location'
9
+
10
+ * /scan_source
11
+
12
+ """
13
+
14
+ def setUp(self):
15
+ super().setUp()
16
+ self.service.work.current_picking_type = self.picking1.picking_type_id
17
+ self.menu.sudo().scan_location_or_pack_first = True
18
+
19
+ def test_scan_source_first_the_product_not_ok(self):
20
+ """Check first scanning a product barcode is not allowed."""
21
+ response = self.service.dispatch(
22
+ "scan_source",
23
+ params={"barcode": self.product_a.barcode},
24
+ )
25
+ move_lines = self.service._find_location_move_lines(
26
+ locations=self.zone_location,
27
+ package=False,
28
+ )
29
+ self.assertTrue(response.get("data").get("select_line"))
30
+ self.assert_response_select_line(
31
+ response,
32
+ zone_location=self.zone_location,
33
+ picking_type=self.picking_type,
34
+ message=self.service.msg_store.barcode_not_found(),
35
+ move_lines=move_lines,
36
+ location_first=True,
37
+ )
38
+
39
+ def test_scan_source_scan_location_then_product_ok(self):
40
+ """Check scanning location and then product is fine."""
41
+ # Have the same product multiple time in sublocation 2
42
+ pickingA = self._create_picking(
43
+ lines=[(self.product_b, 12), (self.product_c, 13)]
44
+ )
45
+ self._fill_stock_for_moves(
46
+ pickingA.move_lines, in_lot=True, location=self.zone_sublocation2
47
+ )
48
+ pickingA.action_assign()
49
+ # Scan product B, send sublocation to simulate a previous scan for a location
50
+ response = self.service.dispatch(
51
+ "scan_source",
52
+ params={
53
+ "barcode": self.product_b.barcode,
54
+ "sublocation_id": self.zone_sublocation2.id,
55
+ },
56
+ )
57
+ move_lines = self.service._find_location_move_lines(
58
+ locations=self.zone_sublocation2, product=self.product_b
59
+ )
60
+ self.assert_response_select_line(
61
+ response,
62
+ zone_location=self.zone_location,
63
+ picking_type=self.picking_type,
64
+ message=self.service.msg_store.several_move_with_different_lot(),
65
+ move_lines=move_lines,
66
+ product=self.product_b,
67
+ sublocation=self.zone_sublocation2,
68
+ location_first=True,
69
+ )
70
+
71
+ def test_scan_source_can_not_select_line_with_package(self):
72
+ """Do not allow to scan product with package without scanning pack first."""
73
+ # Picking 1 with one product in a package is already in sub location 1
74
+ pickingA = self._create_picking(lines=[(self.product_a, 13)])
75
+ self._fill_stock_for_moves(
76
+ pickingA.move_lines[0], in_package=True, location=self.zone_sublocation1
77
+ )
78
+ pickingA.action_assign()
79
+ # Scanning a product after having scan a location (sublocation_id)
80
+ response = self.service.dispatch(
81
+ "scan_source",
82
+ params={
83
+ "barcode": self.product_a.barcode,
84
+ "sublocation_id": self.zone_sublocation1.id,
85
+ },
86
+ )
87
+ self.assertEqual(response["next_state"], "select_line")
88
+ move_lines = self.service._find_location_move_lines(
89
+ locations=self.zone_sublocation1, package=False, product=self.product_a
90
+ )
91
+ self.assert_response_select_line(
92
+ response,
93
+ zone_location=self.zone_location,
94
+ sublocation=self.zone_sublocation1,
95
+ picking_type=self.picking_type,
96
+ message=self.service.msg_store.product_not_found(),
97
+ move_lines=move_lines,
98
+ location_first=True,
99
+ )
100
+
101
+ def test_scan_source_scan_location_no_lines_without_package(self):
102
+ """Check list of lines when first scanning location.
103
+
104
+ With the scan_location_or_pack_first option on. When scanning first the
105
+ location and no lines without package exist, ask to scan a package.
106
+
107
+ """
108
+ # Picking 1 with one product in a package is already in sub location 1
109
+ pickingA = self._create_picking(lines=[(self.product_a, 13)])
110
+ self._fill_stock_for_moves(
111
+ pickingA.move_lines[0], in_package=True, location=self.zone_sublocation1
112
+ )
113
+ pickingA.action_assign()
114
+ response = self.service.dispatch(
115
+ "scan_source",
116
+ params={
117
+ "barcode": self.zone_sublocation1.barcode,
118
+ },
119
+ )
120
+ move_lines = self.service._find_location_move_lines(
121
+ locations=self.zone_sublocation1, package=False
122
+ )
123
+ self.assert_response_select_line(
124
+ response,
125
+ zone_location=self.zone_location,
126
+ sublocation=self.zone_sublocation1,
127
+ picking_type=self.picking_type,
128
+ message=self.service.msg_store.several_packs_in_location(
129
+ self.zone_sublocation1
130
+ ),
131
+ move_lines=move_lines,
132
+ location_first=True,
133
+ )
134
+
135
+ def test_scan_source_scan_package_first_with_two_product(self):
136
+ """Scan a package with two product and then scan a product."""
137
+ pickingA = self._create_picking(
138
+ lines=[(self.product_a, 13), (self.product_b, 5)]
139
+ )
140
+ self._fill_stock_for_moves(
141
+ pickingA.move_lines, in_package=True, location=self.zone_sublocation1
142
+ )
143
+ pickingA.action_assign()
144
+ package = pickingA.package_level_ids[0].package_id
145
+ response = self.service.dispatch(
146
+ "scan_source",
147
+ params={
148
+ "barcode": package.name,
149
+ },
150
+ )
151
+ move_lines = self.service._find_location_move_lines(
152
+ locations=self.zone_sublocation1, package=package
153
+ )
154
+ self.assertTrue(len(move_lines), 2)
155
+ self.assert_response_select_line(
156
+ response,
157
+ zone_location=self.zone_location,
158
+ picking_type=self.picking_type,
159
+ message=self.service.msg_store.several_products_in_package(package),
160
+ move_lines=move_lines,
161
+ location_first=True,
162
+ package=package,
163
+ )
164
+ response = self.service.dispatch(
165
+ "scan_source",
166
+ params={"barcode": self.product_a.barcode, "package_id": package.id},
167
+ )
168
+ move_line = pickingA.move_line_ids[0]
169
+ self.assert_response_set_line_destination(
170
+ response,
171
+ zone_location=self.zone_location,
172
+ picking_type=self.picking_type,
173
+ move_line=move_line,
174
+ qty_done=13.0,
175
+ )
176
+
177
+ # def test_scan_source_scan_package_first_with_one_line(self):
178
+ # pickingA = self._create_picking(lines=[(self.product_a, 13)])
179
+ # self._fill_stock_for_moves(
180
+ # pickingA.move_lines[0], in_package=True, location=self.zone_sublocation1
181
+ # )
182
+ # pickingA.action_assign()
183
+ # package = pickingA.package_level_ids[0].package_id
184
+ # response = self.service.dispatch(
185
+ # "scan_source",
186
+ # params={
187
+ # "barcode": package.name,
188
+ # },
189
+ # )
190
+ # move_lines = self.service._find_location_move_lines(
191
+ # locations=self.zone_sublocation1, package=package
192
+ # )
193
+ # self.assert_response_select_line(
194
+ # response,
195
+ # zone_location=self.zone_location,
196
+ # picking_type=self.picking_type,
197
+ # # message=self.service.msg_store.location_empty_scan_package(
198
+ # # self.zone_sublocation1
199
+ # # ),
200
+ # move_lines=move_lines,
201
+ # # location_first=True,
202
+ # )
@@ -0,0 +1,107 @@
1
+ # Copyright 2022 Camptocamp SA (http://www.camptocamp.com)
2
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3
+
4
+ from .test_zone_picking_base import ZonePickingCommonCase
5
+
6
+ # pylint: disable=missing-return
7
+
8
+
9
+ class ZonePickingSelectLineCase(ZonePickingCommonCase):
10
+ """Tests for endpoint used from select_line with no prefill quantity
11
+
12
+ * /scan_source
13
+
14
+ """
15
+
16
+ def setUp(self):
17
+ super().setUp()
18
+ self.service.work.current_picking_type = self.picking1.picking_type_id
19
+ self.menu.sudo().no_prefill_qty = True
20
+
21
+ def test_scan_source_barcode_location_no_prefill(self):
22
+ """When a location is scanned, qty_done in response is False."""
23
+ response = self.service.dispatch(
24
+ "scan_source",
25
+ params={"barcode": self.zone_sublocation1.barcode},
26
+ )
27
+ move_line = self.picking1.move_line_ids
28
+ self.assert_response_set_line_destination(
29
+ response,
30
+ zone_location=self.zone_location,
31
+ picking_type=self.picking_type,
32
+ move_line=move_line,
33
+ qty_done=False,
34
+ )
35
+
36
+ def test_scan_source_barcode_package_no_prefill(self):
37
+ """When a package is scanned, qty_done in response is False."""
38
+ package = self.picking1.package_level_ids[0].package_id
39
+ response = self.service.dispatch(
40
+ "scan_source",
41
+ params={"barcode": package.name},
42
+ )
43
+ move_lines = self.service._find_location_move_lines(
44
+ package=package,
45
+ )
46
+ move_lines = move_lines.sorted(lambda l: l.move_id.priority, reverse=True)
47
+ move_line = move_lines[0]
48
+ self.assert_response_set_line_destination(
49
+ response,
50
+ zone_location=self.zone_location,
51
+ picking_type=self.picking_type,
52
+ move_line=move_line,
53
+ qty_done=False,
54
+ )
55
+
56
+ def test_scan_source_barcode_product_no_prefill(self):
57
+ """When a product is scanned, qty_done in response is 1.0."""
58
+ response = self.service.dispatch(
59
+ "scan_source",
60
+ params={"barcode": self.product_a.barcode},
61
+ )
62
+ move_line = self.service._find_location_move_lines(
63
+ product=self.product_a,
64
+ )
65
+ self.assert_response_set_line_destination(
66
+ response,
67
+ zone_location=self.zone_location,
68
+ picking_type=self.picking_type,
69
+ move_line=move_line,
70
+ qty_done=1.0,
71
+ )
72
+
73
+ def test_scan_source_barcode_lot_no_prefill(self):
74
+ """When a lot is scanned, qty_done in response is 1.0"""
75
+ lot = self.picking2.move_line_ids.lot_id[0]
76
+ response = self.service.dispatch(
77
+ "scan_source",
78
+ params={"barcode": lot.name},
79
+ )
80
+ move_lines = self.service._find_location_move_lines(lot=lot)
81
+ move_lines = move_lines.sorted(lambda l: l.move_id.priority, reverse=True)
82
+ move_line = move_lines[0]
83
+ self.assert_response_set_line_destination(
84
+ response,
85
+ zone_location=self.zone_location,
86
+ picking_type=self.picking_type,
87
+ move_line=move_line,
88
+ qty_done=1.0,
89
+ )
90
+
91
+ def test_scan_source_barcode_packaging_no_prefill(self):
92
+ """Check qty_done for packaginge scan with no_prefill."""
93
+ packaging = self.product_a_packaging
94
+ response = self.service.dispatch(
95
+ "scan_source",
96
+ params={"barcode": packaging.barcode},
97
+ )
98
+ move_line = self.service._find_location_move_lines(
99
+ product=self.product_a,
100
+ )
101
+ self.assert_response_set_line_destination(
102
+ response,
103
+ zone_location=self.zone_location,
104
+ picking_type=self.picking_type,
105
+ move_line=move_line,
106
+ qty_done=packaging.qty,
107
+ )
@@ -0,0 +1,26 @@
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
+ class ZonePickingSelectPickingTypeCase(ZonePickingCommonCase):
7
+ """Tests for endpoint used from select_picking_type
8
+
9
+ * /list_move_lines
10
+
11
+ """
12
+
13
+ def test_list_move_lines_ok(self):
14
+ zone_location = self.zone_location
15
+ picking_type = self.picking1.picking_type_id
16
+ response = self.service.dispatch(
17
+ "list_move_lines",
18
+ params={},
19
+ )
20
+ move_lines = self.service._find_location_move_lines(zone_location, picking_type)
21
+ self.assert_response_select_line(
22
+ response,
23
+ zone_location=self.zone_location,
24
+ picking_type=self.picking_type,
25
+ move_lines=move_lines,
26
+ )