myLogger = \Config\Services::mylogger(); $this->clientModel = new ClientModel(); $this->userModel = new UserModel(); $this->clientBranchModel = new ClientBranchModel(); $this->clientPolicyModel = new ClientPolicyModel(); $this->levelContactModel = new LevelContactModel(); $this->leadsModel = new LeadsModel(); $this->policyTypeModel = new PolicyTypeModel(); $this->kycEntityTypeModel = new KYCEntityTypeModel(); $this->policyTransactionStatusModel = new PolicyTransactionStatusModel(); $this->insurerBranchModel = new InsurerBranchModel(); $this->tpaBranchModel = new TPABranchModel(); $this->RFQModel = new RFQModel(); $this->insurerModel = new InsurerModel(); $this->occupancyModel = new OccupancyMasterModel(); $this->issuer = [1 => 'JIBS', 2 => 'Nhance']; $this->clientType = [1 => 'Group', 2 => 'Individual']; $this->leadType = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over']; $this->buisnessType = [1 => 'Industrial', 2 => 'Non Industrial']; $this->leadsStatus = [ 'queued' => 'Queued', 'qcr_sent' => 'QCR sent', 'lost' => 'Lost', 'co_insurer_pending' => 'Co-Insurer Pending', 'won' => 'Won', 'completed_with_corrections' => 'Completed with Corrections', 'completed_without_corrections' => 'Completed w/o Corrections', ]; $this->claim_type_for_gpa = [ 'accident_death' => 'Accident Death', 'permanent_total_disablement' => 'Permanent Total Disablement', 'permanent_partial_disablement' => 'Permanent Partial Disablement', 'temporary_total_disablement_benefit' => 'Temporary Total Disablement benefit' ]; $this->cause_of_death = [ 'natural_death' => 'Natural Death', 'suicide' => 'Suicide', 'accident' => 'Accident' ]; } public function viewLeadsList() { $data['page_name'] = 'Leads'; // Set basic data $data['issuer'] = $this->issuer; $data['client_type'] = $this->clientType; $data['lead_type'] = $this->leadType; $data['lead_status'] = $this->leadsStatus; // Fetch policy types and entity data $data['policy_type'] = $this->policyTypeModel->where('is_active', 1)->findAll(); $data['entity'] = $this->kycEntityTypeModel->where('is_active', 1)->findAll(); // dd($lastFiveYears); if ($this->request->is('get')) { // Fetch leads data $data['lead_data_list'] = $this->leadsModel->getLeadDataForLising(); // Load layout and pass data $this->loadLayout('lead_filter', $data); } else { $search_data = $this->request->getPost(); // print_r($search_data); $where = []; foreach ($search_data as $search_objects => $key) { if ($key != null && $key != '' && $key != 0) { $where[$search_objects] = $key; } } $data['lead_data_list'] = $this->leadsModel->getLeadDataForLising($where); $html = view('leads_list', $data); return $this->respond(['status' => true, 'html' => $html], 200); } } public function createLead() { // print_r($this->request->getPost()); die; $id = $this->request->getPost('id'); $data = $this->prepareLeadData(); // print_r($data); die; if (!$id) { return $this->insertNewLead($data); } else { return $this->updateOldLead($id, $data); } } private function prepareLeadData() { $data = $this->request->getPost(); if ($data['lead_type'] == 2) { $client_data = $this->clientModel->where('id', $data['client_id'])->where('is_active', 1)->first(); $data['client_name'] = $client_data['client_name']; $data['client_short_name'] = $client_data['short_name']; $data['entity_type_id'] = $client_data['entity_type_id']; $data['client_type'] = $client_data['client_type']; } else { $data['client_id'] = 0; $data['client_branch_id'] = 0; $data['source_policy_id'] = 0; } $data['client_code'] = generate_client_code(); if ($data['client_code'] == 2) { $data['client_code'] = generate_client_code('IC'); } if (isset($data['lead_form_type'])) { $data = $this->prepareSingleLeadData($data); } else { $data = $this->prepareMultipleLeadData($data); } // print_r($data); die; return $data; } private function prepareSingleLeadData($data) { // print_r($data); die; $uploadFilePath = WRITEPATH . 'uploads/lead_files/'; // Get all uploaded files for 'file_name[]' $files = $this->request->getFileMultiple('file_name'); // print_r($files); die; // Separate the insurer and insurer branch, handle missing or invalid data if (isset($data['insurer']) && strpos($data['insurer'], '-') !== false) { list($insurer_branch_id, $insurer_id) = explode('-', $data['insurer']); } else { $insurer_branch_id = 0; $insurer_id = 0; } $data['insurer_id'] = $insurer_id; $data['insurer_branch_id'] = $insurer_branch_id; // Separate the insurer and insurer branch, handle missing or invalid data if (isset($data['tpa']) && strpos($data['tpa'], '-') !== false) { list($tpa_branch_id, $tpa_id) = explode('-', $data['tpa']); } else { $tpa_branch_id = 0; $tpa_id = 0; } $data['tpa_id'] = $tpa_id; $data['tpa_branch_id'] = $tpa_branch_id; if (!empty($data['policy_start_date'])) { $data['policy_start_date'] = change_date_format($data['policy_start_date']); } else { $data['policy_start_date'] = null; } if (!empty($data['policy_end_date'])) { $data['policy_end_date'] = change_date_format($data['policy_end_date']); } else { $data['policy_end_date'] = null; } $data['file_name'] = file_Upload($files, $uploadFilePath); $processcedData[] = $data; // print_r($data);die(); return $processcedData; } private function prepareMultipleLeadData($data) { // print_r($data); die; $processedData = []; $uploadFilePath = WRITEPATH . 'uploads/lead_files/'; // Get all uploaded files for 'file_name[]' $files = $this->request->getFileMultiple('file_name'); // print_r($files); die; foreach ($data['policy_type_id'] as $index => $value) { // Separate the insurer and insurer branch, handle missing or invalid data if (isset($data['insurer'][$index]) && strpos($data['insurer'][$index], '-') !== false) { list($insurer_branch_id, $insurer_id) = explode('-', $data['insurer'][$index]); } else { $insurer_branch_id = 0; $insurer_id = 0; } // Separate the insurer and insurer branch, handle missing or invalid data if (isset($data['tpa'][$index]) && strpos($data['tpa'][$index], '-') !== false) { list($tpa_branch_id, $tpa_id) = explode('-', $data['tpa'][$index]); } else { $tpa_branch_id = 0; $tpa_id = 0; } // Separate the insurer and insurer branch, handle missing or invalid data if (isset($data['proposed_insurer'][$index]) && strpos($data['proposed_insurer'][$index], '-') !== false) { list($proposed_insurer_branch_id, $proposed_insurer_id) = explode('-', $data['proposed_insurer'][$index]); } else { $proposed_insurer_branch_id = 0; $proposed_insurer_id = 0; } // Separate the TPA and TPA branch, handle missing or invalid data if (isset($data['proposed_tpa'][$index]) && strpos($data['proposed_tpa'][$index], '-') !== false) { list($proposed_tpa_branch_id, $proposed_tpa_id) = explode('-', $data['proposed_tpa'][$index]); } else { $proposed_tpa_branch_id = 0; $proposed_tpa_id = 0; } if (!empty($data['policy_start_date'][$index])) { $policy_start_date = change_date_format($data['policy_start_date'][$index], 'd/m/Y', 'Y-m-d'); } else { $policy_start_date = null; } if (!empty($data['policy_end_date'][$index])) { $policy_end_date = change_date_format($data['policy_end_date'][$index], 'd/m/Y', 'Y-m-d'); } else { $policy_end_date = null; } if (!empty($data['incurred_claim_date'][$index])) { $incurred_claims_date = change_date_format($data['incurred_claim_date'][$index], 'd/m/Y', 'Y-m-d'); } else { $incurred_claims_date = null; } if (!empty($data['premium_date'][$index])) { $premium_date = change_date_format($data['premium_date'][$index], 'd/m/Y', 'Y-m-d'); } else { $premium_date = null; } $file_name = file_Upload($files[$index], $uploadFilePath); $last_3_years_claims = $data['finyear']; $processedData[] = [ 'lead_type' => $data['lead_type'], 'issuer' => $data['issuer'], 'client_type' => $data['client_type'], 'client_name' => $data['client_name'], 'client_short_name' => $data['client_short_name'], 'entity_type_id' => $data['entity_type_id'], 'client_code' => $data['client_code'], 'pan' => $data['pan'], 'gst' => $data['gst'], 'branch_name' => $data['branch_name'], 'branch_code' => $data['branch_code'], 'contact_person_name' => $data['contact_person_name'], 'contact_person_mobile' => $data['contact_person_mobile'], 'contact_person_email' => $data['contact_person_email'], 'client_id' => $data['client_id'] ?? 0, 'client_branch_id' => $data['client_branch_id'] ?? 0, 'source_policy_id' => $data['source_policy_id'] ?? 0, 'policy_type_id' => $value, 'salse_person_id' => $data['salse_person_id'] ?? 0, 'insurer_id' => $insurer_id ?? 0, 'insurer_branch_id' => $insurer_branch_id ?? 0, 'tpa_id' => $tpa_id ?? 0, 'tpa_branch_id' => $tpa_branch_id ?? 0, 'policy_start_date' => $policy_start_date, 'policy_end_date' => $policy_end_date, 'no_of_lives' => $data['no_of_lives'][$index] ?? null, 'incurred_claims' => $data['incurred_claims'][$index] ?? 0, 'location' => $data['location'][$index] ?? null, 'proposed_insurer_id' => $proposed_insurer_id ?? 0, 'proposed_insurer_branch_id' => $proposed_insurer_branch_id ?? 0, 'proposed_tpa_id' => $proposed_tpa_id ?? 0, 'proposed_tpa_branch_id' => $proposed_tpa_branch_id ?? 0, 'renewal_emp_count' => $data['renewal_emp_count'][$index] ?? 0, 'renewal_dept_count' => $data['renewal_dept_count'][$index] ?? 0, 'renewal_no_of_lives' => $data['renewal_no_of_lives'][$index] ?? 0, 'incept_emp_count' => $data['incept_emp_count'][$index] ?? 0, 'incept_dept_count' => $data['incept_dept_count'][$index] ?? 0, 'incept_no_of_lives' => $data['incept_no_of_lives'][$index] ?? 0, 'exp_emp_count' => $data['exp_emp_count'][$index] ?? 0, 'exp_dept_count' => $data['exp_dept_count'][$index] ?? 0, 'exp_no_of_lives' => $data['exp_no_of_lives'][$index] ?? 0, 'incurred_claims_date' => $incurred_claims_date, 'paid_claims' => $data['paid_claims'][$index] ?? 0, 'outstanding_claims' => $data['outstanding_claims'][$index] ?? 0, 'policy_run_days' => $data['policy_run_days'][$index] ?? 0, 'premium_at_inception' => $data['premium_at_inception'][$index] ?? 0, 'premium_date' => $premium_date, 'earned_premium' => $data['earned_premium'][$index] ?? 0, 'annualised_claims' => $data['annualised_claims'][$index] ?? 0, 'incurred_claims_ratio' => $data['incurred_claims_ratio'][$index] ?? 0, 'earned_claims_ratio' => $data['earned_claims_ratio'][$index] ?? 0, 'total_si_at_incept' => $data['total_si_at_incept'][$index] ?? 0, 'total_si_at_renewal' => $data['total_si_at_renewal'][$index] ?? 0, 'fin_years_claims' => $last_3_years_claims, 'file_name' => $file_name, 'status' => $data['status'] ?? null, 'notes' => $data['notes'] ?? null, 'lead_form_type' => $data['lead_form_type'] ?? 1, 'custom_fields' => $data['custom_fields'] ?? null, ]; } // print_r($processedData);die(); return $processedData; } private function insertNewLead($data) { $insertCount = []; foreach ($data as $value) { $insert = $this->leadsModel->insert($value); $insertCount[] = $insert; $this->insertLeadStatus($insert, $value['status'], 3); if ($value['lead_form_type'] == 1) { //for this push the job to the calculateMembersDemography() function $job_details = new Jobs(); $r = Jobs::addJob(['job_name' => 'calculateMembersDemography', 'payload' => [ 'lead_id' => $insert, ]]); } } if (count($insertCount) > 0) { return $this->respond(['status' => true, 'lead_id' => $insert, 'message' => 'New Lead created successfully', 'data' => $data], 200); } return $this->respond(['status' => false, 'lead_id' => $insert, 'message' => "Failed to create Lead", 'data' => $data], 200); } private function updateOldLead($id, $data) { if ($this->leadsModel->where('id', $id)->set($data[0])->update()) { $this->insertLeadStatus($id, $data[0]['status'], 3); return $this->respond(['status' => true, 'lead_id' => $id, 'message' => "Lead updated successfully", 'data' => $data], 200); } return $this->respond(['status' => false, 'lead_id' => $id, 'message' => "Failed to update Lead", 'data' => $data], 200); } // Get the Single Lead data for edit public function getLeadDataForEdit($id) { $data = $this->leadsModel ->where('leads.id', $id) ->where('leads.is_active', 1) ->first(); $data['lead_edit_data'] = $this->leadsModel ->where('leads.id', $id) ->where('leads.is_active', 1) ->first(); if (!empty($data['policy_start_date'])) { $data['policy_start_date'] = change_date_format($data['policy_start_date'], 'Y-m-d', 'd/m/Y'); } else { $data['policy_start_date'] = null; } if (!empty($data['policy_end_date'])) { $data['policy_end_date'] = change_date_format($data['policy_end_date'], 'Y-m-d', 'd/m/Y'); } else { $data['policy_end_date'] = null; } if (!empty($data['incurred_claims_date'])) { $data['incurred_claims_date'] = change_date_format($data['incurred_claims_date'], 'Y-m-d', 'd/m/Y'); } else { $data['incurred_claims_date'] = null; } if (!empty($data['premium_date'])) { $data['premium_date'] = change_date_format($data['premium_date'], 'Y-m-d', 'd/m/Y'); } else { $data['premium_date'] = null; } $data['lastFiveYears'] = $this->getLastFiveFinancialYears(); $data['gpaClaimType'] = $this->claim_type_for_gpa; $data['causeOfDeath'] = $this->cause_of_death; if (!empty($data['fin_years_claims'])) { $decoded = json_decode($data['fin_years_claims'], true); $data['lead_edit_data']['fin_years_claims_array'] = isset($decoded['finyear']) ? $decoded['finyear'] : []; } else { $data['lead_edit_data']['fin_years_claims_array'] = []; } $data['html'] = $this->generateViewPageHtml($data['policy_type_id'], $data) ?? ""; if ($data) { return $this->respond(['status' => true, 'data' => $data], 200); } else { return $this->respond(['status' => false], 200); } } private function insertLeadStatus($primaryKey, $status, $statusType) { $statusData = [ 'policy_tran_id' => $primaryKey, 'status' => $status, 'status_type' => $statusType, 'created_by' => get_session_userid(), ]; $this->policyTransactionStatusModel->insert($statusData); } //--------RFQ----------------------------------------------------------------------------------------------- public function viewRFQ($id, $type = 1) { $data['rfq_data'] = $this->RFQModel ->where('lead_id', $id) // ->where('type', $type) ->where('is_active', 1) ->orderBy('id', 'desc') ->first(); // dd($data); $data['rfq_count'] = $this->RFQModel ->where('lead_id', $id) // ->where('type', 1) ->where('is_active', 1) ->countAllResults(); $data['qcr_count'] = $this->RFQModel ->where('lead_id', $id) ->where('type', 2) ->where('is_active', 1) ->countAllResults(); // dd(count($data['rfq_data'])); $data['lead_id'] = $id; $lead_data = $this->leadsModel ->select(' leads.*, policy_type.question_json, policy_type.policy_type, policy_type.long_name, user_profiles.email as created_person_email ') ->join('policy_type', 'leads.policy_type_id = policy_type.id') ->join('user_profiles', 'leads.created_by = user_profiles.id', 'left') ->where('leads.id', $id) ->where('leads.is_active', 1) ->first(); // dd($lead_data); if ($lead_data['lead_type'] == 2) { $client_policy_data = $this->clientPolicyModel->where('is_active', 1)->where('id', $lead_data['source_policy_id'])->first(); $data['policy_terms'] = $client_policy_data['policy_terms']; } $data['question_json'] = $lead_data['question_json']; $data['page_name'] = $type == 2 ? 'QCR' : 'RFQ'; $data['insurer'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames(); $data['userList'] = $this->userModel->getUserListForRFQ(); $data['lead_data'] = $lead_data; $mail_content = "

Dear Sir,

Greetings From Nhance India!

Please find attached the {{RFQ_OR_QCR}} for {{POLICY_TYPE}} policy pertaining to {{CLIENT_NAME}}.

Kindly request you to share the competitive quotes at the earliest.

In case of any query, please feel free to contact us.

Thank You!

"; $subject = "{{CLIENT_NAME}} _ {{POLICY_TYPE}} _ {{RFQ_OR_QCR}} _ {{POLICY_YEAR}}"; $data['mail_content'] = $this->transformMailContent($lead_data, $mail_content, $data['page_name']); $data['subject'] = $this->transformMailContent($lead_data, $subject, $data['page_name']); // dd($data); if ($data['lead_data']['lead_form_type'] == 1) { $this->loadLayout('view_rfq.php', $data); } else if ($data['lead_data']['lead_form_type'] == 2) { $data['occupancy'] = $this->occupancyModel->findAll(); // dd($data['occupancy']); $data['policies'] = json_decode($data['question_json'], true)['policies']; $data["child_table_data"] = json_decode($data['question_json'], true)['child_table_data']; // $data['lead_register_data'] = json_decode($data['lead_data']['custom_fields']); // dd($data['lead_register_data']); $data['client_type'] = $this->clientType; $data['buisness_type'] = $this->buisnessType; $this->loadLayout('view_rfq_non_eb', $data); } } public function savePolicyInfo() { $data = $this->request->getPost(); $lead_id = $data['lead_id']; $json_data = $data['registration_json']; $existingJson = $this->RFQModel->where('is_active', 1)->where("lead_id", $lead_id)->first()['registration_json'] ?? null; if (empty($existingJson)) { $this->RFQModel ->where('lead_id', $lead_id) ->where('type', 1) ->where('is_active', 1) ->set('is_active', 0) ->update(); $insertData['lead_id'] = $lead_id; $insertData['registration_json'] = json_encode($json_data); $this->RFQModel->insert($insertData); return $this->respond(['status' => true, "message" => "Policy Inforamtion saved"]); } else { return $this->respond(['status' => true, "message" => "Policy Inforamtion Already saved"]); } } public function createRFQ() { $data = $this->request->getPost(); $lead_id = $data['lead_id'] ?? null; if (!$lead_id) { return $this->respond(['status' => false, 'message' => 'Lead ID is required'], 400); } $data['type'] = 1; // Deactivate existing RFQs for this lead and type $this->RFQModel ->where('lead_id', $lead_id) ->where('type', 1) ->where('is_active', 1) ->set('is_active', 0) ->update(); // Handle registration_json if (empty($data['registration_json'])) { // Fetch the latest registration_json if not provided $latest = $this->RFQModel ->select('registration_json') ->where('lead_id', $lead_id) ->orderBy('id', 'DESC') ->first(); if (!empty($latest['registration_json'])) { $data['registration_json'] = $latest['registration_json']; } } // Insert new RFQ $insertId = $this->RFQModel->insert($data); if ($insertId) { $message = ($data['submit_type'] ?? '') == 'QCR' ? 'QCR submitted successfully' : 'RFQ submitted successfully'; return $this->respond([ 'status' => true, 'id' => $insertId, 'message' => $message, 'data' => $data ], 200); } $message = ($data['submit_type'] ?? '') == 'QCR' ? 'Failed to create QCR' : 'Failed to create RFQ'; return $this->respond([ 'status' => false, 'id' => null, 'message' => $message, 'data' => $data ], 200); } public function createQCR() { $data = $this->request->getPost(); $lead_id = $data['lead_id']; $data['type'] = 2; $this->RFQModel ->where('lead_id', $lead_id) ->where('type', 2) ->where('is_active', 1) ->set('is_active', 0) ->update(); $result = $this->RFQModel->insert($data); if ($result) { return $this->respond(['status' => true, 'id' => $result, 'message' => 'QCR created successfully', 'data' => $data], 200); } return $this->respond(['status' => false, 'id' => $result, 'message' => "Failed to create QCR", 'data' => $data], 200); } //-----RFQ and QCR EXPORT------------------------------------------------------------------------------------------------ //export main route function public function exportQCRandRFQ($lead_id, $type, $lead_form_type) { $this->exportExcelForQCRandRFQ($lead_id, $type, $lead_form_type); } //FOR EXCEL public function exportExcelForQCRandRFQ($lead_id, $type, $lead_form_type = 1) { if ($lead_form_type == 2) { $filepath = $this->constructNonEbExcelToSaveTemp($lead_id, $type); } else { $filepath = $this->constructExcelToSaveTemp($lead_id, $type); } $lead_data = $this->RFQModel->getRFQTableDataWithLeadIDAndType($lead_id, $type); // dd($filepath); //Excel merging part if ($lead_data['file_name'] != null && $lead_data['file_name'] != '') { $temp_file_path = $filepath['filePath']; $temp_file_name = $filepath['fileName']; $lead_file_path = WRITEPATH . 'uploads/lead_files/' . $lead_data['file_name']; // dd($lead_data, $temp_file_path, $temp_file_name, $lead_file_path); if ($lead_file_path) { $filePaths = [ ['file_path' => $temp_file_path, 'sheets' => []], ['file_path' => $lead_file_path, 'sheets' => []] ]; // $outputPath = dirname($temp_file_path) . '/' . 'merged_' . $temp_file_name; $result = ExcelMergeHelper::mergeExcelFiles($filePaths, $temp_file_path); // print_rr($result); } } $filepath = $filepath['filePath']; if (file_exists($filepath)) { // Set headers to force download header('Content-Description: File Transfer'); header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment; filename="' . basename($filepath) . '"'); header('Content-Length: ' . filesize($filepath)); header('Pragma: public'); // Output the file content readfile($filepath); // Delete the file after download unlink($filepath); exit; } else { echo "File does not exist."; } } //Construct excel file and save the file to the folder and return file path public function constructExcelToSaveTemp($lead_id, $type, $propsal_and_insurer = null) { $rfq_data = $this->RFQModel->getRFQTableDataWithLeadIDAndType($lead_id, $type); // dd($rfq_data, $lead_id, $type, $propsal_and_insurer); // print_r($propsal_and_insurer); die; if ($rfq_data['lead_type'] == 1) { if ($rfq_data['policy_type_id'] == 2) { $lead_data = [ 'Insured' => $rfq_data['client_name'], 'Policy Status' => $rfq_data['status'], 'No of Employees' => $rfq_data['incept_emp_count'], 'No of Dependents' => $rfq_data['incept_dept_count'], 'Total Lives' => $rfq_data['incept_no_of_lives'], 'Period of Insurance ' => date('d/m/Y', strtotime($rfq_data['policy_start_date'])) . ' to ' . date('d/m/Y', strtotime($rfq_data['policy_end_date'])), 'Policy Run Days' => $rfq_data['policy_run_days'], ]; } else if ($rfq_data['policy_type_id'] == 1) { $lead_data = [ 'Insured' => $rfq_data['client_name'], 'No of Employees at Inception' => $rfq_data['incept_emp_count'], 'Total Sum Insured at Inception ' => $rfq_data['total_si_at_incept'], 'Policy Period' => date('d/m/Y', strtotime($rfq_data['policy_start_date'])) . ' to ' . date('d/m/Y', strtotime($rfq_data['policy_end_date'])), 'Policy Status' => $rfq_data['status'], 'Existing Insurer' => $rfq_data['insurer_name'], 'TPA ' => $rfq_data['tpa_name'], ]; } } else { if ($rfq_data['policy_type_id'] == 2) { $lead_data = [ 'Insured' => $rfq_data['client_name'], 'Policy Status' => $rfq_data['status'], 'No of Employees at Inception' => $rfq_data['incept_emp_count'], 'No of Dependents at Inception' => $rfq_data['incept_dept_count'], 'Total Lives at Inception ' => $rfq_data['incept_no_of_lives'], 'No of Employees at Expiry' => $rfq_data['exp_emp_count'], 'No of Dependents at Expiry' => $rfq_data['exp_dept_count'], 'Total Lives at Expiry ' => $rfq_data['exp_no_of_lives'], 'No of Employees at Renewal' => $rfq_data['renewal_emp_count'], 'No of Dependents at Renewal' => $rfq_data['renewal_dept_count'], 'Total Lives at Renewal ' => $rfq_data['renewal_no_of_lives'], 'Period of Insurance ' => date('d/m/Y', strtotime($rfq_data['policy_start_date'])) . ' to ' . date('d/m/Y', strtotime($rfq_data['policy_end_date'])), 'Policy Run Days' => $rfq_data['policy_run_days'], 'Inception Premium' => $rfq_data['premium_at_inception'], 'Premium as on (Date - DD MM YYYY should be entered based on the claims dump report)' => $rfq_data['premium_date'], 'Earned Premium' => $rfq_data['earned_premium'], 'Incurred Claims as on (Date - DD MM YYYY should be entered based on the claims dump report)' => $rfq_data['incurred_claims_date'], 'Annualised Claims' => $rfq_data['annualised_claims'], 'Incurred Claims Ratio' => $rfq_data['incurred_claims_ratio'], 'Earned Claims Ratio' => $rfq_data['earned_claims_ratio'], ]; } else if ($rfq_data['policy_type_id'] == 1) { $lead_data = [ 'Insured' => $rfq_data['client_name'], 'No of Employees at Renewal' => $rfq_data['renewal_emp_count'], 'Total Sum Insured at Renewal ' => $rfq_data['total_si_at_renewal'], 'Policy Period' => date('d/m/Y', strtotime($rfq_data['policy_start_date'])) . ' to ' . date('d/m/Y', strtotime($rfq_data['policy_end_date'])), 'Policy Status' => $rfq_data['status'], 'Existing Insurer' => $rfq_data['insurer_name'], 'TPA ' => $rfq_data['tpa_name'], ]; } } $data = json_decode($rfq_data['json'], true); // dd($data); if ($type == 2) { $data = $this->convertJsonForQCR($data, $type); if ($propsal_and_insurer !== null) { list($proposal_key, $insurer_key) = explode('-', $propsal_and_insurer, 2); $data = $this->transformProposelData($data, $proposal_key, $insurer_key); } } else if ($type == 1) { $data = $this->convertJsonForQCR($data, $type); // dd($data); } $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Start with lead_data at the top $rowNumber = 1; $mergeRange1 = "A{$rowNumber}:C{$rowNumber}"; $sheet->mergeCells($mergeRange1); $sheet->setCellValue("A{$rowNumber}", "Nhance India Insurance Broking Pvt Ltd"); $sheet->getStyle("A{$rowNumber}")->applyFromArray([ 'font' => [ 'bold' => true, 'size' => 20 ], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], ]); // Set column width to fit the image properly $sheet->getColumnDimension('D')->setWidth(20); // Adjust as needed $sheet->getRowDimension($rowNumber)->setRowHeight(40); // Adjust as needed $drawing = new Drawing(); $path = ROOTPATH . "public/assets/images/Nhance-Logo-Final.png"; // Use FCPATH for server path $drawing->setPath($path); $drawing->setCoordinates("D{$rowNumber}"); // Set position in column B $drawing->setHeight(35); // Adjust image height // Center align the image in the cell $drawing->setOffsetX(30); // Adjust horizontal offset $drawing->setOffsetY(5); // Adjust vertical offset $drawing->setWorksheet($sheet); // Apply center alignment to the cell $sheet->getStyle("D{$rowNumber}")->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); $sheet->getStyle("D{$rowNumber}")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER); $rowNumber = $rowNumber + 1; // Initialize max width tracking variables $maxWidthA = 0; $maxWidthB = 0; foreach ($lead_data as $key => $value) { // Merge A:B for key and C:D for value $mergeRangeKey = "A{$rowNumber}:B{$rowNumber}"; $mergeRangeValue = "C{$rowNumber}:D{$rowNumber}"; $sheet->mergeCells($mergeRangeKey); $sheet->mergeCells($mergeRangeValue); // Set values in merged cells $sheet->setCellValue("A{$rowNumber}", $key); $sheet->setCellValue("C{$rowNumber}", $value); // Apply styles for alignment and bold text in A:B $sheet->getStyle($mergeRangeKey)->applyFromArray([ 'font' => ['bold' => true], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], ]); // Apply bold style to B column if the key is "Insured" if ($key == "Insured") { $sheet->getStyle("C{$rowNumber}")->applyFromArray([ 'font' => ['bold' => true], ]); } // Track max width needed for columns $maxWidthA = max($maxWidthA, mb_strlen($key)); $maxWidthB = max($maxWidthB, mb_strlen($value)); $rowNumber++; } // Set column width based on max content length (adjusted for padding) $sheet->getColumnDimension('A')->setWidth($maxWidthA * 1.2); $sheet->getColumnDimension('B')->setWidth($maxWidthA * 1.2); $sheet->getColumnDimension('C')->setWidth($maxWidthB * 1.2); $sheet->getColumnDimension('D')->setWidth($maxWidthB * 1.2); // $rowNumber += 2; // Add headers and subheaders $headers = $data['table_data']['headers']; $sheet->setCellValue("A{$rowNumber}", "Details of Coverage"); $sheet->getStyle("A{$rowNumber}")->applyFromArray([ 'font' => [ 'bold' => true, ], 'fill' => [ 'fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => 'ADD8E6'], ], 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); $subheader_count = array_sum(array_map(fn($header) => count($header['subHeaders']), $data['table_data']['headers'])); $subheader_count = $subheader_count - 2; $headerCount = count($data['table_data']['headers']); $lastColumn = Coordinate::stringFromColumnIndex($subheader_count); // dd( $headerCount, $lastColumn); // Merge cells from A to the last column $mergeRange = "A{$rowNumber}:{$lastColumn}{$rowNumber}"; $sheet->getStyle($mergeRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); $sheet->mergeCells($mergeRange); $rowNumber = $rowNumber + 1; $subHeaderRow = $rowNumber + 1; $columnLetter = 'A'; foreach ($headers as $header) { if (in_array($header['parentHeader'], ['Item Key', 'Action'])) { continue; } if ($header['parentHeader'] === 'Sno') { $header['parentHeader'] = 'S.No.'; $sheet->getColumnDimension('A')->setWidth(10); } if ($header['parentHeader'] === 'Particulars') { $sheet->getColumnDimension('B')->setWidth(40); } $startColumn = $columnLetter; // Start of the current header range $subHeaderCount = count($header['subHeaders']); // Number of subheaders for this parent header // Set parent header value $sheet->setCellValue("{$startColumn}{$rowNumber}", $header['parentHeader']); $sheet->getStyle("{$startColumn}{$rowNumber}")->applyFromArray([ 'font' => ['bold' => true], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], ]); // Merge header cells if it spans multiple subheaders if ($subHeaderCount > 1) { $endColumn = chr(ord($startColumn) + $subHeaderCount - 1); // Calculate the end column $sheet->mergeCells("{$startColumn}{$rowNumber}:{$endColumn}{$rowNumber}"); } else { $endColumn = $startColumn; // No merge needed if only one subheader } // Add subheaders foreach ($header['subHeaders'] as $subHeader) { $sheet->setCellValue("{$columnLetter}{$subHeaderRow}", $subHeader); if ($columnLetter != "A" && $columnLetter != "B" && $columnLetter != "C" && $columnLetter != "D") { $sheet->getColumnDimension($columnLetter)->setWidth(35); } else { $sheet->getColumnDimension('A')->setWidth(10); } $sheet->getStyle("{$columnLetter}{$subHeaderRow}")->applyFromArray([ 'font' => ['bold' => true], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], ]); $columnLetter++; // Move to the next column for subheaders } } // Apply border to the header range $headerRange = "A{$rowNumber}:" . chr(ord($columnLetter) - 1) . "{$subHeaderRow}"; $sheet->getStyle($headerRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); // Increase row height for headers and subheaders $sheet->getRowDimension($rowNumber)->setRowHeight(25); // Header row height $sheet->getRowDimension($subHeaderRow)->setRowHeight(20); // Subheader row height $rowNumber = $subHeaderRow + 2; $column_data = $data['table_data']['data']; $serial_no = 1; $maxColumnWidths = []; // Add table data rows foreach ($column_data as $dataRow) { $columnLetter = 'A'; foreach ($dataRow['data'] as $cellData) { if (in_array($cellData['parentth'], ['Item Key', 'Action'])) { continue; } if ($cellData['parentth'] == 'Sno') { $sheet->setCellValue("{$columnLetter}{$rowNumber}", $serial_no); } else { $sheet->setCellValue("{$columnLetter}{$rowNumber}", $cellData['value']); } $columnLetter++; } $rowNumber++; $serial_no++; } $dataRange = "A" . ($subHeaderRow + 1) . ":" . chr(ord($columnLetter) - 1) . ($rowNumber - 1); $sheet->getStyle($dataRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); if ($type == 2) { $rowNumber += 2; // Add premium data // dd($data); $labelArray = ["Premium", "GST (%)", "GST Amount (₹)", "Total"]; $premiumData = $data['premium_data']['data']; $premium = [$labelArray[0]]; $gst = [$labelArray[1]]; $gstAmt = [$labelArray[2]]; $total = [$labelArray[3]]; foreach ($premiumData as $proposal => $insurers) { if ($proposal != 'Particulars') { foreach ($insurers as $insurer => $values) { $premium[] = $values[$labelArray[0]]; $gst[] = $values[$labelArray[1]]; $gstAmt[] = $values[$labelArray[2]]; $total[] = $values[$labelArray[3]]; } } } foreach ([$premium, $gst, $gstAmt, $total] as $index => $rowData) { $columnLetter = 'B'; foreach ($rowData as $key => $value) { $sheet->setCellValue("{$columnLetter}{$rowNumber}", $value); if ($key === 0) { $sheet->getStyle("{$columnLetter}{$rowNumber}")->applyFromArray(['font' => ['bold' => true,],]); } $columnLetter++; } $rowNumber++; } $premiumRange = "B" . ($rowNumber - 4) . ":" . chr(ord($columnLetter) - 2) . ($rowNumber - 1); // dd($premiumRange); $sheet->getStyle($premiumRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); } // Auto-size columns // foreach ($sheet->getColumnIterator() as $column) { // $sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true); // } $dataRange = $sheet->calculateWorksheetDimension(); $sheet->getStyle($dataRange)->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_CENTER) ->setVertical(Alignment::VERTICAL_CENTER) ->setWrapText(true); $sheet->getStyle('A1')->applyFromArray([ 'alignment' => [ 'wrapText' => false, // Disables text wrapping for A1 ], ]); // Apply border to the entire sheet preg_match('/([A-Z]+)(\d+):([A-Z]+)(\d+)/', $dataRange, $matches); if ($matches) { $startColumn = $matches[1]; // A $startRow = $matches[2]; // 1 $endColumn = $matches[3]; // G $endRow = $matches[4]; // 75 // Convert column letter to index, reduce by 1, and convert back $endColumnIndex = Coordinate::columnIndexFromString($endColumn) - 1; $newEndColumn = Coordinate::stringFromColumnIndex($endColumnIndex); // Generate the new range (e.g., "A1:F75" instead of "A1:G75") $newDataRange = "{$startColumn}{$startRow}:{$newEndColumn}{$endRow}"; // $sheet->getStyle($newDataRange)->getBorders()->getAllBorders()->setBorderStyle(Border::BORDER_THIN); } $lastRow = count($lead_data) + 1; $leadRange = "A1:D{$lastRow}"; $sheet->getStyle($leadRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); // Set filename $string = ($type == 2) ? 'QCR' : 'RFQ'; $filename = "{$string}_{$rfq_data['client_short_name']}_{$rfq_data['policy_type']}_" . date('YmdHis') . '.xlsx'; // Save to temporary location $uploadFilePath = WRITEPATH . 'tmp/' . $filename; $writer = new Xlsx($spreadsheet); $writer->save($uploadFilePath); return [ 'filePath' => $uploadFilePath, 'fileName' => $filename, ]; } //Merge RFQ/QCR file with lead members file public function mergeQuoteExcelFileWithMembersListExcelFile($lead_id, $type, $source_file_path) { $rfq_data = $this->RFQModel->getRFQTableDataWithLeadIDAndType($lead_id, $type); if ($source_file_path && $rfq_data['file_name']) { } return true; } public function calculateMembersDemography($params) { $lead_id = $params['lead_id']; $lead_data = $this->leadsModel->find($lead_id); $file_name_with_path = WRITEPATH . "/uploads/lead_files/" . $lead_data['file_name']; if (!$lead_data) { return ['status' => 'failed', 'message' => 'Lead data not found']; } if ($lead_data['file_name']) { // $file_name_with_path = WRITEPATH . "/uploads/lead_files/NonPrintableCharacters.xlsx"; //check physical file if (!file_exists($file_name_with_path)) { //file not found update status and reason $message = "Lead Physcial file not found"; // echo $message; $this->myLogger->logme('error', ($message . ' for file ' . $file_name_with_path)); return ['status' => 'failed', 'message' => 'no physical file']; } $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path); //get members data $members_sheet = $spreadsheet->getSheet(0); $highestRowAndColumn = $members_sheet->getHighestRowAndColumn(); // dd($highestRowAndColumn); $uncleaned_members = $members_sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']); $members = ExcelSanitizeHelper::sanitizeArrayData($uncleaned_members); //get age band data $age_band_sheet = $spreadsheet->getSheet(1); $highestRowAndColumn = $age_band_sheet->getHighestRowAndColumn(); $age_band_data = $age_band_sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']); //check age or dob column $members_heading = $members[0]; $available_col = null; $col_index = null; if (in_array('age', array_map('strtolower', $members_heading))) { $available_col = 'age'; $col_index = array_search('age', array_map('strtolower', $members_heading)); } elseif (in_array('dob', array_map('strtolower', $members_heading))) { $available_col = 'dob'; $col_index = array_search('dob', array_map('strtolower', $members_heading)); } if ($available_col == null) { $message = 'No DOB or Age column '; $this->myLogger->logme('error', ($message . $file_name_with_path)); return ['status' => 'failed', 'message' => $message]; } try { $classifiers = $this->getDemographyData($members, $age_band_data, $members_heading, $available_col, $col_index); } catch (Exception $e) { return ['status' => 'fail', 'message' => $e->getMessage()]; } try { $result = $this->generateClassifierSpreadsheet($classifiers, WRITEPATH . 'uploads/lead_files/'); if ($result['success']) { $this->myLogger->logme('error', "Spreadsheet generated successfully!"); echo "Location: " . $result['fullpath'] . "\n"; echo "Filename: " . $result['filename'] . "\n"; $filePaths = [ ['file_path' => WRITEPATH . 'uploads/lead_files/' . $lead_data['file_name'], 'sheets' => [0, 1]], ['file_path' => WRITEPATH . '/uploads/lead_files/' . $result['filename'], 'sheets' => []], ]; $outputPath = WRITEPATH . 'uploads/lead_files/Member_Data.xlsx'; $result_merge = ExcelMergeHelper::mergeExcelFiles($filePaths, $outputPath); if ($result_merge) { // Call the delete function after the file is successfully created $deleteResponse = $this->deleteGeneratedFile($result['fullpath']); // Add delete message to response $response['deleteMessage'] = $deleteResponse['message']; return ['status' => 'success', 'message' => 'Member_Data Merged Suceesfully']; } } else { echo "Error generating spreadsheet: " . $result['error']; } } catch (Exception $e) { echo "Error: " . $e->getMessage(); return ['status' => 'fail', 'message' => $e->getMessage()]; } } else { $this->myLogger->logme('error', (' no file found ' . $file_name_with_path)); return ['status' => 'failed', 'message' => 'no file found']; } } public function getDemographyData($members, $age_band_data, $members_heading, $available_col, $col_index) { $first_loop = 0; $col_index_si = array_search('si enhancement', array_map('strtolower', $members_heading)); $col_index_relationship = array_search('relationship', array_map('strtolower', $members_heading)); $relations = []; $si_amt = ['general']; // Initialize with 'general' as per first loop condition // First pass - collect unique relations and SI amounts foreach ($members as $member) { if ($first_loop == 0) { $first_loop++; continue; } if ($member == null) { continue; } if (!in_array($member[$col_index_relationship], $relations) && $member[$col_index_relationship] != null) { $relations[] = $member[$col_index_relationship]; } if (!in_array($member[$col_index_si], $si_amt) && $member[$col_index_si] != null) { $si_amt[] = $member[$col_index_si]; } } // Initialize classifier array $classifiers = []; foreach ($si_amt as $si) { $classifiers[$si] = []; // Initialize relation counts including Grand Total row foreach ($relations as $relation) { $classifiers[$si][$relation] = []; foreach ($age_band_data as $age_bands) { foreach ($age_bands as $age_interval) { $classifiers[$si][$relation][$age_interval] = 0; } } // Add Grand Total column for each relation echo('test passed 3.5'); $classifiers[$si][$relation]['Grand Total'] = 0; } // Initialize Grand Total row $classifiers[$si]['Grand Total'] = []; foreach ($age_band_data as $age_bands) { foreach ($age_bands as $age_interval) { $classifiers[$si]['Grand Total'][$age_interval] = 0; } } // Add grand total of grand totals $classifiers[$si]['Grand Total']['Grand Total'] = 0; } // Process members and count them foreach ($members as $member) { if ($first_loop == 0) { $first_loop++; continue; } // Get age $age = $this->getAge($available_col, $member, $col_index); $relation = $member[$col_index_relationship]; $member_si = $member[$col_index_si]; // Find the correct age band (only once per member) $found_band = false; foreach ($age_band_data as $age_bands) { if ($found_band) break; foreach ($age_bands as $age_band) { //get Min and Max Age list($min_age, $max_age) = $this->getAgeRange($age_band); // If age fits in this band if ($age >= $min_age && $age <= $max_age) { // Update counts for general category if (isset($classifiers['general'][$relation][$age_band])) { // Increment count for specific relation and age band $classifiers['general'][$relation][$age_band]++; // Update row total (Grand Total column) $classifiers['general'][$relation]['Grand Total']++; // Update column total (Grand Total row) $classifiers['general']['Grand Total'][$age_band]++; // Update grand total of grand totals $classifiers['general']['Grand Total']['Grand Total']++; } // Update counts for specific SI category if (isset($classifiers[$member_si][$relation][$age_band])) { // Increment count for specific relation and age band $classifiers[$member_si][$relation][$age_band]++; // Update row total (Grand Total column) $classifiers[$member_si][$relation]['Grand Total']++; // Update column total (Grand Total row) $classifiers[$member_si]['Grand Total'][$age_band]++; // Update grand total of grand totals $classifiers[$member_si]['Grand Total']['Grand Total']++; } $found_band = true; break; } } } } return $classifiers; } public function generateClassifierSpreadsheet($classifiers, $outputDir = 'exports') { if (!file_exists($outputDir)) { if (!mkdir($outputDir, 0755, true)) { throw new Exception("Failed to create directory: $outputDir"); } } // Check if directory is writable if (!is_writable($outputDir)) { throw new Exception("Directory is not writable: $outputDir"); } // Generate unique filename $timestamp = date('Y-m-d_His'); $filename = "member_classification_{$timestamp}.xlsx"; $filepath = $outputDir . DIRECTORY_SEPARATOR . $filename; // Check if file already exists (shouldn't happen with timestamp, but just in case) if (file_exists($filepath)) { $counter = 1; while (file_exists($outputDir . DIRECTORY_SEPARATOR . "member_classification_{$timestamp}_{$counter}.xlsx")) { $counter++; } $filename = "member_classification_{$timestamp}_{$counter}.xlsx"; $filepath = $outputDir . DIRECTORY_SEPARATOR . $filename; } $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setTitle('Demography_Data'); // Get all age bands $age_bands = array_keys(reset($classifiers['general'])); array_pop($age_bands); // Remove 'Grand Total' $age_bands[] = 'Grand Total'; // Add it back at the end $currentRow = 5; // Start from row 5 to match the example // Function to write section data $writeSectionData = function ($data, $sheet, &$currentRow, $si_type) use ($age_bands) { // Add section header for the SI type $sheet->setCellValue('B' . $currentRow, strtoupper($si_type)); // Style section header $sheet->getStyle('B' . $currentRow)->applyFromArray([ 'font' => ['bold' => true, 'size' => 14], 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], ]); $currentRow++; // Move to the next row after the section header // Set headers for the data table $sheet->setCellValue('B' . $currentRow, 'Relationship'); $col = 'C'; foreach ($age_bands as $band) { $sheet->setCellValue($col . $currentRow, $band); $col++; } // Style headers $lastCol = chr(ord('B') + count($age_bands)); $headerRange = 'B' . $currentRow . ':' . $lastCol . $currentRow; $sheet->getStyle($headerRange)->applyFromArray([ 'font' => ['bold' => true], 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => '000000'], ], ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, ], ]); $currentRow++; // Write data rows foreach ($data as $relation => $values) { if ($relation !== 'Grand Total') { $sheet->setCellValue('B' . $currentRow, $relation); $col = 'C'; foreach ($age_bands as $band) { $value = $values[$band] ?: ''; // Convert 0 to empty string $sheet->setCellValue($col . $currentRow, $value); $col++; } // Style data row $dataRange = 'B' . $currentRow . ':' . $lastCol . $currentRow; $sheet->getStyle($dataRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => '000000'], ], ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, ], ]); $currentRow++; } } // Add Grand Total row $sheet->setCellValue('B' . $currentRow, 'Grand Total'); $col = 'C'; foreach ($age_bands as $band) { $sheet->setCellValue($col . $currentRow, $data['Grand Total'][$band]); $col++; } // Style Grand Total row $totalRange = 'B' . $currentRow . ':' . $lastCol . $currentRow; $sheet->getStyle($totalRange)->applyFromArray([ 'font' => ['bold' => true], 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => '000000'], ], ], 'fill' => [ 'fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => 'F2F2F2'], ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, ], ]); $currentRow += 3; // Add gap after each section }; // Write each SI section with gaps foreach ($classifiers as $si_type => $data) { $writeSectionData($data, $sheet, $currentRow, $si_type); } // Auto-size columns foreach (range('B', chr(ord('B') + count($age_bands))) as $col) { $sheet->getColumnDimension($col)->setAutoSize(true); } // Create Excel file try { // Create Excel file $writer = new Xlsx($spreadsheet); $writer->save($filepath); // Verify file was created successfully if (!file_exists($filepath)) { throw new Exception("Failed to create file: $filepath"); } // Return the file info after creation $response = [ 'success' => true, 'filepath' => $filepath, 'filename' => $filename, 'fullpath' => realpath($filepath) ]; return $response; } catch (Exception $e) { return [ 'success' => false, 'error' => $e->getMessage() ]; } } // Function to delete generated file public function deleteGeneratedFile($filePath) { try { if (file_exists($filePath)) { unlink($filePath); // Delete the file return [ 'success' => true, 'message' => "File deleted successfully" ]; } else { return [ 'success' => false, 'message' => "File does not exist" ]; } } catch (Exception $e) { return [ 'success' => false, 'error' => $e->getMessage() ]; } } public function getAge($available_col, $member, $col_index) { if ($available_col == 'age') { $age = $member[$col_index]; } else { $dob = $member[$col_index]; if ($dob == 'DOB') { return; } $dobDate = \DateTime::createFromFormat('d-M-Y', $dob); $currentDate = new \DateTime(); if ($dobDate == false) { $this->myLogger->logme('error', $dob . 'is not valid'); return; } $age = $currentDate->diff($dobDate)->y; } return $age; } public function getAgeRange($age_band) { $age_band = trim($age_band); // Parse age range if (strpos($age_band, '-') === false) { $min_age = (int)filter_var($age_band, FILTER_SANITIZE_NUMBER_INT); $max_age = PHP_INT_MAX; } else { $parts = explode("-", $age_band); $min_age = (int)$parts[0]; $max_age = (int)$parts[1]; } return array($min_age, $max_age); } //this funciton for send mail to insurer and client with either RFQ/QCR public function sendMailWithAttachement() { helper('excel_util_helper'); helper('MailHelper'); helper('ExcelMergeHelper'); $params = $this->request->getPost(); // print_r($params); die; $lead_id = $params['lead_id']; $file_type = $params['file_type']; //rfq or qcr $recipient_type = $params['recipient_type']; //insurer or client or internal or placement $recipient_mail = $params['recipient_mail']; // - only primary key of contacts $recipient_mail = json_decode($params['recipient_mail'], true); // - only primary key of contacts $propsal_and_insurer = isset($params['proposal_insurer']) ? $params['proposal_insurer'] : null; $mail_content = $params['mail_content']; $mail_subject = $params['subject']; $result_data = []; // dd($recipient_mail); if ($recipient_type == 'insurer' && (!is_array($recipient_mail) || count($recipient_mail) == 0)) { return $this->respond(['status' => 'failed', 'code' => 400, 'data' => '', 'messgae' => 'Recipient mail not found ! '], 200); } // dd(); //gather lead info $lead_data = $this->leadsModel ->select('leads.*,policy_type.long_name,policy_type.policy_type,user_profiles.email as created_person_email') ->join('policy_type', 'leads.policy_type_id = policy_type.id', 'left') ->join('user_profiles', 'leads.created_by = user_profiles.id', 'left') ->where('leads.id', $lead_id) ->first(); // print_r($lead_data ); die; $cc_mails = []; $bcc_mails = []; //get CC Mails if ($recipient_type == 'internal' || $recipient_type == 'placement' || $recipient_type == 'insurer' || $recipient_type == 'client') { $cc_data = isset($params['cc']) ? $params['cc'] : ""; $param_cc_mail = json_decode($cc_data, true); if (isset($param_cc_mail) && is_array($param_cc_mail) && count($param_cc_mail) > 0) { // Fetch user data where ID is in the param_cc_mail array $userData = $this->userModel ->where('is_active', 1) ->whereIn('id', $param_cc_mail) ->findAll(); // print_r($userData); die; // Extract emails from the fetched user data $cc_mails = array_column($userData, 'email'); // print_r(json_encode($cc_mails)); die; // If no emails were found, return an error response // if (empty($cc_mails)) { // return $this->respond(['status' => 'failed','code' => 400,'data' => '','message' => 'No valid CC mail addresses found!'], 200); // } } else { // Handle case where param_cc_mail is not valid // return $this->respond(['status' => 'failed','code' => 400,'data' => '','message' => 'CC mail not found!'], 200); } } //get BCC Mails if ($recipient_type == 'insurer' || $recipient_type == 'client') { $bcc_data = isset($params['bcc']) ? $params['bcc'] : ""; $param_bcc_mail = json_decode($bcc_data, true); if (isset($param_bcc_mail) && is_array($param_bcc_mail) && count($param_bcc_mail) > 0) { // Fetch user data where ID is in the param_cc_mail array $userData = $this->userModel ->where('is_active', 1) ->whereIn('id', $param_bcc_mail) ->findAll(); // print_r($userData); die; // Extract emails from the fetched user data $bcc_mails = array_column($userData, 'email'); // print_r(json_encode($cc_mails)); die; // If no emails were found, return an error response // if (empty($cc_mails)) { // return $this->respond(['status' => 'failed','code' => 400,'data' => '','message' => 'No valid CC mail addresses found!'], 200); // } } else { // Handle case where param_cc_mail is not valid // return $this->respond(['status' => 'failed','code' => 400,'data' => '','message' => 'CC mail not found!'], 200); } } if ($recipient_type == 'client' && ($lead_data['contact_person_email'] == '' || $lead_data['contact_person_email'] == null)) { return $this->respond(['status' => 'failed', 'code' => 400, 'data' => '', 'messgae' => 'Recipient mail not found ! '], 200); } // dd($lead_data); $reply_to = $lead_data['created_person_email'] ?? ""; //get file path to attach if ($lead_data["lead_form_type"] == 2) { $file_info = $this->constructNonEbExcelToSaveTemp($lead_id, ($file_type == 'rfq' ? 1 : 2), $propsal_and_insurer); } else { $file_info = $this->constructExcelToSaveTemp($lead_id, ($file_type == 'rfq' ? 1 : 2), $propsal_and_insurer); } // $file_info = $this->constructExcelToSaveTemp($lead_id, ($file_type == 'rfq' ? 1 : 2), $propsal_and_insurer); log_message('error', 'File Info' . json_encode($file_info)); if ($lead_data['file_name'] != null && $lead_data['file_name'] != '') { $temp_file_path = $file_info['filePath']; $temp_file_name = $file_info['fileName']; $lead_file_path = WRITEPATH . 'uploads/lead_files/' . $lead_data['file_name']; if ($lead_file_path) { $filePaths = [ ['file_path' => $temp_file_path, 'sheets' => []], ['file_path' => $lead_file_path, 'sheets' => []] ]; $outputPath = dirname($temp_file_path) . '/' . 'merged_' . $temp_file_name; $result = ExcelMergeHelper::mergeExcelFiles($filePaths, $outputPath); // print_rr($result); } } else { $result = $file_info['filePath']; // return $this->respond(['status' => 'fail', 'code' => 200, 'messgae' => 'File Not Found'], 200); } // print_rr($result); die; // print_rr($file_info); // $file_path = WRITEPATH."uploads/excel/sample/correction.xls"; // $file_name = $file_type.'.xlsx'; // !dd($file_info); $file_path = $result; $file_name = basename($result); $attachments = [['fileName' => $file_name, 'filePath' => $file_path]]; //get recipient address if ($recipient_type == 'insurer' || $recipient_type == 'placement') { // print_r($recipient_mail); die; $recipient_data = $this->levelContactModel ->where(['contact_type' => 'insurer', 'is_active' => 1]) ->whereIn('id', $recipient_mail) ->findAll(); // print_r($recipient_data); die; } else if ($recipient_type == 'client') { $recipient_data = [['name' => $lead_data['contact_person_name'], 'email' => $lead_data['contact_person_email']]]; } else { $recipient_data = [['name' => "Team", 'email' => $params['to']]]; } // print_r($recipient_data); die; $subject = $file_type == 'rfq' ? 'Request for Quotation from ' . $lead_data['client_name'] . ' for ' . $lead_data['policy_type'] : 'Quotation Comparison Report for ' . $lead_data['policy_type']; $original_message = '

Request for Quotation (RFQ)

Dear {{RECIPIENT_NAME}},

We are reaching out to request a quotation for the following insurance coverage. Please review the details below and provide your quote at your earliest convenience.

RFQ Details

Client name{{CLIENT_NAME}}
Coverage Type{{POLICY_LONG_NAME}}
Policy Start Date{{POLICY_START_DATE}}
Policy Duration{{DURATION}}
Please note: Additional terms and details are included in the attachment for your reference.

Please feel free to reach out if you require any further information to prepare the quote. We look forward to receiving your proposal.

Best regards,

Nhance India Pvt Ltd

© Nhance India Pvt Ltd. All rights reserved.

'; //for mail content if (!empty($mail_content)) { $original_message = $mail_content; } //for mail subject if (!empty($mail_subject)) { $subject = $mail_subject; } // print_r($subject); die; if ($recipient_data) { foreach ($recipient_data as $recipient) { $message = $original_message; $message = str_replace("{{RECIPIENT_NAME}}", $recipient['name'], $message); $message = str_replace("{{CLIENT_NAME}}", $lead_data['client_name'], $message); $message = str_replace("{{POLICY_LONG_NAME}}", $lead_data['long_name'], $message); $message = str_replace("{{POLICY_START_DATE}}", change_date_format($lead_data['policy_start_date'], 'Y-m-d', 'd-m-Y'), $message); $message = str_replace("{{DURATION}}", calculate_days_bw_dates($lead_data['policy_end_date'] ?? "", $lead_data['policy_start_date'] ?? "")->days, $message) ?? '--'; // print_rr($message);calculate_days_bw_dates $string = implode(", ", $cc_mails); $bcc_string = implode(", ", $bcc_mails); $res = MailHelper::send_email(['mail' => $recipient['email'], 'cc' => $string, 'subject' => $subject, 'message' => $message, 'attachments' => $attachments, 'reply_to' => $reply_to, 'bcc' => $bcc_string]); // !dd($res); $result_data[] = ['mail' => $recipient['email'], 'status' => $res]; } } if ($recipient_type == 'placement') { list($proposal_key, $insurer_key) = explode('-', $propsal_and_insurer, 2); $lead_update_data = [ 'proposel_name' => $proposal_key, 'insurer_name' => $insurer_key, 'insurer' => $params['insurer_and_branch'], ]; $data = [ 'proposel_data' => json_encode($lead_update_data), 'status' => 'won', 'placement_date' => change_date_format($params['placement_date'], 'd/m/Y', 'Y-m-d'), 'utr_no' => $params['utr_no'], 'premium_amount' => $params['premium_amount'], 'total_amount' => $params['total_amount'], 'cd_amount' => $params['cd_amount'], ]; $this->leadsModel->where('id', $lead_id)->set($data)->update(); } //delete attachment file unlink($file_path); return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result_data], 200); } public function getLevelContects() { $data = $this->levelContactModel->getContactForRFQ(); if ($data) { return $this->respond(['status' => true, 'data' => $data], 200); } else { return $this->respond(['status' => false], 200); } } public function getInsurerBranchContacts($insurer_and_branch_id) { if (strpos($insurer_and_branch_id, '-') === false) { return $this->respond(['status' => false, 'message' => 'Invalid ID format'], 400); } // Split the insurer_and_branch_id list($insurerBranchId, $insurerId) = explode('-', $insurer_and_branch_id); $data = $this->levelContactModel->getContactForRFQ($insurerId, $insurerBranchId); if (!empty($data)) { return $this->respond(['status' => true, 'data' => $data], 200); } else { return $this->respond(['status' => false, 'data' => $data, 'message' => 'No contacts were found for the selected insurer.'], 200); } } public function transformProposelData($data, $proposel, $insurer) { // print_r($data['premium_data']['data']); die; $headerData = []; // Default headers: S. No and Particulars $defaultHeaders = [ [ 'parentHeader' => 'Sno', 'subHeaders' => ['-'] ], [ 'parentHeader' => 'Particulars', 'subHeaders' => ['-'] ] ]; // Add default headers to the result $headerData = array_merge($headerData, $defaultHeaders); foreach ($data['table_data']['headers'] as $header) { // Check if the parentHeader matches the target proposal if ($header['parentHeader'] === $proposel) { // Check if subHeaders contain the target insurer key foreach ($header['subHeaders'] as $subHeader) { if ($subHeader === $insurer) { $headerData[] = [ 'parentHeader' => $header['parentHeader'], 'subHeaders' => [ 'Quote Asked', // Default value $subHeader // Matched insurer key ] ]; break; } } } } $columnData = []; foreach ($data['table_data']['data'] as $entry) { $sno = $entry['SNO']; $items = $entry['items']; $dataEntry = $entry['data']; $result = [ "SNO" => $sno, "items" => $items, "data" => [] ]; foreach ($dataEntry as $item) { // Include Sno and Particulars by default if (in_array($item['parentth'], ['Sno', 'Particulars'])) { $result['data'][] = [ "parentth" => $item['parentth'], "subth" => $item['subth'], "value" => $item['value'], "input_value" => $item['input_value'] ]; } // Include Proposal with Quote Asked by default if ($item['parentth'] === $proposel && $item['subth'] === "Quote Asked") { $result['data'][] = [ "parentth" => $item['parentth'], "subth" => $item['subth'], "value" => $item['value'], "input_value" => $item['input_value'] ]; } // Example of including matching specific proposals and insurers if ($item['parentth'] === $proposel && $item['subth'] === $insurer) { $result['data'][] = [ "parentth" => $item['parentth'], "subth" => $item['subth'], "value" => $item['value'], "input_value" => $item['input_value'] ]; } } // Add to the final result $columnData[] = $result; } $premiumData = []; foreach ($data['premium_data']['data'] as $key => $value) { if ($key === $proposel) { $premiumData[$key]['Quote Asked'] = $value['Quote Asked']; $premiumData[$key][$insurer] = $value[$insurer]; } } $data['table_data']['headers'] = $headerData; $data['table_data']['data'] = $columnData; $data['premium_data']['data'] = $premiumData; return $data; } public function convertJsonForQCR($json, $type) { if ($json) { // Deep copy of JSON $first_json = json_decode(json_encode($json), true); // dd($first_json); if ($type == 2) { // Column-wise Check: Remove headers and relevant data if qcr == 0 foreach ($json['proposal_data']['over_all_column_data'] as $proposalKey => $proposalData) { if (($proposalData['qcr'] == 0 || $proposalData['qcr'] === false) || ($proposalData['stc'] == 0 || $proposalData['stc'] === false)) { // Remove matching parentHeader in headers foreach ($first_json['table_data']['headers'] as $index => $header) { if ($header['parentHeader'] === $proposalKey) { unset($first_json['table_data']['headers'][$index]); } } // Remove data entries with matching parentth foreach ($first_json['table_data']['data'] as &$item) { $item['data'] = array_values(array_filter($item['data'], function ($entry) use ($proposalKey) { return $entry['parentth'] !== $proposalKey; })); } // Remove proposalKey from over_all_column_data unset($first_json['proposal_data']['over_all_column_data'][$proposalKey]); if ($type == 2) { // Remove proposalKey from premium_data unset($first_json['premium_data']['data'][$proposalKey]); } } // Insurer Check: Remove subHeaders and relevant data for insurers with qcr == 0 foreach ($proposalData['insurers'] as $insurerIndex => $insurer) { if (($insurer['qcr'] === 0 || $insurer['qcr'] === false) || ($insurer['stc'] === 0 || $insurer['stc'] === false)) { foreach ($first_json['table_data']['headers'] as &$header) { if (isset($header['subHeaders'])) { $header['subHeaders'] = array_values(array_filter($header['subHeaders'], function ($sub) use ($insurer) { return $sub !== $insurer['display_name']; })); } } foreach ($first_json['table_data']['data'] as &$item) { $item['data'] = array_values(array_filter($item['data'], function ($entry) use ($insurer) { return $entry['subth'] !== $insurer['display_name']; })); } // Remove insurer from proposal's insurers array unset($first_json['proposal_data']['over_all_column_data'][$proposalKey]['insurers'][$insurerIndex]); if ($type == 2) { unset($first_json['premium_data']['data'][$proposalKey][$insurer['display_name']]); } } } } // Row-wise Check: Remove rows if qcr == 0 for actions foreach ($first_json['table_data']['data'] as $rowKey => $rowData) { foreach ($rowData['data'] as $data) { if ($data['parentth'] === "Action" && (isset($data['input_value']['qcr']) && $data['input_value']['qcr'] == 0) || (isset($data['input_value']['stc']) && $data['input_value']['stc'] == 0)) { unset($first_json['table_data']['data'][$rowKey]); break; } } } // Reindex arrays to maintain proper structure $first_json['table_data']['headers'] = array_values($first_json['table_data']['headers']); $first_json['table_data']['data'] = array_values($first_json['table_data']['data']); $first_json['proposal_data']['over_all_column_data'] = array_map(function ($proposal) { $proposal['insurers'] = array_values($proposal['insurers']); return $proposal; }, $first_json['proposal_data']['over_all_column_data']); } else { //remove insurer as Subheaders for RFQ foreach ($first_json['table_data']['headers'] as &$header) { $header['subHeaders'] = array_filter($header['subHeaders'], function ($subHeader) { return in_array($subHeader, ['Quote Asked', '-']); }); } //Remove insurer Row wise data for RFQ foreach ($first_json['table_data']['data'] as &$row) { // Filter the inner data array $row['data'] = array_filter( $row['data'], function ($item) { return in_array($item['subth'], ['Quote Asked', '-']); } ); $row['data'] = array_values($row['data']); } // Ensure to unset the reference after the loop unset($row); // Remove insurers from Proposal Data key for RFQ foreach ($first_json['proposal_data']['over_all_column_data'] as $key => &$proposal) { if (isset($proposal['insurers'])) { // Set the insurers array to empty $proposal['insurers'] = []; } } // Ensure to reset the reference unset($proposal); } return $first_json; } return null; } //----- Featch Lead data and insert Client ------------------------------------------------------------------------------------------- public function featchLeadDataAndInsertClient($lead_id) { $data = $this->leadsModel->where('leads.id', $lead_id)->where('leads.is_active', 1)->first(); if (!$data) { return $this->respond(['status' => false, 'message' => 'Failed to create Client', 'data' => null], 200); } $result = $this->createClientWithLeadData($data); if ($result) { $policy_data = $this->clientPolicyModel->where('client_id', $result)->where('is_active', 1)->first(); return $this->respond(['status' => true, 'message' => 'New Client created successfully', 'client_id' => $result, 'data' => $data, 'client_policy_id' => $policy_data['id']], 200); } return $this->respond(['status' => false, 'message' => 'Failed to create client', 'data' => $data], 200); } public function createClientWithLeadData($data) { $client_data = $this->prepareClientData($data); $client_id = $this->clientModel->insert($client_data); if ($client_id) { $this->createClientBranchAndContactWithLeadData($data, $client_id); $this->leadsModel->where('id', $data['id'])->set('is_client_created', $client_id)->update(); } return $client_id; } private function prepareClientData($data) { return [ 'client_type' => $data['client_type'], 'entity_type_id' => $data['entity_type_id'], 'client_code' => $data['client_code'], 'client_name' => $data['client_name'], 'short_name' => $data['client_short_name'], 'pan' => $data['pan'], ]; } public function createClientBranchAndContactWithLeadData($data, $client_id) { $branch_data = $this->prepareClientBranchData($data, $client_id); $branch_id = $this->clientBranchModel->insert($branch_data); if ($branch_id) { $this->leadsModel->where('id', $data['id'])->set('is_client_created', $client_id)->update(); $contact_data = $this->prepareContactData($data, $branch_id); $this->levelContactModel->insert($contact_data); $this->createClientPolicyWithLeadData($data, $client_id, $branch_id); } return $branch_id; } private function prepareClientBranchData($data, $client_id) { $default_unit = trim(($data['client_short_name'] ?? '') . '-' . ($data['branch_code'] ?? ''), '-'); return [ 'client_id' => $client_id, 'branch_name' => $data['branch_name'], 'branch_code' => $data['branch_code'], 'gst' => $data['gst'], 'units' => json_encode([$default_unit]), ]; } private function prepareContactData($data, $branch_id) { return [ 'name' => $data['contact_person_name'], 'mobile' => $data['contact_person_mobile'], 'email' => $data['contact_person_email'], 'contact_type' => 'client', 'ref_id' => $branch_id, ]; } public function createClientPolicyWithLeadData($data, $client_id, $branch_id) { $client_policy_data = $this->prepareClientPolicyData($data, $client_id, $branch_id); $client_policy_id = $this->clientPolicyModel->insert($client_policy_data); if ($client_policy_id) { $this->leadsModel->where('id', $data['id'])->set('is_client_created', $client_id)->update(); } return $client_policy_id; } private function prepareClientPolicyData($data, $client_id, $branch_id) { $proposel_data = json_decode($data['proposel_data'], true); // print_r($proposel_data); die; list($insurer_branch_id, $insurer_id) = explode('-', $proposel_data['insurer'], 2); $client_policy_data = [ 'client_id' => $client_id, 'client_branch_id' => $branch_id, 'policy_type_id' => $data['policy_type_id'], 'insurer_id' => $insurer_id, 'insurer_branch_id' => $insurer_branch_id, 'tpa_id' => $data['tpa_id'], 'tpa_branch_id' => $data['tpa_branch_id'], 'policy_start_date' => $data['policy_start_date'], 'policy_end_date' => $data['policy_end_date'], 'policy_status' => 1, ]; $terms = $this->preparePolicyTermsFromRFQ($data); $policy_type_id = $data['policy_type_id']; if (in_array($policy_type_id, [1, 2, 6, 7])) { $client_policy_data['is_addon'] = 1; // Base Policy } elseif (in_array($policy_type_id, [4, 5])) { $client_policy_data['is_addon'] = 2; // SI TOPUP } elseif ($policy_type_id == 3) { // if ($base_policy) { // $data['is_addon'] = 3; // Dependent Addon // } else { $data['is_addon'] = 1; // } } $client_policy_data['policy_terms'] = $this->preparePolicyTermsFromRFQ($data); // print_r($client_policy_data); die; return $client_policy_data; } private function preparePolicyTermsFromRFQ($data) { $proposel_data = json_decode($data['proposel_data'], true); $QCRData = $this->RFQModel->where('is_active', 1)->where('type', 2)->where('lead_id', $data['id'])->first(); $JSON = json_decode($QCRData['json'], true); $converted_json = $this->transformProposelData($JSON, $proposel_data['proposel_name'], $proposel_data['insurer_name']); return $this->convertQCRJsonToPolicyTerms($converted_json, $data['policy_type_id'], $proposel_data['proposel_name'], $proposel_data['insurer_name']); } //Function for convert the RFQ and QCR Json to Policy Terms Json public function convertQCRJsonToPolicyTerms($data, $policy_type, $proposel_name, $insurer_name) { //transform the data into the currernt proposel and insurere ( get single proposel ) $data = $this->transformProposelData($data, $proposel_name, $insurer_name); // Initialize age_ratio based on policy type $age_ratio = $policy_type == 2 ? [ 'self' => ['min' => '18', 'max' => '60'], 'spouse' => ['min' => 0, 'max' => 0], 'child' => ['min' => 0, 'max' => '25'], 'elders' => ['min' => 0, 'max' => 0], ] : [ 'self' => ['min' => '18', 'max' => '60'] ]; foreach ($data['table_data']['data'] as $dataRow) { $item = $dataRow['items'] ?? ''; foreach ($dataRow['data'] as $cellData) { $parentth = $cellData['parentth'] ?? ''; $subth = $cellData['subth'] ?? ''; $input_value = $cellData['input_value'] ?? ''; $value = $cellData['value'] ?? ''; // Skip unwanted keys if (in_array($parentth, ['Sno', 'Item Key', 'Particulars', 'Action']) || in_array($subth, ['Quote Asked'])) { continue; } switch (true) { // CASE 1: Handle special conditions case str_starts_with($item, 'special_condition') && $parentth === $proposel_name && $subth === $insurer_name: $parts = explode('-', $input_value); $labelKey = $policy_type == 1 ? 'gpa_special_condition_label' : 'special_condition_label'; $inputKey = $policy_type == 1 ? 'gpa_special_condition_input' : 'special_condition_input'; $terms_array[$labelKey][] = $parts[0] ?? ''; $terms_array[$inputKey][] = $parts[1] ?? ''; break; // CASE 2: Handle sum insured case in_array($item, ['sum_insured', 'sumInsured2']): $si_amt = explode(',', $value); $terms_array[$item] = $si_amt[0] ?? ''; $terms_array['multiple_sum_insured'] = array_slice($si_amt, 1); // Add age_ratio after Sum insured if ($policy_type == 1) { $terms_array['age_ratio'] = $age_ratio; } break; // CASE 3: Handle family floaters case $item === 'family_composition': $terms_array['family_floaters'] = isJsonString($input_value) ? json_decode($input_value, true) : $input_value; // Add age_ratio after family floaters if ($policy_type == 2) { $terms_array['age_ratio'] = $age_ratio; } break; // DEFAULT CASE : default: // $terms_array[$item] = isJsonString($input_value) ? (json_decode($input_value, true)['key'] ?? '') : $value; $terms_array[$item] = $value; break; } } } return json_encode($terms_array); } public function featchClientPolicyFromLead($client_id, $branch_id, $lead_id) { $data = $this->leadsModel->where('leads.id', $lead_id)->where('leads.is_active', 1)->first(); if (!$data) { return $this->respond(['status' => false, 'message' => 'Failed to create policy', 'data' => null], 200); } $result = $this->createClientPolicyWithLeadData($data, $client_id, $branch_id); // print_r($result); die; if ($result) { $policy_data = $this->clientPolicyModel->where('id', $result)->where('is_active', 1)->first(); return $this->respond(['status' => true, 'message' => 'New Policy created successfully', 'client_policy_id' => $result, 'data' => $data, 'client_id' => $policy_data['client_id']], 200); } return $this->respond(['status' => false, 'message' => 'Failed to create policy', 'data' => $data], 200); } //------------------------------------------------------------------------------------------------ public function transformMailContent($lead_data, $mail_content, $page_name) { $current_year = date('Y'); $next_year = $current_year + 1; $policy_year = "$current_year-$next_year"; if ($lead_data) { // Replacing placeholders with actual values $message = $mail_content; $message = str_replace("{{CLIENT_NAME}}", $lead_data['client_name'] ?? "Valued Client", $message); $message = str_replace("{{POLICY_LONG_NAME}}", $lead_data['long_name'] ?? $lead_data['policy_type'] ?? "Insurance Policy", $message); $message = str_replace("{{POLICY_TYPE}}", $lead_data['policy_type'] ?? "Insurance Policy", $message); $message = str_replace("{{RFQ_OR_QCR}}", $page_name, $message); $message = str_replace("{{POLICY_YEAR}}", $policy_year, $message); return $message; } else { return ''; // Return empty if no lead data found } } function getLastFiveFinancialYears() { $currentYear = date('Y'); $currentMonth = date('m'); // In India, the financial year starts from April (04) if ($currentMonth < 4) { $currentYear--; // Adjust year if it's Jan-Mar } $financialYears = []; for ($i = 0; $i < 5; $i++) { $startYear = $currentYear - $i - 1; $endYear = $currentYear - $i; $financialYears[] = "$startYear-$endYear"; } return $financialYears; } // ------------ RFQ NON EB FUNCTIONS----------------------------------------------------------------------------------------- public function rfqNonEB() { $this->loadLayout('view_rfq_non_eb'); } public function getLeadNonEB($type, $id = null) { // Set basic data $data = [ 'issuer' => $this->issuer, 'client_type' => $this->clientType, 'lead_type' => $this->leadType, 'lead_status' => $this->leadsStatus, 'policy_type' => $this->policyTypeModel->where('is_active', 1)->findAll(), 'entity' => $this->kycEntityTypeModel->where('is_active', 1)->findAll(), 'insurer' => $this->insurerBranchModel->getInsurerBranchesWithInsurerNames(), 'tpa' => $this->tpaBranchModel->getTpaBranchesWithTpaNames(), 'lastFiveYears' => $this->getLastFiveFinancialYears(), 'gpaClaimType' => $this->claim_type_for_gpa, 'causeOfDeath' => $this->cause_of_death, 'selected_lead_type' => $type, ]; // Fetch sales team members who are active in team 5 $data['salse_team'] = $this->userModel ->select('user_profiles.*') ->join('user_teams', 'user_profiles.id = user_teams.user_id') ->where('user_teams.team_id', 5) ->where('user_teams.is_active', 1) ->where('user_profiles.is_active', 1) ->findAll(); if (!empty($id)) { $data['lead_edit_data'] = $this->leadsModel->where('id', $id)->first() ?? []; // Decode and merge custom fields if present $custom_fields_data = !empty($data['lead_edit_data']['custom_fields']) ? json_decode($data['lead_edit_data']['custom_fields'], true) : []; if (!empty($custom_fields_data) && is_array($custom_fields_data)) { $data['lead_edit_data'] = array_merge($data['lead_edit_data'], $custom_fields_data); } if (!empty($data['lead_edit_data'])) { foreach (['policy_start_date', 'policy_end_date', 'incurred_claims_date', 'premium_date'] as $dateField) { $data['lead_edit_data'][$dateField] = !empty($data['lead_edit_data'][$dateField]) ? change_date_format($data['lead_edit_data'][$dateField], 'Y-m-d', 'd/m/Y') : null; } $data['lead_edit_data']['fin_years_claims_array'] = !empty($data['lead_edit_data']['fin_years_claims']) ? json_decode($data['lead_edit_data']['fin_years_claims'], true)['finyear'] ?? [] : []; $data['lead_edit_data']['html'] = $this->generateViewPageHtml( $data['lead_edit_data']['policy_type_id'] ?? null, $data ) ?? ""; } if ($data['lead_edit_data']['lead_type'] != 1 && $data['lead_edit_data']['lead_form_type'] == 2) { $data['lead_edit_data']['claims_details_html'] = view('rfq/claims_details_non_eb', $data['lead_edit_data']); } else { $data['lead_edit_data']['claims_details_html'] = ""; } } // dd($data); return $this->loadLayout('leads_form_handler', $data); } public function getPolicyTypeFields() { $policy_type_id = $this->request->getGET('policy_type_id'); $html = $this->generateViewPageHtml($policy_type_id) ?? ""; if (!empty($html)) { return $this->respond(['status' => true, 'code' => 200, 'message' => 'Policy Type FIELDS are found', 'data' => $html], 200); } else { return $this->respond(['status' => false, 'code' => 400, 'message' => 'Fields not found for this policy type'], 200); } } public function generateViewPageHtml($policy_type_id, $data = []) { $data['insurer'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames(); $data['tpa'] = $this->tpaBranchModel->getTpaBranchesWithTpaNames(); $viewMap = [ 1 => 'rfq/gpa', 6 => 'rfq/gpa', 7 => 'rfq/gpa', 2 => 'rfq/gmc', 3 => 'rfq/gmc', 4 => 'rfq/gmc', 5 => 'rfq/gmc', 22 => 'rfq/car', 23 => 'rfq/cpm', 24 => 'rfq/cyber_crime', 25 => 'rfq/do', 27 => 'rfq/eo', 49 => 'rfq/money', 19 => 'rfq/cgl', 59 => 'rfq/sfsp', 63 => 'rfq/wc', 15 => 'rfq/blu', 16 => 'rfq/bsu', 44 => 'rfq/marine', 45 => 'rfq/marine', 46 => 'rfq/marine', 47 => 'rfq/marine', 50 => 'rfq/office' ]; return isset($viewMap[$policy_type_id]) ? view($viewMap[$policy_type_id], $data) : ""; } // ------------------- RFQ NON EB EXCEL EXPORT FUNCTION --------------------------------------------------------------------------------------- public function constructNonEbExcelToSaveTemp($lead_id, $type, $propsal_and_insurer = null) { $rfq_data = $this->RFQModel->getRFQTableDataWithLeadIDAndType($lead_id, $type); $lead_data = json_decode($rfq_data['custom_fields'], true) ?? []; if (!is_array($lead_data)) { $lead_data = []; } $lead_data = array_merge(['Insured' => $rfq_data['client_name']], $lead_data); $policy_registration_data = []; if(isset($rfq_data['registration_json']) && !empty($rfq_data['registration_json'])){ $policy_registration_data = json_decode($rfq_data['registration_json'], true); } // dd($policy_registration_data); // if(!empty($rfq_data['fin_years_claims'])){ // $claim_details = json_decode($rfq_data['fin_years_claims'], true) ?? []; // if(!empty($claim_details['finyear'])){ // $lead_data['claim_details'] = $claim_details['finyear']; // } // Kint::dump($claim_details); // } $jsonData = json_decode($rfq_data['json'], true); $proposalData = end($jsonData); array_pop($jsonData); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Start with lead_data at the top $rowNumber = 1; $title = "Nhance India Insurance Broking Pvt Ltd"; $mergeRange1 = "A{$rowNumber}:B{$rowNumber}"; $sheet->mergeCells($mergeRange1); $sheet->setCellValue("A{$rowNumber}", $title); $sheet->getStyle("A{$rowNumber}")->applyFromArray([ 'font' => [ 'bold' => true, 'size' => 20 ], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], ]); // Calculate title width $maxWidthA = mb_strlen($title); // Set column width to fit the image properly $sheet->getColumnDimension('C')->setWidth(20); // Adjust as needed $sheet->getRowDimension($rowNumber)->setRowHeight(40); // Adjust as needed $drawing = new Drawing(); $path = ROOTPATH . "public/assets/images/Nhance-Logo-Final.png"; // Use FCPATH for server path $drawing->setPath($path); $drawing->setCoordinates("C{$rowNumber}"); // Set position in column C $drawing->setHeight(35); // Adjust image height // Center align the image in the cell $drawing->setOffsetX(30); // Adjust horizontal offset $drawing->setOffsetY(5); // Adjust vertical offset $drawing->setWorksheet($sheet); // Apply center alignment to the cell $sheet->getStyle("C{$rowNumber}")->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER); $sheet->getStyle("C{$rowNumber}")->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER); $rowNumber++; // Initialize max width tracking variables $maxWidthB = 0; foreach ($lead_data as $key => $value) { $formattedKey = ucwords(str_replace('_', ' ', $key)); // Merge A:B for key $mergeRangeKey = "A{$rowNumber}:B{$rowNumber}"; $sheet->mergeCells($mergeRangeKey); // Set values in merged cells $sheet->setCellValue("A{$rowNumber}", $formattedKey); $sheet->setCellValue("C{$rowNumber}", $value); // Apply styles for alignment and bold text in A:B $sheet->getStyle($mergeRangeKey)->applyFromArray([ 'font' => ['bold' => true], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], ]); // Apply bold style to C column if the key is "Insured" // if ($key === "Insured") { // $sheet->getStyle("C{$rowNumber}")->applyFromArray([ // 'font' => ['bold' => true], // ]); // } // Track max width needed for columns $maxWidthA = max($maxWidthA, mb_strlen($formattedKey)); // Consider title and keys $maxWidthB = max($maxWidthB, mb_strlen((string) $value)); $rowNumber++; } // Set column width based on max content length (adjusted for padding) $sheet->getColumnDimension('A')->setWidth($maxWidthA * 1.2); $sheet->getColumnDimension('B')->setWidth($maxWidthA * 1.2); $sheet->getColumnDimension('C')->setWidth($maxWidthB * 1.2); $rowNumber += 2; // Kint::dump($jsonData); foreach ($jsonData as $key => $data) { // Kint::dump($data, 'First'); if ($type == 2) { $data = $this->convertNonEbJsonForQCR($data, $type, $proposalData, $key); // Kint::dump($data, 'Second'); if ($propsal_and_insurer !== null) { list($proposal_key, $insurer_key) = explode('-', $propsal_and_insurer, 2); $data = $this->transformNonEbProposelData($data, $proposal_key, $insurer_key, $key); } unset($data['proposalData']); } else if ($type == 1) { $data = $this->convertNonEbJsonForQCR($data, $type, $proposalData, $key); unset($data['proposalData']); } // dd($data); // Add headers and subheaders $headers = $data['table_data']['headers']; // dd($headers); $rowNumber = $rowNumber + 1; $subHeaderRow = $rowNumber + 1; $columnLetter = 'A'; foreach ($headers as $header) { if (in_array($header['parentHeader'], ['Action'])) { continue; } $sheet->getColumnDimension($columnLetter)->setWidth(60); if ($header['parentHeader'] == 'Policy') { // $header['parentHeader'] = 'S.No.'; $sheet->getColumnDimension('A')->setWidth(10); } if ($header['parentHeader'] === 'Particulars') { $sheet->getColumnDimension('B')->setWidth(60); } if (strpos($header['parentHeader'], 'Proposal') === 0) { $sheet->getColumnDimension('C')->setWidth(60); $sheet->getColumnDimension('D')->setWidth(35); } $startColumn = $columnLetter; // Start of the current header range $subHeaderCount = count($header['subHeaders']); // Number of subheaders for this parent header // Set parent header value $sheet->setCellValue("{$startColumn}{$rowNumber}", $header['parentHeader']); $sheet->getStyle("{$startColumn}{$rowNumber}")->applyFromArray([ 'font' => ['bold' => true], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], 'fill' => [ 'fillType' => Fill::FILL_SOLID, 'startColor' => ['rgb' => 'ADD8E6'], ], ]); // Merge header cells if it spans multiple subheaders if ($subHeaderCount > 1) { $endColumn = chr(ord($startColumn) + $subHeaderCount - 1); // Calculate the end column $sheet->mergeCells("{$startColumn}{$rowNumber}:{$endColumn}{$rowNumber}"); } else { $endColumn = $startColumn; // No merge needed if only one subheader } // Add subheaders foreach ($header['subHeaders'] as $subHeader) { $sheet->setCellValue("{$columnLetter}{$subHeaderRow}", $subHeader); if ($columnLetter != "A" && $columnLetter != "B" && $columnLetter != "C" && $columnLetter != "D") { $sheet->getColumnDimension($columnLetter)->setWidth(35); } else { $sheet->getColumnDimension('A')->setWidth(10); } $sheet->getStyle("{$columnLetter}{$subHeaderRow}")->applyFromArray([ 'font' => ['bold' => true], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], ]); $columnLetter++; // Move to the next column for subheaders } } // Apply border to the header range $headerRange = "A{$rowNumber}:" . chr(ord($columnLetter) - 1) . "{$subHeaderRow}"; $sheet->getStyle($headerRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); // Increase row height for headers and subheaders $sheet->getRowDimension($rowNumber)->setRowHeight(25); // Header row height $sheet->getRowDimension($subHeaderRow)->setRowHeight(20); // Subheader row height $rowNumber = $subHeaderRow + 2; $column_data = $data['table_data']['data']; $serial_no = 1; $maxColumnWidths = []; // Add table data rows foreach ($column_data as $dataRow) { $columnLetter = 'A'; foreach ($dataRow['data'] as $cellData) { if (in_array($cellData['parentth'], ['Action'])) { continue; } if ($cellData['parentth'] == 'SNO') { $sheet->setCellValue("{$columnLetter}{$rowNumber}", $serial_no); } else if ($cellData['parentth'] == 'Policy') { $mergeStart = $rowNumber; // Start row for merging $mergeEnd = $rowNumber + ($cellData['rowspan'] - 1); // End row for merging $sheet->setCellValue("{$columnLetter}{$mergeStart}", $dataRow['SNO']); $sheet->mergeCells("{$columnLetter}{$mergeStart}:{$columnLetter}{$mergeEnd}"); $sheet->getStyle("{$columnLetter}{$mergeStart}:{$columnLetter}{$mergeEnd}") ->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER); } else { $sheet->setCellValue("{$columnLetter}{$rowNumber}", $cellData['display_content']); } $columnLetter++; } $rowNumber++; $serial_no++; } $dataRange = "A" . ($subHeaderRow + 1) . ":" . chr(ord($columnLetter) - 1) . ($rowNumber - 1); $sheet->getStyle($dataRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); // Auto-size columns // foreach ($sheet->getColumnIterator() as $column) { // $sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true); // } $dataRange = $sheet->calculateWorksheetDimension(); $sheet->getStyle($dataRange)->getAlignment() ->setHorizontal(Alignment::HORIZONTAL_CENTER) ->setVertical(Alignment::VERTICAL_CENTER) ->setWrapText(true); $sheet->getStyle('A1')->applyFromArray([ 'alignment' => [ 'wrapText' => false, // Disables text wrapping for A1 ], ]); // Apply border to the entire sheet preg_match('/([A-Z]+)(\d+):([A-Z]+)(\d+)/', $dataRange, $matches); if ($matches) { $startColumn = $matches[1]; // A $startRow = $matches[2]; // 1 $endColumn = $matches[3]; // G $endRow = $matches[4]; // 75 // Convert column letter to index, reduce by 1, and convert back $endColumnIndex = Coordinate::columnIndexFromString($endColumn) - 1; $newEndColumn = Coordinate::stringFromColumnIndex($endColumnIndex); // Generate the new range (e.g., "A1:F75" instead of "A1:G75") $newDataRange = "{$startColumn}{$startRow}:{$newEndColumn}{$endRow}"; // $sheet->getStyle($newDataRange)->getBorders()->getAllBorders()->setBorderStyle(Border::BORDER_THIN); } $lastRow = count($lead_data) + 1; $leadRange = "A1:C{$lastRow}"; $sheet->getStyle($leadRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); } // dd($rowNumber); // Set filename $string = ($type == 2) ? 'QCR' : 'RFQ'; $filename = "{$string}_{$rfq_data['client_short_name']}_{$rfq_data['policy_type']}_" . date('YmdHis') . '.xlsx'; // Save to temporary location $uploadFilePath = WRITEPATH . 'tmp/' . $filename; $writer = new Xlsx($spreadsheet); $writer->save($uploadFilePath); return [ 'filePath' => $uploadFilePath, 'fileName' => $filename, ]; } public function convertNonEbJsonForQCR($jsonArr, $type, $proposeldata, $indexOfTheTable) { $first_json = $jsonArr; $first_json = array_merge($first_json, $proposeldata); if ($type == 2) { // Column-wise Check: Remove headers and relevant data if qcr == 0 foreach ($first_json['proposal_data']['over_all_column_data'] as $proposalKey => $proposalData) { if ((isset($proposalData['qcr']) && isset($proposalData['stc'])) && ($proposalData['qcr'] == 0 || $proposalData['qcr'] === false) || ($proposalData['stc'] == 0 || $proposalData['stc'] === false)) { // Remove matching parentHeader in headers foreach ($first_json['table_data']['headers'] as $index => $header) { if ($header['parentHeader'] === $proposalKey) { unset($first_json['table_data']['headers'][$index]); } } // Remove data entries with matching parentth foreach ($first_json['table_data']['data'] as &$item) { $item['data'] = array_values(array_filter($item['data'], function ($entry) use ($proposalKey) { return $entry['parentth'] !== $proposalKey; })); } // Remove proposalKey from over_all_column_data unset($first_json['proposal_data']['over_all_column_data'][$proposalKey]); if ($type == 2) { // Remove proposalKey from premium_data unset($first_json['premium_data']['data'][$proposalKey]); } } // Insurer Check: Remove subHeaders and relevant data for insurers with qcr == 0 foreach ($proposalData['insurers'] as $insurerIndex => $insurer) { $qcr = $insurer['qcr'] ?? null; $stc = $insurer['stc'] ?? null; if (($qcr === 0 || $qcr === false) || ($stc === 0 || $stc === false)) { foreach ($first_json['table_data']['headers'] as &$header) { if (isset($header['subHeaders'])) { $header['subHeaders'] = array_values(array_filter($header['subHeaders'], function ($sub) use ($insurer) { return $sub !== $insurer['display_name']; })); } } foreach ($first_json['table_data']['data'] as &$item) { $item['data'] = array_values(array_filter($item['data'], function ($entry) use ($insurer) { return $entry['subth'] !== $insurer['display_name']; })); } // Remove insurer from proposal's insurers array unset($first_json['proposal_data']['over_all_column_data'][$proposalKey]['insurers'][$insurerIndex]); if ($type == 2) { unset($first_json['premium_data']['data'][$proposalKey][$insurer['display_name']]); } } } } // Row-wise Check: Remove rows if qcr == 0 for actions foreach ($first_json['table_data']['data'] as $rowKey => $rowData) { foreach ($rowData['data'] as $data) { if ($indexOfTheTable == 0) { if ($data['parentth'] == "Policy" && $data['input_value'] != "Checked") { unset($first_json['table_data']['data'][$rowKey]); break; } } else { if ( isset($data['parentth'], $data['input_value']['qcr'], $data['input_value']['stc']) && $data['parentth'] === "Action" && ($data['input_value']['qcr'] == 0 || $data['input_value']['stc'] == 0) ) { unset($first_json['table_data']['data'][$rowKey]); break; } } } } // Reindex arrays to maintain proper structure $first_json['table_data']['headers'] = array_values($first_json['table_data']['headers']); $first_json['table_data']['data'] = array_values($first_json['table_data']['data']); $first_json['proposal_data']['over_all_column_data'] = array_map(function ($proposal) { $proposal['insurers'] = array_values($proposal['insurers']); return $proposal; }, $first_json['proposal_data']['over_all_column_data']); } else { //remove insurer as Subheaders for RFQ foreach ($first_json['table_data']['headers'] as &$header) { // Ensure 'subHeaders' exists and is an array before filtering if (isset($header['subHeaders']) && is_array($header['subHeaders'])) { $header['subHeaders'] = array_filter($header['subHeaders'], function ($subHeader) { return in_array($subHeader, ['Quote asked', '-'], true); }); } } //Remove insurer Row wise data for RFQ foreach ($first_json['table_data']['data'] as &$row) { // Filter the inner data array $row['data'] = array_filter( $row['data'], function ($item) { return in_array($item['subth'], ['Quote asked', '-']); } ); $row['data'] = array_values($row['data']); } // Ensure to unset the reference after the loop unset($row); // Remove insurers from Proposal Data key for RFQ foreach ($proposeldata['proposal_data']['over_all_column_data'] as $key => &$proposal) { if (isset($proposal['insurers'])) { // Set the insurers array to empty $proposal['insurers'] = []; } } // Ensure to reset the reference unset($proposal); } return $first_json; return null; } public function transformNonEbProposelData(&$data, $proposal, $insurer, $tableCount) { // Kint::dump($data, $proposal, $insurer, $tableCount); // Initialize headers with defaults $headerData = []; // Add the first two default headers only once $headerData[] = [ 'parentHeader' => $data['table_data']['headers'][0]['parentHeader'], 'subHeaders' => ['-'] ]; $headerData[] = [ 'parentHeader' => $data['table_data']['headers'][1]['parentHeader'], 'subHeaders' => ['-'] ]; $second_table_name = $data['table_data']['headers'][1]['parentHeader'] ?? ""; // Loop through the headers to find matching proposal and insurer foreach ($data['table_data']['headers'] as $header) { if ($header['parentHeader'] === $proposal) { foreach ($header['subHeaders'] as $subHeader) { if ($subHeader === $insurer) { $headerData[] = [ 'parentHeader' => $header['parentHeader'], 'subHeaders' => ['Quote asked', $subHeader] ]; break 2; // Exit both loops after match is found } } } } // Update the original data's headers $data['table_data']['headers'] = $headerData; foreach ($data['table_data']['data'] as &$entry) { $sno = $entry['SNO']; $items = $entry['items']; $row_id = $entry['row_id']; $filteredData = []; foreach ($entry['data'] as $item) { // Always include SNO and Particulars if (in_array($item['parentth'], ['S.NO', "Policy", "", 'Particulars', $second_table_name])) { $filteredData[] = $item; } // Include Proposal with Quote Asked if ($item['parentth'] === $proposal && $item['subth'] === "Quote asked") { $filteredData[] = $item; } // Include specific proposal and insurer if ($item['parentth'] === $proposal && $item['subth'] === $insurer) { $filteredData[] = $item; } } // Update the entry with filtered data $entry['SNO'] = $sno; $entry['items'] = $items; $entry['row_id'] = $row_id; $entry['data'] = $filteredData; } unset($entry); // kint::dump($data); return $data; } }