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 new_product_type/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizard
14 changes: 14 additions & 0 deletions new_product_type/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "New Product Type",
"version": "1.0",
'author': "abkus",
"depends": ["sale", "product"],
"data": [
"security/ir.model.access.csv",
"views/product_kit_wizard_views.xml",
"views/product_views.xml",
"views/sale_order_line_views.xml",
],
"installable": True,
'license': 'LGPL-3',
}
2 changes: 2 additions & 0 deletions new_product_type/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import product_template
from . import sale_order_line
8 changes: 8 additions & 0 deletions new_product_type/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


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

is_kit = fields.Boolean()
sub_product_ids = fields.Many2many('product.product')
32 changes: 32 additions & 0 deletions new_product_type/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from odoo import api, fields, models, _
from odoo.exceptions import UserError


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

is_kit = fields.Boolean(
related="product_id.product_tmpl_id.is_kit",
store=True
)
is_kit_product = fields.Boolean()
kit_parent_line_id = fields.Many2one('sale.order.line', ondelete='cascade')
extra_price = fields.Float(default=0.0)

@api.ondelete(at_uninstall=False)
def _check_kit_product_restriction(self):
for line in self:
if line.is_kit_product:
raise UserError(_("You can't direclty delete the sub product"))

def action_open_kit_wizard(self):
return {
"type": "ir.actions.act_window",
"name": "Configure Kit",
"res_model": "product.kit.wizard",
"view_mode": "form",
"target": "new",
"context": {
"active_id": self.id
},
}
3 changes: 3 additions & 0 deletions new_product_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_create,perm_write,perm_unlink
access_product_wizard_kit_line,access_product_wizard_kit_line,model_product_wizard_kit_line,base.group_user,1,1,1,1
access_product_kit_wizard,access_product_kit_wizard,model_product_kit_wizard,base.group_user,1,1,1,1
25 changes: 25 additions & 0 deletions new_product_type/views/product_kit_wizard_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="product_kit_wizard_form" model="ir.ui.view">
<field name="name">product.kit.wizard.form</field>
<field name="model">product.kit.wizard</field>
<field name="arch" type="xml">
<form string="Configure Kit">
<sheet>
<group>
<field name="main_product_id" readonly="1" class="fw-bold"/>
</group>
<separator string="Sub Products"/>
<field name="line_ids" nolabel="1">
<list editable="bottom" create="false" class="table table-sm">
<field name="product_id" readonly="1" optional="show" force_save="1"/>
<field name="quantity" widget="float" sum="Total quantity"/>
<field name="price" widget="float"/>
<field name="price_subtotal" string="Total Amount" sum="Grand Total"/>
</list>
</field>
</sheet>
</form>
</field>
</record>
</odoo>
17 changes: 17 additions & 0 deletions new_product_type/views/product_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="product_template_view_form" model="ir.ui.view">
<field name="name">product.template.view_form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_only_form_view" />
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_policy']" position="after">
<field name="is_kit" />
</xpath>
<xpath expr="//field[@name='is_kit']" position="after">
<field name="sub_product_ids" widgets="many2many_tags"
options="{'no_create': True}" invisible="not is_kit" />
</xpath>
</field>
</record>
</odoo>
20 changes: 20 additions & 0 deletions new_product_type/views/sale_order_line_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="sale_order_line_form_view" model="ir.ui.view">
<field name="name">sale.order.line.form.view</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='order_line']/list" position="attributes">
<attribute name="decoration-warning">is_kit_product</attribute>
</xpath>
<xpath expr="//field[@name='product_template_id']" position="after">
<button name="action_open_kit_wizard"
type="object"
string="Configure Kit"
class="btn-primary"
invisible="not is_kit or state!='draft'" />
</xpath>
</field>
</record>
</odoo>
2 changes: 2 additions & 0 deletions new_product_type/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import product_kit_wizard_line
from . import product_kit_wizard
59 changes: 59 additions & 0 deletions new_product_type/wizard/product_kit_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from odoo import api, fields, models


class ProductKitWizard(models.TransientModel):
_name = "product.kit.wizard"
_description = "Sub Product Kit Wizard"

main_product_id = fields.Many2one(
'product.product',
string="Product",
)
sale_line_id = fields.Many2one('sale.order.line')
line_ids = fields.One2many(
'product.wizard.kit.line',
'wizard_id',
string="Sub Product"
)

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

sale_line = self.env['sale.order.line'].browse(
self.env.context.get('active_id')
)
if not sale_line.product_id:
return res
order = sale_line.order_id
product = sale_line.product_id
lines = []

for sub_product in product.product_tmpl_id.sub_product:
existing_line = order.order_line.filtered(
lambda l:
l.product_id == sub_product
and l.kit_parent_line_id == sale_line
)[:1]

lines.append(
(0, 0, {
"product_id": sub_product.id,
"quantity": (
existing_line.product_uom_qty
if existing_line else 1.0
),
"price": (
existing_line.extra_price
if existing_line else sub_product.lst_price
),
})
)

res.update({
"sale_line_id": sale_line.id,
"main_product_id": product.id,
"line_ids": lines,
})

return res
24 changes: 24 additions & 0 deletions new_product_type/wizard/product_kit_wizard_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from odoo import api, fields, models


class ProductKitWizardLine(models.TransientModel):
_name = "product.wizard.kit.line"
_description = "Kit Wizard Line"

wizard_id = fields.Many2one('product.kit.wizard')
product_id = fields.Many2one(
'product.product',
readonly=True
)
quantity = fields.Float(default=1.0)
price = fields.Float()
price_subtotal = fields.Float(
string="Total Amount",
compute="_check_total_price",
store=True
)

@api.depends('quantity', 'price')
def _check_total_price(self):
for line in self:
line.price_subtotal = line.quantity * line.price