from odoo import models, fields, api
import math
from collections import defaultdict
from odoo.tools.misc import format_amount
class Battery_Installation_Requirement(models.Model):
_name = 'sos_proposal_boq'
_description = 'Battery Installation Details'
_rec_name="proposal_id"
_order = 'id desc'
_sql_constraints = [
('unique_proposal_id', 'unique(proposal_id)', 'Proposal ID must be unique!')
]
proposal_id = fields.Many2one('sos_proposal_customer_requirement',string="Proposal ID", required= True,
domain=lambda self: [('id', 'not in', self.env['sos_proposal_boq'].search([]).mapped('proposal_id').ids)])
sales_executive = fields.Many2one('res.users', string='Requirement Submitted By',related="proposal_id.requirement_submitted_by_name")
customer_name = fields.Char(string="Customer Name")
location = fields.Char(string="Location")
number_of_batteries = fields.Integer(string="Number of Batteries")
number_of_strings = fields.Integer(string="Number of Strings")
number_of_ups = fields.Integer(string="Number of UPS",store=True)
ups_rating_kva = fields.Integer(string="UPS Rating (KVA)")
no_of_electrical_panel = fields.Integer(string="No of Electrical Panel")
battery_capacity_ah = fields.Integer(string="Battery Capacity (AH)")
products = fields.Selection([
('BHMS 1.2V', 'BHMS 1.2V'),
('BHMS 2V', 'BHMS 2V'),
('BHMS 12V', 'BHMS 12V'),
('BHMS 48V', 'BHMS 48V'),
('BMS-HV', 'BMS-HV'),
('BMS-LV 100A', 'BMS-LV 100A'),
('BMS-LV 40A', 'BMS-LV 40A'),
('SBMS 55A', 'SBMS 55A'),
('MC 250W', 'MC 250W'),
('HeartTarang', 'HeartTarang')
], string="Products")
main_master_count= fields.Integer(string="No of Master")
main_slave_count= fields.Integer(string="No of Slave")
line_ids_material = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Materials",copy=True)
line_ids_sfg = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="Semi-Finished Goods",copy=True)
line_ids_fg = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="Finished Goods",copy=True)
line_ids_miscellaneous = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id',string="")
line_ids_installation_kit = fields.One2many('sos_proposal_line_material_installation', 'ref_id',string="")
boq_submitted_by_name = fields.Many2one('res.users', string='BOQ Submitted By')
boq_submitted_by_image = fields.Image(related="boq_submitted_by_name.signature_image",readonly=True)
boq_submitted_by_approved_on = fields.Datetime(string="Submitted On")
currency_id = fields.Many2one(
'res.currency',
string='Currency',
default=lambda self: self.env['res.currency'].search([('name', '=', 'INR')], limit=1).id or False
)
total_fg_cost = fields.Monetary(compute='_compute_total_fg_cost', string="Total FG Cost", currency_field='currency_id', readonly=True)
total_sfg_cost = fields.Monetary(compute='_compute_total_sfg_cost', string="Total SFG Cost", currency_field='currency_id', readonly=True)
total_material_cost = fields.Monetary(compute='_compute_total_material_cost', string="Total Material Cost", currency_field='currency_id', readonly=True)
total_installation_material_cost = fields.Monetary(compute='_compute_total_installation_material_cost', string="Total Installation Cost", currency_field='currency_id', readonly=True)
total_miscellaneous_cost = fields.Monetary(compute='_compute_total_miscellaneous_cost', string="Total Miscellaneous Cost", currency_field='currency_id', readonly=True)
total_cost = fields.Monetary(compute='_compute_total_cost', string="Total Cost", currency_field='currency_id', readonly=True)
acc_approved_by_name = fields.Many2one('res.users', string='Accounts By')
acc_approved_by_image = fields.Image(related="acc_approved_by_name.signature_image",readonly=True)
acc_approved_on = fields.Datetime(string="Approved On")
warranty_cost = fields.Monetary(string="Warranty Cost", compute='_compute_warranty', store=True, currency_field='currency_id')
margin = fields.Monetary(string="Opreational Cost",compute='_compute_margin', currency_field='currency_id')
margin_per_battery = fields.Monetary(string="Opreational Cost per Battery", currency_field='currency_id')
warranty_percentage = fields.Float(string="Warranty(%)")
final_cost = fields.Monetary(string="Final Cost", compute='_compute_final_cost', store=True, currency_field='currency_id')
final_cost_per_battery = fields.Monetary(string="Final Cost", compute='_compute_final_cost_per_battery', store=True, currency_field='currency_id')
final_cost_by_acc = fields.Monetary(string="Final Cost By Accounts", currency_field='currency_id')
final_total = fields.Monetary(string="Final Cost", compute='_compute_final_cost_acc', store=True, currency_field='currency_id')
communication_type = fields.Selection([
('wired', 'Wired'),
('wireless', 'Wireless')
], string="Communication Type", default='wired')
slave_type = fields.Selection([
('15S Individual Slave', '15S Individual Slave'),
('90S Electrical Panel', '90S Electrical Panel'),
('60S Electrical Panel', '60S Electrical Panel')
], string="Slave Type", default='15S Individual Slave')
specific_requirements = fields.Html(string="Specific Requirements")
#CE Team Fields
engineers_nos=fields.Integer(string="No of engineers required")
no_of_days=fields.Integer(string="No of days")
extra_cost_line_ids = fields.One2many('sos_extra_cost_lines', 'ref_id',copy=True)
# mode_of_transport = fields.Selection([('car','đ Car'),('bus','đ Bus'),('train','đ Train'),('flight','đŠī¸ Flight')],string='Mode of Transport',default="train")
# transport_expense = fields.Monetary(readonly=False,string="Transport", compute='_compute_transport_expense', store=True, currency_field='currency_id')
# food_expense = fields.Monetary(readonly=False,string="Food", compute='_compute_food_expense', store=True, currency_field='currency_id')
# stay_expense = fields.Monetary(readonly=False,string="Room Rent", compute='_compute_stay_expense', store=True, currency_field='currency_id')
# local_expense = fields.Monetary(readonly=False,string="Local Conveyance", compute='_compute_local_expense', store=True, currency_field='currency_id')
man_month_1to2_yrs_persons = fields.Integer(string="Man Month (Persons) 1 to 2 Yrs")
man_month_2to3_yrs_persons = fields.Integer(string="Man Month (Persons) 2 to 3 Yrs")
man_month_manager_persons = fields.Integer(string="Man Month (Persons) Manager Yrs")
man_month_1to2_yrs_cost = fields.Monetary(string="Cost", currency_field='currency_id')
man_month_2to3_yrs_cost = fields.Monetary(string="Cost", currency_field='currency_id')
man_month_manager_cost = fields.Monetary(string="Cost", currency_field='currency_id')
iandc_costing=fields.Monetary(readonly=False,string="I & C Man Month Cost",currency_field='currency_id',compute='_compute_iandc_expense')
iandc_travel_cost = fields.Monetary(string="Travel Cost", currency_field='currency_id')
#FG Fields
line_ids_fg_ups1 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 1",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups2 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 2",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups3 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 3",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups4 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 4",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups5 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 5",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups6 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 6",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups7 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 7",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups8 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 8",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups9 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 9",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups10 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 10",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups11 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 11",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups12 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 12",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups13 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 13",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups14 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 14",compute='_compute_line_ids_by_ups',store=False)
line_ids_fg_ups15 = fields.One2many('sos_proposal_boq_fg', 'ref_id', string="FG UPS 15",compute='_compute_line_ids_by_ups',store=False)
merged_fg_html = fields.Html(string="FG (Merged)", compute="_compute_merged_fg_html", sanitize=False)
merged_sfg_html = fields.Html(string="SFG (Merged)", compute="_compute_merged_sfg_html", sanitize=False)
merged_material_html = fields.Html(string="Materials (Merged)", compute="_compute_merged_material_html", sanitize=False)
merged_installation_kit_html = fields.Html(string="InstallationKit (Merged)", compute="_compute_merged_installation_kit_html", sanitize=False)
merged_miscellaneous_html = fields.Html(string="Miscellaneous (Merged)", compute="_compute_merged_miscellaneous_html", sanitize=False)
merged_spare_html = fields.Html(string="Spare (Merged)", compute="_compute_merged_spare_html", sanitize=False)
#SFG Fields
line_ids_sfg_ups1 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 1",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups2 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 2",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups3 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 3",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups4 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 4",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups5 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 5",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups6 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 6",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups7 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 7",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups8 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 8",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups9 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 9",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups10 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 10",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups11 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 11",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups12 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 12",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups13 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 13",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups14 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 14",compute='_compute_line_ids_by_ups',store=False)
line_ids_sfg_ups15 = fields.One2many('sos_proposal_boq_sfg', 'ref_id', string="SFG UPS 15",compute='_compute_line_ids_by_ups',store=False)
#Material Fields
line_ids_material_ups1 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 1",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups2 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 2",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups3 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 3",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups4 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 4",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups5 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 5",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups6 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 6",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups7 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 7",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups8 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 8",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups9 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 9",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups10 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 10",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups11 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 11",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups12 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 12",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups13 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 13",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups14 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 14",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_material_ups15 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 15",compute='_compute_line_ids_by_ups',store=False,readonly=False)
#Installation Kit Fields
line_ids_installation_kit_ups1 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 1",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups2 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 2",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups3 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 3",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups4 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 4",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups5 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 5",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups6 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 6",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups7 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 7",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups8 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 8",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups9 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 9",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups10 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 10",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups11 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 11",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups12 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 12",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups13 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 13",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups14 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 14",compute='_compute_line_ids_by_ups',store=False,readonly=False)
line_ids_installation_kit_ups15 = fields.One2many('sos_proposal_line_material_installation', 'ref_id', string="Installation Kit UPS 15",compute='_compute_line_ids_by_ups',store=False,readonly=False)
#Miscellaneous Kit Fields
line_ids_miscellaneous_ups1 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 1",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups2 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 2",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups3 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 3",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups4 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 4",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups5 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 5",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups6 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 6",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups7 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 7",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups8 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 8",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups9 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 9",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups10 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 10",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups11 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 11",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups12 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 12",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups13 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 13",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups14 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 14",compute='_compute_line_ids_by_ups',store=False)
line_ids_miscellaneous_ups15 = fields.One2many('sos_proposal_miscellaneous_items', 'ref_id', string="Miscellaneous UPS 15",compute='_compute_line_ids_by_ups',store=False)
#ups totals
ups1_total = fields.Float(string="UPS 1 Total Cost",compute='_compute_ups_total',store=True)
ups2_total = fields.Float(string="UPS 2 Total Cost", compute='_compute_ups_total', store=True)
ups3_total = fields.Float(string="UPS 3 Total Cost", compute='_compute_ups_total', store=True)
ups4_total = fields.Float(string="UPS 4 Total Cost", compute='_compute_ups_total', store=True)
ups5_total = fields.Float(string="UPS 5 Total Cost", compute='_compute_ups_total', store=True)
ups6_total = fields.Float(string="UPS 6 Total Cost", compute='_compute_ups_total', store=True)
ups7_total = fields.Float(string="UPS 7 Total Cost", compute='_compute_ups_total', store=True)
ups8_total = fields.Float(string="UPS 8 Total Cost", compute='_compute_ups_total', store=True)
ups9_total = fields.Float(string="UPS 9 Total Cost", compute='_compute_ups_total', store=True)
ups10_total = fields.Float(string="UPS 10 Total Cost", compute='_compute_ups_total', store=True)
ups11_total = fields.Float(string="UPS 11 Total Cost", compute='_compute_ups_total', store=True)
ups12_total = fields.Float(string="UPS 12 Total Cost", compute='_compute_ups_total', store=True)
ups13_total = fields.Float(string="UPS 13 Total Cost", compute='_compute_ups_total', store=True)
ups14_total = fields.Float(string="UPS 14 Total Cost", compute='_compute_ups_total', store=True)
ups15_total = fields.Float(string="UPS 15 Total Cost", compute='_compute_ups_total', store=True)
extra_lines_cost = fields.Monetary(string="Cost", compute='_compute_extra_lines_cost', store=True, currency_field='currency_id')
packing_and_forwarding = fields.Monetary(string="Packing & Forwarding", currency_field='currency_id',store=True,compute="_compute_packing_and_forwarding",compute_sudo=True)
additional_warranty = fields.Monetary(string="Additional Warranty", currency_field='currency_id',store=True)
line_ids_spare_ups1 = fields.One2many('sos_proposal_line_spare_ups1','ref_id', string="Spare UPS 1")
line_ids_spare_ups2 = fields.One2many('sos_proposal_line_spare_ups2', 'ref_id',string="Spare UPS 2")
line_ids_spare_ups3 = fields.One2many('sos_proposal_line_spare_ups3','ref_id', string="Spare UPS 3")
line_ids_spare_ups4 = fields.One2many('sos_proposal_line_spare_ups4', 'ref_id',string="Spare UPS 4")
line_ids_spare_ups5 = fields.One2many('sos_proposal_line_spare_ups5','ref_id', string="Spare UPS 5")
line_ids_spare_ups6 = fields.One2many('sos_proposal_line_spare_ups6', 'ref_id',string="Spare UPS 6")
line_ids_spare_ups7 = fields.One2many('sos_proposal_line_spare_ups7','ref_id', string="Spare UPS 7")
line_ids_spare_ups8 = fields.One2many('sos_proposal_line_spare_ups8','ref_id', string="Spare UPS 8")
line_ids_spare_ups9 = fields.One2many('sos_proposal_line_spare_ups9','ref_id', string="Spare UPS 9")
line_ids_spare_ups10 = fields.One2many('sos_proposal_line_spare_ups10','ref_id', string="Spare UPS 10")
line_ids_spare_ups11 = fields.One2many('sos_proposal_line_spare_ups11','ref_id', string="Spare UPS 11")
line_ids_spare_ups12 = fields.One2many('sos_proposal_line_spare_ups12','ref_id', string="Spare UPS 12")
line_ids_spare_ups13 = fields.One2many('sos_proposal_line_spare_ups13','ref_id', string="Spare UPS 13")
line_ids_spare_ups14 = fields.One2many('sos_proposal_line_spare_ups14','ref_id', string="Spare UPS 14")
line_ids_spare_ups15 = fields.One2many('sos_proposal_line_spare_ups15','ref_id', string="Spare UPS 15")
@api.depends(
'final_cost_by_acc','number_of_batteries'
)
def _compute_final_cost_acc(self):
for rec in self:
rec.final_total = rec.final_cost_by_acc * rec.number_of_batteries
@api.depends(
'proposal_id.number_of_batteries',
'proposal_id.number_of_ups',
'proposal_id.direction',
)
def _compute_packing_and_forwarding(self):
for rec in self:
val = 0.0
p = rec.proposal_id
if p:
packing_calculation = 1200
packing_kg_12V = 100 * (p.number_of_ups or 0)
direction = (p.direction or '').strip()
rate = 20 if direction == "North" else 19 if direction == "West" \
else 23 if direction == "East" else 13
forwarding_calculation = rate * packing_kg_12V
base_amount = 1.20 * (packing_calculation + forwarding_calculation)
val = base_amount * 1.18
rec.packing_and_forwarding = val
def _compute_merged_spare_html(self):
for rec in self:
# Collect lines from ups1..ups15 (skip models that don't exist)
models = [f'sos_proposal_line_spare_ups{i}' for i in range(1, 16)]
agg = defaultdict(float) # (component_id, uom, currency_id, unit_price) -> qty
name_map, curr_map, price_map = {}, {}, {}
for model in models:
if model not in self.env:
continue
for l in self.env[model].search([('ref_id', '=', rec.id)]):
if l.production_cost:
unit_price = l.unit_price or 0.0
curr_id = l.currency_id.id if l.currency_id else False
key = (l.component_id.id, l.uom, curr_id, unit_price)
agg[key] += float(l.quantity or 0)
if key not in name_map:
# Use part number (fallback to component name if needed)
name_map[key] = (getattr(l.component_id, 'part_no', False) or l.component_id.name or '')
curr_map[key] = l.currency_id if l.currency_id else False
price_map[key] = unit_price
rows_sorted = sorted(agg.items(), key=lambda it: name_map[it[0]].lower())
if not rows_sorted:
rec.merged_spare_html = "No Material items."
continue
def fmt_price(amount, currency):
return format_amount(self.env, amount, currency) if currency else f"{amount:.2f}"
total_sum = 0.0
rows_html = ""
for key, qty in rows_sorted:
if not qty:
continue
total_price = qty * price_map[key]
total_sum += total_price
rows_html += (
f"
"
f"| {name_map[key]} | "
f"{key[1] or ''} | "
f"{fmt_price(price_map[key], curr_map[key])} | "
f"{qty:.2f} | "
f"{fmt_price(total_price, curr_map[key])} | "
f"
"
)
if not rows_html:
rec.merged_spare_html = "No Material items."
continue
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f""
f"| Grand Total: | "
f"{fmt_price(total_sum, currency_for_total)} | "
f"
"
)
rec.merged_spare_html = f"""
| Material Name |
UoM |
Unit Price |
Total Qty |
Total Price |
{rows_html}
"""
def _compute_merged_miscellaneous_html(self):
for rec in self:
lines = self.env['sos_proposal_miscellaneous_items'].search([('ref_id', '=', rec.id)])
# Group by (component, currency, cost)
agg = defaultdict(float)
name_map = {}
curr_map = {}
price_map = {}
for l in lines:
cost = l.cost or 0.0
curr_id = l.currency_id.id if l.currency_id else False
key = (l.name, curr_id, cost)
agg[key] += float(l.quantity or 0)
if key not in name_map:
name_map[key] = l.name or ''
curr_map[key] = l.currency_id if l.currency_id else False
price_map[key] = cost
rows_sorted = sorted(agg.items(), key=lambda it: name_map[it[0]].lower())
if not rows_sorted:
rec.merged_miscellaneous_html = "No Miscellaneous items."
continue
def fmt_price(amount, currency):
if currency:
return format_amount(self.env, amount, currency)
return f"{amount:.2f}"
total_sum = 0.0
rows_html = ""
for key, qty in rows_sorted:
if not qty: # Skip rows with qty = 0
continue
total_price = qty * price_map[key]
total_sum += total_price
rows_html += (
f""
f"| {name_map[key]} | "
f"{fmt_price(price_map[key], curr_map[key])} | "
f"{qty:.2f} | "
f"{fmt_price(total_price, curr_map[key])} | "
f"
"
)
if not rows_html: # If all rows were skipped
rec.merged_miscellaneous_html = "No Miscellaneous items."
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f""
f"| Grand Total: | "
f"{fmt_price(total_sum, currency_for_total)} | "
f"
"
)
rec.merged_miscellaneous_html = f"""
| Name |
Unit Price |
Total Qty |
Total Price |
{rows_html}
"""
def _compute_merged_installation_kit_html(self):
for rec in self:
lines = self.env['sos_proposal_line_material_installation'].search([('ref_id', '=', rec.id)])
# Group by (component, uom, currency, unit_price)
agg = defaultdict(float)
name_map = {}
curr_map = {}
price_map = {}
for l in lines:
if l.production_cost:
unit_price = l.unit_price or 0.0
curr_id = l.currency_id.id if l.currency_id else False
key = (l.component_id.id, l.uom, curr_id, unit_price)
agg[key] += float(l.quantity or 0)
if key not in name_map:
name_map[key] = l.component_id.part_no or ''
curr_map[key] = l.currency_id if l.currency_id else False
price_map[key] = unit_price
rows_sorted = sorted(agg.items(), key=lambda it: name_map[it[0]].lower())
if not rows_sorted:
rec.merged_installation_kit_html = "No Material items."
continue
def fmt_price(amount, currency):
if currency:
return format_amount(self.env, amount, currency)
return f"{amount:.2f}"
total_sum = 0.0
rows_html = ""
for key, qty in rows_sorted:
if not qty: # Skip rows with qty = 0
continue
total_price = qty * price_map[key]
total_sum += total_price
rows_html += (
f""
f"| {name_map[key]} | "
f"{key[1] or ''} | "
f"{fmt_price(price_map[key], curr_map[key])} | "
f"{qty:.2f} | "
f"{fmt_price(total_price, curr_map[key])} | "
f"
"
)
if not rows_html: # If all rows were skipped
rec.merged_installation_kit_html = "No Material items."
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f""
f"| Grand Total: | "
f"{fmt_price(total_sum, currency_for_total)} | "
f"
"
)
rec.merged_installation_kit_html = f"""
| Material Name |
UoM |
Unit Price |
Total Qty |
Total Price |
{rows_html}
"""
def _compute_merged_material_html(self):
for rec in self:
lines = self.env['sos_proposal_boq_material'].search([('ref_id', '=', rec.id)])
# Group by (component, uom, currency, unit_price)
agg = defaultdict(float)
name_map = {}
curr_map = {}
price_map = {}
for l in lines:
unit_price = l.unit_price or 0.0
curr_id = l.currency_id.id if l.currency_id else False
key = (l.component_id.id, l.uom, curr_id, unit_price)
agg[key] += float(l.quantity or 0)
if key not in name_map:
name_map[key] = l.component_id.part_no or ''
curr_map[key] = l.currency_id if l.currency_id else False
price_map[key] = unit_price
rows_sorted = sorted(agg.items(), key=lambda it: name_map[it[0]].lower())
if not rows_sorted:
rec.merged_material_html = "No Material items."
continue
def fmt_price(amount, currency):
if currency:
return format_amount(self.env, amount, currency)
return f"{amount:.2f}"
total_sum = 0.0
rows_html = ""
for key, qty in rows_sorted:
if not qty: # Skip rows with qty = 0
continue
total_price = qty * price_map[key]
total_sum += total_price
rows_html += (
f""
f"| {name_map[key]} | "
f"{key[1] or ''} | "
f"{fmt_price(price_map[key], curr_map[key])} | "
f"{qty:.2f} | "
f"{fmt_price(total_price, curr_map[key])} | "
f"
"
)
if not rows_html: # If all rows were skipped
rec.merged_material_html = "No Material items."
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f""
f"| Grand Total: | "
f"{fmt_price(total_sum, currency_for_total)} | "
f"
"
)
rec.merged_material_html = f"""
| Material Name |
UoM |
Unit Price |
Total Qty |
Total Price |
{rows_html}
"""
def _compute_merged_sfg_html(self):
for rec in self:
lines = self.env['sos_proposal_boq_sfg'].search([('ref_id', '=', rec.id)])
# Group by (component, uom, currency, unit_price)
agg = defaultdict(float)
name_map = {}
curr_map = {}
price_map = {}
for l in lines:
if l.production_cost:
unit_price = l.unit_price or 0.0
curr_id = l.currency_id.id if l.currency_id else False
key = (l.component_id.id, l.uom, curr_id, unit_price)
agg[key] += float(l.quantity or 0)
if key not in name_map:
name_map[key] = l.component_id.name or ''
curr_map[key] = l.currency_id if l.currency_id else False
price_map[key] = unit_price
rows_sorted = sorted(agg.items(), key=lambda it: name_map[it[0]].lower())
if not rows_sorted:
rec.merged_sfg_html = "No SFG items."
continue
def fmt_price(amount, currency):
if currency:
return format_amount(self.env, amount, currency)
return f"{amount:.2f}"
total_sum = 0.0
rows_html = ""
for key, qty in rows_sorted:
if not qty: # Skip rows with qty = 0
continue
total_price = qty * price_map[key]
total_sum += total_price
rows_html += (
f""
f"| {name_map[key]} | "
f"{key[1] or ''} | "
f"{fmt_price(price_map[key], curr_map[key])} | "
f"{qty:.2f} | "
f"{fmt_price(total_price, curr_map[key])} | "
f"
"
)
if not rows_html: # If all rows were skipped
rec.merged_sfg_html = "No SFG items."
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f""
f"| Grand Total: | "
f"{fmt_price(total_sum, currency_for_total)} | "
f"
"
)
rec.merged_sfg_html = f"""
| SFG Name |
UoM |
Unit Price |
Total Qty |
Total Price |
{rows_html}
"""
def _compute_merged_fg_html(self):
for rec in self:
lines = self.env['sos_proposal_boq_fg'].search([('ref_id', '=', rec.id)])
# Group by (component, uom, currency, unit_price)
agg = defaultdict(float)
name_map = {}
curr_map = {}
price_map = {}
for l in lines:
if l.production_cost:
unit_price = l.unit_price or 0.0
curr_id = l.currency_id.id if l.currency_id else False
key = (l.component_id.id, l.uom, curr_id, unit_price)
agg[key] += float(l.quantity or 0)
if key not in name_map:
name_map[key] = l.component_id.name or ''
curr_map[key] = l.currency_id if l.currency_id else False
price_map[key] = unit_price
rows_sorted = sorted(agg.items(), key=lambda it: name_map[it[0]].lower())
if not rows_sorted:
rec.merged_fg_html = "No FG items."
continue
def fmt_price(amount, currency):
if currency:
return format_amount(self.env, amount, currency)
return f"{amount:.2f}"
total_sum = 0.0
rows_html = ""
for key, qty in rows_sorted:
if not qty: # Skip rows with qty = 0
continue
total_price = qty * price_map[key]
total_sum += total_price
rows_html += (
f""
f"| {name_map[key]} | "
f"{key[1] or ''} | "
f"{fmt_price(price_map[key], curr_map[key])} | "
f"{qty:.2f} | "
f"{fmt_price(total_price, curr_map[key])} | "
f"
"
)
if not rows_html: # If all rows were skipped
rec.merged_fg_html = "No FG items."
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f""
f"| Grand Total: | "
f"{fmt_price(total_sum, currency_for_total)} | "
f"
"
)
rec.merged_fg_html = f"""
| FG Name |
UoM |
Unit Price |
Total Qty |
Total Price |
{rows_html}
"""
@api.model
def create(self, vals):
res = super().create(vals)
if 'boq_submitted_by_name' in vals:
res._trigger_recompute_on_target_model()
elif 'acc_approved_by_name' in vals:
res._trigger_recompute_on_target_model_acc()
return res
def write(self, vals):
result = super().write(vals)
if 'boq_submitted_by_name' in vals:
self._trigger_recompute_on_target_model()
elif 'acc_approved_by_name' in vals:
self._trigger_recompute_on_target_model_acc()
return result
def _trigger_recompute_on_target_model(self):
related_records = self.env['sos_proposal_customer_requirement'].search([('proposal_id', '=', self.proposal_id.id)])
for rec in related_records:
rec._compute_boq_submitted_by()
def _trigger_recompute_on_target_model_acc(self):
related_records = self.env['sos_proposal_customer_requirement'].search([('proposal_id', '=', self.proposal_id.id)])
for rec in related_records:
rec._compute_acc_costing_submitted_by()
# @api.depends('no_of_days')
# def _compute_local_expense(self):
# for rec in self:
# rec.local_expense = rec.no_of_days * 500
# @api.depends('no_of_days')
# def _compute_stay_expense(self):
# for rec in self:
# rec.stay_expense = rec.no_of_days * 2500
# @api.depends('no_of_days')
# def _compute_food_expense(self):
# for rec in self:
# rec.food_expense = rec.no_of_days * 600
# @api.depends('no_of_days')
# def _compute_transport_expense(self):
# for rec in self:
# rec.transport_expense = 5000
@api.depends('iandc_travel_cost','no_of_days','man_month_1to2_yrs_persons','man_month_2to3_yrs_persons','man_month_manager_persons','man_month_1to2_yrs_cost','man_month_2to3_yrs_cost','man_month_manager_cost')
def _compute_iandc_expense(self):
for rec in self:
rec.iandc_costing = rec.iandc_travel_cost + ((rec.man_month_1to2_yrs_persons * rec.man_month_1to2_yrs_cost) +
(rec.man_month_2to3_yrs_persons * rec.man_month_2to3_yrs_cost) +
(rec.man_month_manager_persons * rec.man_month_manager_cost)) * rec.no_of_days
@api.depends('extra_cost_line_ids.cost')
def _compute_extra_lines_cost(self):
for record in self:
record.extra_lines_cost = sum(line.cost for line in record.extra_cost_line_ids)
@api.depends('warranty_cost', 'total_cost','margin','extra_lines_cost','packing_and_forwarding','additional_warranty','iandc_costing')
def _compute_final_cost(self):
for rec in self:
rec.final_cost = rec.warranty_cost + rec.total_cost + rec.margin + rec.extra_lines_cost + rec.packing_and_forwarding + rec.additional_warranty + rec.iandc_costing
@api.depends('total_cost', 'warranty_percentage')
def _compute_warranty(self):
for rec in self:
base = rec.total_cost or 0.0
percent = rec.warranty_percentage or 0
rec.warranty_cost = (percent / 100.0) * base
@api.depends('margin_per_battery', 'number_of_batteries')
def _compute_margin(self):
for rec in self:
if rec.number_of_batteries:
rec.margin= rec.margin_per_battery * rec.number_of_batteries
else:
rec.margin = 0.0
@api.depends('final_cost', 'number_of_batteries')
def _compute_final_cost_per_battery(self):
for rec in self:
if rec.number_of_batteries:
rec.final_cost_per_battery = rec.final_cost / rec.number_of_batteries
else:
rec.final_cost_per_battery = 0.0
@api.depends(
'line_ids_fg.total_price', 'line_ids_fg.ups_index', 'line_ids_fg.production_cost',
'line_ids_sfg.total_price', 'line_ids_sfg.ups_index', 'line_ids_sfg.production_cost',
'line_ids_material.total_price', 'line_ids_material.ups_index', 'line_ids_material.production_cost',
'line_ids_installation_kit.total_price', 'line_ids_installation_kit.ups_index', 'line_ids_installation_kit.production_cost',
'line_ids_miscellaneous.total_price', 'line_ids_miscellaneous.ups_index', 'line_ids_miscellaneous.production_cost',
'line_ids_spare_ups1.total_price', 'line_ids_spare_ups1.production_cost',
'line_ids_spare_ups2.total_price', 'line_ids_spare_ups2.production_cost',
'line_ids_spare_ups3.total_price', 'line_ids_spare_ups3.production_cost',
'line_ids_spare_ups4.total_price', 'line_ids_spare_ups4.production_cost',
'line_ids_spare_ups5.total_price', 'line_ids_spare_ups5.production_cost',
'line_ids_spare_ups6.total_price', 'line_ids_spare_ups6.production_cost',
'line_ids_spare_ups7.total_price', 'line_ids_spare_ups7.production_cost',
'line_ids_spare_ups8.total_price', 'line_ids_spare_ups8.production_cost',
'line_ids_spare_ups9.total_price', 'line_ids_spare_ups9.production_cost',
'line_ids_spare_ups10.total_price', 'line_ids_spare_ups10.production_cost',
'line_ids_spare_ups11.total_price', 'line_ids_spare_ups11.production_cost',
'line_ids_spare_ups12.total_price', 'line_ids_spare_ups12.production_cost',
'line_ids_spare_ups13.total_price', 'line_ids_spare_ups13.production_cost',
'line_ids_spare_ups14.total_price', 'line_ids_spare_ups14.production_cost',
'line_ids_spare_ups15.total_price', 'line_ids_spare_ups15.production_cost'
)
def _compute_ups_total(self):
for rec in self:
for i in range(1, 16):
total = 0
for field_name in [
'line_ids_fg',
'line_ids_sfg',
'line_ids_material',
'line_ids_installation_kit',
'line_ids_miscellaneous',
f'line_ids_spare_ups{i}',
]:
lines = getattr(rec, field_name)
total += sum(
line.total_price for line in lines
if line.ups_index == i and line.production_cost
)
setattr(rec, f'ups{i}_total', total)
@api.depends(
'line_ids_fg.ups_index',
'line_ids_sfg.ups_index',
'line_ids_material.ups_index',
'line_ids_installation_kit.ups_index',
'line_ids_miscellaneous.ups_index'
)
def _compute_line_ids_by_ups(self):
for rec in self:
rec.line_ids_fg_ups1 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 1)
rec.line_ids_fg_ups2 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 2)
rec.line_ids_fg_ups3 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 3)
rec.line_ids_fg_ups4 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 4)
rec.line_ids_fg_ups5 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 5)
rec.line_ids_fg_ups6 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 6)
rec.line_ids_fg_ups7 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 7)
rec.line_ids_fg_ups8 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 8)
rec.line_ids_fg_ups9 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 9)
rec.line_ids_fg_ups10 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 10)
rec.line_ids_fg_ups11 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 11)
rec.line_ids_fg_ups12 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 12)
rec.line_ids_fg_ups13 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 13)
rec.line_ids_fg_ups14 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 14)
rec.line_ids_fg_ups15 = rec.line_ids_fg.filtered(lambda l: l.ups_index == 15)
rec.line_ids_sfg_ups1 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 1)
rec.line_ids_sfg_ups2 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 2)
rec.line_ids_sfg_ups3 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 3)
rec.line_ids_sfg_ups4 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 4)
rec.line_ids_sfg_ups5 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 5)
rec.line_ids_sfg_ups6 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 6)
rec.line_ids_sfg_ups7 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 7)
rec.line_ids_sfg_ups8 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 8)
rec.line_ids_sfg_ups9 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 9)
rec.line_ids_sfg_ups10 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 10)
rec.line_ids_sfg_ups11 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 11)
rec.line_ids_sfg_ups12 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 12)
rec.line_ids_sfg_ups13 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 13)
rec.line_ids_sfg_ups14 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 14)
rec.line_ids_sfg_ups15 = rec.line_ids_sfg.filtered(lambda l: l.ups_index == 15)
rec.line_ids_material_ups1 = rec.line_ids_material.filtered(lambda l: l.ups_index == 1)
rec.line_ids_material_ups2 = rec.line_ids_material.filtered(lambda l: l.ups_index == 2)
rec.line_ids_material_ups3 = rec.line_ids_material.filtered(lambda l: l.ups_index == 3)
rec.line_ids_material_ups4 = rec.line_ids_material.filtered(lambda l: l.ups_index == 4)
rec.line_ids_material_ups5 = rec.line_ids_material.filtered(lambda l: l.ups_index == 5)
rec.line_ids_material_ups6 = rec.line_ids_material.filtered(lambda l: l.ups_index == 6)
rec.line_ids_material_ups7 = rec.line_ids_material.filtered(lambda l: l.ups_index == 7)
rec.line_ids_material_ups8 = rec.line_ids_material.filtered(lambda l: l.ups_index == 8)
rec.line_ids_material_ups9 = rec.line_ids_material.filtered(lambda l: l.ups_index == 9)
rec.line_ids_material_ups10 = rec.line_ids_material.filtered(lambda l: l.ups_index == 10)
rec.line_ids_material_ups11 = rec.line_ids_material.filtered(lambda l: l.ups_index == 11)
rec.line_ids_material_ups12 = rec.line_ids_material.filtered(lambda l: l.ups_index == 12)
rec.line_ids_material_ups13 = rec.line_ids_material.filtered(lambda l: l.ups_index == 13)
rec.line_ids_material_ups14 = rec.line_ids_material.filtered(lambda l: l.ups_index == 14)
rec.line_ids_material_ups15 = rec.line_ids_material.filtered(lambda l: l.ups_index == 15)
rec.line_ids_installation_kit_ups1 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 1)
rec.line_ids_installation_kit_ups2 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 2)
rec.line_ids_installation_kit_ups3 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 3)
rec.line_ids_installation_kit_ups4 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 4)
rec.line_ids_installation_kit_ups5 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 5)
rec.line_ids_installation_kit_ups6 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 6)
rec.line_ids_installation_kit_ups7 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 7)
rec.line_ids_installation_kit_ups8 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 8)
rec.line_ids_installation_kit_ups9 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 9)
rec.line_ids_installation_kit_ups10 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 10)
rec.line_ids_installation_kit_ups11 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 11)
rec.line_ids_installation_kit_ups12 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 12)
rec.line_ids_installation_kit_ups13 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 13)
rec.line_ids_installation_kit_ups14 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 14)
rec.line_ids_installation_kit_ups15 = rec.line_ids_installation_kit.filtered(lambda l: l.ups_index == 15)
rec.line_ids_miscellaneous_ups1 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 1)
rec.line_ids_miscellaneous_ups2 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 2)
rec.line_ids_miscellaneous_ups3 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 3)
rec.line_ids_miscellaneous_ups4 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 4)
rec.line_ids_miscellaneous_ups5 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 5)
rec.line_ids_miscellaneous_ups6 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 6)
rec.line_ids_miscellaneous_ups7 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 7)
rec.line_ids_miscellaneous_ups8 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 8)
rec.line_ids_miscellaneous_ups9 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 9)
rec.line_ids_miscellaneous_ups10 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 10)
rec.line_ids_miscellaneous_ups11 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 11)
rec.line_ids_miscellaneous_ups12 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 12)
rec.line_ids_miscellaneous_ups13 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 13)
rec.line_ids_miscellaneous_ups14 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 14)
rec.line_ids_miscellaneous_ups15 = rec.line_ids_miscellaneous.filtered(lambda l: l.ups_index == 15)
@api.model
def create(self, vals):
record = super().create(vals)
if vals.get('proposal_id') and vals.get('products') == "BHMS 12V":
record._generate_boq_lines_from_proposal_12v()
elif vals.get('proposal_id') and vals.get('products') == "BHMS 1.2V" and vals.get('slave_type') == "15S Individual Slave":
record._generate_boq_lines_from_proposal_15s()
return record
@api.onchange('proposal_id')
def _onchange_proposal_id(self):
if not self.proposal_id:
return
if self.line_ids_fg or self.line_ids_material or self.line_ids_sfg:
return
self.customer_name = self.proposal_id.customer_name
self.location = self.proposal_id.location
self.no_of_electrical_panel = self.proposal_id.no_of_electrical_panel
self.number_of_batteries = self.proposal_id.number_of_batteries
self.number_of_ups = self.proposal_id.number_of_ups
self.products = self.proposal_id.products
self.communication_type = self.proposal_id.communication_type
self.slave_type = self.proposal_id.slave_type
self.specific_requirements = self.proposal_id.specific_requirements
self.line_ids_fg = [(5, 0, 0)]
self.line_ids_sfg = [(5, 0, 0)]
self.line_ids_material = [(5, 0, 0)]
self.line_ids_installation_kit = [(5, 0, 0)]
self.line_ids_miscellaneous = [(5, 0, 0)]
if self.products == 'BHMS 12V':
self._generate_boq_lines_from_proposal_12v()
elif self.products == 'BHMS 1.2V':
self._generate_boq_lines_from_proposal_15s()
def _generate_boq_lines_from_proposal_15s(self):
if not self.proposal_id:
return
record = self.env['sos_deliverables_config'].search([
('fg_name', '=', self.products),
('slave_type', '=', self.slave_type)
], limit=1)
if record and self.number_of_ups:
fg_lines = []
sfg_lines = []
material_lines = []
install_kit_lines = []
misc_lines = []
for ups_index in range(1, self.number_of_ups + 1):
for line in record.fg_ids:
single_set_qty = 1
if line.item_type == 'Master Panel':
single_set_qty = 1
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery
ct_module = ((matching_ups_line.ups_capacity_kva * 1000) / (12 * matching_ups_line.number_of_batteries)) / 10
if 0 <= ct_module < 100:
material_code="MDS070"
elif 100 <= ct_module < 200:
material_code="MDS071"
elif 200 <= ct_module < 300:
material_code="MDS069"
else:
material_code="MDS040"
material_record=self.env['sos_material'].search([('material_code', '=', material_code)],limit=1)
material_lines.append((0, 0, {
'component_id': material_record.id,
'uom': material_record.uom,
'singet_set_qty':single_set_qty,
'unit_price': material_record.unit_price,
'description': material_record.description,
'ups_index': ups_index,
'production_cost':True
}))
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = math.ceil((matching_ups_line.number_of_batteries / 15)
* matching_ups_line.number_of_strings_per_battery)
name_lower = (line.component_id.name or "").lower()
is_electrical_panel = "electrical panel" in name_lower
# Find the UPS line for this index (use first match if multiple)
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)[:1]
num_strings = (matching_ups_line.number_of_strings_per_battery
if matching_ups_line and matching_ups_line.number_of_strings_per_battery
else 0)
fg_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': line.component_id.unit_price, # no panel-based zeroing
'description': line.description,
'item_type': line.item_type,
'total_set': 1, # stays 1
'singet_set_qty': num_strings if is_electrical_panel else single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index,
}))
for line in record.sfg_ids:
if line.item_type == 'Master Panel':
single_set_qty = 1
elif line.item_type == 'Battery Count':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = matching_ups_line.number_of_batteries
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery # example logic
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = math.ceil((matching_ups_line.number_of_batteries)/4) * matching_ups_line.number_of_strings_per_battery
sfg_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': line.component_id.unit_price,
'description': line.description,
'item_type': line.item_type,
'singet_set_qty': single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index
}))
for line in record.material_ids:
if line.item_type == 'Internet Module' and self.proposal_id.internet_connectivity != 'yes':
continue
if line.item_type == 'Master Panel':
single_set_qty = 1 * line.quantity
elif line.item_type == 'Battery Count':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = matching_ups_line.number_of_batteries
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery * line.quantity
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = (math.ceil((matching_ups_line.number_of_batteries)/4) * matching_ups_line.number_of_strings_per_battery) * line.quantity
material_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': line.component_id.unit_price,
'description': line.description,
'item_type': line.item_type,
'singet_set_qty': single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index
}))
for line in record.installation_kit_ids:
if line.item_type == 'Master Panel':
single_set_qty = 1 * line.quantity
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery * line.quantity
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = (math.ceil((matching_ups_line.number_of_batteries)/4) * matching_ups_line.number_of_strings_per_battery) * line.quantity
install_kit_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': line.component_id.unit_price,
'description': line.description,
'item_type': line.item_type,
'singet_set_qty': single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index
}))
misc_lines += [(0, 0, {
'name': line.name,
'cost': line.cost,
'quantity': line.quantity,
'ups_index': ups_index
}) for line in record.miscellaneous_ids]
self.write({
'line_ids_fg': fg_lines,
'line_ids_sfg': sfg_lines,
'line_ids_material': material_lines,
'line_ids_installation_kit': install_kit_lines,
'line_ids_miscellaneous': misc_lines
})
def _generate_boq_lines_from_proposal_12v(self):
if not self.proposal_id:
return
record = self.env['sos_deliverables_config'].search([
('fg_name', '=', self.products),
('communication_type', '=', self.communication_type)
], limit=1)
if record and self.number_of_ups:
fg_lines = []
sfg_lines = []
material_lines = []
install_kit_lines = []
misc_lines = []
for ups_index in range(1, self.number_of_ups + 1):
for line in record.fg_ids:
single_set_qty = 1
if line.item_type == 'Master Panel':
single_set_qty = 1
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery
ct_module = ((matching_ups_line.ups_capacity_kva * 1000) / (12 * matching_ups_line.number_of_batteries)) / 10
if 0 <= ct_module < 100:
material_code="MDS070"
elif 100 <= ct_module < 200:
material_code="MDS071"
elif 200 <= ct_module < 300:
material_code="MDS069"
else:
material_code="MDS040"
material_record=self.env['sos_material'].search([('material_code', '=', material_code)],limit=1)
material_lines.append((0, 0, {
'component_id': material_record.id,
'uom': material_record.uom,
'singet_set_qty':single_set_qty,
'unit_price': material_record.unit_price,
'description': material_record.description,
'ups_index': ups_index,
'production_cost':True
}))
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = math.ceil((matching_ups_line.number_of_batteries)/4) * matching_ups_line.number_of_strings_per_battery
name_lower = (line.component_id.name or "").lower()
is_electrical_panel = "electrical panel" in name_lower
is_panel_exceeding = self.proposal_id.no_of_electrical_panel < ups_index
fg_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': 0.00 if is_panel_exceeding and is_electrical_panel else line.component_id.unit_price,
'description': line.description,
'item_type': line.item_type,
'total_set': 0 if is_panel_exceeding and is_electrical_panel else 1,
'singet_set_qty': 0 if is_panel_exceeding and is_electrical_panel else single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index
}))
for line in record.sfg_ids:
if line.item_type == 'Master Panel':
single_set_qty = 1
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery # example logic
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = math.ceil((matching_ups_line.number_of_batteries)/4) * matching_ups_line.number_of_strings_per_battery
sfg_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': line.component_id.unit_price,
'description': line.description,
'item_type': line.item_type,
'singet_set_qty': single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index
}))
for line in record.material_ids:
if line.item_type == 'Internet Module' and self.proposal_id.internet_connectivity != 'yes':
continue
if line.item_type == 'Master Panel':
single_set_qty = 1 * line.quantity
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery * line.quantity
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = (math.ceil((matching_ups_line.number_of_batteries)/4) * matching_ups_line.number_of_strings_per_battery) * line.quantity
material_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': line.component_id.unit_price,
'description': line.description,
'item_type': line.item_type,
'singet_set_qty': single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index
}))
for line in record.installation_kit_ids:
if line.item_type == 'Master Panel':
single_set_qty = 1 * line.quantity
elif line.item_type == 'CT Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
number_of_strings_per_battery = matching_ups_line.number_of_strings_per_battery
single_set_qty = number_of_strings_per_battery * line.quantity
elif line.item_type == 'Slave Module':
matching_ups_line = self.proposal_id.ups_line_ids.filtered(lambda l: l.ups_index == ups_index)
if matching_ups_line:
single_set_qty = (math.ceil((matching_ups_line.number_of_batteries)/4) * matching_ups_line.number_of_strings_per_battery) * line.quantity
install_kit_lines.append((0, 0, {
'component_id': line.component_id.id,
'uom': line.uom,
'unit_price': line.component_id.unit_price,
'description': line.description,
'item_type': line.item_type,
'singet_set_qty': single_set_qty,
'production_cost': line.add_production_cost,
'ups_index': ups_index
}))
misc_lines += [(0, 0, {
'name': line.name,
'cost': line.cost,
'quantity': line.quantity,
'ups_index': ups_index
}) for line in record.miscellaneous_ids]
self.write({
'line_ids_fg': fg_lines,
'line_ids_sfg': sfg_lines,
'line_ids_material': material_lines,
'line_ids_installation_kit': install_kit_lines,
'line_ids_miscellaneous': misc_lines
})
def action_report_btn(self):
try:
action = self.env.ref("sos_sales.action_report_proposal_boq").report_action(self)
return action
except ValueError as e:
print(f"Failed to find report action: {e}")
@api.depends('ups1_total','ups2_total','ups3_total','ups4_total','ups5_total','ups6_total','ups7_total','ups8_total','ups9_total','ups10_total')
def _compute_total_cost(self):
for record in self:
record.total_cost = record.ups1_total + record.ups2_total + record.ups3_total + record.ups4_total + record.ups5_total + record.ups6_total + record.ups7_total + record.ups8_total + record.ups9_total + record.ups10_total
@api.depends('line_ids_miscellaneous.cost')
def _compute_total_miscellaneous_cost(self):
for record in self:
record.total_miscellaneous_cost = sum(line.total_price for line in record.line_ids_miscellaneous)
@api.depends('line_ids_installation_kit.unit_price')
def _compute_total_installation_material_cost(self):
for record in self:
record.total_installation_material_cost = sum(line.total_price for line in record.line_ids_installation_kit)
@api.depends('line_ids_material.unit_price')
def _compute_total_material_cost(self):
for record in self:
record.total_material_cost = sum(line.total_price for line in record.line_ids_material)
@api.depends('line_ids_sfg.unit_price')
def _compute_total_sfg_cost(self):
for record in self:
record.total_sfg_cost = sum(line.total_price for line in record.line_ids_sfg)
@api.depends('line_ids_fg.unit_price')
def _compute_total_fg_cost(self):
for record in self:
record.total_fg_cost = sum(line.total_price for line in record.line_ids_fg)
def action_ce_esign_btn(self):
body_html = f"""
Below BOQ is waiting for your updation.
Customer Name: {self.customer_name or ''}
Location: {self.location or ''}
Number of Batteries: {self.number_of_batteries or ''}
"""
sequence_util = self.env['sos_common_scripts']
sequence_util.send_group_email(
self.env,
'sos_proposal_boq',
self.id,
"deenalaura.m@sosaley.in",
f"Proposal System - BOQ Submitted for {self.customer_name}",
body_html,
'sos_inventory.sos_finance_user'
)
return sequence_util.action_assign_signature(
self,
'boq_submitted_by_name',
'boq_submitted_by_approved_on'
)
def action_acc_esign_btn(self):
self.ensure_one()
sequence_util = self.env['sos_common_scripts']
# ---- Pretty values with fallbacks ----
customer = self.customer_name or 'â'
location = self.location or 'â'
batteries = int(self.number_of_batteries or 0)
currency_symbol = self.env.company.currency_id.symbol or ''
final_cost = float(self.final_cost_by_acc or 0.0)
final_cost_disp = f"{currency_symbol} {final_cost:,.2f}"
warranty = self.proposal_id.warranty
insta_location = self.proposal_id.installation_location or 'â'
# ---- HTML body ----
body_html = f"""
Below Proposal Costing was completed. You can proceed with the proposal builder.
| Customer |
{customer} |
| Delivery Location |
{location} |
| Installation Location |
{insta_location} |
| Number of Batteries |
{batteries:,} |
| Warranty (In Months) |
{warranty} |
| Final MSP per Battery |
{final_cost_disp} |
"""
# Who submitted requirements?
req_submitted_by = self.env['sos_proposal_customer_requirement'].search([
('proposal_id', '=', self.proposal_id.proposal_id)
], limit=1)
if req_submitted_by and req_submitted_by.requirement_submitted_by_name and req_submitted_by.requirement_submitted_by_name.login:
sequence_util.send_direct_email(
self.env,
"sos_proposal_boq",
self.id,
req_submitted_by.requirement_submitted_by_name.login,
f"Costing Done - {customer}",
body_html
)
# Assign signature (account approval)
return sequence_util.action_assign_signature(
self,
'acc_approved_by_name',
'acc_approved_on'
)
class SOS_Proposal_BOQ_Material(models.Model):
_name = 'sos_proposal_boq_material'
_description = 'Proposal BOQ Material Lines'
ref_id = fields.Many2one('sos_proposal_boq', string="Materials", ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'), ('Packs', 'Packs'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",store=True)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
item_type = fields.Selection([
('Master Panel', 'Master Panel'),
('CT Module', 'CT Module'),
('Slave Module', 'Slave Module'),
('Internet Module', 'Internet Module')
], string="Type",default="Master Panel")
production_cost = fields.Boolean(string="Include in Costing")
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
record.total_price = record.unit_price * record.quantity
class SOS_Proposal_BOQ_SFG(models.Model):
_name = 'sos_proposal_boq_sfg'
_description = 'Proposal BOQ SFG Lines'
ref_id = fields.Many2one('sos_proposal_boq', string="SFG", ondelete="cascade")
currency_id = fields.Many2one('res.currency', string='Currency')
component_id = fields.Many2one('sos_sfg', string="SFG Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
sfg_code = fields.Char(related="component_id.sfg_code",string="SFG Code")
sfg_name = fields.Char(related="component_id.name",string="SFG Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",store=True)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
item_type = fields.Selection([
('Master Panel', 'Master Panel'),
('CT Module', 'CT Module'),
('Slave Module', 'Slave Module'),
('Internet Module', 'Internet Module')
], string="Type",default="Master Panel")
production_cost = fields.Boolean(string="Include in Costing")
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
"""
Set the initial value of `unit_price` when `component_id` is changed.
"""
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class SOS_Proposal_BOQ_FG(models.Model):
_name = 'sos_proposal_boq_fg'
_description = 'Proposal BOQ FG Lines'
ref_id = fields.Many2one('sos_proposal_boq', string="FG", ondelete="cascade")
currency_id = fields.Many2one('res.currency', string='Currency')
component_id = fields.Many2one('sos_fg',string="FG Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
fg_code = fields.Char(related="component_id.fg_code",string="FG Code")
fg_name = fields.Char(related="component_id.name",string="FG Name")
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",store=True)
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
item_type = fields.Selection([
('Master Panel', 'Master Panel'),
('CT Module', 'CT Module'),
('Slave Module', 'Slave Module'),
('Internet Module', 'Internet Module')
], string="Type",default="Master Panel")
production_cost = fields.Boolean(string="Include in Costing")
ups_index = fields.Integer(string="UPS Index",store=True)
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_proposal_MiscellaneousCost(models.Model):
_name = 'sos_proposal_miscellaneous_items'
_description = 'Miscellaneous Items'
ref_id = fields.Many2one('sos_proposal_boq', string="Miscellaneous", ondelete="cascade")
name = fields.Char(string='Name')
cost = fields.Float(string='Cost')
quantity = fields.Integer(string="Quantity")
currency_id = fields.Many2one('res.currency', string='Currency')
total_price = fields.Monetary(string="Total", currency_field='currency_id',compute="_compute_total_price")
ups_index = fields.Integer(string="UPS Index",store=True)
production_cost = fields.Boolean(string="Include in Costing",default=True)
@api.depends('cost','quantity')
def _compute_total_price(self):
for record in self:
record.total_price = record.cost * record.quantity
class sos_proposal_Material_installationkit(models.Model):
_name = 'sos_proposal_line_material_installation'
_description = 'Installation Kit Lines'
ref_id = fields.Many2one('sos_proposal_boq', string="Materials", ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
item_type = fields.Selection([
('Master Panel', 'Master Panel'),
('CT Module', 'CT Module'),
('Slave Module', 'Slave Module'),
('Internet Module', 'Internet Module')
], string="Type",default="Master Panel")
production_cost = fields.Boolean(string="Include in Costing")
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity','production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_proposal_Material_installationkit(models.Model):
_name = 'sos_proposal_line_spare'
_description = 'Spare Lines'
ref_id = fields.Many2one('sos_proposal_boq', string="Materials", ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing")
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price','quantity')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_extra_cost_lines(models.Model):
_name = 'sos_extra_cost_lines'
_description = 'Extra Lines'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
field_name = fields.Char(string="Name")
currency_id = fields.Many2one(
'res.currency',
string='Currency',
default=lambda self: self.env['res.currency'].search([('name', '=', 'INR')], limit=1).id or False
)
cost = fields.Monetary(string="Cost", currency_field='currency_id', store=True)
class sos_spare_material1(models.Model):
_name = 'sos_proposal_line_spare_ups1'
_description = 'Spare Material 1'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material2(models.Model):
_name = 'sos_proposal_line_spare_ups2'
_description = 'Spare Material 2'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material3(models.Model):
_name = 'sos_proposal_line_spare_ups3'
_description = 'Spare Material 3'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material4(models.Model):
_name = 'sos_proposal_line_spare_ups4'
_description = 'Spare Material 4'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material5(models.Model):
_name = 'sos_proposal_line_spare_ups5'
_description = 'Spare Material 5'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material6(models.Model):
_name = 'sos_proposal_line_spare_ups6'
_description = 'Spare Material 6'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material7(models.Model):
_name = 'sos_proposal_line_spare_ups7'
_description = 'Spare Material 7'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material8(models.Model):
_name = 'sos_proposal_line_spare_ups8'
_description = 'Spare Material 8'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material9(models.Model):
_name = 'sos_proposal_line_spare_ups9'
_description = 'Spare Material 9'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material10(models.Model):
_name = 'sos_proposal_line_spare_ups10'
_description = 'Spare Material 10'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material11(models.Model):
_name = 'sos_proposal_line_spare_ups11'
_description = 'Spare Material 11'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material12(models.Model):
_name = 'sos_proposal_line_spare_ups12'
_description = 'Spare Material 12'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material13(models.Model):
_name = 'sos_proposal_line_spare_ups13'
_description = 'Spare Material 13'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material14(models.Model):
_name = 'sos_proposal_line_spare_ups14'
_description = 'Spare Material 14'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00
class sos_spare_material15(models.Model):
_name = 'sos_proposal_line_spare_ups15'
_description = 'Spare Material 15'
ref_id = fields.Many2one('sos_proposal_boq', ondelete="cascade")
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
uom = fields.Selection([('meters', 'Meters'),('Nos', 'Nos'),('coils', 'Coils'), ('litre', 'litre'), ('kg', 'Kilogram'), ('Packs', 'Packs')], default="Nos",string="Uom")
currency_id = fields.Many2one('res.currency', string='Currency')
material_code = fields.Char(related="component_id.material_code",string="Material Code")
material_name = fields.Char(related="component_id.part_no",string="Material Name")
singet_set_qty = fields.Integer(string="Single Set Quantity",default=1)
total_set = fields.Integer(string="Total Set",default=1)
quantity = fields.Integer(string="Quantity",compute="_compute_set_wise",readonly=False)
unit_price = fields.Monetary(store=True,currency_field='currency_id',string="Unit Price",related="component_id.unit_price")
total_price = fields.Monetary(string="Total",compute="_compute_total_price")
description = fields.Char(string="Description")
production_cost = fields.Boolean(string="Include in Costing",default=True)
ups_index = fields.Integer(string="UPS Index",store=True)
@api.onchange('component_id')
def _onchange_component_id(self):
for record in self:
if record.component_id:
record.unit_price = record.component_id.unit_price
@api.depends('singet_set_qty','total_set')
def _compute_set_wise(self):
for record in self:
record.quantity = record.singet_set_qty * record.total_set
@api.depends('unit_price', 'quantity', 'production_cost')
def _compute_total_price(self):
for record in self:
if record.production_cost:
record.total_price = record.unit_price * record.quantity
else:
record.total_price = 0.00