diff --git a/procurement_mto_analytic/README.rst b/procurement_mto_analytic/README.rst index c3affb029a..9f6e562ef7 100644 --- a/procurement_mto_analytic/README.rst +++ b/procurement_mto_analytic/README.rst @@ -7,7 +7,7 @@ Purchase Analytic (MTO) !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:5422c8951e5b5e292bcb68881aac0c7296bd9abe57ed26b8eecf69b555fef59c + !! source digest: sha256:541299b9d83e8dca12c223d23e8d78357360045ca1f7272edd4f4120da984de7 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -17,13 +17,13 @@ Purchase Analytic (MTO) :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--analytic-lightgray.png?logo=github - :target: https://github.com/OCA/account-analytic/tree/15.0/procurement_mto_analytic + :target: https://github.com/OCA/account-analytic/tree/16.0/procurement_mto_analytic :alt: OCA/account-analytic .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/account-analytic-15-0/account-analytic-15-0-procurement_mto_analytic + :target: https://translation.odoo-community.org/projects/account-analytic-16-0/account-analytic-16-0-procurement_mto_analytic :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/account-analytic&target_branch=15.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-analytic&target_branch=16.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -74,7 +74,7 @@ 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 `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -125,6 +125,6 @@ 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. -This module is part of the `OCA/account-analytic `_ project on GitHub. +This module is part of the `OCA/account-analytic `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/procurement_mto_analytic/__manifest__.py b/procurement_mto_analytic/__manifest__.py index 8bfa5c5887..82a7832bb8 100644 --- a/procurement_mto_analytic/__manifest__.py +++ b/procurement_mto_analytic/__manifest__.py @@ -2,13 +2,13 @@ { "name": "Purchase Analytic (MTO)", - "summary": "This module sets analytic account in purchase order line from " - "sale order analytic account", - "version": "15.0.1.0.0", + "summary": "This module sets analytic distribution in purchase order line from " + "sale order line analytic distribution", + "version": "16.0.1.0.0", "category": "Analytic", "license": "AGPL-3", "author": "Tecnativa, VentorTech, Odoo Community Association (OCA)", "website": "https://github.com/OCA/account-analytic", - "depends": ["sale_stock", "purchase_stock"], + "depends": ["purchase_stock", "sale_stock"], "installable": True, } diff --git a/procurement_mto_analytic/models/purchase_order_line.py b/procurement_mto_analytic/models/purchase_order_line.py index 31fbaec58e..aa9142533c 100644 --- a/procurement_mto_analytic/models/purchase_order_line.py +++ b/procurement_mto_analytic/models/purchase_order_line.py @@ -15,5 +15,5 @@ def _prepare_purchase_order_line_from_procurement( )._prepare_purchase_order_line_from_procurement( product_id, product_qty, product_uom, company_id, values, po ) - res["account_analytic_id"] = values.get("account_analytic_id", False) + res["analytic_distribution"] = values.get("analytic_distribution", False) return res diff --git a/procurement_mto_analytic/models/sale_order_line.py b/procurement_mto_analytic/models/sale_order_line.py index bd4fa4360e..d174311a97 100644 --- a/procurement_mto_analytic/models/sale_order_line.py +++ b/procurement_mto_analytic/models/sale_order_line.py @@ -8,12 +8,12 @@ class SaleOrderLine(models.Model): def _prepare_procurement_values(self, group_id=False): res = super()._prepare_procurement_values(group_id) - res.update({"account_analytic_id": self.order_id.analytic_account_id.id}) + res.update({"analytic_distribution": self.analytic_distribution}) return res def _purchase_service_prepare_line_values(self, purchase_order, quantity=False): res = super()._purchase_service_prepare_line_values( purchase_order=purchase_order, quantity=quantity ) - res.update({"account_analytic_id": self.order_id.analytic_account_id.id}) + res.update({"analytic_distribution": self.analytic_distribution}) return res diff --git a/procurement_mto_analytic/models/stock_move.py b/procurement_mto_analytic/models/stock_move.py index 7f3c315727..f710e7b8e9 100644 --- a/procurement_mto_analytic/models/stock_move.py +++ b/procurement_mto_analytic/models/stock_move.py @@ -8,7 +8,11 @@ class StockMove(models.Model): def _prepare_procurement_values(self): res = super()._prepare_procurement_values() - res.update( - {"account_analytic_id": self.group_id.sale_id.analytic_account_id.id} - ) + analytic_distribution = self.sale_line_id.analytic_distribution + # In case of using stock_analytic and mrp_stock_analytic + if not analytic_distribution and hasattr(self, "analytic_distribution"): + analytic_distribution = self.analytic_distribution + # Update the procurement values with analytic_distribution if it exists + if analytic_distribution: + res.update({"analytic_distribution": analytic_distribution}) return res diff --git a/procurement_mto_analytic/models/stock_rule.py b/procurement_mto_analytic/models/stock_rule.py index 26a53afc3f..571a4cb81f 100644 --- a/procurement_mto_analytic/models/stock_rule.py +++ b/procurement_mto_analytic/models/stock_rule.py @@ -1,18 +1,39 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import json + from odoo import models class StockRule(models.Model): _inherit = "stock.rule" + def _find_matching_analytic_distribution_record(self, analytic_distribution): + # Prepare the JSONB structure as a string for the SQL query + analytic_distribution_str = json.dumps(analytic_distribution) + # Use a parameterized query for safety + query = """ + SELECT id FROM purchase_order_line + WHERE analytic_distribution::jsonb = %s::jsonb; + """ + self.env.cr.execute(query, (analytic_distribution_str,)) + result = self.env.cr.fetchall() + # Extract IDs from the result + matching_po_line = [res[0] for res in result] + return matching_po_line + def _make_po_get_domain(self, company_id, values, partner): - res = super()._make_po_get_domain(company_id, values, partner) - res += ( - ( - "order_line.account_analytic_id", - "=", - values.get("account_analytic_id", False), - ), - ) - return res + domain = super()._make_po_get_domain(company_id, values, partner) + if values.get("analytic_distribution"): + # Fetch matching record IDs based on dynamic analytic_distribution + matching_po_line = self._find_matching_analytic_distribution_record( + values["analytic_distribution"] + ) + if matching_po_line: + domain += (("order_line", "in", tuple(matching_po_line)),) + else: + # To create new PO + domain += (("order_line", "=", 0000000),) + else: + domain += (("order_line.analytic_distribution", "=", False),) + return domain diff --git a/procurement_mto_analytic/static/description/index.html b/procurement_mto_analytic/static/description/index.html index eaeb07e7df..e9259d58b5 100644 --- a/procurement_mto_analytic/static/description/index.html +++ b/procurement_mto_analytic/static/description/index.html @@ -367,9 +367,9 @@

Purchase Analytic (MTO)

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:5422c8951e5b5e292bcb68881aac0c7296bd9abe57ed26b8eecf69b555fef59c +!! source digest: sha256:541299b9d83e8dca12c223d23e8d78357360045ca1f7272edd4f4120da984de7 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/account-analytic Translate me on Weblate Try me on Runboat

This module takes account analytic value from sale order to the created purchase order line.

Table of contents

@@ -426,7 +426,7 @@

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.

+feedback.

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

@@ -472,7 +472,7 @@

Maintainers

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.

-

This module is part of the OCA/account-analytic project on GitHub.

+

This module is part of the OCA/account-analytic project on GitHub.

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

diff --git a/procurement_mto_analytic/tests/test_purchase_procurement_analytic.py b/procurement_mto_analytic/tests/test_purchase_procurement_analytic.py index 65097e81fc..4dd1549390 100644 --- a/procurement_mto_analytic/tests/test_purchase_procurement_analytic.py +++ b/procurement_mto_analytic/tests/test_purchase_procurement_analytic.py @@ -9,8 +9,10 @@ class TestPurchaseProcurementAnalytic(common.TransactionCase): @classmethod def setUpClass(cls): super(TestPurchaseProcurementAnalytic, cls).setUpClass() - vendor = cls.env["res.partner"].create({"name": "Partner #2"}) - supplierinfo = cls.env["product.supplierinfo"].create({"name": vendor.id}) + cls.vendor = cls.env["res.partner"].create({"name": "Partner #2"}) + supplierinfo = cls.env["product.supplierinfo"].create( + {"partner_id": cls.vendor.id} + ) mto = cls.env.ref("stock.route_warehouse0_mto") mto.write({"active": True}) buy = cls.env.ref("purchase_stock.route_warehouse0_buy") @@ -22,7 +24,7 @@ def setUpClass(cls): } ) supplierinfo_service = cls.env["product.supplierinfo"].create( - {"name": vendor.id} + {"partner_id": cls.vendor.id} ) cls.service_product = cls.env["product.product"].create( { @@ -33,15 +35,14 @@ def setUpClass(cls): } ) cls.partner = cls.env["res.partner"].create({"name": "Partner #1"}) + cls.analytic_distribution = dict( + {str(cls.env.ref("analytic.analytic_agrolait").id): 100.0} + ) def test_sale_to_procurement(self): - analytic_account = self.env["account.analytic.account"].create( - {"name": "Test Analytic Account"} - ) sale_order = self.env["sale.order"].create( { "partner_id": self.partner.id, - "analytic_account_id": analytic_account.id, "order_line": [ ( 0, @@ -51,6 +52,7 @@ def test_sale_to_procurement(self): "product_uom_qty": 1, "price_unit": self.product.list_price, "name": self.product.name, + "analytic_distribution": self.analytic_distribution, }, ) ], @@ -58,20 +60,18 @@ def test_sale_to_procurement(self): } ) sale_order.with_context(test_enabled=True).action_confirm() - - purchase_order = self.env["purchase.order.line"].search( - [("account_analytic_id", "=", analytic_account.id)] + purchase_order_line = self.env["purchase.order.line"].search( + [("partner_id", "=", self.vendor.id)] + ) + self.assertTrue(purchase_order_line) + self.assertEqual( + purchase_order_line.analytic_distribution, self.analytic_distribution ) - self.assertTrue(purchase_order) def test_sale_service_product(self): - analytic_account = self.env["account.analytic.account"].create( - {"name": "Test Service Analytic Account"} - ) sale_order = self.env["sale.order"].create( { "partner_id": self.partner.id, - "analytic_account_id": analytic_account.id, "order_line": [ ( 0, @@ -79,8 +79,9 @@ def test_sale_service_product(self): { "product_id": self.service_product.id, "product_uom_qty": 1, - "price_unit": self.product.list_price, - "name": self.product.name, + "price_unit": self.service_product.list_price, + "name": self.service_product.name, + "analytic_distribution": self.analytic_distribution, }, ) ], @@ -89,7 +90,10 @@ def test_sale_service_product(self): ) sale_order.with_context(test_enabled=True).action_confirm() - purchase_order = self.env["purchase.order.line"].search( - [("account_analytic_id", "=", analytic_account.id)] + purchase_order_line = self.env["purchase.order.line"].search( + [("partner_id", "=", self.vendor.id)] + ) + self.assertTrue(purchase_order_line) + self.assertTrue( + purchase_order_line.analytic_distribution, self.analytic_distribution ) - self.assertTrue(purchase_order)