# -*- coding: utf-8 -*- from odoo import models, fields, api import time,logging from odoo.exceptions import UserError from collections import Counter _logger = logging.getLogger(__name__) class SOS_Dock_Audit(models.Model): _name = 'sos_dock_audit' _description = 'Dock Audit' _rec_name = 'dock_audit_no' _order = 'id desc' dock_audit_no = fields.Char(string="Dock Audit No", readonly= True, required= True, default=lambda self: self._generate_id()) 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 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="Product Type",required=True) quantity = fields.Integer(string="Quantity") invoice_no = fields.Char(string="Invoice No") customer_name = fields.Char(string="Customer Name") lead_time = fields.Datetime(string="Lead Time") customer_po_no = fields.Char(string="PO No") customer_location = fields.Char(string="Customer Location") customer_po_date = fields.Datetime(string="PO Date") line_ids_miscellaneous = fields.One2many('sos_dock_audit_miscellaneous_items','ref_id', string="Miscellaneous") line_ids_installation_kit = fields.One2many('sos_dock_audit_line_material_installation', 'ref_id', string="Installation Kit") line_ids_fg = fields.One2many('sos_dock_audit_line_fg', 'ref_id', string="Finished Goods") line_ids_sfg = fields.One2many('sos_dock_audit_line_sfg', 'ref_id', string="Semi-Finished Goods") line_ids_material = fields.One2many('sos_dock_audit_line_material', 'ref_id', string="Finished Goods") line_ids_transaction = fields.One2many('sos_dock_audit_transaction', 'ref_id', string="Finished Goods") payment_status= fields.Selection([('credit_after_delivery', 'Payment After Delivery'),('received', 'Received'),('demo', 'Demo'),('warranty', 'Warranty'),('validation', 'Validation')],string="Payment Status") billing_address = fields.Text(string="Billing Address") shipping_address = fields.Text(string="Shipping Address") purpose = fields.Char(string="Purpose") gst_no = fields.Char(string="GST No") design_verification_ids = fields.One2many('sos_design_verification', 'ref_id',copy=True, ondelete='cascade') user_manual = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="User Manual") installation_video = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Installation Video") wiring_diagram = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Wiring Diagram") warranty_card = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Warranty Card") test_report = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Test Report") sdcard_data = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="SD card Data") cloud_data = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Cloud Data") sim_provided_status = fields.Selection([('yes', 'Yes'),('no', 'No')], default='no',string="SIM Card Provided") sim_number = fields.Char(string="SIM Number") correct_product = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Product Correct?") packaging_correct = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Packaging Correct?") packing_received = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Packaging List Received?") labeling_correct = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Is the Labeling Correct?") internal_rework = fields.Selection([('yes', 'Yes'),('no', 'No'),('na', 'NA')], default='yes',string="Internal Rework (If Issued)") top_management_name = fields.Many2one('res.users', string='Top Management Approver') top_management_approval_image = fields.Image(related="top_management_name.signature_image",string='Top Management Approval',readonly=True) top_management_approved_on = fields.Datetime(string="Approved On") audited_by_name = fields.Many2one('res.users', string='Audited by') audited_by_image = fields.Image(related="audited_by_name.signature_image",string='Audited by Sign',readonly=True) audited_on = fields.Datetime(string="Audited On") ce_name = fields.Many2one('res.users', string='CE') ce_image = fields.Image(related="ce_name.signature_image",string='CE Sign',readonly=True) ce_approved_on = fields.Datetime(string="Approved On") qa_by_name = fields.Many2one('res.users', string='QA Sign') qa_by_image = fields.Image(related="qa_by_name.signature_image",string='QA by Sign',readonly=True) accounts_approved_on = fields.Datetime(string="Accounts Approved On") accounts_approved_name = fields.Many2one('res.users', string='Accounts Sign') accounts_approved_by_image = fields.Image(related="accounts_approved_name.signature_image",string='Accounts Sign',readonly=True) qa_tested_on = fields.Datetime(string="Tested On") min_no = fields.Many2one('sos_min',string="Issue Note Ref No") phase_version = fields.Integer(string="Phase",readonly=True) report_phase = fields.Char(string="Report Phase") status = fields.Selection([ ('open', 'Open'),('close', 'Closed')], default='open' , string="Status") @api.model def create(self, vals): customer_po_no = vals.get('customer_po_no') deliverables_boq_id = vals.get('deliverables_boq_id') dock_audit_no = vals.get('dock_audit_no') sequence_util = self.env['sos_common_scripts'] #print(f" {customer_po_no } : customer_po_no : {deliverables_boq_id}") if customer_po_no and deliverables_boq_id: existing = self.search([ ('customer_po_no', '=', customer_po_no), ('deliverables_boq_id', '=', deliverables_boq_id) ], limit=1) if existing: db_dock_audit_no = existing.dock_audit_no db_deliverables_boq_id = existing.deliverables_boq_id db_customer_po_no = existing.customer_po_no if db_dock_audit_no: url =f"https://slink.sosaley.in//web#id={existing.id}&cids=1&menu_id=175&action=233&model=sos_dock_audit&view_type=form" raise UserError( f"Dock audit [{db_dock_audit_no}] already exists for this BOQ and PO number.\n\n" f"{url}" ) return existing else: return super().create(vals) else: return super().create(vals) @api.onchange('min_no') def _onchange_min_no(self): for line in self.line_ids_fg: if self.min_no and self.min_no.line_ids_fg: matching_lines = self.min_no.line_ids_fg.filtered(lambda l: l.component_id == line.component_id) # Compare based on fields line.matched_line = True if matching_lines else False # 10 (green), 1 (red) else: line.matched_line = False # Default to red def _generate_id(self): sequence_util = self.env['sos_common_scripts'] return sequence_util.generate_sequence('sos_dock_audit','DA','dock_audit_no') def action_top_esign_btn(self): sequence_util = self.env['sos_common_scripts'] sequence_util.action_assign_signature( self, 'top_management_name', 'top_management_approved_on', 'sos_inventory.sos_management_user' ) for record in self: record.write({ 'phase_version': record.phase_version+1, 'status': 'close', }) def action_acc_esign_btn(self): sequence_util = self.env['sos_common_scripts'] sequence_util.action_assign_signature( self, 'accounts_approved_name', 'accounts_approved_on', 'sos_inventory.sos_finance_user' ) # Email part body_html = f"""
Below Dock Audit is waiting for your Approval
""" sequence_util.send_direct_email(self.env,"sos_dock_audit",self.id,"ramachandran.r@sosaley.in","Dock Audit Approval",body_html) # Email part ends def action_auditor_esign_btn(self): sequence_util = self.env['sos_common_scripts'] sequence_util.action_assign_signature( self, 'audited_by_name', 'audited_on' ) # Email part body_html = f"""Below Dock Audit is waiting for your Approval
""" sequence_util.send_group_email(self.env,'sos_dock_audit',self.id,"deenalaura.m@sosaley.in","Dock Audit Approval",body_html,'sos_inventory.sos_qa_user') # Email part ends def action_qa_esign_btn(self): sequence_util = self.env['sos_common_scripts'] sequence_util.action_assign_signature( self, 'qa_by_name', 'qa_tested_on' ) # Email part body_html = f"""Below Dock Audit is waiting for your Approval
""" sequence_util.send_group_email(self.env,'sos_dock_audit',self.id,"deenalaura.m@sosaley.in","Dock Audit Approval",body_html,'sos_inventory.sos_ce_user') # Email part ends def action_ce_esign_btn(self): sequence_util = self.env['sos_common_scripts'] sequence_util.action_assign_signature( self, 'ce_name', 'ce_approved_on' ) # Email part body_html = f"""Below Dock Audit is waiting for your Approval
""" sequence_util.send_direct_email(self.env,"sos_dock_audit",self.id,"anitha.a@sosaley.in","Dock Audit Approval",body_html) # Email part ends @api.onchange('deliverables_boq_id') def _onchange_deliverables_boq_id(self): if self.deliverables_boq_id: self.user_manual = self.deliverables_boq_id.sales_id.user_manual self.installation_video = self.deliverables_boq_id.sales_id.installation_video self.wiring_diagram = self.deliverables_boq_id.sales_id.wiring_diagram self.warranty_card = self.deliverables_boq_id.sales_id.warranty_card self.test_report = self.deliverables_boq_id.sales_id.test_report self.sdcard_data = self.deliverables_boq_id.sales_id.sdcard_data self.cloud_data = self.deliverables_boq_id.sales_id.cloud_data self.billing_address = self.deliverables_boq_id.sales_id.billing_address self.shipping_address = self.deliverables_boq_id.sales_id.shipping_address self.gst_no = self.deliverables_boq_id.sales_id.gst_no self.payment_status = self.deliverables_boq_id.sales_id.payment_status self.customer_name = self.deliverables_boq_id.sales_id.customer_name self.fg_name = self.deliverables_boq_id.sales_id.fg_name self.quantity = self.deliverables_boq_id.sales_id.qty self.lead_time = self.deliverables_boq_id.sales_id.lead_time self.customer_po_no = self.deliverables_boq_id.sales_id.customer_po_no self.customer_po_date = self.deliverables_boq_id.sales_id.customer_po_date self.line_ids_installation_kit = [(5, 0, 0)] # Clear existing records self.line_ids_installation_kit = [ (0, 0, { 'component_id': line.component_id, # Replace 'field1' with the actual field names 'uom': line.uom, 'material_code': line.material_code, 'material_name': line.material_name, 'singet_set_qty': line.singet_set_qty, 'total_set': line.total_set, 'quantity': line.quantity, 'unit_price': line.unit_price, 'total_price': line.total_price, 'phase': self.phase_version+1 # Add other fields to copy here }) for line in self.deliverables_boq_id.line_ids_installation_kit ] self.line_ids_fg = [(5, 0, 0)] # Clear existing records self.line_ids_fg = [ (0, 0, { 'component_id': line.component_id, # Replace 'field1' with the actual field names 'uom': line.uom, 'fg_code': line.fg_code, 'fg_name': line.fg_name, 'singet_set_qty': line.singet_set_qty, 'total_set': line.total_set, 'quantity': line.quantity, 'unit_price': line.unit_price, 'total_price': line.total_price, 'is_spare':line.is_spare, 'phase': self.phase_version+1 # Add other fields to copy here }) for line in self.deliverables_boq_id.line_ids_fg ] self.line_ids_sfg = [(5, 0, 0)] # Clear existing records self.line_ids_sfg = [ (0, 0, { 'component_id': line.component_id, # Replace 'field1' with the actual field names 'uom': line.uom, 'sfg_code': line.sfg_code, 'sfg_name': line.sfg_name, 'singet_set_qty': line.singet_set_qty, 'total_set': line.total_set, 'quantity': line.quantity, 'unit_price': line.unit_price, 'total_price': line.total_price, 'is_spare':line.is_spare, 'phase': self.phase_version+1 # Add other fields to copy here }) for line in self.deliverables_boq_id.line_ids_sfg ] self.line_ids_material = [(5, 0, 0)] # Clear existing records self.line_ids_material = [ (0, 0, { 'component_id': line.component_id, # Replace 'field1' with the actual field names 'uom': line.uom, 'material_code': line.material_code, 'material_name': line.material_name, 'singet_set_qty': line.singet_set_qty, 'total_set': line.total_set, 'quantity': line.quantity, 'unit_price': line.unit_price, 'total_price': line.total_price, 'is_spare':line.is_spare, 'phase': self.phase_version+1 # Add other fields to copy here }) for line in self.deliverables_boq_id.line_ids_material ] self.line_ids_miscellaneous = [(5, 0, 0)] # Clear existing records self.line_ids_miscellaneous = [ (0, 0, { 'name': line.name, # Replace 'field1' with the actual field names 'cost': line.cost, 'quantity': line.quantity, 'total_price': line.total_price, 'phase': self.phase_version+1 # Add other fields to copy here }) for line in self.deliverables_boq_id.line_ids_miscellaneous ] def action_clear_approval(self): for record in self: related_task_model = self.env['sos_dock_audit_transaction'] related_task_model.create({ 'ref_id': record.id, 'dock_audit_no': record.dock_audit_no, 'phase_version': record.phase_version, 'audited_by_image': record.audited_by_image, 'audited_on': record.audited_on, 'audited_by_name': record.audited_by_name.id if record.audited_by_name else False, 'qa_by_image': record.qa_by_image, 'qa_tested_on': record.qa_tested_on, 'qa_by_name': record.qa_by_name.id if record.qa_by_name else False, 'ce_image': record.ce_image, 'ce_approved_on': record.ce_approved_on, 'ce_name': record.ce_name.id if record.qa_by_name else False, 'accounts_approved_by_image': record.accounts_approved_by_image, 'accounts_approved_on': record.accounts_approved_on, 'accounts_approved_name': record.accounts_approved_name.id if record.qa_by_name else False, 'top_management_approval_image': record.top_management_approval_image, 'top_management_approved_on': record.top_management_approved_on, 'top_management_name': record.top_management_name.id if record.qa_by_name else False, }) record.write({ #'phase_version': record.phase_version+1, 'audited_by_image': False, 'audited_on': False, 'audited_by_name': False, 'qa_by_image': False, 'qa_tested_on': False, 'qa_by_name': False, 'ce_image': False, 'ce_approved_on': False, 'ce_name': False, 'accounts_approved_by_image': False, 'accounts_approved_on': False, 'accounts_approved_name': False, 'top_management_approval_image': False, 'top_management_approved_on': False, 'top_management_name': False, 'status': 'open' }) #task_id = 5 # Just an example, this ID would typically come from somewhere (a field or context) def action_report_dock_audit_btn(self): try: # filtered_recordfg = self.env['sos_dock_audit_line_fg'].search([ # ('phase', 'ilike', '1'), # ('ref_id', 'in', self.ids) # Restrict to current records, if needed # ]) #for line in filtered_recordfg: # print(f" Filtered_recordfg : {line.component_id.display_name} ") # filtered_recordsfg = self.env['sos_dock_audit_line_sfg'].search([ # ('phase', 'ilike', '1,2'), # ('ref_id', 'in', self.ids) # Restrict to current records, if needed # ]) action = self.env.ref("sos_inventory.action_report_dock_audit").report_action(self) return action except ValueError as e: print(f"Failed to find report action: {e}") def action_open_audit_report_wizard(self): self.ensure_one() if self.phase_version <= 0: raise UserError("Phase version is zero. Please complete one phase before going for report.") #print(f" {self.phase_version} : LLLL : {self.dock_audit_no}") return { 'name': 'Dock Audit Report', 'type': 'ir.actions.act_window', 'res_model': 'dock.audit.report', 'view_mode': 'form', 'target': 'new', 'context': { 'default_dock_audit_id': self.dock_audit_no, #'default_phase': ','.join(map(str, int_array)), 'phase': self.phase_version, } } class sos_dock_audit_Line_Material(models.Model): _name = 'sos_dock_audit_line_material' _description = 'Material Lines' 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") 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") total_price = fields.Monetary(string="Total",compute="_compute_total_price") is_spare = fields.Boolean(string="Spare") phase = fields.Char(string="Phase",readonly=True) total_phase_count = fields.Char(string="Aggregate Phase") @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: record.total_price = record.unit_price * record.quantity @api.model def create(self, vals): #print(f" First line in create ") #component_id = vals.get('component_id') ref_id = vals.get('ref_id') #sequence_util = self.env['sos_common_scripts'] # if component_id and ref_id: # # Search for an existing line with the same component_id and ref_id # existing = self.search([ # ('component_id', '=', component_id), # ('ref_id', '=', ref_id) # ], limit=1) # if existing: # # Merge logic: add quantities # existing.singet_set_qty += vals.get('singet_set_qty', 1) # #existing.total_set += vals.get('total_set', 1) # previousval = 0 # if vals.get('ref_id'): # parent = self.env['sos_dock_audit'].browse(vals['ref_id']) # existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1) # previousval = sequence_util.extract_value(existing.total_phase_count) # if existing.total_phase_count: # #existing.total_phase_count = str(existing.total_phase_count)+","+str(existing.singet_set_qty * existing.total_set) # existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval)) # else: # existing.total_phase_count = str(existing.singet_set_qty * existing.total_set) # # quantity and total_price are computed, so they'll auto update # return existing #print(f"Initial : singet {vals.get('singet_set_qty', 1)}") #print(f"Initial : total {vals.get('total_set', 1)}") singleset = vals.get('singet_set_qty', 1) total_set = vals.get('total_set', 1) #print(f" singleset : {singleset}") #print(f" totalset : {total_set}") # If no match found, continue with normal creation if vals.get('ref_id'): parent = self.env['sos_dock_audit'].browse(vals['ref_id']) vals['phase'] = (parent.phase_version + 1) or 0 #vals['total_phase_count'] = singleset * total_set vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set) return super(sos_dock_audit_Line_Material, self).create(vals) class sos_dock_audit_Line_sfg(models.Model): _name = 'sos_dock_audit_line_sfg' _description = 'SFG Order Lines' ref_id = fields.Many2one('sos_dock_audit', string="Materials", 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')], 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") assembling_charges = fields.Monetary(string="Assembling cost per unit") total_price = fields.Monetary(string="Total",compute="_compute_total_price") is_spare = fields.Boolean(string="Spare") phase = fields.Char(string="Phase",readonly=True) # ,readonly=True total_phase_count = fields.Char(string="Aggregate Phase") @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 record.assembling_charges = record.component_id.assembling_charges @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.assembling_charges) * record.quantity @api.model def create(self, vals): #print(f" First line in create ") #component_id = vals.get('component_id') ref_id = vals.get('ref_id') #sequence_util = self.env['sos_common_scripts'] # if component_id and ref_id: # # Search for an existing line with the same component_id and ref_id # existing = self.search([ # ('component_id', '=', component_id), # ('ref_id', '=', ref_id) # ], limit=1) # if existing: # # Merge logic: add quantities # existing.singet_set_qty += vals.get('singet_set_qty', 1) # #existing.total_set += vals.get('total_set', 1) # previousval = 0 # if vals.get('ref_id'): # parent = self.env['sos_dock_audit'].browse(vals['ref_id']) # existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1) # previousval = sequence_util.extract_value(existing.total_phase_count) # if existing.total_phase_count: # #existing.total_phase_count = str(existing.total_phase_count)+","+str(existing.singet_set_qty * existing.total_set) # existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval)) # else: # existing.total_phase_count = str(existing.singet_set_qty * existing.total_set) # # quantity and total_price are computed, so they'll auto update # return existing singleset = vals.get('singet_set_qty', 1) total_set = vals.get('total_set', 1) # If no match found, continue with normal creation if vals.get('ref_id'): parent = self.env['sos_dock_audit'].browse(vals['ref_id']) vals['phase'] = (parent.phase_version + 1) or 0 #vals['total_phase_count'] = singleset * total_set vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set) return super(sos_dock_audit_Line_sfg, self).create(vals) class sos_dock_audit_Line_fg(models.Model): _name = 'sos_dock_audit_line_fg' _description = 'FG Order Lines' ref_id = fields.Many2one('sos_dock_audit', string="Materials", 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')], 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") fg_display_name = fields.Char(related="component_id.display_name",string="FG Display 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") is_spare = fields.Boolean(string="Spare") matched_line = fields.Boolean(default=False) phase = fields.Char(string="Phase",readonly=True) # ,readonly=True default=lambda self: self._get_phase_version_default() ,compute="_compute_phase" ,default=lambda self: self._compute_phase() total_phase_count = fields.Char(string="Phase Wise Quantity") #current_phase_value = fields.Char(compute="_compute_current_phase_value") # @api.depends('total_phase_count') # def _compute_current_phase_value(self): # current_phase = self.env.context.get('current_phase') # for line in self: # line.current_phase_value = '' # if current_phase and line.total_phase_count: # for entry in line.total_phase_count.split(','): # if entry.startswith(f'P{current_phase}-'): # line.current_phase_value = entry # break @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 @api.model def create(self, vals): #component_id = vals.get('component_id') ref_id = vals.get('ref_id') #sequence_util = self.env['sos_common_scripts'] # if component_id and ref_id: # # Search for an existing line with the same component_id and ref_id # existing = self.search([ # ('component_id', '=', component_id), # ('ref_id', '=', ref_id) # ], limit=1) ##if existing: # # Merge logic: add quantities # existing.singet_set_qty += vals.get('singet_set_qty', 1) # #existing.total_set += vals.get('total_set', 1) ## previousval = 0 ## if vals.get('ref_id'): ## parent = self.env['sos_dock_audit'].browse(vals['ref_id']) # existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1) ## previousval = sequence_util.extract_value(existing.total_phase_count) ## if existing.total_phase_count: # #print(f" TT :: {existing.total_phase_count} ") ## existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval)) # else: # existing.total_phase_count = "P"+str(existing.phase)+"-"+str(existing.singet_set_qty * existing.total_set) # # quantity and total_price are computed, so they'll auto update #return existing singleset = vals.get('singet_set_qty', 1) total_set = vals.get('total_set', 1) # data = "P3-1,P4-4" # # Step 1: Split by comma to get individual items # items = data.split(',') # # Step 2: Split each item by hyphen # split_data = [item.split('-') for item in items] # print(f" {split_data} : split_data : {items[len(items)-2]}") # If no match found, continue with normal creation if vals.get('ref_id'): #print(f"if vals ") parent = self.env['sos_dock_audit'].browse(vals['ref_id']) vals['phase'] = (parent.phase_version + 1) or 0 vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set) return super(sos_dock_audit_Line_fg, self).create(vals) class sos_dock_audit_MiscellaneousCost(models.Model): _name = 'sos_dock_audit_miscellaneous_items' _description = 'Miscellaneous Items' ref_id = fields.Many2one('sos_dock_audit', 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") phase = fields.Char(string="Phase", readonly=True) # , default=lambda self: self._phase_value() #total_phase_count = fields.Char(string="Aggregate Phase") @api.model def create(self, vals): ref_id = vals.get('ref_id') if ref_id: parent = self.env['sos_dock_audit'].browse(vals['ref_id']) vals['phase'] = (parent.phase_version+1) or 0 return super().create(vals) @api.depends('cost','quantity') def _compute_total_price(self): #self.phase_version = (self.ref_id.phase_version+1) for record in self: record.total_price = record.cost * record.quantity class sos_dock_audit_Material_installationkit(models.Model): _name = 'sos_dock_audit_line_material_installation' _description = 'Installation Kit Lines' 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") 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",readonly=False) total_price = fields.Monetary(string="Total",compute="_compute_total_price") phase = fields.Char(string="Phase",readonly=True) total_phase_count = fields.Char(string="Aggregate Phase") @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: record.total_price = record.unit_price * record.quantity @api.model def create(self, vals): #component_id = vals.get('component_id') ref_id = vals.get('ref_id') #sequence_util = self.env['sos_common_scripts'] # if component_id and ref_id: # # Search for an existing line with the same component_id and ref_id # existing = self.search([ # ('component_id', '=', component_id), # ('ref_id', '=', ref_id) # ], limit=1) # if existing: # # Merge logic: add quantities # existing.singet_set_qty += vals.get('singet_set_qty', 1) # #existing.total_set += vals.get('total_set', 1) # previousval = 0 # if vals.get('ref_id'): # parent = self.env['sos_dock_audit'].browse(vals['ref_id']) # existing.phase = str(existing.phase) + "," + str(parent.phase_version + 1) # #print(f" Total_phase_count :{existing.total_phase_count}") # #print(f" Extract Value :{self.extract_value(existing.total_phase_count)}") # previousval = sequence_util.extract_value(existing.total_phase_count) # #print(f" : previousval : {previousval}") # if existing.total_phase_count: # #existing.total_phase_count = str(existing.total_phase_count)+","+str(existing.singet_set_qty * existing.total_set) # #print(f" Total Count : {existing.singet_set_qty * existing.total_set}") # existing.total_phase_count = str(existing.total_phase_count)+","+"P"+str(parent.phase_version + 1 or '') +"-"+str((existing.singet_set_qty * existing.total_set)- int(previousval)) # else: # existing.total_phase_count = str(existing.singet_set_qty * existing.total_set) # # quantity and total_price are computed, so they'll auto update # return existing singleset = vals.get('singet_set_qty', 1) total_set = vals.get('total_set', 1) # If no match found, continue with normal creation if vals.get('ref_id'): parent = self.env['sos_dock_audit'].browse(vals['ref_id']) vals['phase'] = (parent.phase_version + 1) or 0 #vals['total_phase_count'] = singleset * total_set vals['total_phase_count'] = "P"+str(parent.phase_version + 1 or '') +"-"+str(singleset * total_set) return super(sos_dock_audit_Material_installationkit, self).create(vals) class SOS_Design_Verification(models.Model): _name = 'sos_design_verification' _description = 'Design Verification' ref_id = fields.Many2one('sos_dock_audit') name = fields.Char(string="Name") remarks = fields.Text(string="Remarks") class SOS_Dock_Audit_Transaction(models.Model): _name = 'sos_dock_audit_transaction' _description = 'Dock Audit Transaction' ref_id = fields.Many2one('sos_dock_audit') dock_audit_no = fields.Char(string="Dock Audit No") phase_version = fields.Integer(string="Phase") audited_by_image = fields.Image(related="audited_by_name.signature_image",string='Audited by Sign',readonly=True) audited_on = fields.Datetime(string="Audited On") audited_by_name = fields.Many2one('res.users', string='Audited by') qa_by_image = fields.Image(related="qa_by_name.signature_image",string='QA by Sign',readonly=True) qa_tested_on = fields.Datetime(string="Tested On") qa_by_name = fields.Many2one('res.users', string='QA Sign') ce_image = fields.Image(related="ce_name.signature_image",string='CE Sign',readonly=True) ce_approved_on = fields.Datetime(string="Approved On") ce_name = fields.Many2one('res.users', string='CE') accounts_approved_by_image = fields.Image(related="accounts_approved_name.signature_image",string='Accounts Sign',readonly=True) accounts_approved_on = fields.Datetime(string="Accounts Approved On") accounts_approved_name = fields.Many2one('res.users', string='Accounts Sign') top_management_approval_image = fields.Image(related="top_management_name.signature_image",string='Top Management Approval',readonly=True) top_management_approved_on = fields.Datetime(string="Approved On") top_management_name = fields.Many2one('res.users', string='Top Management Approver')