Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions product_kit_type/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizard
17 changes: 17 additions & 0 deletions product_kit_type/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
'name': 'Product Type Kit',
'version': '1.0',
'category': 'Sales/Sales',
'summary': 'Allow selecting salesperson for pos order',
'depends': ['sale_management'],
'installable': True,
'data': [
'security/ir.model.access.csv',
'views/product_template_form_view.xml',
'views/sale_order_views.xml',
'views/sale_order_customer_preview.xml',
'wizard/views/sub_products_view.xml',
'report/invoice_report.xml'
],
'license': 'LGPL-3',
}
3 changes: 3 additions & 0 deletions product_kit_type/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import product_template
from . import sale_order_line
from . import sale_order
13 changes: 13 additions & 0 deletions product_kit_type/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from odoo import models, fields, api


class InheritedProductTemplate(models.Model):
_inherit = "product.template"

is_kit = fields.Boolean("Is kit?")
sub_products = fields.Many2many("product.product", string="Sub Products")

@api.onchange("is_kit")
def _onchange_is_kit(self):
if not self.is_kit:
self.sub_products = None
7 changes: 7 additions & 0 deletions product_kit_type/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from odoo import models, fields


class InheritedSalesOrder(models.Model):
_inherit = "sale.order"

print_in_report = fields.Boolean()
31 changes: 31 additions & 0 deletions product_kit_type/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from odoo import models, fields, api


class InheritedSalesOrderLine(models.Model):
_inherit = "sale.order.line"

is_kit = fields.Boolean(related="product_template_id.is_kit", store=False)
is_sub_product = fields.Boolean()

def action_sub_products(self):
return {
'name': f'Product: {self.name}',
'view_mode': 'form',
'res_model': 'product_kit_type.subproducts',
'view_id': self.env.ref('product_kit_type.subproducts_view_form').id,
'type': 'ir.actions.act_window',
'target': 'new',
}

@api.ondelete(at_uninstall=False)
def unlink_with_sub_product_lines(self):
for line in self:
if not line.is_sub_product:
sale_order_line_id = line.id
sub_lines = self.search([
('product_id', '=', line.product_id.id),
('is_sub_product', '=', True),
('linked_line_id', '=', sale_order_line_id)
])
if sub_lines:
sub_lines.unlink()
8 changes: 8 additions & 0 deletions product_kit_type/report/invoice_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="sale_order_report_inherit" inherit_id="sale.report_saleorder_document">
<xpath expr="//tbody/t/tr" position="attributes">
<attribute name="t-if">(doc.print_in_report) or (not line.is_sub_product)</attribute>
</xpath>
</template>
</odoo>
3 changes: 3 additions & 0 deletions product_kit_type/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_subproducts,access_product_kit_type.subproducts,product_kit_type.model_product_kit_type_subproducts,base.group_user,1,1,1,
access_subproducts_lines,access_product_kit_type.subproducts.line,product_kit_type.model_product_kit_type_subproducts_line,base.group_user,1,1,1,
14 changes: 14 additions & 0 deletions product_kit_type/views/product_template_form_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="product_template_form_view_inherit" model="ir.ui.view">
<field name="name">product.template.form.inherit.product_type_kit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="arch" type="xml">
<xpath expr="//page[@name='general_information']//group[@name='group_general']" position="inside">
<field name="is_kit" />
<field name="sub_products" invisible="not is_kit" widget="many2many_tags" />
</xpath>
</field>
</record>
</odoo>
9 changes: 9 additions & 0 deletions product_kit_type/views/sale_order_customer_preview.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="sale_portal_templates_report_inherit" inherit_id="sale.sale_order_portal_content">
<xpath expr="//table[@id='sales_order_table']/tbody/t/tr" position="attributes">
<attribute name="t-if">(sale_order.print_in_report) or (not line.is_sub_product)</attribute>
</xpath>
</template>
</odoo>

37 changes: 37 additions & 0 deletions product_kit_type/views/sale_order_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_order_form_inherit" model="ir.ui.view">
<field name="name">sale.order.form.inherit.product_type_kit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='product_template_id']" position="after">
<button name="action_sub_products" icon="fa-tags" title="Sub Products" type="object" invisible="is_kit == False or state != 'draft'" />
</xpath>

<xpath expr="//field[@name='order_line']/list" position="attributes">
<attribute name="decoration-warning">is_sub_product</attribute>
</xpath>

<xpath expr="//field[@name='order_line']/list/field[@name='product_template_id']" position="attributes">
<attribute name="readonly">is_sub_product</attribute>
</xpath>

<xpath expr="//field[@name='order_line']/list/field[@name='product_uom_qty']" position="attributes">
<attribute name="readonly">is_sub_product</attribute>
</xpath>

<xpath expr="//field[@name='order_line']/list/field[@name='price_unit']" position="attributes">
<attribute name="readonly">is_sub_product</attribute>
</xpath>

<xpath expr="//field[@name='order_line']/list/field[@name='tax_id']" position="attributes">
<attribute name="readonly">is_sub_product</attribute>
</xpath>

<xpath expr="//group[@name='order_details']" position="inside">
<field name="print_in_report" string="Print in report?" />
</xpath>
</field>
</record>
</odoo>
2 changes: 2 additions & 0 deletions product_kit_type/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import sub_products
from . import sub_product_line
10 changes: 10 additions & 0 deletions product_kit_type/wizard/sub_product_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from odoo import models, fields


class SubProductLineWizard(models.TransientModel):
_name = "product_kit_type.subproducts.line"

wizard_id = fields.Many2one("product_kit_type.subproducts", required=True)
product_id = fields.Many2one("product.product", string="Product")
product_qty = fields.Float(string="Quantity")
price_unit = fields.Float(string="Price")
73 changes: 73 additions & 0 deletions product_kit_type/wizard/sub_products.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from odoo import models, fields, api


class SubProductsWizard(models.TransientModel):
_name = "product_kit_type.subproducts"
_description = "Sub Products"

sale_order_line_id = fields.Many2one("sale.order.line", string="Sale Order Line")
sub_product_line_ids = fields.One2many("product_kit_type.subproducts.line", "wizard_id", string="Sub Products")

@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)

sale_order_line = self.env["sale.order.line"].browse(self.env.context.get("active_id"))

if sale_order_line:
res["sale_order_line_id"] = sale_order_line.id

existing_lines = self.env["sale.order.line"].search([
("linked_line_id", "=", sale_order_line.id),
("is_sub_product", "=", True)
])

sub_product_lines = []
if existing_lines:
for line in existing_lines:
sub_product_lines.append((0, 0, {
"product_id": line.product_id.id,
"product_qty": line.product_uom_qty,
"price_unit": line.product_id.list_price,
}))
else:
for sub_product in sale_order_line.product_template_id.sub_products:
sub_product_lines.append((0, 0, {
"product_id": sub_product.id,
"product_qty": 1,
"price_unit": sub_product.list_price,
}))

res["sub_product_line_ids"] = sub_product_lines
return res

def action_confirm(self):
self.ensure_one()
sale_order = self.sale_order_line_id.order_id
existing_sub_lines = sale_order.order_line.filtered(lambda line: line.is_sub_product and line.linked_line_id.id == self.sale_order_line_id.id)
existing_sub_product_map = {line.product_id.id: line for line in existing_sub_lines}
total_price = 0

for sub_product in self.sub_product_line_ids:
if sub_product.product_id.id in existing_sub_product_map:
existing_line = existing_sub_product_map[sub_product.product_id.id]
existing_line.write({
"product_uom_qty": sub_product.product_qty,
"price_unit": 0.00,
})
else:
self.env["sale.order.line"].create({
"name": sub_product.product_id.name,
"order_id": self.sale_order_line_id.order_id.id,
"product_id": sub_product.product_id.id,
"product_uom_qty": sub_product.product_qty,
"price_unit": 0.00,
"is_sub_product": True,
'linked_line_id': self.sale_order_line_id.id,
})

total_price += sub_product.product_qty * sub_product.price_unit

self.sale_order_line_id.write({'price_unit': total_price})

return {"type": "ir.actions.act_window_close"}
22 changes: 22 additions & 0 deletions product_kit_type/wizard/views/sub_products_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="subproducts_view_form" model="ir.ui.view">
<field name="name">product_kit_type.subproducts.form</field>
<field name="model">product_kit_type.subproducts</field>
<field name="arch" type="xml">
<form>
<field name="sub_product_line_ids" nolabel="1">
<list editable="bottom" create='0'>
<field name="product_id" />
<field name="product_qty"/>
<field name="price_unit"/>
</list>
</field>
<footer>
<button string="Confirm" type="object" name="action_confirm" class="btn-primary" />
<button string="Cancel" special="cancel" />
</footer>
</form>
</field>
</record>
</odoo>