[ADD] product_origin_char: Free text origin field per supplier
New addon to replace structured country/state fields with flexible free-text origin descriptions. Features: - Translatable origin_text field in product.supplierinfo - Computed origin field in products based on main_seller_id - Support for creative supplier origin descriptions - Full OCA documentation structure - ES/EU translations included - 8 unit tests (all passing) Replaces product_origin for use cases where suppliers use non-standardized origin descriptions (e.g., 'Valencia, Spain', 'Huerta de...', etc.) Depends on: product, product_main_seller Author: Criptomart Funding: Elika Bilbo
This commit is contained in:
parent
1a8f92a01e
commit
c8b83cc333
24 changed files with 1071 additions and 0 deletions
6
product_origin_char/models/__init__.py
Normal file
6
product_origin_char/models/__init__.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# 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
|
||||
30
product_origin_char/models/product_product.py
Normal file
30
product_origin_char/models/product_product.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# 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
|
||||
|
||||
|
||||
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",
|
||||
)
|
||||
|
||||
@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
|
||||
15
product_origin_char/models/product_supplierinfo.py
Normal file
15
product_origin_char/models/product_supplierinfo.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# 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.)",
|
||||
)
|
||||
30
product_origin_char/models/product_template.py
Normal file
30
product_origin_char/models/product_template.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# 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
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = "product.template"
|
||||
|
||||
origin_text = fields.Char(
|
||||
string="Origin",
|
||||
compute="_compute_origin_text",
|
||||
store=False,
|
||||
help="Origin text from main vendor's supplierinfo",
|
||||
)
|
||||
|
||||
@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
|
||||
Loading…
Add table
Add a link
Reference in a new issue