From aa9ab28c943d9ddf6f9f450ba7b2e182b5aa2679 Mon Sep 17 00:00:00 2001
From: Antonio Yamuta
Date: Tue, 12 Jun 2018 08:43:01 -0700
Subject: [PATCH 001/224] [11.0] product_internal_reference_mandatory (#334)
* [ADD] Module to set the internal reference of the product as required.
---
product_code_mandatory/README.rst | 66 ++++++++++++++++++
product_code_mandatory/__init__.py | 16 +++++
product_code_mandatory/__manifest__.py | 19 +++++
.../i18n/product_code_mandatory.pot | 20 ++++++
product_code_mandatory/models/__init__.py | 4 ++
product_code_mandatory/models/product.py | 15 ++++
.../static/description/icon.png | Bin 0 -> 9455 bytes
.../views/product_code_seq.xml | 11 +++
product_code_mandatory/views/product_view.xml | 26 +++++++
9 files changed, 177 insertions(+)
create mode 100644 product_code_mandatory/README.rst
create mode 100644 product_code_mandatory/__init__.py
create mode 100644 product_code_mandatory/__manifest__.py
create mode 100644 product_code_mandatory/i18n/product_code_mandatory.pot
create mode 100644 product_code_mandatory/models/__init__.py
create mode 100644 product_code_mandatory/models/product.py
create mode 100644 product_code_mandatory/static/description/icon.png
create mode 100644 product_code_mandatory/views/product_code_seq.xml
create mode 100644 product_code_mandatory/views/product_view.xml
diff --git a/product_code_mandatory/README.rst b/product_code_mandatory/README.rst
new file mode 100644
index 00000000000..e264aaeb221
--- /dev/null
+++ b/product_code_mandatory/README.rst
@@ -0,0 +1,66 @@
+.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+
+======================
+Product Code Mandatory
+======================
+
+This module sets the field internal reference (default_code) of the product
+as required.
+
+Usage
+=====
+
+* Unable to save a product with an empty or blank internal reference.
+* When creating more than one product variant from the template, a variant will be created
+ with a default value for default_code field.
+* A pre_init_hook process is initiated when there exist records without an internal reference(default_code).
+ A default value is generated to populate empty field as a temporary value.
+
+.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
+ :alt: Try me on Runbot
+ :target: https://runbot.odoo-community.org/runbot/135/11.0
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues
+`_. In case of trouble, please
+check there if your issue has already been reported. If you spotted it first,
+help us smash it by providing detailed and welcomed feedback.
+
+Credits
+=======
+
+Images
+------
+
+* Odoo Community Association: `Icon `_.
+
+Contributors
+------------
+
+* Antonio Yamuta
+
+Funders
+-------
+
+The development of this module has been financially supported by:
+
+* Open Source Integrators
+
+Maintainer
+----------
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+This module is maintained by the OCA.
+
+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.
+
+To contribute to this module, please visit https://odoo-community.org.
diff --git a/product_code_mandatory/__init__.py b/product_code_mandatory/__init__.py
new file mode 100644
index 00000000000..c1430458d08
--- /dev/null
+++ b/product_code_mandatory/__init__.py
@@ -0,0 +1,16 @@
+# Copyright (C) 2018 - TODAY, Open Source Integrators
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from . import models
+
+
+def pre_init_product_code(cr):
+ cr.execute("""UPDATE product_template
+ SET default_code = 'DEFAULT' || nextval('ir_default_id_seq')
+ WHERE default_code is NULL
+ OR LENGTH(default_code) = 0""")
+ cr.execute("""UPDATE product_product
+ SET default_code = 'DEFAULT' || nextval('ir_default_id_seq')
+ WHERE default_code is NULL
+ OR LENGTH(default_code) = 0""")
+ return True
diff --git a/product_code_mandatory/__manifest__.py b/product_code_mandatory/__manifest__.py
new file mode 100644
index 00000000000..17c8541bbb7
--- /dev/null
+++ b/product_code_mandatory/__manifest__.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2018 - TODAY, Open Source Integrators
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ "name": "Product Internal Reference as Required",
+ "summary": "Set Product Internal Reference as a required field",
+ "version": "11.0.1.0.0",
+ "license": "AGPL-3",
+ "author": "Open Source Integrators, Odoo Community Association (OCA)",
+ "category": "Product",
+ "website": "http://www.opensourceintegrators.com",
+ "depends": ["product"],
+ "data": [
+ "views/product_view.xml",
+ "views/product_code_seq.xml",
+ ],
+ "pre_init_hook": 'pre_init_product_code',
+ "installable": True,
+}
diff --git a/product_code_mandatory/i18n/product_code_mandatory.pot b/product_code_mandatory/i18n/product_code_mandatory.pot
new file mode 100644
index 00000000000..f67715231d5
--- /dev/null
+++ b/product_code_mandatory/i18n/product_code_mandatory.pot
@@ -0,0 +1,20 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * product_code_mandatory
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 11.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_code_mandatory
+#: model:ir.model,name:product_code_mandatory.model_product_product
+msgid "Product"
+msgstr ""
+
diff --git a/product_code_mandatory/models/__init__.py b/product_code_mandatory/models/__init__.py
new file mode 100644
index 00000000000..e2434221bf7
--- /dev/null
+++ b/product_code_mandatory/models/__init__.py
@@ -0,0 +1,4 @@
+# Copyright (C) 2018 - TODAY, Open Source Integrators License AGPL-3.0
+# or later (http://www.gnu.org/licenses/agpl).
+
+from . import product
diff --git a/product_code_mandatory/models/product.py b/product_code_mandatory/models/product.py
new file mode 100644
index 00000000000..1314f7a61ea
--- /dev/null
+++ b/product_code_mandatory/models/product.py
@@ -0,0 +1,15 @@
+# Copyright (C) 2018 - TODAY, Open Source Integrators License AGPL-3.0
+# or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class ProductProduct(models.Model):
+ _inherit = 'product.product'
+
+ def _get_default_code(self):
+ res = self.env['ir.sequence'].next_by_code('product.default.code')
+ return res
+
+ default_code = fields.Char('Internal Reference', index=True,
+ default=_get_default_code)
diff --git a/product_code_mandatory/static/description/icon.png b/product_code_mandatory/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d
GIT binary patch
literal 9455
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
z
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
Xviia!U7SGha1wx#SCgwmn*{w2TRX*I
literal 0
HcmV?d00001
diff --git a/product_code_mandatory/views/product_code_seq.xml b/product_code_mandatory/views/product_code_seq.xml
new file mode 100644
index 00000000000..224fa46d933
--- /dev/null
+++ b/product_code_mandatory/views/product_code_seq.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ Productc Default Code Mandatory
+ product.default.code
+ DEFAULT-
+ 4
+
+
+
diff --git a/product_code_mandatory/views/product_view.xml b/product_code_mandatory/views/product_view.xml
new file mode 100644
index 00000000000..d01729f1fb8
--- /dev/null
+++ b/product_code_mandatory/views/product_view.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ product.template.only.form.code.mandatory.view
+ product.template
+
+
+
+ {'invisible': [('product_variant_count', '>', 1)],
+ 'required': [('product_variant_count', '=', 1)]}
+
+
+
+
+
+ product.normal.form.code.mandatory.view
+ product.product
+
+
+
+ True
+
+
+
+
From ef358a0c1764e1609e4d702dafd27906c2fe9022 Mon Sep 17 00:00:00 2001
From: Sudhir Arya
Date: Tue, 4 Dec 2018 12:18:06 +0530
Subject: [PATCH 002/224] [MIG] Migrated product_code_mandatory to v12
---
product_code_mandatory/README.rst | 78 ++--
product_code_mandatory/__init__.py | 3 -
product_code_mandatory/__manifest__.py | 10 +-
.../{views => data}/product_code_seq.xml | 5 +-
.../i18n/product_code_mandatory.pot | 12 +-
product_code_mandatory/models/__init__.py | 3 -
product_code_mandatory/models/product.py | 3 +-
.../readme/CONTRIBUTORS.rst | 2 +
product_code_mandatory/readme/DESCRIPTION.rst | 2 +
product_code_mandatory/readme/USAGE.rst | 9 +
.../static/description/index.html | 433 ++++++++++++++++++
product_code_mandatory/tests/__init__.py | 1 +
.../tests/test_product_code.py | 17 +
product_code_mandatory/views/product_view.xml | 17 +-
14 files changed, 544 insertions(+), 51 deletions(-)
rename product_code_mandatory/{views => data}/product_code_seq.xml (72%)
create mode 100644 product_code_mandatory/readme/CONTRIBUTORS.rst
create mode 100644 product_code_mandatory/readme/DESCRIPTION.rst
create mode 100644 product_code_mandatory/readme/USAGE.rst
create mode 100644 product_code_mandatory/static/description/index.html
create mode 100644 product_code_mandatory/tests/__init__.py
create mode 100644 product_code_mandatory/tests/test_product_code.py
diff --git a/product_code_mandatory/README.rst b/product_code_mandatory/README.rst
index e264aaeb221..1f61b0b1605 100644
--- a/product_code_mandatory/README.rst
+++ b/product_code_mandatory/README.rst
@@ -1,66 +1,88 @@
-.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
+======================================
+Product Internal Reference as Required
+======================================
+
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |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
-
-======================
-Product Code Mandatory
-======================
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github
+ :target: https://github.com/OCA/product-attribute/tree/12.0/product_code_mandatory
+ :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-12-0/product-attribute-12-0-product_code_mandatory
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/135/12.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
This module sets the field internal reference (default_code) of the product
as required.
+**Table of contents**
+
+.. contents::
+ :local:
+
Usage
=====
* Unable to save a product with an empty or blank internal reference.
* When creating more than one product variant from the template, a variant will be created
- with a default value for default_code field.
+ with a default value for default_code field.
* A pre_init_hook process is initiated when there exist records without an internal reference(default_code).
A default value is generated to populate empty field as a temporary value.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
- :target: https://runbot.odoo-community.org/runbot/135/11.0
+ :target: https://runbot.odoo-community.org/runbot/135/12.0
Bug Tracker
===========
-Bugs are tracked on `GitHub Issues
-`_. In case of trouble, please
-check there if your issue has already been reported. If you spotted it first,
-help us smash it by providing detailed and welcomed feedback.
+Bugs are tracked on `GitHub Issues `_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+`feedback `_.
+
+Do not contact contributors directly about support or help with technical issues.
Credits
=======
-Images
-------
+Authors
+~~~~~~~
-* Odoo Community Association: `Icon `_.
+* Open Source Integrators
Contributors
-------------
+~~~~~~~~~~~~
* Antonio Yamuta
+* Sudhir Arya
-Funders
--------
-
-The development of this module has been financially supported by:
+Maintainers
+~~~~~~~~~~~
-* Open Source Integrators
-
-Maintainer
-----------
+This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
- :alt: Odoo Community Association
- :target: https://odoo-community.org
-
-This module is maintained by the OCA.
+ :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.
-To contribute to this module, please visit https://odoo-community.org.
+This module is part of the `OCA/product-attribute `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/product_code_mandatory/__init__.py b/product_code_mandatory/__init__.py
index c1430458d08..98feeb03b6c 100644
--- a/product_code_mandatory/__init__.py
+++ b/product_code_mandatory/__init__.py
@@ -1,6 +1,3 @@
-# Copyright (C) 2018 - TODAY, Open Source Integrators
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
from . import models
diff --git a/product_code_mandatory/__manifest__.py b/product_code_mandatory/__manifest__.py
index 17c8541bbb7..bfdc375d3fb 100644
--- a/product_code_mandatory/__manifest__.py
+++ b/product_code_mandatory/__manifest__.py
@@ -4,15 +4,17 @@
{
"name": "Product Internal Reference as Required",
"summary": "Set Product Internal Reference as a required field",
- "version": "11.0.1.0.0",
+ "version": "12.0.1.0.0",
"license": "AGPL-3",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
"category": "Product",
- "website": "http://www.opensourceintegrators.com",
- "depends": ["product"],
+ "website": "https://github.com/OCA/product-attribute",
+ "depends": [
+ "product",
+ ],
"data": [
+ "data/product_code_seq.xml",
"views/product_view.xml",
- "views/product_code_seq.xml",
],
"pre_init_hook": 'pre_init_product_code',
"installable": True,
diff --git a/product_code_mandatory/views/product_code_seq.xml b/product_code_mandatory/data/product_code_seq.xml
similarity index 72%
rename from product_code_mandatory/views/product_code_seq.xml
rename to product_code_mandatory/data/product_code_seq.xml
index 224fa46d933..95121f4a751 100644
--- a/product_code_mandatory/views/product_code_seq.xml
+++ b/product_code_mandatory/data/product_code_seq.xml
@@ -1,11 +1,12 @@
-
+
- Productc Default Code Mandatory
+ Product Default Code Mandatory
product.default.code
DEFAULT-
4
+
diff --git a/product_code_mandatory/i18n/product_code_mandatory.pot b/product_code_mandatory/i18n/product_code_mandatory.pot
index f67715231d5..e29d9a5a846 100644
--- a/product_code_mandatory/i18n/product_code_mandatory.pot
+++ b/product_code_mandatory/i18n/product_code_mandatory.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 11.0\n"
+"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
@@ -13,8 +13,18 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
+msgid "Internal Reference"
+msgstr ""
+
#. module: product_code_mandatory
#: model:ir.model,name:product_code_mandatory.model_product_product
msgid "Product"
msgstr ""
+#. module: product_code_mandatory
+#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
+msgid "Set to '/' and save if you want a new internal reference to be proposed."
+msgstr ""
+
diff --git a/product_code_mandatory/models/__init__.py b/product_code_mandatory/models/__init__.py
index e2434221bf7..9649db77a15 100644
--- a/product_code_mandatory/models/__init__.py
+++ b/product_code_mandatory/models/__init__.py
@@ -1,4 +1 @@
-# Copyright (C) 2018 - TODAY, Open Source Integrators License AGPL-3.0
-# or later (http://www.gnu.org/licenses/agpl).
-
from . import product
diff --git a/product_code_mandatory/models/product.py b/product_code_mandatory/models/product.py
index 1314f7a61ea..e8f59b0a4f8 100644
--- a/product_code_mandatory/models/product.py
+++ b/product_code_mandatory/models/product.py
@@ -8,8 +8,7 @@ class ProductProduct(models.Model):
_inherit = 'product.product'
def _get_default_code(self):
- res = self.env['ir.sequence'].next_by_code('product.default.code')
- return res
+ return self.env['ir.sequence'].next_by_code('product.default.code')
default_code = fields.Char('Internal Reference', index=True,
default=_get_default_code)
diff --git a/product_code_mandatory/readme/CONTRIBUTORS.rst b/product_code_mandatory/readme/CONTRIBUTORS.rst
new file mode 100644
index 00000000000..bfde52f3cc0
--- /dev/null
+++ b/product_code_mandatory/readme/CONTRIBUTORS.rst
@@ -0,0 +1,2 @@
+* Antonio Yamuta
+* Sudhir Arya
diff --git a/product_code_mandatory/readme/DESCRIPTION.rst b/product_code_mandatory/readme/DESCRIPTION.rst
new file mode 100644
index 00000000000..2c500712643
--- /dev/null
+++ b/product_code_mandatory/readme/DESCRIPTION.rst
@@ -0,0 +1,2 @@
+This module sets the field internal reference (default_code) of the product
+as required.
diff --git a/product_code_mandatory/readme/USAGE.rst b/product_code_mandatory/readme/USAGE.rst
new file mode 100644
index 00000000000..adb3cce07ca
--- /dev/null
+++ b/product_code_mandatory/readme/USAGE.rst
@@ -0,0 +1,9 @@
+* Unable to save a product with an empty or blank internal reference.
+* When creating more than one product variant from the template, a variant will be created
+ with a default value for default_code field.
+* A pre_init_hook process is initiated when there exist records without an internal reference(default_code).
+ A default value is generated to populate empty field as a temporary value.
+
+.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
+ :alt: Try me on Runbot
+ :target: https://runbot.odoo-community.org/runbot/135/12.0
diff --git a/product_code_mandatory/static/description/index.html b/product_code_mandatory/static/description/index.html
new file mode 100644
index 00000000000..649f33bf581
--- /dev/null
+++ b/product_code_mandatory/static/description/index.html
@@ -0,0 +1,433 @@
+
+
+
+
+
+
+Product Internal Reference as Required
+
+
+
+
+
Product Internal Reference as Required
+
+
+

+
This module sets the field internal reference (default_code) of the product
+as required.
+
Table of contents
+
+
+
+
+- Unable to save a product with an empty or blank internal reference.
+- When creating more than one product variant from the template, a variant will be created
+with a default value for default_code field.
+- A pre_init_hook process is initiated when there exist records without an internal reference(default_code).
+A default value is generated to populate empty field as a temporary value.
+
+

+
+
+
+
Bugs are tracked on GitHub Issues.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+feedback.
+
Do not contact contributors directly about support or help with technical issues.
+
+
+
+
+
+
+- Open Source Integrators
+
+
+
+
+
+
This module is maintained by the OCA.
+

+
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.
+
This module is part of the OCA/product-attribute project on GitHub.
+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
+
+
+
+
+
diff --git a/product_code_mandatory/tests/__init__.py b/product_code_mandatory/tests/__init__.py
new file mode 100644
index 00000000000..fd357bf2801
--- /dev/null
+++ b/product_code_mandatory/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_product_code
diff --git a/product_code_mandatory/tests/test_product_code.py b/product_code_mandatory/tests/test_product_code.py
new file mode 100644
index 00000000000..c9fb4bec296
--- /dev/null
+++ b/product_code_mandatory/tests/test_product_code.py
@@ -0,0 +1,17 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo.tests.common import TransactionCase
+
+
+class TestProductCode(TransactionCase):
+
+ def setUp(self):
+ super(TestProductCode, self).setUp()
+ self.product_model = self.env['product.product']
+ self.product = self.product_model.create({
+ 'name': 'Test Product Code',
+ })
+
+ def test_product_code(self):
+ """Check Product Code"""
+ self.assertTrue(self.product.default_code, 'Product code is not set.')
diff --git a/product_code_mandatory/views/product_view.xml b/product_code_mandatory/views/product_view.xml
index d01729f1fb8..654e6236b2a 100644
--- a/product_code_mandatory/views/product_view.xml
+++ b/product_code_mandatory/views/product_view.xml
@@ -1,26 +1,27 @@
-
+
-
+
product.template.only.form.code.mandatory.view
product.template
-
+
{'invisible': [('product_variant_count', '>', 1)],
- 'required': [('product_variant_count', '=', 1)]}
-
+ 'required': [('product_variant_count', '=', 1)]}
+
-
+
product.normal.form.code.mandatory.view
product.product
-
+
True
-
+
+
From 8844af0040a768f329a297e82781b4792489d954 Mon Sep 17 00:00:00 2001
From: Pedro Castro Silva
Date: Mon, 23 Mar 2020 12:16:55 +0000
Subject: [PATCH 003/224] Added translation using Weblate (Portuguese)
---
product_code_mandatory/i18n/pt.po | 34 +++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 product_code_mandatory/i18n/pt.po
diff --git a/product_code_mandatory/i18n/pt.po b/product_code_mandatory/i18n/pt.po
new file mode 100644
index 00000000000..3c7c2afabf2
--- /dev/null
+++ b/product_code_mandatory/i18n/pt.po
@@ -0,0 +1,34 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * product_code_mandatory
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2020-03-23 14:13+0000\n"
+"Last-Translator: Pedro Castro Silva \n"
+"Language-Team: none\n"
+"Language: pt\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 3.10\n"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
+msgid "Internal Reference"
+msgstr "Referência Interna"
+
+#. module: product_code_mandatory
+#: model:ir.model,name:product_code_mandatory.model_product_product
+msgid "Product"
+msgstr "Produto"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
+msgid "Set to '/' and save if you want a new internal reference to be proposed."
+msgstr ""
+"Defina como '/' e guarde caso pretenda que uma nova referência interna seja "
+"proposta."
From a69b7cc7d923354ece8d34ce5de589279ce97132 Mon Sep 17 00:00:00 2001
From: Jaime Arroyo
Date: Thu, 9 Jul 2020 12:46:30 +0200
Subject: [PATCH 004/224] [IMP] product_code_mandatory: black, isort, prettier
---
product_code_mandatory/__init__.py | 12 ++++++++----
product_code_mandatory/__manifest__.py | 13 ++++---------
product_code_mandatory/data/product_code_seq.xml | 6 ++----
product_code_mandatory/models/product.py | 9 +++++----
product_code_mandatory/readme/USAGE.rst | 2 +-
product_code_mandatory/tests/test_product_code.py | 9 +++------
product_code_mandatory/views/product_view.xml | 13 ++++++-------
7 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/product_code_mandatory/__init__.py b/product_code_mandatory/__init__.py
index 98feeb03b6c..1c1865a1dd0 100644
--- a/product_code_mandatory/__init__.py
+++ b/product_code_mandatory/__init__.py
@@ -2,12 +2,16 @@
def pre_init_product_code(cr):
- cr.execute("""UPDATE product_template
+ cr.execute(
+ """UPDATE product_template
SET default_code = 'DEFAULT' || nextval('ir_default_id_seq')
WHERE default_code is NULL
- OR LENGTH(default_code) = 0""")
- cr.execute("""UPDATE product_product
+ OR LENGTH(default_code) = 0"""
+ )
+ cr.execute(
+ """UPDATE product_product
SET default_code = 'DEFAULT' || nextval('ir_default_id_seq')
WHERE default_code is NULL
- OR LENGTH(default_code) = 0""")
+ OR LENGTH(default_code) = 0"""
+ )
return True
diff --git a/product_code_mandatory/__manifest__.py b/product_code_mandatory/__manifest__.py
index bfdc375d3fb..039726156b3 100644
--- a/product_code_mandatory/__manifest__.py
+++ b/product_code_mandatory/__manifest__.py
@@ -4,18 +4,13 @@
{
"name": "Product Internal Reference as Required",
"summary": "Set Product Internal Reference as a required field",
- "version": "12.0.1.0.0",
+ "version": "13.0.1.0.0",
"license": "AGPL-3",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
"category": "Product",
"website": "https://github.com/OCA/product-attribute",
- "depends": [
- "product",
- ],
- "data": [
- "data/product_code_seq.xml",
- "views/product_view.xml",
- ],
- "pre_init_hook": 'pre_init_product_code',
+ "depends": ["product"],
+ "data": ["data/product_code_seq.xml", "views/product_view.xml"],
+ "pre_init_hook": "pre_init_product_code",
"installable": True,
}
diff --git a/product_code_mandatory/data/product_code_seq.xml b/product_code_mandatory/data/product_code_seq.xml
index 95121f4a751..b388e14c240 100644
--- a/product_code_mandatory/data/product_code_seq.xml
+++ b/product_code_mandatory/data/product_code_seq.xml
@@ -1,12 +1,10 @@
-
+
-
Product Default Code Mandatory
product.default.code
DEFAULT-
4
-
+
-
diff --git a/product_code_mandatory/models/product.py b/product_code_mandatory/models/product.py
index e8f59b0a4f8..ea6415717f9 100644
--- a/product_code_mandatory/models/product.py
+++ b/product_code_mandatory/models/product.py
@@ -5,10 +5,11 @@
class ProductProduct(models.Model):
- _inherit = 'product.product'
+ _inherit = "product.product"
def _get_default_code(self):
- return self.env['ir.sequence'].next_by_code('product.default.code')
+ return self.env["ir.sequence"].next_by_code("product.default.code")
- default_code = fields.Char('Internal Reference', index=True,
- default=_get_default_code)
+ default_code = fields.Char(
+ "Internal Reference", index=True, default=_get_default_code
+ )
diff --git a/product_code_mandatory/readme/USAGE.rst b/product_code_mandatory/readme/USAGE.rst
index adb3cce07ca..e9a7b9fc7f7 100644
--- a/product_code_mandatory/readme/USAGE.rst
+++ b/product_code_mandatory/readme/USAGE.rst
@@ -1,5 +1,5 @@
* Unable to save a product with an empty or blank internal reference.
-* When creating more than one product variant from the template, a variant will be created
+* When creating more than one product variant from the template, a variant will be created
with a default value for default_code field.
* A pre_init_hook process is initiated when there exist records without an internal reference(default_code).
A default value is generated to populate empty field as a temporary value.
diff --git a/product_code_mandatory/tests/test_product_code.py b/product_code_mandatory/tests/test_product_code.py
index c9fb4bec296..6db56fce44c 100644
--- a/product_code_mandatory/tests/test_product_code.py
+++ b/product_code_mandatory/tests/test_product_code.py
@@ -4,14 +4,11 @@
class TestProductCode(TransactionCase):
-
def setUp(self):
super(TestProductCode, self).setUp()
- self.product_model = self.env['product.product']
- self.product = self.product_model.create({
- 'name': 'Test Product Code',
- })
+ self.product_model = self.env["product.product"]
+ self.product = self.product_model.create({"name": "Test Product Code"})
def test_product_code(self):
"""Check Product Code"""
- self.assertTrue(self.product.default_code, 'Product code is not set.')
+ self.assertTrue(self.product.default_code, "Product code is not set.")
diff --git a/product_code_mandatory/views/product_view.xml b/product_code_mandatory/views/product_view.xml
index 654e6236b2a..648dd282b20 100644
--- a/product_code_mandatory/views/product_view.xml
+++ b/product_code_mandatory/views/product_view.xml
@@ -1,27 +1,26 @@
-
+
-
product.template.only.form.code.mandatory.view
product.template
-
+
- {'invisible': [('product_variant_count', '>', 1)],
+ {'invisible': [('product_variant_count', '>', 1)],
'required': [('product_variant_count', '=', 1)]}
-
product.normal.form.code.mandatory.view
product.product
-
+
True
-
From 4f21f959a2035b3b60fb7b34c5309745a4c311f5 Mon Sep 17 00:00:00 2001
From: Jaime Arroyo
Date: Thu, 9 Jul 2020 12:48:25 +0200
Subject: [PATCH 005/224] [13.0][MIG] product_code_mandatory
---
product_code_mandatory/README.rst | 18 +++++++++---------
product_code_mandatory/__manifest__.py | 2 +-
.../i18n/product_code_mandatory.pot | 10 +++++-----
.../static/description/index.html | 12 ++++++------
4 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/product_code_mandatory/README.rst b/product_code_mandatory/README.rst
index 1f61b0b1605..7e5ef9ca0b5 100644
--- a/product_code_mandatory/README.rst
+++ b/product_code_mandatory/README.rst
@@ -1,6 +1,6 @@
-======================================
-Product Internal Reference as Required
-======================================
+======================
+Product Code Mandatory
+======================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
@@ -14,13 +14,13 @@ Product Internal Reference as Required
: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/12.0/product_code_mandatory
+ :target: https://github.com/OCA/product-attribute/tree/13.0/product_code_mandatory
: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-12-0/product-attribute-12-0-product_code_mandatory
+ :target: https://translation.odoo-community.org/projects/product-attribute-13-0/product-attribute-13-0-product_code_mandatory
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/135/12.0
+ :target: https://runbot.odoo-community.org/runbot/135/13.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -37,7 +37,7 @@ Usage
=====
* Unable to save a product with an empty or blank internal reference.
-* When creating more than one product variant from the template, a variant will be created
+* When creating more than one product variant from the template, a variant will be created
with a default value for default_code field.
* A pre_init_hook process is initiated when there exist records without an internal reference(default_code).
A default value is generated to populate empty field as a temporary value.
@@ -52,7 +52,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -83,6 +83,6 @@ 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.
-This module is part of the `OCA/product-attribute `_ project on GitHub.
+This module is part of the `OCA/product-attribute `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/product_code_mandatory/__manifest__.py b/product_code_mandatory/__manifest__.py
index 039726156b3..ec7d3656fc6 100644
--- a/product_code_mandatory/__manifest__.py
+++ b/product_code_mandatory/__manifest__.py
@@ -2,7 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
- "name": "Product Internal Reference as Required",
+ "name": "Product Code Mandatory",
"summary": "Set Product Internal Reference as a required field",
"version": "13.0.1.0.0",
"license": "AGPL-3",
diff --git a/product_code_mandatory/i18n/product_code_mandatory.pot b/product_code_mandatory/i18n/product_code_mandatory.pot
index e29d9a5a846..2807d2b6076 100644
--- a/product_code_mandatory/i18n/product_code_mandatory.pot
+++ b/product_code_mandatory/i18n/product_code_mandatory.pot
@@ -1,12 +1,12 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
-# * product_code_mandatory
+# * product_code_mandatory
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 12.0\n"
+"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"Last-Translator: <>\n"
+"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -25,6 +25,6 @@ msgstr ""
#. module: product_code_mandatory
#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
-msgid "Set to '/' and save if you want a new internal reference to be proposed."
+msgid ""
+"Set to '/' and save if you want a new internal reference to be proposed."
msgstr ""
-
diff --git a/product_code_mandatory/static/description/index.html b/product_code_mandatory/static/description/index.html
index 649f33bf581..1be3881f468 100644
--- a/product_code_mandatory/static/description/index.html
+++ b/product_code_mandatory/static/description/index.html
@@ -4,7 +4,7 @@
-Product Internal Reference as Required
+Product Code Mandatory
-
-
Product Internal Reference as Required
+
+
Product Code Mandatory
-

+

This module sets the field internal reference (default_code) of the product
as required.
Table of contents
@@ -399,7 +399,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback.
+
feedback.
Do not contact contributors directly about support or help with technical issues.
@@ -424,7 +424,7 @@
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.
-
This module is part of the OCA/product-attribute project on GitHub.
+
This module is part of the OCA/product-attribute project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
From 653b55399a7fd6212e408afbbd693f19da0a0002 Mon Sep 17 00:00:00 2001
From: watthanun
Date: Fri, 4 Dec 2020 17:19:59 +0700
Subject: [PATCH 006/224] [MIG] product_code_mandatory: Migration to 14.0
---
product_code_mandatory/README.rst | 11 ++++++-----
product_code_mandatory/__manifest__.py | 4 ++--
.../i18n/product_code_mandatory.pot | 17 ++++++++++++++++-
product_code_mandatory/models/product.py | 2 +-
product_code_mandatory/readme/CONTRIBUTORS.rst | 1 +
.../static/description/index.html | 7 ++++---
6 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/product_code_mandatory/README.rst b/product_code_mandatory/README.rst
index 7e5ef9ca0b5..c4a02364328 100644
--- a/product_code_mandatory/README.rst
+++ b/product_code_mandatory/README.rst
@@ -14,13 +14,13 @@ Product Code Mandatory
: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/13.0/product_code_mandatory
+ :target: https://github.com/OCA/product-attribute/tree/14.0/product_code_mandatory
: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-13-0/product-attribute-13-0-product_code_mandatory
+ :target: https://translation.odoo-community.org/projects/product-attribute-14-0/product-attribute-14-0-product_code_mandatory
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/135/13.0
+ :target: https://runbot.odoo-community.org/runbot/135/14.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -52,7 +52,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -69,6 +69,7 @@ Contributors
* Antonio Yamuta
* Sudhir Arya
+* Watthanun Khorchai
Maintainers
~~~~~~~~~~~
@@ -83,6 +84,6 @@ 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.
-This module is part of the `OCA/product-attribute `_ project on GitHub.
+This module is part of the `OCA/product-attribute `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/product_code_mandatory/__manifest__.py b/product_code_mandatory/__manifest__.py
index ec7d3656fc6..159049bbbf5 100644
--- a/product_code_mandatory/__manifest__.py
+++ b/product_code_mandatory/__manifest__.py
@@ -1,10 +1,10 @@
# Copyright (C) 2018 - TODAY, Open Source Integrators
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Product Code Mandatory",
"summary": "Set Product Internal Reference as a required field",
- "version": "13.0.1.0.0",
+ "version": "14.0.1.0.1",
"license": "AGPL-3",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
"category": "Product",
diff --git a/product_code_mandatory/i18n/product_code_mandatory.pot b/product_code_mandatory/i18n/product_code_mandatory.pot
index 2807d2b6076..da873055f4c 100644
--- a/product_code_mandatory/i18n/product_code_mandatory.pot
+++ b/product_code_mandatory/i18n/product_code_mandatory.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 13.0\n"
+"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -13,11 +13,26 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__id
+msgid "ID"
+msgstr ""
+
#. module: product_code_mandatory
#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
msgid "Internal Reference"
msgstr ""
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product____last_update
+msgid "Last Modified on"
+msgstr ""
+
#. module: product_code_mandatory
#: model:ir.model,name:product_code_mandatory.model_product_product
msgid "Product"
diff --git a/product_code_mandatory/models/product.py b/product_code_mandatory/models/product.py
index ea6415717f9..33e5f57039a 100644
--- a/product_code_mandatory/models/product.py
+++ b/product_code_mandatory/models/product.py
@@ -1,5 +1,5 @@
# Copyright (C) 2018 - TODAY, Open Source Integrators License AGPL-3.0
-# or later (http://www.gnu.org/licenses/agpl).
+# or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
diff --git a/product_code_mandatory/readme/CONTRIBUTORS.rst b/product_code_mandatory/readme/CONTRIBUTORS.rst
index bfde52f3cc0..c683f780130 100644
--- a/product_code_mandatory/readme/CONTRIBUTORS.rst
+++ b/product_code_mandatory/readme/CONTRIBUTORS.rst
@@ -1,2 +1,3 @@
* Antonio Yamuta
* Sudhir Arya
+* Watthanun Khorchai
diff --git a/product_code_mandatory/static/description/index.html b/product_code_mandatory/static/description/index.html
index 1be3881f468..08b37e2e3fa 100644
--- a/product_code_mandatory/static/description/index.html
+++ b/product_code_mandatory/static/description/index.html
@@ -367,7 +367,7 @@ Product Code Mandatory
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-

+

This module sets the field internal reference (default_code) of the product
as required.
Table of contents
@@ -399,7 +399,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback.
+feedback.
Do not contact contributors directly about support or help with technical issues.
@@ -424,7 +425,7 @@
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.
-
This module is part of the OCA/product-attribute project on GitHub.
+
This module is part of the OCA/product-attribute project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
From 2e6e13360112c3f6774874ab49eee6ee87838247 Mon Sep 17 00:00:00 2001
From: Yves Le Doeuff
Date: Sat, 10 Apr 2021 09:00:12 +0000
Subject: [PATCH 007/224] Added translation using Weblate (French)
---
product_code_mandatory/i18n/fr.po | 50 ++++++++++++++++++++++++++++
product_code_mandatory/i18n/fr_FR.po | 50 ++++++++++++++++++++++++++++
2 files changed, 100 insertions(+)
create mode 100644 product_code_mandatory/i18n/fr.po
create mode 100644 product_code_mandatory/i18n/fr_FR.po
diff --git a/product_code_mandatory/i18n/fr.po b/product_code_mandatory/i18n/fr.po
new file mode 100644
index 00000000000..7b3d4e1b893
--- /dev/null
+++ b/product_code_mandatory/i18n/fr.po
@@ -0,0 +1,50 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * product_code_mandatory
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 14.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2021-04-10 11:46+0000\n"
+"Last-Translator: Yves Le Doeuff \n"
+"Language-Team: none\n"
+"Language: fr\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.3.2\n"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__display_name
+msgid "Display Name"
+msgstr "Nom affiché"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__id
+msgid "ID"
+msgstr ""
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
+msgid "Internal Reference"
+msgstr "Référence interne"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product____last_update
+msgid "Last Modified on"
+msgstr "Dernière modification"
+
+#. module: product_code_mandatory
+#: model:ir.model,name:product_code_mandatory.model_product_product
+msgid "Product"
+msgstr "Article"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
+msgid ""
+"Set to '/' and save if you want a new internal reference to be proposed."
+msgstr ""
+"Mettez '/' et sauvegardez si vous voulez qu'une nouvelle référence vous soit "
+"proposée."
diff --git a/product_code_mandatory/i18n/fr_FR.po b/product_code_mandatory/i18n/fr_FR.po
new file mode 100644
index 00000000000..c5200207018
--- /dev/null
+++ b/product_code_mandatory/i18n/fr_FR.po
@@ -0,0 +1,50 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * product_code_mandatory
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 14.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2021-04-10 15:46+0000\n"
+"Last-Translator: Yves Le Doeuff \n"
+"Language-Team: none\n"
+"Language: fr_FR\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.3.2\n"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__display_name
+msgid "Display Name"
+msgstr "Nom affiché"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__id
+msgid "ID"
+msgstr ""
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
+msgid "Internal Reference"
+msgstr "Référence interne"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product____last_update
+msgid "Last Modified on"
+msgstr "Dernière modification"
+
+#. module: product_code_mandatory
+#: model:ir.model,name:product_code_mandatory.model_product_product
+msgid "Product"
+msgstr "Article"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
+msgid ""
+"Set to '/' and save if you want a new internal reference to be proposed."
+msgstr ""
+"Mettez '/' et sauvegardez si vous voulez qu'une nouvelle référence vous soit "
+"proposée."
From a7b12359c979a2e792fb29efad5fb313064cb7a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nedas=20=C5=BDilinskas?=
Date: Wed, 19 Jan 2022 07:41:02 +0000
Subject: [PATCH 008/224] [MIG] product_code_mandatory: Migration to 15.0
---
product_code_mandatory/README.rst | 11 +++++----
product_code_mandatory/__manifest__.py | 2 +-
.../i18n/product_code_mandatory.pot | 23 +------------------
.../readme/CONTRIBUTORS.rst | 1 +
.../static/description/index.html | 7 +++---
5 files changed, 13 insertions(+), 31 deletions(-)
diff --git a/product_code_mandatory/README.rst b/product_code_mandatory/README.rst
index c4a02364328..5349fc1e3a4 100644
--- a/product_code_mandatory/README.rst
+++ b/product_code_mandatory/README.rst
@@ -14,13 +14,13 @@ Product Code Mandatory
: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/14.0/product_code_mandatory
+ :target: https://github.com/OCA/product-attribute/tree/15.0/product_code_mandatory
: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-14-0/product-attribute-14-0-product_code_mandatory
+ :target: https://translation.odoo-community.org/projects/product-attribute-15-0/product-attribute-15-0-product_code_mandatory
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/135/14.0
+ :target: https://runbot.odoo-community.org/runbot/135/15.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -52,7 +52,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -70,6 +70,7 @@ Contributors
* Antonio Yamuta
* Sudhir Arya
* Watthanun Khorchai
+* Nedas Žilinskas
Maintainers
~~~~~~~~~~~
@@ -84,6 +85,6 @@ 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.
-This module is part of the `OCA/product-attribute `_ project on GitHub.
+This module is part of the `OCA/product-attribute `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/product_code_mandatory/__manifest__.py b/product_code_mandatory/__manifest__.py
index 159049bbbf5..3b690c0108d 100644
--- a/product_code_mandatory/__manifest__.py
+++ b/product_code_mandatory/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Product Code Mandatory",
"summary": "Set Product Internal Reference as a required field",
- "version": "14.0.1.0.1",
+ "version": "15.0.1.0.0",
"license": "AGPL-3",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
"category": "Product",
diff --git a/product_code_mandatory/i18n/product_code_mandatory.pot b/product_code_mandatory/i18n/product_code_mandatory.pot
index da873055f4c..9b3d81258c2 100644
--- a/product_code_mandatory/i18n/product_code_mandatory.pot
+++ b/product_code_mandatory/i18n/product_code_mandatory.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 14.0\n"
+"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -13,33 +13,12 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__display_name
-msgid "Display Name"
-msgstr ""
-
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__id
-msgid "ID"
-msgstr ""
-
#. module: product_code_mandatory
#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
msgid "Internal Reference"
msgstr ""
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product____last_update
-msgid "Last Modified on"
-msgstr ""
-
#. module: product_code_mandatory
#: model:ir.model,name:product_code_mandatory.model_product_product
msgid "Product"
msgstr ""
-
-#. module: product_code_mandatory
-#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
-msgid ""
-"Set to '/' and save if you want a new internal reference to be proposed."
-msgstr ""
diff --git a/product_code_mandatory/readme/CONTRIBUTORS.rst b/product_code_mandatory/readme/CONTRIBUTORS.rst
index c683f780130..21c5ea62267 100644
--- a/product_code_mandatory/readme/CONTRIBUTORS.rst
+++ b/product_code_mandatory/readme/CONTRIBUTORS.rst
@@ -1,3 +1,4 @@
* Antonio Yamuta
* Sudhir Arya
* Watthanun Khorchai
+* Nedas Žilinskas
diff --git a/product_code_mandatory/static/description/index.html b/product_code_mandatory/static/description/index.html
index 08b37e2e3fa..c3cafc938dc 100644
--- a/product_code_mandatory/static/description/index.html
+++ b/product_code_mandatory/static/description/index.html
@@ -367,7 +367,7 @@ Product Code Mandatory
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-

+

This module sets the field internal reference (default_code) of the product
as required.
Table of contents
@@ -399,7 +399,7 @@
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback.
+feedback.
Do not contact contributors directly about support or help with technical issues.
@@ -425,7 +426,7 @@
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.
-
This module is part of the OCA/product-attribute project on GitHub.
+
This module is part of the OCA/product-attribute project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
From 2067b1610a1bd774ac9e76a7c43961979df4bec6 Mon Sep 17 00:00:00 2001
From: pablontura
Date: Fri, 22 Apr 2022 08:14:55 +0000
Subject: [PATCH 009/224] Added translation using Weblate (Catalan)
---
product_code_mandatory/i18n/ca.po | 27 +++++++++++++++++++
.../i18n/product_code_mandatory.pot | 6 +++++
2 files changed, 33 insertions(+)
create mode 100644 product_code_mandatory/i18n/ca.po
diff --git a/product_code_mandatory/i18n/ca.po b/product_code_mandatory/i18n/ca.po
new file mode 100644
index 00000000000..4488d5f9ac9
--- /dev/null
+++ b/product_code_mandatory/i18n/ca.po
@@ -0,0 +1,27 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * product_code_mandatory
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 15.0\n"
+"Report-Msgid-Bugs-To: \n"
+"PO-Revision-Date: 2022-04-22 10:05+0000\n"
+"Last-Translator: pablontura \n"
+"Language-Team: none\n"
+"Language: ca\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.3.2\n"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
+msgid "Internal Reference"
+msgstr "Referència interna"
+
+#. module: product_code_mandatory
+#: model:ir.model,name:product_code_mandatory.model_product_product
+msgid "Product"
+msgstr "Producte"
diff --git a/product_code_mandatory/i18n/product_code_mandatory.pot b/product_code_mandatory/i18n/product_code_mandatory.pot
index 9b3d81258c2..784b6ca0b6b 100644
--- a/product_code_mandatory/i18n/product_code_mandatory.pot
+++ b/product_code_mandatory/i18n/product_code_mandatory.pot
@@ -22,3 +22,9 @@ msgstr ""
#: model:ir.model,name:product_code_mandatory.model_product_product
msgid "Product"
msgstr ""
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
+msgid ""
+"Set to '/' and save if you want a new internal reference to be proposed."
+msgstr ""
From 03704b7b61f21c4c639246d11b2c23edb8ef03a6 Mon Sep 17 00:00:00 2001
From: OCA Transbot
Date: Sun, 3 Jul 2022 14:40:00 +0000
Subject: [PATCH 010/224] Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.
Translation: product-attribute-15.0/product-attribute-15.0-product_code_mandatory
Translate-URL: https://translation.odoo-community.org/projects/product-attribute-15-0/product-attribute-15-0-product_code_mandatory/
---
product_code_mandatory/i18n/ca.po | 6 ++++++
product_code_mandatory/i18n/fr.po | 21 ++++++---------------
product_code_mandatory/i18n/fr_FR.po | 21 ++++++---------------
product_code_mandatory/i18n/pt.po | 5 +++--
4 files changed, 21 insertions(+), 32 deletions(-)
diff --git a/product_code_mandatory/i18n/ca.po b/product_code_mandatory/i18n/ca.po
index 4488d5f9ac9..1419f045da6 100644
--- a/product_code_mandatory/i18n/ca.po
+++ b/product_code_mandatory/i18n/ca.po
@@ -25,3 +25,9 @@ msgstr "Referència interna"
#: model:ir.model,name:product_code_mandatory.model_product_product
msgid "Product"
msgstr "Producte"
+
+#. module: product_code_mandatory
+#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
+msgid ""
+"Set to '/' and save if you want a new internal reference to be proposed."
+msgstr ""
diff --git a/product_code_mandatory/i18n/fr.po b/product_code_mandatory/i18n/fr.po
index 7b3d4e1b893..c8c9fe611a7 100644
--- a/product_code_mandatory/i18n/fr.po
+++ b/product_code_mandatory/i18n/fr.po
@@ -16,26 +16,11 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.3.2\n"
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__display_name
-msgid "Display Name"
-msgstr "Nom affiché"
-
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__id
-msgid "ID"
-msgstr ""
-
#. module: product_code_mandatory
#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
msgid "Internal Reference"
msgstr "Référence interne"
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product____last_update
-msgid "Last Modified on"
-msgstr "Dernière modification"
-
#. module: product_code_mandatory
#: model:ir.model,name:product_code_mandatory.model_product_product
msgid "Product"
@@ -48,3 +33,9 @@ msgid ""
msgstr ""
"Mettez '/' et sauvegardez si vous voulez qu'une nouvelle référence vous soit "
"proposée."
+
+#~ msgid "Display Name"
+#~ msgstr "Nom affiché"
+
+#~ msgid "Last Modified on"
+#~ msgstr "Dernière modification"
diff --git a/product_code_mandatory/i18n/fr_FR.po b/product_code_mandatory/i18n/fr_FR.po
index c5200207018..af934ded787 100644
--- a/product_code_mandatory/i18n/fr_FR.po
+++ b/product_code_mandatory/i18n/fr_FR.po
@@ -16,26 +16,11 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.3.2\n"
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__display_name
-msgid "Display Name"
-msgstr "Nom affiché"
-
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__id
-msgid "ID"
-msgstr ""
-
#. module: product_code_mandatory
#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product__default_code
msgid "Internal Reference"
msgstr "Référence interne"
-#. module: product_code_mandatory
-#: model:ir.model.fields,field_description:product_code_mandatory.field_product_product____last_update
-msgid "Last Modified on"
-msgstr "Dernière modification"
-
#. module: product_code_mandatory
#: model:ir.model,name:product_code_mandatory.model_product_product
msgid "Product"
@@ -48,3 +33,9 @@ msgid ""
msgstr ""
"Mettez '/' et sauvegardez si vous voulez qu'une nouvelle référence vous soit "
"proposée."
+
+#~ msgid "Display Name"
+#~ msgstr "Nom affiché"
+
+#~ msgid "Last Modified on"
+#~ msgstr "Dernière modification"
diff --git a/product_code_mandatory/i18n/pt.po b/product_code_mandatory/i18n/pt.po
index 3c7c2afabf2..e90e12a1fc5 100644
--- a/product_code_mandatory/i18n/pt.po
+++ b/product_code_mandatory/i18n/pt.po
@@ -1,6 +1,6 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
-# * product_code_mandatory
+# * product_code_mandatory
#
msgid ""
msgstr ""
@@ -28,7 +28,8 @@ msgstr "Produto"
#. module: product_code_mandatory
#: model:ir.model.fields,help:product_code_mandatory.field_product_product__default_code
-msgid "Set to '/' and save if you want a new internal reference to be proposed."
+msgid ""
+"Set to '/' and save if you want a new internal reference to be proposed."
msgstr ""
"Defina como '/' e guarde caso pretenda que uma nova referência interna seja "
"proposta."
From 210d3fa9aa9644435a91af3d36cecdfcf6243419 Mon Sep 17 00:00:00 2001
From: augusto-weiss
Date: Thu, 15 Sep 2022 10:56:33 -0300
Subject: [PATCH 011/224] [FIX] product_code_mandatory: align code with Odoo
way to set default code
---
product_code_mandatory/README.rst | 15 +++++---
product_code_mandatory/__init__.py | 16 ++++++--
product_code_mandatory/__manifest__.py | 2 +-
.../static/description/index.html | 38 ++++++++++---------
4 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/product_code_mandatory/README.rst b/product_code_mandatory/README.rst
index 5349fc1e3a4..11c77f4cc12 100644
--- a/product_code_mandatory/README.rst
+++ b/product_code_mandatory/README.rst
@@ -2,10 +2,13 @@
Product Code Mandatory
======================
-.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+..
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! source digest: sha256:df7bdf43dba84557746371c9915e7f7822e56daf2dfa9a50222336a573df1235
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
@@ -19,11 +22,11 @@ Product Code Mandatory
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/product-attribute-15-0/product-attribute-15-0-product_code_mandatory
:alt: Translate me on Weblate
-.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/135/15.0
- :alt: Try me on Runbot
+.. |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=15.0
+ :alt: Try me on Runboat
-|badge1| |badge2| |badge3| |badge4| |badge5|
+|badge1| |badge2| |badge3| |badge4| |badge5|
This module sets the field internal reference (default_code) of the product
as required.
@@ -51,7 +54,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
-If you spotted it first, help us smashing it by providing a detailed and welcomed
+If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback `_.
Do not contact contributors directly about support or help with technical issues.
diff --git a/product_code_mandatory/__init__.py b/product_code_mandatory/__init__.py
index 1c1865a1dd0..511066707ab 100644
--- a/product_code_mandatory/__init__.py
+++ b/product_code_mandatory/__init__.py
@@ -1,17 +1,27 @@
from . import models
+from odoo import api, SUPERUSER_ID
+
def pre_init_product_code(cr):
+ env = api.Environment(cr, SUPERUSER_ID, {})
+
cr.execute(
- """UPDATE product_template
- SET default_code = 'DEFAULT' || nextval('ir_default_id_seq')
+ """
+ SELECT product_tmpl_id from product_product
WHERE default_code is NULL
- OR LENGTH(default_code) = 0"""
+ OR LENGTH(default_code) = 0
+ GROUP BY product_tmpl_id
+ HAVING COUNT(product_tmpl_id) = 1"""
)
+ product_template_ids = [x[0] for x in cr.fetchall()]
cr.execute(
"""UPDATE product_product
SET default_code = 'DEFAULT' || nextval('ir_default_id_seq')
WHERE default_code is NULL
OR LENGTH(default_code) = 0"""
)
+
+ env["product.template"].browse(product_template_ids)._compute_default_code()
+
return True
diff --git a/product_code_mandatory/__manifest__.py b/product_code_mandatory/__manifest__.py
index 3b690c0108d..8ec22912d31 100644
--- a/product_code_mandatory/__manifest__.py
+++ b/product_code_mandatory/__manifest__.py
@@ -4,7 +4,7 @@
{
"name": "Product Code Mandatory",
"summary": "Set Product Internal Reference as a required field",
- "version": "15.0.1.0.0",
+ "version": "15.0.1.0.1",
"license": "AGPL-3",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
"category": "Product",
diff --git a/product_code_mandatory/static/description/index.html b/product_code_mandatory/static/description/index.html
index c3cafc938dc..d4c4c0c8cc0 100644
--- a/product_code_mandatory/static/description/index.html
+++ b/product_code_mandatory/static/description/index.html
@@ -1,20 +1,20 @@
-
+
-
+
Product Code Mandatory
+
+
+
+
Product Abc Classification
+
+
+

+
This modules provides the bases to build ABC analysis (or ABC classification)
+addons. These classification are used by inventory management teams to help
+identify the most important products in their portfolio and ensure they
+prioritize managing them above those less valuable.
+
Managers will create a profile with several levels (percentages) and then the
+profiled products will automatically get a corresponding level using the
+ABC classification.
+
The addon product_abc_classification_sale_stock defines a computation profile
+based on the number of sale order line delivered by product.
+
Table of contents
+
+
+
+
To use this module, you need to:
+
#. Go to Sales or Inventory menu, then to Configuration/Products/ABC Classification Profile
+and create a profile with levels, knowing that the sum of all levels in the profile
+should sum 100 and all the levels should be different.
+
#. Later you should go to product categories or product variants, and assign them a profile.
+Then the cron classification will proceed to assign to these products one of the profile’s levels.
+
NOTE: If you profile (or unprofile) a product category, then all its
+child categories and products will be profiled (or unprofiled).
+
+
+
+
Bugs are tracked on GitHub Issues.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+feedback.
+
Do not contact contributors directly about support or help with technical issues.
+
+
+
+
+
+
+- ACSONE SA/NV
+- ForgeFlow
+
+
+
+
+
+
This module is maintained by the OCA.
+

+
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.
+
This module is part of the OCA/product-attribute project on GitHub.
+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
+
+
+
+
+
diff --git a/product_abc_classification/tests/__init__.py b/product_abc_classification/tests/__init__.py
new file mode 100644
index 00000000000..8292c06ca32
--- /dev/null
+++ b/product_abc_classification/tests/__init__.py
@@ -0,0 +1,3 @@
+from . import test_abc_classification_product_level
+from . import test_abc_classification_profile
+from . import test_product
diff --git a/product_abc_classification/tests/common.py b/product_abc_classification/tests/common.py
new file mode 100644
index 00000000000..4900770fdce
--- /dev/null
+++ b/product_abc_classification/tests/common.py
@@ -0,0 +1,123 @@
+# Copyright 2021 ACSONE SA/NV
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo.tests.common import TransactionCase
+
+
+class ABCClassificationCase(TransactionCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
+ # add a fake profile_type
+ cls.ABCClassificationProfile = cls.env["abc.classification.profile"]
+ cls.ABCClassificationProfile._fields["profile_type"].selection = [
+ ("test_type", "Test Type")
+ ]
+ cls.classification_profile = cls.ABCClassificationProfile.create(
+ {"name": "Profile test", "profile_type": "test_type"}
+ )
+
+
+class ABCClassificationLevelCase(ABCClassificationCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 60,
+ "percentage_products": 40,
+ "name": "a",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 40,
+ "percentage_products": 60,
+ "name": "b",
+ },
+ ),
+ ]
+ }
+ )
+
+ levels = cls.classification_profile.level_ids
+ cls.classification_level_a = levels.filtered(lambda l: l.name == "a")
+ cls.classification_level_b = levels.filtered(lambda l: l.name == "b")
+ cls.classification_profile_bis = cls.ABCClassificationProfile.create(
+ {
+ "name": "Profile test bis",
+ "profile_type": "test_type",
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 80,
+ "percentage_products": 40,
+ "name": "a",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 20,
+ "percentage_products": 60,
+ "name": "b",
+ },
+ ),
+ ],
+ }
+ )
+ levels = cls.classification_profile_bis.level_ids
+ cls.classification_level_bis_a = levels.filtered(lambda l: l.name == "a")
+
+ cls.classification_level_bis_b = levels.filtered(lambda l: l.name == "b")
+ # create a template with one variant adn declare attributes to create
+ # an other variant on demand
+ cls.size_attr = cls.env["product.attribute"].create(
+ {
+ "name": "Size",
+ "create_variant": "no_variant",
+ "value_ids": [(0, 0, {"name": "S"}), (0, 0, {"name": "M"})],
+ }
+ )
+ cls.size_attr_value_s = cls.size_attr.value_ids[0]
+ cls.size_attr_value_m = cls.size_attr.value_ids[1]
+ cls.uom_unit = cls.env.ref("uom.product_uom_unit")
+ cls.product_template = cls.env["product.template"].create(
+ {
+ "name": "Test sized",
+ "uom_id": cls.uom_unit.id,
+ "uom_po_id": cls.uom_unit.id,
+ "attribute_line_ids": [
+ (
+ 0,
+ 0,
+ {
+ "attribute_id": cls.size_attr.id,
+ "value_ids": [(6, 0, cls.size_attr.value_ids.ids)],
+ },
+ )
+ ],
+ }
+ )
+ cls.product_product = cls.product_template.product_variant_ids
+ cls.ProductLevel = cls.env["abc.classification.product.level"]
+
+ @classmethod
+ def _create_variant(cls, size_value):
+ return cls.env["product.product"].create(
+ {
+ "product_tmpl_id": cls.product_template.id,
+ "product_template_attribute_value_ids": [(6, 0, size_value.ids)],
+ }
+ )
diff --git a/product_abc_classification/tests/test_abc_classification_product_level.py b/product_abc_classification/tests/test_abc_classification_product_level.py
new file mode 100644
index 00000000000..9b2db6df872
--- /dev/null
+++ b/product_abc_classification/tests/test_abc_classification_product_level.py
@@ -0,0 +1,363 @@
+# Copyright 2021 ACSONE SA/NV
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from psycopg2 import IntegrityError
+
+from odoo.exceptions import ValidationError
+
+from .common import ABCClassificationLevelCase
+
+
+class TestABCClassificationProductLevel(ABCClassificationLevelCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.product_1 = cls.env["product.product"].create(
+ {
+ "name": "Test 1",
+ "uom_id": cls.uom_unit.id,
+ "uom_po_id": cls.uom_unit.id,
+ }
+ )
+ cls.product_level = cls.ProductLevel.create(
+ {
+ "product_id": cls.product_product.id,
+ "computed_level_id": cls.classification_level_a.id,
+ "profile_id": cls.classification_profile.id,
+ }
+ )
+
+ @classmethod
+ def _create_product_levels(cls):
+ product_2 = cls.env["product.product"].create(
+ {
+ "name": "Test 2",
+ "uom_id": cls.uom_unit.id,
+ "uom_po_id": cls.uom_unit.id,
+ }
+ )
+
+ product_3 = cls.env["product.product"].create(
+ {
+ "name": "Test 3",
+ "uom_id": cls.uom_unit.id,
+ "uom_po_id": cls.uom_unit.id,
+ }
+ )
+ cls.ProductLevel.create(
+ {
+ "product_id": product_2.id,
+ "manual_level_id": cls.classification_level_b.id,
+ "computed_level_id": cls.classification_level_a.id,
+ "profile_id": cls.classification_profile.id,
+ }
+ )
+ cls.ProductLevel.create(
+ {
+ "product_id": product_3.id,
+ "manual_level_id": cls.classification_level_b.id,
+ "computed_level_id": cls.classification_level_a.id,
+ "profile_id": cls.classification_profile.id,
+ }
+ )
+
+ def test_00(self):
+ """
+ Test case:
+ Create a classification product level with only a computed_level_id
+ Expected result:
+ A instance is created with:
+ * the manual_level_id and level_id set
+ * flag is False since manual and computd are the same
+
+ """
+ level = self.ProductLevel.create(
+ {
+ "product_id": self.product_1.id,
+ "computed_level_id": self.classification_level_a.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+ self.assertEqual(level.manual_level_id, self.classification_level_a)
+ self.assertEqual(level.level_id, self.classification_level_a)
+ self.assertFalse(level.flag)
+
+ def test_01(self):
+ """
+ Test case:
+ Create product level with only a manual level
+
+ A creation if a product level is created without computed value
+ the computed value is never taken into account
+ Expected result:
+ A new level is create with:
+ * computed_level_id = False
+ * level_id = manual_level_id
+ * flag = False
+ """
+ level = self.ProductLevel.create(
+ {
+ "product_id": self.product_1.id,
+ "manual_level_id": self.classification_level_a.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+ self.assertFalse(level.computed_level_id)
+ self.assertEqual(level.manual_level_id, self.classification_level_a)
+ self.assertEqual(level.level_id, self.classification_level_a)
+ self.assertFalse(level.flag)
+
+ def test_02(self):
+ """
+ Data:
+ An existing classification level with computed = manual
+ Test case:
+ 1. Change manual_level_id to an other value than the computed one
+ 2. Reset manual_level_id to the computed one
+ Expected result:
+ 1. level_id === manual =! computed and flag is true
+ 2 level_id == manual == computed and flag is true
+ ValidationError
+ """
+ self.assertFalse(self.product_level.flag)
+ self.assertEqual(
+ self.product_level.manual_level_id,
+ self.product_level.computed_level_id,
+ )
+ self.assertEqual(
+ self.product_level.computed_level_id, self.classification_level_a
+ )
+ self.assertEqual(self.product_level.level_id, self.classification_level_a)
+ # 1
+ self.product_level.manual_level_id = self.classification_level_b
+ self.assertEqual(self.product_level.level_id, self.classification_level_b)
+ self.assertTrue(self.product_level.flag)
+ # 2
+ self.product_level.manual_level_id = self.product_level.computed_level_id
+ self.assertEqual(self.product_level.level_id, self.classification_level_a)
+ self.assertFalse(self.product_level.flag)
+
+ def test_03(self):
+ """
+ Data:
+ An existing product level
+ Test case:
+ Create a new product level for the same product and the same profile
+ Expected result:
+ IntegrityError (level name must be unique by profile and product)
+ """
+ with self.assertRaises(IntegrityError):
+ self.ProductLevel.create(
+ {
+ "product_id": self.product_product.id,
+ "computed_level_id": self.classification_level_a.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+
+ def test_04(self):
+ """
+ Data:
+ An existing product level
+ Test case:
+ 1. Link a manual level from an other profile
+ 2. Link a computed level from an other profile
+ Expected result:
+ 1. and 2. Validation error (All the levels must share the same
+ profile as the one on the product level)
+ """
+ with self.assertRaises(ValidationError), self.env.cr.savepoint():
+ self.product_level.write(
+ {
+ "manual_level_id": self.classification_level_b.id,
+ "computed_level_id": self.classification_level_bis_a.id,
+ }
+ )
+ with self.assertRaises(ValidationError), self.env.cr.savepoint():
+ self.product_level.write(
+ {
+ "manual_level_id": self.classification_level_bis_a.id,
+ "computed_level_id": self.classification_level_a.id,
+ }
+ )
+ self.product_level.write(
+ {
+ "manual_level_id": self.classification_level_bis_a.id,
+ "computed_level_id": self.classification_level_bis_a.id,
+ "profile_id": self.classification_profile_bis.id,
+ }
+ )
+
+ def test_05(self):
+ """
+ Test case:
+ Create a product level without computed nor manual level
+ Expected result:
+ Validation error (at least a value for one of these fields is
+ expected)
+ """
+ with self.assertRaises(ValidationError):
+ self.ProductLevel.create(
+ {
+ "product_id": self.product_1.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+
+ def test_06_update_product_level_with_auto_compute(self):
+ self.classification_profile_bis.auto_apply_computed_value = True
+ self.product_level.write(
+ {
+ "computed_level_id": self.classification_level_bis_a.id,
+ "profile_id": self.classification_profile_bis.id,
+ }
+ )
+
+ self.assertEqual(
+ self.product_level.manual_level_id,
+ self.product_level.computed_level_id,
+ )
+ self.assertEqual(
+ self.product_level.computed_level_id, self.classification_level_bis_a
+ )
+ self.assertEqual(self.product_level.level_id, self.classification_level_bis_a)
+
+ self.product_level.write(
+ {
+ "computed_level_id": self.classification_level_bis_b.id,
+ }
+ )
+ self.assertEqual(
+ self.product_level.manual_level_id,
+ self.product_level.computed_level_id,
+ )
+ self.assertEqual(
+ self.product_level.computed_level_id, self.classification_level_bis_b
+ )
+ self.assertEqual(self.product_level.level_id, self.classification_level_bis_b)
+
+ def test_07_update_product_level_without_auto_compute(self):
+ self.classification_profile.auto_apply_computed_value = False
+ self.product_level.write(
+ {
+ "manual_level_id": self.classification_level_b.id,
+ "computed_level_id": self.classification_level_a.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+
+ self.assertNotEqual(
+ self.product_level.manual_level_id,
+ self.product_level.computed_level_id,
+ )
+ self.assertEqual(
+ self.product_level.computed_level_id, self.classification_level_a
+ )
+ self.assertEqual(
+ self.product_level.manual_level_id, self.classification_level_b
+ )
+ self.assertEqual(self.product_level.level_id, self.classification_level_b)
+
+ self.product_level.write(
+ {
+ "manual_level_id": self.classification_level_a.id,
+ "computed_level_id": self.classification_level_b.id,
+ }
+ )
+
+ self.assertNotEqual(
+ self.product_level.manual_level_id,
+ self.product_level.computed_level_id,
+ )
+ self.assertEqual(
+ self.product_level.computed_level_id, self.classification_level_b
+ )
+ self.assertEqual(
+ self.product_level.manual_level_id, self.classification_level_a
+ )
+ self.assertEqual(self.product_level.level_id, self.classification_level_a)
+
+ def test_08_update_recordset_with__autocompute(self):
+ self._create_product_levels()
+ self.classification_profile.auto_apply_computed_value = True
+
+ levels = self.ProductLevel.search(
+ [("profile_id", "=", self.classification_profile.id)]
+ )
+ levels.write(
+ {
+ "manual_level_id": self.classification_level_a.id,
+ "computed_level_id": self.classification_level_b.id,
+ }
+ )
+
+ for level in levels:
+ self.assertEqual(level.manual_level_id, level.computed_level_id)
+ self.assertEqual(level.manual_level_id, self.classification_level_b)
+ self.assertEqual(level.computed_level_id, self.classification_level_b)
+ self.assertEqual(level.level_id, self.classification_level_b)
+
+ def test_09_update_recordset_and_change_profile(self):
+ self._create_product_levels()
+ self.classification_profile_bis.auto_apply_computed_value = True
+
+ levels = self.ProductLevel.search(
+ [("profile_id", "=", self.classification_profile.id)]
+ )
+ levels.write(
+ {
+ "computed_level_id": self.classification_level_bis_a.id,
+ "profile_id": self.classification_profile_bis.id,
+ }
+ )
+
+ for level in levels:
+ self.assertEqual(level.manual_level_id, level.computed_level_id)
+ self.assertEqual(level.manual_level_id, self.classification_level_bis_a)
+ self.assertEqual(level.computed_level_id, self.classification_level_bis_a)
+ self.assertEqual(level.level_id, self.classification_level_bis_a)
+
+ def test_10_create_product_level_for_profile_auto_assign(self):
+ self.classification_profile.auto_apply_computed_value = True
+ level = self.ProductLevel.create(
+ {
+ "product_id": self.product_1.id,
+ "manual_level_id": self.classification_level_b.id,
+ "computed_level_id": self.classification_level_a.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+ self.assertEqual(level.manual_level_id, level.computed_level_id)
+ self.assertEqual(level.manual_level_id, self.classification_level_a)
+ self.assertEqual(level.computed_level_id, self.classification_level_a)
+ self.assertEqual(level.level_id, self.classification_level_a)
+
+ def test_11_auto_apply_computed_level(self):
+ self._create_product_levels()
+
+ levels = self.ProductLevel.search(
+ [("profile_id", "=", self.classification_profile.id)]
+ )
+ level0 = levels[0]
+ level1 = levels[1]
+ level2 = levels[2]
+ self.assertEqual(level0.manual_level_id, level0.computed_level_id)
+ self.assertEqual(level0.manual_level_id, self.classification_level_a)
+ self.assertEqual(level0.computed_level_id, self.classification_level_a)
+ self.assertEqual(level0.level_id, self.classification_level_a)
+
+ self.assertNotEqual(level1.manual_level_id, level1.computed_level_id)
+ self.assertEqual(level1.manual_level_id, self.classification_level_b)
+ self.assertEqual(level1.computed_level_id, self.classification_level_a)
+ self.assertEqual(level1.level_id, self.classification_level_b)
+
+ self.assertNotEqual(level2.manual_level_id, level2.computed_level_id)
+ self.assertEqual(level2.manual_level_id, self.classification_level_b)
+ self.assertEqual(level2.computed_level_id, self.classification_level_a)
+ self.assertEqual(level2.level_id, self.classification_level_b)
+
+ self.classification_profile.auto_apply_computed_value = True
+ for level in levels:
+ self.assertEqual(level.manual_level_id, self.classification_level_a)
+ self.assertEqual(level.computed_level_id, self.classification_level_a)
+ self.assertEqual(level.level_id, self.classification_level_a)
diff --git a/product_abc_classification/tests/test_abc_classification_profile.py b/product_abc_classification/tests/test_abc_classification_profile.py
new file mode 100644
index 00000000000..51691913cf2
--- /dev/null
+++ b/product_abc_classification/tests/test_abc_classification_profile.py
@@ -0,0 +1,300 @@
+# Copyright 2021 ACSONE SA/NV
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from psycopg2 import IntegrityError
+
+from odoo.exceptions import ValidationError
+
+from .common import ABCClassificationCase
+
+
+class TestABCClassificationProfile(ABCClassificationCase):
+ def test_00(self):
+ """
+ Data:
+ A test profile
+ Test case:
+ Assign levels for a total of 100%
+ Expected result:
+ OK
+ """
+ self.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 60,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 40,
+ "percentage_products": 60,
+ "name": "B",
+ },
+ ),
+ ]
+ }
+ )
+ self.assertEqual(len(self.classification_profile.level_ids), 2)
+
+ def test_01(self):
+ """
+ Data:
+ A test profile
+ Test case:
+ Assign levels for a total < 100%
+ Expected result:
+ ValidationError
+ """
+ with self.assertRaises(ValidationError):
+ self.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 60,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 30,
+ "percentage_products": 60,
+ "name": "B",
+ },
+ ),
+ ]
+ }
+ )
+
+ def test_02(self):
+ """
+ Data:
+ A test profile
+ Test case:
+ Assign levels for a total > 100%
+ Expected result:
+ ValidationError
+ """
+ with self.assertRaises(ValidationError):
+ self.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 60,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 50,
+ "percentage_products": 60,
+ "name": "B",
+ },
+ ),
+ ]
+ }
+ )
+
+ def test_03(self):
+ """
+ Data:
+ A test profile
+ Test case:
+ Assign levels for a total = 100% but with same percentage
+ Expected result:
+ ValidationError
+ """
+ with self.assertRaises(ValidationError):
+ self.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 50,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 50,
+ "percentage_products": 60,
+ "name": "B",
+ },
+ ),
+ ]
+ }
+ )
+
+ def test_04(self):
+ """
+ Data:
+ A test profile
+ Test case:
+ Assign levels for a total = 100% but with one level with negative
+ percentage and one level exceeding 100%
+ Expected result:
+ ValidationError
+ """
+ with self.assertRaises(ValidationError):
+ self.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 150,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": -50,
+ "percentage_products": 60,
+ "name": "B",
+ },
+ ),
+ ]
+ }
+ )
+
+ def test_05(self):
+ """
+ Data:
+ A test profile
+ Test case:
+ Assign levels for a total = 100% but with same name
+ Expected result:
+ IntegrityError (level name must be unique by profile)
+ """
+ with self.assertRaises(IntegrityError):
+ self.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 60,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 40,
+ "percentage_products": 60,
+ "name": "A",
+ },
+ ),
+ ]
+ }
+ )
+
+ def test_06(self):
+ """
+ Data:
+ A test profile with 2 levels A and B
+ Test case:
+ Create a new profile with the same level name
+ Expected result:
+ Profile created without error since the level name is unique by
+ profile
+ """
+ self.classification_profile.write(
+ {
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 60,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 40,
+ "percentage_products": 60,
+ "name": "B",
+ },
+ ),
+ ]
+ }
+ )
+ new_profile = self.ABCClassificationProfile.create(
+ {
+ "name": "New Profile test",
+ "profile_type": "test_type",
+ "level_ids": [
+ (
+ 0,
+ 0,
+ {
+ "percentage": 60,
+ "percentage_products": 40,
+ "name": "A",
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "percentage": 40,
+ "percentage_products": 60,
+ "name": "B",
+ },
+ ),
+ ],
+ }
+ )
+ self.assertTrue(new_profile)
+
+ def test_07(self):
+ """
+ Data:
+ A test profile
+ Test case:
+ Create a new profile with the same name
+ Expected result:
+ IntegrityError (profile name must be unique by profile)
+ """
+ with self.assertRaises(IntegrityError):
+ self.ABCClassificationProfile.create(
+ {
+ "name": self.classification_profile.name,
+ "profile_type": "test_type",
+ }
+ )
diff --git a/product_abc_classification/tests/test_product.py b/product_abc_classification/tests/test_product.py
new file mode 100644
index 00000000000..923ae1eefe9
--- /dev/null
+++ b/product_abc_classification/tests/test_product.py
@@ -0,0 +1,109 @@
+# Copyright 2021 ACSONE SA/NV
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from .common import ABCClassificationLevelCase
+
+
+class TestProduct(ABCClassificationLevelCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+
+ def test_00(self):
+ """
+ Data:
+ A product template with one variant.
+ Test Case:
+ 1. Associate a classification profile to the template
+ 2. Unset the classifiation profile
+ Expected:
+ 1. The classification profile is also associated to the variant
+ 2. The classification profile no more associated to the variant
+ """
+ self.assertFalse(self.product_template.abc_classification_profile_ids)
+ self.assertFalse(self.product_product.abc_classification_profile_ids)
+ # 1
+ self.product_template.abc_classification_profile_ids = (
+ self.classification_profile
+ )
+ self.assertEqual(
+ self.product_product.abc_classification_profile_ids,
+ self.classification_profile,
+ )
+ # 2
+ self.product_template.abc_classification_profile_ids = False
+ self.assertFalse(self.product_product.abc_classification_profile_ids)
+
+ def test_01(self):
+ """
+ Data:
+ A product template with two variants (without profiles).
+ Test Case:
+ 1. Associate a classification profile to the template
+ Expected:
+ The classification profile is not associated to the variant
+ """
+ self._create_variant(self.size_attr_value_m)
+ variants = self.product_template.product_variant_ids
+ self.assertEqual(len(variants), 2)
+ self.assertFalse(variants.mapped("abc_classification_profile_ids"))
+ self.product_template.abc_classification_profile_ids = (
+ self.classification_profile
+ )
+ self.assertFalse(variants.mapped("abc_classification_profile_ids"))
+
+ def test_02(self):
+ """
+ Data:
+ A product template with one variant
+ Test Case:
+ 1 Associate a product level to the variant
+ 2 unlink the level
+ Expected result:
+ 1 The product level is also associated to the template
+ 2 No more level associated to the template
+ """
+ product_level = self.ProductLevel.create(
+ {
+ "product_id": self.product_product.id,
+ "computed_level_id": self.classification_level_a.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+ self.assertEqual(
+ self.product_product.abc_classification_product_level_ids,
+ product_level,
+ )
+ self.assertEqual(
+ self.product_template.abc_classification_product_level_ids,
+ product_level,
+ )
+ product_level.unlink()
+
+ self.assertFalse(self.product_product.abc_classification_product_level_ids)
+ self.assertFalse(self.product_template.abc_classification_product_level_ids)
+
+ def test_03(self):
+ """
+ Data:
+ A product template with two variants
+ Test Case:
+ Associate a product level to one variant
+ Expected result:
+ The product level is not associated to the template
+ """
+ new_variant = self._create_variant(self.size_attr_value_m)
+ variants = self.product_template.product_variant_ids
+ self.assertEqual(len(variants), 2)
+ product_level = self.ProductLevel.create(
+ {
+ "product_id": new_variant.id,
+ "computed_level_id": self.classification_level_a.id,
+ "profile_id": self.classification_profile.id,
+ }
+ )
+ self.assertEqual(
+ new_variant.abc_classification_product_level_ids,
+ product_level,
+ )
+ self.assertFalse(self.product_template.abc_classification_product_level_ids)
diff --git a/product_abc_classification/views/abc_classification_product_level.xml b/product_abc_classification/views/abc_classification_product_level.xml
new file mode 100644
index 00000000000..71ac10979bd
--- /dev/null
+++ b/product_abc_classification/views/abc_classification_product_level.xml
@@ -0,0 +1,101 @@
+
+
+
+
+ abc.classification.product.level.form (in product_abc_classification)
+ abc.classification.product.level
+
+
+
+
+
+ abc.classification.product.level.tree (in product_abc_classification)
+ abc.classification.product.level
+
+
+
+
+
+
+
+
+
+
+
+ abc.classification.product.level.search (in product_abc_classification)
+ abc.classification.product.level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Products ABC Classification
+ abc.classification.product.level
+ tree,form
+ {'search_default_group_by_level': 1}
+
+
+
diff --git a/product_abc_classification/views/abc_classification_profile.xml b/product_abc_classification/views/abc_classification_profile.xml
new file mode 100644
index 00000000000..f7eaf1f93da
--- /dev/null
+++ b/product_abc_classification/views/abc_classification_profile.xml
@@ -0,0 +1,54 @@
+
+
+
+
+ abc.classification.profile.form (in product_abc_classification)
+ abc.classification.profile
+
+
+
+
+
+ abc.classification.profile.tree (in product_abc_classification)
+ abc.classification.profile
+
+
+
+
+
+
+
+ ABC Classification profiles
+ abc.classification.profile
+ tree,form
+
+
+
diff --git a/product_abc_classification/views/product_product.xml b/product_abc_classification/views/product_product.xml
new file mode 100644
index 00000000000..ef810e32598
--- /dev/null
+++ b/product_abc_classification/views/product_product.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ product.product.form (ABC Classification)
+ product.product
+
+
+
+ {'default_product_id': active_id, 'default_profile_id': abc_classification_profile_ids and abc_classification_profile_ids[0] and abc_classification_profile_ids[0][2] and abc_classification_profile_ids[0][2][0] or False}
+ {'read_only': False}
+ [('product_id', '=', active_id)]
+
+
+
+
diff --git a/product_abc_classification/views/product_template.xml b/product_abc_classification/views/product_template.xml
new file mode 100644
index 00000000000..1127c274e5f
--- /dev/null
+++ b/product_abc_classification/views/product_template.xml
@@ -0,0 +1,32 @@
+
+
+
+
+ product.template.form (ABC Classification)
+ product.template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 24c91f573f716060bf4d12695eceae14cc5188b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miquel=20Ra=C3=AFch?=
Date: Wed, 2 Feb 2022 17:34:19 +0100
Subject: [PATCH 025/224] [IMP] product_abc_classification: add product smart
button in profile
---
.../models/abc_classification_profile.py | 37 +++++++++++++++++++
.../views/abc_classification_profile.xml | 10 +++++
2 files changed, 47 insertions(+)
diff --git a/product_abc_classification/models/abc_classification_profile.py b/product_abc_classification/models/abc_classification_profile.py
index b57b0a1e46d..6411834d0ee 100644
--- a/product_abc_classification/models/abc_classification_profile.py
+++ b/product_abc_classification/models/abc_classification_profile.py
@@ -30,6 +30,15 @@ class AbcClassificationProfile(models.Model):
required=True,
)
+ product_variant_ids = fields.Many2many(
+ comodel_name="product.product",
+ relation="abc_classification_profile_product_rel",
+ column1="profile_id",
+ column2="product_id",
+ index=True,
+ )
+ product_count = fields.Integer(compute="_compute_product_count", readonly=True)
+
auto_apply_computed_value = fields.Boolean(default=False)
_sql_constraints = [("name_uniq", "UNIQUE(name)", _("Profile name must be unique"))]
@@ -60,6 +69,34 @@ def _check_levels(self):
def _compute_abc_classification(self):
raise NotImplementedError()
+ @api.depends("product_variant_ids")
+ def _compute_product_count(self):
+ for profile in self:
+ profile.product_count = len(profile.product_variant_ids)
+
+ def action_view_products(self):
+ products = self.mapped("product_variant_ids")
+ action = self.env["ir.actions.act_window"].for_xml_id(
+ "product", "product_variant_action"
+ )
+ del action["context"]
+ if len(products) > 1:
+ action["domain"] = [("id", "in", products.ids)]
+ elif len(products) == 1:
+ form_view = [
+ (self.env.ref("product.product_variant_easy_edit_view").id, "form")
+ ]
+ if "views" in action:
+ action["views"] = form_view + [
+ (state, view) for state, view in action["views"] if view != "form"
+ ]
+ else:
+ action["views"] = form_view
+ action["res_id"] = products.id
+ else:
+ action = {"type": "ir.actions.act_window_close"}
+ return action
+
@api.model
def _cron_compute_abc_classification(self):
self.search([])._compute_abc_classification()
diff --git a/product_abc_classification/views/abc_classification_profile.xml b/product_abc_classification/views/abc_classification_profile.xml
index f7eaf1f93da..65830d78c4f 100644
--- a/product_abc_classification/views/abc_classification_profile.xml
+++ b/product_abc_classification/views/abc_classification_profile.xml
@@ -10,6 +10,16 @@