Skip to content

Commit

Permalink
[MIG] sale_order_secondary_unit: Migration to 17.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mmrondon committed Oct 31, 2024
1 parent cc0d5d8 commit bc8cb8f
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 46 deletions.
2 changes: 1 addition & 1 deletion sale_order_secondary_unit/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"name": "Sale Order Secondary Unit",
"summary": "Sale product in a secondary unit",
"version": "15.0.2.2.0",
"version": "17.0.1.0.0",
"development_status": "Production/Stable",
"category": "Sale",
"website": "https://github.com/OCA/sale-workflow",
Expand Down
4 changes: 2 additions & 2 deletions sale_order_secondary_unit/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ def onchange_sale_secondary_uom_id(self):

@api.model_create_multi
def create(self, vals_list):
templates = super(ProductTemplate, self).create(vals_list)
templates = super().create(vals_list)
# This is needed to set given values to first variant after creation
for template, vals in zip(templates, vals_list):
for template, vals in zip(templates, vals_list, strict=True):
related_vals = {}
if vals.get("sale_secondary_uom_id"):
related_vals["sale_secondary_uom_id"] = vals["sale_secondary_uom_id"]

Check warning on line 69 in sale_order_secondary_unit/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

sale_order_secondary_unit/models/product_template.py#L69

Added line #L69 was not covered by tests
Expand Down
48 changes: 25 additions & 23 deletions sale_order_secondary_unit/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,37 @@ class SaleOrderLine(models.Model):
compute="_compute_secondary_uom_unit_price",
)

product_uom_qty = fields.Float(
store=True, readonly=False, compute="_compute_product_uom_qty", copy=True
)
product_uom_qty = fields.Float(copy=True)

@api.depends("secondary_uom_qty", "secondary_uom_id", "product_uom_qty")
@api.depends(
"display_type",
"product_id",
"product_packaging_qty",
"secondary_uom_qty",
"secondary_uom_id",
"product_uom_qty",
)
def _compute_product_uom_qty(self):
self._compute_helper_target_field_qty()
res = super()._compute_product_uom_qty()
for line in self:
line._compute_helper_target_field_qty()
return res

@api.onchange("product_uom")
def onchange_product_uom_for_secondary(self):
self._onchange_helper_product_uom_for_secondary()
@api.depends("product_id")
def _compute_product_uom(self):
res = super()._compute_product_uom()
for line in self:
line._onchange_helper_product_uom_for_secondary()
return res

@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:
def _onchange_product_id_warning(self):
res = super()._onchange_product_id_warning()
if self.product_id:
self.secondary_uom_id = self.product_id.sale_secondary_uom_id
if self.product_uom_qty == 1.0:
self.secondary_uom_qty = 1.0
self.onchange_product_uom_for_secondary()
else:
self.product_uom_qty = line_uom_qty
self._onchange_helper_product_uom_for_secondary()
return res

@api.depends("secondary_uom_qty", "product_uom_qty", "price_unit")
Expand Down
3 changes: 2 additions & 1 deletion sale_order_secondary_unit/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import test_sale_order_secondary_unit
from . import test_product_template
from . import test_sale_order
130 changes: 130 additions & 0 deletions sale_order_secondary_unit/tests/test_product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Copyright 2018-2020 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.tests import TransactionCase, tagged


@tagged("post_install", "-at_install")
class TestProductTemplate(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.product_uom_unit = cls.env.ref("uom.product_uom_unit")
cls.product_attribute_model = cls.env["product.attribute"]
cls.product_attribute_value_model = cls.env["product.attribute.value"]
# Create product attributes
cls.color_attribute = cls.product_attribute_model.create(
{"name": "Color", "create_variant": "always"}
)
cls.color_values = cls.product_attribute_value_model.create(
[
{"name": "Red", "attribute_id": cls.color_attribute.id},
{"name": "Blue", "attribute_id": cls.color_attribute.id},
{"name": "Green", "attribute_id": cls.color_attribute.id},
]
)
cls.size_attribute = cls.product_attribute_model.create(
{"name": "Size", "create_variant": "always"}
)
cls.size_values = cls.product_attribute_value_model.create(
[
{"name": "S", "attribute_id": cls.size_attribute.id},
{"name": "M", "attribute_id": cls.size_attribute.id},
{"name": "L", "attribute_id": cls.size_attribute.id},
]
)

# Create product template
cls.product_template_1 = cls.env["product.template"].create(
{
"name": "Test Product 1",
}
)
# Create product variants
cls.product_template_2 = cls.env["product.template"].create(
{
"name": "Test Product 2",
"attribute_line_ids": [
(
0,
0,
{
"attribute_id": cls.color_attribute.id,
"value_ids": [(6, 0, cls.color_values.ids)],
},
),
(
0,
0,
{
"attribute_id": cls.size_attribute.id,
"value_ids": [(6, 0, cls.size_values.ids)],
},
),
],
}
)
# Create secondary units
cls.secondary_uom_1 = cls.env["product.secondary.unit"].create(
{
"name": "Unit 1",
"uom_id": cls.product_uom_unit.id,
"factor": 1,
"product_tmpl_id": cls.product_template_1.id,
}
)
cls.secondary_uom_2 = cls.env["product.secondary.unit"].create(
{
"name": "Unit 2",
"uom_id": cls.product_uom_unit.id,
"factor": 1,
"product_tmpl_id": cls.product_template_1.id,
}
)
cls.secondary_uom_3 = cls.env["product.secondary.unit"].create(
{
"name": "Unit 3",
"uom_id": cls.product_uom_unit.id,
"factor": 1,
"product_tmpl_id": cls.product_template_2.id,
}
)
cls.secondary_uom_4 = cls.env["product.secondary.unit"].create(
{
"name": "Unit 4",
"uom_id": cls.product_uom_unit.id,
"factor": 1,
"product_tmpl_id": cls.product_template_2.id,
}
)

def test_create_sets_sale_secondary_uom_id_for_single_variant(self):
product_variant_ids = self.product_template_1.product_variant_ids
product_variant_ids.sale_secondary_uom_id = self.secondary_uom_1
self.assertEqual(self.product_template_1.sale_secondary_uom_id.name, "Unit 1")

def test_create_not_sale_secondary_uom_id_for_variants_and_warns(self):
product_variant_ids = self.product_template_2.product_variant_ids
product_variant_ids[0].sale_secondary_uom_id = self.secondary_uom_3
product_variant_ids[1].sale_secondary_uom_id = self.secondary_uom_4
self.assertFalse(self.product_template_2.sale_secondary_uom_id)

warning = self.product_template_2.onchange_sale_secondary_uom_id()
self.assertIn("warning", warning)
self.assertIn(
"Product variants have distinct sale secondary uom",
warning["warning"]["message"],
)

def test_create_sale_secondary_uom_id_multiple_variants_same_uom(self):
product_variant_ids = self.product_template_2.product_variant_ids
product_variant_ids[0].sale_secondary_uom_id = self.secondary_uom_3
product_variant_ids[1].sale_secondary_uom_id = self.secondary_uom_3
self.assertEqual(self.product_template_2.sale_secondary_uom_id.name, "Unit 3")

def test_inverse_sale_secondary_uom_id_updates_variants_correctly(self):
self.product_template_1.sale_secondary_uom_id = self.secondary_uom_2
self.product_template_1._inverse_sale_secondary_uom_id()
self.assertEqual(
self.product_template_1.product_variant_ids.sale_secondary_uom_id,
self.product_template_1.sale_secondary_uom_id,
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


@tagged("post_install", "-at_install")
class TestSaleOrderSecondaryUnit(TransactionCase):
class TestSaleOrder(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
Expand All @@ -21,9 +21,6 @@ def setUpClass(cls):
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",
Expand Down Expand Up @@ -54,7 +51,6 @@ def setUpClass(cls):
cls.partner = cls.env["res.partner"].create({"name": "test - partner"})
with Form(cls.env["sale.order"]) as order_form:
order_form.partner_id = cls.partner
order_form.pricelist_id = cls.price_list
with order_form.order_line.new() as line_form:
line_form.product_id = cls.product
line_form.product_uom_qty = 1
Expand All @@ -75,7 +71,7 @@ def test_onchange_secondary_unit_product_uom_qty(self):
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.order.order_line._onchange_product_id_warning()
self.assertEqual(self.order.order_line.secondary_uom_id, self.secondary_unit)

def test_onchange_order_product_uom(self):
Expand Down
7 changes: 5 additions & 2 deletions sale_order_secondary_unit/views/product_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
<field name="name">Product template Secondary Unit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="groups_id" eval="[(4, ref('uom.group_uom'))]" />
<field name="arch" type="xml">
<field name="uom_id" position="after">
<field name="sale_secondary_uom_id" options="{'no_create': True}" />
<field
name="sale_secondary_uom_id"
options="{'no_create': True}"
groups="uom.group_uom"
/>
</field>
</field>
</record>
Expand Down
27 changes: 16 additions & 11 deletions sale_order_secondary_unit/views/sale_order_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,32 @@
<field name="name">Sale Order Secondary Unit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="groups_id" eval="[(4, ref('uom.group_uom'))]" />
<field name="arch" type="xml">
<xpath
expr="//field[@name='order_line']/form//field[@name='price_subtotal']"
position="after"
>
<label for="secondary_uom_qty" />
<div class="o_row" name="secondary_uom_qty">
<label for="secondary_uom_qty" groups="uom.group_uom" />
<div class="o_row" name="secondary_uom_qty" groups="uom.group_uom">
<field
name="secondary_uom_qty"
class="oe_inline oe_no_button"
widget="numeric_step"
options="{'auto_select': True}"
attrs="{'readonly': [('state', 'in', ('done', 'cancel'))]}"
readonly="state in ['done', 'cancel']"
/>

<field
name="secondary_uom_id"
class="oe_inline oe_no_button"
domain="['|', ('product_id', '=', product_id),
'&amp;', ('product_tmpl_id.product_variant_ids', 'in', [product_id]),
('product_id', '=', False)]"
options="{'no_create': True, 'no_open': True}"
attrs="{'readonly': [('product_uom_readonly', '=', True)], 'required': [('secondary_uom_qty', '!=', 0.0)]}"
readonly="product_uom_readonly"
required="secondary_uom_qty != 0.0"
/>

</div>
</xpath>
<xpath
Expand All @@ -38,18 +40,21 @@
>
<field
name="secondary_uom_qty"
attrs="{'readonly': [('parent.state', 'in', ('done', 'cancel'))]}"
optional="show"
column_invisible="parent.state in ('done', 'cancel')"
groups="uom.group_uom"
/>

<field
name="secondary_uom_id"
domain="['|', ('product_id', '=', product_id),
'&amp;', ('product_tmpl_id.product_variant_ids', 'in', [product_id]),
('product_id', '=', False)]"
options="{'no_create': True}"
attrs="{'readonly': [('product_uom_readonly', '=', True)], 'required': [('secondary_uom_qty', '!=', 0.0)]}"
optional="show"
readonly="product_uom_readonly"
required="secondary_uom_qty != 0.0"
groups="uom.group_uom"
/>

</xpath>
<xpath
expr="//field[@name='order_line']/kanban//field[@name='company_id']"
Expand All @@ -59,10 +64,10 @@
<field name="secondary_uom_qty" invisible="1" />
</xpath>
<xpath
expr="//field[@name='order_line']/kanban//t[@t-esc='record.product_uom_qty.value']"
expr="//field[@name='order_line']/kanban//t[@t-out='record.product_uom_qty.value']"
position="before"
>
<t t-if="record.secondary_uom_id.value">
<t t-if="record.secondary_uom_id.value" groups="uom.group_uom">
<t t-esc="record.secondary_uom_qty.value" />
<t t-esc="record.secondary_uom_id.value" /> ->
</t>
Expand Down

0 comments on commit bc8cb8f

Please sign in to comment.