diff --git a/product_supplierinfo_purchase_contact/README.rst b/product_supplierinfo_purchase_contact/README.rst new file mode 100644 index 00000000000..45c0ecdea00 --- /dev/null +++ b/product_supplierinfo_purchase_contact/README.rst @@ -0,0 +1,119 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================================= +Product Supplier Purchase Contact +================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:4e40ad1a5516889c80e7723b017b02fb0e2f0cb7b4ec51d6f0f897ac01ff093f + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/product_supplierinfo_purchase_contact + :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-product_supplierinfo_purchase_contact + :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 adds Purchase contact field on supplier rates +(product.supplierinfo) and allows you to use this contact when creating +the purchase order from supplies (replacement or to order). + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +This module had 2 purposes: + +- To specify which contact the purchase orders generated from + procurements associated to this supplierinfo have to be put. +- That the auto-created supplierinfo from the purchase order has the + main partner associated, not the specific contact one. + +The 'Purchase contact' (purchase_partner_id) field is required if for +example you use sales pricelist based on supplierinfo +(product_pricelist_supplierinfo), you want to use as supplier filter the +'Supplier' (partner_id) field. + +Usage +===== + +- Go to Purchase > Configuration > Vendor pricelist and create new + Vendor pricelist and complete Purchase contact. +- Go to Inventory > Operations > Replenishment and create a new + replenishment for product with Vendor pricelist created before. +- Press button "Order once" and will create a new purchase order for + Purchase contact instead of Vendor from Vendor Pricelist. + +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 +------- + +* Tecnativa + +Contributors +------------ + +- `Tecnativa `__: + + - Carolina Fernandez + - Pedro M. Baeza + - Víctor Martínez + +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-victoralmau| image:: https://github.com/victoralmau.png?size=40px + :target: https://github.com/victoralmau + :alt: victoralmau + +Current `maintainer `__: + +|maintainer-victoralmau| + +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/product_supplierinfo_purchase_contact/__init__.py b/product_supplierinfo_purchase_contact/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/product_supplierinfo_purchase_contact/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_supplierinfo_purchase_contact/__manifest__.py b/product_supplierinfo_purchase_contact/__manifest__.py new file mode 100644 index 00000000000..b4eda7e0e91 --- /dev/null +++ b/product_supplierinfo_purchase_contact/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2024 Tecnativa - Carolina Fernandez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "Product Supplier Purchase Contact", + "version": "19.0.1.0.0", + "category": "Purchase Management", + "author": "Tecnativa,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/purchase-workflow", + "license": "AGPL-3", + "summary": "Add Purchase Contact in product supplier info", + "depends": ["purchase_stock"], + "data": [ + "views/product_supplierinfo_view.xml", + ], + "installable": True, + "maintainers": ["victoralmau"], +} diff --git a/product_supplierinfo_purchase_contact/i18n/es.po b/product_supplierinfo_purchase_contact/i18n/es.po new file mode 100644 index 00000000000..bf2e068882c --- /dev/null +++ b/product_supplierinfo_purchase_contact/i18n/es.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_supplierinfo_purchase_contact +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-05-21 14:32+0000\n" +"PO-Revision-Date: 2024-05-21 14:32+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: product_supplierinfo_purchase_contact +#: model:ir.model.fields,field_description:product_supplierinfo_purchase_contact.field_product_supplierinfo__purchase_partner_id +msgid "Purchase contact" +msgstr "Contacto de compra" + +#. module: product_supplierinfo_purchase_contact +#: model:ir.model,name:product_supplierinfo_purchase_contact.model_stock_rule +msgid "Stock Rule" +msgstr "Regla de Inventario" + +#. module: product_supplierinfo_purchase_contact +#: model:ir.model,name:product_supplierinfo_purchase_contact.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "Tarifa de proveedor" diff --git a/product_supplierinfo_purchase_contact/i18n/it.po b/product_supplierinfo_purchase_contact/i18n/it.po new file mode 100644 index 00000000000..d8b8a01aaba --- /dev/null +++ b/product_supplierinfo_purchase_contact/i18n/it.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_supplierinfo_purchase_contact +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-06-04 15:38+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: product_supplierinfo_purchase_contact +#: model:ir.model.fields,field_description:product_supplierinfo_purchase_contact.field_product_supplierinfo__purchase_partner_id +msgid "Purchase contact" +msgstr "Contratto di acquisto" + +#. module: product_supplierinfo_purchase_contact +#: model:ir.model,name:product_supplierinfo_purchase_contact.model_stock_rule +msgid "Stock Rule" +msgstr "Regola di giacenza" + +#. module: product_supplierinfo_purchase_contact +#: model:ir.model,name:product_supplierinfo_purchase_contact.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "Listino prezzi fornitore" diff --git a/product_supplierinfo_purchase_contact/i18n/product_supplierinfo_purchase_contact.pot b/product_supplierinfo_purchase_contact/i18n/product_supplierinfo_purchase_contact.pot new file mode 100644 index 00000000000..54b191bddb3 --- /dev/null +++ b/product_supplierinfo_purchase_contact/i18n/product_supplierinfo_purchase_contact.pot @@ -0,0 +1,29 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_supplierinfo_purchase_contact +# +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: product_supplierinfo_purchase_contact +#: model:ir.model.fields,field_description:product_supplierinfo_purchase_contact.field_product_supplierinfo__purchase_partner_id +msgid "Purchase contact" +msgstr "" + +#. module: product_supplierinfo_purchase_contact +#: model:ir.model,name:product_supplierinfo_purchase_contact.model_stock_rule +msgid "Stock Rule" +msgstr "" + +#. module: product_supplierinfo_purchase_contact +#: model:ir.model,name:product_supplierinfo_purchase_contact.model_product_supplierinfo +msgid "Supplier Pricelist" +msgstr "" diff --git a/product_supplierinfo_purchase_contact/models/__init__.py b/product_supplierinfo_purchase_contact/models/__init__.py new file mode 100644 index 00000000000..0fb42bc1623 --- /dev/null +++ b/product_supplierinfo_purchase_contact/models/__init__.py @@ -0,0 +1,2 @@ +from . import product_supplierinfo +from . import stock_rule diff --git a/product_supplierinfo_purchase_contact/models/product_supplierinfo.py b/product_supplierinfo_purchase_contact/models/product_supplierinfo.py new file mode 100644 index 00000000000..1bde44049cd --- /dev/null +++ b/product_supplierinfo_purchase_contact/models/product_supplierinfo.py @@ -0,0 +1,13 @@ +# Copyright 2024 Tecnativa - Carolina Fernandez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class ProductSupplierInfo(models.Model): + _inherit = "product.supplierinfo" + + purchase_partner_id = fields.Many2one( + comodel_name="res.partner", + string="Purchase contact", + domain="[('parent_id', '=', partner_id)]", + ) diff --git a/product_supplierinfo_purchase_contact/models/stock_rule.py b/product_supplierinfo_purchase_contact/models/stock_rule.py new file mode 100644 index 00000000000..c940d12615f --- /dev/null +++ b/product_supplierinfo_purchase_contact/models/stock_rule.py @@ -0,0 +1,19 @@ +# Copyright 2024 Tecnativa - Carolina Fernandez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import models + + +class StockRule(models.Model): + _inherit = "stock.rule" + + def _make_po_get_domain(self, company_id, values, partner): + if values.get("supplier") and values["supplier"].purchase_partner_id: + partner = values["supplier"].purchase_partner_id + return super()._make_po_get_domain(company_id, values, partner) + + def _prepare_purchase_order(self, company_id, origins, values): + res = super()._prepare_purchase_order(company_id, origins, values) + values = values[0] + if "supplier" in values and values["supplier"].purchase_partner_id: + res["partner_id"] = values["supplier"].purchase_partner_id.id + return res diff --git a/product_supplierinfo_purchase_contact/pyproject.toml b/product_supplierinfo_purchase_contact/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/product_supplierinfo_purchase_contact/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/product_supplierinfo_purchase_contact/readme/CONTEXT.md b/product_supplierinfo_purchase_contact/readme/CONTEXT.md new file mode 100644 index 00000000000..7c7a2b65c00 --- /dev/null +++ b/product_supplierinfo_purchase_contact/readme/CONTEXT.md @@ -0,0 +1,6 @@ +This module had 2 purposes: +- To specify which contact the purchase orders generated from procurements associated to this supplierinfo have to be put. +- That the auto-created supplierinfo from the purchase order has the main partner associated, not the specific contact one. + +The 'Purchase contact' (purchase_partner_id) field is required if for example you use sales pricelist based on supplierinfo +(product_pricelist_supplierinfo), you want to use as supplier filter the 'Supplier' (partner_id) field. \ No newline at end of file diff --git a/product_supplierinfo_purchase_contact/readme/CONTRIBUTORS.md b/product_supplierinfo_purchase_contact/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..2655c1de1c1 --- /dev/null +++ b/product_supplierinfo_purchase_contact/readme/CONTRIBUTORS.md @@ -0,0 +1,5 @@ +- [Tecnativa](https://www.tecnativa.com): + + > - Carolina Fernandez + > - Pedro M. Baeza + > - Víctor Martínez diff --git a/product_supplierinfo_purchase_contact/readme/DESCRIPTION.md b/product_supplierinfo_purchase_contact/readme/DESCRIPTION.md new file mode 100644 index 00000000000..2851bc39204 --- /dev/null +++ b/product_supplierinfo_purchase_contact/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module adds Purchase contact field on supplier rates +(product.supplierinfo) and allows you to use this contact when creating +the purchase order from supplies (replacement or to order). diff --git a/product_supplierinfo_purchase_contact/readme/USAGE.md b/product_supplierinfo_purchase_contact/readme/USAGE.md new file mode 100644 index 00000000000..dff14c5a718 --- /dev/null +++ b/product_supplierinfo_purchase_contact/readme/USAGE.md @@ -0,0 +1,6 @@ +- Go to Purchase \> Configuration \> Vendor pricelist and create new + Vendor pricelist and complete Purchase contact. +- Go to Inventory \> Operations \> Replenishment and create a new + replenishment for product with Vendor pricelist created before. +- Press button "Order once" and will create a new purchase order for + Purchase contact instead of Vendor from Vendor Pricelist. diff --git a/product_supplierinfo_purchase_contact/static/description/icon.png b/product_supplierinfo_purchase_contact/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/product_supplierinfo_purchase_contact/static/description/icon.png differ diff --git a/product_supplierinfo_purchase_contact/static/description/index.html b/product_supplierinfo_purchase_contact/static/description/index.html new file mode 100644 index 00000000000..278f150bce8 --- /dev/null +++ b/product_supplierinfo_purchase_contact/static/description/index.html @@ -0,0 +1,468 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Product Supplier Purchase Contact

+ +

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

+

This module adds Purchase contact field on supplier rates +(product.supplierinfo) and allows you to use this contact when creating +the purchase order from supplies (replacement or to order).

+

Table of contents

+ +
+

Use Cases / Context

+

This module had 2 purposes:

+
    +
  • To specify which contact the purchase orders generated from +procurements associated to this supplierinfo have to be put.
  • +
  • That the auto-created supplierinfo from the purchase order has the +main partner associated, not the specific contact one.
  • +
+

The ‘Purchase contact’ (purchase_partner_id) field is required if for +example you use sales pricelist based on supplierinfo +(product_pricelist_supplierinfo), you want to use as supplier filter the +‘Supplier’ (partner_id) field.

+
+
+

Usage

+
    +
  • Go to Purchase > Configuration > Vendor pricelist and create new +Vendor pricelist and complete Purchase contact.
  • +
  • Go to Inventory > Operations > Replenishment and create a new +replenishment for product with Vendor pricelist created before.
  • +
  • Press button “Order once” and will create a new purchase order for +Purchase contact instead of Vendor from Vendor Pricelist.
  • +
+
+
+

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

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • Tecnativa:

    +
    +
      +
    • Carolina Fernandez
    • +
    • Pedro M. Baeza
    • +
    • Víctor Martínez
    • +
    +
    +
  • +
+
+
+

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:

+

victoralmau

+

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/product_supplierinfo_purchase_contact/tests/__init__.py b/product_supplierinfo_purchase_contact/tests/__init__.py new file mode 100644 index 00000000000..892a4c70ec7 --- /dev/null +++ b/product_supplierinfo_purchase_contact/tests/__init__.py @@ -0,0 +1 @@ +from . import test_stock_rule diff --git a/product_supplierinfo_purchase_contact/tests/test_stock_rule.py b/product_supplierinfo_purchase_contact/tests/test_stock_rule.py new file mode 100644 index 00000000000..b7655a18734 --- /dev/null +++ b/product_supplierinfo_purchase_contact/tests/test_stock_rule.py @@ -0,0 +1,77 @@ +# Copyright 2024 Tecnativa - Carolina Fernandez +# Copyright 2025 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import Command +from odoo.tools import mute_logger + +from odoo.addons.base.tests.common import BaseCommon + + +class TestStockRule(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.supplierinfo_obj = cls.env["product.supplierinfo"] + cls.partner2 = cls.env["res.partner"].create({"name": "Mrs. Odoo 2"}) + cls.product1 = cls.env["product.product"].create( + { + "name": "Test Product 1", + "seller_ids": [ + Command.create( + { + "partner_id": cls.partner2.id, + "purchase_partner_id": cls.partner.id, + "price": 100, + } + ) + ], + } + ) + cls.product2 = cls.env["product.product"].create( + { + "name": "Test Product 2", + "seller_ids": [ + Command.create( + { + "partner_id": cls.partner2.id, + "price": 50, + } + ) + ], + } + ) + + def _create_orderpoint(self, product): + return self.env["stock.warehouse.orderpoint"].create( + { + "name": product.name, + "product_id": product.id, + "product_min_qty": 1, + "product_max_qty": 10, + "trigger": "manual", + } + ) + + @mute_logger("odoo.models.unlink") + def test_replenishment_with_vendor_purchase(self): + op = self._create_orderpoint(self.product1) + op.action_replenish() + purchase = self.env["purchase.order"].search( + [("partner_id", "=", self.partner.id)], order="id desc", limit=1 + ) + self.assertEqual(purchase.partner_id, self.partner) + self.assertEqual(purchase.order_line.product_id, self.product1) + self.assertEqual(purchase.order_line.price_unit, 100) + self.assertEqual(purchase.order_line.product_qty, 10) + + @mute_logger("odoo.models.unlink") + def test_replenishment_without_vendor_purchase(self): + op = self._create_orderpoint(self.product2) + op.action_replenish() + purchase = self.env["purchase.order"].search( + [("partner_id", "=", self.partner2.id)], order="id desc", limit=1 + ) + self.assertEqual(purchase.partner_id, self.partner2) + self.assertEqual(purchase.order_line.product_id, self.product2) + self.assertEqual(purchase.order_line.price_unit, 50) + self.assertEqual(purchase.order_line.product_qty, 10) diff --git a/product_supplierinfo_purchase_contact/views/product_supplierinfo_view.xml b/product_supplierinfo_purchase_contact/views/product_supplierinfo_view.xml new file mode 100644 index 00000000000..edcfc45277f --- /dev/null +++ b/product_supplierinfo_purchase_contact/views/product_supplierinfo_view.xml @@ -0,0 +1,26 @@ + + + product.supplierinfo + + + + + + + + + product.supplierinfo + + + + + + + +