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
18 changes: 18 additions & 0 deletions new_product_type/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "New Product Kit",
"version": "1.0",
'author': "Ruchita Gothi (Rugot)",
"depends": ["sale", "product", 'account'],
"data": [
'security/ir.model.access.csv',
"views/product_views.xml",
"views/sale_order_line_views.xml",
"views/kit_wizard_views.xml",
"report/sale_order_report.xml",
"report/invoice_report.xml",
"report/sale_order_portal_report.xml",

],
"installable": True,
'license': 'LGPL-3',
}
3 changes: 3 additions & 0 deletions new_product_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
15 changes: 15 additions & 0 deletions new_product_type/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from odoo import models, fields, api
from odoo.exceptions import ValidationError


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

is_kit = fields.Boolean()
sub_product = fields.Many2many("product.product")

@api.constrains("sub_product")
def _check_no_self_product_reference(self):
for record in self:
if record.product_variant_id in record.sub_product:
raise ValidationError("A product cannot be added as a sub-product in its own kit.")
7 changes: 7 additions & 0 deletions new_product_type/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from odoo import fields, models


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

print_in_report = fields.Boolean()
38 changes: 38 additions & 0 deletions new_product_type/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from odoo import models, fields, _
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")
extra_price = fields.Float(default=0.0)

def unlink(self):
parents_in_self = self.filtered(lambda l: not l.is_kit_product)
# parents = self.env["sale.order.line"].search([
# ("id", "in", self.ids),
# ("is_kit_product", "=", False),
# ])
children_in_self = self.filtered(lambda l: l.is_kit_product)
for child in children_in_self:
if child.kit_parent_line_id not in parents_in_self:
raise UserError(_("You cannot delete a kit sub product directly."))
child_lines = self.search([
("kit_parent_line_id", "in", parents_in_self.ids)
])
if child_lines:
child_lines.unlink()
return super().unlink()

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},
}
13 changes: 13 additions & 0 deletions new_product_type/report/invoice_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<odoo>

<template id="report_invoice_document_inherit_print_option"
inherit_id="account.report_invoice_document">
<xpath expr="//t[@t-set='lines_to_report']" position="attributes">
<attribute name="t-value">
o._get_move_lines_to_report().filtered(lambda l: not (any(sl.is_kit_product for sl in l.sale_line_ids)
and not any(sl.order_id.print_in_report for sl in l.sale_line_ids)))
</attribute>
</xpath>
</template>

</odoo>
14 changes: 14 additions & 0 deletions new_product_type/report/sale_order_portal_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<odoo>

<template id="sale_order_portal_content_inherit_print_option"
inherit_id="sale.sale_order_portal_content">
<xpath expr="//t[@t-set='lines_to_report']" position="attributes">
<attribute name="t-value">
sale_order._get_order_lines_to_report().filtered(
lambda l: not l.is_kit_product or sale_order.print_in_report
)
</attribute>
</xpath>
</template>

</odoo>
15 changes: 15 additions & 0 deletions new_product_type/report/sale_order_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>

<template id="report_saleorder_document_inherit_print_option"
inherit_id="sale.report_saleorder_document">
<xpath expr="//t[@t-set='lines_to_report']" position="attributes">
<attribute name="t-value">
doc._get_order_lines_to_report().filtered(
lambda l: not l.is_kit_product or doc.print_in_report
)
</attribute>
</xpath>
</template>

</odoo>
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_write,perm_create,perm_unlink
product_kit_wizard,product_kit_wizard,model_product_kit_wizard,base.group_user,1,1,1,1
kit_wizard_line,kit_wizard_line,model_kit_wizard_line,base.group_user,1,1,1,1
29 changes: 29 additions & 0 deletions new_product_type/views/kit_wizard_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<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">
<group>
<field name="main_product_id" readonly="1" force_save="1"/>
</group>
<group>
<div class="fw-bold fs-4">Sub Products</div>
<field name="line_ids" nolabel="1">
<list editable="bottom" create="false">
<field name="product_id" readonly="1" force_save="1"/>
<field name="quantity"/>
<field name="price"/>
</list>
</field>
</group>
<footer>
<button name="action_confirm" type="object" class="btn-primary" string="Confirm"/>
<button string="Cancel" special="cancel" class="btn-secondary"/>
</footer>
</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 @@
<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" widget="many2many_tags"
options="{'no_create': True}" invisible="not is_kit"/>
</xpath>
</field>
</record>
</odoo>
40 changes: 40 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,40 @@
<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="type">form</field>-->
<field name="arch" type="xml">
<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>
<xpath expr="//field[@name='order_line']/list/field[@name='product_id']" position="attributes">
<attribute name="readonly">is_kit_product</attribute>
</xpath>

<xpath expr="//field[@name='order_line']/list/field[@name='product_template_id']" position="attributes">
<attribute name="readonly">is_kit_product</attribute>
</xpath>
<xpath expr="//field[@name='order_line']/list/field[@name='price_unit']" position="attributes">
<attribute name="readonly">is_kit_product</attribute>
</xpath>
<xpath expr="//field[@name='order_line']/list/field[@name='product_uom_qty']" position="attributes">
<attribute name="readonly">is_kit_product</attribute>
</xpath>
<xpath expr="//field[@name='order_line']/list/field[@name='tax_ids']" position="attributes">
<attribute name="readonly">is_kit_product</attribute>
</xpath>
<xpath expr="//field[@name='payment_term_id']" position="after">
<field name="print_in_report"/>
</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 kit_wizard_line
from . import kit_wizard
93 changes: 93 additions & 0 deletions new_product_type/wizard/kit_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from odoo import models, fields, api

from odoo.fields import Command


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

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

@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
sale_line = self.env["sale.order.line"].browse(self._context.get("active_id"))
if sale_line.product_id:
product = sale_line.product_id
sale_order = sale_line.order_id
kit_sub_product = []
for sub in product.product_tmpl_id.sub_product:
existing_line = sale_order.order_line.filtered(
lambda line: line.product_id == sub
and line.kit_parent_line_id == sale_line
)
# existing_line = self.env["sale.order.line"].search([
# ("order_id", "=", sale_order.id),
# ("product_id", "=", sub.id),
# ("kit_parent_line_id", "=", sale_line.id),
# ], limit=1)

kit_sub_product.append(
Command.create(
{
"product_id": sub.id,
"quantity": existing_line.product_uom_qty if existing_line else 1.0,
"price": existing_line.extra_price if existing_line else sub.lst_price,
# "existing_line_id": existing_line.id if existing_line else False,
}
)
)

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

def action_confirm(self):
order = self.sale_line_id.order_id
Parent_kit_product_line = self.sale_line_id
parent_product = Parent_kit_product_line.product_id
parent_sequence = Parent_kit_product_line.sequence
total_price = parent_product.list_price
for wizard_line in self.line_ids:
existing_line = order.order_line.filtered(
lambda line: line.product_id == wizard_line.product_id
and line.kit_parent_line_id == Parent_kit_product_line

)
# existing_line = self.env["sale.order.line"].search([
# ("order_id", "=", order.id),
# ("product_id", "=", wizard_line.product_id.id),
# ("kit_parent_line_id", "=", Parent_kit_product_line.id),
# ], limit=1)
values = {
"product_uom_qty": wizard_line.quantity,
"price_unit": 0.0,
"extra_price": wizard_line.price,
"sequence": parent_sequence,
}

if existing_line:
existing_line.write(values)
else:
self.env["sale.order.line"].create(
{
**values,
"name": wizard_line.product_id.name,
"order_id": order.id,
"product_id": wizard_line.product_id.id,
"is_kit_product": True,
"kit_parent_line_id": Parent_kit_product_line.id,
}
)

total_price += wizard_line.price * wizard_line.quantity

Parent_kit_product_line.write({"price_unit": total_price})
12 changes: 12 additions & 0 deletions new_product_type/wizard/kit_wizard_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from odoo import models, fields


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

wizard_id = fields.Many2one("product.kit.wizard")
product_id = fields.Many2one("product.product", readonly=True)
quantity = fields.Float()
price = fields.Float()
# existing_line_id = fields.Many2one("sale.order.line", string="Existing Product order line")