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,119 @@
|
|
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 odoo.addons.component.core import Component
|
4
|
+
|
5
|
+
|
6
|
+
class MoveLineSearch(Component):
|
7
|
+
"""Provide methods to search move line records.
|
8
|
+
|
9
|
+
The methods should be used in Service Components, so a search will always
|
10
|
+
have the same result in all scenarios.
|
11
|
+
"""
|
12
|
+
|
13
|
+
_name = "shopfloor.search.move.line"
|
14
|
+
_inherit = "shopfloor.process.action"
|
15
|
+
_usage = "search_move_line"
|
16
|
+
|
17
|
+
@property
|
18
|
+
def picking_types(self):
|
19
|
+
return getattr(
|
20
|
+
self.work, "picking_types", self.env["stock.picking.type"].browse()
|
21
|
+
)
|
22
|
+
|
23
|
+
def _search_move_lines_by_location_domain(
|
24
|
+
self,
|
25
|
+
locations,
|
26
|
+
picking_type=None,
|
27
|
+
package=None,
|
28
|
+
product=None,
|
29
|
+
lot=None,
|
30
|
+
match_user=False,
|
31
|
+
picking_ready=True,
|
32
|
+
# When True, adds the package in the domain even if the package is False
|
33
|
+
enforce_empty_package=False,
|
34
|
+
):
|
35
|
+
domain = [
|
36
|
+
("location_id", "child_of", locations.ids),
|
37
|
+
("qty_done", "=", 0),
|
38
|
+
("state", "in", ("assigned", "partially_available")),
|
39
|
+
]
|
40
|
+
if picking_type:
|
41
|
+
# auto_join in place for this field
|
42
|
+
domain += [("picking_id.picking_type_id", "=", picking_type.id)]
|
43
|
+
elif self.picking_types:
|
44
|
+
domain += [("picking_id.picking_type_id", "in", self.picking_types.ids)]
|
45
|
+
if package or package is not None and enforce_empty_package:
|
46
|
+
domain += [("package_id", "=", package.id if package else False)]
|
47
|
+
if product:
|
48
|
+
domain += [("product_id", "=", product.id)]
|
49
|
+
if lot:
|
50
|
+
domain += [("lot_id", "=", lot.id)]
|
51
|
+
if match_user:
|
52
|
+
domain += [
|
53
|
+
"|",
|
54
|
+
("shopfloor_user_id", "=", False),
|
55
|
+
("shopfloor_user_id", "=", self.env.uid),
|
56
|
+
]
|
57
|
+
if picking_ready:
|
58
|
+
domain += [("picking_id.state", "=", "assigned")]
|
59
|
+
return domain
|
60
|
+
|
61
|
+
def search_move_lines_by_location(
|
62
|
+
self,
|
63
|
+
locations,
|
64
|
+
picking_type=None,
|
65
|
+
package=None,
|
66
|
+
product=None,
|
67
|
+
lot=None,
|
68
|
+
order="priority",
|
69
|
+
match_user=False,
|
70
|
+
sort_keys_func=None,
|
71
|
+
picking_ready=True,
|
72
|
+
enforce_empty_package=False,
|
73
|
+
):
|
74
|
+
"""Find lines that potentially need work in given locations."""
|
75
|
+
move_lines = self.env["stock.move.line"].search(
|
76
|
+
self._search_move_lines_by_location_domain(
|
77
|
+
locations,
|
78
|
+
picking_type,
|
79
|
+
package,
|
80
|
+
product,
|
81
|
+
lot,
|
82
|
+
match_user=match_user,
|
83
|
+
picking_ready=picking_ready,
|
84
|
+
enforce_empty_package=enforce_empty_package,
|
85
|
+
)
|
86
|
+
)
|
87
|
+
sort_keys_func = sort_keys_func or self._sort_key_move_lines(order)
|
88
|
+
move_lines = move_lines.sorted(sort_keys_func)
|
89
|
+
return move_lines
|
90
|
+
|
91
|
+
@staticmethod
|
92
|
+
def _sort_key_move_lines(order):
|
93
|
+
"""Return a sorting function to order lines."""
|
94
|
+
|
95
|
+
if order == "priority":
|
96
|
+
# make prority negative to keep sorting ascending
|
97
|
+
return lambda line: (
|
98
|
+
-int(line.move_id.priority or "0"),
|
99
|
+
line.move_id.date,
|
100
|
+
line.move_id.id,
|
101
|
+
)
|
102
|
+
elif order == "location":
|
103
|
+
return lambda line: (
|
104
|
+
line.move_id.location_id.shopfloor_picking_sequence or "",
|
105
|
+
line.move_id.location_id.name,
|
106
|
+
line.move_id.date,
|
107
|
+
line.move_id.id,
|
108
|
+
)
|
109
|
+
return lambda line: line
|
110
|
+
|
111
|
+
def counters_for_lines(self, lines):
|
112
|
+
# Not using mapped/filtered to support simple lists and generators
|
113
|
+
priority_lines = [x for x in lines if int(x.picking_id.priority or "0") > 0]
|
114
|
+
return {
|
115
|
+
"lines_count": len(lines),
|
116
|
+
"picking_count": len({x.picking_id.id for x in lines}),
|
117
|
+
"priority_lines_count": len(priority_lines),
|
118
|
+
"priority_picking_count": len({x.picking_id.id for x in priority_lines}),
|
119
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright 2021 Camptocamp SA (http://www.camptocamp.com)
|
2
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
3
|
+
from odoo.addons.component.core import Component
|
4
|
+
|
5
|
+
|
6
|
+
class PackagingAction(Component):
|
7
|
+
"""Provide methods to work with packaging operations."""
|
8
|
+
|
9
|
+
_name = "shopfloor.packaging.action"
|
10
|
+
_inherit = "shopfloor.process.action"
|
11
|
+
_usage = "packaging"
|
12
|
+
|
13
|
+
def packaging_valid_for_carrier(self, packaging, carrier):
|
14
|
+
return self.packaging_type_valid_for_carrier(packaging.package_type_id, carrier)
|
15
|
+
|
16
|
+
def packaging_type_valid_for_carrier(self, packaging_type, carrier):
|
17
|
+
return packaging_type.package_carrier_type in (
|
18
|
+
"none",
|
19
|
+
carrier.delivery_type,
|
20
|
+
)
|
21
|
+
|
22
|
+
def create_delivery_package(self, carrier):
|
23
|
+
default_packaging = self._get_default_packaging(carrier)
|
24
|
+
return self.create_package_from_packaging(default_packaging)
|
25
|
+
|
26
|
+
def _get_default_packaging(self, carrier):
|
27
|
+
# TODO: refactor `delivery_[carrier_name]` modules
|
28
|
+
# to have always the same field named `default_packaging_id`
|
29
|
+
# to unify lookup of this field.
|
30
|
+
# As alternative add a computed field.
|
31
|
+
# AFAIS there's no reason to have 1 field per carrier type.
|
32
|
+
fname = carrier.delivery_type + "_default_packaging_id"
|
33
|
+
if fname not in carrier._fields:
|
34
|
+
return self.env["stock.package.type"].browse()
|
35
|
+
return carrier[fname]
|
36
|
+
|
37
|
+
def create_package_from_packaging(self, packaging=None):
|
38
|
+
if packaging:
|
39
|
+
vals = self._package_vals_from_packaging(packaging)
|
40
|
+
else:
|
41
|
+
vals = self._package_vals_without_packaging()
|
42
|
+
return self.env["stock.quant.package"].create(vals)
|
43
|
+
|
44
|
+
def _package_vals_from_packaging(self, packaging):
|
45
|
+
return {
|
46
|
+
"package_type_id": packaging.id,
|
47
|
+
"pack_length": packaging.packaging_length,
|
48
|
+
"width": packaging.width,
|
49
|
+
"height": packaging.height,
|
50
|
+
}
|
51
|
+
|
52
|
+
def _package_vals_without_packaging(self):
|
53
|
+
return {}
|
54
|
+
|
55
|
+
def package_has_several_products(self, package):
|
56
|
+
return len(package.quant_ids.product_id) > 1
|
57
|
+
|
58
|
+
def package_has_several_lots(self, package):
|
59
|
+
return len(package.quant_ids.lot_id) > 1
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright 2020 Camptocamp SA (http://www.camptocamp.com)
|
2
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
3
|
+
import uuid
|
4
|
+
|
5
|
+
from psycopg2 import sql
|
6
|
+
|
7
|
+
from odoo.addons.component.core import Component
|
8
|
+
|
9
|
+
|
10
|
+
class SavepointBuilder(Component):
|
11
|
+
"""Return a new Savepoint instance"""
|
12
|
+
|
13
|
+
_name = "shopfloor.savepoint.action"
|
14
|
+
_inherit = "shopfloor.process.action"
|
15
|
+
_usage = "savepoint"
|
16
|
+
|
17
|
+
def new(self):
|
18
|
+
return Savepoint(self.env.cr)
|
19
|
+
|
20
|
+
|
21
|
+
class Savepoint(object):
|
22
|
+
"""Wrapper for SQL Savepoint
|
23
|
+
|
24
|
+
Close to "cr.savepoint()" context manager but this class gives more control
|
25
|
+
over when the release/rollback are called.
|
26
|
+
"""
|
27
|
+
|
28
|
+
def __init__(self, cr):
|
29
|
+
self._cr = cr
|
30
|
+
self.name = uuid.uuid1().hex
|
31
|
+
self._cr.flush()
|
32
|
+
self._execute("SAVEPOINT {}")
|
33
|
+
|
34
|
+
def rollback(self):
|
35
|
+
self._cr.clear()
|
36
|
+
self._execute("ROLLBACK TO SAVEPOINT {}")
|
37
|
+
|
38
|
+
def release(self):
|
39
|
+
self._cr.flush()
|
40
|
+
self._execute("RELEASE SAVEPOINT {}")
|
41
|
+
|
42
|
+
def _execute(self, query):
|
43
|
+
# pylint: disable=sql-injection
|
44
|
+
self._cr.execute(sql.SQL(query).format(sql.Identifier(self.name)))
|
@@ -0,0 +1,182 @@
|
|
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 odoo.addons.component.core import Component
|
4
|
+
|
5
|
+
|
6
|
+
class ShopfloorSchemaAction(Component):
|
7
|
+
|
8
|
+
_inherit = "shopfloor.schema.action"
|
9
|
+
|
10
|
+
def picking(self):
|
11
|
+
return {
|
12
|
+
"id": {"required": True, "type": "integer"},
|
13
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
14
|
+
"origin": {"type": "string", "nullable": True, "required": False},
|
15
|
+
"note": {"type": "string", "nullable": True, "required": False},
|
16
|
+
"move_line_count": {"type": "integer", "nullable": True, "required": True},
|
17
|
+
"package_level_count": {
|
18
|
+
"type": "integer",
|
19
|
+
"nullable": True,
|
20
|
+
"required": True,
|
21
|
+
},
|
22
|
+
"bulk_line_count": {"type": "integer", "nullable": True, "required": True},
|
23
|
+
"weight": {"required": True, "nullable": True, "type": "float"},
|
24
|
+
"partner": self._schema_dict_of(self._simple_record()),
|
25
|
+
"carrier": self._schema_dict_of(self._simple_record(), required=False),
|
26
|
+
"ship_carrier": self._schema_dict_of(self._simple_record(), required=False),
|
27
|
+
"scheduled_date": {"type": "string", "nullable": False, "required": True},
|
28
|
+
"progress": {"type": "float", "nullable": True},
|
29
|
+
}
|
30
|
+
|
31
|
+
def move_line(self, with_packaging=False, with_picking=False):
|
32
|
+
schema = {
|
33
|
+
"id": {"type": "integer", "required": True},
|
34
|
+
"qty_done": {"type": "float", "required": True},
|
35
|
+
"quantity": {"type": "float", "required": True},
|
36
|
+
"product": self._schema_dict_of(self.product()),
|
37
|
+
"lot": {
|
38
|
+
"type": "dict",
|
39
|
+
"required": False,
|
40
|
+
"nullable": True,
|
41
|
+
"schema": self.lot(),
|
42
|
+
},
|
43
|
+
"package_src": self._schema_dict_of(
|
44
|
+
self.package(with_packaging=with_packaging)
|
45
|
+
),
|
46
|
+
"package_dest": self._schema_dict_of(
|
47
|
+
self.package(with_packaging=with_packaging), required=False
|
48
|
+
),
|
49
|
+
"location_src": self._schema_dict_of(self.location()),
|
50
|
+
"location_dest": self._schema_dict_of(self.location()),
|
51
|
+
"priority": {"type": "string", "nullable": True, "required": False},
|
52
|
+
"progress": {"type": "float", "nullable": True},
|
53
|
+
}
|
54
|
+
if with_picking:
|
55
|
+
schema["picking"] = self._schema_dict_of(self.picking())
|
56
|
+
return schema
|
57
|
+
|
58
|
+
def move(self):
|
59
|
+
return {
|
60
|
+
"id": {"required": True, "type": "integer"},
|
61
|
+
"priority": {"type": "string", "required": False, "nullable": True},
|
62
|
+
"quantity_done": {"type": "float", "required": True},
|
63
|
+
"quantity": {"type": "float", "required": True},
|
64
|
+
"product": self._schema_dict_of(self.product()),
|
65
|
+
"location_src": self._schema_dict_of(self.location()),
|
66
|
+
"location_dest": self._schema_dict_of(self.location()),
|
67
|
+
"progress": {"type": "float", "nullable": True},
|
68
|
+
}
|
69
|
+
|
70
|
+
def product(self):
|
71
|
+
return {
|
72
|
+
"id": {"required": True, "type": "integer"},
|
73
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
74
|
+
"display_name": {"type": "string", "nullable": False, "required": True},
|
75
|
+
"default_code": {"type": "string", "nullable": True, "required": True},
|
76
|
+
"barcode": {"type": "string", "nullable": True, "required": False},
|
77
|
+
"supplier_code": {"type": "string", "nullable": True, "required": False},
|
78
|
+
"packaging": self._schema_list_of(self.packaging()),
|
79
|
+
"uom": self._schema_dict_of(
|
80
|
+
self._simple_record(
|
81
|
+
factor={"required": True, "nullable": True, "type": "float"},
|
82
|
+
rounding={"required": True, "nullable": True, "type": "float"},
|
83
|
+
)
|
84
|
+
),
|
85
|
+
}
|
86
|
+
|
87
|
+
def package(self, with_packaging=False):
|
88
|
+
schema = {
|
89
|
+
"id": {"required": True, "type": "integer"},
|
90
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
91
|
+
"weight": {"required": True, "nullable": True, "type": "float"},
|
92
|
+
"move_line_count": {"required": False, "nullable": True, "type": "integer"},
|
93
|
+
"storage_type": self._schema_dict_of(self._simple_record()),
|
94
|
+
}
|
95
|
+
if with_packaging:
|
96
|
+
schema["packaging"] = self._schema_dict_of(self.packaging())
|
97
|
+
return schema
|
98
|
+
|
99
|
+
def lot(self):
|
100
|
+
return {
|
101
|
+
"id": {"required": True, "type": "integer"},
|
102
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
103
|
+
"ref": {"type": "string", "nullable": True, "required": False},
|
104
|
+
"expiration_date": {"type": "string", "nullable": True, "required": False},
|
105
|
+
}
|
106
|
+
|
107
|
+
def location(self):
|
108
|
+
return {
|
109
|
+
"id": {"required": True, "type": "integer"},
|
110
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
111
|
+
"barcode": {"type": "string", "nullable": True, "required": False},
|
112
|
+
"operation_progress": {
|
113
|
+
"type": "dict",
|
114
|
+
"required": False,
|
115
|
+
"schema": {
|
116
|
+
"done": {"type": "float", "required": False},
|
117
|
+
"to_do": {"type": "float", "required": False},
|
118
|
+
},
|
119
|
+
},
|
120
|
+
}
|
121
|
+
|
122
|
+
def packaging(self):
|
123
|
+
return {
|
124
|
+
"id": {"required": True, "type": "integer"},
|
125
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
126
|
+
"code": {"type": "string", "nullable": True, "required": True},
|
127
|
+
"qty": {"type": "float", "required": True},
|
128
|
+
}
|
129
|
+
|
130
|
+
def delivery_packaging(self):
|
131
|
+
return {
|
132
|
+
"id": {"required": True, "type": "integer"},
|
133
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
134
|
+
"packaging_type": {"type": "string", "nullable": True, "required": True},
|
135
|
+
"barcode": {"type": "string", "nullable": True, "required": True},
|
136
|
+
}
|
137
|
+
|
138
|
+
def picking_batch(self, with_pickings=False):
|
139
|
+
schema = {
|
140
|
+
"id": {"required": True, "type": "integer"},
|
141
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
142
|
+
"picking_count": {"required": True, "type": "integer"},
|
143
|
+
"move_line_count": {"required": True, "type": "integer"},
|
144
|
+
"weight": {"required": True, "nullable": True, "type": "float"},
|
145
|
+
}
|
146
|
+
if with_pickings:
|
147
|
+
schema["pickings"] = self._schema_list_of(self.picking())
|
148
|
+
return schema
|
149
|
+
|
150
|
+
def package_level(self):
|
151
|
+
return {
|
152
|
+
"id": {"required": True, "type": "integer"},
|
153
|
+
"is_done": {"type": "boolean", "nullable": False, "required": True},
|
154
|
+
"picking": self._schema_dict_of(self._simple_record()),
|
155
|
+
"package_src": self._schema_dict_of(self.package()),
|
156
|
+
"location_src": self._schema_dict_of(self.location()),
|
157
|
+
"location_dest": self._schema_dict_of(self.location()),
|
158
|
+
"product": self._schema_dict_of(self.product()),
|
159
|
+
"quantity": {"type": "float", "required": True},
|
160
|
+
}
|
161
|
+
|
162
|
+
def picking_type(self):
|
163
|
+
return {
|
164
|
+
"id": {"required": True, "type": "integer"},
|
165
|
+
"name": {"type": "string", "nullable": False, "required": True},
|
166
|
+
}
|
167
|
+
|
168
|
+
def move_lines_counters(self):
|
169
|
+
return {
|
170
|
+
"lines_count": {"type": "float", "required": False, "nullable": True},
|
171
|
+
"picking_count": {"type": "float", "required": False, "nullable": True},
|
172
|
+
"priority_lines_count": {
|
173
|
+
"type": "float",
|
174
|
+
"required": False,
|
175
|
+
"nullable": True,
|
176
|
+
},
|
177
|
+
"priority_picking_count": {
|
178
|
+
"type": "float",
|
179
|
+
"required": False,
|
180
|
+
"nullable": True,
|
181
|
+
},
|
182
|
+
}
|
@@ -0,0 +1,98 @@
|
|
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 odoo.addons.component.core import Component
|
4
|
+
|
5
|
+
|
6
|
+
class ShopfloorSchemaDetailAction(Component):
|
7
|
+
_inherit = "shopfloor.schema.detail.action"
|
8
|
+
|
9
|
+
def location_detail(self):
|
10
|
+
schema = self.location()
|
11
|
+
schema.update(
|
12
|
+
{
|
13
|
+
"complete_name": {
|
14
|
+
"type": "string",
|
15
|
+
"nullable": False,
|
16
|
+
"required": True,
|
17
|
+
},
|
18
|
+
"reserved_move_lines": self._schema_list_of(self.move_line()),
|
19
|
+
}
|
20
|
+
)
|
21
|
+
return schema
|
22
|
+
|
23
|
+
def picking_detail(self):
|
24
|
+
schema = self.picking()
|
25
|
+
schema.update(
|
26
|
+
{
|
27
|
+
"picking_type_code": {
|
28
|
+
"type": "string",
|
29
|
+
"nullable": True,
|
30
|
+
"required": False,
|
31
|
+
},
|
32
|
+
"priority": {"type": "string", "nullable": True, "required": False},
|
33
|
+
"operation_type": self._schema_dict_of(self._simple_record()),
|
34
|
+
"move_lines": self._schema_list_of(self.move_line()),
|
35
|
+
}
|
36
|
+
)
|
37
|
+
return schema
|
38
|
+
|
39
|
+
def package_detail(self):
|
40
|
+
schema = self.package(with_packaging=True)
|
41
|
+
schema.update(
|
42
|
+
{
|
43
|
+
"pickings": self._schema_list_of(self.picking()),
|
44
|
+
"move_lines": self._schema_list_of(self.move_line()),
|
45
|
+
"location": self._schema_dict_of(self._simple_record()),
|
46
|
+
}
|
47
|
+
)
|
48
|
+
return schema
|
49
|
+
|
50
|
+
def lot_detail(self):
|
51
|
+
schema = self.lot()
|
52
|
+
schema.update(
|
53
|
+
{
|
54
|
+
"removal_date": {"type": "string", "nullable": True, "required": False},
|
55
|
+
"expire_date": {"type": "string", "nullable": True, "required": False},
|
56
|
+
"product": self._schema_dict_of(self.product_detail()),
|
57
|
+
# TODO: packaging
|
58
|
+
}
|
59
|
+
)
|
60
|
+
return schema
|
61
|
+
|
62
|
+
def product(self):
|
63
|
+
schema = super().product()
|
64
|
+
schema.update(
|
65
|
+
{
|
66
|
+
"qty_available": {"type": "float", "required": True},
|
67
|
+
"qty_reserved": {"type": "float", "required": True},
|
68
|
+
}
|
69
|
+
)
|
70
|
+
return schema
|
71
|
+
|
72
|
+
def product_detail(self):
|
73
|
+
schema = self.product()
|
74
|
+
schema.update(
|
75
|
+
{
|
76
|
+
"image": {"type": "string", "nullable": True, "required": False},
|
77
|
+
"manufacturer": self._schema_dict_of(self._simple_record()),
|
78
|
+
"suppliers": self._schema_list_of(self.product_supplierinfo()),
|
79
|
+
}
|
80
|
+
)
|
81
|
+
return schema
|
82
|
+
|
83
|
+
def product_supplierinfo(self):
|
84
|
+
return {
|
85
|
+
"id": {"required": True, "type": "integer"},
|
86
|
+
"partner": {"type": "string", "nullable": True, "required": False},
|
87
|
+
"product_name": {"type": "string", "nullable": True, "required": False},
|
88
|
+
"product_code": {"type": "string", "nullable": True, "required": False},
|
89
|
+
}
|
90
|
+
|
91
|
+
# TODO
|
92
|
+
# def packaging_detail(self):
|
93
|
+
# schema = self.packaging()
|
94
|
+
# schema.update(
|
95
|
+
# {
|
96
|
+
# }
|
97
|
+
# )
|
98
|
+
# return schema
|