chore: eliminar módulo obsoleto product_origin

Eliminado product_origin (antiguo) que ha sido reemplazado por product_origin_char.
El nuevo módulo product_origin_char usa tipo Char en vez de Selection para el campo origin.
This commit is contained in:
snt 2026-02-25 20:19:05 +01:00
parent 2a005a9d5a
commit c2f9f347b7
22 changed files with 0 additions and 1202 deletions

View file

@ -1,65 +0,0 @@
# Product Origin
## Summary
Adds an origin field to products to track where they come from (geographic origin).
## Features
- **Origin Field**: Adds a text field to store the product's origin
- **Visible in Views**: Shows in both product template and product variant forms
- **Simple Implementation**: Extends core product models
## Technical Details
### Models Extended
- `product.template`: Main product template
- `product.product`: Product variants
### Fields Added
- `origin` (Char): Text field for product origin
### Views Modified
- Product Template Form
- Product Variant Form
## Dependencies
- `product` (Odoo core)
## Installation
```bash
docker-compose exec odoo odoo -d odoo -u product_origin --stop-after-init
```
## Usage
1. Open a product form (Products > Products > [Product])
2. Find the "Origin" field
3. Enter the geographic origin (e.g., "Spain", "France", "Local")
## OCA Source
- **Repository**: [product-attribute](https://github.com/OCA/product-attribute)
- **Original Authors**: ACSONE SA/NV, GRAP
- **License**: AGPL-3
## Modifications for Kidekoop
None - Used as-is from OCA.
## Translations
- ✅ Spanish (es)
- ✅ Euskera (eu)
Located in `i18n/` directory.
---
**Version**: 18.0.1.0.0
**License**: AGPL-3

View file

@ -1,114 +0,0 @@
==============
Product Origin
==============
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2db486ad6cf453e31192b518e0e0de9647f6b65545047439e05da8bc413dc410
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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/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%2Fproduct--attribute-lightgray.png?logo=github
:target: https://github.com/OCA/product-attribute/tree/18.0/product_origin
:alt: OCA/product-attribute
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_origin
: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/product-attribute&target_branch=18.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module adds a field to associate the country and state of origin of
a product
https://en.wikipedia.org/wiki/Country_of_origin
**Table of contents**
.. contents::
:local:
Usage
=====
- Go to product form
- Fill in the country and/or state of origin of the product under the
'General Information' tab.
|image1|
.. |image1| image:: https://raw.githubusercontent.com/OCA/product-attribute/18.0/product_origin/static/description/product_form.png
Changelog
=========
10.0.1.0.0 (2019-01-11)
-----------------------
- [10.0][ADD] product_origin
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/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 <https://github.com/OCA/product-attribute/issues/new?body=module:%20product_origin%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* ACSONE SA/NV
* GRAP
Contributors
------------
- Denis Roussel <denis.roussel@acsone.eu>
- Sylvain LE GAL (https://twitter.com/legalsylvain)
- `Heliconia Solutions Pvt. Ltd. <https://www.heliconia.io>`__
- Bhavesh Heliconia
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
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.
.. |maintainer-rousseldenis| image:: https://github.com/rousseldenis.png?size=40px
:target: https://github.com/rousseldenis
:alt: rousseldenis
.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px
:target: https://github.com/legalsylvain
:alt: legalsylvain
Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-rousseldenis| |maintainer-legalsylvain|
This module is part of the `OCA/product-attribute <https://github.com/OCA/product-attribute/tree/18.0/product_origin>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -1 +0,0 @@
from . import models

View file

@ -1,18 +0,0 @@
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Product Origin",
"summary": """Adds the origin of the product""",
"version": "18.0.1.0.0",
"license": "AGPL-3",
"development_status": "Beta",
"author": "ACSONE SA/NV,GRAP,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/product-attribute",
"maintainers": ["rousseldenis", "legalsylvain"],
"depends": ["product"],
"data": [
"views/product_product.xml",
"views/product_template.xml",
],
}

View file

@ -1,72 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_origin
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-11 13:46+0000\n"
"PO-Revision-Date: 2024-01-11 13:46+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id
msgid "Country State of Origin"
msgstr "Région de fabrication"
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__country_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__country_id
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_search_view
msgid "Country of Origin"
msgstr "Pays de fabrication"
#. module: product_origin
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_form_view
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form_variant
msgid "Origin"
msgstr "Origine"
#. module: product_origin
#: model:ir.model,name:product_origin.model_product_template
msgid "Product"
msgstr "Produit"
#. module: product_origin
#: model:ir.model,name:product_origin.model_product_product
msgid "Product Variant"
msgstr "Variante de produit"
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id_domain
msgid "State Id Domain"
msgstr ""
#. module: product_origin
#: model:ir.model.fields,help:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,help:product_origin.field_product_template__state_id_domain
msgid ""
"Technical field, used to compute dynamically state domain depending on the "
"country."
msgstr ""
"Champ technique, utilisé pour calculer dynamiquement le domaine de l'état, "
"en fonction du pays."
#. module: product_origin
#. odoo-python
#: code:addons/product_origin/models/product_product.py:0
#: code:addons/product_origin/models/product_template.py:0
#, python-format
msgid ""
"The state '%(state_name)s' doesn't belong to the country '%(country_name)s'"
msgstr "La région '%(state_name)s' n'appartient pas au pays '%(country_name)s'"

View file

@ -1,73 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_origin
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-05-22 17:37+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id
msgid "Country State of Origin"
msgstr "Nazione paese di orgine"
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__country_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__country_id
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_search_view
msgid "Country of Origin"
msgstr "Paese di origine"
#. module: product_origin
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_form_view
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form_variant
msgid "Origin"
msgstr "Origine"
#. module: product_origin
#: model:ir.model,name:product_origin.model_product_template
msgid "Product"
msgstr "Prodotto"
#. module: product_origin
#: model:ir.model,name:product_origin.model_product_product
msgid "Product Variant"
msgstr "Variante prodotto"
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id_domain
msgid "State Id Domain"
msgstr "Dominio ID stato"
#. module: product_origin
#: model:ir.model.fields,help:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,help:product_origin.field_product_template__state_id_domain
msgid ""
"Technical field, used to compute dynamically state domain depending on the "
"country."
msgstr ""
"Campo tecnico, utilizzato per calcolare dinamicamente il dominio dello stato "
"in funzione della nazione."
#. module: product_origin
#. odoo-python
#: code:addons/product_origin/models/product_product.py:0
#: code:addons/product_origin/models/product_template.py:0
#, python-format
msgid ""
"The state '%(state_name)s' doesn't belong to the country '%(country_name)s'"
msgstr ""
"Lo stato '%(state_name)s' non appartiene alla nazione '%(country_name)s'"

View file

@ -1,66 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_origin
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id
msgid "Country State of Origin"
msgstr ""
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__country_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__country_id
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_search_view
msgid "Country of Origin"
msgstr ""
#. module: product_origin
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_form_view
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form_variant
msgid "Origin"
msgstr ""
#. module: product_origin
#: model:ir.model,name:product_origin.model_product_template
msgid "Product"
msgstr ""
#. module: product_origin
#: model:ir.model,name:product_origin.model_product_product
msgid "Product Variant"
msgstr ""
#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id_domain
msgid "State Id Domain"
msgstr ""
#. module: product_origin
#: model:ir.model.fields,help:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,help:product_origin.field_product_template__state_id_domain
msgid ""
"Technical field, used to compute dynamically state domain depending on the "
"country."
msgstr ""
#. module: product_origin
#. odoo-python
#: code:addons/product_origin/models/product_product.py:0
#: code:addons/product_origin/models/product_template.py:0
msgid ""
"The state '%(state_name)s' doesn't belong to the country '%(country_name)s'"
msgstr ""

View file

@ -1,2 +0,0 @@
from . import product_product
from . import product_template

View file

@ -1,60 +0,0 @@
# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api
from odoo import fields
from odoo import models
from odoo.exceptions import ValidationError
class ProductProduct(models.Model):
_inherit = "product.product"
country_id = fields.Many2one(
comodel_name="res.country",
string="Country of Origin",
ondelete="restrict",
)
state_id = fields.Many2one(
comodel_name="res.country.state",
string="Country State of Origin",
ondelete="restrict",
)
state_id_domain = fields.Binary(
compute="_compute_state_id_domain",
help="Technical field, used to compute dynamically state domain"
" depending on the country.",
)
@api.constrains("country_id", "state_id")
def _check_country_id_state_id(self):
for product in self.filtered(lambda x: x.state_id and x.country_id):
if product.country_id != product.state_id.country_id:
raise ValidationError(
self.env._(
"The state '%(state_name)s' doesn't belong to"
" the country '%(country_name)s'",
state_name=product.state_id.name,
country_name=product.country_id.name,
)
)
@api.onchange("country_id")
def onchange_country_id(self):
if self.state_id and self.state_id.country_id != self.country_id:
self.state_id = False
@api.onchange("state_id")
def onchange_state_id(self):
if self.state_id:
self.country_id = self.state_id.country_id
@api.depends("country_id")
def _compute_state_id_domain(self):
for product in self.filtered(lambda x: x.country_id):
product.state_id_domain = [("country_id", "=", product.country_id.id)]
for product in self.filtered(lambda x: not x.country_id):
product.state_id_domain = []

View file

@ -1,95 +0,0 @@
# Copyright 2018 ACSONE SA/NV
# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api
from odoo import fields
from odoo import models
from odoo.exceptions import ValidationError
class ProductTemplate(models.Model):
_inherit = "product.template"
country_id = fields.Many2one(
comodel_name="res.country",
compute="_compute_country_id",
inverse="_inverse_country_id",
string="Country of Origin",
store=True,
)
state_id = fields.Many2one(
comodel_name="res.country.state",
compute="_compute_state_id",
inverse="_inverse_state_id",
string="Country State of Origin",
store=True,
)
state_id_domain = fields.Binary(
compute="_compute_state_id_domain",
help="Technical field, used to compute dynamically state domain"
" depending on the country.",
)
@api.onchange("country_id")
def onchange_country_id(self):
if self.state_id and self.state_id.country_id != self.country_id:
self.state_id = False
@api.onchange("state_id")
def onchange_state_id(self):
if self.state_id:
self.country_id = self.state_id.country_id
@api.constrains("country_id", "state_id")
def _check_country_id_state_id(self):
for template in self.filtered(lambda x: x.state_id and x.country_id):
if template.country_id != template.state_id.country_id:
raise ValidationError(
self.env._(
"The state '%(state_name)s' doesn't belong to"
" the country '%(country_name)s'",
state_name=template.state_id.name,
country_name=template.country_id.name,
)
)
@api.depends("product_variant_ids", "product_variant_ids.country_id")
def _compute_country_id(self):
for template in self:
if template.product_variant_count == 1:
template.country_id = template.product_variant_ids.country_id
else:
template.country_id = False
def _inverse_country_id(self):
for template in self:
if len(template.product_variant_ids) == 1:
template.product_variant_ids.country_id = template.country_id
@api.depends("product_variant_ids", "product_variant_ids.state_id")
def _compute_state_id(self):
for template in self:
if template.product_variant_count == 1:
template.state_id = template.product_variant_ids.state_id
else:
template.state_id = False
@api.depends("country_id")
def _compute_state_id_domain(self):
for template in self.filtered(lambda x: x.country_id):
template.state_id_domain = [("country_id", "=", template.country_id.id)]
for template in self.filtered(lambda x: not x.country_id):
template.state_id_domain = []
def _inverse_state_id(self):
for template in self:
if len(template.product_variant_ids) == 1:
template.product_variant_ids.country_id = template.country_id
def _get_related_fields_variant_template(self):
res = super()._get_related_fields_variant_template()
res += ["country_id", "state_id"]
return res

View file

@ -1,3 +0,0 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View file

@ -1,4 +0,0 @@
- Denis Roussel \<<denis.roussel@acsone.eu>\>
- Sylvain LE GAL (<https://twitter.com/legalsylvain>)
- [Heliconia Solutions Pvt. Ltd.](https://www.heliconia.io)
- Bhavesh Heliconia

View file

@ -1,4 +0,0 @@
This module adds a field to associate the country and state of origin of
a product
<https://en.wikipedia.org/wiki/Country_of_origin>

View file

@ -1,3 +0,0 @@
## 10.0.1.0.0 (2019-01-11)
- \[10.0\]\[ADD\] product_origin

View file

@ -1,5 +0,0 @@
- Go to product form
- Fill in the country and/or state of origin of the product under the
'General Information' tab.
![](../static/description/product_form.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -1,456 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Product Origin</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="product-origin">
<h1 class="title">Product Origin</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2db486ad6cf453e31192b518e0e0de9647f6b65545047439e05da8bc413dc410
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/product-attribute/tree/18.0/product_origin"><img alt="OCA/product-attribute" src="https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_origin"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/product-attribute&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module adds a field to associate the country and state of origin of
a product</p>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Country_of_origin">https://en.wikipedia.org/wiki/Country_of_origin</a></p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-2">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-3">10.0.1.0.0 (2019-01-11)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<ul class="simple">
<li>Go to product form</li>
<li>Fill in the country and/or state of origin of the product under the
General Information tab.</li>
</ul>
<p><img alt="image1" src="https://raw.githubusercontent.com/OCA/product-attribute/18.0/product_origin/static/description/product_form.png" /></p>
</div>
<div class="section" id="changelog">
<h1><a class="toc-backref" href="#toc-entry-2">Changelog</a></h1>
<div class="section" id="section-1">
<h2><a class="toc-backref" href="#toc-entry-3">10.0.1.0.0 (2019-01-11)</a></h2>
<ul class="simple">
<li>[10.0][ADD] product_origin</li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/product-attribute/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/product-attribute/issues/new?body=module:%20product_origin%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
<ul class="simple">
<li>ACSONE SA/NV</li>
<li>GRAP</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<ul class="simple">
<li>Denis Roussel &lt;<a class="reference external" href="mailto:denis.roussel&#64;acsone.eu">denis.roussel&#64;acsone.eu</a>&gt;</li>
<li>Sylvain LE GAL (<a class="reference external" href="https://twitter.com/legalsylvain">https://twitter.com/legalsylvain</a>)</li>
<li><a class="reference external" href="https://www.heliconia.io">Heliconia Solutions Pvt. Ltd.</a><ul>
<li>Bhavesh Heliconia</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>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.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainers</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/rousseldenis"><img alt="rousseldenis" src="https://github.com/rousseldenis.png?size=40px" /></a> <a class="reference external image-reference" href="https://github.com/legalsylvain"><img alt="legalsylvain" src="https://github.com/legalsylvain.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/product-attribute/tree/18.0/product_origin">OCA/product-attribute</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

View file

@ -1 +0,0 @@
from . import test_module

View file

@ -1,86 +0,0 @@
# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.exceptions import ValidationError
from odoo.addons.base.tests.common import BaseCommon
class TestModule(BaseCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.country_us = cls.env.ref("base.us")
cls.state_tarapaca = cls.env.ref("base.state_cl_01")
cls.state_us = cls.env.ref("base.state_us_1")
cls.country_chile = cls.env.ref("base.cl")
def test_product_product(self):
self._test_compute_and_constrains(self.env["product.product"])
self._test_onchange_methods(self.env["product.product"])
def test_product_template(self):
self._test_compute_and_constrains(self.env["product.template"])
self._test_onchange_methods(self.env["product.template"])
def _test_compute_and_constrains(self, model):
# Set state should set country
product = model.create({"name": "Test Name"})
self.assertEqual(product.state_id_domain, [])
product.country_id = self.country_us
self.assertEqual(
product.state_id_domain, [("country_id", "=", self.country_us.id)]
)
with self.assertRaises(ValidationError):
product.state_id = self.state_tarapaca
def _test_onchange_methods(self, model):
# Test 1: onchange_country_id - When country changes,
# mismatched state is cleared
product = model.create({"name": "Test Onchange"})
# Set state first
product.state_id = self.state_us
# Set matching country
product.country_id = self.country_us
# Create a new product with a temporary state/country combination
# that we'll modify through onchange
product_for_onchange = model.new(
{
"name": "Test Onchange Product",
"state_id": self.state_us.id,
"country_id": self.country_us.id,
}
)
# Verify initial state
self.assertEqual(product_for_onchange.state_id.id, self.state_us.id)
self.assertEqual(product_for_onchange.country_id.id, self.country_us.id)
# Change country and trigger onchange
product_for_onchange.country_id = self.country_chile
product_for_onchange.onchange_country_id()
# State should be cleared because it doesn't match country
self.assertFalse(product_for_onchange.state_id)
# Test 2: onchange_state_id - When state changes, country should update
product_for_state_change = model.new(
{
"name": "Test Onchange State",
}
)
# Initially no country
self.assertFalse(product_for_state_change.country_id)
# Set state and trigger onchange
product_for_state_change.state_id = self.state_us
product_for_state_change.onchange_state_id()
# Country should be set to match state's country
self.assertEqual(product_for_state_change.country_id.id, self.country_us.id)

View file

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright (C) 2023 - Today: GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<odoo>
<record id="view_product_product_form" model="ir.ui.view">
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='group_lots_and_weight']" position="after">
<group string="Origin" name="group_origin">
<field name="country_id" />
<field name="state_id_domain" invisible="1" />
<field name="state_id" domain="state_id_domain" />
</group>
</xpath>
</field>
</record>
<record id="view_product_product_form_variant" model="ir.ui.view">
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_variant_easy_edit_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='weight']" position="after">
<group string="Origin" name="group_origin">
<field name="country_id" />
<field name="state_id_domain" invisible="1" />
<field name="state_id" domain="state_id_domain" />
</group>
</xpath>
</field>
</record>
</odoo>

View file

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2018 ACSONE SA/NV
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="product_template_form_view">
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='group_lots_and_weight']" position="after">
<group
string="Origin"
name="group_origin"
invisible="product_variant_count > 1"
>
<field name="country_id" />
<field name="state_id_domain" invisible="1" />
<field name="state_id" domain="state_id_domain" />
</group>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="product_template_search_view">
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_search_view" />
<field name="arch" type="xml">
<filter name="favorites" position="before">
<field name="country_id" />
</filter>
<filter name="categ_id" position="after">
<filter
string="Country of Origin"
name="country_id"
context="{'group_by':'country_id'}"
/>
</filter>
</field>
</record>
</odoo>