diff --git a/product_multi_company_stock/README.rst b/product_multi_company_stock/README.rst index 5fabb7f0ffc..515d0d8b873 100644 --- a/product_multi_company_stock/README.rst +++ b/product_multi_company_stock/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - =========================== Product multi-company Stock =========================== @@ -17,7 +13,7 @@ Product multi-company Stock .. |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 +.. |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%2Fmulti--company-lightgray.png?logo=github @@ -62,6 +58,7 @@ Contributors ------------ - Joan Sisquella +- Lois Rilo Maintainers ----------- diff --git a/product_multi_company_stock/models/__init__.py b/product_multi_company_stock/models/__init__.py index e8fa8f6bf1e..0b022754d91 100644 --- a/product_multi_company_stock/models/__init__.py +++ b/product_multi_company_stock/models/__init__.py @@ -1 +1,2 @@ from . import product_template +from . import stock_lot diff --git a/product_multi_company_stock/models/stock_lot.py b/product_multi_company_stock/models/stock_lot.py new file mode 100644 index 00000000000..3d3cd07175f --- /dev/null +++ b/product_multi_company_stock/models/stock_lot.py @@ -0,0 +1,23 @@ +# Copyright 2026 ForgeFlow S.L. (http://www.forgeflow.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import api, models + + +class StockLot(models.Model): + _inherit = "stock.lot" + + @api.depends("product_id.company_id", "product_id.company_ids") + def _compute_company_id(self): + # For lots belonging to single-company products, defer to standard logic. + # For multi-company products, preserve the stored company_id so that a + # change to product.company_ids (e.g. adding a third company) never + # overwrites the lot's original company — which would cause _check_unique_lot + # to fire when two lots share the same name across different companies. + single_company_lots = self.filtered( + lambda rec: len(rec.product_id.sudo().company_ids) == 1 + ) + res = super(StockLot, single_company_lots)._compute_company_id() + for lot in self - single_company_lots: + lot.company_id = lot._origin.company_id or lot.product_id.company_id + return res diff --git a/product_multi_company_stock/readme/CONTRIBUTORS.md b/product_multi_company_stock/readme/CONTRIBUTORS.md index 2fa75245648..5c3dd6681ba 100644 --- a/product_multi_company_stock/readme/CONTRIBUTORS.md +++ b/product_multi_company_stock/readme/CONTRIBUTORS.md @@ -1 +1,2 @@ - Joan Sisquella \ +- Lois Rilo \ diff --git a/product_multi_company_stock/static/description/index.html b/product_multi_company_stock/static/description/index.html index aab8c02a277..f8bb8e78aeb 100644 --- a/product_multi_company_stock/static/description/index.html +++ b/product_multi_company_stock/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Product multi-company Stock -
+
+

Product multi-company Stock

- - -Odoo Community Association - -
-

Product multi-company Stock

-

Beta License: AGPL-3 OCA/multi-company Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/multi-company Translate me on Weblate Try me on Runboat

This modules does not allow to remove a company from company_ids if there is stock or moves in that company

Table of contents

@@ -390,7 +385,7 @@

Product multi-company Stock

-

Bug Tracker

+

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 @@ -398,21 +393,22 @@

Bug Tracker

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

-
diff --git a/product_multi_company_stock/tests/test_product_multi_company_stock.py b/product_multi_company_stock/tests/test_product_multi_company_stock.py index a09fcf21ae5..2fded426fcb 100644 --- a/product_multi_company_stock/tests/test_product_multi_company_stock.py +++ b/product_multi_company_stock/tests/test_product_multi_company_stock.py @@ -1,5 +1,4 @@ -# Copyright 2025 ForgeFlow S.L. -# (http://www.forgeflow.com) +# Copyright 2025-26 ForgeFlow S.L. (http://www.forgeflow.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo.exceptions import UserError @@ -116,3 +115,46 @@ def test_remove_company_with_quants_or_moves_archived_product(self): with self.assertRaises(UserError) as error_move: product.write({"company_ids": [(6, 0, [self.company_2.id])]}) self.assertIn("stock moves", str(error_move.exception)) + + def test_add_company_does_not_break_same_name_lots(self): + """Adding a company to a product must not affect existing lots. + + Adding a new company to a product's company_ids triggers a + recompute of stock.lot.company_id (which depends on product_id.company_id). + should not change lots company. + """ + product = self.env["product.product"].create( + { + "name": "Test Tracked Product", + "is_storable": True, + "tracking": "lot", + "company_ids": [(6, 0, [self.company_1.id, self.company_2.id])], + } + ) + company_3 = self.company_obj.create({"name": "Test company 3"}) + lot_1 = ( + self.env["stock.lot"] + .with_company(self.company_1) + .create( + { + "name": "LOT001", + "product_id": product.id, + "company_id": self.company_1.id, + } + ) + ) + lot_2 = ( + self.env["stock.lot"] + .with_company(self.company_2) + .create( + { + "name": "LOT001", + "product_id": product.id, + "company_id": self.company_2.id, + } + ) + ) + # Adding a third company should neither raise nor alter the lot companies. + product.write({"company_ids": [(4, company_3.id)]}) + self.assertEqual(lot_1.company_id, self.company_1) + self.assertEqual(lot_2.company_id, self.company_2)