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->issuer = [1 => 'JIBS', 2 => 'Nhance']; $this->clientType = [1 => 'Group', 2 => 'Individual']; $this->leadType = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over']; $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', ]; } public function viewLeadsList() { // $d = $this->constructExcelToSaveTemp(24, 1, $propsal_and_insurer = null); // $job_details = new Jobs(); // $r = Jobs::addJob(['job_name' => 'calculateMembersDemography', 'payload' => ['lead_id' => 24]]); // $d = $this->calculateMembersDemography(['lead_id' => 24]); //$this->mergeQuoteExcelFileWithMembersListExcelFile(24, 1, $propsal_and_insurer = null); // dd($d); $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(); // Fetch insurer and TPA branch data $data['insurer'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames(); $data['tpa'] = $this->tpaBranchModel->getTpaBranchesWithTpaNames(); // 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(); // dd($data); // Fetch leads data $data['lead_data_list'] = $this->leadsModel->getLeadDataForLising(); // Load layout and pass data $this->loadLayout('leads_list', $data); } public function createLead() { // print_r($this->request->getPost()); die; $id = $this->request->getPost('id'); $data = $this->prepareLeadData(); // print_r($this->request->getPost()); 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'); } $data = $this->prepareMultipleLeadData($data); // print_r($data); die; return $data; } 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]); $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 = null; if($value != 2){ $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, ]; } return $processedData; } private function insertNewLead($data) { $insertCount = []; foreach ($data as $value) { $insert = $this->leadsModel->insert($value); $insertCount[] = $insert; $this->insertLeadStatus($insert, $value['status'], 3); //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(); 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; } 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) ->first(); $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') ->join('policy_type', 'leads.policy_type_id = policy_type.id') ->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; $data['mail_content'] = $this->transformMailContent($id); // dd($data); $this->loadLayout('view_rfq.php', $data); } public function createRFQ(){ // print_r($this->request->getPost('json')); die(); $data = $this->request->getPost(); $lead_id = $data['lead_id']; $data['type'] = 1; $this->RFQModel ->where('lead_id', $lead_id) ->where('type', 1) ->where('is_active', 1) ->set('is_active', 0) ->update(); $result = $this->RFQModel->insert($data); if ($result) { $message = "RFQ submitted successfully"; if($data['submit_type'] == 'QCR'){ $message = "QCR submitted successfully"; } return $this->respond(['status' => true, 'id' => $result, 'message' => $message, 'data' => $data], 200); } return $this->respond(['status' => false, 'id' => $result, 'message' => "Failed to create RFQ", '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, $export_type) { $this->exportExcelForQCRandRFQ($lead_id, $type); } //FOR EXCEL public function exportExcelForQCRandRFQ($lead_id, $type) { $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); 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; foreach ($lead_data as $key => $value) { $sheet->setCellValue("A{$rowNumber}", $key); $sheet->setCellValue("B{$rowNumber}", $value); $sheet->getStyle("A{$rowNumber}")->applyFromArray(['font' => ['bold' => true]]); $rowNumber++; } $leadRange = "A1:B" . (count($lead_data)); $sheet->getStyle($leadRange)->applyFromArray([ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => 'FF000000'], // Black color ], ], ]); $rowNumber += 2; // Add headers and subheaders $headers = $data['table_data']['headers']; $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.'; } $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); $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(30); // Header row height $sheet->getRowDimension($subHeaderRow)->setRowHeight(25); // Subheader row height $rowNumber = $subHeaderRow + 2; $column_data = $data['table_data']['data']; $serial_no = 1; // 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 $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 - 3) . ":" . chr(ord($columnLetter) - 1) . ($rowNumber - 1); $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); } // 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 $file_info = $this->constructExcelToSaveTemp($lead_id, ($file_type == 'rfq' ? 1 : 2), $propsal_and_insurer); 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); } } // print_rr($lead_data); // 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 $res = MailHelper::send_email(['mail' => $recipient['email'], 'cc' => $cc_mails, 'subject' => $subject, 'message' => $message, 'attachments' => $attachments, 'reply_to' => $reply_to, 'bcc' => $bcc_mails]); // !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']); } private function convertQCRJsonToPolicyTerms($data, $policy_type, $proposel_name, $insurer_name) { $GMC_Keys = [ "sum_insured", "family_floater", "family_floaters", "age_ratio", "waiverofpreexistingdiseases", "maternitycoverage", "twindelivery", "preandpostnatal", "babyday1cover", "9monthwaitingperiodwaived", "coverfromthedateofjoining", "waiverof1,2,3&4thyearexclusions", "waiverof30dayswaitingperiod", "prehospitalizationcover", "congenitaldiseasesinternal", "copayzonewisecopay", "bioabsorbablestenttoriclensmultifocallens", "roomrentlimit", "proportionatedeductionclause", "ailmentcapping", "ambulancecharges", "airambulance", "familytransportationbenefit", "reasonableandcustomarycharges", "ayudhtreatmentcover", "congenitaldiseasesexternal", "optionalparentalcopay", "posthospitalizationcover", "corporatebuffer", "sublimitofcorporatebuffer", "ayushTreatmentCoverData", "armdcovered", "suminsuredenhancement", "automaticsuminsuredreinstatement", "additionalsicknessbenefit", "lasiksurgery", "midterminclusion", "capd", "organdonorexpenses", "moderntreatmentsasperirdai", "Wellness", "days_of_discharge", "days_from_dod", "special_condition_label", "special_condition_input", "multiple_sum_insured", "cataract", "cataractData" ]; $GPA_Keys = [ "sumInsured2", "totalSumInsured", "age_ratio", "accidentalDeathBenefit", "permanentTotalDisablement", "permanentPartialDisablement", "temporaryTotalDisablementBenefit", "accidentalHospitalizationExpenses", "childrenEducationWelfareFund", "compassionateVisitExpenses", "compassionateVisitExpensesData", "brokenBoneExpenses", "brokenBoneExpensesData", "ambulanceCharges", "ambulanceChargesData", "burnExpenses", "burnExpensesData", "carriageOfDeadBody", "carriageOfDeadBodyData", "animalSnakeInsectBite", "terrorism", "worldwideCover", "gpa_special_condition_label", "gpa_special_condition_input", "multiple_sum_insured" ]; // Select keys based on policy type $termsKey = $policy_type == 1 ? $GPA_Keys : $GMC_Keys; // Initialize terms_array with default empty values $terms_array = array_fill_keys($termsKey, ""); $specialKeys = ['special_condition_label', 'special_condition_input', 'gpa_special_condition_label', 'gpa_special_condition_input', 'multiple_sum_insured']; foreach ($specialKeys as $key) { $terms_array[$key] = []; } // Initialize age_ratio based on policy type $terms_array['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; } // Handle special conditions if (str_starts_with($item, "special_condition") && $parentth === $proposel_name && $subth === $insurer_name) { $parts = explode("-", $input_value); $question = $parts[0] ?? ''; $answer = $parts[1] ?? ''; $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][] = $question; $terms_array[$inputKey][] = $answer; continue; } // Handle sum insured if (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); continue; } // Handle family floaters if ($item === 'family_composition') { $terms_array['family_floaters'] = isJsonString($input_value) ? json_decode($input_value, true) : $input_value; continue; } // Decode JSON if valid $terms_array[$item] = isJsonString($input_value) ? (json_decode($input_value, true)['key'] ?? '') : $input_value; } } 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_id) { helper('excel_util_helper'); // $params = $this->request->getGet(); // 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 // $propsal_and_insurer = isset($params['proposal_insurer']) ? $params['proposal_insurer'] : null; // if ($recipient_type == 'insurer' && empty($recipient_mail)) { // return $this->respond(['status' => 'failed', 'code' => 400, 'data' => '', 'messgae' => 'Recipient mail not found ! '], 200); // } //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(); // dd($lead_data); if($lead_data){ $recipient_data = ['name' => "Team"]; $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.

'; $message = $original_message; $message = str_replace("{{RECIPIENT_NAME}}", $recipient_data['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) ?? '--'; // return $this->respond(['status' => true, 'code' => 200, 'data' => $message], 200); return $message; }else{ // return $this->respond(['status' => false, 'code' => 404, 'message' => "This lead has not data"], 200); return ''; } } }