Skip to content

Commit

Permalink
[REF] sale_product_pack: improve coverage and refactor unlink order l…
Browse files Browse the repository at this point in the history
…ine product pack
  • Loading branch information
petrus-v committed Jan 18, 2024
1 parent ead2322 commit d544e24
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 21 deletions.
20 changes: 0 additions & 20 deletions sale_product_pack/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,3 @@ def check_pack_line_unlink(self):
" delete the pack itself"
)
)

def write(self, vals):
if "order_line" in vals:
to_delete_ids = [e[1] for e in vals["order_line"] if e[0] == 2]
subpacks_to_delete_ids = (
self.env["sale.order.line"]
.search(
[("id", "child_of", to_delete_ids), ("id", "not in", to_delete_ids)]
)
.ids
)
if subpacks_to_delete_ids:
for cmd in vals["order_line"]:
if cmd[1] in subpacks_to_delete_ids:
if cmd[0] != 2:
cmd[0] = 2
subpacks_to_delete_ids.remove(cmd[1])
for to_delete_id in subpacks_to_delete_ids:
vals["order_line"].append([2, to_delete_id, False])
return super().write(vals)
38 changes: 38 additions & 0 deletions sale_product_pack/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Copyright 2019 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from collections import defaultdict

from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.fields import first
Expand Down Expand Up @@ -117,3 +119,39 @@ def action_open_parent_pack_product_view(self):
"view_mode": "tree,form",
"domain": domain,
}

def unlink(self):
for order, lines in self.group_recordset_by(lambda sol: sol.order_id):
pack_component_to_delete = self.env["sale.order.line"].search(
[
("id", "child_of", lines.ids),
("id", "not in", lines.ids),
("order_id", "=", order.id),
]
)
pack_component_to_delete.unlink()
return super().unlink()

def group_recordset_by(self, key):
"""Return a collection of pairs ``(key, recordset)`` from ``self``. The
``key`` is a function computing a key value for each element. This
function is similar to ``itertools.groupby``, but aggregates all
elements under the same key, not only consecutive elements.
it's also similar to ``òdoo.tools.misc.groupby`` but return a recordset
of sale.order.line instead list
this let write some code likes this::
my_recordset.filtered(
lambda record: record.to_use
).group_recordset_by(
lambda record: record.type
)
# TODO: consider moving this method on odoo.models.Model
"""
groups = defaultdict(self.env[self._name].browse)
for elem in self:
groups[key(elem)] |= elem
return groups.items()
193 changes: 192 additions & 1 deletion sale_product_pack/tests/test_sale_product_pack.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Copyright 2019 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo.tests import SavepointCase
from odoo.exceptions import UserError
from odoo.tests import Form, SavepointCase


class TestSaleProductPack(SavepointCase):
Expand Down Expand Up @@ -155,6 +156,7 @@ def qty_in_order():
}
)
total_qty_init = qty_in_order()

# change qty of main sol
main_sol.product_uom_qty = 2 * main_sol.product_uom_qty
total_qty_updated = qty_in_order()
Expand All @@ -169,6 +171,107 @@ def qty_in_order():
total_qty_confirmed = qty_in_order()
self.assertAlmostEqual(total_qty_updated * 2, total_qty_confirmed)

def test_update_qty_do_not_expand(self):
product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
main_sol = self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)
main_sol.with_context(update_prices=True).product_uom_qty = 2
self.assertTrue(
all(
self.sale_order.order_line.filtered(
lambda sol: sol.pack_parent_line_id == main_sol
).mapped(lambda sol: sol.product_uom_qty == 1)
),
)

def test_update_pack_qty_with_new_component(self):

product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
main_sol = self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)

self.assertEqual(
sum(
self.sale_order.order_line.filtered(
lambda sol: sol.pack_parent_line_id == main_sol
).mapped("product_uom_qty")
),
3,
"Expected 3 lines with quantity 1 while setup this test",
)

product_cp.pack_line_ids |= self.env["product.pack.line"].create(
{
"parent_product_id": product_cp.id,
"product_id": self.env.ref("product.product_product_12").id,
"quantity": 2,
}
)

main_sol.product_uom_qty = 2
self.assertEqual(
sum(
self.sale_order.order_line.filtered(
lambda sol: sol.pack_parent_line_id == main_sol
).mapped("product_uom_qty")
),
10,
"Expected 3 lines with quantity 2 and new component line with quantity 4",
)

def test_update_pack_qty_with_new_component_do_not_expand(self):

product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
main_sol = self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)

self.assertEqual(
sum(
self.sale_order.order_line.filtered(
lambda sol: sol.pack_parent_line_id == main_sol
).mapped("product_uom_qty")
),
3,
"Expected 3 lines with quantity 1 while setup this test",
)

product_cp.pack_line_ids |= self.env["product.pack.line"].create(
{
"parent_product_id": product_cp.id,
"product_id": self.env.ref("product.product_product_12").id,
"quantity": 2,
}
)

main_sol.with_context(update_prices=True).product_uom_qty = 2
self.assertEqual(
sum(
self.sale_order.order_line.filtered(
lambda sol: sol.pack_parent_line_id == main_sol
).mapped("product_uom_qty")
),
3,
"Expected 3 lines with quantity 2 and no new component line",
)

def test_do_not_expand(self):
product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
pack_line = self.env["sale.order.line"].create(
Expand Down Expand Up @@ -221,3 +324,91 @@ def test_create_several_lines(self):
self.assertEqual(sequence_tp, self.sale_order.order_line[5].sequence)
self.assertEqual(sequence_tp, self.sale_order.order_line[6].sequence)
self.assertEqual(sequence_tp, self.sale_order.order_line[7].sequence)

def test_copy_sale_order_with_detailed_product_pack(self):

product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)
copied_order = self.sale_order.copy()
copied_order_component_lines_pack_line = copied_order.order_line.filtered(
lambda line: line.product_id.pack_ok
)
copied_order_component_lines = copied_order.order_line.filtered(
lambda line: line.pack_parent_line_id
)
self.assertEqual(
copied_order_component_lines.pack_parent_line_id,
copied_order_component_lines_pack_line,
)

def test_check_pack_line_unlink(self):
product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)
with Form(self.sale_order) as so_form:
with self.assertRaisesRegex(
UserError,
"You cannot delete this line because is part of a pack in this sale order. "
"In order to delete this line you need to delete the pack itself",
):
so_form.order_line.remove(len(self.sale_order.order_line) - 1)

def test_unlink_pack_form_proxy(self):
product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)
with Form(self.sale_order) as so_form:
so_form.order_line.remove(0)
so_form.save()
self.assertEqual(len(self.sale_order.order_line), 0)

def test_unlink_pack_record_unlink(self):
product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)
pack_line = self.sale_order.order_line.filtered(
lambda line: line.product_id.pack_ok
)
pack_line.unlink()
self.assertEqual(len(self.sale_order.order_line), 0)

def test_unlink_pack_old_style_like_ui(self):
product_cp = self.env.ref("product_pack.product_pack_cpu_detailed_components")
self.env["sale.order.line"].create(
{
"order_id": self.sale_order.id,
"name": product_cp.name,
"product_id": product_cp.id,
"product_uom_qty": 1,
}
)
pack_line = self.sale_order.order_line.filtered(
lambda line: line.product_id.pack_ok
)
self.sale_order.write({"order_line": [(2, pack_line.id)]})
self.assertEqual(len(self.sale_order.order_line), 0)

0 comments on commit d544e24

Please sign in to comment.