Merge branch 'dev' of bitbucket.org:jubilian/nhance into dev

This commit is contained in:
VENKATESHWARAN 2025-03-24 15:16:59 +05:30
commit 1d1c439c56
7 changed files with 1210 additions and 739 deletions

View File

@ -9,3 +9,5 @@ From command propmt run the following cmds
Run speeific method
`php vendor/bin/phpunit tests\unit\PremiumCalculationTest.php --filter testPremiumCalculationWithPrimaryRackRateAndAdditionalRackRate`
Test Comments

View File

@ -404,6 +404,7 @@ $routes->group("leads", ["filter" => "authMVC"], function ($routes) {
$routes->group("rfq", ["filter" => "authMVC"], function ($routes) {
$routes->post("create", "LeadsController::createRFQ");
$routes->post("savePolicyInfo", "LeadsController::savePolicyInfo");
$routes->post("createQCR", "LeadsController::createQCR");
$routes->get("list/(:any)", "LeadsController::viewRFQ/$1");
$routes->get("nonEB","LeadsController::rfqNonEB");

View File

@ -28,6 +28,7 @@ use App\Models\InsurerBranchModel;
use App\Models\TPABranchModel;
use App\Models\RFQModel;
use App\Models\InsurerModel;
use App\Models\OccupancyMasterModel;
use App\Helpers\MailHelper;
use App\Helpers\ExcelMergeHelper;
@ -60,6 +61,7 @@ class LeadsController extends BaseController
protected $tpaBranchModel;
protected $RFQModel;
protected $insurerModel;
protected $occupancyModel;
//variables for storing array
protected $issuer;
@ -68,6 +70,7 @@ class LeadsController extends BaseController
protected $leadsStatus;
protected $claim_type_for_gpa;
protected $cause_of_death;
protected $buisnessType;
public function __construct()
@ -88,10 +91,12 @@ class LeadsController extends BaseController
$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',
@ -113,7 +118,6 @@ class LeadsController extends BaseController
'suicide' => 'Suicide',
'accident' => 'Accident'
];
}
public function viewLeadsList()
@ -133,10 +137,10 @@ class LeadsController extends BaseController
// dd($lastFiveYears);
if ($this->request->is('get')) {
// Fetch leads data
$data ['lead_data_list'] = $this->leadsModel->getLeadDataForLising();
$data['lead_data_list'] = $this->leadsModel->getLeadDataForLising();
// Load layout and pass data
$this->loadLayout('lead_filter', $data);
}else{
} else {
$search_data = $this->request->getPost();
// print_r($search_data);
@ -147,7 +151,7 @@ class LeadsController extends BaseController
$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);
@ -190,9 +194,9 @@ class LeadsController extends BaseController
$data['client_code'] = generate_client_code('IC');
}
if(isset($data['lead_form_type'])){
if (isset($data['lead_form_type'])) {
$data = $this->prepareSingleLeadData($data);
}else{
} else {
$data = $this->prepareMultipleLeadData($data);
}
// print_r($data); die;
@ -208,46 +212,45 @@ class LeadsController extends BaseController
$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;
}
// 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;
}
if (!empty($data['policy_end_date'])) {
$data['policy_end_date'] = change_date_format($data['policy_end_date']);
} else {
$data['policy_end_date'] = null;
}
$data['insurer_id'] = $insurer_id;
$data['insurer_branch_id'] = $insurer_branch_id;
$data['file_name'] = file_Upload($files, $uploadFilePath);
$processcedData[] = $data;
// 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;
@ -263,14 +266,13 @@ class LeadsController extends BaseController
$files = $this->request->getFileMultiple('file_name');
// print_r($files); die;
foreach($data['policy_type_id'] as $index => $value){
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{
} else {
$insurer_branch_id = 0;
$insurer_id = 0;
}
@ -310,15 +312,15 @@ class LeadsController extends BaseController
$policy_end_date = null;
}
if(!empty($data['incurred_claim_date'][$index])){
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{
} else {
$incurred_claims_date = null;
}
if(!empty($data['premium_date'][$index])){
if (!empty($data['premium_date'][$index])) {
$premium_date = change_date_format($data['premium_date'][$index], 'd/m/Y', 'Y-m-d');
}else{
} else {
$premium_date = null;
}
@ -406,7 +408,7 @@ class LeadsController extends BaseController
$insertCount[] = $insert;
$this->insertLeadStatus($insert, $value['status'], 3);
if($value['lead_form_type'] == 1){
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' => [
@ -441,9 +443,9 @@ class LeadsController extends BaseController
->first();
$data['lead_edit_data'] = $this->leadsModel
->where('leads.id', $id)
->where('leads.is_active', 1)
->first();
->where('leads.id', $id)
->where('leads.is_active', 1)
->first();
if (!empty($data['policy_start_date'])) {
@ -509,18 +511,18 @@ class LeadsController extends BaseController
{
$data['rfq_data'] = $this->RFQModel
->where('lead_id', $id)
// ->where('type', $type)
->where('is_active', 1)
->orderBy('id', 'desc')
->first();
->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();
->where('lead_id', $id)
// ->where('type', 1)
->where('is_active', 1)
->countAllResults();
$data['qcr_count'] = $this->RFQModel
->where('lead_id', $id)
@ -532,18 +534,18 @@ class LeadsController extends BaseController
$data['lead_id'] = $id;
$lead_data = $this->leadsModel
->select('
->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();
->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);
@ -557,7 +559,7 @@ class LeadsController extends BaseController
$data['insurer'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames();
$data['userList'] = $this->userModel->getUserListForRFQ();
$data['lead_data'] = $lead_data;
$mail_content = "
<p>Dear Sir,</p>
<p>Greetings From Nhance India!</p>
@ -566,8 +568,8 @@ class LeadsController extends BaseController
<p>In case of any query, please feel free to contact us.</p>
<p>Thank You!</p>
";
$subject = "{{CLIENT_NAME}} _ {{POLICY_TYPE}} _ {{RFQ_OR_QCR}} _ {{POLICY_YEAR}}";
$data['mail_content'] = $this->transformMailContent($lead_data, $mail_content, $data['page_name']);
@ -575,27 +577,58 @@ class LeadsController extends BaseController
// dd($data);
if ($data['lead_data']['lead_form_type'] == 1){
$this->loadLayout('view_rfq.php', $data);
if ($data['lead_data']['lead_form_type'] == 1) {
}else if ($data['lead_data']['lead_form_type'] == 2){
$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()
{
// print_r($this->request->getPost('json')); die();
$data = $this->request->getPost();
@ -608,12 +641,37 @@ class LeadsController extends BaseController
->set('is_active', 0)
->update();
$result = $this->RFQModel->insert($data);
$registrationJson = $data['registration_json'] ?? null; // Use null coalescing operator for safety
if ($registrationJson) {
// If registration_json is provided, insert the data directly
$result = $this->RFQModel->insert($data);
} else {
// If registration_json is not provided, fetch the latest registration_json from the database
$this->RFQModel->select('registration_json')
->where("lead_id", $lead_id)
->order_by('id', 'DESC') // Assuming 'id' is an auto-increment field
->limit(1);
$query = $this->RFQModel->get();
$latestRegistrationJson = $query->row()->registration_json ?? null;
if ($latestRegistrationJson) {
// If a valid registration_json is found, update the data and insert
$data['registration_json'] = $latestRegistrationJson;
$result = $this->RFQModel->insert($data);
} else {
// If no registration_json is found, insert the data as-is
$result = $this->RFQModel->insert($data);
}
}
if ($result) {
$message = "RFQ submitted successfully";
if($data['submit_type'] == 'QCR'){ $message = "QCR submitted successfully"; }
if ($data['submit_type'] == 'QCR') {
$message = "QCR submitted successfully";
}
return $this->respond(['status' => true, 'id' => $result, 'message' => $message, 'data' => $data], 200);
}
@ -655,10 +713,10 @@ class LeadsController extends BaseController
//FOR EXCEL
public function exportExcelForQCRandRFQ($lead_id, $type, $lead_form_type = 1)
{
if($lead_form_type == 2){
{
if ($lead_form_type == 2) {
$filepath = $this->constructNonEbExcelToSaveTemp($lead_id, $type);
}else{
} else {
$filepath = $this->constructExcelToSaveTemp($lead_id, $type);
}
@ -1189,7 +1247,7 @@ class LeadsController extends BaseController
$highestRowAndColumn = $members_sheet->getHighestRowAndColumn();
// dd($highestRowAndColumn);
$uncleaned_members = $members_sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']);
$members = ExcelSanitizeHelper::sanitizeArrayData($uncleaned_members);
$members = ExcelSanitizeHelper::sanitizeArrayData($uncleaned_members);
//get age band data
$age_band_sheet = $spreadsheet->getSheet(1);
$highestRowAndColumn = $age_band_sheet->getHighestRowAndColumn();
@ -1224,21 +1282,21 @@ class LeadsController extends BaseController
$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' => []],
['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'];
$deleteResponse = $this->deleteGeneratedFile($result['fullpath']);
// Add delete message to response
$response['deleteMessage'] = $deleteResponse['message'];
return ['status' => 'success', 'message' => 'Member_Data Merged Suceesfully'];
}
} else {
@ -1370,17 +1428,17 @@ class LeadsController extends BaseController
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;
@ -1390,31 +1448,31 @@ class LeadsController extends BaseController
$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';
@ -1422,7 +1480,7 @@ class LeadsController extends BaseController
$sheet->setCellValue($col . $currentRow, $band);
$col++;
}
// Style headers
$lastCol = chr(ord('B') + count($age_bands));
$headerRange = 'B' . $currentRow . ':' . $lastCol . $currentRow;
@ -1438,9 +1496,9 @@ class LeadsController extends BaseController
'horizontal' => Alignment::HORIZONTAL_CENTER,
],
]);
$currentRow++;
// Write data rows
foreach ($data as $relation => $values) {
if ($relation !== 'Grand Total') {
@ -1451,7 +1509,7 @@ class LeadsController extends BaseController
$sheet->setCellValue($col . $currentRow, $value);
$col++;
}
// Style data row
$dataRange = 'B' . $currentRow . ':' . $lastCol . $currentRow;
$sheet->getStyle($dataRange)->applyFromArray([
@ -1465,11 +1523,11 @@ class LeadsController extends BaseController
'horizontal' => Alignment::HORIZONTAL_CENTER,
],
]);
$currentRow++;
}
}
// Add Grand Total row
$sheet->setCellValue('B' . $currentRow, 'Grand Total');
$col = 'C';
@ -1477,7 +1535,7 @@ class LeadsController extends BaseController
$sheet->setCellValue($col . $currentRow, $data['Grand Total'][$band]);
$col++;
}
// Style Grand Total row
$totalRange = 'B' . $currentRow . ':' . $lastCol . $currentRow;
$sheet->getStyle($totalRange)->applyFromArray([
@ -1496,31 +1554,31 @@ class LeadsController extends BaseController
'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,
@ -1530,7 +1588,6 @@ class LeadsController extends BaseController
];
return $response;
} catch (Exception $e) {
return [
'success' => false,
@ -1538,7 +1595,7 @@ class LeadsController extends BaseController
];
}
}
// Function to delete generated file
public function deleteGeneratedFile($filePath)
{
@ -1562,7 +1619,7 @@ class LeadsController extends BaseController
];
}
}
public function getAge($available_col, $member, $col_index)
{
if ($available_col == 'age') {
@ -1643,7 +1700,7 @@ class LeadsController extends BaseController
$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
@ -1674,7 +1731,7 @@ class LeadsController extends BaseController
$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
@ -1709,14 +1766,14 @@ class LeadsController extends BaseController
//get file path to attach
if($lead_data["lead_form_type"] == 2){
if ($lead_data["lead_form_type"] == 2) {
$file_info = $this->constructNonEbExcelToSaveTemp($lead_id, ($file_type == 'rfq' ? 1 : 2), $propsal_and_insurer);
}else{
} 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));
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'];
@ -1730,7 +1787,7 @@ class LeadsController extends BaseController
$result = ExcelMergeHelper::mergeExcelFiles($filePaths, $outputPath);
// print_rr($result);
}
}else{
} else {
$result = $file_info['filePath'];
// return $this->respond(['status' => 'fail', 'code' => 200, 'messgae' => 'File Not Found'], 200);
}
@ -1767,12 +1824,12 @@ class LeadsController extends BaseController
$original_message = '<div style="width:100%;max-width:600px;margin:0 auto;padding:20px;border:1px solid #e0e0e0;background-color:#f9f9f9;font-family:Arial,sans-serif;color:#333;line-height:1.6"><div style=background-color:#4a90e2;color:#fff;padding:15px;text-align:center><h1 style=margin:0;font-size:24px>Request for Quotation (RFQ)</h1></div><div style=padding:20px;background-color:#fff><h2 style=color:#4a90e2;font-size:20px;margin-top:0>Dear {{RECIPIENT_NAME}},</h2><p>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.<h2 style=color:#4a90e2;font-size:20px;margin-top:20px>RFQ Details</h2><table style=width:100%;border-collapse:collapse;margin-top:20px><tr><th style="border:1px solid #ddd;padding:10px;text-align:left;background-color:#f2f2f2">Client name<td style="border:1px solid #ddd;padding:10px;text-align:left">{{CLIENT_NAME}}<tr><th style="border:1px solid #ddd;padding:10px;text-align:left;background-color:#f2f2f2">Coverage Type<td style="border:1px solid #ddd;padding:10px;text-align:left">{{POLICY_LONG_NAME}}<tr><th style="border:1px solid #ddd;padding:10px;text-align:left;background-color:#f2f2f2">Policy Start Date<td style="border:1px solid #ddd;padding:10px;text-align:left">{{POLICY_START_DATE}}<tr><th style="border:1px solid #ddd;padding:10px;text-align:left;background-color:#f2f2f2">Policy Duration<td style="border:1px solid #ddd;padding:10px;text-align:left">{{DURATION}}</table><div style="margin-top:20px;padding:10px;background-color:#f7f7f7;border-left:4px solid #4a90e2;font-style:italic">Please note: Additional terms and details are included in the attachment for your reference.</div><p>Please feel free to reach out if you require any further information to prepare the quote. We look forward to receiving your proposal.<p>Best regards,<p><strong>Nhance India Pvt Ltd</strong><br></div><div style=margin-top:20px;font-size:12px;color:#777;text-align:center><p>© Nhance India Pvt Ltd. All rights reserved.</div></div>';
//for mail content
if(!empty($mail_content)){
if (!empty($mail_content)) {
$original_message = $mail_content;
}
//for mail subject
if(!empty($mail_subject)){
if (!empty($mail_subject)) {
$subject = $mail_subject;
}
@ -1963,16 +2020,16 @@ class LeadsController extends BaseController
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){
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) {
@ -1995,8 +2052,8 @@ class LeadsController extends BaseController
// Remove proposalKey from over_all_column_data
unset($first_json['proposal_data']['over_all_column_data'][$proposalKey]);
if($type == 2){
if ($type == 2) {
// Remove proposalKey from premium_data
unset($first_json['premium_data']['data'][$proposalKey]);
}
@ -2004,7 +2061,7 @@ class LeadsController extends BaseController
// 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) ) {
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) {
@ -2023,7 +2080,7 @@ class LeadsController extends BaseController
// Remove insurer from proposal's insurers array
unset($first_json['proposal_data']['over_all_column_data'][$proposalKey]['insurers'][$insurerIndex]);
if($type == 2){
if ($type == 2) {
unset($first_json['premium_data']['data'][$proposalKey][$insurer['display_name']]);
}
}
@ -2047,8 +2104,7 @@ class LeadsController extends BaseController
$proposal['insurers'] = array_values($proposal['insurers']);
return $proposal;
}, $first_json['proposal_data']['over_all_column_data']);
}else{
} else {
//remove insurer as Subheaders for RFQ
foreach ($first_json['table_data']['headers'] as &$header) {
@ -2082,10 +2138,9 @@ class LeadsController extends BaseController
$proposal['insurers'] = [];
}
}
// Ensure to reset the reference
unset($proposal);
}
return $first_json;
@ -2250,7 +2305,7 @@ class LeadsController extends BaseController
//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);
@ -2295,7 +2350,7 @@ class LeadsController extends BaseController
$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;
@ -2306,7 +2361,7 @@ class LeadsController extends BaseController
// 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;
@ -2350,13 +2405,13 @@ class LeadsController extends BaseController
public function transformMailContent($lead_data, $mail_content, $page_name)
{
$current_year = date('Y');
{
$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);
@ -2366,30 +2421,29 @@ class LeadsController extends BaseController
$message = str_replace("{{POLICY_YEAR}}", $policy_year, $message);
return $message;
} else {
return ''; // Return empty if no lead data found
}
}
function getLastFiveFinancialYears()
function getLastFiveFinancialYears()
{
$currentYear = date('Y');
$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;
}
@ -2426,7 +2480,7 @@ class LeadsController extends BaseController
->where('user_teams.team_id', 5)
->where('user_teams.is_active', 1)
->where('user_profiles.is_active', 1)
->findAll();
->findAll();
if (!empty($id)) {
$data['lead_edit_data'] = $this->leadsModel->where('id', $id)->first() ?? [];
@ -2452,15 +2506,14 @@ class LeadsController extends BaseController
: [];
$data['lead_edit_data']['html'] = $this->generateViewPageHtml(
$data['lead_edit_data']['policy_type_id'] ?? null,
$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){
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{
} else {
$data['lead_edit_data']['claims_details_html'] = "";
}
}
@ -2471,36 +2524,50 @@ class LeadsController extends BaseController
}
public function getPolicyTypeFields()
{
{
$policy_type_id = $this->request->getGET('policy_type_id');
$html = $this->generateViewPageHtml($policy_type_id) ?? "";
if(!empty($html)){
if (!empty($html)) {
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Policy Type FIELDS are found', 'data' => $html], 200);
}else{
} 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',
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) : "";
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
class OccupancyMasterModel extends Model
{
protected $table = 'occupancy_master';
protected $allowedFields = [
'id',
'iib_code',
'section',
'description',
'iib_loss_rate',
'created_by',
'created_at',
'is_active'
];
}

View File

@ -17,6 +17,7 @@ class RFQModel extends Model
'type',
'lead_id',
'json',
"registration_json",
'created_at',
'created_by',
'updated_at',

File diff suppressed because it is too large Load Diff

View File

@ -215,7 +215,7 @@
<div class="form-row" id="input_for_row">
</div>
</div>
<div class="form-group text-right m-b-0" id="hide_smbt_btn">
<button type="submit" class="btn btn-primary" onclick="constructURL(1)">Send Mail</button>
</div>
@ -243,12 +243,12 @@
<select class="form-control" id="to" name="to" required>
<?php if (isset($userList)) { ?>
<?php foreach ($userList as $user) { ?>
<option value="<?= $user['email'];?>">
<?= $user['first_name'].' - '.$user['email'];?>
<option value="<?= $user['email']; ?>">
<?= $user['first_name'] . ' - ' . $user['email']; ?>
</option>
<?php } ?>
<?php } ?>
</select>
</select>
</div>
<div class="form-group col-md-4">
@ -256,12 +256,12 @@
<select class="form-control" id="cc" name="cc" required multiple>
<?php if (isset($userList)) { ?>
<?php foreach ($userList as $user) { ?>
<option value="<?= $user['id'];?>">
<?= $user['first_name'].' - '.$user['email'];?>
<option value="<?= $user['id']; ?>">
<?= $user['first_name'] . ' - ' . $user['email']; ?>
</option>
<?php } ?>
<?php } ?>
</select>
</select>
</div>
<div class="form-group col-md-12">
@ -278,7 +278,7 @@
</div>
<br>
<div class="form-group text-right m-b-0" id="hide_smbt_btn">
<button type="submit" class="btn btn-primary" onclick="constructURL(2)">Send Mail</button>
<button type="submit" class="btn btn-primary" onclick="constructURL(2)">Send Mail</button>
</div>
</div>
</div><!-- /.modal-content -->
@ -300,7 +300,7 @@
<!-- For display perpose placement alredy submited text display -->
<div class="form-group col-md-12">
<label><span id="alert_msg"class="text-danger"></span></label>
<label><span id="alert_msg" class="text-danger"></span></label>
</div>
<div class="form-row">
@ -335,16 +335,16 @@
<div class="form-row">
<div class="form-group col-md-6">
<label for="proposals"> Proposals/Insurer <span id="base_danger"class="text-danger">*</span></label>
<select class="form-control" id="proposals"name="proposals" onchange="getInsurerBranchContacts(this)" required>
<option value="" >Select Proposals</option>
<label for="proposals"> Proposals/Insurer <span id="base_danger" class="text-danger">*</span></label>
<select class="form-control" id="proposals" name="proposals" onchange="getInsurerBranchContacts(this)" required>
<option value="">Select Proposals</option>
</select>
</div>
<div class="form-group col-md-6">
<label for="placement_to"> To <span id="base_danger"class="text-danger">*</span></label>
<label for="placement_to"> To <span id="base_danger" class="text-danger">*</span></label>
<select class="form-control" id="placement_to" name="placement_to" required>
<option value="" >Select To Mail</option>
<option value="">Select To Mail</option>
</select>
</div>
@ -353,12 +353,12 @@
<select class="form-control" id="placement_cc" name="placement_cc" required multiple>
<?php if (isset($userList)) { ?>
<?php foreach ($userList as $user) { ?>
<option value="<?= $user['id'];?>">
<?= $user['first_name'].' - '.$user['email'];?>
<option value="<?= $user['id']; ?>">
<?= $user['first_name'] . ' - ' . $user['email']; ?>
</option>
<?php } ?>
<?php } ?>
</select>
</select>
</div>
<div class="form-group col-md-12">
@ -405,11 +405,18 @@
}
};
var suggestions = {};
var storedData = JSON.parse(localStorage.getItem('policyData'));
var policySummary;
if (!$.isEmptyObject(storedData)) {
policySummary = addPolicySummaryTable(storedData);
var policyInformationData = <?= isset($rfq_data['registration_json']) ? json_encode($rfq_data['registration_json'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) : '""' ?>;
var storedData = {};
console.log("stored data : ", typeof(policyInformationData))
if (policyInformationData.length) {
localStorage.setItem('policyData', (policyInformationData));
storedData = policyInformationData;
}
var policySummary = [];
console.log("policy summary is set :", !$.isEmptyObject(policySummary) ? "no" : "yes")
$(document).ready(function() {
myModal = new bootstrap.Modal(document.getElementById('policyRegisterModel'));
@ -486,37 +493,7 @@
1: ['Quote asked']
}; // Stores quote columns for each proposal
// Generate a random quote code (e.g., abc123)
function generateRandomCode() {
const chars = 'abcdefghijklmnopqrstuvwxyz';
const nums = '0123456789';
return Array.from({
length: 3
}, () => chars[Math.floor(Math.random() * 26)]).join('') +
Array.from({
length: 3
}, () => nums[Math.floor(Math.random() * 10)]).join('');
}
// Add a new quote column to a specific proposal
// function addNewQuote(proposalNumber) {
// console.log("this doesnt work");
// let increaseBy = 25;
// increaseTableWidth(increaseBy)
// console.log('ADD NEW QUOTE proposalNumber' + proposalNumber);
// console.log('ADD NEW QUOTE overall quotesConfig');
// console.log(quotesConfig);
// if (!quotesConfig[proposalNumber]) {
// quotesConfig[proposalNumber] = ['Quote asked']; // Initialize with default quote
// }
// const newQuote = generateRandomCode();
// quotesConfig[proposalNumber].push(newQuote); // Add new quote to the proposal
// // Update all tables (parent and child) with the new quote column
// updateAllTables(proposalNumber, newQuote);
// // hideProposalOptionsForChild();
// }
// Update all tables with the new quote column
function updateAllTables_old(proposalNumber, newQuote) {
@ -726,6 +703,7 @@
// console.log('Row id for excess table',rowId);
$("#excess .three-dot-menu").hide();
moveExcessTableLast();
}
} else {
// Handle regular table
@ -733,6 +711,9 @@
generateTable(childContainer, true, rowId, childTable);
// console.log('Row id for excess table', rowId);
$(childContainer).find(".three-dot-menu").hide();
// alert(`${rowId.toUpperCase()}_register`);
$(`#${rowId.toUpperCase()}_register`).prop("disabled", false);
moveExcessTableLast();
}
});
@ -742,7 +723,10 @@
container.appendChild(childContainer);
}
arrangeTables();
alignTableColumn();
} else {
console.log('UNCHECKED:', rowId);
selectedPolicies.delete(rowId);
@ -751,6 +735,7 @@
regularContainers.forEach(container => {
console.log(" contaitner ", container);
$(`#${rowId.toUpperCase()}_register`).prop("disabled", true);
container.remove();
});
console.log("row id ", rowId);
@ -1138,6 +1123,10 @@
${newQuote}
<span class="three-dot-menu" onclick="showDropdown(event)">&#8942;</span>
<div class="dropdown-content">
<button id = "isInsurerSTC" class="sendInsurerClientProposal" onclick = "addOrRemoveIconInsurer(this,event)"
style="background-color: rgb(221, 221, 221);">Send to Client <i
class="fa fa-check-square"
style="color: green; margin-left: 8px; "></i></button>
<button onclick="changeInsurer(event, ${proposalNumber}, '${newQuote}')">Change Insurer</button>
<button onclick="removeQuote(event, ${proposalNumber}, '${newQuote}')">Remove Quote</button>
</div>
@ -1187,7 +1176,7 @@
const headerRow1 = document.createElement('tr');
headerRow1.innerHTML =
`
${isChildTable ? '<th>S.NO</th>' : '<th><input type="checkbox"></th>'}
${isChildTable ? '<th>S.NO</th>' : '<th>Policy</th>'}
<th>${tableName}</th>
${Object.keys(quotesConfig).map(proposal => `
<th data-proposal="${proposal}" colspan="${quotesConfig[proposal].length}">
@ -1214,13 +1203,15 @@
<th>-</th>
${Object.entries(quotesConfig).flatMap(([proposal, codes]) =>
codes.map(code => `
<th data-proposal="${proposal}" data-quote="${code}">
${code}
<span class="three-dot-menu" onclick="showDropdown(event)">&#8942;</span>
<div class="dropdown-content">
<button onclick="removeQuote(event, ${proposal}, '${code}')">Remove Quote</button>
</div>
</th>
<th data-proposal="${proposal}" data-quote="${code}"
class="${code !== 'Quote asked' ? 'insurer_proposal' : ''}">
${code}
<span class="three-dot-menu" onclick="showDropdown(event)">&#8942;</span>
<div class="dropdown-content">
<button onclick="removeQuote(event, ${proposal}, '${code}')">Remove Quote</button>
</div>
</th>
`)
).join('')}
<th>-</th>`;
@ -1262,7 +1253,7 @@
<input type="checkbox" class="sno-checkbox">
${policy.name}
${policy.name === 'Fire' || policy.name === 'Burglary' ?
`<br><button class = "btn btn-primary btn-sm" onclick = "getPolicyInfo()" class="policy-link" data-policy-name="${policy.name}">Register</button>` :
`<br><button id = '${policy.name.toUpperCase()}_register' class = "btn btn-primary btn-sm" onclick = "getPolicyInfo('${policy.name}')" class="policy-link" data-policy-name="${policy.name}" disabled>Register</button>` :
''}
</td>
<td contenteditable="true">${desc}</td>
@ -1303,13 +1294,14 @@
suggestions[rowID] = row_fields[rowID].answer_type;
if (answer_type == 'dropdown') {
default_answers_array = row_fields[rowID].default_answer;
console.log("default ans array : ", typeof(default_answers_array))
// createDropdown(default_answers_array);
default_value = default_answers_array[0].key;
default_answer = default_answers_array[0].display_value;
} else {
default_answers_array = row_fields[rowID].default_answer ? row_fields[rowID].default_answer : "-";
console.log("default ans array else: ", default_answers_array)
// console.log("defaultansetgoa : ",default_answers_array);
default_value = default_answers_array;
default_answer = default_answers_array;
@ -1325,16 +1317,44 @@
${isChildTable
? `<td>${SNO}</td>`
: `<td rowspan = "${policy.description.length}"><input type="checkbox" class="sno-checkbox">${policy.name}${policy.name == 'Fire' || policy.name == 'Burglary'
? `<br><button class = "btn btn-primary btn-sm" onclick = "getPolicyInfo()" class="policy-link" data-policy-name="${policy.name}">Register</a>`
? `<br><button id = '${policy.name.toUpperCase()}_register' class = "btn btn-primary btn-sm" onclick = "getPolicyInfo('${policy.name}')" class="policy-link" data-policy-name="${policy.name}" disabled>Register</a>`
: ""}</td>`
}
<td contenteditable="true">${tableData ? policy_question : policy.description}</td>
${Object.values(quotesConfig).flatMap(codes =>
codes.map(() => `<td onblur="setValueForHiddenField(this,'${answer_type}')" onclick = "getAnswer('${tableID}','${rowID}')" contenteditable="true">${tableData ? (default_value === '-' ? `${default_value} <input type="hidden" value='${default_value}' />` : `${default_answer} <input type="hidden" value='${typeof(default_answers_array) == "object" ? JSON.stringify(default_answers_array[0]) : String(default_answer)}' />`)
: policy.quote_asked}</td>`)
).join('')}
codes.map((_, colIndex) => {
// Get the subheader (assuming it's the second <tr> inside <thead>)
let subHeaderTh = document.querySelector(`thead tr:nth-child(2) th:nth-child(${colIndex + 1})`);
let subHeaderText = subHeaderTh ? subHeaderTh.textContent.trim() : '';
// Check if subheader is NOT "Quote asked"
let className = subHeaderText !== "Quote asked" && subHeaderText != "-" ? "insurer_proposal" : "";
let defaultJsonString = typeof default_answers_array == "object" ? JSON.stringify(default_answers_array[0]) : String(default_answers_array);
// console.log("defaultJsonString", defaultJsonString);
// console.log("defaultJsonString type", typeof defaultJsonString);
// console.log("defaultJsonString string", String(defaultJsonString));
return `<td class="${className}" onblur="setValueForHiddenField(this,'${answer_type}')"
onclick="getAnswer('${tableID}','${rowID}')"
contenteditable="true">
${tableData ?
(default_value === '-' ?
`${default_value} <input type="hidden" value="${default_value}" />`
: `${default_answer} <input type="hidden" value='${defaultJsonString}' />`
)
: policy.quote_asked
}
</td>`;
})
).join('')}
<td>
${isChildTable ? `
<input id = "qcrCheckbox" name = "qcr" checked type="checkbox" class="qcr-checkbox"> <label for = "qcrCheckbox">QCR</label>
@ -1482,6 +1502,23 @@
jsonToTables();
proposalDataForDropDown = rfq_data[rfq_data.length - 1].proposal_data;
console.log("proposalDataForDropDown", proposalDataForDropDown);
if (!$.isEmptyObject(storedData)) {
console.log("DATA FROM DB : ", JSON.parse(storedData));
let data = JSON.parse(storedData);
Object.keys(data).forEach(key => {
policySummary[key] = addPolicySummaryTable(data[key], key);
// prependTable(policySummary[key],key);
});
// console.log("policy summary : ",child_table_data[key])
console.log("generate policy summary : ", policySummary);
}
// generateTable(document.getElementById('tablesContainer'));
// console.log("polices Length ", policies.length);
@ -1791,18 +1828,41 @@
function getPolicyInfo(policyName) {
console.log("anchor link clicked ", policyName);
if (!myModal) {
myModal = new bootstrap.Modal(document.getElementById('policyRegisterModel'));
console.log("inside if condition");
}
myModal = new bootstrap.Modal(document.getElementById('policyRegisterModel'));
console.log("inside if condition");
var leadID = $("#lead_id").val();
let policy = policies.find(p => p.name === policyName);
// alert(policy.quote_asked[0]);
// var policySI = policies[]
$("#policyName").val(policyName);
$("#policySI").val(policy.quote_asked[0]);
$("#leadID").val(leadID);
$("#multilocation_type_div").hide();
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
// Add 'show active' to the 'product-selection' tab
$("#policy_register_forms .tab-pane.show.active").removeClass("active show");
// Add 'show active' to the 'product-selection' tab
$("#product-selection").addClass("active show");
hideAndShowBurglary();
storedPolicyData = JSON.parse(localStorage.getItem('policyData'));
if (!$.isEmptyObject(storedPolicyData)) {
// alert("not empty");
prepareDataForEdit(storedPolicyData);
}
myModal.show();
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
}
function addPolicySummaryTable(storedData) {
function addPolicySummaryTable(storedData, policyName) {
// alert(policyName);
var locationCount = storedData.locations.length;
var tableRowContent = [];
@ -1812,13 +1872,12 @@
tableRowContent.push({
table_type: "new",
table_id: "fire_summary_" + locationIndex,
table_id: `${policyName}_summary_` + locationIndex,
table_editable: true,
table_name: "Risk Location " + locationIndex + "- " +
storedData.locations[i].policyRisk['occupancy'] + "- " +
storedData.locations[i].policyRisk['address1'] + " " +
storedData.locations[i].policyRisk['address2'],
"answer_type": "free-text",
table_row_contents: [{
[`fire_plantMachineries_${locationIndex}`]: {
"display_value": "Plant & Machineries and Accessories",
@ -1922,15 +1981,17 @@
console.log("save button clicked");
leadJson = tablesToJson();
console.log("json from function ", leadJson);
saveRFQTODB(leadJson);
var policyJson = localStorage.getItem("policyData") ?? null;
saveRFQTODB(leadJson, policyJson);
}
function saveRFQTODB(tableJSON) {
function saveRFQTODB(tableJSON, policyJson) {
var formData = {
lead_id: $("#lead_id").val(),
json: JSON.stringify(tableJSON),
submit_type: "RFQ"
submit_type: "RFQ",
registration_json: policyJson
}
var url = '<?= base_url('rfq/create') ?>';
@ -1943,6 +2004,8 @@
method: "POST",
success: function(response) {
if (response.status == true) {
localStorage.removeItem('policyData');
toastr.success(response.message, "Success");
console.log(rfq_data.length);
@ -1958,7 +2021,7 @@
}
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
// window.location.reload();
window.location.reload();
},
error: function(xhr, status, error) {
$('.loader').fadeOut();
@ -1971,8 +2034,6 @@
function prepareOverallData() {
const overAllData = {};
// console.log("Policy Configuration Data : ", policyConfig);
// Iterate through each proposal in quotesConfig
Object.entries(policyConfig).forEach(([proposalNumber, insurers]) => {
const proposalKey = `Proposal ${proposalNumber}`;
overAllData[proposalKey] = {
@ -1981,7 +2042,6 @@
insurers: []
};
// Get QCR/STC status from proposal header
const proposalHeader = document.querySelector(`th[data-proposal="${proposalNumber}"]`);
if (proposalHeader) {
const qcrSelected = proposalHeader.querySelector('.qcrProposal .fa-check-square') !== null;
@ -1991,13 +2051,25 @@
}
console.log("Insurers Found", insurers);
// Get unique insurers from quotesConfig (stored during addNewQuote)
const uniqueInsurers = [];
insurers.forEach(insurer => {
if (typeof insurer === 'object' && insurer.id) { // Check if stored properly id:dataId,
if (typeof insurer === 'object' && insurer.id) {
let stcInsurerSelected = false;
const insurerHeaders = document.querySelectorAll(`th[data-quote="${insurer.insurerName}"]`);
insurerHeaders.forEach(header => {
const headerProposalCount = header.getAttribute("data-proposal");
if (headerProposalCount == proposalNumber) {
console.log("Found the subheader we are searching");
if (header.querySelector('.sendInsurerClientProposal .fa-check-square') !== null) {
stcInsurerSelected = true;
}
console.log("STC selected for insurer:", stcInsurerSelected);
}
});
uniqueInsurers.push({
ins_name: insurer.insurerName,
qcr: 1,
stc: rfq_or_qcr == 1 ? 1 : stcInsurerSelected ? 1 : 0,
display_name: insurer.insurerName,
id: insurer.id
});
@ -2010,6 +2082,7 @@
return overAllData;
}
function getTextExcludingButton(cell) {
return Array.from(cell.childNodes)
.filter(node => node.nodeType === Node.TEXT_NODE) // Get only text nodes
@ -2055,7 +2128,7 @@
const headerHTML = header.innerHTML;
const headerText = headerHTML.replace(/<span class="three-dot-menu"[\s\S]*?<\/div>/g, '').trim();
console.log("processing sub header array : ", subHeaderArray);
console.log("HEader : ", headerText);
console.log("HEader : ", header.innerText == " " ? header.innerText.trim() : headerText);
headers.push({
// parentHeader: header.innerText.replace('⋮', '').split('\n')[0].replace(/:.*/, '').trim(),
parentHeader: headerText,
@ -2260,6 +2333,17 @@
// child_table_data[rowData.rowID]
}
function getTotalCount(proposalDataArray) {
let proposals = proposalDataArray.proposal_data.over_all_column_data;
let proposalCount = Object.keys(proposals).length; // Count proposals
let insurerCount = Object.values(proposals).reduce((sum, proposal) => {
return sum + (proposal.insurers ? proposal.insurers.length : 0);
}, 0); // Count insurers across all proposals
return proposalCount + insurerCount;
}
function jsonToTables() {
@ -2288,7 +2372,15 @@
console.log("proposal count : ", proposalCount);
console.log("proposal count quotes config ... : ", proposalDataArray.proposal_data.over_all_column_data);
var totalCount = getTotalCount(proposalDataArray);
let increaseBy = proposalCount * 150;
if (rfq_or_qcr == 1) {
console.log("inside if ")
increaseBy = proposalCount * 150;
} else if (rfq_or_qcr == 2) {
increaseBy = totalCount * 150;
}
console.log("trying to find checkbox data : : : ", increaseBy);
@ -2351,10 +2443,15 @@
// Handle regular cells
else {
td.innerHTML = processCellContent(cellData.input_value, rowData, cellData.display_content);
if (cellData.parentth.startsWith("Proposal")) {
td.onclick = () => getAnswer(table.id, tr.id);
if (cellData.subth != "Quote asked") {
console.log("debug 1: ","table id : ",table.id,"Cell data parent header :",cellData.parentth,"others: ",cellData);
console.log("debug 1 : ",td.innerHTML)
// console.log("debug 1: ",cellData," ");
td.classList.add("insurer_proposal");
console.log("debug 1: ",td.className);
}
}
td.contentEditable = true;
@ -2418,6 +2515,7 @@
const headerRow1 = document.createElement('tr');
const headerRow2 = document.createElement('tr');
var overallColumnDataProposal = proposal_data.proposal_data.over_all_column_data;
var matchedKey = "";
headers.forEach(header => {
// Parent header
const th1 = document.createElement('th');
@ -2426,7 +2524,7 @@
var headerName = header.parentHeader;
console.log("header name : ", th1.textContent.trim());
console.log("over all column data : ", over_all_column_data)
let matchedKey = Object.keys(overallColumnDataProposal).find(key => headerName.startsWith(key));
matchedKey = Object.keys(overallColumnDataProposal).find(key => headerName.startsWith(key));
if (matchedKey) {
console.log("something wrong : ", overallColumnDataProposal[matchedKey]);
var headerCheckBoxProperties = overallColumnDataProposal[matchedKey];
@ -2459,14 +2557,23 @@
header.subHeaders.forEach(subHeader => {
const th2 = document.createElement('th');
if (header.parentHeader.startsWith("Proposal")) {
var insurers = overallColumnDataProposal[matchedKey].insurers;
const matchedInsurer = insurers.find(ins => ins.ins_name == subHeader);
if (subHeader != "Quote asked") {
console.log("trying to find something : ", matchedInsurer.stc);
console.log("this is the subheader : ", subHeader);
console.log("debug 2: ",subHeader,"parent header : ",header.parentHeader);
th2.classList.add("insurer_proposal");
th2.innerHTML = `
${subHeader}
<span class="three-dot-menu">&#8942;</span>
<div class="dropdown-content">
<button id = "isInsurerSTC" class="sendInsurerClientProposal" onclick = "addOrRemoveIconInsurer(this,event)"
style="background-color: rgb(221, 221, 221);">Send to Client ${matchedInsurer.stc == 1 ? `<i
class="fa fa-check-square"
style="color: green; margin-left: 8px; "></i>`: ""} </button>
<button onclick="changeInsurer(event, ${header.parentHeader.split(' ')[1]}, '${subHeader}')">Change Insurer</button>
<button onclick="removeQuote(event, ${header.parentHeader.split(' ')[1]}, '${subHeader}')">Remove Quote</button>
</div>
@ -2505,7 +2612,7 @@
}
// console.log("insude the function value ", value);
return `<input type="checkbox" ${value == "Checked" ? "checked" :""} class = "sno-checkbox" /> ${cellData.SNO} ${cellData.SNO == 'Fire' || cellData.SNO == 'Burglary'
? `<br><button class = "btn btn-primary btn-sm" onclick = "getPolicyInfo()" class="policy-link" data-policy-name="${cellData.SNO}">Register</a>`
? `<br><button id = '${cellData.SNO.toUpperCase()}_register' class = "btn btn-primary btn-sm" onclick = "getPolicyInfo('${cellData.SNO}')" class="policy-link" data-policy-name="${cellData.SNO}" ${value == "Checked" ? "" :"disabled"} >Register</a>`
: ""}`;
}
if (typeof value === 'string' && value.startsWith('{')) {
@ -2944,25 +3051,72 @@
});
});
}
function prependTable(policyJson,policyName) {
// alert("hi");
console.log("table to prepened : ", policyJson);
let parentDiv = document.querySelector(`div[data-parent-row=${policyName}]`);
// let newTable = document.createElement("table");
if (parentDiv){
let tables = Array.from(parentDiv.querySelectorAll("table"));
tables.forEach(table => {
if (table.id.includes("summary")) {
table.remove(); // reMove summary table from the top
}
});
policyJson.slice().reverse().forEach(childTable => {
generateTable(parentDiv, true, policyName, childTable);
});
moveSummaryTableToTop(policyName);
hideProposalOptionsForChild();
showOrHideFieldsBasedOnRFQorQCR();
}
}
function moveSummaryTableToTop(policyName) {
let parentDiv = document.querySelector(`div[data-parent-row="${policyName}"]`);
if (!parentDiv) return; // Exit if no such div exists
let tables = Array.from(parentDiv.querySelectorAll("table"));
tables.forEach(table => {
if (table.id.includes("summary")) {
parentDiv.prepend(table); // Move summary table to the top
updateSNO(table.id);
}
});
}
</script>
<!-- Export Excel and Mail Script -->
<script>
var proposalDataForDropDown = {};
var user_role_id = <?= get_role_id(); ?>;
const editorConfig = {
buttons: [
"bold",
"italic",
"strikethrough",
"|",
"superscript",
"subscript",
"|",
"align",
"fontsize",
"|",
"bold",
"italic",
"strikethrough",
"|",
"superscript",
"subscript",
"|",
"align",
"fontsize",
"|",
"source" // Add the "source" button for editing HTML
],
fontsize: ["8px", "10px", "12px", "14px", "16px", "18px", "20px", "22px", "24px"], // Font sizes in pixels
@ -2977,7 +3131,7 @@
placeholder: "Start typing here...", // Optional placeholder text
};
$(document).ready(function(){
$(document).ready(function() {
const path = window.location.pathname; // Get the current URL path
const segments = path.split('/'); // Split the path into segments
@ -2989,7 +3143,7 @@
let excel_url = '<?= base_url('leads/exportQCRandRFQ/') ?>' + lead_id + '/' + rfq_type + '/' + 2
console.log(excel_url, excel_url);
$('#submitExcel').attr('data-url', excel_url);
$('#cc').select2({
@ -3020,10 +3174,10 @@
if (placementLeadData) {
placementLeadData = JSON.parse(placementLeadData);
let txt = 'The data has already been sent to the insurer '
+ placementLeadData.insurer_name
+ ' and the proposal is '
+ placementLeadData.proposel_name + '.';
let txt = 'The data has already been sent to the insurer ' +
placementLeadData.insurer_name +
' and the proposal is ' +
placementLeadData.proposel_name + '.';
$('#alert_msg').text(txt);
} else {
$('#alert_msg').text('');
@ -3044,34 +3198,34 @@
})
function checkTheTableDataChanged(redirect_type){
function checkTheTableDataChanged(redirect_type) {
if(redirect_type == 1){
if (redirect_type == 1) {
//BACK BUTTON
window.location.href="<?= base_url("leads/list")?>"
window.location.href = "<?= base_url("leads/list") ?>"
}else if(redirect_type == 2){
} else if (redirect_type == 2) {
//EXCEL EXPORT
let url = $('#submitExcel').data('url');
window.location.href = url;
}else if(redirect_type == 3){
} else if (redirect_type == 3) {
//INSURER OR CLIENT MAIL SEND
showModal(1);
}else if(redirect_type == 4){
} else if (redirect_type == 4) {
//INTERNAL MAIL SEND
showModal(2);
}else if(redirect_type == 5){
} else if (redirect_type == 5) {
//PROCCED TO QCR
// submitQCRData();
let lead_id = $('#lead_id').val();
let url = '<?= base_url('rfq/list/') ?>' + lead_id + '/' + 2;
window.location.href = url;
}else if(redirect_type == 6){
} else if (redirect_type == 6) {
//INTERNAL MAIL SEND
showModal(3);
@ -3080,18 +3234,18 @@
function showModal(mail_type) {
if(mail_type == 1){
if (mail_type == 1) {
insurerAndClientMailPopUp()
}else if(mail_type == 2){
} else if (mail_type == 2) {
var myModal = new bootstrap.Modal(document.getElementById('internal_mail_modal'));
myModal.show();
// getMailContent('internal_mail_content');
}else if(mail_type == 3){
} else if (mail_type == 3) {
placementMailPopUp()
// getMailContent('placement_mail_content');
@ -3100,7 +3254,7 @@
}
function insurerAndClientMailPopUp(){
function insurerAndClientMailPopUp() {
var url = '';
var lead_id = $('#lead_id').val();
@ -3195,7 +3349,7 @@
`;
}
if(user_role_id == 1 || user_role_id == 5){
if (user_role_id == 1 || user_role_id == 5) {
html += `
@ -3204,8 +3358,8 @@
<select class="form-control" id="client_cc" name="client_cc" required multiple>
<?php if (isset($userList)) { ?>
<?php foreach ($userList as $user) { ?>
<option value="<?= $user['id'];?>">
<?= $user['first_name'].' - '.$user['email'];?>
<option value="<?= $user['id']; ?>">
<?= $user['first_name'] . ' - ' . $user['email']; ?>
</option>
<?php } ?>
<?php } ?>
@ -3217,8 +3371,8 @@
<select class="form-control" id="client_bcc" name="client_bcc" required multiple>
<?php if (isset($userList)) { ?>
<?php foreach ($userList as $user) { ?>
<option value="<?= $user['id'];?>">
<?= $user['first_name'].' - '.$user['email'];?>
<option value="<?= $user['id']; ?>">
<?= $user['first_name'] . ' - ' . $user['email']; ?>
</option>
<?php } ?>
<?php } ?>
@ -3266,8 +3420,8 @@
<select class="form-control" id="client_cc" name="client_cc" required multiple>
<?php if (isset($userList)) { ?>
<?php foreach ($userList as $user) { ?>
<option value="<?= $user['id'];?>">
<?= $user['first_name'].' - '.$user['email'];?>
<option value="<?= $user['id']; ?>">
<?= $user['first_name'] . ' - ' . $user['email']; ?>
</option>
<?php } ?>
<?php } ?>
@ -3279,8 +3433,8 @@
<select class="form-control" id="client_bcc" name="client_bcc" required multiple>
<?php if (isset($userList)) { ?>
<?php foreach ($userList as $user) { ?>
<option value="<?= $user['id'];?>">
<?= $user['first_name'].' - '.$user['email'];?>
<option value="<?= $user['id']; ?>">
<?= $user['first_name'] . ' - ' . $user['email']; ?>
</option>
<?php } ?>
<?php } ?>
@ -3302,7 +3456,7 @@
<label for="insurer_and_client_mail_content">Mail Content</label>
<textarea id="insurer_and_client_mail_content" class="form-control" name="insurer_and_client_mail_content" rows="3"><?= isset($mail_content) ? $mail_content : " " ?></textarea>
</div>
`;
`;
$('#input_for_row').append(html);
@ -3341,11 +3495,11 @@
function constructURL(url_type) {
if(url_type == 1){
if (url_type == 1) {
constructURL_ForInsurerAndClientMailSend()
}else if(url_type == 2){
} else if (url_type == 2) {
constructURL_ForInternalMailSend()
}else if(url_type == 3){
} else if (url_type == 3) {
Swal.fire({
title: "Do you want to place the proposal data?",
@ -3358,7 +3512,7 @@
}).then((result) => {
if (result.isConfirmed) {
constructURL_ForPlacementMailSend()
}else{
} else {
return false;
}
});
@ -3530,19 +3684,19 @@
$('#to').select2({
placeholder: 'Select To Mail',
});
});
$('#cc').val('').select2({
placeholder : 'select CC Mail'
});
placeholder: 'select CC Mail'
});
// $('#subject').val('');
$('#proposals').val('');
$('#proposals').val('');
$('#placement_to').val('').select2({
placeholder : 'select To Mail'
});
placeholder: 'select To Mail'
});
$('#placement_cc').val('').select2({
placeholder : 'select CC Mail'
});
$('#placement_subject').val('');
placeholder: 'select CC Mail'
});
$('#placement_subject').val('');
$("textarea.select2-search__field").attr('rows', '1');
$("textarea.select2-search__field").css('resize', 'none');
@ -3552,7 +3706,7 @@
return Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
}
function getInsurerBranchContacts(input){
function getInsurerBranchContacts(input) {
let insurer_and_branch = $(input).val();
console.log('insurer_and_branch', insurer_and_branch);
@ -3568,9 +3722,9 @@
console.log(res)
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
if(res.status == false){
if (res.status == false) {
toastr.warning(res.message, 'WARNING')
}else{
} else {
appendInsurerContact(res.data)
}
},
@ -3596,33 +3750,53 @@
$.each(data, function(index, item) {
var option = $('<option>', {
value: item.id,
text: item.contact_person_email
text: item.contact_person_email
});
$('#placement_to').append(option);
});
}
}
$('.close').click(function(){
$('.close').click(function() {
$('#to').select2({
placeholder: 'Select To Mail',
});
});
$('#cc').val('').select2({
placeholder : 'select CC Mail'
});
placeholder: 'select CC Mail'
});
// $('#subject').val('');
$('#proposals').val('');
$('#proposals').val('');
$('#placement_to').val('').select2({
placeholder : 'select To Mail'
});
placeholder: 'select To Mail'
});
$('#placement_cc').val('').select2({
placeholder : 'select CC Mail'
});
$('#placement_subject').val('');
placeholder: 'select CC Mail'
});
$('#placement_subject').val('');
$("textarea.select2-search__field").attr('rows', '1');
$("textarea.select2-search__field").css('resize', 'none');
})
function addOrRemoveIconInsurer(element, event) {
event.stopPropagation(); // Prevent event bubbling
// Find the button inside the dropdown (or use `element` directly)
const stcButton = element.closest('.dropdown-content') ?
element.closest('.dropdown-content').querySelector('.sendInsurerClientProposal') :
element;
// Check if the icon already exists
let icon = stcButton.querySelector("i.fa-check-square");
if (icon) {
// Remove the icon if it already exists
icon.remove();
} else {
// Create and append the check icon
createIcon(stcButton);
}
}
</script>