diff --git a/setup/shopfloor_checkout_putinpack_restriction/odoo/addons/shopfloor_checkout_putinpack_restriction b/setup/shopfloor_checkout_putinpack_restriction/odoo/addons/shopfloor_checkout_putinpack_restriction new file mode 120000 index 0000000000..fd9a1463c2 --- /dev/null +++ b/setup/shopfloor_checkout_putinpack_restriction/odoo/addons/shopfloor_checkout_putinpack_restriction @@ -0,0 +1 @@ +../../../../shopfloor_checkout_putinpack_restriction \ No newline at end of file diff --git a/setup/shopfloor_checkout_putinpack_restriction/setup.py b/setup/shopfloor_checkout_putinpack_restriction/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/shopfloor_checkout_putinpack_restriction/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopfloor/services/checkout.py b/shopfloor/services/checkout.py index 34297735d6..2432e878a4 100644 --- a/shopfloor/services/checkout.py +++ b/shopfloor/services/checkout.py @@ -94,17 +94,20 @@ def _response_for_manual_selection(self, message=None): data = {"pickings": self.data.pickings(pickings)} return self._response(next_state="manual_selection", data=data, message=message) + def _data_response_for_select_package(self, picking, lines): + return { + "selected_move_lines": self._data_for_move_lines(lines.sorted()), + "picking": self.data.picking(picking), + "packing_info": self._data_for_packing_info(picking), + "no_package_enabled": not self.options.get("checkout__disable_no_package"), + # Used by inheriting module + "package_allowed": True, + } + def _response_for_select_package(self, picking, lines, message=None): return self._response( next_state="select_package", - data={ - "selected_move_lines": self._data_for_move_lines(lines.sorted()), - "picking": self.data.picking(picking), - "packing_info": self._data_for_packing_info(picking), - "no_package_enabled": not self.options.get( - "checkout__disable_no_package" - ), - }, + data=self._data_response_for_select_package(picking, lines), message=message, ) @@ -960,6 +963,13 @@ def scan_package_action(self, picking_id, selected_line_ids, barcode): selected_lines = self.env["stock.move.line"].browse(selected_line_ids).exists() search_result = self._scan_package_find(picking, barcode) + message = self._check_scan_package_find(picking, search_result) + if message: + return self._response_for_select_package( + picking, + selected_lines, + message=message, + ) result_handler = getattr( self, "_scan_package_action_from_" + search_result.type ) @@ -984,6 +994,10 @@ def _scan_package_find(self, picking, barcode, search_types=None): ), ) + def _check_scan_package_find(self, picking, search_result): + # Used by inheriting modules + return False + def _find_line_to_increment(self, product_lines): """Find which line should have its qty incremented. @@ -1679,6 +1693,11 @@ def _states(self): "nullable": True, "required": False, }, + package_allowed={ + "type": "boolean", + "nullable": True, + "required": False, + }, ), "change_quantity": self._schema_selected_lines, "select_dest_package": self._schema_select_package, diff --git a/shopfloor/tests/test_checkout_base.py b/shopfloor/tests/test_checkout_base.py index 85241b317b..6e743b5e42 100644 --- a/shopfloor/tests/test_checkout_base.py +++ b/shopfloor/tests/test_checkout_base.py @@ -69,6 +69,7 @@ def _assert_select_package_qty_above(self, response, picking): "picking": self._picking_summary_data(picking), "packing_info": "", "no_package_enabled": True, + "package_allowed": True, }, message={ "message_type": "warning", diff --git a/shopfloor/tests/test_checkout_list_delivery_packaging.py b/shopfloor/tests/test_checkout_list_delivery_packaging.py index 48fc87c446..8097aca08e 100644 --- a/shopfloor/tests/test_checkout_list_delivery_packaging.py +++ b/shopfloor/tests/test_checkout_list_delivery_packaging.py @@ -115,6 +115,7 @@ def test_list_delivery_packaging_not_available(self): "no_package_enabled": not self.service.options.get( "checkout__disable_no_package" ), + "package_allowed": True, }, message=self.service.msg_store.no_delivery_packaging_available(), ) diff --git a/shopfloor/tests/test_checkout_scan_package_action.py b/shopfloor/tests/test_checkout_scan_package_action.py index 446f50debd..5c1e990ea6 100644 --- a/shopfloor/tests/test_checkout_scan_package_action.py +++ b/shopfloor/tests/test_checkout_scan_package_action.py @@ -176,6 +176,7 @@ def test_scan_package_action_scan_package_keep_source_package_error(self): "no_package_enabled": not self.service.options.get( "checkout__disable_no_package" ), + "package_allowed": True, }, message=self.service.msg_store.dest_package_not_valid(pack1), ) diff --git a/shopfloor/tests/test_checkout_select_package_base.py b/shopfloor/tests/test_checkout_select_package_base.py index 5f4ffe42ce..82e532a9c3 100644 --- a/shopfloor/tests/test_checkout_select_package_base.py +++ b/shopfloor/tests/test_checkout_select_package_base.py @@ -10,6 +10,7 @@ def _assert_selected_response( message=None, packing_info="", no_package_enabled=True, + package_allowed=True, ): picking = selected_lines.mapped("picking_id") self.assert_response( @@ -22,6 +23,7 @@ def _assert_selected_response( "picking": self._picking_summary_data(picking), "packing_info": packing_info, "no_package_enabled": no_package_enabled, + "package_allowed": package_allowed, }, message=message, ) diff --git a/shopfloor_checkout_putinpack_restriction/README.rst b/shopfloor_checkout_putinpack_restriction/README.rst new file mode 100644 index 0000000000..314e781fad --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/README.rst @@ -0,0 +1,97 @@ +========================================== +Shopfloor Checkout Put In Pack Restriction +========================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c41308e3379843fe0566e62fdc74629ab919e92f8206447846a761d238cbbc5b + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/14.0/shopfloor_checkout_putinpack_restriction + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-shopfloor_checkout_putinpack_restriction + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the checkout scenario of the shopfloor module. +And depends on `stock_picking_putinpack_restriction` from +`stock-logistic-workflow`. + +It restricts the display of the put in pack buttons from the +`select_package` state. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp +* BCIM +* Raumschmiede + +Contributors +~~~~~~~~~~~~ + +* Thierry Ducrest +* Joshua Lauer + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-TDu| image:: https://github.com/TDu.png?size=40px + :target: https://github.com/TDu + :alt: TDu + +Current `maintainer `__: + +|maintainer-TDu| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/shopfloor_checkout_putinpack_restriction/__init__.py b/shopfloor_checkout_putinpack_restriction/__init__.py new file mode 100644 index 0000000000..cf850b590c --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/__init__.py @@ -0,0 +1,2 @@ +from . import actions +from . import services diff --git a/shopfloor_checkout_putinpack_restriction/__manifest__.py b/shopfloor_checkout_putinpack_restriction/__manifest__.py new file mode 100644 index 0000000000..e2361b333f --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{ + "name": "Shopfloor Checkout Put In Pack Restriction", + "summary": "", + "version": "14.0.1.0.0", + "development_status": "Alpha", + "category": "Inventory", + "website": "https://github.com/OCA/wms", + "author": "Camptocamp, BCIM, Raumschmiede, Odoo Community Association (OCA)", + "maintainers": ["TDu"], + "license": "AGPL-3", + "depends": [ + # OCA/wms + "shopfloor", + # OCA/stock-logistics-workflow + "stock_picking_putinpack_restriction", + ], + "installable": True, +} diff --git a/shopfloor_checkout_putinpack_restriction/actions/__init__.py b/shopfloor_checkout_putinpack_restriction/actions/__init__.py new file mode 100644 index 0000000000..51a1e70dbd --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/actions/__init__.py @@ -0,0 +1 @@ +from . import message diff --git a/shopfloor_checkout_putinpack_restriction/actions/message.py b/shopfloor_checkout_putinpack_restriction/actions/message.py new file mode 100644 index 0000000000..7e33416d1d --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/actions/message.py @@ -0,0 +1,15 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import _ + +from odoo.addons.component.core import Component + + +class MessageAction(Component): + _inherit = "shopfloor.message.action" + + def package_not_allowed_for_operation(self): + return { + "message_type": "error", + "body": _("The operation does not allow the use of package"), + } diff --git a/shopfloor_checkout_putinpack_restriction/readme/CONTRIBUTORS.rst b/shopfloor_checkout_putinpack_restriction/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..f7528d36a5 --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Thierry Ducrest +* Joshua Lauer diff --git a/shopfloor_checkout_putinpack_restriction/readme/DESCRIPTION.rst b/shopfloor_checkout_putinpack_restriction/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..7b9be188f7 --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/readme/DESCRIPTION.rst @@ -0,0 +1,6 @@ +This module extends the checkout scenario of the shopfloor module. +And depends on `stock_picking_putinpack_restriction` from +`stock-logistic-workflow`. + +It restricts the display of the put in pack buttons from the +`select_package` state. diff --git a/shopfloor_checkout_putinpack_restriction/services/__init__.py b/shopfloor_checkout_putinpack_restriction/services/__init__.py new file mode 100644 index 0000000000..fe83da5688 --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/services/__init__.py @@ -0,0 +1 @@ +from . import checkout diff --git a/shopfloor_checkout_putinpack_restriction/services/checkout.py b/shopfloor_checkout_putinpack_restriction/services/checkout.py new file mode 100644 index 0000000000..e1241f55d1 --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/services/checkout.py @@ -0,0 +1,23 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + + +from odoo.addons.component.core import Component + + +class Checkout(Component): + _inherit = "shopfloor.checkout" + + def _data_response_for_select_package(self, picking, lines, message=None): + res = super()._data_response_for_select_package(picking, lines) + if picking.put_in_pack_restriction == "no_package": + res["package_allowed"] = False + elif picking.put_in_pack_restriction == "with_package": + res["no_package_enabled"] = False + return res + + def _check_scan_package_find(self, picking, search_result): + if search_result.type in ["package", "delivery_packaging"]: + if picking.put_in_pack_restriction == "no_package": + return self.msg_store.package_not_allowed_for_operation() + return super()._check_scan_package_find(picking, search_result) diff --git a/shopfloor_checkout_putinpack_restriction/static/description/index.html b/shopfloor_checkout_putinpack_restriction/static/description/index.html new file mode 100644 index 0000000000..b1d9deb63a --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/static/description/index.html @@ -0,0 +1,436 @@ + + + + + + +Shopfloor Checkout Put In Pack Restriction + + + +
+

Shopfloor Checkout Put In Pack Restriction

+ + +

Alpha License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

+

This module extends the checkout scenario of the shopfloor module. +And depends on stock_picking_putinpack_restriction from +stock-logistic-workflow.

+

It restricts the display of the put in pack buttons from the +select_package state.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
  • BCIM
  • +
  • Raumschmiede
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

TDu

+

This module is part of the OCA/wms project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/shopfloor_checkout_putinpack_restriction/tests/__init__.py b/shopfloor_checkout_putinpack_restriction/tests/__init__.py new file mode 100644 index 0000000000..c0d0c0fccb --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/tests/__init__.py @@ -0,0 +1 @@ +from . import test_checkout_putinpack_restriction diff --git a/shopfloor_checkout_putinpack_restriction/tests/test_checkout_putinpack_restriction.py b/shopfloor_checkout_putinpack_restriction/tests/test_checkout_putinpack_restriction.py new file mode 100644 index 0000000000..c6443bd5d6 --- /dev/null +++ b/shopfloor_checkout_putinpack_restriction/tests/test_checkout_putinpack_restriction.py @@ -0,0 +1,82 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.addons.shopfloor.tests.test_checkout_base import CheckoutCommonCase +from odoo.addons.shopfloor.tests.test_checkout_select_package_base import ( + CheckoutSelectPackageMixin, +) + + +class CheckoutPutInPackRestriction(CheckoutCommonCase, CheckoutSelectPackageMixin): + @classmethod + def setUpClassBaseData(cls): + super().setUpClassBaseData() + cls.carrier = cls.env.ref("delivery.normal_delivery_carrier") + cls.picking = cls._create_picking( + lines=[ + (cls.product_a, 10), + ] + ) + cls.pack1_moves = cls.picking.move_lines[:3] + cls._fill_stock_for_moves(cls.pack1_moves, in_package=True) + cls.picking.action_assign() + + def test_select_line_putinpack_restriction_no_package(self): + """Check info for put in pack restriction is passed to select_package state.""" + self.picking.sudo().picking_type_id.put_in_pack_restriction = "no_package" + selected_lines = self.picking.move_line_ids + pack = self.picking.move_line_ids.package_id + response = self.service.dispatch( + "select_line", + params={ + "picking_id": self.picking.id, + "package_id": pack.id, + }, + ) + self._assert_selected( + response, + selected_lines, + no_package_enabled=True, + package_allowed=False, + ) + + def test_select_line_putinpack_restriction_with_package(self): + """Check info for put in pack restriction is passed to select_package state.""" + self.picking.sudo().picking_type_id.put_in_pack_restriction = "with_package" + selected_lines = self.picking.move_line_ids + pack = self.picking.move_line_ids.package_id + response = self.service.dispatch( + "select_line", + params={ + "picking_id": self.picking.id, + "package_id": pack.id, + }, + ) + self._assert_selected( + response, + selected_lines, + no_package_enabled=False, + package_allowed=True, + ) + + def test_scan_package_action_restriction_no_package(self): + """Check scanning a package with a no package restriction.""" + self.picking.sudo().picking_type_id.put_in_pack_restriction = "no_package" + move = self.picking.move_lines + selected_line = move.move_line_ids + other_package = self.env["stock.quant.package"].create({}) + response = self.service.dispatch( + "scan_package_action", + params={ + "picking_id": self.picking.id, + "selected_line_ids": selected_line.ids, + "barcode": other_package.name, + }, + ) + data = self.service._data_response_for_select_package( + self.picking, selected_line + ) + message = self.service.msg_store.package_not_allowed_for_operation() + self.assert_response( + response, next_state="select_package", message=message, data=data + ) diff --git a/shopfloor_mobile/static/wms/src/scenario/checkout.js b/shopfloor_mobile/static/wms/src/scenario/checkout.js index 479ee3c52b..fe463fa21e 100644 --- a/shopfloor_mobile/static/wms/src/scenario/checkout.js +++ b/shopfloor_mobile/static/wms/src/scenario/checkout.js @@ -92,7 +92,7 @@ const Checkout = { :key="make_state_component_key(['detail-picking-select'])" />
- + Existing pack - +