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.
- odoo/addons/shopfloor/README.rst +160 -0
- odoo/addons/shopfloor/__init__.py +4 -0
- odoo/addons/shopfloor/__manifest__.py +65 -0
- odoo/addons/shopfloor/actions/__init__.py +15 -0
- odoo/addons/shopfloor/actions/change_package_lot.py +164 -0
- odoo/addons/shopfloor/actions/completion_info.py +42 -0
- odoo/addons/shopfloor/actions/data.py +329 -0
- odoo/addons/shopfloor/actions/data_detail.py +154 -0
- odoo/addons/shopfloor/actions/inventory.py +150 -0
- odoo/addons/shopfloor/actions/location_content_transfer_sorter.py +89 -0
- odoo/addons/shopfloor/actions/message.py +846 -0
- odoo/addons/shopfloor/actions/move_line_search.py +119 -0
- odoo/addons/shopfloor/actions/packaging.py +59 -0
- odoo/addons/shopfloor/actions/savepoint.py +44 -0
- odoo/addons/shopfloor/actions/schema.py +182 -0
- odoo/addons/shopfloor/actions/schema_detail.py +98 -0
- odoo/addons/shopfloor/actions/search.py +187 -0
- odoo/addons/shopfloor/actions/stock.py +239 -0
- odoo/addons/shopfloor/actions/stock_unreserve.py +66 -0
- odoo/addons/shopfloor/components/__init__.py +5 -0
- odoo/addons/shopfloor/components/scan_handler_location.py +26 -0
- odoo/addons/shopfloor/components/scan_handler_lot.py +26 -0
- odoo/addons/shopfloor/components/scan_handler_package.py +26 -0
- odoo/addons/shopfloor/components/scan_handler_product.py +26 -0
- odoo/addons/shopfloor/components/scan_handler_transfer.py +26 -0
- odoo/addons/shopfloor/data/shopfloor_scenario_data.xml +73 -0
- odoo/addons/shopfloor/demo/shopfloor_app_demo.xml +12 -0
- odoo/addons/shopfloor/demo/shopfloor_menu_demo.xml +64 -0
- odoo/addons/shopfloor/demo/shopfloor_profile_demo.xml +8 -0
- odoo/addons/shopfloor/demo/stock_picking_type_demo.xml +93 -0
- odoo/addons/shopfloor/docs/checkout_diag_seq.plantuml +61 -0
- odoo/addons/shopfloor/docs/checkout_diag_seq.png +0 -0
- odoo/addons/shopfloor/docs/cluster_picking_diag_seq.plantuml +112 -0
- odoo/addons/shopfloor/docs/cluster_picking_diag_seq.png +0 -0
- odoo/addons/shopfloor/docs/delivery_diag_seq.plantuml +56 -0
- odoo/addons/shopfloor/docs/delivery_diag_seq.png +0 -0
- odoo/addons/shopfloor/docs/location_content_transfer_diag_seq.plantuml +66 -0
- odoo/addons/shopfloor/docs/location_content_transfer_diag_seq.png +0 -0
- odoo/addons/shopfloor/docs/oca_logo.png +0 -0
- odoo/addons/shopfloor/docs/single_pack_transfer_diag_seq.plantuml +36 -0
- odoo/addons/shopfloor/docs/single_pack_transfer_diag_seq.png +0 -0
- odoo/addons/shopfloor/docs/zone_picking_diag_seq.plantuml +85 -0
- odoo/addons/shopfloor/docs/zone_picking_diag_seq.png +0 -0
- odoo/addons/shopfloor/exceptions.py +6 -0
- odoo/addons/shopfloor/i18n/ca.po +1802 -0
- odoo/addons/shopfloor/i18n/de.po +1791 -0
- odoo/addons/shopfloor/i18n/es_AR.po +2147 -0
- odoo/addons/shopfloor/i18n/pt_BR.po +1791 -0
- odoo/addons/shopfloor/i18n/shopfloor.pot +1877 -0
- odoo/addons/shopfloor/models/__init__.py +12 -0
- odoo/addons/shopfloor/models/priority_postpone_mixin.py +41 -0
- odoo/addons/shopfloor/models/shopfloor_app.py +9 -0
- odoo/addons/shopfloor/models/shopfloor_menu.py +436 -0
- odoo/addons/shopfloor/models/stock_location.py +76 -0
- odoo/addons/shopfloor/models/stock_move.py +119 -0
- odoo/addons/shopfloor/models/stock_move_line.py +307 -0
- odoo/addons/shopfloor/models/stock_package_level.py +50 -0
- odoo/addons/shopfloor/models/stock_picking.py +118 -0
- odoo/addons/shopfloor/models/stock_picking_batch.py +41 -0
- odoo/addons/shopfloor/models/stock_picking_type.py +26 -0
- odoo/addons/shopfloor/models/stock_quant.py +31 -0
- odoo/addons/shopfloor/models/stock_quant_package.py +101 -0
- odoo/addons/shopfloor/readme/CONTRIBUTORS.rst +18 -0
- odoo/addons/shopfloor/readme/CREDITS.rst +5 -0
- odoo/addons/shopfloor/readme/DESCRIPTION.rst +17 -0
- odoo/addons/shopfloor/readme/HISTORY.rst +4 -0
- odoo/addons/shopfloor/readme/ROADMAP.rst +4 -0
- odoo/addons/shopfloor/readme/USAGE.rst +6 -0
- odoo/addons/shopfloor/security/groups.xml +17 -0
- odoo/addons/shopfloor/services/__init__.py +16 -0
- odoo/addons/shopfloor/services/checkout.py +1763 -0
- odoo/addons/shopfloor/services/cluster_picking.py +1628 -0
- odoo/addons/shopfloor/services/delivery.py +828 -0
- odoo/addons/shopfloor/services/forms/__init__.py +1 -0
- odoo/addons/shopfloor/services/forms/picking_form.py +78 -0
- odoo/addons/shopfloor/services/location_content_transfer.py +1194 -0
- odoo/addons/shopfloor/services/menu.py +60 -0
- odoo/addons/shopfloor/services/picking_batch.py +126 -0
- odoo/addons/shopfloor/services/service.py +101 -0
- odoo/addons/shopfloor/services/single_pack_transfer.py +366 -0
- odoo/addons/shopfloor/services/zone_picking.py +1938 -0
- odoo/addons/shopfloor/static/description/icon.png +0 -0
- odoo/addons/shopfloor/static/description/index.html +500 -0
- odoo/addons/shopfloor/tests/__init__.py +83 -0
- odoo/addons/shopfloor/tests/common.py +324 -0
- odoo/addons/shopfloor/tests/models.py +29 -0
- odoo/addons/shopfloor/tests/test_actions_change_package_lot.py +1175 -0
- odoo/addons/shopfloor/tests/test_actions_data.py +376 -0
- odoo/addons/shopfloor/tests/test_actions_data_base.py +244 -0
- odoo/addons/shopfloor/tests/test_actions_data_detail.py +322 -0
- odoo/addons/shopfloor/tests/test_actions_search.py +248 -0
- odoo/addons/shopfloor/tests/test_actions_stock.py +48 -0
- odoo/addons/shopfloor/tests/test_checkout_auto_post.py +67 -0
- odoo/addons/shopfloor/tests/test_checkout_base.py +81 -0
- odoo/addons/shopfloor/tests/test_checkout_cancel_line.py +154 -0
- odoo/addons/shopfloor/tests/test_checkout_change_packaging.py +184 -0
- odoo/addons/shopfloor/tests/test_checkout_done.py +133 -0
- odoo/addons/shopfloor/tests/test_checkout_list_delivery_packaging.py +131 -0
- odoo/addons/shopfloor/tests/test_checkout_list_package.py +327 -0
- odoo/addons/shopfloor/tests/test_checkout_new_package.py +88 -0
- odoo/addons/shopfloor/tests/test_checkout_no_package.py +95 -0
- odoo/addons/shopfloor/tests/test_checkout_scan.py +174 -0
- odoo/addons/shopfloor/tests/test_checkout_scan_line.py +377 -0
- odoo/addons/shopfloor/tests/test_checkout_scan_line_base.py +25 -0
- odoo/addons/shopfloor/tests/test_checkout_scan_line_no_prefill_qty.py +91 -0
- odoo/addons/shopfloor/tests/test_checkout_scan_package_action.py +451 -0
- odoo/addons/shopfloor/tests/test_checkout_scan_package_action_no_prefill_qty.py +107 -0
- odoo/addons/shopfloor/tests/test_checkout_select.py +74 -0
- odoo/addons/shopfloor/tests/test_checkout_select_line.py +130 -0
- odoo/addons/shopfloor/tests/test_checkout_select_package_base.py +64 -0
- odoo/addons/shopfloor/tests/test_checkout_set_qty.py +257 -0
- odoo/addons/shopfloor/tests/test_checkout_summary.py +69 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_base.py +83 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_batch.py +109 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_change_pack_lot.py +111 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_is_zero.py +98 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_scan_destination.py +376 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_scan_destination_no_prefill_qty.py +115 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_scan_line.py +402 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_scan_line_location_or_pack_first.py +114 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_scan_line_no_prefill_qty.py +70 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_select.py +387 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_skip.py +90 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_stock_issue.py +364 -0
- odoo/addons/shopfloor/tests/test_cluster_picking_unload.py +911 -0
- odoo/addons/shopfloor/tests/test_delivery_base.py +155 -0
- odoo/addons/shopfloor/tests/test_delivery_done.py +108 -0
- odoo/addons/shopfloor/tests/test_delivery_list_stock_picking.py +49 -0
- odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_line.py +119 -0
- odoo/addons/shopfloor/tests/test_delivery_reset_qty_done_pack.py +107 -0
- odoo/addons/shopfloor/tests/test_delivery_scan_deliver.py +557 -0
- odoo/addons/shopfloor/tests/test_delivery_select.py +38 -0
- odoo/addons/shopfloor/tests/test_delivery_set_qty_done_line.py +91 -0
- odoo/addons/shopfloor/tests/test_delivery_set_qty_done_pack.py +135 -0
- odoo/addons/shopfloor/tests/test_delivery_sublocation.py +180 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_base.py +136 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_get_work.py +125 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_mix.py +509 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_putaway.py +143 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_scan_location.py +34 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_set_destination_all.py +343 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_set_destination_package_or_line.py +1074 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_single.py +748 -0
- odoo/addons/shopfloor/tests/test_location_content_transfer_start.py +359 -0
- odoo/addons/shopfloor/tests/test_menu_base.py +261 -0
- odoo/addons/shopfloor/tests/test_menu_counters.py +61 -0
- odoo/addons/shopfloor/tests/test_misc.py +25 -0
- odoo/addons/shopfloor/tests/test_move_action_assign.py +87 -0
- odoo/addons/shopfloor/tests/test_openapi.py +21 -0
- odoo/addons/shopfloor/tests/test_picking_form.py +62 -0
- odoo/addons/shopfloor/tests/test_scan_anything.py +49 -0
- odoo/addons/shopfloor/tests/test_single_pack_transfer.py +1121 -0
- odoo/addons/shopfloor/tests/test_single_pack_transfer_base.py +32 -0
- odoo/addons/shopfloor/tests/test_single_pack_transfer_putaway.py +104 -0
- odoo/addons/shopfloor/tests/test_stock_split.py +204 -0
- odoo/addons/shopfloor/tests/test_user.py +42 -0
- odoo/addons/shopfloor/tests/test_zone_picking_base.py +608 -0
- odoo/addons/shopfloor/tests/test_zone_picking_change_pack_lot.py +140 -0
- odoo/addons/shopfloor/tests/test_zone_picking_select_line.py +723 -0
- odoo/addons/shopfloor/tests/test_zone_picking_select_line_first_scan_location.py +207 -0
- odoo/addons/shopfloor/tests/test_zone_picking_select_line_first_scan_location.py.bak +202 -0
- odoo/addons/shopfloor/tests/test_zone_picking_select_line_no_prefill_qty.py +107 -0
- odoo/addons/shopfloor/tests/test_zone_picking_select_picking_type.py +26 -0
- odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination.py +643 -0
- odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_no_prefill_qty.py +146 -0
- odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_pick_pack.py +241 -0
- odoo/addons/shopfloor/tests/test_zone_picking_start.py +206 -0
- odoo/addons/shopfloor/tests/test_zone_picking_stock_issue.py +121 -0
- odoo/addons/shopfloor/tests/test_zone_picking_unload_all.py +353 -0
- odoo/addons/shopfloor/tests/test_zone_picking_unload_buffer_lines.py +113 -0
- odoo/addons/shopfloor/tests/test_zone_picking_unload_set_destination.py +374 -0
- odoo/addons/shopfloor/tests/test_zone_picking_unload_single.py +123 -0
- odoo/addons/shopfloor/tests/test_zone_picking_zero_check.py +43 -0
- odoo/addons/shopfloor/utils.py +13 -0
- odoo/addons/shopfloor/views/shopfloor_menu.xml +167 -0
- odoo/addons/shopfloor/views/stock_location.xml +20 -0
- odoo/addons/shopfloor/views/stock_move_line.xml +52 -0
- odoo/addons/shopfloor/views/stock_picking_type.xml +19 -0
- odoo_addon_shopfloor-16.0.1.0.0.24.dist-info/METADATA +192 -0
- odoo_addon_shopfloor-16.0.1.0.0.24.dist-info/RECORD +182 -0
- odoo_addon_shopfloor-16.0.1.0.0.24.dist-info/WHEEL +5 -0
- 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
|
+
)
|