diff --git a/product_origin_char/README.rst b/product_origin_char/README.rst
index 0cbdfa6..e8a0f90 100644
--- a/product_origin_char/README.rst
+++ b/product_origin_char/README.rst
@@ -19,8 +19,7 @@ Product Origin Text
|badge1| |badge2|
-This module replaces the structured country/state origin fields from ``product_origin``
-with a flexible free-text field that can be defined per supplier.
+This module adds a simple free-text ``origin_text`` field to products.
**Problem:**
@@ -38,21 +37,18 @@ These free-form descriptions don't fit into structured country/state fields.
**Solution:**
-This module adds a translatable ``origin_text`` field to ``product.supplierinfo`` that:
+This module adds a simple ``origin_text`` field to ``product.template`` that:
* Allows free-form text to describe product origin
-* Is stored per supplier (different suppliers may have different origin info)
-* Is translatable (can be described differently in each language)
-* Is automatically displayed on the product based on the main vendor
- (from ``product_main_seller`` module)
+* Is accessible from product variants via related field
+* Works with any product workflow
**Features:**
-* Free-text ``Origin`` field in supplier info (Purchase tab of product)
-* Computed ``Origin`` field in product form (shows main vendor's origin)
-* Field is visible in product list view (optional column)
-* Full translation support for multiple languages
-* Compatible with existing supplier management workflows
+* Free-text ``Origin`` field in product form
+* Field visible in product list views (optional column)
+* Variants share the same origin as their template
+* Editable from both template and variant views
**Table of contents**
@@ -65,7 +61,6 @@ Installation
This module depends on:
* ``product`` - Base product management
-* ``product_main_seller`` - To determine the main vendor for products
To install:
@@ -77,8 +72,8 @@ Configuration
No configuration is needed. The module works automatically after installation.
-The origin text displayed on a product is based on the **main vendor** as determined
-by ``product_main_seller`` (the first supplier in the vendors list).
+The origin field appears in the product form view (next to category) and can be
+enabled as an optional column in list views.
Usage
=====
@@ -86,29 +81,21 @@ Usage
**To add origin information to a product:**
#. Go to a product form
-#. Open the **Purchase** tab
-#. In the **Vendors** section, select a supplier line
-#. Fill in the **Origin** field with free-form text describing the origin
- (e.g., "Valencia, Huerta de..., Spain")
+#. Find the **Origin** field (near the product category)
+#. Fill in the origin with free-form text
+ (e.g., "Valencia, Spain", "Local producer - Basque Country")
#. Save the product
-**To view origin information:**
+**To view origin information in lists:**
-* The **Origin** field will be automatically displayed on the product form
- (below the **Main Vendor** field in the Purchase tab)
-* The origin shown is from the **main vendor** (first supplier in the list)
-* You can also add the Origin column to product list views
+* In product list views, enable the optional "Origin" column
+* The origin is shown for both product templates and variants
-**To change the displayed origin:**
+**Product variants:**
-* Reorder the vendors list to change which is the main vendor
-* The origin text will automatically update to show the new main vendor's origin
-
-**Multi-language support:**
-
-* The origin text is translatable
-* Switch to another language and edit the supplier info to provide a translation
-* Each language can have a different description of the origin
+* All variants of a product template share the same origin
+* Updating the origin on any variant updates the template
+* This ensures consistency across all variants
Bug Tracker
===========
diff --git a/product_origin_char/README_DEV.md b/product_origin_char/README_DEV.md
index 3ed005a..789407d 100644
--- a/product_origin_char/README_DEV.md
+++ b/product_origin_char/README_DEV.md
@@ -4,111 +4,88 @@
### Architecture
-This module extends the product origin information system to use free-text fields instead of structured country/state fields.
+This module adds a simple free-text origin field to products.
**Models:**
-1. **product.supplierinfo** - Base model with the `origin_text` field
- - Field: `origin_text` (Char, translate=True)
+1. **product.template** - Base model with the `origin_text` field
+ - Field: `origin_text` (Char)
- This is where the actual data is stored
- - Each supplier can have a different origin text for the same product
+ - Editable directly on the product form
-2. **product.template** - Computed field
- - Field: `origin_text` (Char, computed, store=False)
- - Computes from main vendor's supplierinfo
- - Depends on: `main_seller_id`, `variant_seller_ids.origin_text`
+2. **product.product** - Related field for variant access
+ - Field: `origin_text` (Char, related to `product_tmpl_id.origin_text`)
+ - `readonly=False` allows editing from variant views
+ - Changes propagate to the template
-3. **product.product** - Computed field (variant level)
- - Field: `origin_text` (Char, computed, store=False)
- - Computes from main vendor's supplierinfo
- - Depends on: `product_tmpl_id.main_seller_id`, `seller_ids.origin_text`
+### Why This Architecture?
-### Why Computed Fields Instead of Related?
+The `origin_text` field is stored in `product.template` because:
-The `origin_text` field in `product.template` and `product.product` cannot be a simple `related` field because:
+- Origin typically applies to all variants of a product
+- Simplifies data management (one source of truth)
+- Avoids duplication across variants
+- Standard Odoo pattern for product-level attributes
-- `main_seller_id` is a `res.partner` record
-- `origin_text` is stored in `product.supplierinfo` records
-- We need to find the supplierinfo record where `partner_id == main_seller_id`
+The related field in `product.product` with `readonly=False` allows:
-This requires a computed field with custom logic to filter and find the correct supplierinfo record.
+- Seamless access from variant views
+- Editing from either template or variant forms
+- Automatic synchronization between template and variants
-### Translation Support
+### Previous Architecture (Deprecated)
-The `origin_text` field in `product.supplierinfo` uses `translate=True`, which means:
+The previous version stored `origin_text` in `product.supplierinfo` with computed
+fields in template/product. This was deprecated because:
-- Each language can have a different value
-- Translations are stored in Odoo's translation system
-- When switching languages, the field shows the translated value
-- If no translation exists, it falls back to the default language value
-
-### Store Strategy
-
-The computed fields in product template and product use `store=False` because:
-
-- The value should always reflect the current main vendor
-- If the main vendor changes or its origin text is updated, the product's origin should update automatically
-- No need to store redundant data
-- Reduces database size and update complexity
+- Supplierinfo records don't always exist when products are created
+- Added unnecessary complexity with computed fields
+- Required `product_main_seller` dependency
+- Origin semantically belongs to the product, not the supplier relationship
### Dependencies
-- **product** - Core product module
-- **product_main_seller** - Provides `main_seller_id` computed field for products
-
-### Relationship to product_origin
-
-This module is a replacement/alternative to the OCA `product_origin` module:
-
-- `product_origin` provides structured fields (country_id, state_id)
-- `product_origin_char` provides free-text field (origin_text)
-- Both cannot be installed simultaneously without potential conflicts
-- This module was created because suppliers use creative, non-standardized origin descriptions
+- **product** - Core product module (only dependency)
### Performance Considerations
-- Computed fields with `store=False` are calculated on-the-fly
-- Performance is acceptable because the computation is simple (filter + get first)
-- If performance becomes an issue, consider:
- - Adding `store=True` with proper dependencies
- - Adding database indexes on frequently searched fields
- - Caching strategies
+- Simple stored field with no computation overhead
+- Related field access is efficient in Odoo ORM
+- No additional queries needed for variant access
### Testing Strategy
Tests cover:
-1. **Basic field storage** - Create supplierinfo with origin_text
-2. **Computed field** - Verify product shows main vendor's origin
-3. **Main vendor change** - Verify origin updates when main vendor changes
-4. **Translation** - Verify field is translatable (multilingual support)
-5. **Empty cases** - Product without vendors, vendor without origin
-
-### Future Improvements
-
-Potential enhancements:
-
-- Add migration script from `product_origin` to convert country/state to text
-- Add bulk update wizard to set origin for multiple products
-- Add origin text to purchase order lines
-- Add search/group by origin in product lists
-- Add validation rules (max length, format checks)
+1. **Basic field storage** - Set origin on template
+2. **Related field access** - Verify variant sees template origin
+3. **Write from variant** - Verify changes propagate to template
+4. **Empty cases** - Products without origin
+5. **Multiple products** - Independent origins
+6. **Variants** - All variants share same origin
## Code Quality
- Follows OCA guidelines
- Black formatted (line length 88)
-- isort sorted imports
-- Passes flake8 and pylint checks
-- Full test coverage
-- Documented with docstrings
-- Translatable strings handled correctly (no `_()` in field definitions)
+- isort for imports
+- Minimal dependencies (only `product`)
+
+## Migration from v1.x
+
+If upgrading from the previous supplier-based architecture:
+
+1. Data in `product.supplierinfo.origin_text` will need manual migration
+2. Run migration script to copy main supplier origin to product template
+3. Remove dependency on `product_main_seller` if no longer needed
## Version History
-- **18.0.1.0.0** (2026-02-25) - Initial release
+- **18.0.2.0.0** (2026-03-06) - Simplified architecture
+ - Field directly on product.template
+ - Related field in product.product
+ - Removed dependency on product_main_seller
+
+- **18.0.1.0.0** (2026-02-25) - Initial release (deprecated)
- Free-text origin field per supplier
- Automatic display based on main vendor
- - Multi-language support
- - Full test coverage
- - OCA documentation structure
diff --git a/product_origin_char/__manifest__.py b/product_origin_char/__manifest__.py
index 5be4956..18c9a8b 100644
--- a/product_origin_char/__manifest__.py
+++ b/product_origin_char/__manifest__.py
@@ -3,19 +3,17 @@
{ # noqa: B018
"name": "Product Origin Text",
- "version": "18.0.1.0.0",
+ "version": "18.0.2.0.0",
"category": "Product",
- "summary": "Free text origin field per supplier",
+ "summary": "Free text origin field for products",
"author": "Odoo Community Association (OCA), Criptomart",
"maintainers": ["Criptomart"],
"license": "AGPL-3",
"website": "https://git.criptomart.net/criptomart/addons-cm",
"depends": [
"product",
- "product_main_seller",
],
"data": [
- "views/product_supplierinfo_views.xml",
"views/product_template_views.xml",
],
}
diff --git a/product_origin_char/models/__init__.py b/product_origin_char/models/__init__.py
index e138082..481ccad 100644
--- a/product_origin_char/models/__init__.py
+++ b/product_origin_char/models/__init__.py
@@ -1,6 +1,5 @@
# Copyright 2026 Criptomart
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from . import product_supplierinfo # noqa: F401
from . import product_template # noqa: F401
from . import product_product # noqa: F401
diff --git a/product_origin_char/models/product_product.py b/product_origin_char/models/product_product.py
index 1ec475b..dea55c5 100644
--- a/product_origin_char/models/product_product.py
+++ b/product_origin_char/models/product_product.py
@@ -1,7 +1,6 @@
# Copyright 2026 Criptomart
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from odoo import api
from odoo import fields
from odoo import models
@@ -10,21 +9,6 @@ class ProductProduct(models.Model):
_inherit = "product.product"
origin_text = fields.Char(
- string="Origin",
- compute="_compute_origin_text",
- store=False,
- help="Origin text from main vendor's supplierinfo",
+ related="product_tmpl_id.origin_text",
+ readonly=False,
)
-
- @api.depends("product_tmpl_id.main_seller_id", "seller_ids.origin_text")
- def _compute_origin_text(self):
- for product in self:
- if product.product_tmpl_id.main_seller_id:
- # Find the supplierinfo record for the main seller
- main_seller = product.product_tmpl_id.main_seller_id
- seller = product.seller_ids.filtered(
- lambda s, ms=main_seller: s.partner_id == ms
- )[:1]
- product.origin_text = seller.origin_text if seller else False
- else:
- product.origin_text = False
diff --git a/product_origin_char/models/product_supplierinfo.py b/product_origin_char/models/product_supplierinfo.py
deleted file mode 100644
index 1f87c7d..0000000
--- a/product_origin_char/models/product_supplierinfo.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2026 Criptomart
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
-from odoo import fields
-from odoo import models
-
-
-class ProductSupplierinfo(models.Model):
- _inherit = "product.supplierinfo"
-
- origin_text = fields.Char(
- string="Origin",
- translate=True,
- help="Free text to describe product origin (country, region, producer, etc.)",
- )
diff --git a/product_origin_char/models/product_template.py b/product_origin_char/models/product_template.py
index 3386907..28876b4 100644
--- a/product_origin_char/models/product_template.py
+++ b/product_origin_char/models/product_template.py
@@ -1,7 +1,6 @@
# Copyright 2026 Criptomart
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from odoo import api
from odoo import fields
from odoo import models
@@ -11,20 +10,5 @@ class ProductTemplate(models.Model):
origin_text = fields.Char(
string="Origin",
- compute="_compute_origin_text",
- store=False,
- help="Origin text from main vendor's supplierinfo",
+ help="Origin of the product.",
)
-
- @api.depends("main_seller_id", "variant_seller_ids.origin_text")
- def _compute_origin_text(self):
- for template in self:
- if template.main_seller_id:
- # Find the supplierinfo record for the main seller
- main_seller = template.main_seller_id
- seller = template.variant_seller_ids.filtered(
- lambda s, ms=main_seller: s.partner_id == ms
- )[:1]
- template.origin_text = seller.origin_text if seller else False
- else:
- template.origin_text = False
diff --git a/product_origin_char/readme/CONFIGURE.rst b/product_origin_char/readme/CONFIGURE.rst
index 6c5dff4..53df9d6 100644
--- a/product_origin_char/readme/CONFIGURE.rst
+++ b/product_origin_char/readme/CONFIGURE.rst
@@ -1,4 +1,4 @@
No configuration is needed. The module works automatically after installation.
-The origin text displayed on a product is based on the **main vendor** as determined
-by ``product_main_seller`` (the first supplier in the vendors list).
+The origin field appears in the product form view (next to category) and can be
+enabled as an optional column in list views.
diff --git a/product_origin_char/readme/DESCRIPTION.rst b/product_origin_char/readme/DESCRIPTION.rst
index 39203bc..b65fe60 100644
--- a/product_origin_char/readme/DESCRIPTION.rst
+++ b/product_origin_char/readme/DESCRIPTION.rst
@@ -1,5 +1,4 @@
-This module replaces the structured country/state origin fields from ``product_origin``
-with a flexible free-text field that can be defined per supplier.
+This module adds a simple free-text ``origin_text`` field to products.
**Problem:**
@@ -17,18 +16,15 @@ These free-form descriptions don't fit into structured country/state fields.
**Solution:**
-This module adds a translatable ``origin_text`` field to ``product.supplierinfo`` that:
+This module adds a simple ``origin_text`` field to ``product.template`` that:
* Allows free-form text to describe product origin
-* Is stored per supplier (different suppliers may have different origin info)
-* Is translatable (can be described differently in each language)
-* Is automatically displayed on the product based on the main vendor
- (from ``product_main_seller`` module)
+* Is accessible from product variants via related field
+* Works with any product workflow
**Features:**
-* Free-text ``Origin`` field in supplier info (Purchase tab of product)
-* Computed ``Origin`` field in product form (shows main vendor's origin)
-* Field is visible in product list view (optional column)
-* Full translation support for multiple languages
-* Compatible with existing supplier management workflows
+* Free-text ``Origin`` field in product form
+* Field visible in product list views (optional column)
+* Variants share the same origin as their template
+* Editable from both template and variant views
diff --git a/product_origin_char/readme/INSTALL.rst b/product_origin_char/readme/INSTALL.rst
index 621a392..48c1f0d 100644
--- a/product_origin_char/readme/INSTALL.rst
+++ b/product_origin_char/readme/INSTALL.rst
@@ -1,7 +1,6 @@
This module depends on:
* ``product`` - Base product management
-* ``product_main_seller`` - To determine the main vendor for products
To install:
diff --git a/product_origin_char/readme/USAGE.rst b/product_origin_char/readme/USAGE.rst
index 60476ba..d0da105 100644
--- a/product_origin_char/readme/USAGE.rst
+++ b/product_origin_char/readme/USAGE.rst
@@ -1,26 +1,18 @@
**To add origin information to a product:**
#. Go to a product form
-#. Open the **Purchase** tab
-#. In the **Vendors** section, select a supplier line
-#. Fill in the **Origin** field with free-form text describing the origin
- (e.g., "Valencia, Huerta de..., Spain")
+#. Find the **Origin** field (near the product category)
+#. Fill in the origin with free-form text
+ (e.g., "Valencia, Spain", "Local producer - Basque Country")
#. Save the product
-**To view origin information:**
+**To view origin information in lists:**
-* The **Origin** field will be automatically displayed on the product form
- (below the **Main Vendor** field in the Purchase tab)
-* The origin shown is from the **main vendor** (first supplier in the list)
-* You can also add the Origin column to product list views
+* In product list views, enable the optional "Origin" column
+* The origin is shown for both product templates and variants
-**To change the displayed origin:**
+**Product variants:**
-* Reorder the vendors list to change which is the main vendor
-* The origin text will automatically update to show the new main vendor's origin
-
-**Multi-language support:**
-
-* The origin text is translatable
-* Switch to another language and edit the supplier info to provide a translation
-* Each language can have a different description of the origin
+* All variants of a product template share the same origin
+* Updating the origin on any variant updates the template
+* This ensures consistency across all variants
diff --git a/product_origin_char/static/description/LOGO_NEEDED.txt b/product_origin_char/static/description/LOGO_NEEDED.txt
deleted file mode 100644
index 8a1fad3..0000000
--- a/product_origin_char/static/description/LOGO_NEEDED.txt
+++ /dev/null
@@ -1 +0,0 @@
-Logo placeholder - run install_logo.sh to add CriptoMart logo
diff --git a/product_origin_char/tests/test_product_origin_char.py b/product_origin_char/tests/test_product_origin_char.py
index 0d7a9df..7b58a6f 100644
--- a/product_origin_char/tests/test_product_origin_char.py
+++ b/product_origin_char/tests/test_product_origin_char.py
@@ -5,190 +5,71 @@ from odoo.tests.common import TransactionCase
class TestProductOriginChar(TransactionCase):
+ """Test cases for product_origin_char module.
+
+ This module adds a simple origin_text field to product.template
+ with a related field in product.product for variant access.
+ """
+
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
- # Create test suppliers
- cls.supplier_1 = cls.env["res.partner"].create(
- {
- "name": "Supplier 1",
- "is_company": True,
- }
- )
- cls.supplier_2 = cls.env["res.partner"].create(
- {
- "name": "Supplier 2",
- "is_company": True,
- }
- )
-
- # Create test product
- cls.product = cls.env["product.product"].create(
+ # Create test product template
+ cls.product_tmpl = cls.env["product.template"].create(
{
"name": "Test Product",
"type": "consu",
}
)
+ cls.product = cls.product_tmpl.product_variant_ids[0]
- def test_01_origin_text_in_supplierinfo(self):
- """Test that origin_text can be set in supplierinfo"""
- supplierinfo = self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": self.product.product_tmpl_id.id,
- "origin_text": "Valencia, Spain",
- }
- )
- self.assertEqual(supplierinfo.origin_text, "Valencia, Spain")
+ def test_01_origin_text_in_template(self):
+ """Test that origin_text can be set in product.template"""
+ self.product_tmpl.origin_text = "Valencia, Spain"
+ self.assertEqual(self.product_tmpl.origin_text, "Valencia, Spain")
- def test_02_origin_from_main_seller(self):
- """Test that product shows origin from main seller"""
- # Create supplierinfo for supplier 1 (will be main seller)
- self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": self.product.product_tmpl_id.id,
- "sequence": 1,
- "origin_text": "Valencia, Spain",
- }
- )
-
- # Verify main seller is supplier 1
- self.product.product_tmpl_id.invalidate_recordset()
- self.assertEqual(self.product.product_tmpl_id.main_seller_id, self.supplier_1)
-
- # Verify origin_text on product matches supplier 1's origin
- self.product.invalidate_recordset()
- self.assertEqual(self.product.origin_text, "Valencia, Spain")
- self.assertEqual(self.product.product_tmpl_id.origin_text, "Valencia, Spain")
-
- def test_03_origin_updates_with_main_seller_change(self):
- """Test that origin updates when main seller changes"""
- # Create supplierinfo for both suppliers
- supplier1_info = self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": self.product.product_tmpl_id.id,
- "sequence": 1,
- "origin_text": "Valencia, Spain",
- }
- )
- supplier2_info = self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_2.id,
- "product_tmpl_id": self.product.product_tmpl_id.id,
- "sequence": 2,
- "origin_text": "Aragón, Spain",
- }
- )
-
- # Initially, main seller is supplier 1
- self.product.product_tmpl_id.invalidate_recordset()
- self.assertEqual(self.product.product_tmpl_id.main_seller_id, self.supplier_1)
- self.product.invalidate_recordset()
- self.assertEqual(self.product.origin_text, "Valencia, Spain")
-
- # Change main seller by swapping sequences
- supplier1_info.sequence = 2
- supplier2_info.sequence = 1
-
- # Verify main seller is now supplier 2
- self.product.product_tmpl_id.invalidate_recordset()
- self.assertEqual(self.product.product_tmpl_id.main_seller_id, self.supplier_2)
-
- # Verify origin_text updated to supplier 2's origin
- self.product.invalidate_recordset()
+ def test_02_origin_text_in_product_related(self):
+ """Test that product.product has related access to origin_text"""
+ self.product_tmpl.origin_text = "Aragón, Spain"
+ # Variant should show template's origin via related field
self.assertEqual(self.product.origin_text, "Aragón, Spain")
- def test_04_empty_origin_without_supplier(self):
- """Test that product without suppliers has no origin"""
- # Create product without suppliers
- product_no_supplier = self.env["product.product"].create(
+ def test_03_origin_text_write_from_variant(self):
+ """Test that origin_text can be written from variant (readonly=False)"""
+ self.product.origin_text = "Basque Country"
+ # Should update the template
+ self.assertEqual(self.product_tmpl.origin_text, "Basque Country")
+
+ def test_04_empty_origin(self):
+ """Test that origin_text defaults to False/empty"""
+ new_product = self.env["product.product"].create(
{
- "name": "Product Without Supplier",
+ "name": "Product Without Origin",
"type": "consu",
}
)
+ self.assertFalse(new_product.origin_text)
+ self.assertFalse(new_product.product_tmpl_id.origin_text)
- # Verify no main seller and no origin
- self.assertFalse(product_no_supplier.product_tmpl_id.main_seller_id)
- self.assertFalse(product_no_supplier.origin_text)
-
- def test_05_empty_origin_with_supplier_no_text(self):
- """Test that supplier without origin_text shows False"""
- # Create supplierinfo without origin_text
- self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": self.product.product_tmpl_id.id,
- "sequence": 1,
- # No origin_text set
- }
- )
-
- # Verify main seller exists but origin is False
- self.product.product_tmpl_id.invalidate_recordset()
- self.assertEqual(self.product.product_tmpl_id.main_seller_id, self.supplier_1)
- self.product.invalidate_recordset()
- self.assertFalse(self.product.origin_text)
-
- def test_06_translation_support(self):
- """Test that origin_text field is translatable"""
- # Create supplierinfo with origin in default language
- supplierinfo = self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": self.product.product_tmpl_id.id,
- "origin_text": "Valencia, Spain",
- }
- )
-
- # Verify field has translate=True attribute
- field = self.env["product.supplierinfo"]._fields["origin_text"]
- self.assertTrue(field.translate)
-
- # Test that we can set translation (requires lang to be installed)
- # This is a basic check - full translation testing would require
- # installing multiple languages
- self.assertEqual(supplierinfo.origin_text, "Valencia, Spain")
-
- def test_07_multiple_products_same_supplier(self):
- """Test that different products can have different origins from same supplier"""
- product2 = self.env["product.product"].create(
+ def test_05_multiple_products_independent_origins(self):
+ """Test that different products have independent origins"""
+ product2_tmpl = self.env["product.template"].create(
{
"name": "Test Product 2",
"type": "consu",
}
)
- # Create supplierinfo for product 1
- self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": self.product.product_tmpl_id.id,
- "origin_text": "Valencia, Spain",
- }
- )
+ self.product_tmpl.origin_text = "Valencia, Spain"
+ product2_tmpl.origin_text = "Aragón, Spain"
- # Create supplierinfo for product 2 with same supplier but different origin
- self.env["product.supplierinfo"].create(
- {
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": product2.product_tmpl_id.id,
- "origin_text": "Aragón, Spain",
- }
- )
+ self.assertEqual(self.product_tmpl.origin_text, "Valencia, Spain")
+ self.assertEqual(product2_tmpl.origin_text, "Aragón, Spain")
- # Verify each product has its own origin
- self.product.invalidate_recordset()
- product2.invalidate_recordset()
- self.assertEqual(self.product.origin_text, "Valencia, Spain")
- self.assertEqual(product2.origin_text, "Aragón, Spain")
-
- def test_08_product_variant_level(self):
- """Test that origin_text works at product variant level"""
+ def test_06_product_variants_share_origin(self):
+ """Test that all variants of a template share the same origin"""
# Create product template with variants
product_attr = self.env["product.attribute"].create({"name": "Color"})
attr_value_red = self.env["product.attribute.value"].create(
@@ -217,17 +98,49 @@ class TestProductOriginChar(TransactionCase):
}
)
- # Create supplierinfo at template level
- self.env["product.supplierinfo"].create(
+ # Set origin on template
+ product_tmpl.origin_text = "Test Origin"
+
+ # Verify all variants show the same origin
+ for variant in product_tmpl.product_variant_ids:
+ self.assertEqual(variant.origin_text, "Test Origin")
+
+ def test_07_origin_update_propagates_to_variants(self):
+ """Test that updating template origin updates all variants"""
+ # Create product with variants
+ product_attr = self.env["product.attribute"].create({"name": "Size"})
+ attr_value_s = self.env["product.attribute.value"].create(
+ {"name": "S", "attribute_id": product_attr.id}
+ )
+ attr_value_m = self.env["product.attribute.value"].create(
+ {"name": "M", "attribute_id": product_attr.id}
+ )
+
+ product_tmpl = self.env["product.template"].create(
{
- "partner_id": self.supplier_1.id,
- "product_tmpl_id": product_tmpl.id,
- "origin_text": "Test Origin",
+ "name": "Sized Product",
+ "type": "consu",
+ "origin_text": "Original Origin",
+ "attribute_line_ids": [
+ (
+ 0,
+ 0,
+ {
+ "attribute_id": product_attr.id,
+ "value_ids": [(6, 0, [attr_value_s.id, attr_value_m.id])],
+ },
+ )
+ ],
}
)
- # Verify all variants show the same origin (from template level)
- product_tmpl.invalidate_recordset()
+ # Verify initial origin
for variant in product_tmpl.product_variant_ids:
- variant.invalidate_recordset()
- self.assertEqual(variant.origin_text, "Test Origin")
+ self.assertEqual(variant.origin_text, "Original Origin")
+
+ # Update origin on template
+ product_tmpl.origin_text = "Updated Origin"
+
+ # Verify all variants show updated origin
+ for variant in product_tmpl.product_variant_ids:
+ self.assertEqual(variant.origin_text, "Updated Origin")
diff --git a/product_origin_char/views/product_supplierinfo_views.xml b/product_origin_char/views/product_supplierinfo_views.xml
deleted file mode 100644
index d881aa0..0000000
--- a/product_origin_char/views/product_supplierinfo_views.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
- product.supplierinfo.form.origin.text
- product.supplierinfo
-
-
-
-
-
-
-
-
-
-
- product.supplierinfo.tree.origin.text
- product.supplierinfo
-
-
-
-
-
-
-
-
diff --git a/product_origin_char/views/product_template_views.xml b/product_origin_char/views/product_template_views.xml
index 19d9db7..8e91092 100644
--- a/product_origin_char/views/product_template_views.xml
+++ b/product_origin_char/views/product_template_views.xml
@@ -8,13 +8,9 @@
product.template
-
-
-
+
+
+
@@ -34,9 +30,9 @@
product.template.tree.origin.text
product.template
-
+
-
+