Skip to content

Commit 16c82fa

Browse files
author
kuay-odoo
committed
[ADD] new_product_type: support for kit products in sale orders
Introduced support for kit products by adding an is kit flag and related sub-products on the product template. Sale order lines have been extended to differentiate between main and sub-products. Sub-products are now handled using related fields and custom logic for display pricing and subtotal computations. Wizard for adding sub-products to main lines introduced. Sub-product lines are made readonly in the UI and their appearance in reports is controlled by a boolean field print in report.
1 parent 5a2ff09 commit 16c82fa

14 files changed

+317
-0
lines changed

new_product_type/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import models
2+
from . import wizard

new_product_type/__manifest__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "New Product Type",
3+
"description": """
4+
"
5+
""",
6+
"version": "0.1",
7+
"depends": ['sale_management'],
8+
"data": [
9+
"security/ir.model.access.csv",
10+
"views/product_template.xml",
11+
"views/sale_order.xml",
12+
"views/sale_order_report.xml",
13+
"wizard/sale_order_wizard.xml"
14+
],
15+
"assets": {},
16+
"license": "AGPL-3",
17+
"installable": True,
18+
"auto-install": True,
19+
}

new_product_type/models/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import product_template
2+
from . import sale_order
3+
from . import sale_order_line
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from odoo import fields, models
2+
3+
4+
class ProductTemplate(models.Model):
5+
_inherit = "product.template"
6+
7+
is_kit = fields.Boolean(string="Is Kit?")
8+
sub_products = fields.Many2many("product.product", string="Sub Products")

new_product_type/models/sale_order.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from odoo import fields, models
2+
3+
4+
class SaleOrder(models.Model):
5+
_inherit = "sale.order"
6+
7+
print_in_report = fields.Boolean(string="Print in Report")
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from odoo import api, fields, models
2+
3+
4+
class SaleOrderLine(models.Model):
5+
_inherit = "sale.order.line"
6+
7+
is_kit = fields.Boolean(related="product_template_id.is_kit")
8+
is_sub_product_ol = fields.Boolean()
9+
main_order_line_id = fields.Many2one(
10+
"sale.order.line",
11+
string="Parent Line",
12+
ondelete="cascade",
13+
)
14+
15+
child_line_ids = fields.One2many(
16+
"sale.order.line",
17+
"main_order_line_id",
18+
string="Child Lines",
19+
)
20+
display_price = fields.Float(
21+
compute="_compute_display_price", inverse="_compute_unit_price"
22+
)
23+
display_sub_total = fields.Float(compute="_compute_amount_price")
24+
25+
@api.depends("price_unit", "is_sub_product_ol")
26+
def _compute_display_price(self):
27+
for line in self:
28+
line.display_price = 0.0 if line.is_sub_product_ol else line.price_unit
29+
30+
@api.depends("display_price", "price_subtotal", "is_sub_product_ol")
31+
def _compute_amount_price(self):
32+
for line in self:
33+
line.display_sub_total = (
34+
0.0 if line.is_sub_product_ol else line.price_subtotal
35+
)
36+
37+
def _compute_unit_price(self):
38+
for line in self:
39+
line.price_unit = line.display_price
40+
41+
def unlink(self):
42+
for line in self:
43+
line.main_order_line_id.price_subtotal -= (
44+
line.product_uom_qty * line.price_unit
45+
)
46+
47+
return super().unlink()
48+
49+
def open_sub_product_wizard(self):
50+
return {
51+
"name": "Sale order line wizard action",
52+
"type": "ir.actions.act_window",
53+
"res_model": "sale.order.wizard",
54+
"view_mode": "form",
55+
"target": "new",
56+
"context": {"active_id": self.id},
57+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2+
new_product_type.access_sale_order_wizard,access_sale_order_wizard,new_product_type.model_sale_order_wizard,base.group_user,1,1,1,1
3+
new_product_type.access_sale_order_line_wizard,access_sale_order_line_wizard,new_product_type.model_sale_order_line_wizard,base.group_user,1,1,1,1
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<record id="product_template_form_view" model="ir.ui.view">
4+
<field name="name">product.template.form.view</field>
5+
<field name="model">product.template</field>
6+
<field name="inherit_id" ref="product.product_template_form_view" />
7+
<field name="arch" type="xml">
8+
<xpath expr="//field[@name='product_tooltip']" position="after">
9+
<group>
10+
<field name="is_kit" />
11+
<field name="sub_products" widget="many2many_tags" invisible="not is_kit" />
12+
</group>
13+
</xpath>
14+
</field>
15+
</record>
16+
</odoo>

new_product_type/views/sale_order.xml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version="1.0"?>
2+
<odoo>
3+
<record id="view_order_form" model="ir.ui.view">
4+
<field name="name">Sale.Order.View.Form.Inherit.kit</field>
5+
<field name="model">sale.order</field>
6+
<field name="inherit_id" ref="sale.view_order_form" />
7+
<field name="arch" type="xml">
8+
<xpath expr="//sheet//group[@name='sale_header']//group[@name='order_details']"
9+
position="inside">
10+
<field name="print_in_report" />
11+
</xpath>
12+
<xpath expr="//field[@name='product_template_id']" position="after">
13+
<button name='open_sub_product_wizard' type="object" string="Add Sub-Product"
14+
invisible="not is_kit or state=='sale'" />
15+
</xpath>
16+
<xpath expr="//field[@name='order_line']//list//field[@name='product_template_id']"
17+
position="attributes">
18+
<attribute name="readonly">is_sub_product_ol</attribute>
19+
</xpath>
20+
<xpath expr="//field[@name='order_line']//list//field[@name='product_uom_qty']"
21+
position="attributes">
22+
<attribute name="readonly">is_sub_product_ol</attribute>
23+
</xpath>
24+
<xpath expr="//field[@name='order_line']//list//field[@name='price_unit']"
25+
position="attributes">
26+
<attribute name="readonly">is_sub_product_ol</attribute>
27+
<attribute name="column_invisible">True</attribute>
28+
</xpath>
29+
<xpath expr="//field[@name='order_line']//list//field[@name='price_unit']"
30+
position="after">
31+
<field name="display_price" string="Unit Price" />
32+
</xpath>
33+
<xpath expr="//field[@name='order_line']//list//field[@name='display_price']"
34+
position="attributes">
35+
<attribute name="readonly">is_sub_product_ol</attribute>
36+
</xpath>
37+
<xpath expr="//field[@name='order_line']//list//field[@name='price_subtotal']"
38+
position="after">
39+
<field name="display_sub_total" string="Amount" />
40+
</xpath>
41+
<xpath expr="//field[@name='order_line']//list//field[@name='price_subtotal']"
42+
position="attributes">
43+
<attribute name="column_invisible">True</attribute>
44+
</xpath>
45+
</field>
46+
</record>
47+
</odoo>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0"?>
2+
<odoo>
3+
<template id="report_saleorder_document" inherit_id="sale.report_saleorder_document">
4+
<xpath expr="//t[@t-foreach='lines_to_report']/tr" position="attributes">
5+
<attribute name="t-if">(not line.is_sub_product_ol or (doc.print_in_report and
6+
line.is_sub_product_ol))</attribute>
7+
</xpath>
8+
</template>
9+
10+
<template id="sale_order_portal_content" inherit_id="sale.sale_order_portal_content">
11+
<xpath expr="//t[@t-foreach='lines_to_report']/tr" position="attributes">
12+
<attribute name="t-if">(not line.is_sub_product_ol or (doc.print_in_report and
13+
line.is_sub_product_ol))</attribute>
14+
</xpath>
15+
</template>
16+
</odoo>

0 commit comments

Comments
 (0)