odoo-addon-shopfloor 16.0.2.7.0.1__py3-none-any.whl → 16.0.2.8.0__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 +1 -1
- odoo/addons/shopfloor/__manifest__.py +1 -1
- odoo/addons/shopfloor/actions/change_package_lot.py +3 -1
- odoo/addons/shopfloor/actions/data.py +2 -1
- odoo/addons/shopfloor/actions/data_detail.py +2 -2
- odoo/addons/shopfloor/actions/location_content_transfer_sorter.py +0 -1
- odoo/addons/shopfloor/actions/message.py +12 -6
- odoo/addons/shopfloor/actions/move_line_search.py +3 -1
- odoo/addons/shopfloor/actions/savepoint.py +1 -1
- odoo/addons/shopfloor/actions/schema.py +0 -1
- odoo/addons/shopfloor/actions/search.py +2 -2
- odoo/addons/shopfloor/actions/stock.py +1 -1
- odoo/addons/shopfloor/demo/shopfloor_app_demo.xml +7 -7
- odoo/addons/shopfloor/i18n/it.po +8 -6
- odoo/addons/shopfloor/i18n/shopfloor.pot +8 -8
- odoo/addons/shopfloor/migrations/16.0.2.0.0/post-migration.py +1 -3
- odoo/addons/shopfloor/models/shopfloor_menu.py +5 -3
- odoo/addons/shopfloor/models/stock_picking.py +2 -1
- odoo/addons/shopfloor/services/checkout.py +16 -16
- odoo/addons/shopfloor/services/cluster_picking.py +10 -10
- odoo/addons/shopfloor/services/delivery.py +3 -3
- odoo/addons/shopfloor/services/service.py +0 -1
- odoo/addons/shopfloor/services/single_pack_transfer.py +0 -1
- odoo/addons/shopfloor/services/zone_picking.py +16 -13
- odoo/addons/shopfloor/static/description/index.html +1 -1
- odoo/addons/shopfloor/tests/common.py +0 -1
- odoo/addons/shopfloor/tests/models.py +1 -0
- odoo/addons/shopfloor/tests/test_actions_change_package_lot.py +6 -10
- odoo/addons/shopfloor/tests/test_actions_data_base.py +4 -4
- odoo/addons/shopfloor/tests/test_checkout_auto_post.py +7 -6
- odoo/addons/shopfloor/tests/test_checkout_base.py +1 -6
- odoo/addons/shopfloor/tests/test_checkout_change_packaging.py +1 -1
- odoo/addons/shopfloor/tests/test_checkout_done.py +1 -1
- odoo/addons/shopfloor/tests/test_checkout_list_delivery_packaging.py +1 -1
- odoo/addons/shopfloor/tests/test_checkout_scan.py +1 -1
- odoo/addons/shopfloor/tests/test_checkout_scan_line.py +4 -4
- odoo/addons/shopfloor/tests/test_checkout_scan_line_no_prefill_qty.py +3 -3
- odoo/addons/shopfloor/tests/test_checkout_scan_package_action.py +10 -10
- odoo/addons/shopfloor/tests/test_cluster_picking_is_zero.py +2 -10
- odoo/addons/shopfloor/tests/test_cluster_picking_scan_destination.py +6 -14
- odoo/addons/shopfloor/tests/test_cluster_picking_scan_line_location_or_pack_first.py +1 -2
- odoo/addons/shopfloor/tests/test_cluster_picking_stock_issue.py +3 -3
- odoo/addons/shopfloor/tests/test_cluster_picking_unload.py +3 -3
- odoo/addons/shopfloor/tests/test_delivery_scan_deliver.py +1 -1
- odoo/addons/shopfloor/tests/test_location_content_transfer_get_work.py +5 -2
- odoo/addons/shopfloor/tests/test_location_content_transfer_mix.py +12 -11
- odoo/addons/shopfloor/tests/test_menu_contrains.py +0 -1
- odoo/addons/shopfloor/tests/test_single_pack_transfer.py +9 -9
- odoo/addons/shopfloor/tests/test_stock_split.py +1 -1
- odoo/addons/shopfloor/tests/test_zone_picking_base.py +11 -10
- odoo/addons/shopfloor/tests/test_zone_picking_complete_mix_pack_flux.py +2 -2
- odoo/addons/shopfloor/tests/test_zone_picking_require_destination_package.py +1 -1
- odoo/addons/shopfloor/tests/test_zone_picking_select_line.py +15 -15
- odoo/addons/shopfloor/tests/test_zone_picking_select_line_no_prefill_qty.py +2 -2
- odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination.py +9 -9
- odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_no_prefill_qty.py +1 -1
- odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_package_not_allowed.py +2 -2
- odoo/addons/shopfloor/tests/test_zone_picking_set_line_destination_pick_pack.py +2 -2
- odoo/addons/shopfloor/tests/test_zone_picking_unload_all.py +3 -1
- odoo/addons/shopfloor/tests/test_zone_picking_unload_set_destination.py +2 -2
- odoo/addons/shopfloor/views/shopfloor_menu.xml +96 -89
- {odoo_addon_shopfloor-16.0.2.7.0.1.dist-info → odoo_addon_shopfloor-16.0.2.8.0.dist-info}/METADATA +2 -2
- {odoo_addon_shopfloor-16.0.2.7.0.1.dist-info → odoo_addon_shopfloor-16.0.2.8.0.dist-info}/RECORD +65 -65
- {odoo_addon_shopfloor-16.0.2.7.0.1.dist-info → odoo_addon_shopfloor-16.0.2.8.0.dist-info}/WHEEL +0 -0
- {odoo_addon_shopfloor-16.0.2.7.0.1.dist-info → odoo_addon_shopfloor-16.0.2.8.0.dist-info}/top_level.txt +0 -0
@@ -367,7 +367,7 @@ ul.auto-toc {
|
|
367
367
|
!! This file is generated by oca-gen-addon-readme !!
|
368
368
|
!! changes will be overwritten. !!
|
369
369
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
370
|
-
!! source digest: sha256:
|
370
|
+
!! source digest: sha256:8f4a1f9cca9cb3a4830c65a6a9d8a65ec3334a34722525fe5da87e77b0e90de2
|
371
371
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
372
372
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/wms/tree/16.0/shopfloor"><img alt="OCA/wms" src="https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
373
373
|
<p>Shopfloor is a barcode scanner application for internal warehouse operations.</p>
|
@@ -716,9 +716,7 @@ class TestActionsChangePackageLot(CommonCase):
|
|
716
716
|
# still we have to handle it). Forbid to pick.
|
717
717
|
expected_message = self.msg_store.package_change_error(
|
718
718
|
new_package,
|
719
|
-
"Package {} has been partially picked in another location"
|
720
|
-
new_package.display_name
|
721
|
-
),
|
719
|
+
f"Package {new_package.display_name} has been partially picked in another location", # noqa
|
722
720
|
)
|
723
721
|
self.change_package_lot.change_package(
|
724
722
|
line,
|
@@ -921,6 +919,10 @@ class TestActionsChangePackageLot(CommonCase):
|
|
921
919
|
line2 = picking2.move_line_ids
|
922
920
|
line2.qty_done = 10
|
923
921
|
|
922
|
+
expected_msg = (
|
923
|
+
f"Package {package2.display_name} does not contain available product "
|
924
|
+
f"{line1.product_id.display_name}, cannot replace package."
|
925
|
+
)
|
924
926
|
self.change_package_lot.change_package(
|
925
927
|
line1,
|
926
928
|
package2,
|
@@ -929,13 +931,7 @@ class TestActionsChangePackageLot(CommonCase):
|
|
929
931
|
# failure callback
|
930
932
|
lambda move_line, message=None: self.assertEqual(
|
931
933
|
message,
|
932
|
-
self.msg_store.package_change_error(
|
933
|
-
package2,
|
934
|
-
"Package {} does not contain available product {},"
|
935
|
-
" cannot replace package.".format(
|
936
|
-
package2.display_name, line1.product_id.display_name
|
937
|
-
),
|
938
|
-
),
|
934
|
+
self.msg_store.package_change_error(package2, expected_msg),
|
939
935
|
),
|
940
936
|
)
|
941
937
|
|
@@ -219,7 +219,7 @@ class ActionsDataDetailCaseBase(ActionsDataCaseBase):
|
|
219
219
|
kw.get("move_lines", [])
|
220
220
|
),
|
221
221
|
"products": self.data_detail._location_content(record),
|
222
|
-
}
|
222
|
+
},
|
223
223
|
)
|
224
224
|
|
225
225
|
def _expected_location_lot(self, record, **kw):
|
@@ -228,7 +228,7 @@ class ActionsDataDetailCaseBase(ActionsDataCaseBase):
|
|
228
228
|
**{
|
229
229
|
"removal_date": record.removal_date or None,
|
230
230
|
"quantity": sum(record.quant_ids.mapped("quantity")),
|
231
|
-
}
|
231
|
+
},
|
232
232
|
)
|
233
233
|
|
234
234
|
def _expected_product_detail(self, record, **kw):
|
@@ -262,7 +262,7 @@ class ActionsDataDetailCaseBase(ActionsDataCaseBase):
|
|
262
262
|
if kw.get("full"):
|
263
263
|
detail.update(
|
264
264
|
{
|
265
|
-
"image": "/web/image/product.product/{}/image_128"
|
265
|
+
"image": f"/web/image/product.product/{record.id}/image_128"
|
266
266
|
if record.image_128
|
267
267
|
else None,
|
268
268
|
"locations": locations_info,
|
@@ -296,5 +296,5 @@ class ActionsDataDetailCaseBase(ActionsDataCaseBase):
|
|
296
296
|
"length_uom": record.length_uom_name,
|
297
297
|
"weight_uom": record.weight_uom_name,
|
298
298
|
"barcode": record.barcode,
|
299
|
-
}
|
299
|
+
},
|
300
300
|
)
|
@@ -12,20 +12,21 @@ class CheckoutAutoPostCase(CheckoutCommonCase):
|
|
12
12
|
self._fill_stock_for_moves(picking.move_ids)
|
13
13
|
picking.action_assign()
|
14
14
|
selected_move_line_a = picking.move_line_ids.filtered(
|
15
|
-
lambda
|
15
|
+
lambda x: x.product_id == self.product_a
|
16
16
|
)
|
17
17
|
selected_move_line_a.qty_done = 7
|
18
18
|
selected_move_line_b = picking.move_line_ids.filtered(
|
19
|
-
lambda
|
19
|
+
lambda x: x.product_id == self.product_b
|
20
20
|
)
|
21
21
|
selected_move_line_b.qty_done = 9
|
22
22
|
selected_move_line_c = picking.move_line_ids.filtered(
|
23
|
-
lambda
|
23
|
+
lambda x: x.product_id == self.product_c
|
24
24
|
)
|
25
25
|
|
26
26
|
# User has selected 7 units out of 10 for product_a,
|
27
27
|
# and 9 units out of 20 for product_b.
|
28
|
-
# We would expect a split picking to be created
|
28
|
+
# We would expect a split picking to be created
|
29
|
+
# with those two lines and qtys done.
|
29
30
|
self.service.dispatch(
|
30
31
|
"scan_package_action",
|
31
32
|
params={
|
@@ -53,10 +54,10 @@ class CheckoutAutoPostCase(CheckoutCommonCase):
|
|
53
54
|
# - the original line for product c, unchanged;
|
54
55
|
# - two lines (products a and b) with the non-split qtys.
|
55
56
|
line_a_in_original_picking = picking.move_line_ids.filtered(
|
56
|
-
lambda
|
57
|
+
lambda x: x.product_id == selected_move_line_a.product_id
|
57
58
|
)
|
58
59
|
line_b_in_original_picking = picking.move_line_ids.filtered(
|
59
|
-
lambda
|
60
|
+
lambda x: x.product_id == selected_move_line_b.product_id
|
60
61
|
)
|
61
62
|
self.assertEqual(line_a_in_original_picking.reserved_uom_qty, 3)
|
62
63
|
self.assertEqual(line_b_in_original_picking.reserved_uom_qty, 11)
|
@@ -91,11 +91,6 @@ class CheckoutCommonCase(CommonCase):
|
|
91
91
|
"message_type": "warning",
|
92
92
|
"body": "The quantity scanned for one or more lines cannot be "
|
93
93
|
"higher than the maximum allowed. "
|
94
|
-
"(
|
95
|
-
% dict(
|
96
|
-
product_name=line.product_id.name,
|
97
|
-
quantity_done=str(line.qty_done),
|
98
|
-
quantity_reserved=str(line.reserved_uom_qty),
|
99
|
-
),
|
94
|
+
f"({line.product_id.name} : {str(line.qty_done)} > {str(line.reserved_uom_qty)})", # noqa
|
100
95
|
},
|
101
96
|
)
|
@@ -135,7 +135,7 @@ class CheckoutListSetPackagingCase(CheckoutCommonCase):
|
|
135
135
|
},
|
136
136
|
message={
|
137
137
|
"message_type": "success",
|
138
|
-
"body": "Packaging changed on package {
|
138
|
+
"body": f"Packaging changed on package {self.package.name}",
|
139
139
|
},
|
140
140
|
)
|
141
141
|
|
@@ -20,7 +20,7 @@ class CheckoutDoneCase(CheckoutCommonCase):
|
|
20
20
|
next_state="select_document",
|
21
21
|
message={
|
22
22
|
"message_type": "success",
|
23
|
-
"body": "Transfer {} done"
|
23
|
+
"body": f"Transfer {picking.name} done",
|
24
24
|
},
|
25
25
|
data={"restrict_scan_first": False},
|
26
26
|
)
|
@@ -31,7 +31,7 @@ class CheckoutListDeliveryPackagingCase(CheckoutCommonCase, CheckoutSelectPackag
|
|
31
31
|
@classmethod
|
32
32
|
def tearDownClass(cls):
|
33
33
|
cls.loader.restore_registry()
|
34
|
-
super(
|
34
|
+
super().tearDownClass()
|
35
35
|
|
36
36
|
@classmethod
|
37
37
|
def setUpClassBaseData(cls, *args, **kwargs):
|
@@ -84,7 +84,7 @@ class CheckoutScanCase(CheckoutCommonCase):
|
|
84
84
|
next_state="select_document",
|
85
85
|
message={
|
86
86
|
"message_type": "error",
|
87
|
-
"body": "Transfer {} is not available."
|
87
|
+
"body": f"Transfer {picking.name} is not available.",
|
88
88
|
},
|
89
89
|
data={"restrict_scan_first": False},
|
90
90
|
)
|
@@ -67,7 +67,7 @@ class CheckoutScanLineCase(CheckoutScanLineCaseBase):
|
|
67
67
|
picking.action_assign()
|
68
68
|
# The product a is scanned, so selected and quantity updated
|
69
69
|
line_a = picking.move_line_ids.filtered(
|
70
|
-
lambda
|
70
|
+
lambda x: x.product_id == self.product_a
|
71
71
|
)
|
72
72
|
# Because not part of a package other lines are selected also
|
73
73
|
related_lines = picking.move_line_ids - line_a
|
@@ -84,7 +84,7 @@ class CheckoutScanLineCase(CheckoutScanLineCaseBase):
|
|
84
84
|
picking.action_assign()
|
85
85
|
# The product a is scanned, so selected and quantity updated
|
86
86
|
lines_a = picking.move_line_ids.filtered(
|
87
|
-
lambda
|
87
|
+
lambda x: x.product_id == self.product_a
|
88
88
|
)
|
89
89
|
# Because not part of a package other lines are selected also
|
90
90
|
related_lines = picking.move_line_ids - lines_a
|
@@ -100,7 +100,7 @@ class CheckoutScanLineCase(CheckoutScanLineCaseBase):
|
|
100
100
|
self._fill_stock_for_moves(picking.move_ids)
|
101
101
|
picking.action_assign()
|
102
102
|
lines_a = picking.move_line_ids.filtered(
|
103
|
-
lambda
|
103
|
+
lambda x: x.product_id == self.product_a
|
104
104
|
)
|
105
105
|
# when we scan the packaging of the product, we should select the
|
106
106
|
# lines as if the product was scanned
|
@@ -177,7 +177,7 @@ class CheckoutScanLineCase(CheckoutScanLineCaseBase):
|
|
177
177
|
package.name,
|
178
178
|
{
|
179
179
|
"message_type": "error",
|
180
|
-
"body": f"Package {package.name} not found in transfer {picking.name}",
|
180
|
+
"body": f"Package {package.name} not found in transfer {picking.name}", # noqa
|
181
181
|
},
|
182
182
|
)
|
183
183
|
|
@@ -37,7 +37,7 @@ class CheckoutScanLineNoPrefillQtyCase(CheckoutScanLineCaseBase):
|
|
37
37
|
"scan_line", params={"picking_id": picking.id, "barcode": barcode}
|
38
38
|
)
|
39
39
|
response_lines = response["data"]["select_package"]["selected_move_lines"]
|
40
|
-
for response_line, qty in zip(response_lines, qties):
|
40
|
+
for response_line, qty in zip(response_lines, qties, strict=False):
|
41
41
|
self.assertEqual(response_line["qty_done"], qty)
|
42
42
|
|
43
43
|
def test_scan_line_product_exist_in_two_lines(self):
|
@@ -65,7 +65,7 @@ class CheckoutScanLineNoPrefillQtyCase(CheckoutScanLineCaseBase):
|
|
65
65
|
self._fill_stock_for_moves(picking.move_ids)
|
66
66
|
picking.action_assign()
|
67
67
|
line_a = picking.move_line_ids.filtered(
|
68
|
-
lambda
|
68
|
+
lambda x: x.product_id == self.product_a
|
69
69
|
)
|
70
70
|
# When no_prefill_qty is enabled in the checkout menu, prefilled qty
|
71
71
|
# should be 1.0 if a product is scanned
|
@@ -79,7 +79,7 @@ class CheckoutScanLineNoPrefillQtyCase(CheckoutScanLineCaseBase):
|
|
79
79
|
self._fill_stock_for_moves(picking.move_ids)
|
80
80
|
picking.action_assign()
|
81
81
|
lines_a = picking.move_line_ids.filtered(
|
82
|
-
lambda
|
82
|
+
lambda x: x.product_id == self.product_a
|
83
83
|
)
|
84
84
|
# When no_prefill_qty is enabled in the checkout menu, prefilled qty
|
85
85
|
# should be the packaging qty, if a packaging is scanned
|
@@ -40,40 +40,40 @@ class CheckoutScanPackageActionCase(CheckoutCommonCase, CheckoutSelectPackageMix
|
|
40
40
|
|
41
41
|
def test_scan_package_action_select_product(self):
|
42
42
|
self._test_select_product(
|
43
|
-
lambda
|
43
|
+
lambda x: x.product_id.barcode, lambda x: x.reserved_uom_qty, lambda __: 0
|
44
44
|
)
|
45
45
|
|
46
46
|
def test_scan_package_action_deselect_product(self):
|
47
47
|
self._test_select_product(
|
48
|
-
lambda
|
48
|
+
lambda x: x.product_id.barcode, lambda __: 0, lambda x: x.reserved_uom_qty
|
49
49
|
)
|
50
50
|
|
51
51
|
def test_scan_package_action_select_product_packaging(self):
|
52
52
|
self._test_select_product(
|
53
|
-
lambda
|
54
|
-
lambda
|
53
|
+
lambda x: x.product_id.packaging_ids.barcode,
|
54
|
+
lambda x: x.reserved_uom_qty,
|
55
55
|
lambda __: 0,
|
56
56
|
)
|
57
57
|
|
58
58
|
def test_scan_package_action_deselect_product_packaging(self):
|
59
59
|
self._test_select_product(
|
60
|
-
lambda
|
60
|
+
lambda x: x.product_id.packaging_ids.barcode,
|
61
61
|
lambda __: 0,
|
62
|
-
lambda
|
62
|
+
lambda x: x.reserved_uom_qty,
|
63
63
|
)
|
64
64
|
|
65
65
|
def test_scan_package_action_select_product_lot(self):
|
66
66
|
self._test_select_product(
|
67
|
-
lambda
|
67
|
+
lambda x: x.lot_id.name,
|
68
68
|
lambda __: 0,
|
69
|
-
lambda
|
69
|
+
lambda x: x.reserved_uom_qty,
|
70
70
|
in_lot=True,
|
71
71
|
)
|
72
72
|
|
73
73
|
def test_scan_package_action_deselect_product_lot(self):
|
74
74
|
self._test_select_product(
|
75
|
-
lambda
|
76
|
-
lambda
|
75
|
+
lambda x: x.lot_id.name,
|
76
|
+
lambda x: x.reserved_uom_qty,
|
77
77
|
lambda __: 0,
|
78
78
|
in_lot=True,
|
79
79
|
)
|
@@ -57,11 +57,7 @@ class ClusterPickingIsZeroCase(ClusterPickingCommonCase):
|
|
57
57
|
data=self._line_data(self.next_line),
|
58
58
|
message={
|
59
59
|
"message_type": "success",
|
60
|
-
"body": "{} {} put in {}"
|
61
|
-
self.line.qty_done,
|
62
|
-
self.line.product_id.display_name,
|
63
|
-
self.bin1.name,
|
64
|
-
),
|
60
|
+
"body": f"{self.line.qty_done} {self.line.product_id.display_name} put in {self.bin1.name}", # noqa
|
65
61
|
},
|
66
62
|
)
|
67
63
|
|
@@ -89,10 +85,6 @@ class ClusterPickingIsZeroCase(ClusterPickingCommonCase):
|
|
89
85
|
data=self._line_data(self.next_line),
|
90
86
|
message={
|
91
87
|
"message_type": "success",
|
92
|
-
"body": "{} {} put in {}"
|
93
|
-
self.line.qty_done,
|
94
|
-
self.line.product_id.display_name,
|
95
|
-
self.bin1.name,
|
96
|
-
),
|
88
|
+
"body": f"{self.line.qty_done} {self.line.product_id.display_name} put in {self.bin1.name}", # noqa
|
97
89
|
},
|
98
90
|
)
|
@@ -64,9 +64,7 @@ class ClusterPickingScanDestinationPackCase(ClusterPickingCommonCase):
|
|
64
64
|
data=self._line_data(next_line),
|
65
65
|
message={
|
66
66
|
"message_type": "success",
|
67
|
-
"body": "{} {} put in {}"
|
68
|
-
line.qty_done, line.product_id.display_name, self.bin1.name
|
69
|
-
),
|
67
|
+
"body": f"{line.qty_done} {line.product_id.display_name} put in {self.bin1.name}", # noqa
|
70
68
|
},
|
71
69
|
)
|
72
70
|
|
@@ -149,8 +147,8 @@ class ClusterPickingScanDestinationPackCase(ClusterPickingCommonCase):
|
|
149
147
|
data=self._line_data(line, qty_done=10.0),
|
150
148
|
message={
|
151
149
|
"message_type": "error",
|
152
|
-
"body": "The destination bin {} is not empty,"
|
153
|
-
"
|
150
|
+
"body": f"The destination bin {self.bin1.name} is not empty, "
|
151
|
+
"please take another.",
|
154
152
|
},
|
155
153
|
)
|
156
154
|
|
@@ -233,9 +231,7 @@ class ClusterPickingScanDestinationPackCase(ClusterPickingCommonCase):
|
|
233
231
|
data=self._line_data(line, qty_done=11.0),
|
234
232
|
message={
|
235
233
|
"message_type": "error",
|
236
|
-
"body": "You must not pick more than {} units."
|
237
|
-
line.reserved_uom_qty
|
238
|
-
),
|
234
|
+
"body": f"You must not pick more than {line.reserved_uom_qty} units.",
|
239
235
|
},
|
240
236
|
)
|
241
237
|
|
@@ -271,9 +267,7 @@ class ClusterPickingScanDestinationPackCase(ClusterPickingCommonCase):
|
|
271
267
|
data=self._line_data(new_line),
|
272
268
|
message={
|
273
269
|
"message_type": "success",
|
274
|
-
"body": "{} {} put in {}"
|
275
|
-
line.qty_done, line.product_id.display_name, self.bin1.name
|
276
|
-
),
|
270
|
+
"body": f"{line.qty_done} {line.product_id.display_name} put in {self.bin1.name}", # noqa
|
277
271
|
},
|
278
272
|
)
|
279
273
|
|
@@ -369,8 +363,6 @@ class ClusterPickingScanDestinationPackCase(ClusterPickingCommonCase):
|
|
369
363
|
data=self._line_data(next_line),
|
370
364
|
message={
|
371
365
|
"message_type": "success",
|
372
|
-
"body": "{} {} put in {}"
|
373
|
-
line.qty_done, line.product_id.display_name, self.bin1.name
|
374
|
-
),
|
366
|
+
"body": f"{line.qty_done} {line.product_id.display_name} put in {self.bin1.name}", # noqa
|
375
367
|
},
|
376
368
|
)
|
@@ -103,8 +103,7 @@ class ClusterPickingScanLineLocationOrPackFirstCase(ClusterPickingLineCommonCase
|
|
103
103
|
"""Check scanning a location then a product without package.
|
104
104
|
|
105
105
|
When there is multiple product in the location and the location is scanned,
|
106
|
-
|
107
|
-
|
106
|
+
User needs to scan the product but the system does not remember the location.
|
108
107
|
"""
|
109
108
|
self._simulate_batch_selected(self.batch, in_package=False, in_lot=False)
|
110
109
|
line = self.batch.picking_ids.move_line_ids
|
@@ -125,7 +125,7 @@ class ClusterPickingStockIssue(ClusterPickingCommonCase):
|
|
125
125
|
+ self.move2.product_uom_qty
|
126
126
|
+ sum(
|
127
127
|
self.batch_other.picking_ids.move_line_ids.filtered(
|
128
|
-
lambda
|
128
|
+
lambda x: x.location_id == self.shelf2
|
129
129
|
).mapped("reserved_uom_qty")
|
130
130
|
)
|
131
131
|
)
|
@@ -162,10 +162,10 @@ class ClusterPickingStockIssue(ClusterPickingCommonCase):
|
|
162
162
|
self.assertEqual(self.move5.move_line_ids.location_id, self.shelf2)
|
163
163
|
|
164
164
|
line_shelf1 = self.move3.move_line_ids.filtered(
|
165
|
-
lambda
|
165
|
+
lambda x: x.location_id == self.shelf1
|
166
166
|
)
|
167
167
|
line_shelf2 = self.move3.move_line_ids.filtered(
|
168
|
-
lambda
|
168
|
+
lambda x: x.location_id == self.shelf2
|
169
169
|
)
|
170
170
|
|
171
171
|
# pick the first 2 moves
|
@@ -430,7 +430,7 @@ class ClusterPickingSetDestinationAllCase(ClusterPickingUnloadingCommonCase):
|
|
430
430
|
)
|
431
431
|
|
432
432
|
def test_set_destination_all_check_confirmation(self):
|
433
|
-
"""Endpoint called confirming with a different location, ask confirmation
|
433
|
+
"""Endpoint called confirming with a different location, ask confirmation"""
|
434
434
|
move_lines = self.move_lines
|
435
435
|
self._set_dest_package_and_done(move_lines, self.bin1)
|
436
436
|
move_lines.write({"location_dest_id": self.packing_a_location.id})
|
@@ -933,8 +933,8 @@ class ClusterPickingUnloadScanDestinationCase(ClusterPickingUnloadingCommonCase)
|
|
933
933
|
response,
|
934
934
|
next_state="unload_single",
|
935
935
|
popup={
|
936
|
-
"body": "Last operation of transfer {}. Next operation "
|
937
|
-
"({}) is ready to proceed."
|
936
|
+
"body": f"Last operation of transfer {picking.name}. Next operation "
|
937
|
+
f"({next_picking.name}) is ready to proceed."
|
938
938
|
},
|
939
939
|
data=data,
|
940
940
|
)
|
@@ -680,7 +680,7 @@ class DeliveryScanDeliverSpecialCase(DeliveryCommonCase):
|
|
680
680
|
response,
|
681
681
|
message={
|
682
682
|
"message_type": "error",
|
683
|
-
"body": "Transfer {} is not available."
|
683
|
+
"body": f"Transfer {picking.name} is not available.",
|
684
684
|
},
|
685
685
|
)
|
686
686
|
|
@@ -123,11 +123,14 @@ class TestLocationContentTransferGetWork(LocationContentTransferCommonCase):
|
|
123
123
|
|
124
124
|
def test_find_work_custom_sort_key(self):
|
125
125
|
# fmt: off
|
126
|
+
custom_code = (
|
127
|
+
f"key = ("
|
128
|
+
f"-1 if line.location_id.id == {self.content_loc.id} else 10, )"
|
129
|
+
)
|
126
130
|
self.menu.sudo().write(
|
127
131
|
{
|
128
132
|
"move_line_search_sort_order": "custom_code",
|
129
|
-
"move_line_search_sort_order_custom_code":
|
130
|
-
f"key = (-1 if line.location_id.id == {self.content_loc.id} else 10, )",
|
133
|
+
"move_line_search_sort_order_custom_code": custom_code,
|
131
134
|
}
|
132
135
|
)
|
133
136
|
# fmt: on
|
@@ -220,7 +220,7 @@ class LocationContentTransferMixCase(LocationContentTransferCommonCase):
|
|
220
220
|
# done, the operator is currently moving the goods to the destination location)
|
221
221
|
pack_move_line1 = pick_move_line1.move_id.move_dest_ids.filtered(
|
222
222
|
lambda m: m.state not in ("cancel", "done")
|
223
|
-
).move_line_ids.filtered(lambda
|
223
|
+
).move_line_ids.filtered(lambda x: not x.shopfloor_user_id)
|
224
224
|
self._location_content_transfer_process_line(pack_move_line1)
|
225
225
|
# Operator-1 process the second pallet with the "zone picking" scenario
|
226
226
|
self._zone_picking_process_line(pick_move_line2)
|
@@ -228,11 +228,12 @@ class LocationContentTransferMixCase(LocationContentTransferCommonCase):
|
|
228
228
|
# the location where this second pallet is
|
229
229
|
pack_move_line2 = pick_move_line2.move_id.move_dest_ids.filtered(
|
230
230
|
lambda m: m.state not in ("cancel", "done")
|
231
|
-
).move_line_ids.filtered(lambda
|
232
|
-
|
233
|
-
len(pack_move_line2)
|
234
|
-
|
235
|
-
|
231
|
+
).move_line_ids.filtered(lambda x: not x.shopfloor_user_id)
|
232
|
+
self.assertEqual(
|
233
|
+
len(pack_move_line2),
|
234
|
+
1,
|
235
|
+
f"Operator-3 should find only "
|
236
|
+
f"one move line in {pack_move_line2.location_id.name}",
|
236
237
|
)
|
237
238
|
self._location_content_transfer_process_line(pack_move_line2)
|
238
239
|
|
@@ -302,12 +303,12 @@ class LocationContentTransferMixCase(LocationContentTransferCommonCase):
|
|
302
303
|
)
|
303
304
|
self.assertEqual(pack_move_a, self.pack_move_a)
|
304
305
|
pack_first_pallet = pack_move_a.move_line_ids.filtered(
|
305
|
-
lambda
|
306
|
+
lambda x: not x.shopfloor_user_id and x.location_id == dest_location1
|
306
307
|
)
|
307
308
|
self.assertEqual(pack_first_pallet.reserved_uom_qty, 6)
|
308
309
|
self.assertEqual(pack_first_pallet.qty_done, 0)
|
309
310
|
pack_second_pallet = pack_move_a.move_line_ids.filtered(
|
310
|
-
lambda
|
311
|
+
lambda x: not x.shopfloor_user_id and x.location_id == dest_location2
|
311
312
|
)
|
312
313
|
self.assertEqual(pack_second_pallet.reserved_uom_qty, 4)
|
313
314
|
self.assertEqual(pack_second_pallet.qty_done, 0)
|
@@ -367,7 +368,7 @@ class LocationContentTransferMixCase(LocationContentTransferCommonCase):
|
|
367
368
|
)
|
368
369
|
self.assertEqual(pack_move_a, self.pack_move_a)
|
369
370
|
pack_second_pallet = pack_move_a.move_line_ids.filtered(
|
370
|
-
lambda
|
371
|
+
lambda x: not x.shopfloor_user_id and x.location_id == dest_location2
|
371
372
|
)
|
372
373
|
picking_before = pack_second_pallet.picking_id
|
373
374
|
move_lines = self.service.search_move_line.search_move_lines(
|
@@ -443,7 +444,7 @@ class LocationContentTransferMixCase(LocationContentTransferCommonCase):
|
|
443
444
|
)
|
444
445
|
self.assertEqual(pack_move_a1, self.pack_move_a)
|
445
446
|
pack_first_pallet = pack_move_a1.move_line_ids.filtered(
|
446
|
-
lambda
|
447
|
+
lambda x: not x.shopfloor_user_id and x.location_id == dest_location1
|
447
448
|
)
|
448
449
|
self.assertEqual(pack_first_pallet.reserved_uom_qty, 6)
|
449
450
|
self.assertEqual(pack_first_pallet.qty_done, 0)
|
@@ -469,7 +470,7 @@ class LocationContentTransferMixCase(LocationContentTransferCommonCase):
|
|
469
470
|
lambda m: m.move_line_ids.package_id == self.package_2
|
470
471
|
)
|
471
472
|
pack_second_pallet = pack_move_a2.move_line_ids.filtered(
|
472
|
-
lambda
|
473
|
+
lambda x: not x.shopfloor_user_id and x.location_id == dest_location2
|
473
474
|
)
|
474
475
|
self.assertEqual(pack_second_pallet.reserved_uom_qty, 4)
|
475
476
|
self.assertEqual(pack_second_pallet.qty_done, 0)
|
@@ -7,7 +7,6 @@ from .test_menu_base import MenuCountersCommonCase
|
|
7
7
|
|
8
8
|
class TestMenuContrains(MenuCountersCommonCase):
|
9
9
|
def test_move_line_search_sort_order_custom_code_invalid(self):
|
10
|
-
|
11
10
|
with self.assertRaises(exceptions.ValidationError):
|
12
11
|
# wrong indentation in python code
|
13
12
|
self.menu1.sudo().write(
|
@@ -154,7 +154,7 @@ class TestSinglePackTransfer(SinglePackTransferCommonBase):
|
|
154
154
|
next_state="start",
|
155
155
|
message={
|
156
156
|
"message_type": "error",
|
157
|
-
"body": "No pending operation for package {
|
157
|
+
"body": f"No pending operation for package {self.pack_a.name}.",
|
158
158
|
},
|
159
159
|
)
|
160
160
|
|
@@ -302,8 +302,7 @@ class TestSinglePackTransfer(SinglePackTransferCommonBase):
|
|
302
302
|
next_state="start",
|
303
303
|
message={
|
304
304
|
"message_type": "error",
|
305
|
-
"body": "Location
|
306
|
-
% (self.shelf2.name,),
|
305
|
+
"body": f"Location {self.shelf2.name} doesn't contain any package.",
|
307
306
|
},
|
308
307
|
)
|
309
308
|
|
@@ -340,8 +339,8 @@ class TestSinglePackTransfer(SinglePackTransferCommonBase):
|
|
340
339
|
next_state="start",
|
341
340
|
message={
|
342
341
|
"message_type": "warning",
|
343
|
-
"body": "Several packages found in
|
344
|
-
|
342
|
+
"body": f"Several packages found in {self.shelf1.name}, "
|
343
|
+
"please scan a package.",
|
345
344
|
},
|
346
345
|
)
|
347
346
|
|
@@ -366,8 +365,9 @@ class TestSinglePackTransfer(SinglePackTransferCommonBase):
|
|
366
365
|
next_state="start",
|
367
366
|
message={
|
368
367
|
"message_type": "error",
|
369
|
-
"body": "You cannot work on a package (
|
370
|
-
|
368
|
+
"body": f"You cannot work on a package ({self.pack_a.name}) "
|
369
|
+
"outside of locations: "
|
370
|
+
f"{self.picking_type.default_location_src_id.name}",
|
371
371
|
},
|
372
372
|
)
|
373
373
|
|
@@ -533,8 +533,8 @@ class TestSinglePackTransfer(SinglePackTransferCommonBase):
|
|
533
533
|
response,
|
534
534
|
next_state="start",
|
535
535
|
popup={
|
536
|
-
"body": "Last operation of transfer {}.
|
537
|
-
"({}) is ready to proceed."
|
536
|
+
"body": f"Last operation of transfer {self.picking.name}. "
|
537
|
+
f"Next operation ({next_picking.name}) is ready to proceed."
|
538
538
|
},
|
539
539
|
message={
|
540
540
|
"message_type": "success",
|
@@ -10,7 +10,7 @@ from odoo.tests.common import TransactionCase
|
|
10
10
|
class TestStockSplit(TransactionCase):
|
11
11
|
@classmethod
|
12
12
|
def setUpClass(cls):
|
13
|
-
super(
|
13
|
+
super().setUpClass()
|
14
14
|
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
15
15
|
cls.warehouse = cls.env.ref("stock.warehouse0")
|
16
16
|
cls.warehouse.delivery_steps = "pick_pack_ship"
|