Slink/sos_sales/models/sos_proposal_builder.py

237 lines
11 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from odoo import models, fields, api
import io
import base64
class SOS_Proposal_Builder(models.Model):
_name = 'sos_proposal_builder'
_description = 'Proposal Builder'
_rec_name="proposal_id"
proposal_id = fields.Many2one('sos_proposal_customer_requirement',string="Proposal ID", required= True)
sales_executive = fields.Many2one('res.users', string='Requirement Submitted By',related="proposal_id.requirement_submitted_by_name")
customer_name = fields.Char(string="Customer Name")
customer_logo=fields.Binary(string="Customer Logo")
doc_attachement = fields.Binary(string="Attachments",help="Any attachments to be attached with Proposal")
doc_attachement_filename = fields.Char(string="Filename")
currency_id = fields.Many2one(
'res.currency',
string='Currency',
default=lambda self: self.env['res.currency'].search([('name', '=', 'INR')], limit=1).id or False
)
total_cost = fields.Float(string="Total Cost", compute='_compute_total_cost', store=True)
buffer_in_percentage = fields.Integer(string="Buffer(%)",default=0,store=True)
total_with_buffer = fields.Monetary(string="Total with Buffer", compute='_compute_total_with_buffer', currency_field='currency_id', store=True)
#Proposal builder
proposal_heading = fields.Text(string="Heading",default="Product Proposal")
about_sosaley = fields.Text(string="About Sosaley",default="Sosaley Technologies Private Limited is an Indian company focusing on manufacturing indigenous Battery Management systems for Lithium-ion and Battery Health Monitoring System for Lead-acid(2V & 12V) & Nickel-Cadmium batteries. All our products are made 100% designed, developed, manufactured in house at our facilities in Chennai. Founded in 2008, Sosaley Technologies is working with customers and partners to deliver solutions for multiple verticals. Our team includes engineering, quality, research & development. Our installation base are all over India and Overseas.")
proposal_objective = fields.Html(string="Proposal Objective")
proposal_overview = fields.Html(string="Proposal Overview")
technical_diagrams = fields.One2many('sos_proposal_diagrams', 'ref_id', string="Images")
#Quotation
quotation_no = fields.Char(string="Quotation No")
quotation_date = fields.Date(string="Quotation Date")
quotation_validity = fields.Date(string="Quotation Validity")
inquiry_ref_no = fields.Char(string="Inquiry Ref No")
billing_address = fields.Text(string="Billing Address")
shipping_address = fields.Text(string="Shipping Address")
contact_person = fields.Char(string="Contact Person")
contact_number = fields.Char(string="Contact Number")
email_id=fields.Char(string="Email ID")
#parameters
parameters_monitored = fields.Html(
string="Parameters Monitored",
default=lambda self: """
<p><b>Measured:</b></p>
<ul>
<li>Voltage - Individual battery</li>
<li>Battery Temperature - Individual Battery</li>
<li>Ambient Temperature</li>
<li>String current</li>
<li>Status of battery (Charging / Discharging / Standby)</li>
</ul>
<p><b>Calculated:</b></p>
<ul>
<li>SoC - Status of Charge</li>
<li>SoH - Battery Life</li>
<li>Battery Bank voltage</li>
<li>Battery Internal Resistance (ohmic value)</li>
</ul>
"""
)
#payment
payment_terms = fields.Html(string="Payment Terms",default=lambda self: """
<table class="table table-sm table_custom" style="width:100%;">
<thead>
<tr>
<th>S.No</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>50% Advance along with order</td>
</tr>
<tr>
<td>2</td>
<td>50% Before Delivery</td>
</tr>
</tbody>
</table>
""")
#terms and conditions
terms_and_conditions = fields.Html(
string="Terms and Conditions",
default=lambda self: """
<table class="table table-sm table_custom" style="width:100%; font-size:13px;">
<thead>
<tr>
<th>S.No</th>
<th>Focus Area</th>
<th>Terms and Conditions</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Price</td>
<td>
1. All the Prices are quoted in INR.<br/>
2. All prices are exclusive of all taxes applicable which would be charged as per actuals.
</td>
</tr>
<tr>
<td>2</td>
<td>Base Warranty</td>
<td>
1. Warranty will be for 12 months from the date of Supply.<br/>
2. Beyond Warranty period, AMC shall be chargeable @ 18% of product cost per annum.<br/>
The warranty specifically covers the core BHMS board and its components. It does not include coverage for physical damage, the enclosure, cables and connectors.
</td>
</tr>
<tr>
<td>3</td>
<td>Remote Monitoring</td>
<td>
Sosaley will provide cloud access credentials to access the cloud server on annual subscription basis. Every year subscription shall be renewed before expiry.<br/>
Internet connectivity with BHMS shall be provided by the customer.<br/>
In case Sosaley provides through internet dongle, telecom charges (SIM card) shall be applicable.<br/>
Cloud subscription charges shall be Rs. 400/- per battery per annum.
</td>
</tr>
<tr>
<td>4</td>
<td>Telecom Connectivity</td>
<td>
Telecom connectivity charges shall be Rs. 5400/- per annum (Optional).<br/>
The charges will be collected in advance before the service start.
</td>
</tr>
<tr>
<td>5</td>
<td>Packaging & Forwarding</td>
<td>
The quoted price is Inclusive of Packaging and Forwarding, FOB- Chennai.
</td>
</tr>
<tr>
<td>6</td>
<td>Proposal Validity</td>
<td>
The proposal validity is for 1 month from the date of submission.
</td>
</tr>
<tr>
<td>7</td>
<td>Delivery Timeline</td>
<td>
Sosaley estimates that it will take roughly 34 weeks to ship the products.
</td>
</tr>
<tr>
<td>8</td>
<td>Installation & Commissioning</td>
<td>
The quoted pricing is inclusive of one-time Installation and Commissioning.<br/>
For additional installations, the charges shall be Rs. 5000/- per man-day plus travel and accommodation.
</td>
</tr>
<tr>
<td>9</td>
<td>Force Majeure</td>
<td>
Sosaley will not be responsible or liable for any delay caused by forces beyond its control, including strikes, work stoppages, acts of war or terrorism, natural catastrophes, etc.<br/>
In such cases, the estimated cost and schedule may need to be re-negotiated.
</td>
</tr>
<tr>
<td>10</td>
<td>Support</td>
<td>
Sosaley will provide support via call and email during the warranty period.<br/>
Contact details will be shared after product delivery.<br/>
Similar support will be provided during AMC if contracted.
</td>
</tr>
</tbody>
</table>
"""
)
def action_report_proposal_btn(self):
try:
action = self.env.ref("sos_sales.action_report_proposal").with_context(download=True).report_action(self)
return action
except ValueError as e:
print(f"Failed to find report action: {e}")
@api.onchange('proposal_id')
def _onchange_proposal_id(self):
if self.proposal_id:
self.customer_name = self.proposal_id.customer_name
boq = self.env['sos_proposal_boq'].search([('proposal_id', '=', self.proposal_id.id)], limit=1, order='id desc')
self.total_cost = boq.final_cost_by_acc
@api.depends('buffer_in_percentage', 'total_cost')
def _compute_total_with_buffer(self):
for rec in self:
buffer_percent = rec.buffer_in_percentage or 0.0
rec.total_with_buffer = rec.total_cost * (1 + buffer_percent / 100.0)
@api.depends('proposal_id')
def _compute_total_cost(self):
for rec in self:
boq = self.env['sos_proposal_boq'].search(
[('proposal_id', '=', rec.proposal_id.id)],
limit=1, order='id desc'
)
rec.total_cost = boq.final_cost_by_acc if boq else 0.0
@api.model
def create(self, vals):
if vals.get('proposal_id') and not vals.get('total_cost'):
boq = self.env['sos_proposal_boq'].search(
[('proposal_id', '=', vals['proposal_id'])], limit=1, order='id desc'
)
if boq:
vals['total_cost'] = boq.final_cost_by_acc
return super().create(vals)
def write(self, vals):
if vals.get('proposal_id') and not vals.get('total_cost'):
boq = self.env['sos_proposal_boq'].search(
[('proposal_id', '=', vals['proposal_id'])], limit=1, order='id desc'
)
if boq:
vals['total_cost'] = boq.final_cost_by_acc
return super().write(vals)
class SOS_Technical_Diagrams(models.Model):
_name = 'sos_proposal_diagrams'
_description = 'Multiple Images for a Record'
image = fields.Binary("Image Title", required=True)
image_name = fields.Char("Image Name")
ref_id = fields.Many2one('sos_proposal_builder', string="Reference", ondelete='cascade')