Skip to content

Commit

Permalink
[IMP] warranty: Add warranty fetures.
Browse files Browse the repository at this point in the history
- Introduced warranty management in the Sales Order (SO) process.
- Updated system to handle warranty details for products.
- Enhanced customer communication for warranty information.
- Added flow for tracking warranty terms post-sale.
  • Loading branch information
krku-odoo committed Sep 26, 2024
1 parent 456c8ed commit 7dec18a
Show file tree
Hide file tree
Showing 19 changed files with 205 additions and 136 deletions.
1 change: 0 additions & 1 deletion dental/models/dental_patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,3 @@ def action_open_invoice(self):
],
}
invoice_obj.create(invoice_vals)

26 changes: 13 additions & 13 deletions dental/views/dental_controller.xml
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,25 @@
<div style="width: 60%; border: 1px solid #ccc; padding: 30px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
<h3 class="text-center mb-4" style="color: #714B67;">PERSONAL INFORMATION</h3>
<form t-foreach="personal" t-as="record">
<div class="form-group mb-3">
<div class="mb-3">
<label for="first_name" style="font-weight: bold;">Name:</label>
<input type="text" id="first_name" name="record.name" class="form-control" t-att-value="record.name" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="gender" style="font-weight: bold;">Gender:</label>
<input type="text" id="gender" name="record.gender" class="form-control" t-att-value="record.gender" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="dob" style="font-weight: bold;">Date of Birth:</label>
<input type="text" id="dob" name="record.date_of_birth" class="form-control" t-att-value="record.date_of_birth" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="occupation" style="font-weight: bold;">Occupation:</label>
<textarea id="occupation" name="record.occupation_or_grade" class="form-control" rows="3" readonly="true">
<t t-esc="record.occupation_or_grade"/>
</textarea>
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="marital_status" style="font-weight: bold;">Marital Status:</label>
<input type="text" id="marital_status" name="record.marital_status" class="form-control" t-att-value="record.marital_status" readonly="true" />
</div>
Expand Down Expand Up @@ -200,19 +200,19 @@
<div style="width: 60%; border: 1px solid #ccc; padding: 30px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
<h3 class="text-center mb-4" style="color: #714B67;">MEDICAL AID</h3>
<t t-foreach="medical_aid" t-as="record">
<div class="form-group mb-3">
<div class="mb-3">
<label for="name" style="font-weight: bold;">Name:</label>
<input type="text" id="name" name="record.name" class="form-control" t-att-value="record.name" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="contact" style="font-weight: bold;">Contact:</label>
<input type="text" id="contact" name="record.contact" class="form-control" t-att-value="record.contact" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="phone_number" style="font-weight: bold;">Phone Number:</label>
<input type="text" id="phone_number" name="record.phone_number" class="form-control" t-att-value="record.phone_number" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="email" style="font-weight: bold;">Email:</label>
<input type="text" id="email" name="record.email" class="form-control" t-att-value="record.email" readonly="true" />
</div>
Expand Down Expand Up @@ -379,19 +379,19 @@
<div style="width: 60%; border: 1px solid #ccc; padding: 30px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
<h3 class="text-center mb-4" style="color: #714B67;">DENTAL HISTORY DETAIL</h3>
<t t-foreach="history" t-as="record">
<div class="form-group mb-3">
<div class="mb-3">
<label for="name" style="font-weight: bold;">Name:</label>
<input type="text" id="name" name="record.display_name" class="form-control" t-att-value="record.display_name" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="contact" style="font-weight: bold;">Date:</label>
<input type="text" id="contact" name="record.date" class="form-control" t-att-value="record.date" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="phone_number" style="font-weight: bold;">Description:</label>
<input type="text" id="phone_number" name="record.description" class="form-control" t-att-value="record.description" readonly="true" />
</div>
<div class="form-group mb-3">
<div class="mb-3">
<label for="email" style="font-weight: bold;">Tags:</label>
<input type="text" id="email" name="record.tags" class="form-control" t-att-value="record.tags" readonly="true" />
</div>
Expand Down
1 change: 0 additions & 1 deletion estate/controller/estate_property_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,3 @@ def get_record(self, record_id, **kwargs):
"estate.property_view_details",
{"record": record},
)

13 changes: 4 additions & 9 deletions estate/models/estate_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,10 @@ def _check_state_before_delete(self):
raise UserError(
"You cannot delete a property that is not in 'New' or 'Canceled' state."
)



def state_change_action(self):

def state_change_action(self):
for property in self:
if property.state == "offer recieved" or property.state == "cancelled":
property.state ="new"
property.state = "new"
else:
raise UserError(
"You can't change status invalid property."
)

raise UserError("You can't change status invalid property.")
2 changes: 1 addition & 1 deletion installment/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "LGPL-3",
"category": "Subscription Installment",
"summary": "Subscription Installment",
"depends": ["base_setup", "sale_subscription","documents"],
"depends": ["base_setup", "sale_subscription", "documents"],
"data": [
"security/ir.model.access.csv",
"wizard/add_button_emi_views.xml",
Expand Down
2 changes: 1 addition & 1 deletion installment/model/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from . import account_move
from . import sale_order
from . import sale_order
40 changes: 20 additions & 20 deletions installment/model/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,31 @@
class InvoiceCreate(models.Model):
_inherit = "sale.order"

#create cron function
# create cron function
@api.model
def action_cron_auto_transfer(self):
invoices = (
self.env["account.move "]
.search(
[
( "line_ids.product_id","=",self.env.ref("installment.product1").id,),
("state", "in", ["posted", "open"]),
("payment_state", "!=", "paid"),
("penalty_applied", "=", False),
]
)
invoices = self.env["account.move "].search(
[
(
"line_ids.product_id",
"=",
self.env.ref("installment.product1").id,
),
("state", "in", ["posted", "open"]),
("payment_state", "!=", "paid"),
("penalty_applied", "=", False),
]
)

current_date = fields.Date.today()
for invoice in invoices:
print(invoice.sale_order_line.id)
penalty_delay_date = self.env["ir.config_parameter"].get_param(
"installment.delay_panalty_process"
)

penalty_delay_days = int(float(penalty_delay_date))
invoice_date = invoice.invoice_date_due + timedelta(days=penalty_delay_days)

if current_date >= invoice_date:
penalty_amount = self.calculate_penalty_amount(invoice)
values = {
Expand Down Expand Up @@ -64,13 +64,12 @@ def action_cron_auto_transfer(self):
# calculate penalty amounte
def calculate_penalty_amount(self, invoice):
down_penalty_percentage = float(
self.env["ir.config_parameter"]
.get_param("installment.delay_panalty_perc")
self.env["ir.config_parameter"].get_param("installment.delay_panalty_perc")
)

penalty_invoice_amount = (invoice.amount_total * down_penalty_percentage) / 100
return penalty_invoice_amount

# create fuction for document upload
def action_upload_documents(self):
# Retrieve the configuration settings
Expand All @@ -94,7 +93,8 @@ def action_upload_documents(self):
for order in self:
# Ensure the Installments folder exists
installments_folder = self.env["documents.folder"].search(
[("name", "=", "Installments")], limit=1)
[("name", "=", "Installments")], limit=1
)
if not installments_folder:
installments_folder = self.env["documents.folder"].create(
{
Expand Down
73 changes: 44 additions & 29 deletions installment/wizard/add_emi_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,66 @@ class AddEmi(models.TransientModel):
total_sale_amount = fields.Float(string="Total sale Amount", readonly=True)
down_payment = fields.Float(compute="_compute_values")
remaining_amount = fields.Float(compute="_compute_values")
interest = fields.Float(compute='_compute_values')
number_of_monthly_installement = fields.Integer(compute='_compute_values')
interest = fields.Float(compute="_compute_values")
number_of_monthly_installement = fields.Integer(compute="_compute_values")
installement_amount = fields.Float(readonly=True)
admin_expense = fields.Float(compute='_compute_values')
remaining_amount_2 = fields.Float(compute='_compute_values')
admin_expense = fields.Float(compute="_compute_values")
remaining_amount_2 = fields.Float(compute="_compute_values")

def default_get(self, fields_list):
defaults = super().default_get(fields_list)
defaults['total_sale_amount'] = self.env['sale.order'].browse(
self.env.context.get('active_id')).amount_total
defaults["total_sale_amount"] = (
self.env["sale.order"]
.browse(self.env.context.get("active_id"))
.amount_total
)
return defaults

@api.depends("total_sale_amount")
def _compute_values(self):
for rec in self:
down_payment_perc = self.env['ir.config_parameter'].get_param(
'installment.down_payment_perc')
down_payment_perc = self.env["ir.config_parameter"].get_param(
"installment.down_payment_perc"
)
x = float(rec.total_sale_amount) * float(down_payment_perc)
rec.down_payment = x / 100
rec.remaining_amount = rec.total_sale_amount - rec.down_payment
administrative_expenses_percentage = self.env['ir.config_parameter'].get_param(
'installment.administ_exp')
administrative_expenses_percentage = self.env[
"ir.config_parameter"
].get_param("installment.administ_exp")
y = float(rec.remaining_amount) * float(administrative_expenses_percentage)
rec.admin_expense = y / 100
rec.remaining_amount_2 = rec.remaining_amount + rec.admin_expense
max_dur = float(self.env['ir.config_parameter'].get_param(
'installment.max_duration'))
annual_rate_percentage = self.env['ir.config_parameter'].get_param(
'installment.annual_rate_perc')
z = float(rec.remaining_amount_2) * float(annual_rate_percentage)*float(max_dur)
max_dur = float(
self.env["ir.config_parameter"].get_param("installment.max_duration")
)
annual_rate_percentage = self.env["ir.config_parameter"].get_param(
"installment.annual_rate_perc"
)
z = (
float(rec.remaining_amount_2)
* float(annual_rate_percentage)
* float(max_dur)
)
rec.interest = z / 100
rec.number_of_monthly_installement = float(max_dur) * 12
rec.installement_amount = (
rec.remaining_amount_2 + rec.interest)/rec.number_of_monthly_installement
# add installment button
rec.remaining_amount_2 + rec.interest
) / rec.number_of_monthly_installement

# add installment button
def add_installement(self):
self.env['sale.order.line'].create([{
'order_id': self.env.context.get('active_id'),
'product_id':self.env.ref('installment.product1').id,
'price_unit':self.installement_amount
},
{
'order_id': self.env.context.get('active_id'),
'product_id':self.env.ref('installment.product2').id,
'price_unit':self.down_payment
}
])

self.env["sale.order.line"].create(
[
{
"order_id": self.env.context.get("active_id"),
"product_id": self.env.ref("installment.product1").id,
"price_unit": self.installement_amount,
},
{
"order_id": self.env.context.get("active_id"),
"product_id": self.env.ref("installment.product2").id,
"price_unit": self.down_payment,
},
]
)
2 changes: 1 addition & 1 deletion warranty/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Product Warranty",
"version": "1.0",
"license": "LGPL-3",
"depends": ["base","stock","sale_management"],
"depends": ["base", "stock", "sale_management"],
"data": [
"security/ir.model.access.csv",
"wizard/add_warranty_button_action.xml",
Expand Down
5 changes: 3 additions & 2 deletions warranty/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from . import product_warranty
from . import product_template
from . import product_template
from . import warranty_configuration
from . import sale_order
from . import sale_order
from . import sale_order_line
9 changes: 4 additions & 5 deletions warranty/models/product_template.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from odoo import models, fields, api
from odoo import models, fields


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


_inherit = "product.template"

is_warranty_available = fields.Boolean()

8 changes: 4 additions & 4 deletions warranty/models/product_warranty.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from odoo import models, fields, api
from odoo import models, fields


class ProductWarranty(models.Model):
_name='product.warranty'
name = fields.Char('Title')
_name = "product.warranty"

name = fields.Char("Title")
28 changes: 19 additions & 9 deletions warranty/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from odoo import models
from datetime import timedelta
from odoo import models
from odoo.exceptions import UserError


Expand All @@ -11,12 +10,23 @@ def add_warranty_wizard_button(self):
for product in products:
if product.product_template_id.is_warranty_available:
return {
'type': 'ir.actions.act_window',
'name': 'Add Warranty',
'res_model': 'add.warranty',
'view_mode': 'form',
'view_id': self.env.ref('warranty.view_warranty_form').id,
'target': 'new',
"type": "ir.actions.act_window",
"name": "Add Warranty",
"res_model": "add.warranty",
"view_mode": "form",
"view_id": self.env.ref("warranty.view_warranty_form").id,
"target": "new",
}
else:
raise UserError('This product does not have a warranty.')
raise UserError("This product does not have a warranty.")

return {
"type": "ir.actions.client",
"tag": "display_notification",
"params": {
"title": "Warning",
"message": "No product with an available warranty found in this order.",
"type": "warning",
"sticky": False,
},
}
17 changes: 17 additions & 0 deletions warranty/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from odoo import models, fields


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

waranty_with_products = fields.Many2one("sale.order.line")

def unlink(self):
for line in self:
warranty_lines = self.env["sale.order.line"].search(
[("waranty_with_products", "=", line.id)]
)
if warranty_lines:
warranty_lines.unlink()

return super().unlink()
Loading

0 comments on commit 7dec18a

Please sign in to comment.