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,846 @@
1
+ # Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
2
+ # Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
3
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
4
+ import logging
5
+
6
+ from odoo import _
7
+
8
+ from odoo.addons.component.core import Component
9
+
10
+ _logger = logging.getLogger(__name__)
11
+
12
+
13
+ class MessageAction(Component):
14
+ _inherit = "shopfloor.message.action"
15
+
16
+ def no_operation_found(self):
17
+ return {
18
+ "message_type": "error",
19
+ "body": _("No operation found for this menu and profile."),
20
+ }
21
+
22
+ def no_picking_type(self):
23
+ return {
24
+ "message_type": "error",
25
+ "body": _("No operation type found for this menu and profile."),
26
+ }
27
+
28
+ def several_picking_types(self):
29
+ return {
30
+ "message_type": "error",
31
+ "body": _("Several operation types found for this menu and profile."),
32
+ }
33
+
34
+ def package_not_found_for_barcode(self, barcode):
35
+ return {
36
+ "message_type": "error",
37
+ "body": _("The package %s doesn't exist") % barcode,
38
+ }
39
+
40
+ def package_has_no_product_to_take(self, barcode):
41
+ return {
42
+ "message_type": "error",
43
+ "body": _("The package %s doesn't contain any product to take.") % barcode,
44
+ }
45
+
46
+ def bin_not_found_for_barcode(self, barcode):
47
+ return {"message_type": "error", "body": _("Bin %s doesn't exist") % barcode}
48
+
49
+ def package_not_allowed_in_src_location(self, barcode, picking_types):
50
+ return {
51
+ "message_type": "error",
52
+ "body": _(
53
+ "You cannot work on a package (%(barcode)s) outside of locations:"
54
+ " %(names)s"
55
+ )
56
+ % dict(
57
+ barcode=barcode,
58
+ names=", ".join(picking_types.mapped("default_location_src_id.name")),
59
+ ),
60
+ }
61
+
62
+ def location_requires_package(self):
63
+ return {
64
+ "message_type": "warning",
65
+ "body": _(
66
+ "This location requires packages. Please scan a destination package."
67
+ ),
68
+ }
69
+
70
+ def already_running_ask_confirmation(self):
71
+ return {
72
+ "message_type": "warning",
73
+ "body": _("Operation's already running. Would you like to take it over?"),
74
+ }
75
+
76
+ def scan_destination(self):
77
+ return {"message_type": "info", "body": _("Scan the destination location")}
78
+
79
+ def scan_lot_on_product_tracked_by_lot(self):
80
+ return {
81
+ "message_type": "warning",
82
+ "body": _("Product tracked by lot, please scan one."),
83
+ }
84
+
85
+ def operation_not_found(self):
86
+ return {
87
+ "message_type": "error",
88
+ "body": _("This operation does not exist anymore."),
89
+ }
90
+
91
+ def stock_picking_not_found(self):
92
+ return {
93
+ "message_type": "error",
94
+ "body": _("This transfer does not exist or is not available anymore."),
95
+ }
96
+
97
+ def package_not_found(self):
98
+ return {
99
+ "message_type": "error",
100
+ "body": _("This package does not exist anymore."),
101
+ }
102
+
103
+ def package_different_change(self):
104
+ return {
105
+ "message_type": "warning",
106
+ "body": _(
107
+ "You scanned a different package with the same product, "
108
+ "do you want to change pack? Scan it again to confirm"
109
+ ),
110
+ }
111
+
112
+ def package_not_available_in_picking(self, package, picking):
113
+ return {
114
+ "message_type": "warning",
115
+ "body": _(
116
+ "Package %(package_name)s is not available in transfer %(picking_name)s."
117
+ ).format(package.name, picking.name),
118
+ }
119
+
120
+ def package_not_empty(self, package):
121
+ return {
122
+ "message_type": "warning",
123
+ "body": _("Package {} is not empty.").format(package.name),
124
+ }
125
+
126
+ def package_already_used(self, package):
127
+ return {
128
+ "message_type": "warning",
129
+ "body": _("Package {} is already used.").format(package.name),
130
+ }
131
+
132
+ def dest_package_required(self):
133
+ return {
134
+ "message_type": "warning",
135
+ "body": _("A destination package is required."),
136
+ }
137
+
138
+ def line_not_available_in_picking(self, picking):
139
+ return {
140
+ "message_type": "warning",
141
+ "body": _("This line is not available in transfer {}.").format(
142
+ picking.name
143
+ ),
144
+ }
145
+
146
+ def record_not_found(self):
147
+ return {
148
+ "message_type": "error",
149
+ "body": _("The record you were working on does not exist anymore."),
150
+ }
151
+
152
+ def barcode_not_found(self):
153
+ return {"message_type": "error", "body": _("Barcode not found")}
154
+
155
+ def operation_has_been_canceled_elsewhere(self):
156
+ return {
157
+ "message_type": "warning",
158
+ "body": _("Restart the operation, someone has canceled it."),
159
+ }
160
+
161
+ def no_location_found(self):
162
+ return {
163
+ "message_type": "error",
164
+ "body": _("No location found for this barcode."),
165
+ }
166
+
167
+ def location_not_allowed(self):
168
+ return {"message_type": "error", "body": _("Location not allowed here.")}
169
+
170
+ def dest_location_not_allowed(self):
171
+ return {"message_type": "error", "body": _("You cannot place it here")}
172
+
173
+ def need_confirmation(self):
174
+ return {"message_type": "warning", "body": _("Are you sure?")}
175
+
176
+ def confirm_location_changed(self, from_location, to_location):
177
+ return {
178
+ "message_type": "warning",
179
+ "body": _(
180
+ "Confirm location change from %(location_from)s to " "%(location_to)s?"
181
+ )
182
+ % dict(location_from=from_location.name, location_to=to_location.name),
183
+ }
184
+
185
+ def confirm_pack_moved(self):
186
+ return {
187
+ "message_type": "success",
188
+ "body": _("The pack has been moved, you can scan a new pack."),
189
+ }
190
+
191
+ def already_done(self):
192
+ return {"message_type": "info", "body": _("Operation already processed.")}
193
+
194
+ def move_already_done(self):
195
+ return {"message_type": "warning", "body": _("Move already processed.")}
196
+
197
+ def confirm_canceled_scan_next_pack(self):
198
+ return {
199
+ "message_type": "success",
200
+ "body": _("Canceled, you can scan a new pack."),
201
+ }
202
+
203
+ def no_pack_in_location(self, location):
204
+ return {
205
+ "message_type": "error",
206
+ "body": _("Location %s doesn't contain any package.") % location.name,
207
+ }
208
+
209
+ def several_packs_in_location(self, location):
210
+ return {
211
+ "message_type": "warning",
212
+ "body": _("Several packages found in %(name)s, please scan a package.")
213
+ % dict(name=location.name),
214
+ }
215
+
216
+ def no_package_or_lot_for_barcode(self, barcode):
217
+ return {
218
+ "message_type": "error",
219
+ "body": _("No package or lot found for barcode {}.").format(barcode),
220
+ }
221
+
222
+ def no_product_for_barcode(self, barcode):
223
+ return {
224
+ "message_type": "error",
225
+ "body": _("No product found for {}").format(barcode),
226
+ }
227
+
228
+ def wrong_product(self):
229
+ # Method to drop in v15
230
+ _logger.warning("`wrong_product` is deprecated, use `wrong_record` instead")
231
+ return {
232
+ "message_type": "error",
233
+ "body": self._wrong_record_msg("product.product"),
234
+ }
235
+
236
+ def _wrong_record_msg(self, model_name):
237
+ return {
238
+ "product.product": _("Wrong product."),
239
+ "stock.lot": _("Wrong lot."),
240
+ "stock.location": _("Wrong location."),
241
+ "stock.quant.package": _("Wrong pack."),
242
+ "product.packaging": _("Wrong packaging."),
243
+ }.get(model_name, _("Wrong."))
244
+
245
+ def wrong_record(self, record):
246
+ return {"message_type": "error", "body": self._wrong_record_msg(record._name)}
247
+
248
+ def no_lot_for_barcode(self, barcode):
249
+ return {
250
+ "message_type": "error",
251
+ "body": _("No lot found for {}").format(barcode),
252
+ }
253
+
254
+ def lot_on_wrong_product(self, barcode):
255
+ return {
256
+ "message_type": "error",
257
+ "body": _("Lot {} is for another product.").format(barcode),
258
+ }
259
+
260
+ def wrong_lot(self):
261
+ # Method to drop in v15
262
+ _logger.warning("`wrong_log` is deprecated, use `wrong_record` instead")
263
+ return {
264
+ "message_type": "error",
265
+ "body": self._wrong_record_msg("stock.lot"),
266
+ }
267
+
268
+ def several_lots_in_location(self, location):
269
+ return {
270
+ "message_type": "warning",
271
+ "body": _("Several lots found in %s, please scan a lot.") % location.name,
272
+ }
273
+
274
+ def several_lots_in_package(self, package):
275
+ return {
276
+ "message_type": "error",
277
+ "body": _("Several lots found in %(name)s, please scan the lot.")
278
+ % dict(name=package.name),
279
+ }
280
+
281
+ def several_move_in_different_location(self):
282
+ return {
283
+ "message_type": "warning",
284
+ "body": _(
285
+ "Several moves found on different locations, please scan first the location."
286
+ ),
287
+ }
288
+
289
+ def several_move_with_different_lot(self):
290
+ return {
291
+ "message_type": "warning",
292
+ "body": _("Several moves found for different lots, please scan the lot."),
293
+ }
294
+
295
+ def several_products_in_location(self, location):
296
+ return {
297
+ "message_type": "warning",
298
+ "body": _("Several products found in %(name)s, please scan a product.")
299
+ % dict(name=location.name),
300
+ }
301
+
302
+ def several_products_in_package(self, package):
303
+ return {
304
+ "message_type": "error",
305
+ "body": _("Several products found in %(name)s, please scan the product.")
306
+ % dict(name=package.name),
307
+ }
308
+
309
+ def no_product_in_location(self, location):
310
+ return {
311
+ "message_type": "error",
312
+ "body": _("No product found in {}").format(location.name),
313
+ }
314
+
315
+ def no_pending_operation_for_pack(self, pack):
316
+ return {
317
+ "message_type": "error",
318
+ "body": _("No pending operation for package %s.") % pack.name,
319
+ }
320
+
321
+ def no_putaway_destination_available(self):
322
+ return {
323
+ "message_type": "error",
324
+ "body": _("No putaway destination is available."),
325
+ }
326
+
327
+ def package_unable_to_transfer(self, pack):
328
+ return {
329
+ "message_type": "error",
330
+ "body": _("The package %s cannot be transferred with this scenario.")
331
+ % pack.name,
332
+ }
333
+
334
+ def unrecoverable_error(self):
335
+ return {
336
+ "message_type": "error",
337
+ "body": _("Unrecoverable error, please restart."),
338
+ }
339
+
340
+ def package_different_content(self, package):
341
+ return {
342
+ "message_type": "error",
343
+ "body": _("Package {} has a different content.").format(package.name),
344
+ }
345
+
346
+ def package_change_error_same_package(self, package):
347
+ return {
348
+ "message_type": "error",
349
+ "body": _("Same package {} is already assigned.").format(package.name),
350
+ }
351
+
352
+ def x_units_put_in_package(self, qty, product, package):
353
+ return {
354
+ "message_type": "success",
355
+ "body": _(
356
+ "%(qty)s %(product_name)s put in %(package_name)s",
357
+ qty=qty,
358
+ product_name=product.display_name,
359
+ package_name=package.name,
360
+ ),
361
+ }
362
+
363
+ def cannot_move_something_in_picking_type(self):
364
+ return {
365
+ "message_type": "error",
366
+ "body": _("You cannot move this using this menu."),
367
+ }
368
+
369
+ def stock_picking_not_available(self, picking):
370
+ return {
371
+ "message_type": "error",
372
+ "body": _("Transfer {} is not available.").format(picking.name),
373
+ }
374
+
375
+ def line_has_package_scan_package(self):
376
+ return {
377
+ "message_type": "warning",
378
+ "body": _("This line has a package, please select the package instead."),
379
+ }
380
+
381
+ def scan_the_location_first(self):
382
+ return {
383
+ "message_type": "warning",
384
+ "body": _("Please scan the location first."),
385
+ }
386
+
387
+ def scan_the_package(self):
388
+ return {
389
+ "message_type": "warning",
390
+ "body": _("Please scan the package."),
391
+ }
392
+
393
+ def product_multiple_packages_scan_package(self):
394
+ return {
395
+ "message_type": "warning",
396
+ "body": _(
397
+ _("This product is part of multiple packages, please scan a package.")
398
+ ),
399
+ }
400
+
401
+ def source_document_multiple_pickings_scan_package(self):
402
+ return {
403
+ "message_type": "warning",
404
+ "body": _(
405
+ _(
406
+ "This source document is part of multiple transfers, please scan a package."
407
+ )
408
+ ),
409
+ }
410
+
411
+ def product_mixed_package_scan_package(self):
412
+ return {
413
+ "message_type": "warning",
414
+ "body": _(
415
+ "This product is part of a package with other products, "
416
+ "please scan a package."
417
+ ),
418
+ }
419
+
420
+ def product_not_unitary_in_package_scan_package(self):
421
+ return {
422
+ "message_type": "warning",
423
+ "body": _("This product is part of a package, please scan a package."),
424
+ }
425
+
426
+ def product_not_found(self):
427
+ return {
428
+ "message_type": "error",
429
+ "body": _("This product does not exist anymore."),
430
+ }
431
+
432
+ def product_not_found_in_pickings(self):
433
+ return {
434
+ "message_type": "warning",
435
+ "body": _("No transfer found for this product."),
436
+ }
437
+
438
+ def x_not_found_or_already_in_dest_package(self, message_code):
439
+ return {
440
+ "message_type": "warning",
441
+ "body": _(
442
+ "{message_code} not found in the current transfer or already in a package."
443
+ ).format(message_code=message_code),
444
+ }
445
+
446
+ def packaging_not_found_in_picking(self):
447
+ return {
448
+ "message_type": "warning",
449
+ "body": _("Packaging not found in the current transfer."),
450
+ }
451
+
452
+ def expiration_date_missing(self):
453
+ return {
454
+ "message_type": "error",
455
+ "body": _("Missing expiration date."),
456
+ }
457
+
458
+ def multiple_picks_found_select_manually(self):
459
+ return {
460
+ "message_type": "error",
461
+ "body": _("Several transfers found, please select a transfer manually."),
462
+ }
463
+
464
+ def no_transfer_for_packaging(self):
465
+ return {
466
+ "message_type": "error",
467
+ "body": _("No transfer found for the scanned packaging."),
468
+ }
469
+
470
+ def no_transfer_for_lot(self):
471
+ return {
472
+ "message_type": "error",
473
+ "body": _("No transfer found for the scanned lot."),
474
+ }
475
+
476
+ def create_new_pack_ask_confirmation(self, barcode):
477
+ return {
478
+ "message_type": "warning",
479
+ "body": _("Create new PACK {}? Scan it again to confirm.").format(barcode),
480
+ }
481
+
482
+ def place_in_location_ask_confirmation(self, location_name):
483
+ return {
484
+ "message_type": "warning",
485
+ "body": _("Place it in {}?").format(location_name),
486
+ }
487
+
488
+ def product_not_found_in_current_picking(self):
489
+ return {
490
+ "message_type": "error",
491
+ "body": _("Product is not in the current transfer."),
492
+ }
493
+
494
+ def lot_mixed_package_scan_package(self):
495
+ return {
496
+ "message_type": "warning",
497
+ "body": _(
498
+ "This lot is part of a package with other products, "
499
+ "please scan a package."
500
+ ),
501
+ }
502
+
503
+ def lot_multiple_packages_scan_package(self):
504
+ return {
505
+ "message_type": "warning",
506
+ "body": _("This lot is part of multiple packages, please scan a package."),
507
+ }
508
+
509
+ def lot_not_found_in_pickings(self):
510
+ return {
511
+ "message_type": "warning",
512
+ "body": _("No transfer found for this lot."),
513
+ }
514
+
515
+ def batch_transfer_complete(self):
516
+ return {
517
+ "message_type": "success",
518
+ "body": _("Batch Transfer complete"),
519
+ }
520
+
521
+ def batch_transfer_line_done(self):
522
+ return {
523
+ "message_type": "success",
524
+ "body": _("Batch Transfer line done"),
525
+ }
526
+
527
+ def transfer_complete(self, picking):
528
+ return {
529
+ "message_type": "success",
530
+ "body": _("Transfer {} complete").format(picking.name),
531
+ }
532
+
533
+ def location_content_transfer_item_complete(self, location_dest):
534
+ return {
535
+ "message_type": "success",
536
+ "body": _("Content transfer to {} completed").format(location_dest.name),
537
+ }
538
+
539
+ def location_content_transfer_complete(self, location_src, location_dest):
540
+ return {
541
+ "message_type": "success",
542
+ "body": _(
543
+ "Content transferred from %(location_name)s to %(location_dest_name)s."
544
+ ).format(location_src.name, location_dest.name),
545
+ }
546
+
547
+ def location_content_unable_to_transfer(self, location_dest):
548
+ return {
549
+ "message_type": "error",
550
+ "body": _(
551
+ "The content of {} cannot be transferred with this scenario."
552
+ ).format(location_dest.name),
553
+ }
554
+
555
+ def product_in_multiple_sublocation(self, product):
556
+ return {
557
+ "message_type": "warning",
558
+ "body": _(
559
+ "Product {} found in multiple locations. Scan your location first."
560
+ ).format(product.name),
561
+ }
562
+
563
+ def lot_in_multiple_sublocation(self, lot):
564
+ return {
565
+ "message_type": "warning",
566
+ "body": _(
567
+ "Lot {lot} for product {product} found in multiple locations. "
568
+ "Scan your location first."
569
+ ).format(lot=lot.name, product=lot.product_id.name),
570
+ }
571
+
572
+ def no_default_location_on_picking_type(self):
573
+ return {
574
+ "message_type": "error",
575
+ "body": _(
576
+ "Operation types for this menu are missing "
577
+ "default source and destination locations."
578
+ ),
579
+ }
580
+
581
+ def location_src_set_to_sublocation(self, location_src):
582
+ return {
583
+ "message_type": "success",
584
+ "body": _("Working location changed to {}").format(location_src.name),
585
+ }
586
+
587
+ def picking_already_started_in_location(self, pickings):
588
+ return {
589
+ "message_type": "error",
590
+ "body": _(
591
+ "Picking has already been started in this location in transfer(s): {}"
592
+ ).format(", ".join(pickings.mapped("name"))),
593
+ }
594
+
595
+ def transfer_done_success(self, picking):
596
+ return {
597
+ "message_type": "success",
598
+ "body": _("Transfer {} done").format(picking.name),
599
+ }
600
+
601
+ def transfer_confirm_done(self):
602
+ return {
603
+ "message_type": "warning",
604
+ "body": _(
605
+ "Not all lines have been processed with full quantity. "
606
+ "Do you confirm partial operation?"
607
+ ),
608
+ }
609
+
610
+ def move_already_returned(self):
611
+ return {
612
+ "message_type": "error",
613
+ "body": _("The product/packaging you selected has already been returned."),
614
+ }
615
+
616
+ def return_line_invalid_qty(self):
617
+ return {
618
+ "message_type": "error",
619
+ "body": _("You cannot return more quantity than what was initially sent."),
620
+ }
621
+
622
+ def transfer_no_qty_done(self):
623
+ return {
624
+ "message_type": "warning",
625
+ "body": _(
626
+ "No quantity has been processed, unable to complete the transfer."
627
+ ),
628
+ }
629
+
630
+ def picking_zero_quantity(self):
631
+ return {
632
+ "message_type": "error",
633
+ "body": _("The picked quantity must be a value above zero."),
634
+ }
635
+
636
+ def selected_lines_qty_done_higher_than_allowed(self):
637
+ return {
638
+ "message_type": "warning",
639
+ "body": _(
640
+ "The quantity scanned for one or more lines cannot be "
641
+ "higher than the maximum allowed."
642
+ ),
643
+ }
644
+
645
+ def line_scanned_qty_done_higher_than_allowed(self):
646
+ return {
647
+ "message_type": "warning",
648
+ "body": _(
649
+ "Please note that the scanned quantity is higher than the maximum allowed."
650
+ ),
651
+ }
652
+
653
+ def recovered_previous_session(self):
654
+ return {
655
+ "message_type": "info",
656
+ "body": _("Recovered previous session."),
657
+ }
658
+
659
+ def no_lines_to_process(self):
660
+ return {
661
+ "message_type": "info",
662
+ "body": _("No lines to process."),
663
+ }
664
+
665
+ def location_empty(self, location):
666
+ return {
667
+ "message_type": "error",
668
+ "body": _("Location {} empty").format(location.name),
669
+ }
670
+
671
+ def location_empty_scan_package(self, location):
672
+ return {
673
+ "message_type": "warning",
674
+ "body": _("Location empty. Try scanning a package"),
675
+ }
676
+
677
+ def location_not_found(self):
678
+ return {
679
+ "message_type": "error",
680
+ "body": _("This location does not exist."),
681
+ }
682
+
683
+ def unable_to_pick_more(self, quantity):
684
+ return {
685
+ "message_type": "error",
686
+ "body": _("You must not pick more than {} units.").format(quantity),
687
+ }
688
+
689
+ def lot_replaced_by_lot(self, old_lot, new_lot):
690
+ return {
691
+ "message_type": "success",
692
+ "body": _("Lot %(old_lot_name)s replaced by lot %(new_lot_name)s.").format(
693
+ old_lot.name, new_lot.name
694
+ ),
695
+ }
696
+
697
+ def package_replaced_by_package(self, old_package, new_package):
698
+ return {
699
+ "message_type": "success",
700
+ "body": _(
701
+ "Package %(old_package_name)s replaced by package %(new_package_name)s."
702
+ ).format(old_package.name, new_package.name),
703
+ }
704
+
705
+ def package_already_picked_by(self, package, picking):
706
+ return {
707
+ "message_type": "error",
708
+ "body": _(
709
+ "Package %(package_name)s cannot be picked, already moved "
710
+ "by transfer %(picking_name)s.",
711
+ package_name=package.name,
712
+ picking_name=picking.name,
713
+ ),
714
+ }
715
+
716
+ def units_replaced_by_package(self, new_package):
717
+ return {
718
+ "message_type": "success",
719
+ "body": _("Units replaced by package {}.").format(new_package.name),
720
+ }
721
+
722
+ def package_change_error(self, package, error_msg):
723
+ return {
724
+ "message_type": "error",
725
+ "body": _(
726
+ "Package %(package_name)s cannot be used: %(error)s",
727
+ package_name=package.name,
728
+ error=error_msg,
729
+ ),
730
+ }
731
+
732
+ def cannot_change_lot_already_picked(self, lot):
733
+ return {
734
+ "message_type": "error",
735
+ "body": _("Cannot change to lot {} which is entirely picked.").format(
736
+ lot.name
737
+ ),
738
+ }
739
+
740
+ def buffer_complete(self):
741
+ return {
742
+ "message_type": "success",
743
+ "body": _("All packages processed."),
744
+ }
745
+
746
+ def picking_type_complete(self, picking_type):
747
+ return {
748
+ "message_type": "success",
749
+ "body": _("Picking type {} complete.").format(picking_type.name),
750
+ }
751
+
752
+ def barcode_no_match(self, barcode):
753
+ return {
754
+ "message_type": "warning",
755
+ "body": _("Barcode does not match with {}.").format(barcode),
756
+ }
757
+
758
+ def lines_different_dest_location(self):
759
+ return {
760
+ "message_type": "error",
761
+ "body": _("Lines have different destination location."),
762
+ }
763
+
764
+ def new_move_lines_not_assigned(self):
765
+ return {
766
+ "message_type": "error",
767
+ "body": _("New move lines cannot be assigned: canceled."),
768
+ }
769
+
770
+ def package_open(self):
771
+ return {
772
+ "message_type": "info",
773
+ "body": _("Package has been opened. You can move partial quantities."),
774
+ }
775
+
776
+ def packaging_invalid_for_carrier(self, packaging, carrier):
777
+ return {
778
+ "message_type": "error",
779
+ "body": _(
780
+ "Packaging '%(package_name)s' is not allowed for carrier "
781
+ "%(carrier_name)s.or carrier %(carrier_name)s.",
782
+ package_name=packaging.name if packaging else _("No value"),
783
+ carrier_name=carrier.name,
784
+ ),
785
+ }
786
+
787
+ def dest_package_not_valid(self, package):
788
+ return {
789
+ "message_type": "error",
790
+ "body": _("{} is not a valid destination package.").format(package.name),
791
+ }
792
+
793
+ def no_valid_package_to_select(self):
794
+ return {
795
+ "message_type": "warning",
796
+ "body": _("No valid package to select."),
797
+ }
798
+
799
+ def no_delivery_packaging_available(self):
800
+ return {
801
+ "message_type": "warning",
802
+ "body": _("No delivery package type available."),
803
+ }
804
+
805
+ def goods_packed_in(self, package):
806
+ return {
807
+ "message_type": "info",
808
+ "body": _("Goods packed into {0.name}").format(package),
809
+ }
810
+
811
+ def picking_without_carrier_cannot_pack(self, picking):
812
+ return {
813
+ "message_type": "error",
814
+ "body": _(
815
+ "Pick + Pack mode ON: the picking {0.name} has no carrier set. "
816
+ "The system couldn't pack goods automatically."
817
+ ).format(picking),
818
+ }
819
+
820
+ def no_work_found(self):
821
+ return {
822
+ "message_type": "warning",
823
+ "body": _("No available work could be found."),
824
+ }
825
+
826
+ def confirm_put_all_goods_in_delivery_package(self, packaging_type):
827
+ return {
828
+ "message_type": "warning",
829
+ "body": _(
830
+ "Delivery package type scanned: %(name)s. "
831
+ "Scan again to place all goods in the same package."
832
+ )
833
+ % dict(name=packaging_type.name),
834
+ }
835
+
836
+ def location_contains_only_packages_scan_one(self):
837
+ return {
838
+ "message_type": "warning",
839
+ "body": _("This location only contains packages, please scan one of them."),
840
+ }
841
+
842
+ def no_line_to_pack(self):
843
+ return {
844
+ "message_type": "warning",
845
+ "body": _("No line to pack found."),
846
+ }