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() { $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) { $processedData = []; foreach($data['policy_type_id'] as $index => $value){ // Separate the insurer and insurer branch list($insurer_branch_id, $insurer_id) = explode('-',$data['insurer'][$index]); // Separate the tpa and tpa branch list($tpa_branch_id, $tpa_id) = explode('-',$data['tpa'][$index]); // 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; } $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, 'claims' => $data['claims'][$index] ?? null, '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, '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); } 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($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('policy_type.question_json') ->join('policy_type', 'leads.policy_type_id = policy_type.id') ->where('leads.id', $id) ->first(); $data['question_json'] = $lead_data['question_json']; $data['page_name'] = isset($data['rfq_data']['type']) && $data['rfq_data']['type'] == 2 ? 'QCR' : 'RFQ'; $data['insurer'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames(); $data['lead_data'] = $this->leadsModel->where('leads.id', $id)->where('leads.is_active', 1)->first(); // dd($data); $this->loadLayout('view_rfq.php', $data); } public function createRFQ(){ $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) { return $this->respond(['status' => true, 'id' => $result, 'message' => 'New RFQ created successfully', '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' => 'New 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){ if($export_type == 'mail'){ $this-> exportMailForQCRandRFQ($lead_id, $type); }else{ $this-> exportExcelForQCRandRFQ($lead_id, $type); } } //FOR EXCEL public function exportExcelForQCRandRFQ($lead_id, $type) { $filepath = $this->constructExcelToSaveTemp($lead_id, $type); $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."; } } //FOR MAIL public function exportMailForQCRandRFQ($lead_id, $type){ $filepath = $this->constructExcelToSaveTemp($lead_id, $type); if ($filepath) { return $this->respond(['status' => true, 'file_path' => $filepath, 'message' => 'Mail send successfully'], 200); } return $this->respond(['status' => false, 'file_path' => $filepath, 'message' => "Mail send failed"], 200); } //Construct excel file and save the file to the folder and return file path public function constructExcelToSaveTemp($lead_id, $type) { $rfq_data = $this->RFQModel ->select(' leads.client_name, leads.client_short_name, insurers.name as insurer_name, insurer_branch.branch_name as insurer_branch_name, tpa.name as tpa_name, tpa_branch.branch_name as tpa_branch_name, policy_type.policy_type, rfq.json ') ->join('leads', 'rfq.lead_id = leads.id') ->join('policy_type', 'leads.policy_type_id = policy_type.id') ->join('insurers', 'leads.insurer_id = insurers.id') ->join('insurer_branch', 'leads.insurer_branch_id = insurer_branch.id') ->join('tpa', 'leads.tpa_id = tpa.id') ->join('tpa_branch', 'leads.tpa_branch_id = tpa_branch.id') ->where('rfq.lead_id', $lead_id) ->where('rfq.type', $type) ->where('rfq.is_active', 1) ->first(); $lead_data = [ 'Insured' => $rfq_data['client_name'], 'Insurer' => $rfq_data['insurer_name'] . ' - ' . $rfq_data['insurer_branch_name'], 'TPA' => $rfq_data['tpa_name'] . ' - ' . $rfq_data['tpa_branch_name'], ]; $jsonData = $rfq_data['json']; $data = json_decode($jsonData, true); // Initialize PhpSpreadsheet $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); // Apply bold style to the key $sheet->getStyle("A{$rowNumber}")->applyFromArray([ 'font' => [ 'bold' => true, ], ]); $rowNumber++; } // Leave two blank rows $rowNumber += 2; // Set headers and subheaders starting from current row $headers = $data['table_data']['headers']; $subHeaderRow = $rowNumber + 1; $columnLetter = 'A'; // Set column width and apply word wrap to headers and subheaders foreach ($headers as $header) { if ($header['parentHeader'] === 'Item Key' || $header['parentHeader'] == 'Action') { continue; // Skip "Item Key" and "Action" columns } if ($header['parentHeader'] === 'Sno') { $header['parentHeader'] = 'S.No.'; } // Set the header cell value $sheet->setCellValue("{$columnLetter}{$rowNumber}", $header['parentHeader']); // Set column width for header $sheet->getColumnDimension($columnLetter)->setWidth(20); // Adjust width as needed $sheet->getStyle("{$columnLetter}{$rowNumber}")->getAlignment()->setWrapText(true); // Apply bold style to the header $sheet->getStyle("{$columnLetter}{$rowNumber}")->applyFromArray([ 'font' => [ 'bold' => true, ], ]); // Add subheaders in the second row foreach ($header['subHeaders'] as $subHeader) { $sheet->setCellValue("{$columnLetter}{$subHeaderRow}", $subHeader); // Enable word wrap for subheaders $sheet->getStyle("{$columnLetter}{$subHeaderRow}")->getAlignment()->setWrapText(true); // Apply bold style to the subheader $sheet->getStyle("{$columnLetter}{$subHeaderRow}")->applyFromArray([ 'font' => [ 'bold' => true, ], ]); $columnLetter++; } } // Move to next row for data entries $rowNumber = $subHeaderRow + 1; // Add data rows and enable word wrap for data cells foreach ($data['table_data']['data'] as $dataRow) { $columnLetter = 'A'; foreach ($dataRow['data'] as $cellData) { if ($cellData['parentth'] === 'Item Key' || $cellData['parentth'] == 'Action') { continue; // Skip "Item Key" data } $sheet->setCellValue("{$columnLetter}{$rowNumber}", $cellData['value']); // Enable word wrap for data cells $sheet->getStyle("{$columnLetter}{$rowNumber}")->getAlignment()->setWrapText(true); $columnLetter++; } $rowNumber++; } // Auto-size all columns after data is entered foreach ($sheet->getColumnIterator() as $column) { $sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true); } // Set filename based on type $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, ]; // Return file path and file name } //this funciton for send mail to insurer and client with either RFQ/QCR public function sendMailWithAttachement() { helper('excel_util_helper'); helper('MailHelper'); $params = $this->request->getGet(); // dd($params); $lead_id = $params['lead_id']; $file_type = $params['file_type']; //rfq or qcr $recipient_type = $params['recipient_type'];//insurer or client $recipient_mail = $params['recipient_mail'];// - only primary key of contacts $recipient_mail = json_decode($params['recipient_mail'], true);;// - only primary key of contacts // $cc = 'velz1990@gmail.com,vitvelz@gmail.com'; $cc = ""; $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') ->join('user_profiles','leads.created_by = user_profiles.id') ->where('leads.id', $lead_id) ->first(); 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) ); // $file_path = WRITEPATH."uploads/excel/sample/correction.xls"; // $file_name = $file_type.'.xlsx'; // !dd($file_info); $file_path = $file_info['filePath']; $file_name = $file_info['fileName']; $attachments = [['fileName' => $file_name,'filePath' => $file_path]]; //get recipient address if($recipient_type == 'insurer') { $recipient_data = $this->levelContactModel ->where(['contact_type' => $recipient_type, 'is_active' => 1]) ->whereIn('id', $recipient_mail) ->findAll(); } else { $recipient_data = [['name' => $lead_data['contact_person_name'],'email' => $lead_data['contact_person_email']] ]; } // !dd($recipient_data); $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.

'; 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); $res = MailHelper::send_email(['mail' => $recipient['email'], 'subject' => $subject, 'message' => $message,'attachments' => $attachments,'reply_to' => $reply_to]); // !dd($res); $result_data[] = ['mail' => $recipient['email'],'status' => $res]; } //delete attachment file unlink($file_path); return $this->respond(['status' => 'success','code' => 200,'data' => $result_data ], 200); } public function getLevelContects() { $data = $this->levelContactModel->getContectForRFQ(); if($data){ return $this->respond(['status' => true, 'data' => $data], 200); }else{ return $this->respond(['status' => false], 200); } } //----- 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) { return $this->respond(['status' => true, 'message' => 'New Client created successfully', 'client_id' => $result, 'data' => $data], 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); } 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) { $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); return $this->clientPolicyModel->insert($client_policy_data); } private function prepareClientPolicyData($data, $client_id, $branch_id) { $client_policy_data = [ 'client_id' => $client_id, 'client_branch_id' => $branch_id, 'policy_type_id' => $data['policy_type_id'], 'insurer_id' => $data['insurer_id'], 'insurer_branch_id' => $data['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, ]; $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; // } } return $client_policy_data; } private function preparePolicyTermsFromRFQ($data) { } }