oca-ocb-sale/odoo-bringout-oca-ocb-sale/sale/tests/test_sale_sections.py
Ernad Husremovic 73afc09215 19.0 vanilla
2026-03-09 09:32:12 +01:00

142 lines
5.5 KiB
Python

from odoo.fields import Command
from odoo.tests import tagged
from odoo.addons.sale.tests.common import SaleCommon
@tagged('post_install', '-at_install')
class TestSaleSections(SaleCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.tax_1 = cls.env['account.tax'].create({
'name': 'Tax 1',
'amount': 10,
})
cls.tax_2 = cls.env['account.tax'].create({
'name': 'Tax 2',
'amount': 20,
})
cls.sections_sale_order = cls.env['sale.order'].create({
'partner_id': cls.partner.id,
'order_line': [
Command.create({
'name': 'r1',
'product_id': cls.product.id,
'price_unit': 10,
}),
Command.create({
'name': 'Sec1',
'display_type': 'line_section',
}),
Command.create({
'name': 'Sec1-r1',
'product_id': cls.product.id,
'tax_ids': cls.tax_2.ids,
'price_unit': 200,
}),
Command.create({
'name': 'Sec1-Sub1',
'display_type': 'line_subsection',
'collapse_composition': True,
}),
Command.create({
'name': 'Sec1-Sub1-r1',
'product_id': cls.product.id,
'tax_ids': (cls.tax_1 + cls.tax_2).ids,
'price_unit': 300,
}),
Command.create({
'name': 'Sec1-Sub1-r2',
'product_id': cls.product.id,
'tax_ids': (cls.tax_1 + cls.tax_2).ids,
'price_unit': 300,
}),
Command.create({
'name': 'Sec1-Sub1-r3',
'product_id': cls.product.id,
'tax_ids': cls.tax_1.ids,
'price_unit': 100,
}),
Command.create({
'name': 'Sec1-Sub2',
'display_type': 'line_subsection',
'collapse_composition': True,
}),
Command.create({
'name': 'Sec1-Sub2-r1',
'product_id': cls.product.id,
'tax_ids': cls.tax_2.ids,
'price_unit': 200,
}),
Command.create({
'name': 'Sec1-Sub2-r2',
'product_id': cls.product.id,
'tax_ids': cls.tax_1.ids,
'price_unit': 100,
}),
],
})
def test_sale_order_line_parent_id(self):
"""Verify correct assignment of `parent_id`:
- Lines with no preceding section/subsection → no parent.
- Section's children (lines + subsections) → parent is the section.
- Subsection's children → parent is the subsection.
"""
self.assertFalse(self.sections_sale_order.order_line[0].parent_id)
self.assertEqual(
self.sections_sale_order.order_line[2].parent_id,
self.sections_sale_order.order_line[1],
)
self.assertEqual(
self.sections_sale_order.order_line[3].parent_id,
self.sections_sale_order.order_line[1],
)
self.assertEqual(
self.sections_sale_order.order_line[4].parent_id,
self.sections_sale_order.order_line[3],
)
def test_sale_order_report_line_visibility_and_grouping(self):
"""Check report utils for sections.
- `_get_order_lines_to_report` must exclude children of collapsed sections/subsections,
but keep regular lines and headers in order.
- `_get_grouped_section_summary` must correctly aggregate totals by tax.
"""
lines_to_report = self.sections_sale_order._get_order_lines_to_report()
self.assertEqual(len(lines_to_report), 5)
self.assertEqual(
lines_to_report.mapped('name'),
['r1', 'Sec1', 'Sec1-r1', 'Sec1-Sub1', 'Sec1-Sub2'],
"Lines of hidden subsection shouldn't be visible in report",
)
subsection_summary_lines = lines_to_report[3]._get_grouped_section_summary()
self.assertEqual(len(subsection_summary_lines), 2)
self.assertEqual(subsection_summary_lines[0]['price_subtotal'], 600.00)
self.assertEqual(subsection_summary_lines[1]['price_subtotal'], 100.00)
def test_sale_order_sections_totals(self):
"""Ensure section totals are computed correctly.
A `line_section` should aggregate the subtotals of all following product
order lines that belong to it, including those under nested subsections.
Aggregation must stop when another section or subsection is encountered.
"""
self.assertEqual(
self.sections_sale_order.order_line[1]._get_section_totals('price_subtotal'),
sum(self.sections_sale_order.order_line[1:].mapped('price_subtotal')),
)
self.assertEqual(
self.sections_sale_order.order_line[3]._get_section_totals('price_subtotal'),
sum(self.sections_sale_order.order_line[4:7].mapped('price_subtotal')),
)
self.assertEqual(
self.sections_sale_order.order_line[7]._get_section_totals('price_subtotal'),
sum(self.sections_sale_order.order_line[8:].mapped('price_subtotal')),
)