Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,168 @@
# Copyright 2024 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from odoo.tests import Form
from odoo.addons.base.tests.common import BaseCommon
class TestSplitStrategy(BaseCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.product_consu_1 = cls.env["product.product"].search(
[("type", "!=", "service")], limit=1
)
cls.product_consu_2 = cls.env["product.product"].search(
[("type", "!=", "service")], offset=1, limit=1
)
cls.product_service_1 = cls.env["product.product"].search(
[("type", "=", "service")], limit=1
)
cls.product_service_2 = cls.env["product.product"].search(
[("type", "=", "service")], offset=1, limit=1
)
cls.product_type_not_service_filter = cls.env["ir.filters"].create(
{
"name": "Product type not service",
"domain": "[('product_id.type', '!=', 'service')]",
"model_id": "sale.order.line",
}
)
cls.product_type_not_service_strategy = cls.env[
"sale.order.split.strategy"
].create(
{
"name": "Product type",
"line_filter_id": cls.product_type_not_service_filter.id,
}
)
@classmethod
def _create_order(cls):
order_form = Form(cls.env["sale.order"])
order_form.partner_id = cls.env["res.partner"].search([], limit=1)
for product in [
cls.product_consu_1,
cls.product_consu_2,
cls.product_service_1,
cls.product_service_2,
]:
with order_form.order_line.new() as line_form:
line_form.product_id = product
line_form.product_uom_qty = 1
return order_form.save()
def _set_sequences_and_sections(self, order):
for seq, line in enumerate(order.order_line, 1):
line.sequence = seq * 10
# First section includes only consumable
first_section = order.order_line.create(
{
"order_id": order.id,
"display_type": "line_section",
"name": "First line",
"sequence": 5,
}
)
# Middle section includes both consumable + service
middle_section = order.order_line.create(
{
"order_id": order.id,
"display_type": "line_section",
"name": "Middle lines",
"sequence": 15,
}
)
# Last section includes only service
last_section = order.order_line.create(
{
"order_id": order.id,
"display_type": "line_section",
"name": "Last line",
"sequence": 35,
}
)
order_lines = order.order_line.sorted()
self.assertEqual(order_lines[0], first_section)
self.assertEqual(order_lines[2], middle_section)
self.assertEqual(order_lines[5], last_section)
def test_split_product_type(self):
order = self._create_order()
order.split_strategy_id = self.product_type_not_service_strategy
self.assertEqual(len(order.order_line), 4)
new_order = order.action_split()
self.assertEqual(len(order.order_line), 2)
self.assertNotIn(self.product_consu_1, order.order_line.mapped("product_id"))
self.assertNotIn(self.product_consu_2, order.order_line.mapped("product_id"))
self.assertIn(self.product_service_1, order.order_line.mapped("product_id"))
self.assertIn(self.product_service_2, order.order_line.mapped("product_id"))
self.assertEqual(len(new_order.order_line), 2)
self.assertIn(self.product_consu_1, new_order.order_line.mapped("product_id"))
self.assertIn(self.product_consu_2, new_order.order_line.mapped("product_id"))
self.assertNotIn(
self.product_service_1, new_order.order_line.mapped("product_id")
)
self.assertNotIn(
self.product_service_2, new_order.order_line.mapped("product_id")
)
def test_split_product_type_copy_sections(self):
order = self._create_order()
self._set_sequences_and_sections(order)
order.order_line.sorted()
self.product_type_not_service_strategy.copy_sections = True
order.split_strategy_id = self.product_type_not_service_strategy
new_order = order.action_split()
# As new order includes only consu product, it must include
# first + middle sections
self.assertEqual(len(new_order.order_line), 4)
self.assertIn("First line", new_order.order_line.mapped("name"))
self.assertIn("Middle lines", new_order.order_line.mapped("name"))
self.assertNotIn("Last line", new_order.order_line.mapped("name"))
# As new order includes only service product, it must include
# middle + last sections
self.assertEqual(len(order.order_line), 4)
self.assertNotIn("First line", order.order_line.mapped("name"))
self.assertIn("Middle lines", order.order_line.mapped("name"))
self.assertIn("Last line", order.order_line.mapped("name"))
def test_split_product_type_not_copy_sections(self):
order = self._create_order()
self._set_sequences_and_sections(order)
self.assertFalse(self.product_type_not_service_strategy.copy_sections)
order.split_strategy_id = self.product_type_not_service_strategy
new_order = order.action_split()
# New order does not have any section
self.assertEqual(len(new_order.order_line), 2)
self.assertNotIn("line_section", new_order.order_line.mapped("display_type"))
# Old order keeps all the sections
self.assertEqual(len(order.order_line), 5)
self.assertIn("First line", order.order_line.mapped("name"))
self.assertIn("Middle lines", order.order_line.mapped("name"))
self.assertIn("Last line", order.order_line.mapped("name"))
def test_split_product_type_not_copy_sections_remove_empty(self):
order = self._create_order()
self._set_sequences_and_sections(order)
# Add extra empty section at the end
order.order_line.create(
{
"order_id": order.id,
"display_type": "line_section",
"name": "Empty section",
"sequence": 999,
}
)
self.assertFalse(self.product_type_not_service_strategy.copy_sections)
self.product_type_not_service_strategy.remove_empty_sections_after_split = True
order.split_strategy_id = self.product_type_not_service_strategy
order.action_split()
# Old order has empty sections removed
self.assertEqual(len(order.order_line), 4)
self.assertNotIn("First line", order.order_line.mapped("name"))
self.assertIn("Middle lines", order.order_line.mapped("name"))
self.assertIn("Last line", order.order_line.mapped("name"))
self.assertNotIn("Empty section", order.order_line.mapped("name"))