diff --git a/purchase_stock_packaging/README.rst b/purchase_stock_packaging/README.rst new file mode 100644 index 00000000000..522a09071c4 --- /dev/null +++ b/purchase_stock_packaging/README.rst @@ -0,0 +1,111 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +======================== +Purchase Stock Packaging +======================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:30344cb837e0523350ba91e7b90cfcdd8a1366b190abaad0fe5a139f3e15967a + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/license-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%2Fpurchase--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/purchase-workflow/tree/19.0/purchase_stock_packaging + :alt: OCA/purchase-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/purchase-workflow-19-0/purchase-workflow-19-0-purchase_stock_packaging + :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/purchase-workflow&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to transmit the product packaging from the +procurement values to the generated purchase order line + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +- For instance, create a sale order with a route that trigger make to + order stock rules (and a purchase order). +- On that sale order, force using a product packaging that would not be + the default one for the filled in qunatity. +- The purchase order line created should use the same product packaging. + +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 +------- + +* ACSONE SA/NV +* ForgeFlow + +Contributors +------------ + +- Lois Rilo Antelo +- Denis Roussel +- `Binhex System Solutions `__: + + - Deriman Alonso + +- `360ERP `__: + + - Kevin Khao + +- `Heliconia Solutions Pvt. Ltd. `__ + + - Bhavesh Heliconia + +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-rousseldenis| image:: https://github.com/rousseldenis.png?size=40px + :target: https://github.com/rousseldenis + :alt: rousseldenis + +Current `maintainer `__: + +|maintainer-rousseldenis| + +This module is part of the `OCA/purchase-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/purchase_stock_packaging/__init__.py b/purchase_stock_packaging/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/purchase_stock_packaging/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/purchase_stock_packaging/__manifest__.py b/purchase_stock_packaging/__manifest__.py new file mode 100644 index 00000000000..d5eb7c4ea0e --- /dev/null +++ b/purchase_stock_packaging/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2022 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Purchase Stock Packaging", + "summary": """ + Allows to transmit the product packaging from the procurement values + to the generated purchase order line""", + "version": "19.0.1.0.0", + "license": "AGPL-3", + "maintainers": ["rousseldenis"], + "author": "ACSONE SA/NV,ForgeFlow,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/purchase-workflow", + "depends": [ + "purchase_stock", + ], +} diff --git a/purchase_stock_packaging/i18n/hr.po b/purchase_stock_packaging/i18n/hr.po new file mode 100644 index 00000000000..0760244e617 --- /dev/null +++ b/purchase_stock_packaging/i18n/hr.po @@ -0,0 +1,23 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_stock_packaging +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-01-04 02:40+0000\n" +"Last-Translator: Bole \n" +"Language-Team: none\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: purchase_stock_packaging +#: model:ir.model,name:purchase_stock_packaging.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Stavka narudžbe" diff --git a/purchase_stock_packaging/i18n/it.po b/purchase_stock_packaging/i18n/it.po new file mode 100644 index 00000000000..505762aa1c7 --- /dev/null +++ b/purchase_stock_packaging/i18n/it.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_stock_packaging +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-12-22 14:36+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: purchase_stock_packaging +#: model:ir.model,name:purchase_stock_packaging.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Riga ordine di acquisto" diff --git a/purchase_stock_packaging/i18n/pt_BR.po b/purchase_stock_packaging/i18n/pt_BR.po new file mode 100644 index 00000000000..00ca431d7b6 --- /dev/null +++ b/purchase_stock_packaging/i18n/pt_BR.po @@ -0,0 +1,20 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_stock_packaging +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#. module: purchase_stock_packaging +#: model:ir.model,name:purchase_stock_packaging.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "" diff --git a/purchase_stock_packaging/i18n/purchase_stock_packaging.pot b/purchase_stock_packaging/i18n/purchase_stock_packaging.pot new file mode 100644 index 00000000000..bc15fbdf49b --- /dev/null +++ b/purchase_stock_packaging/i18n/purchase_stock_packaging.pot @@ -0,0 +1,19 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_stock_packaging +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: purchase_stock_packaging +#: model:ir.model,name:purchase_stock_packaging.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "" diff --git a/purchase_stock_packaging/i18n/sl.po b/purchase_stock_packaging/i18n/sl.po new file mode 100644 index 00000000000..b12be1de6f9 --- /dev/null +++ b/purchase_stock_packaging/i18n/sl.po @@ -0,0 +1,23 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_stock_packaging +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2026-01-10 08:44+0000\n" +"Last-Translator: Matjaz Mozetic \n" +"Language-Team: none\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " +"n%100==4 ? 2 : 3;\n" +"X-Generator: Weblate 5.10.4\n" + +#. module: purchase_stock_packaging +#: model:ir.model,name:purchase_stock_packaging.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Postavka nabavnega naloga" diff --git a/purchase_stock_packaging/models/__init__.py b/purchase_stock_packaging/models/__init__.py new file mode 100644 index 00000000000..fa6c0e40fde --- /dev/null +++ b/purchase_stock_packaging/models/__init__.py @@ -0,0 +1 @@ +from . import purchase_order_line diff --git a/purchase_stock_packaging/models/purchase_order_line.py b/purchase_stock_packaging/models/purchase_order_line.py new file mode 100644 index 00000000000..2f7de0c078c --- /dev/null +++ b/purchase_stock_packaging/models/purchase_order_line.py @@ -0,0 +1,42 @@ +# Copyright 2022 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class PurchaseOrderLine(models.Model): + _inherit = "purchase.order.line" + + @api.model + def _prepare_purchase_order_line_from_procurement( + self, + product_id, + product_qty, + product_uom, + location_dest_id, + name, + origin, + company_id, + values, + po, + ): + # For new PO lines we set the product packaging if present in + # the procurement values. + res = super()._prepare_purchase_order_line_from_procurement( + product_id, + product_qty, + product_uom, + location_dest_id, + name, + origin, + company_id, + values, + po, + ) + packaging_uom = values.get("packaging_uom_id") + if packaging_uom: + res["product_uom_id"] = packaging_uom.id + res["product_qty"] = product_uom._compute_quantity( + product_qty, packaging_uom + ) + return res diff --git a/purchase_stock_packaging/pyproject.toml b/purchase_stock_packaging/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/purchase_stock_packaging/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/purchase_stock_packaging/readme/CONTRIBUTORS.md b/purchase_stock_packaging/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..6a572ccb3ff --- /dev/null +++ b/purchase_stock_packaging/readme/CONTRIBUTORS.md @@ -0,0 +1,8 @@ +- Lois Rilo Antelo \<\> +- Denis Roussel \<\> +- [Binhex System Solutions](https://binhex.cloud/): + - Deriman Alonso \<\> +- [360ERP](https://www.360erp.com): + - Kevin Khao \<\> +- [Heliconia Solutions Pvt. Ltd.](https://www.heliconia.io) + - Bhavesh Heliconia diff --git a/purchase_stock_packaging/readme/DESCRIPTION.md b/purchase_stock_packaging/readme/DESCRIPTION.md new file mode 100644 index 00000000000..8f5299c8ad5 --- /dev/null +++ b/purchase_stock_packaging/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module allows to transmit the product packaging from the +procurement values to the generated purchase order line diff --git a/purchase_stock_packaging/readme/USAGE.md b/purchase_stock_packaging/readme/USAGE.md new file mode 100644 index 00000000000..a0d55767a9f --- /dev/null +++ b/purchase_stock_packaging/readme/USAGE.md @@ -0,0 +1,5 @@ +- For instance, create a sale order with a route that trigger make to + order stock rules (and a purchase order). +- On that sale order, force using a product packaging that would not be + the default one for the filled in qunatity. +- The purchase order line created should use the same product packaging. diff --git a/purchase_stock_packaging/static/description/icon.png b/purchase_stock_packaging/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/purchase_stock_packaging/static/description/icon.png differ diff --git a/purchase_stock_packaging/static/description/index.html b/purchase_stock_packaging/static/description/index.html new file mode 100644 index 00000000000..deb4e0de2f3 --- /dev/null +++ b/purchase_stock_packaging/static/description/index.html @@ -0,0 +1,457 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Purchase Stock Packaging

+ +

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

+

This module allows to transmit the product packaging from the +procurement values to the generated purchase order line

+

Table of contents

+ +
+

Usage

+
    +
  • For instance, create a sale order with a route that trigger make to +order stock rules (and a purchase order).
  • +
  • On that sale order, force using a product packaging that would not be +the default one for the filled in qunatity.
  • +
  • The purchase order line created should use the same product packaging.
  • +
+
+
+

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

+
    +
  • ACSONE SA/NV
  • +
  • ForgeFlow
  • +
+
+
+

Contributors

+ +
+
+

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:

+

rousseldenis

+

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

+

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

+
+
+
+
+ + diff --git a/purchase_stock_packaging/tests/__init__.py b/purchase_stock_packaging/tests/__init__.py new file mode 100644 index 00000000000..4463a320243 --- /dev/null +++ b/purchase_stock_packaging/tests/__init__.py @@ -0,0 +1 @@ +from . import test_purchase_packaging diff --git a/purchase_stock_packaging/tests/test_purchase_packaging.py b/purchase_stock_packaging/tests/test_purchase_packaging.py new file mode 100644 index 00000000000..0f70f23d766 --- /dev/null +++ b/purchase_stock_packaging/tests/test_purchase_packaging.py @@ -0,0 +1,96 @@ +# Copyright 2022 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import Command + +from odoo.addons.base.tests.common import BaseCommon + + +class TestPurchasePackaging(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.line_obj = cls.env["purchase.order.line"] + cls.product = cls.env["product.product"].create( + { + "name": "Test Product", + "type": "consu", + "purchase_ok": True, + "seller_ids": [ + Command.create( + { + "partner_id": cls.partner.id, + "min_qty": 1, + "price": 10.0, + } + ) + ], + } + ) + cls.uom_unit = cls.env.ref("uom.product_uom_unit") + cls.packaging_uom = cls.env["uom.uom"].create( + { + "name": "Box of 6", + "relative_uom_id": cls.uom_unit.id, + "relative_factor": 6.0, + } + ) + cls.warehouse = cls.env["stock.warehouse"].search([], limit=1) + + def test_purchase_packaging_from_procurement(self): + """Test if packaging UoM is passed from procurement to PO line""" + values = { + "warehouse_id": self.warehouse, + "packaging_uom_id": self.packaging_uom, + "route_ids": self.warehouse.reception_route_id, + } + self.env["stock.rule"].run( + [ + self.env["stock.rule"].Procurement( + self.product, + 12.0, + self.uom_unit, + self.warehouse.lot_stock_id, + "Test procurement", + "TEST_PROC", + self.env.company, + values, + ) + ] + ) + po_line = self.line_obj.search( + [ + ("product_id", "=", self.product.id), + ("order_id.origin", "ilike", "TEST_PROC"), + ] + ) + self.assertTrue(po_line, "PO line should have been created") + self.assertEqual(po_line.product_uom_id, self.packaging_uom) + self.assertEqual(po_line.product_qty, 2.0) + + def test_purchase_packaging_from_move(self): + """Test if packaging UoM is passed from stock move to procurement to PO line""" + buy_route = self.env.ref("purchase_stock.route_warehouse0_buy") + self.product.route_ids = [Command.link(buy_route.id)] + move = self.env["stock.move"].create( + { + "origin": "TEST_MOVE_ORIGIN", + "location_dest_id": self.env.ref("stock.stock_location_customers").id, + "location_id": self.warehouse.lot_stock_id.id, + "product_id": self.product.id, + "product_uom_qty": 18.0, + "product_uom": self.uom_unit.id, + "procure_method": "make_to_order", + } + ) + move.packaging_uom_id = self.packaging_uom + move._action_confirm() + po_line = self.line_obj.search( + [ + ("product_id", "=", self.product.id), + ("order_id.origin", "ilike", "TEST_MOVE_ORIGIN"), + ] + ) + + self.assertTrue(po_line, "PO line should have been created from move") + self.assertEqual(po_line.product_uom_id, self.packaging_uom) + self.assertEqual(po_line.product_qty, 3.0) # 18 / 6