Skip to content

Commit

Permalink
[ADD] product_warranty: add product warranty module
Browse files Browse the repository at this point in the history
Add product warranty module which adds warranty product by clicking on 'Add
Warranty' button in quotation on addition of related product in sales order line
Also by deleting the product warranty will also get removed. Add warranty as
sale order line so we can see it as any other product in sales order in print
report.

Firstly we need to configure warranty from warranty config.(Which is located
in sales-> menu -> Configuration -> (Under product section) -> Warranty Config)

By clicking on is warranty product on product template's sales section we can
mark that product as warranty product.

task - 4504888
  • Loading branch information
nipl-odoo committed Jan 24, 2025
1 parent 51536f4 commit f9ffd66
Show file tree
Hide file tree
Showing 15 changed files with 267 additions and 0 deletions.
2 changes: 2 additions & 0 deletions product_warranty/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizard
21 changes: 21 additions & 0 deletions product_warranty/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "Product Warranty",
"version": "1.0",
"category": "Sales/Warranty",
"summary": "Add warranty information to products and display it on sale order lines.",
"description": """
This module provides functionality to manage product warranties.
Users can define warranties for products and see warranty details in sale order lines.
""",
"license": "AGPL-3",
"depends": ["base", "sale_management"],
"data": [
"security/ir.model.access.csv",
"views/product_template_views.xml",
"views/product_warranty_config_menu.xml",
"views/product_warranty_config_views.xml",
"views/sale_order_views.xml",
"wizard/product_warranty_wizard_view.xml",
],
"auto_install": True,
}
3 changes: 3 additions & 0 deletions product_warranty/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
from . import warranty_config
7 changes: 7 additions & 0 deletions product_warranty/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from odoo import fields, models


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

is_warranty_product = fields.Boolean("Is Warranty Product")
34 changes: 34 additions & 0 deletions product_warranty/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from odoo import api, Command, models


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

def action_open_warranty_wizard(self):
return {
"name": "Add Warranty",
"type": "ir.actions.act_window",
"res_model": "product.warranty.wizard",
"view_mode": "form",
"target": "new",
}

@api.onchange("order_line")
def _onchange_order_line(self):
super()._onchange_order_line()
deleted_product_template_ids = []
for line in self.order_line:
# Find each products that is not in Sale Order currently
if (
line.linked_line_id.id
and line.linked_line_id.id not in self.order_line.ids
):
deleted_product_template_ids.append(line.linked_line_id.id)

linked_line_ids_to_delete = self.order_line.search(
[("linked_line_id", "in", deleted_product_template_ids)]
)
self.order_line = [
Command.unlink(linked_line_id)
for linked_line_id in linked_line_ids_to_delete.ids
]
17 changes: 17 additions & 0 deletions product_warranty/models/warranty_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from odoo import fields, models


class ProductWarrantyConfig(models.Model):
_name = "product.warranty.config"
_description = "Product Warranty Configuration"

name = fields.Char(string="Name", required=True)
product_template_id = fields.Many2one(
"product.template", string="Product", required=True
)
percentage = fields.Float(string="Percentage", required=True)
years = fields.Integer(string="Years", required=True)

_sql_constraints = [
("name_uniq", "unique (name)", "Two Waranties can not be of same name"),
]
4 changes: 4 additions & 0 deletions product_warranty/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
product_warranty.access_product_warranty_config,access_product_warranty_config,product_warranty.model_product_warranty_config,base.group_user,1,1,1,1
product_warranty.access_prodcut_warranty_wizard,access_prodcut_warranty_wizard,product_warranty.model_product_warranty_wizard,base.group_user,1,1,1,1
product_warranty.access_product_warranty_wizard_line,access_product_warranty_wizard_line,product_warranty.model_product_warranty_wizard_line,base.group_user,1,1,1,1
18 changes: 18 additions & 0 deletions product_warranty/views/product_template_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="product_template_form_view_inherit_product_warranty" model="ir.ui.view">
<field name="name">product.template.view.form.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='upsell']" position="after">
<group string="Warranty">
<field name="is_warranty_product" />
</group>
</xpath>

</field>
</record>

</odoo>
4 changes: 4 additions & 0 deletions product_warranty/views/product_warranty_config_menu.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<menuitem id="product_warranty_config_menu" name="Warranty Config" action="product_warranty.product_warranty_config_action" parent="sale.prod_config_main" sequence="10"/>
</odoo>
28 changes: 28 additions & 0 deletions product_warranty/views/product_warranty_config_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="product_warranty_config_action" model="ir.actions.act_window">
<field name="name">Warranty Config</field>
<field name="res_model">product.warranty.config</field>
<field name="view_mode">list</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Define new warranty
</p>
</field>
</record>

<record id="product_warranty_config_view_list" model="ir.ui.view">
<field name="name">product.warranty.config.view.tree</field>
<field name="model">product.warranty.config</field>
<field name="arch" type="xml">
<list string="Warranty Config" sample="1" editable="bottom">
<field name="name" />
<field name="product_template_id" />
<field name="percentage" />
<field name="years" />
</list>
</field>
</record>

</odoo>
15 changes: 15 additions & 0 deletions product_warranty/views/sale_order_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="view_order_form_inherit_product_warranty" model="ir.ui.view">
<field name="name">sale.order.view.form.inherit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='so_button_below_order_lines']" position="inside">
<button string="Add Warranty" name="action_open_warranty_wizard" type="object" class="btn btn-secondary"/>
</xpath>
</field>
</record>

</odoo>
2 changes: 2 additions & 0 deletions product_warranty/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import product_warranty_wizard
from . import product_warranty_wizard_line
51 changes: 51 additions & 0 deletions product_warranty/wizard/product_warranty_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from odoo import api, Command, fields, models


class WarrantyWizard(models.TransientModel):
_name = "product.warranty.wizard"
_description = "Warranty Selection Wizard"

sale_order_id = fields.Many2one("sale.order", string="Sale Order")
line_ids = fields.One2many(
"product.warranty.wizard.line", "wizard_id", string="Warranty Lines"
)

@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
sale_order = self.env["sale.order"].browse(self.env.context.get("active_id"))
warranty_lines = []

for line in sale_order.order_line.filtered(
lambda line: line.product_template_id and line.product_template_id.is_warranty_product
):
warranty = self.env["product.warranty.wizard.line"].create(
{
"sale_order_line_id": line.id,
"warranty_config_id": False,
}
)
warranty_lines.append(Command.link(warranty.id))

res["sale_order_id"] = sale_order.id
res["line_ids"] = warranty_lines
return res

def apply_warranty(self):
for line in self.line_ids:
product = self.env["product.template"].browse(line.product_template_id.id)
if line.warranty_config_id:
self.env["sale.order.line"].create(
{
"order_id": self.sale_order_id.id,
"product_template_id": line.warranty_config_id.product_template_id.id,
"name": "Extended Warranty of %d Years - %s"
% (line.warranty_config_id.years, product.name),
"product_uom_qty": 1,
"linked_line_id": line.sale_order_line_id.id,
"price_unit": (line.warranty_config_id.percentage / 100)
* line.sale_order_line_id.price_subtotal,
}
)

return {"type": "ir.actions.act_window_close"}
34 changes: 34 additions & 0 deletions product_warranty/wizard/product_warranty_wizard_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from datetime import datetime
from dateutil.relativedelta import relativedelta

from odoo import models, fields, api


class WarrantyWizardLine(models.TransientModel):
_name = "product.warranty.wizard.line"
_description = "Warranty Wizard Line"

wizard_id = fields.Many2one("product.warranty.wizard", string="Wizard")
sale_order_line_id = fields.Many2one("sale.order.line", string="Sale Order Line")
product_template_id = fields.Many2one(
"product.template", string="Product", compute="_compute_product_template_id"
)
warranty_config_id = fields.Many2one(
"product.warranty.config", string="Warranty Type"
)
date_end = fields.Date(string="Date End", compute="_compute_date_end")

@api.depends("warranty_config_id.years")
def _compute_date_end(self):
for line in self:
line.date_end = datetime.today() + relativedelta(
years=line.warranty_config_id.years
)

@api.depends("sale_order_line_id")
def _compute_product_template_id(self):
for line in self:
if line.sale_order_line_id:
line.product_template_id = line.sale_order_line_id.product_template_id
else:
line.product_template_id = False
27 changes: 27 additions & 0 deletions product_warranty/wizard/product_warranty_wizard_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_product_warranty_wizard_form" model="ir.ui.view">
<field name="name">product.warranty.wizard.form</field>
<field name="model">product.warranty.wizard</field>
<field name="arch" type="xml">
<form string="Add Warranty" nolabel="1">
<sheet>
<group>
<field name="sale_order_id" invisible="1"/>
<field name="line_ids">
<list editable="bottom" delete="0" create="0">
<field name="product_template_id" readonly="1"/>
<field name="warranty_config_id" options="{'no_create': True}"/>
<field name="date_end" readonly="1"/>
</list>
</field>
</group>
<footer>
<button string="Apply" type="object" name="apply_warranty" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
</odoo>

0 comments on commit f9ffd66

Please sign in to comment.