Reference #9
This commit is contained in:
parent
faa8f2ff3b
commit
611cb5e418
|
|
@ -114,6 +114,7 @@
|
|||
'report/mme_history_card_report.xml',
|
||||
'report/sos_boq_labels.xml',
|
||||
'report/shelflife_report.xml',
|
||||
'report/sos_boq_report.xml',
|
||||
'data/send_indent_plan_email_template.xml',
|
||||
'data/selection_item.xml'
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -65,6 +65,19 @@ class sos_deliverables_boq(models.Model):
|
|||
verified_by = fields.Many2one('res.users', string='Prepared by')
|
||||
verified_by_image = fields.Image(related="verified_by.signature_image",string='Prepared by Sign',readonly=True)
|
||||
verified_on = fields.Datetime(string="Prepared On")
|
||||
ce_verified_by = fields.Many2one('res.users', string='CE Verified by')
|
||||
ce_verified_by_image = fields.Image(related="ce_verified_by.signature_image",string='CE Verified by Sign',readonly=True)
|
||||
ce_verified_on = fields.Datetime(string="CE Head Verified On")
|
||||
scg_head_verified_by = fields.Many2one('res.users', string='SCG Verified by')
|
||||
scg_head_verified_by_image = fields.Image(related="scg_head_verified_by.signature_image",string='SCG Verified by Sign',readonly=True)
|
||||
scg_head_verified_on = fields.Datetime(string="SCG Head Verified On")
|
||||
batter_or_cells=fields.Integer(string="Battery/Cells")
|
||||
def action_report_boq(self):
|
||||
try:
|
||||
action = self.env.ref("sos_inventory.action_sos_deliverables_boq").report_action(self)
|
||||
return action
|
||||
except ValueError as e:
|
||||
print(f"Failed to find report action: {e}")
|
||||
def action_print_labels_btn(self):
|
||||
try:
|
||||
action = self.env.ref("sos_inventory.action_report_labels").report_action(self)
|
||||
|
|
@ -127,11 +140,44 @@ class sos_deliverables_boq(models.Model):
|
|||
)
|
||||
def action_prepared_esign_btn(self):
|
||||
sequence_util = self.env['sos_common_scripts']
|
||||
# Email part
|
||||
body_html = f"""
|
||||
<p>Below <b>Deliverables/BOQ</b> is waiting for your Approval</p>
|
||||
"""
|
||||
sequence_util.send_group_email(self.env,'sos_deliverables_boq',self.id,"deenalaura.m@sosaley.in","Deliverables/BOQ Approval Request",body_html,'sos_inventory.sos_ce_head')
|
||||
# Email part ends
|
||||
return sequence_util.action_assign_signature(
|
||||
self,
|
||||
'prepared_by',
|
||||
'prepared_on'
|
||||
)
|
||||
def action_ce_verified_esign_btn(self):
|
||||
sequence_util = self.env['sos_common_scripts']
|
||||
# Email part
|
||||
body_html = f"""
|
||||
<p>Below <b>Deliverables/BOQ</b> is waiting for your Approval</p>
|
||||
"""
|
||||
sequence_util.send_group_email(self.env,'sos_deliverables_boq',self.id,"deenalaura.m@sosaley.in","Deliverables/BOQ Approval Request",body_html,'sos_inventory.sos_scg_group_manager')
|
||||
# Email part ends
|
||||
return sequence_util.action_assign_signature(
|
||||
self,
|
||||
'ce_verified_by',
|
||||
'ce_verified_on'
|
||||
)
|
||||
def action_scg_head_verified_esign_btn(self):
|
||||
sequence_util = self.env['sos_common_scripts']
|
||||
# Email part
|
||||
body_html = f"""
|
||||
<p>Below <b>Deliverables/BOQ</b> is waiting for your Approval</p>
|
||||
"""
|
||||
sequence_util.send_group_email(self.env,'sos_deliverables_boq',self.id,"deenalaura.m@sosaley.in","Deliverables/BOQ Approval Request",body_html,'sos_inventory.sos_qa_user')
|
||||
# Email part ends
|
||||
return sequence_util.action_assign_signature(
|
||||
self,
|
||||
'scg_head_verified_by',
|
||||
'scg_head_verified_on'
|
||||
)
|
||||
|
||||
def action_scg_esign_btn(self):
|
||||
sequence_util = self.env['sos_common_scripts']
|
||||
return sequence_util.action_assign_signature(
|
||||
|
|
@ -185,6 +231,7 @@ class sos_deliverables_boq_Line_Material(models.Model):
|
|||
|
||||
ref_id = fields.Many2one('sos_deliverables_boq', string="Materials", ondelete="cascade")
|
||||
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
|
||||
display_name = fields.Char(string="Display Name", related="component_id.name", store=True)
|
||||
uom = fields.Selection([('meters', 'Meters'),('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")
|
||||
|
|
@ -306,6 +353,7 @@ class sos_deliverables_Material_installationkit(models.Model):
|
|||
|
||||
ref_id = fields.Many2one('sos_deliverables_boq', string="Materials", ondelete="cascade")
|
||||
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
|
||||
display_name = fields.Char(string="Display Name", related="component_id.name", store=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")
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@ class SOS_Dock_Audit(models.Model):
|
|||
deliverables_boq_id = fields.Many2one('sos_deliverables_boq', string="Deliverables/BOQ Id")
|
||||
fg_name = fields.Selection(
|
||||
[
|
||||
('BHMS 1.2V', 'BHMS 1.2V'),
|
||||
('BHMS 2V', 'BHMS 2V'),
|
||||
('BHMS 12V', 'BHMS 12V'),
|
||||
('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'),
|
||||
('MC 250W', 'MC 250W'),
|
||||
('BMS-LV 40A', 'BMS-LV 40A'),
|
||||
('SBMS 55A', 'SBMS 55A'),
|
||||
('MC 250W', 'MC 250W'),
|
||||
('HeartTarang', 'HeartTarang')
|
||||
],
|
||||
string="Product Type",required=True)
|
||||
|
|
@ -384,6 +387,7 @@ class sos_dock_audit_Line_Material(models.Model):
|
|||
|
||||
ref_id = fields.Many2one('sos_dock_audit', string="Materials", ondelete="cascade")
|
||||
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
|
||||
display_name = fields.Char(string="Display Name", related="component_id.name", store=True)
|
||||
uom = fields.Selection([('meters', 'Meters'),('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")
|
||||
|
|
@ -689,6 +693,7 @@ class sos_dock_audit_Material_installationkit(models.Model):
|
|||
|
||||
ref_id = fields.Many2one('sos_dock_audit', string="Materials", ondelete="cascade")
|
||||
component_id = fields.Many2one('sos_material', string="Material Name", required=True)
|
||||
display_name = fields.Char(string="Display Name", related="component_id.name", store=True)
|
||||
uom = fields.Selection([('meters', 'Meters'),('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")
|
||||
|
|
|
|||
|
|
@ -51,21 +51,45 @@ class FIR_Only(models.Model):
|
|||
stores_received_on = fields.Date(string="Stores Received On")
|
||||
ncmr_ref = fields.Many2one('sos_ncmr',string="NCMR Reference (If any Rejected)")
|
||||
customer_name = fields.Many2one('sos_inventory_customers', string="Customer Name", required=True)
|
||||
|
||||
remarks = fields.Text(string="Remarks")
|
||||
test_log = fields.Binary("Test Log", required=False, attachment=True)
|
||||
test_log_filename = fields.Char("Test Log Filename")
|
||||
rejected_line_ids = fields.One2many('sos_fir_rejected_lines', 'ref_id', string="Finished Goods",copy=True, ondelete='cascade')
|
||||
serial_no_line_ids = fields.One2many('sos_fir_serial_no_lines', 'ref_id',copy=True)
|
||||
|
||||
sd_card_data = fields.Binary("SD Card Data", required=False, attachment=True)
|
||||
sd_card_data_filename = fields.Char("SD Card Data Filename")
|
||||
|
||||
cloud_data = fields.Binary("Cloud Data", required=False, attachment=True)
|
||||
cloud_data_filename = fields.Char("Cloud Data Filename")
|
||||
|
||||
firmware_data = fields.Binary("Firmware Data", required=False, attachment=True)
|
||||
firmware_data_filename = fields.Char("Firmware Data Filename")
|
||||
serial_no_parse = fields.Text(string="Serial no's to parse")
|
||||
def parse_serial_nos(self):
|
||||
self.ensure_one()
|
||||
if not self.serial_no_parse:
|
||||
return
|
||||
|
||||
# Split into clean serial numbers
|
||||
serial_numbers = [
|
||||
line.strip() for line in self.serial_no_parse.splitlines() if line.strip()
|
||||
]
|
||||
|
||||
SerialLine = self.env['sos_fir_serial_no_lines']
|
||||
|
||||
for serial in serial_numbers:
|
||||
# Check if already exists for this ref_id
|
||||
exists = SerialLine.search([
|
||||
('ref_id', '=', self.id),
|
||||
('serial_no', '=', serial)
|
||||
], limit=1)
|
||||
|
||||
if not exists:
|
||||
SerialLine.create({
|
||||
'ref_id': self.id,
|
||||
'serial_no': serial,
|
||||
'inspection_decision': 'PASS', # default
|
||||
})
|
||||
|
||||
|
||||
@api.onchange('batch_size')
|
||||
def _onchange_batch_size(self):
|
||||
if self._origin and self.batch_size is not False:
|
||||
|
|
|
|||
|
|
@ -18,18 +18,30 @@ class sos_inventory_customers(models.Model):
|
|||
new_name = (vals.get('customer_name') or '').lower()
|
||||
|
||||
if new_name and len(new_name) >= 5:
|
||||
existing_customers = self.search([])
|
||||
# Words/phrases to exclude
|
||||
blacklist = [
|
||||
'private limited', 'pvt ltd', 'pvt. ltd.', 'ltd', 'llp', 'inc', 'co', 'company', 'corporation'
|
||||
]
|
||||
|
||||
def clean_name(name):
|
||||
for word in blacklist:
|
||||
name = name.replace(word, '')
|
||||
return name.strip()
|
||||
|
||||
new_name_clean = clean_name(new_name)
|
||||
|
||||
existing_customers = self.search([])
|
||||
for customer in existing_customers:
|
||||
existing_name = (customer.customer_name or '').lower()
|
||||
existing_name_clean = clean_name(existing_name)
|
||||
|
||||
# Check all substrings of length 5 or more
|
||||
for i in range(len(new_name) - 4):
|
||||
substring = new_name[i:i+5]
|
||||
if substring in existing_name:
|
||||
# Check all substrings of length 7 or more
|
||||
for i in range(len(new_name_clean) - 6):
|
||||
substring = new_name_clean[i:i+7]
|
||||
if substring in existing_name_clean:
|
||||
raise UserError(
|
||||
f"A customer with a similar name already exists: '{customer.customer_name}' "
|
||||
f"(matched substring: '{substring}')"
|
||||
)
|
||||
|
||||
return super(sos_inventory_customers, self).create(vals)
|
||||
return super().create(vals)
|
||||
|
|
@ -217,6 +217,11 @@ class SOS_IR(models.Model):
|
|||
for item in self.line_ids_material:
|
||||
# Fetch the component related to the current item
|
||||
component = self.env['sos_material'].browse(item.component_id.id)
|
||||
if self.supplier_name and self.supplier_name.id not in component.suppliers.ids:
|
||||
component.write({
|
||||
'suppliers': [(4, self.supplier_name.id)]
|
||||
})
|
||||
|
||||
if component.shelf_life == "yes":
|
||||
shelflife_line_values = {
|
||||
'ir_ref_no':self.id,
|
||||
|
|
@ -301,6 +306,10 @@ class SOS_IR(models.Model):
|
|||
for item in self.line_ids_sfg:
|
||||
# PO update part
|
||||
sfg_component = self.env['sos_sfg'].browse(item.component_id.id)
|
||||
if self.service_provider_name and self.service_provider_name.id not in sfg_component.service_providers.ids:
|
||||
sfg_component.write({
|
||||
'service_providers': [(4, self.service_provider_name.id)]
|
||||
})
|
||||
if self.wo_planned_at == "outsource":
|
||||
if self.wo_no:
|
||||
if not self.orr_no:
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class SOS_SalesOrder(models.Model):
|
|||
],
|
||||
string="Product Name",required=True)
|
||||
line_ids = fields.One2many('sos_sales_order_line', 'ref_id',copy=True)
|
||||
customer_name = fields.Char(string="Customer Name")
|
||||
customer_name = fields.Many2one('sos_inventory_customers',string="Customer Name")
|
||||
lead_time = fields.Datetime(string="Lead Time")
|
||||
customer_po_no = fields.Char(string="PO No")
|
||||
customer_po_date = fields.Datetime(string="PO Date")
|
||||
|
|
@ -58,7 +58,7 @@ class SOS_SalesOrder(models.Model):
|
|||
'sales_id':self.id,
|
||||
'fg_name':self.fg_name,
|
||||
'quantity':self.qty,
|
||||
'customer_name':self.customer_name,
|
||||
'customer_name':self.customer_name.customer_name,
|
||||
'lead_time':self.lead_time,
|
||||
'customer_po_no':self.customer_po_no,
|
||||
'customer_po_date':self.customer_po_date
|
||||
|
|
@ -109,15 +109,15 @@ class SOS_SalesOrder(models.Model):
|
|||
sequence_util = self.env['sos_common_scripts']
|
||||
return sequence_util.generate_sequence('sos_sales_order','SALES', 'order_id')
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
customer_name = vals.get('customer_name')
|
||||
if customer_name:
|
||||
existing = self.env['sos_inventory_customers'].search([('customer_name', '=', customer_name)], limit=1)
|
||||
if not existing:
|
||||
self.env['sos_inventory_customers'].create({'customer_name': customer_name})
|
||||
# @api.model
|
||||
# def create(self, vals):
|
||||
# customer_name = vals.get('customer_name')
|
||||
# if customer_name:
|
||||
# existing = self.env['sos_inventory_customers'].search([('customer_name', '=', customer_name)], limit=1)
|
||||
# if not existing:
|
||||
# self.env['sos_inventory_customers'].create({'customer_name': customer_name})
|
||||
|
||||
return super(SOS_SalesOrder, self).create(vals)
|
||||
# return super(SOS_SalesOrder, self).create(vals)
|
||||
|
||||
class SOS_SalesOrder_Line(models.Model):
|
||||
_name = 'sos_sales_order_line'
|
||||
|
|
|
|||
|
|
@ -86,131 +86,192 @@
|
|||
}
|
||||
</style>
|
||||
|
||||
<div class="page">
|
||||
<div class="page">
|
||||
|
||||
|
||||
<t t-set="counter" t-value="0"/>
|
||||
<t t-foreach="range(o.master_quantity)" t-as="line_items">
|
||||
<t t-set="counter" t-value="counter + 1"/>
|
||||
<div class="label-set">
|
||||
<!-- Combine all tables into a single list -->
|
||||
<t t-set="all_tables" t-value="[]"/>
|
||||
<!-- Add FG tables -->
|
||||
<t t-set="fg_counter" t-value="0"/>
|
||||
<t t-foreach="o.line_ids_fg or []" t-as="fg_item">
|
||||
<t t-set="fg_counter" t-value="fg_counter + 1"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(1, fg_item, fg_counter)]"/>
|
||||
</t>
|
||||
<!-- Add SFG tables -->
|
||||
<t t-set="sfg_counter" t-value="0"/>
|
||||
<t t-foreach="o.line_ids_sfg or []" t-as="sfg_item">
|
||||
<t t-set="sfg_counter" t-value="sfg_counter + 1"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(2, sfg_item, sfg_counter)]"/>
|
||||
</t>
|
||||
<!-- Add Materials tables -->
|
||||
<t t-set="material_counter" t-value="0"/>
|
||||
<t t-foreach="o.line_ids_material or []" t-as="material_item">
|
||||
<t t-set="material_counter" t-value="material_counter + 1"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(3, material_item, material_counter)]"/>
|
||||
</t>
|
||||
<!-- Add Installation Kit tables -->
|
||||
<t t-set="installation_kit_counter" t-value="0"/>
|
||||
<t t-foreach="o.line_ids_installation_kit or []" t-as="installation_kit_item">
|
||||
<t t-set="installation_kit_counter" t-value="installation_kit_counter + 1"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(4, installation_kit_item, installation_kit_counter)]"/>
|
||||
</t>
|
||||
<!-- Add Miscelleneous tables -->
|
||||
<t t-set="miscellaneous_counter" t-value="0"/>
|
||||
<t t-foreach="o.line_ids_miscellaneous or []" t-as="miscellaneous_item">
|
||||
<t t-set="miscellaneous_counter" t-value="miscellaneous_counter + 1"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(5, miscellaneous_item, miscellaneous_counter)]"/>
|
||||
</t>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Process all tables in pairs -->
|
||||
<t t-foreach="range(0, len(all_tables), 2)" t-as="pair_index">
|
||||
<div class="row">
|
||||
<!-- First table in the pair -->
|
||||
<div class="col-6">
|
||||
<t t-set="table_info" t-value="all_tables[pair_index]"/>
|
||||
<t t-set="category" t-value="table_info[0]"/>
|
||||
<t t-set="item" t-value="table_info[1]"/>
|
||||
<t t-set="index" t-value="table_info[2]"/>
|
||||
|
||||
<div class="table-container">
|
||||
<table class="label-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="column">Set No</td>
|
||||
<td>#<t t-esc="counter"/>/<t t-esc="o.master_quantity"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Battery</td>
|
||||
<td><t t-esc="o.batter_or_cells"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">No</td>
|
||||
<td><t t-esc="category"/>.<t t-esc="index"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Name</td>
|
||||
<td>
|
||||
<t t-if="'component_id' in item">
|
||||
<t t-esc="item.component_id.name or item.component_id.part_no or item.name or 'N/A'"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="item.name or 'N/A'"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">UOM</td>
|
||||
<td>
|
||||
<t t-if="'uom' in item">
|
||||
<t t-esc="item.uom or 'N/A'"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="'N/A'"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Qty</td>
|
||||
<td>
|
||||
<t t-if="'singet_set_qty' in item">
|
||||
<t t-esc="item.singet_set_qty or 'N/A'"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="item.quantity or 'N/A'"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="column">S.No</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<t t-set="counter" t-value="0"/>
|
||||
<t t-foreach="range(o.master_quantity)" t-as="line_items">
|
||||
<t t-set="counter" t-value="counter + 1"/>
|
||||
<div class="label-set">
|
||||
<!-- Combine all tables into a single list -->
|
||||
<t t-set="all_tables" t-value="[]"/>
|
||||
<!-- Add FG tables -->
|
||||
<t t-foreach="o.line_ids_fg or []" t-as="fg_item">
|
||||
<t t-set="fg_index_safe" t-value="fg_index if fg_index is not None else 0"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(1, fg_item, fg_index_safe + 1)]"/>
|
||||
</t>
|
||||
<!-- Add SFG tables -->
|
||||
<t t-foreach="o.line_ids_sfg or []" t-as="sfg_item">
|
||||
<t t-set="sfg_index_safe" t-value="sfg_index if sfg_index is not None else 0"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(2, sfg_item, sfg_index_safe + 1)]"/>
|
||||
</t>
|
||||
<!-- Add Materials tables -->
|
||||
<t t-foreach="o.line_ids_material or []" t-as="material_item">
|
||||
<t t-set="material_index_safe" t-value="material_index if material_index is not None else 0"/>
|
||||
<t t-set="all_tables" t-value="all_tables + [(3, material_item, material_index_safe + 1)]"/>
|
||||
</t>
|
||||
|
||||
|
||||
|
||||
<!-- Process all tables in pairs -->
|
||||
<t t-foreach="range(0, len(all_tables), 2)" t-as="pair_index">
|
||||
<div class="row">
|
||||
<!-- First table in the pair -->
|
||||
<div class="col-6">
|
||||
<t t-set="table_info" t-value="all_tables[pair_index]"/>
|
||||
<t t-set="category" t-value="table_info[0]"/>
|
||||
<t t-set="item" t-value="table_info[1]"/>
|
||||
<t t-set="index" t-value="table_info[2]"/>
|
||||
<div class="table-container">
|
||||
<table class="label-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="column">Set No</td>
|
||||
<td>#<t t-esc="counter"/>/<t t-esc="o.master_quantity"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Battery</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">No</td>
|
||||
<td><t t-esc="category"/>.<t t-esc="index"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Name</td>
|
||||
<td><t t-esc="item.component_id.name or 'N/A'"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">UOM</td>
|
||||
<td><t t-esc="item.uom or 'N/A'"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Qty</td>
|
||||
<td><t t-esc="item.singet_set_qty or 'N/A'"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">S.No</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Second table in the pair (if exists) -->
|
||||
<div class="col-6">
|
||||
<t t-if="pair_index + 1 < len(all_tables)">
|
||||
<t t-set="table_info" t-value="all_tables[pair_index + 1]"/>
|
||||
<t t-set="category" t-value="table_info[0]"/>
|
||||
<t t-set="item" t-value="table_info[1]"/>
|
||||
<t t-set="index" t-value="table_info[2]"/>
|
||||
<div class="table-container">
|
||||
<table class="label-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="column">Set No</td>
|
||||
<td>#<t t-esc="counter"/>/<t t-esc="o.master_quantity"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Battery</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">No</td>
|
||||
<td><t t-esc="category"/>.<t t-esc="index"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Name</td>
|
||||
<td><t t-esc="item.component_id.name or 'N/A'"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">UOM</td>
|
||||
<td><t t-esc="item.uom or 'N/A'"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Qty</td>
|
||||
<td><t t-esc="item.singet_set_qty or 'N/A'"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">S.No</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="empty-col"></div>
|
||||
</t>
|
||||
</div>
|
||||
</div> <!-- Close row -->
|
||||
</t>
|
||||
<!-- Second table in the pair (if exists) -->
|
||||
<div class="col-6">
|
||||
<t t-if="pair_index + 1 < len(all_tables)">
|
||||
<t t-set="table_info" t-value="all_tables[pair_index + 1]"/>
|
||||
<t t-set="category" t-value="table_info[0]"/>
|
||||
<t t-set="item" t-value="table_info[1]"/>
|
||||
<t t-set="index" t-value="table_info[2]"/>
|
||||
<div class="table-container">
|
||||
<table class="label-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="column">Set No</td>
|
||||
<td>#<t t-esc="counter"/>/<t t-esc="o.master_quantity"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Battery</td>
|
||||
<td><t t-esc="o.batter_or_cells"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">No</td>
|
||||
<td><t t-esc="category"/>.<t t-esc="index"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Name</td>
|
||||
<td>
|
||||
<t t-if="'component_id' in item">
|
||||
<t t-esc="item.component_id.name or item.component_id.part_no or item.name or 'N/A'"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="item.name or 'N/A'"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">UOM</td>
|
||||
<td>
|
||||
<t t-if="'uom' in item">
|
||||
<t t-esc="item.uom or 'N/A'"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="'N/A'"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Qty</td>
|
||||
<td>
|
||||
<t t-if="'singet_set_qty' in item">
|
||||
<t t-esc="item.singet_set_qty or 'N/A'"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="item.quantity or 'N/A'"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">S.No</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="empty-col"></div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div> <!-- Close row -->
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<template id="report_boq">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<h2>Deliverables/BOQ Report</h2>
|
||||
<br></br>
|
||||
|
||||
<table class="table">
|
||||
|
||||
<tr><td class="column">Customer Name</td><td><t t-esc="o.customer_name"/></td><td class="column">Location</td><td><t t-esc="o.customer_location"/></td></tr>
|
||||
|
||||
<tr><td class="column">Product Name</td><td><t t-esc="o.fg_name"/></td><td class="column">Quantity</td><td><t t-esc="o.quantity"/></td></tr>
|
||||
</table>
|
||||
<br></br>
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr><td colspan="6" class="column" style="background-color:#ccc">Finished Goods</td></tr>
|
||||
<tr class="column">
|
||||
<td>S.No</td>
|
||||
<td>Name</td>
|
||||
<td>UOM</td>
|
||||
<td>Single set Qty</td>
|
||||
<td>Total Set</td>
|
||||
<td>Qty</td>
|
||||
</tr>
|
||||
<t t-foreach="enumerate(o.line_ids_fg)" t-as="it">
|
||||
<tr>
|
||||
<td><t t-esc="'1.%s' % (it[0] + 1)"/></td>
|
||||
<td><t t-esc="it[1].component_id.name"/></td>
|
||||
<td><t t-esc="it[1].uom"/></td>
|
||||
<td><t t-esc="it[1].singet_set_qty"/></td>
|
||||
<td><t t-esc="it[1].total_set"/></td>
|
||||
<td><t t-esc="it[1].quantity"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr><td colspan="6" class="column" style="background-color:#ccc">Semi-Finished Goods</td></tr>
|
||||
<t t-foreach="enumerate(o.line_ids_sfg)" t-as="it">
|
||||
<tr>
|
||||
<td><t t-esc="'2.%s' % (it[0] + 1)"/></td>
|
||||
<td><t t-esc="it[1].component_id.name"/></td>
|
||||
<td><t t-esc="it[1].uom"/></td>
|
||||
<td><t t-esc="it[1].singet_set_qty"/></td>
|
||||
<td><t t-esc="it[1].total_set"/></td>
|
||||
<td><t t-esc="it[1].quantity"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr><td colspan="6" class="column" style="background-color:#ccc">Materials</td></tr>
|
||||
<t t-foreach="enumerate(o.line_ids_material)" t-as="it">
|
||||
<tr>
|
||||
<td><t t-esc="'3.%s' % (it[0] + 1)"/></td>
|
||||
<td><t t-esc="it[1].component_id.part_no"/></td>
|
||||
<td><t t-esc="it[1].uom"/></td>
|
||||
<td><t t-esc="it[1].singet_set_qty"/></td>
|
||||
<td><t t-esc="it[1].total_set"/></td>
|
||||
<td><t t-esc="it[1].quantity"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr><td colspan="6" class="column" style="background-color:#ccc">Installation Kit</td></tr>
|
||||
<t t-foreach="enumerate(o.line_ids_installation_kit)" t-as="it">
|
||||
<tr>
|
||||
<td><t t-esc="'4.%s' % (it[0] + 1)"/></td>
|
||||
<td><t t-esc="it[1].component_id.part_no"/></td>
|
||||
<td><t t-esc="it[1].uom"/></td>
|
||||
<td><t t-esc="it[1].singet_set_qty"/></td>
|
||||
<td><t t-esc="it[1].total_set"/></td>
|
||||
<td><t t-esc="it[1].quantity"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr><td colspan="6" class="column" style="background-color:#ccc">Miscellaneous</td></tr>
|
||||
<tr class="column">
|
||||
<td>S.No</td>
|
||||
<td>Name</td>
|
||||
<td colspan="4">Qty</td>
|
||||
</tr>
|
||||
<t t-foreach="enumerate(o.line_ids_miscellaneous)" t-as="it">
|
||||
|
||||
<tr>
|
||||
<td><t t-esc="'5.%s' % (it[0] + 1)"/></td>
|
||||
<td><t t-esc="it[1].name"/></td>
|
||||
<td colspan="4"><t t-esc="it[1].quantity"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<record id="action_sos_deliverables_boq" model="ir.actions.report">
|
||||
<field name="name">BOQ Report</field>
|
||||
<field name="model">sos_deliverables_boq</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">sos_inventory.report_boq</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -45,10 +45,7 @@
|
|||
<td class="column">Sampling Size</td><td><t t-esc="o.approved_qty"/></td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Serial No</td><td colspan="3"><t t-esc="o.serial_no"/></td>
|
||||
|
||||
</tr>
|
||||
|
||||
</t>
|
||||
<t t-else="">
|
||||
<tr>
|
||||
|
|
@ -56,10 +53,7 @@
|
|||
<td class="column">Sampling Size</td><td><t t-esc="o.sampling_size"/></td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="column">Serial No</td><td colspan="3"><t t-esc="o.serial_no"/></td>
|
||||
|
||||
</tr>
|
||||
|
||||
|
||||
</t>
|
||||
<tr>
|
||||
|
|
@ -74,7 +68,21 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br></br>
|
||||
<table class="table table-bordered" style="width:100%;">
|
||||
<tbody>
|
||||
<tr style="background-color:#ccc"><td colspan="7" class="column"><h5>Serial No's</h5></td></tr>
|
||||
|
||||
|
||||
<t t-set="lines" t-value="o.serial_no_line_ids"/>
|
||||
<t t-foreach="range(0, len(lines), 2)" t-as="i">
|
||||
<tr>
|
||||
<td><t t-esc="lines[i].serial_no or ''"/></td>
|
||||
<td><t t-esc="(lines[i+1].serial_no if i+1 < len(lines) else '')"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- <table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr style="background-color:#ccc"><td colspan="7" class="column"><h5>Summary Report</h5></td></tr>
|
||||
|
|
|
|||
|
|
@ -43,10 +43,12 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Model Form">
|
||||
<header>
|
||||
<button class="btn btn-primary" type="object"
|
||||
<button class="btn btn-primary" type="object"
|
||||
name="action_print_labels_btn"><i class="fa fa-print"></i> Print Labels</button>
|
||||
|
||||
|
||||
|
||||
<button name="action_report_boq" string="Report"
|
||||
type="object" class="btn-primary"/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
||||
|
|
@ -71,7 +73,7 @@
|
|||
<field name="show_ev_fields" invisible="1"/>
|
||||
<field name="master_quantity" invisible="show_ev_fields == False"/>
|
||||
<field name="slave_quantity" invisible="show_ev_fields == False"/>
|
||||
|
||||
<field name="batter_or_cells"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
|
|
@ -108,6 +110,7 @@
|
|||
<field name="line_ids_material">
|
||||
<tree editable="bottom">
|
||||
<field name="component_id"/>
|
||||
<field name="display_name"/>
|
||||
<field name="add_production_cost" widget="boolean_toggle"/>
|
||||
<field name="is_spare" widget="boolean_toggle"/>
|
||||
|
||||
|
|
@ -122,6 +125,7 @@
|
|||
<field name="line_ids_installation_kit">
|
||||
<tree editable="bottom">
|
||||
<field name="component_id"/>
|
||||
<field name="display_name"/>
|
||||
<field name="uom"/>
|
||||
<field name="singet_set_qty"/>
|
||||
<field name="total_set"/>
|
||||
|
|
@ -285,13 +289,55 @@
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-4"></div>
|
||||
<div class="col-4">
|
||||
<table class="table_custom" style="box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;background-color: #fff;border: solid 4px #9689c1;">
|
||||
|
||||
<tr style="border-bottom: solid 1px #ccc;">
|
||||
<td style="padding: 8px;" class="column"><b>CE Head Verified By</b>
|
||||
<br></br><br></br>
|
||||
<button string="Approve" invisible="ce_verified_by_image" class="btn-primary custom_btn" type="object" name="action_ce_verified_esign_btn"></button>
|
||||
</td>
|
||||
<td><field name="ce_verified_by_image" widget="image"/></td>
|
||||
</tr>
|
||||
<tr invisible="ce_verified_by_image == False">
|
||||
<td style="padding: 8px;" class="column"><b>Verified On</b></td>
|
||||
<td><field name="ce_verified_on" readonly="1"/></td>
|
||||
</tr>
|
||||
<tr invisible="ce_verified_by_image == False">
|
||||
<td style="padding: 8px;" class="column"><b>Verified By</b></td>
|
||||
<td><field name="ce_verified_by" readonly="1"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<table class="table_custom" style="box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;background-color: #fff;border: solid 4px #9689c1;">
|
||||
|
||||
<tr style="border-bottom: solid 1px #ccc;">
|
||||
<td style="padding: 8px;" class="column"><b>SCG Head Verified By</b>
|
||||
<br></br><br></br>
|
||||
<button string="Approve" invisible="scg_head_verified_by_image" class="btn-primary custom_btn" type="object" name="action_scg_head_verified_esign_btn"></button>
|
||||
</td>
|
||||
<td><field name="scg_head_verified_by_image" widget="image"/></td>
|
||||
</tr>
|
||||
<tr invisible="scg_head_verified_by_image == False">
|
||||
<td style="padding: 8px;" class="column"><b>Verified On</b></td>
|
||||
<td><field name="scg_head_verified_on" readonly="1"/></td>
|
||||
</tr>
|
||||
<tr invisible="scg_head_verified_by_image == False">
|
||||
<td style="padding: 8px;" class="column"><b>Verified By</b></td>
|
||||
<td><field name="scg_head_verified_by" readonly="1"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3"></div>
|
||||
<div class="col-6">
|
||||
<!-- Second Table -->
|
||||
<table class="table_custom" style="box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;background-color: #fff;border: solid 4px #9689c1;">
|
||||
|
||||
<tr style="border-bottom: solid 1px #ccc;">
|
||||
<td style="padding: 8px;" class="column"><b>Verified By</b>
|
||||
<td style="padding: 8px;" class="column"><b>QA Verified By</b>
|
||||
<br></br><br></br>
|
||||
<button string="Approve" invisible="verified_by_image" class="btn-primary custom_btn" type="object" name="action_verified_esign_btn"></button>
|
||||
</td>
|
||||
|
|
@ -307,6 +353,8 @@
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-3"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</sheet>
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@
|
|||
<field name="line_ids_material" >
|
||||
<tree editable="bottom">
|
||||
<field name="component_id"/>
|
||||
<field name="display_name"/>
|
||||
<field name="is_spare" widget="boolean_toggle"/>
|
||||
|
||||
<field name="uom"/>
|
||||
|
|
@ -122,6 +123,7 @@
|
|||
<field name="line_ids_installation_kit" >
|
||||
<tree editable="bottom">
|
||||
<field name="component_id"/>
|
||||
<field name="display_name"/>
|
||||
<field name="uom"/>
|
||||
<field name="singet_set_qty"/>
|
||||
<field name="total_set"/>
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@
|
|||
<field name="fg_name" widget="many2many_tags"/>
|
||||
<field name="product_type"/>
|
||||
|
||||
<field name="customer_name"/>
|
||||
|
||||
</group>
|
||||
<group>
|
||||
<field name="customer_name"/>
|
||||
<field name="batch_No"/>
|
||||
<field name="serial_no"/>
|
||||
<!-- <field name="serial_no"/> -->
|
||||
<field name="mfg_date"/>
|
||||
<field name="sampling_size"/>
|
||||
<field name="remarks"/>
|
||||
|
|
@ -61,6 +62,13 @@
|
|||
</field>
|
||||
</page>
|
||||
<page string="Serial No's">
|
||||
<table class="table_custom">
|
||||
<thead><tr><td colspan="3"><b>Parse Serial No's</b></td></tr></thead>
|
||||
<tr><td colspan="3"><field name="serial_no_parse"/></td><td><button type="object" name="parse_serial_nos" class="btn btn-primary" string="Parse"></button></td></tr>
|
||||
</table>
|
||||
<br></br>
|
||||
|
||||
|
||||
<field name="serial_no_line_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="serial_no"/>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Accessories">
|
||||
<page string="Product / Accessories">
|
||||
|
||||
<div class="new_header">Finished Goods</div>
|
||||
<field name="line_ids_fg">
|
||||
|
|
|
|||
Loading…
Reference in New Issue