diff --git a/setup/stock_picking_limit_return_qty/odoo/addons/stock_picking_limit_return_qty b/setup/stock_picking_limit_return_qty/odoo/addons/stock_picking_limit_return_qty new file mode 120000 index 000000000000..082e77405e78 --- /dev/null +++ b/setup/stock_picking_limit_return_qty/odoo/addons/stock_picking_limit_return_qty @@ -0,0 +1 @@ +../../../../stock_picking_limit_return_qty \ No newline at end of file diff --git a/setup/stock_picking_limit_return_qty/setup.py b/setup/stock_picking_limit_return_qty/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/stock_picking_limit_return_qty/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_picking_limit_return_qty/README.rst b/stock_picking_limit_return_qty/README.rst new file mode 100644 index 000000000000..55fe5b209cb0 --- /dev/null +++ b/stock_picking_limit_return_qty/README.rst @@ -0,0 +1,103 @@ +============================== +Stock Picking Return Qty Limit +============================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:24694f02b89b92d57ec7abed32c042f2b655f5d95cac430fa40ef24abc80086c + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |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%2Fstock--logistics--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/stock-logistics-workflow/tree/16.0/stock_picking_limit_return_qty + :alt: OCA/stock-logistics-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/stock-logistics-workflow-16-0/stock-logistics-workflow-16-0-stock_picking_limit_return_qty + :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/stock-logistics-workflow&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Limit the item quantity that can be returned. It makes impossible to +return more items than it was in the original picking. + +If user tries to return more items than it is possible to return +following blocking messages is shown: "You can return only of +" + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +By default Odoo doesn't enforce any limit on item quantity that can be +returned in picking. It means that it is possible to return more items +that there were in the original picking. Eg if you delivered 5 pcs of +"Acoustic Block Screens" in picking you can return 8 pcs of it. This +module implements constraint with allows to return not more than the +original amount of item in the picking. It also takes into account +existing returns for the same picking. Eg if you delivered 5 pcs of +"Acoustic Block Screens" in picking then you can return no more than 5 +pcs of it. If you have already returned 2 pcs in the same picking then +you can return no more than 3 pcs. + +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 +------- + +* Cetmix + +Contributors +------------ + +- `Cetmix `__ + +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-CetmixGitDrone| image:: https://github.com/CetmixGitDrone.png?size=40px + :target: https://github.com/CetmixGitDrone + :alt: CetmixGitDrone + +Current `maintainer `__: + +|maintainer-CetmixGitDrone| + +This module is part of the `OCA/stock-logistics-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_picking_limit_return_qty/__init__.py b/stock_picking_limit_return_qty/__init__.py new file mode 100644 index 000000000000..40272379f721 --- /dev/null +++ b/stock_picking_limit_return_qty/__init__.py @@ -0,0 +1 @@ +from . import wizard diff --git a/stock_picking_limit_return_qty/__manifest__.py b/stock_picking_limit_return_qty/__manifest__.py new file mode 100644 index 000000000000..c012aa050b0b --- /dev/null +++ b/stock_picking_limit_return_qty/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2023 Cetmix OU +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Stock Picking Return Qty Limit", + "summary": """ + Don't allow to return more items as there were in the original picking""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Cetmix,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/stock-logistics-workflow", + "depends": ["stock"], + "maintainers": ["CetmixGitDrone"], + "data": [ + "wizard/stock_picking_return.xml", + ], + "demo": [], +} diff --git a/stock_picking_limit_return_qty/readme/CONTEXT.md b/stock_picking_limit_return_qty/readme/CONTEXT.md new file mode 100644 index 000000000000..4c1b5756c2bf --- /dev/null +++ b/stock_picking_limit_return_qty/readme/CONTEXT.md @@ -0,0 +1,4 @@ +By default Odoo doesn't enforce any limit on item quantity that can be returned in picking. It means that it is possible to return more items that there were in the original picking. +Eg if you delivered 5 pcs of "Acoustic Block Screens" in picking you can return 8 pcs of it. +This module implements constraint with allows to return not more than the original amount of item in the picking. It also takes into account existing returns for the same picking. +Eg if you delivered 5 pcs of "Acoustic Block Screens" in picking then you can return no more than 5 pcs of it. If you have already returned 2 pcs in the same picking then you can return no more than 3 pcs. diff --git a/stock_picking_limit_return_qty/readme/CONTRIBUTORS.md b/stock_picking_limit_return_qty/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..95293dd6761d --- /dev/null +++ b/stock_picking_limit_return_qty/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +* [Cetmix](https://cetmix.com) diff --git a/stock_picking_limit_return_qty/readme/DESCRIPTION.md b/stock_picking_limit_return_qty/readme/DESCRIPTION.md new file mode 100644 index 000000000000..ea75035cee96 --- /dev/null +++ b/stock_picking_limit_return_qty/readme/DESCRIPTION.md @@ -0,0 +1,4 @@ +Limit the item quantity that can be returned. It makes impossible to return more items than it was in the original picking. + +If user tries to return more items than it is possible to return following blocking messages is shown: "You can return only of " + diff --git a/stock_picking_limit_return_qty/static/description/icon.png b/stock_picking_limit_return_qty/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/stock_picking_limit_return_qty/static/description/icon.png differ diff --git a/stock_picking_limit_return_qty/static/description/index.html b/stock_picking_limit_return_qty/static/description/index.html new file mode 100644 index 000000000000..c8d861867408 --- /dev/null +++ b/stock_picking_limit_return_qty/static/description/index.html @@ -0,0 +1,441 @@ + + + + + + +Stock Picking Return Qty Limit + + + +
+

Stock Picking Return Qty Limit

+ + +

Beta License: AGPL-3 OCA/stock-logistics-workflow Translate me on Weblate Try me on Runboat

+

Limit the item quantity that can be returned. It makes impossible to +return more items than it was in the original picking.

+

If user tries to return more items than it is possible to return +following blocking messages is shown: “You can return only of +<product_name>”

+

Table of contents

+ +
+

Use Cases / Context

+

By default Odoo doesn’t enforce any limit on item quantity that can be +returned in picking. It means that it is possible to return more items +that there were in the original picking. Eg if you delivered 5 pcs of +“Acoustic Block Screens” in picking you can return 8 pcs of it. This +module implements constraint with allows to return not more than the +original amount of item in the picking. It also takes into account +existing returns for the same picking. Eg if you delivered 5 pcs of +“Acoustic Block Screens” in picking then you can return no more than 5 +pcs of it. If you have already returned 2 pcs in the same picking then +you can return no more than 3 pcs.

+
+
+

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

+
    +
  • Cetmix
  • +
+
+ +
+

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:

+

CetmixGitDrone

+

This module is part of the OCA/stock-logistics-workflow project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_picking_limit_return_qty/tests/__init__.py b/stock_picking_limit_return_qty/tests/__init__.py new file mode 100644 index 000000000000..50972625c5ea --- /dev/null +++ b/stock_picking_limit_return_qty/tests/__init__.py @@ -0,0 +1 @@ +from . import test_stock_picking_return diff --git a/stock_picking_limit_return_qty/tests/test_stock_picking_return.py b/stock_picking_limit_return_qty/tests/test_stock_picking_return.py new file mode 100644 index 000000000000..eda2020c6820 --- /dev/null +++ b/stock_picking_limit_return_qty/tests/test_stock_picking_return.py @@ -0,0 +1,74 @@ +# Copyright 2023 Cetmix OU +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import ValidationError +from odoo.tests.common import TransactionCase + + +class TestStockReturnPicking(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + + cls.supplier_location = cls.env.ref("stock.stock_location_suppliers") + cls.stock_location = cls.env.ref("stock.stock_location_stock") + cls.picking_type_in = cls.env.ref("stock.picking_type_in") + cls.picking_return = cls.env["stock.return.picking"] + cls.picking_return_line = cls.env["stock.return.picking.line"] + cls.stock_move = cls.env["stock.move"] + cls.product_product = cls.env["product.product"] + + @classmethod + def _create_picking(cls, location, destination_location, picking_type): + return cls.env["stock.picking"].create( + { + "picking_type_id": picking_type.id, + "location_id": location.id, + "location_dest_id": destination_location.id, + } + ) + + def test_00(self): + picking = self._create_picking( + self.supplier_location, self.stock_location, self.picking_type_in + ) + product_a = self.product_product.create( + {"name": "Product A", "type": "product"} + ) + product_b = self.product_product.create( + {"name": "Product B", "type": "product"} + ) + move_1 = self.stock_move.create( + { + "name": product_a.name, + "product_id": product_a.id, + "product_uom_qty": 2, + "picking_id": picking.id, + "location_id": picking.location_id.id, + "location_dest_id": picking.location_dest_id.id, + } + ) + move_2 = self.stock_move.create( + { + "name": product_b.name, + "product_id": product_b.id, + "product_uom_qty": 1, + "picking_id": picking.id, + "location_id": picking.location_id.id, + "location_dest_id": picking.location_dest_id.id, + } + ) + picking.action_confirm() + picking.action_assign() + move_1.quantity_done = 2 + move_2.quantity_done = 1 + picking.button_validate() + return_wizard = self.picking_return.with_context( + active_id=picking.id, active_model="stock.picking" + ).create({}) + return_wizard._onchange_picking_id() + for line in return_wizard.product_return_moves: + self.assertEqual(line.quantity, line.quantity_max) + with self.assertRaises(ValidationError): + line.quantity = line.quantity + 1 diff --git a/stock_picking_limit_return_qty/wizard/__init__.py b/stock_picking_limit_return_qty/wizard/__init__.py new file mode 100644 index 000000000000..ad0b47c23ff7 --- /dev/null +++ b/stock_picking_limit_return_qty/wizard/__init__.py @@ -0,0 +1 @@ +from . import stock_picking_return diff --git a/stock_picking_limit_return_qty/wizard/stock_picking_return.py b/stock_picking_limit_return_qty/wizard/stock_picking_return.py new file mode 100644 index 000000000000..011b15d035a2 --- /dev/null +++ b/stock_picking_limit_return_qty/wizard/stock_picking_return.py @@ -0,0 +1,46 @@ +# Copyright 2023 Cetmix OU +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class ReturnPickingLine(models.TransientModel): + _inherit = "stock.return.picking.line" + + quantity_max = fields.Float( + "Maximum Quantity", + digits="Product Unit of Measure", + help="Maximum quantity that can be returned", + ) + + @api.constrains("quantity") + def _constraints_quantity(self): + for rec in self: + if rec.quantity and rec.quantity_max and rec.quantity > rec.quantity_max: + raise ValidationError( + _( + "You can return only %(max_qty)s of %(product)s", + max_qty=rec.quantity_max, + product=rec.product_id.name, + ) + ) + + +class ReturnPicking(models.TransientModel): + _inherit = "stock.return.picking" + + @api.model + def _prepare_stock_return_picking_line_vals_from_move(self, stock_move): + + res = super( + ReturnPicking, self + )._prepare_stock_return_picking_line_vals_from_move(stock_move) + + # Store maximum quantity that is possible to return + res.update( + { + "quantity_max": res["quantity"], + } + ) + return res diff --git a/stock_picking_limit_return_qty/wizard/stock_picking_return.xml b/stock_picking_limit_return_qty/wizard/stock_picking_return.xml new file mode 100644 index 000000000000..1c5925a5a765 --- /dev/null +++ b/stock_picking_limit_return_qty/wizard/stock_picking_return.xml @@ -0,0 +1,16 @@ + + + + Return lines + stock.return.picking + + + + + + + +