From 221c07cf9d33c1f1b14acbd1bc43a35c427d125d Mon Sep 17 00:00:00 2001
From: Alexey Pelykh
Date: Sat, 16 Mar 2024 05:43:15 +0100
Subject: [PATCH] [MIG] sale_order_secondary_unit: Migration to 16.0
---
sale_order_secondary_unit/README.rst | 14 +--
sale_order_secondary_unit/__manifest__.py | 2 +-
sale_order_secondary_unit/i18n/de.po | 2 +-
sale_order_secondary_unit/i18n/es.po | 2 +-
sale_order_secondary_unit/i18n/fi.po | 2 +-
.../i18n/sale_order_secondary_unit.pot | 2 +-
sale_order_secondary_unit/i18n/zh_CN.po | 2 +-
.../migrations/15.0.2.0.0/post-migration.py | 17 ----
.../models/sale_order.py | 57 ++++++-------
.../readme/CONTRIBUTORS.rst | 4 +
.../static/description/index.html | 10 ++-
.../tests/test_sale_order_secondary_unit.py | 70 ++++++++-------
.../views/product_views.xml | 14 ++-
.../views/sale_order_views.xml | 85 ++++++++++++-------
14 files changed, 151 insertions(+), 132 deletions(-)
delete mode 100644 sale_order_secondary_unit/migrations/15.0.2.0.0/post-migration.py
diff --git a/sale_order_secondary_unit/README.rst b/sale_order_secondary_unit/README.rst
index c0da61d8b61..a09e9652388 100644
--- a/sale_order_secondary_unit/README.rst
+++ b/sale_order_secondary_unit/README.rst
@@ -17,13 +17,13 @@ Sale Order Secondary Unit
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
- :target: https://github.com/OCA/sale-workflow/tree/15.0/sale_order_secondary_unit
+ :target: https://github.com/OCA/sale-workflow/tree/16.0/sale_order_secondary_unit
:alt: OCA/sale-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/sale-workflow-15-0/sale-workflow-15-0-sale_order_secondary_unit
+ :target: https://translation.odoo-community.org/projects/sale-workflow-16-0/sale-workflow-16-0-sale_order_secondary_unit
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
- :target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=15.0
+ :target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -61,7 +61,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 to smash it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -86,6 +86,10 @@ Contributors
* Ernesto Tejeda
* Pedro M. Baeza
+* `CorporateHub `__
+
+ * Alexey Pelykh
+
Maintainers
~~~~~~~~~~~
@@ -99,6 +103,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/sale-workflow `_ project on GitHub.
+This module is part of the `OCA/sale-workflow `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/sale_order_secondary_unit/__manifest__.py b/sale_order_secondary_unit/__manifest__.py
index e3d32b0d9b6..9b31ce1dca6 100644
--- a/sale_order_secondary_unit/__manifest__.py
+++ b/sale_order_secondary_unit/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Sale Order Secondary Unit",
"summary": "Sale product in a secondary unit",
- "version": "15.0.2.1.0",
+ "version": "16.0.1.0.0",
"development_status": "Production/Stable",
"category": "Sale",
"website": "https://github.com/OCA/sale-workflow",
diff --git a/sale_order_secondary_unit/i18n/de.po b/sale_order_secondary_unit/i18n/de.po
index 7074272f51d..7582c540bff 100644
--- a/sale_order_secondary_unit/i18n/de.po
+++ b/sale_order_secondary_unit/i18n/de.po
@@ -21,7 +21,7 @@ msgid "->"
msgstr ""
#. module: sale_order_secondary_unit
-#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_unit_price
+#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_price_unit
msgid "2nd unit price"
msgstr ""
diff --git a/sale_order_secondary_unit/i18n/es.po b/sale_order_secondary_unit/i18n/es.po
index 69d10c5f932..c4ecb0040d0 100644
--- a/sale_order_secondary_unit/i18n/es.po
+++ b/sale_order_secondary_unit/i18n/es.po
@@ -23,7 +23,7 @@ msgid "->"
msgstr "->"
#. module: sale_order_secondary_unit
-#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_unit_price
+#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_price_unit
msgid "2nd unit price"
msgstr "Precio de la 2ª unidad"
diff --git a/sale_order_secondary_unit/i18n/fi.po b/sale_order_secondary_unit/i18n/fi.po
index 021c177367a..1616390dc36 100644
--- a/sale_order_secondary_unit/i18n/fi.po
+++ b/sale_order_secondary_unit/i18n/fi.po
@@ -22,7 +22,7 @@ msgid "->"
msgstr ""
#. module: sale_order_secondary_unit
-#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_unit_price
+#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_price_unit
msgid "2nd unit price"
msgstr "2. Yksikköhinta"
diff --git a/sale_order_secondary_unit/i18n/sale_order_secondary_unit.pot b/sale_order_secondary_unit/i18n/sale_order_secondary_unit.pot
index c1a254cc7c2..20037af0481 100644
--- a/sale_order_secondary_unit/i18n/sale_order_secondary_unit.pot
+++ b/sale_order_secondary_unit/i18n/sale_order_secondary_unit.pot
@@ -19,7 +19,7 @@ msgid "->"
msgstr ""
#. module: sale_order_secondary_unit
-#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_unit_price
+#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_price_unit
msgid "2nd unit price"
msgstr ""
diff --git a/sale_order_secondary_unit/i18n/zh_CN.po b/sale_order_secondary_unit/i18n/zh_CN.po
index 6155ca465f7..ca9f774b608 100644
--- a/sale_order_secondary_unit/i18n/zh_CN.po
+++ b/sale_order_secondary_unit/i18n/zh_CN.po
@@ -21,7 +21,7 @@ msgid "->"
msgstr ""
#. module: sale_order_secondary_unit
-#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_unit_price
+#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line__secondary_uom_price_unit
msgid "2nd unit price"
msgstr ""
diff --git a/sale_order_secondary_unit/migrations/15.0.2.0.0/post-migration.py b/sale_order_secondary_unit/migrations/15.0.2.0.0/post-migration.py
deleted file mode 100644
index 55b11c79f67..00000000000
--- a/sale_order_secondary_unit/migrations/15.0.2.0.0/post-migration.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2023 Tecnativa - Sergio Teruel
-# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-
-from openupgradelib import openupgrade
-
-
-@openupgrade.migrate()
-def migrate(env, version):
- # Set default sale secondary uom from template to variants
- sql = """
- UPDATE product_product pp
- SET sale_secondary_uom_id = pt.sale_secondary_uom_id
- FROM product_template pt
- WHERE pt.id = pp.product_tmpl_id
- AND pt.sale_secondary_uom_id IS NOT NULL
- """
- openupgrade.logged_query(env.cr, sql)
diff --git a/sale_order_secondary_unit/models/sale_order.py b/sale_order_secondary_unit/models/sale_order.py
index 935dd50cf6a..17f39d3f0b0 100644
--- a/sale_order_secondary_unit/models/sale_order.py
+++ b/sale_order_secondary_unit/models/sale_order.py
@@ -1,4 +1,5 @@
# Copyright 2018-2020 Tecnativa - Carlos Dauden
+# Copyright 2024 CorporateHub
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
@@ -11,52 +12,44 @@ class SaleOrderLine(models.Model):
"uom_field": "product_uom",
}
- secondary_uom_unit_price = fields.Float(
- string="2nd unit price",
+ secondary_uom_price_unit = fields.Float(
+ string="Secondary Unit Price",
digits="Product Price",
- compute="_compute_secondary_uom_unit_price",
+ compute="_compute_secondary_uom_price_unit",
+ store=True,
+ precompute=True,
)
- product_uom_qty = fields.Float(
- store=True, readonly=False, compute="_compute_product_uom_qty", copy=True
- )
-
- @api.depends("secondary_uom_qty", "secondary_uom_id", "product_uom_qty")
+ @api.depends("secondary_uom_qty", "secondary_uom_id")
def _compute_product_uom_qty(self):
+ res = super()._compute_product_uom_qty()
self._compute_helper_target_field_qty()
+ return res
@api.onchange("product_uom")
- def onchange_product_uom_for_secondary(self):
+ def _onchange_product_uom(self):
self._onchange_helper_product_uom_for_secondary()
@api.onchange("product_id")
- def product_id_change(self):
- """
- If default sales secondary unit set on product, put on secondary
- quantity 1 for being the default quantity. We override this method,
- that is the one that sets by default 1 on the other quantity with that
- purpose.
- """
- res = super().product_id_change()
- line_uom_qty = self.product_uom_qty
- self.secondary_uom_id = self.product_id.sale_secondary_uom_id
- if self.product_id.sale_secondary_uom_id:
- if line_uom_qty == 1.0:
- self.secondary_uom_qty = 1.0
- self.onchange_product_uom_for_secondary()
- else:
- self.product_uom_qty = line_uom_qty
- return res
-
- @api.depends("secondary_uom_qty", "product_uom_qty", "price_unit")
- def _compute_secondary_uom_unit_price(self):
+ def _onchange_product_id(self):
+ inherited_secondary_uom_id = (
+ self.product_id.sale_secondary_uom_id
+ or self.product_id.product_tmpl_id.sale_secondary_uom_id
+ )
+ if inherited_secondary_uom_id:
+ line_uom_qty = self.product_uom_qty
+ self.secondary_uom_id = inherited_secondary_uom_id
+ self.product_uom_qty = line_uom_qty
+
+ @api.depends("secondary_uom_qty", "product_uom_qty", "price_subtotal")
+ def _compute_secondary_uom_price_unit(self):
for line in self:
if line.secondary_uom_id:
try:
- line.secondary_uom_unit_price = (
+ line.secondary_uom_price_unit = (
line.price_subtotal / line.secondary_uom_qty
)
except ZeroDivisionError:
- line.secondary_uom_unit_price = 0
+ line.secondary_uom_price_unit = 0
else:
- line.secondary_uom_unit_price = 0
+ line.secondary_uom_price_unit = 0
diff --git a/sale_order_secondary_unit/readme/CONTRIBUTORS.rst b/sale_order_secondary_unit/readme/CONTRIBUTORS.rst
index cb9aa25b433..b6d15f38277 100644
--- a/sale_order_secondary_unit/readme/CONTRIBUTORS.rst
+++ b/sale_order_secondary_unit/readme/CONTRIBUTORS.rst
@@ -7,3 +7,7 @@
* Sergio Teruel
* Ernesto Tejeda
* Pedro M. Baeza
+
+* `CorporateHub `__
+
+ * Alexey Pelykh
diff --git a/sale_order_secondary_unit/static/description/index.html b/sale_order_secondary_unit/static/description/index.html
index bd08c7fa09d..a9addc82217 100644
--- a/sale_order_secondary_unit/static/description/index.html
+++ b/sale_order_secondary_unit/static/description/index.html
@@ -368,7 +368,7 @@ Sale Order Secondary Unit
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:d870b4aa2365687416065e0cd5aef2754fc39659c2bef870bbf907d7d5b0cd6c
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
This module extends the functionality of sale orders to allow sale products in
secondary unit of distinct category.
Table of contents
@@ -409,7 +409,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 to smash it by providing a detailed and welcomed
-feedback .
+feedback .
Do not contact contributors directly about support or help with technical issues.
@@ -442,7 +446,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/sale-workflow project on GitHub.
+
This module is part of the OCA/sale-workflow project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
diff --git a/sale_order_secondary_unit/tests/test_sale_order_secondary_unit.py b/sale_order_secondary_unit/tests/test_sale_order_secondary_unit.py
index 5cf4076f3b4..6ac88c28a7a 100644
--- a/sale_order_secondary_unit/tests/test_sale_order_secondary_unit.py
+++ b/sale_order_secondary_unit/tests/test_sale_order_secondary_unit.py
@@ -1,52 +1,47 @@
# Copyright 2018-2020 Tecnativa - Carlos Dauden
+# Copyright 2024 CorporateHub
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from odoo.fields import Command
from odoo.tests import Form, TransactionCase, tagged
+from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT
+
@tagged("post_install", "-at_install")
class TestSaleOrderSecondaryUnit(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- # Remove this variable in v16 and put instead:
- # from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT
- DISABLED_MAIL_CONTEXT = {
- "tracking_disable": True,
- "mail_create_nolog": True,
- "mail_create_nosubscribe": True,
- "mail_notrack": True,
- "no_reset_password": True,
- }
cls.env = cls.env(context=dict(cls.env.context, **DISABLED_MAIL_CONTEXT))
cls.product_uom_kg = cls.env.ref("uom.product_uom_kgm")
cls.product_uom_gram = cls.env.ref("uom.product_uom_gram")
cls.product_uom_unit = cls.env.ref("uom.product_uom_unit")
- cls.price_list = cls.env["product.pricelist"].create(
- {"name": "price list for test"}
- )
cls.product = cls.env["product.product"].create(
{
"name": "test",
+ "list_price": 1000.00,
"uom_id": cls.product_uom_kg.id,
"uom_po_id": cls.product_uom_kg.id,
}
)
- # Set secondary uom on product template
cls.product.product_tmpl_id.write(
{
"secondary_uom_ids": [
- (
- 0,
- 0,
+ Command.create(
{
"name": "unit-500",
"uom_id": cls.product_uom_unit.id,
"factor": 0.5,
- },
+ }
)
],
}
)
+ cls.price_list = cls.env["product.pricelist"].create(
+ {
+ "name": "price list for test",
+ }
+ )
cls.secondary_unit = cls.env["product.secondary.unit"].search(
[("product_tmpl_id", "=", cls.product.product_tmpl_id.id)]
)
@@ -58,28 +53,21 @@ def setUpClass(cls):
with order_form.order_line.new() as line_form:
line_form.product_id = cls.product
line_form.product_uom_qty = 1
- line_form.price_unit = 1000.00
cls.order = order_form.save()
- def test_onchange_secondary_uom(self):
+ def test_compute_product_uom_qty(self):
self.order.order_line.write(
{"secondary_uom_id": self.secondary_unit.id, "secondary_uom_qty": 5}
)
- self.order.order_line._compute_product_uom_qty()
self.assertEqual(self.order.order_line.product_uom_qty, 2.5)
- def test_onchange_secondary_unit_product_uom_qty(self):
- self.order.order_line.update(
+ def test_compute_secondary_uom_qty(self):
+ self.order.order_line.write(
{"secondary_uom_id": self.secondary_unit.id, "product_uom_qty": 3.5}
)
self.assertEqual(self.order.order_line.secondary_uom_qty, 7.0)
- def test_default_secondary_unit(self):
- self.order.order_line.product_id_change()
- self.assertEqual(self.order.order_line.secondary_uom_id, self.secondary_unit)
-
- def test_onchange_order_product_uom(self):
- self.order.order_line.update(
+ self.order.order_line.write(
{
"secondary_uom_id": self.secondary_unit.id,
"product_uom": self.product_uom_gram.id,
@@ -88,6 +76,10 @@ def test_onchange_order_product_uom(self):
)
self.assertEqual(self.order.order_line.secondary_uom_qty, 7.0)
+ def test_default_secondary_unit(self):
+ self.order.order_line._onchange_product_id()
+ self.assertEqual(self.order.order_line.secondary_uom_id, self.secondary_unit)
+
def test_independent_type(self):
# dependent type is already tested as dependency_type by default
self.order.order_line.secondary_uom_id = self.secondary_unit.id
@@ -103,18 +95,24 @@ def test_independent_type(self):
self.assertEqual(self.order.order_line.secondary_uom_qty, 2)
self.assertEqual(self.order.order_line.product_uom_qty, 17)
- def test_secondary_uom_unit_price(self):
- # Remove secondary uom in sale line to do a complete test of secondary price
+ def test_secondary_uom_price_unit(self):
self.order.order_line.secondary_uom_id = False
- self.assertEqual(self.order.order_line.secondary_uom_unit_price, 0)
- self.order.order_line.update(
+ self.assertEqual(self.order.order_line.product_uom_qty, 1)
+ self.assertEqual(self.order.order_line.price_unit, 1000)
+ self.assertEqual(self.order.order_line.price_subtotal, 1000)
+ self.assertEqual(self.order.order_line.secondary_uom_qty, 0)
+ self.assertEqual(self.order.order_line.secondary_uom_price_unit, 0)
+
+ self.order.order_line.write(
{"secondary_uom_id": self.secondary_unit.id, "product_uom_qty": 2}
)
-
+ self.assertEqual(self.order.order_line.product_uom_qty, 2)
+ self.assertEqual(self.order.order_line.price_unit, 1000)
+ self.assertEqual(self.order.order_line.price_subtotal, 2000)
self.assertEqual(self.order.order_line.secondary_uom_qty, 4)
- self.assertEqual(self.order.order_line.secondary_uom_unit_price, 500)
+ self.assertEqual(self.order.order_line.secondary_uom_price_unit, 500)
self.order.order_line.write({"product_uom_qty": 8})
- self.assertEqual(self.order.order_line.secondary_uom_qty, 16)
- self.assertEqual(self.order.order_line.secondary_uom_unit_price, 500)
self.assertEqual(self.order.order_line.price_subtotal, 8000)
+ self.assertEqual(self.order.order_line.secondary_uom_qty, 16)
+ self.assertEqual(self.order.order_line.secondary_uom_price_unit, 500)
diff --git a/sale_order_secondary_unit/views/product_views.xml b/sale_order_secondary_unit/views/product_views.xml
index 960783fd6ee..bf494bd55ca 100644
--- a/sale_order_secondary_unit/views/product_views.xml
+++ b/sale_order_secondary_unit/views/product_views.xml
@@ -1,15 +1,21 @@
-
+
Product template Secondary Unit
product.template
-
-
+
diff --git a/sale_order_secondary_unit/views/sale_order_views.xml b/sale_order_secondary_unit/views/sale_order_views.xml
index 88b37540f43..c52ba766785 100644
--- a/sale_order_secondary_unit/views/sale_order_views.xml
+++ b/sale_order_secondary_unit/views/sale_order_views.xml
@@ -1,36 +1,48 @@
-
+
Sale Order Secondary Unit
sale.order
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
-
-
- ->
+
+
+ ->