This commit is contained in:
Deena 2025-08-11 11:14:47 +05:30
parent f7db2aebc9
commit faa8f2ff3b
5 changed files with 531 additions and 121 deletions

View File

@ -1,5 +1,7 @@
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'
@ -100,6 +102,14 @@ class Battery_Installation_Requirement(models.Model):
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)
@ -120,21 +130,21 @@ class Battery_Installation_Requirement(models.Model):
#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)
line_ids_material_ups2 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 2",compute='_compute_line_ids_by_ups',store=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)
line_ids_material_ups4 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 4",compute='_compute_line_ids_by_ups',store=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)
line_ids_material_ups6 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 6",compute='_compute_line_ids_by_ups',store=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)
line_ids_material_ups8 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 8",compute='_compute_line_ids_by_ups',store=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)
line_ids_material_ups10 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 10",compute='_compute_line_ids_by_ups',store=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)
line_ids_material_ups12 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 12",compute='_compute_line_ids_by_ups',store=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)
line_ids_material_ups14 = fields.One2many('sos_proposal_boq_material', 'ref_id', string="Material UPS 14",compute='_compute_line_ids_by_ups',store=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)
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
@ -206,6 +216,454 @@ class Battery_Installation_Requirement(models.Model):
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")
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)]):
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 = "<em>No Material items.</em>"
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"<tr>"
f"<td>{name_map[key]}</td>"
f"<td>{key[1] or ''}</td>"
f"<td style='text-align:right'>{fmt_price(price_map[key], curr_map[key])}</td>"
f"<td style='text-align:right'>{qty:.2f}</td>"
f"<td style='text-align:right'>{fmt_price(total_price, curr_map[key])}</td>"
f"</tr>"
)
if not rows_html:
rec.merged_spare_html = "<em>No Material items.</em>"
continue
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f"<tr style='font-weight:bold;'>"
f"<td colspan='4' style='text-align:right'>Grand Total:</td>"
f"<td style='text-align:right'>{fmt_price(total_sum, currency_for_total)}</td>"
f"</tr>"
)
rec.merged_spare_html = f"""
<table class="table table-sm" style="width:100%;">
<thead>
<tr>
<th><b>Material Name</b></th>
<th><b>UoM</b></th>
<th style="text-align:right"><b>Unit Price</b></th>
<th style="text-align:right"><b>Total Qty</b></th>
<th style="text-align:right"><b>Total Price</b></th>
</tr>
</thead>
<tbody>{rows_html}</tbody>
</table>
"""
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 = "<em>No Miscellaneous items.</em>"
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"<tr>"
f"<td>{name_map[key]}</td>"
f"<td style='text-align:right'>{fmt_price(price_map[key], curr_map[key])}</td>"
f"<td style='text-align:right'>{qty:.2f}</td>"
f"<td style='text-align:right'>{fmt_price(total_price, curr_map[key])}</td>"
f"</tr>"
)
if not rows_html: # If all rows were skipped
rec.merged_miscellaneous_html = "<em>No Miscellaneous items.</em>"
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f"<tr style='font-weight:bold;'>"
f"<td colspan='3' style='text-align:right'>Grand Total:</td>"
f"<td style='text-align:right'>{fmt_price(total_sum, currency_for_total)}</td>"
f"</tr>"
)
rec.merged_miscellaneous_html = f"""
<table class="table table-sm" style="width:100%;">
<thead>
<tr>
<th><b>Name</b></th>
<th style="text-align:right"><b>Unit Price</b></th>
<th style="text-align:right"><b>Total Qty</b></th>
<th style="text-align:right"><b>Total Price</b></th>
</tr>
</thead>
<tbody>{rows_html}</tbody>
</table>
"""
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:
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 = "<em>No Material items.</em>"
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"<tr>"
f"<td>{name_map[key]}</td>"
f"<td>{key[1] or ''}</td>"
f"<td style='text-align:right'>{fmt_price(price_map[key], curr_map[key])}</td>"
f"<td style='text-align:right'>{qty:.2f}</td>"
f"<td style='text-align:right'>{fmt_price(total_price, curr_map[key])}</td>"
f"</tr>"
)
if not rows_html: # If all rows were skipped
rec.merged_installation_kit_html = "<em>No Material items.</em>"
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f"<tr style='font-weight:bold;'>"
f"<td colspan='4' style='text-align:right'>Grand Total:</td>"
f"<td style='text-align:right'>{fmt_price(total_sum, currency_for_total)}</td>"
f"</tr>"
)
rec.merged_installation_kit_html = f"""
<table class="table table-sm" style="width:100%;">
<thead>
<tr>
<th><b>Material Name</b></th>
<th><b>UoM</b></th>
<th style="text-align:right"><b>Unit Price</b></th>
<th style="text-align:right"><b>Total Qty</b></th>
<th style="text-align:right"><b>Total Price</b></th>
</tr>
</thead>
<tbody>{rows_html}</tbody>
</table>
"""
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 = "<em>No Material items.</em>"
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"<tr>"
f"<td>{name_map[key]}</td>"
f"<td>{key[1] or ''}</td>"
f"<td style='text-align:right'>{fmt_price(price_map[key], curr_map[key])}</td>"
f"<td style='text-align:right'>{qty:.2f}</td>"
f"<td style='text-align:right'>{fmt_price(total_price, curr_map[key])}</td>"
f"</tr>"
)
if not rows_html: # If all rows were skipped
rec.merged_material_html = "<em>No Material items.</em>"
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f"<tr style='font-weight:bold;'>"
f"<td colspan='4' style='text-align:right'>Grand Total:</td>"
f"<td style='text-align:right'>{fmt_price(total_sum, currency_for_total)}</td>"
f"</tr>"
)
rec.merged_material_html = f"""
<table class="table table-sm" style="width:100%;">
<thead>
<tr>
<th><b>Material Name</b></th>
<th><b>UoM</b></th>
<th style="text-align:right"><b>Unit Price</b></th>
<th style="text-align:right"><b>Total Qty</b></th>
<th style="text-align:right"><b>Total Price</b></th>
</tr>
</thead>
<tbody>{rows_html}</tbody>
</table>
"""
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:
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 = "<em>No SFG items.</em>"
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"<tr>"
f"<td>{name_map[key]}</td>"
f"<td>{key[1] or ''}</td>"
f"<td style='text-align:right'>{fmt_price(price_map[key], curr_map[key])}</td>"
f"<td style='text-align:right'>{qty:.2f}</td>"
f"<td style='text-align:right'>{fmt_price(total_price, curr_map[key])}</td>"
f"</tr>"
)
if not rows_html: # If all rows were skipped
rec.merged_sfg_html = "<em>No SFG items.</em>"
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f"<tr style='font-weight:bold;'>"
f"<td colspan='4' style='text-align:right'>Grand Total:</td>"
f"<td style='text-align:right'>{fmt_price(total_sum, currency_for_total)}</td>"
f"</tr>"
)
rec.merged_sfg_html = f"""
<table class="table table-sm" style="width:100%;">
<thead>
<tr>
<th><b>SFG Name</b></th>
<th><b>UoM</b></th>
<th style="text-align:right"><b>Unit Price</b></th>
<th style="text-align:right"><b>Total Qty</b></th>
<th style="text-align:right"><b>Total Price</b></th>
</tr>
</thead>
<tbody>{rows_html}</tbody>
</table>
"""
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:
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 = "<em>No FG items.</em>"
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"<tr>"
f"<td>{name_map[key]}</td>"
f"<td>{key[1] or ''}</td>"
f"<td style='text-align:right'>{fmt_price(price_map[key], curr_map[key])}</td>"
f"<td style='text-align:right'>{qty:.2f}</td>"
f"<td style='text-align:right'>{fmt_price(total_price, curr_map[key])}</td>"
f"</tr>"
)
if not rows_html: # If all rows were skipped
rec.merged_fg_html = "<em>No FG items.</em>"
continue
# Add grand total row
currency_for_total = curr_map[rows_sorted[0][0]] if rows_sorted else False
rows_html += (
f"<tr style='font-weight:bold;'>"
f"<td colspan='4' style='text-align:right'>Grand Total:</td>"
f"<td style='text-align:right'>{fmt_price(total_sum, currency_for_total)}</td>"
f"</tr>"
)
rec.merged_fg_html = f"""
<table class="table table-sm" style="width:100%;">
<thead>
<tr>
<th><b>FG Name</b></th>
<th><b>UoM</b></th>
<th style="text-align:right"><b>Unit Price</b></th>
<th style="text-align:right"><b>Total Qty</b></th>
<th style="text-align:right"><b>Total Price</b></th>
</tr>
</thead>
<tbody>{rows_html}</tbody>
</table>
"""
@api.model
def create(self, vals):
res = super().create(vals)
@ -662,10 +1120,22 @@ class Battery_Installation_Requirement(models.Model):
record.total_fg_cost = sum(line.total_price for line in record.line_ids_fg)
def action_ce_esign_btn(self):
body_html = f"""
<p>Below <b>Proposal</b> is waiting for your Updation</p>
<p>Below <b>BOQ</b> is waiting for your updation.</p>
<p><b>Customer Name:</b> {self.customer_name or ''}</p>
<p><b>Location:</b> {self.location or ''}</p>
<p><b>Number of Batteries:</b> {self.number_of_batteries or ''}</p>
"""
sequence_util = self.env['sos_common_scripts']
sequence_util.send_group_email(self.env,'sos_proposal_boq',self.id,"deenalaura.m@sosaley.in","Proposal System - BOQ Submitted",body_html,'sos_inventory.sos_finance_user')
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',

View File

@ -694,16 +694,31 @@ class SOS_Sales_Achievement_Report_Brief(models.Model):
report.write({
new_field_billed: (getattr(report, new_field_billed, 0.0) or 0.0) + new_billed_amount
})
# Optionally create billing collection entry (if needed)
if new_billed_amount > 0:
# Optionally create billing collection entry (if needed
domain = [
('ref_id', '=', report.id),
('sales_person', '=', report.sales_person.id),
('customer_name', '=', vals.get('customer_name', rec.customer_name.id))
]
existing = self.env['sos_billing_collection'].search(domain, limit=1)
if not existing:
self.env['sos_billing_collection'].create({
'ref_id': report.id,
'customer_name': vals.get('customer_name', rec.customer_name.id),
'sales_person': report.sales_person.id,
'action_status': 'Billed',
'date_of_action': new_billed_date,
'po_no':vals.get('po_no'),
'value': new_billed_amount
})
else:
existing.write({
'value': new_billed_amount,
'po_no':vals.get('po_no'),
'date_of_action': new_billed_date
})
return super(SOS_Sales_Achievement_Report_Brief, self).write(vals)
@ -748,7 +763,8 @@ class SOS_Sales_Achievement_Report_Brief(models.Model):
'sales_person': report.sales_person.id,
'action_status': 'Billed',
'date_of_action': billed_date,
'value': billed_value
'value': billed_value,
'po_no':vals.get('po_no')
})
new_record = super(SOS_Sales_Achievement_Report_Brief, self).create(vals)
return new_record

View File

@ -40,6 +40,7 @@
<notebook>
<!-- Page 1 -->
<page string="UPS 1" invisible="number_of_ups &lt; 1">
<h3 style="text-transform: uppercase;
text-decoration: underline;">Finished Goods</h3>
@ -1654,115 +1655,38 @@
</div>
</div>
</page>
<!-- <page string="Finished Goods">
<field name="line_ids_fg">
<tree editable="bottom">
<field name="production_cost" widget="boolean_toggle"/>
<field name="component_id"/>
<field name="description"/>
<field name="item_type"/>
<field name="uom"/>
<field name="unit_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
<field name="singet_set_qty"/>
<field name="total_set"/>
<field name="quantity"/>
<field name="total_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
</tree>
</field>
<group style="float: right;
font-weight: bold;
font-size: 18px;">
<field name="total_fg_cost"/>
</group>
</page> -->
<!-- <page string="Semi Finished Goods">
<field name="line_ids_sfg">
<tree editable="bottom">
<field name="production_cost" widget="boolean_toggle"/>
<field name="component_id"/>
<field name="description"/>
<field name="item_type"/>
<field name="uom"/>
<field name="unit_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
<field name="singet_set_qty"/>
<field name="total_set"/>
<field name="quantity"/>
<field name="total_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
</tree>
</field>
<group style="float: right;
font-weight: bold;
font-size: 18px;">
<field name="total_sfg_cost"/>
</group>
</page> -->
<!-- <page string="Materials">
<field name="line_ids_material">
<tree editable="bottom">
<field name="production_cost" widget="boolean_toggle"/>
<field name="component_id"/>
<field name="item_type"/>
<field name="description"/>
<field name="uom"/>
<field name="unit_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
<field name="singet_set_qty"/>
<field name="total_set"/>
<field name="quantity"/>
<field name="total_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
</tree>
</field>
<group style="float: right;
font-weight: bold;
font-size: 18px;">
<field name="total_material_cost"/>
</group>
</page> -->
<!-- <page string="Installation Kit">
<field name="line_ids_installation_kit">
<tree editable="bottom">
<field name="production_cost" widget="boolean_toggle"/>
<field name="component_id"/>
<field name="description"/>
<field name="item_type"/>
<field name="uom"/>
<field name="unit_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
<field name="singet_set_qty"/>
<field name="total_set"/>
<field name="quantity"/>
<field name="total_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
</tree>
</field>
<group style="float: right;
font-weight: bold;
font-size: 18px;">
<field name="total_installation_material_cost"/>
</group>
<page string="Summary" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user">
<h3 style="text-transform: uppercase;
text-decoration: underline;">Finished Goods</h3>
<field name="merged_fg_html" nolabel="1"/>
<h3 style="text-transform: uppercase;
text-decoration: underline;">Semi-Finished Goods</h3>
<field name="merged_sfg_html" nolabel="1"/>
<h3 style="text-transform: uppercase;
text-decoration: underline;">Materials</h3>
<field name="merged_material_html" nolabel="1"/>
<h3 style="text-transform: uppercase;
text-decoration: underline;">Installation Kit</h3>
<field name="merged_installation_kit_html" nolabel="1"/>
<h3 style="text-transform: uppercase;
text-decoration: underline;">Spare</h3>
<field name="merged_spare_html" nolabel="1"/>
<h3 style="text-transform: uppercase;
text-decoration: underline;">Miscellaneous</h3>
<field name="merged_miscellaneous_html" nolabel="1"/>
</page>
<page string="Miscellaneous">
<field name="line_ids_miscellaneous">
<tree editable="bottom">
<field name="name"/>
<field name="cost"/>
<field name="quantity"/>
<field name="total_price" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user,sos_inventory.sos_scg_group_user"/>
</tree>
</field>
<group style="float: right;
font-weight: bold;
font-size: 18px;">
<field name="total_miscellaneous_cost"/>
</group>
</page> -->
<page string="Installation &amp; Commissioning" invisible="proposal_id == False">
<group><field name="engineers_nos"/></group>
<group><field name="no_of_days"/></group>
<br></br>
<table class="table_custom" groups="sos_inventory.sos_management_user,sos_inventory.sos_finance_user">
<thead><td></td><td><b>No of Persons</b></td><td><b>Cost</b></td></thead>
<thead><td></td><td><b>No of Persons</b></td><td><b>Cost per Day</b></td></thead>
<tbody>
<tr><td><b>Man Month( 1 to 2 Yrs)</b></td><td><field name="man_month_1to2_yrs_persons"/></td><td><field name="man_month_1to2_yrs_cost"/></td></tr>
<tr><td><b>Man Month( 2 to 3 Yrs)</b></td><td><field name="man_month_2to3_yrs_persons"/></td><td><field name="man_month_2to3_yrs_cost"/></td></tr>
<tr><td><b>Man Month( 2 to 3 Yrs)</b></td><td><field name="man_month_1to2_yrs_persons"/></td><td><field name="man_month_1to2_yrs_cost"/></td></tr>
<tr><td><b>Man Month( 3 to 5 Yrs)</b></td><td><field name="man_month_2to3_yrs_persons"/></td><td><field name="man_month_2to3_yrs_cost"/></td></tr>
<tr><td><b>Man Month(Manager)</b></td><td><field name="man_month_manager_persons"/></td><td><field name="man_month_manager_cost"/></td></tr>
<tr><td><b>Total</b></td><td colspan="2"><field name="iandc_costing"/></td></tr>
</tbody>