[REF] product_origin_char: simplify to template-based origin

- Move origin_text field from product.supplierinfo to product.template
- Add related field in product.product for variant access
- Remove dependency on product_main_seller
- Update views to show field near category (editable)
- Rewrite tests for new architecture
- Update all documentation (README, readme/ fragments)
- Bump version to 18.0.2.0.0
This commit is contained in:
snt 2026-03-06 17:43:20 +01:00
parent e2ced75ecd
commit 5efe57dc19
15 changed files with 180 additions and 402 deletions

View file

@ -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
===========

View file

@ -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

View file

@ -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",
],
}

View file

@ -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

View file

@ -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

View file

@ -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.)",
)

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -1,7 +1,6 @@
This module depends on:
* ``product`` - Base product management
* ``product_main_seller`` - To determine the main vendor for products
To install:

View file

@ -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

View file

@ -1 +0,0 @@
Logo placeholder - run install_logo.sh to add CriptoMart logo

View file

@ -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")

View file

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2026 Criptomart
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<!-- Add origin_text field to product.supplierinfo form view -->
<record id="product_supplierinfo_form_view_origin_text" model="ir.ui.view">
<field name="name">product.supplierinfo.form.origin.text</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="product.product_supplierinfo_form_view" />
<field name="arch" type="xml">
<field name="product_code" position="after">
<field
name="origin_text"
placeholder="e.g., Valencia, Huerta de..., Spain"
/>
</field>
</field>
</record>
<!-- Add origin_text field to supplierinfo tree in product form -->
<record id="product_supplierinfo_tree_view_origin_text" model="ir.ui.view">
<field name="name">product.supplierinfo.tree.origin.text</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="product.product_supplierinfo_tree_view" />
<field name="arch" type="xml">
<field name="product_code" position="after">
<field name="origin_text" optional="show" />
</field>
</field>
</record>
</odoo>

View file

@ -8,13 +8,9 @@
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="arch" type="xml">
<group name="purchase" position="inside">
<field
name="origin_text"
readonly="1"
string="Origin (from Main Vendor)"
/>
</group>
<xpath expr="//field[@name='categ_id']" position="after">
<field name="origin_text" />
</xpath>
</field>
</record>
@ -34,9 +30,9 @@
<record id="product_template_tree_view_origin_text" model="ir.ui.view">
<field name="name">product.template.tree.origin.text</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product_main_seller.view_product_template_tree" />
<field name="inherit_id" ref="product.product_template_tree_view" />
<field name="arch" type="xml">
<field name="main_seller_id" position="after">
<field name="categ_id" position="after">
<field name="origin_text" optional="hide" />
</field>
</field>