diff --git a/app/Config/Constants.php b/app/Config/Constants.php index eee4bdcd..5cd84385 100755 --- a/app/Config/Constants.php +++ b/app/Config/Constants.php @@ -94,12 +94,12 @@ define('EVENT_PRIORITY_NORMAL', 100); define('EVENT_PRIORITY_HIGH', 10); /** - * @User Role Constant + * @User Teams Constant */ - define('ENROLLMENT_TEAM_ID', '1'); define('CLAIMS_TEAM_ID', '2'); -define('BUSINESS_TEAM_ID', '3'); +// define('BUSINESS_TEAM_ID', '3'); // old don't delete it +define('BUSINESS_TEAM_ID', '4'); // 25th OCT 2025 changed define('FINANCE_TEAM_ID', '4'); define('SALES_TEAM_ID', '5'); define('MANAGEMENT_TEAM_ID', '6'); @@ -107,9 +107,8 @@ define('BUSINESS_SUPPORT_TEAM_ID', '7'); define('POS_TEAM_ID', '8'); /** - * @User Teams Constant + * @User Role Constant */ - define('ADMIN_ROLE_ID', 1); define('MANAGER_ROLE_ID', 2); define('ACCOUNT_MANAGER_ROLE_ID', 3); diff --git a/app/Config/Routes.php b/app/Config/Routes.php index a7e41f8f..a685eb1f 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -399,8 +399,8 @@ $routes->group("/util", ["filter" => "authMVC"], function ($routes) { $routes->match(['get', 'post', 'delete'], 'nhanceBranchMaster', 'MasterController::nhanceBranchMaster'); $routes->match(['get', 'post', 'delete'], 'vehicleTypeMaster', 'MasterController::vehicleTypeMaster'); $routes->match(['get', 'post', 'delete'], 'rtoMaster', 'MasterController::rtoMaster'); - - + $routes->get('checkDuplicateCdAccount', 'MasterController::checkDuplicateCdAccount'); + $routes->get('proceedExcelFileDataValidation', 'EmployeeController::proceedExcelFileDataValidation'); }); $routes->post("policy_tranction/sendInstallmentRemainderMail","PolicyTransactionController::sendInstallmentRemainderMail"); @@ -427,7 +427,7 @@ $routes->group("policy_tranction", ["filter" => "authMVC"], function ($routes) { }); $routes->group("report", ["filter" => "authMVC"], function ($routes) { - $routes->match(['get', 'post'],"list", "PolicyTransactionController::reportBDS"); + $routes->match(['get', 'post'],"list", "PolicyTransactionController::reportBDSNew"); $routes->match(['get', 'post'],"listNew", "PolicyTransactionController::reportBDSNew"); $routes->get("report-varience-list", "PolicyTransactionController::reportVarience"); $routes->get("report-business-list", "PolicyTransactionController::reportBusinessList"); @@ -719,6 +719,7 @@ $routes->group('test', function($routes) { $routes->get('membervalidation', 'TestingController::membervalidation'); $routes->get('generateExcel', 'TestingController::generateExcel'); $routes->get('logo_renaming','TestingController::logo_renaming'); + // $routes->get('createDefaultMailTempalteInDB','TestingController::createDefaultMailTempalteInDB'); }); $routes->cli('cli/testcli', 'TestingController::testcli'); diff --git a/app/Controllers/ClientController.php b/app/Controllers/ClientController.php index e09c74ec..9f367e97 100755 --- a/app/Controllers/ClientController.php +++ b/app/Controllers/ClientController.php @@ -869,6 +869,12 @@ class ClientController extends AdminController if ($insert) { $client_data = $this->clientModel->where(['id' => $insert, 'is_active' => 1])->first(); + + $client_id = $insert; + $default_template_creation = $this->createDefaultMailTemplate($client_id , $client_data); + if($default_template_creation == false){ + $this->myLogger->logme('error', 'Default Mail Template Creation Failed for Client ID: {data}', ['data' => $client_id]); + } return $this->respond(['status' => true, 'code' => 200, 'data' => $client_data], 200); } else { return $this->respond(['status' => false, 'code' => 404, 'message' => 'no data found'], 200); @@ -5640,11 +5646,11 @@ class ClientController extends AdminController public function sendextraparam() { - // $data = db_connect()->table('jobs')->where('id', 1677)->get()->getRowArray(); - // // dd($data); - // $return = $this->updatePolicyTransactionDataWhileClinetPolicyUpdate(json_decode($data['payload'], true)); - // dd($return); - // die; + // $data = db_connect()->table('jobs')->where('id', 1677)->get()->getRowArray(); + // // dd($data); + // $return = $this->updatePolicyTransactionDataWhileClinetPolicyUpdate(json_decode($data['payload'], true)); + // dd($return); + // die; // $employeeController = new EmployeeController(); // $employeeController->truncateFileData('633'); @@ -5662,15 +5668,16 @@ class ClientController extends AdminController // ---------- EMP SERVICE CONTROLLER -------------------------------------------------------------------------------- $empServiceController = new EmployeeServiceController(); - $res = $empServiceController->excelFileFormatValidation(['file_id' => '2055']); + // $res = $empServiceController->excelFileFormatValidation(['file_id' => '1126']); // $res = $empServiceController->excelFileDataValidation(['file_id' => '865']); // $res = $empServiceController->employeesOnboardPreprocess(['file_id' => 726]); // $res = $empServiceController->employeesOnboardProcess(['file_id' => 835]); // $res = $empServiceController->employeesEnrollmentInsert(['file_id' => 836]); - // $res = $empServiceController->employeesSIEnhanceProcess(['file_id' => '978']); + // $res = $empServiceController->employeesSIEnhanceProcess(['file_id' => '1131']); // $res = $empServiceController->employeeDisembark(['file_id' => '1681']); - // $res = $empServiceController->employeesCorrectionProcess(['file_id' => '2033']); - dd($res); + // $res = $empServiceController->employeesCorrectionProcess(['file_id' => '2033']); + // $res = $empServiceController->compareMemberDataAndInceptionData(['file_id' => '1126']); + // dd($res); $EmployeeMultiEventServiceController = new EmployeeMultiEventServiceController(); // $res = $EmployeeMultiEventServiceController->constructMultiEventData(['file_id' => '1069']); @@ -5730,8 +5737,8 @@ class ClientController extends AdminController // $res = $EmpDataServiceController->generateExcelForCorrection($batch_data); // $res = $EmpDataServiceController->importInceptionFileValidation(['file_id' => 1932]); die; // $res = $EmpDataServiceController->importDeletionValidation(['file_id' => 304]); //for live - // $res = $EmpDataServiceController->importSIEnhancementUpdateEndorsementID(['file_id' => 1199]); //for live - // $res = $EmpDataServiceController->importSIEnhancementValidation(['file_id' => 2496]); //for live + // $res = $EmpDataServiceController->importSIEnhancementUpdateEndorsementID(['file_id' => 387]); //for live + // $res = $EmpDataServiceController->importSIEnhancementValidation(['file_id' => 387]); //for live // $res = $EmpDataServiceController->importInceptionUpdateTPAandUHID(['file_id' => 214]); //for live // $res = $EmpDataServiceController->importInceptionUpdateTPAandUHID(['file_id' => 310]); dd($res);//for live // $res = $EmpDataServiceController->getInceptionBasePremium(["13332","13333","13334","13335","13336"]); dd($res);//for live @@ -7731,9 +7738,76 @@ class ClientController extends AdminController return true; } + public function createDefaultMailTemplate($client_id , $client_data){ + + $member_welcome_mail_template = $this->notificationModel->where('client_id',NULL)->where('template_name','member_welcome_mail')->get()->getResultArray()[0]??[]; + + $member_remainder_mail_template = $this->notificationModel->where('client_id',NULL)->where('template_name','member_reminder_mail')->get()->getResultArray()[0]??[]; + + $member_review_and_summary_mail_template = $this->notificationModel->where('client_id',NULL)->where('template_name','member_review_and_summary_mail')->get()->getResultArray()[0]??[]; + + $default_member_welcome_mail_template = [ + 'client_id' => $client_id, + 'template_name' => 'member_welcome_mail', + 'subject' => $member_welcome_mail_template['subject']??'', + 'mail_content' => $member_welcome_mail_template['mail_content']??'', + 'mail_content_json'=> $member_welcome_mail_template['mail_content_json']??'', + + 'created_by' => get_session_userid(), + 'created_at' => date('Y-m-d H:i:s'), + 'updated_by' => null, + 'updated_at' => date('Y-m-d H:i:s'), + 'mail_content_copy'=> null + ]; + + $default_member_remainder_mail_template = [ + 'client_id' => $client_id, + 'template_name' => 'member_reminder_mail', + 'subject' => $member_remainder_mail_template['subject']??'', + 'mail_content' => $member_remainder_mail_template['mail_content']??'', + 'mail_content_json'=> $member_remainder_mail_template['mail_content_json']??'', + + 'created_by' => get_session_userid(), + 'created_at' => date('Y-m-d H:i:s'), + 'updated_by' => null, + 'updated_at' => date('Y-m-d H:i:s'), + 'mail_content_copy'=> null + ]; + + $default_member_review_and_summary_mail_template = [ + 'client_id' => $client_id, + 'template_name' => 'member_review_and_summary_mail', + 'subject' => $member_review_and_summary_mail_template['subject']??'', + 'mail_content' => $member_review_and_summary_mail_template['mail_content']??'', + 'mail_content_json'=> $member_review_and_summary_mail_template['mail_content_json']??'', + + 'created_by' => get_session_userid(), + 'created_at' => date('Y-m-d H:i:s'), + 'updated_by' => null, + 'updated_at' => date('Y-m-d H:i:s'), + 'mail_content_copy'=> null + ]; + + $this->myLogger->logme('error', 'Default Mail Template Data ' . json_encode([ + $default_member_welcome_mail_template, + $default_member_remainder_mail_template, + $default_member_review_and_summary_mail_template + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + $default_templates_inserted = $this->notificationModel->insertBatch([ + $default_member_welcome_mail_template, + $default_member_remainder_mail_template, + $default_member_review_and_summary_mail_template + ]); + + + return $default_templates_inserted ? true : false; + + + } + diff --git a/app/Controllers/EmpDataServiceController.php b/app/Controllers/EmpDataServiceController.php index 1c9fac18..b57ad0f0 100755 --- a/app/Controllers/EmpDataServiceController.php +++ b/app/Controllers/EmpDataServiceController.php @@ -1457,6 +1457,47 @@ class EmpDataServiceController extends BaseController //get the employee data for excel file validation $employee_data = $this->employeePolicyModel->getInceptionEmployeeDataForExportExcel($ref_data, 1); + // ----------------- CD BALANCE CHECK --------------------------------------------------------------------------- + + $cash_balance = $this->clientDepositModel + ->where('cd_ac_pk', $client_policy_data['cd_ac_pk']) + ->where('is_active', 1) + ->orderBy('id', 'DESC') + ->first(); + + if ($cash_balance == null) { + $balance = $this->CDMasterModel + ->where('client_id', $file['client_id']) + ->where('insurer_id', $client_policy_data['insurer_id']) + ->where('id', $client_policy_data['cd_ac_pk']) + ->first(); + + $cash_balance['balance'] = $balance['opening_bal']; + } + + // Calculate the total amount from the objects + $totals = 0; + foreach ($employee_data as $item) { + $totals = $totals + $item['total']; + } + + $totals = round($totals, 2); + + //check CD amt insufficient only insurer, not tpa + if($file['insurer_or_tpa'] == 'insurer') + { + if (!empty($cash_balance)) { + if ((int) $cash_balance['balance'] < (int) $totals) { + $this->myLogger->logme('error', 'Inception export failed due to insufficient deposit amount. CASH BALANCE : {balance} and TOTAL AMOUNT : {total}', ['balance' => $cash_balance['balance'], 'total' => $totals]); + $this->batchFileModel->where('id', $file_id)->set(['status' => 'failed-7', 'error_data' => 'Insufficient deposit balance. Available CD Balance: ' . $cash_balance['balance'] . ', Excel Total Amount: ' . $totals])->update(); + return ['status' => 'error', 'message' => 'Insufficient deposit balance. Available CD Balance: ' . $cash_balance['balance'] . ', Required Amount: ' . $totals]; + } + } + } + + // ---------------- END CD BALANCE CHECK ---------------------------------------------------------------------------- + + if ($employee_data == null || empty($employee_data)) { if ($insurer_or_tpa == 'tpa') { @@ -2569,6 +2610,7 @@ class EmpDataServiceController extends BaseController 'event_type' => $file['event_type'], ]; + $client_policy_data = $this->clientPolicyModel->where('id', $client_policy_id)->first(); $file_name_with_path = WRITEPATH . "/uploads/import_excel/" . $file['file_name']; @@ -2691,6 +2733,47 @@ class EmpDataServiceController extends BaseController // dd($endorsement_data, $excel_data); + // ----------------- CD BALANCE CHECK --------------------------------------------------------------------------- + + $cash_balance = $this->clientDepositModel + ->where('cd_ac_pk', $client_policy_data['cd_ac_pk']) + ->where('is_active', 1) + ->orderBy('id', 'DESC') + ->first(); + + if ($cash_balance == null) { + $balance = $this->CDMasterModel + ->where('client_id', $file['client_id']) + ->where('insurer_id', $client_policy_data['insurer_id']) + ->where('id', $client_policy_data['cd_ac_pk']) + ->first(); + + $cash_balance['balance'] = $balance['opening_bal']; + } + + // Calculate the total amount from the objects + $totals = 0; + foreach ($endorsement_data as $item) { + $totals = $totals + $item['total']; + } + + $totals = round($totals, 2); + + //check CD amt insufficient only insurer, not tpa + if($file['insurer_or_tpa'] == 'insurer') + { + if (!empty($cash_balance)) { + if ((int) $cash_balance['balance'] < (int) $totals) { + $this->myLogger->logme('error', 'Inception export failed due to insufficient deposit amount. CASH BALANCE : {balance} and TOTAL AMOUNT : {total}', ['balance' => $cash_balance['balance'], 'total' => $totals]); + $this->batchFileModel->where('id', $file_id)->set(['status' => 'failed-7', 'error_data' => 'Insufficient deposit balance. Available CD Balance: ' . $cash_balance['balance'] . ', Excel Total Amount: ' . $totals])->update(); + return ['status' => 'error', 'message' => 'Insufficient deposit balance. Available CD Balance: ' . $cash_balance['balance'] . ', Required Amount: ' . $totals]; + } + } + } + + // ---------------- END CD BALANCE CHECK ---------------------------------------------------------------------------- + + if ($endorsement_data == null || empty($endorsement_data)) { @@ -3119,6 +3202,7 @@ class EmpDataServiceController extends BaseController $empData['rata_premimum'] = $value[16]; $empData['gst'] = $value[17]; $empData['created_by'] = $user_id; + $empData['old_basic_cover_si'] = $value[9]; $emp_details[] = $empData; } @@ -3139,11 +3223,41 @@ class EmpDataServiceController extends BaseController // $insertedIds[] = $startId + $i; // } + // $insertedIds = []; + // foreach ($emp_details as $emp) { + + // $old_si_value = $emp['old_basic_cover_si']; + // $new_si_value = $emp['basic_cover_si']; + + // if($old_si_value < $new_si_value){ + // $insertedIds['si_adjustment'] = 2; + // }else{ + // $insertedIds['si_adjustment'] = 1; + // } + + // unset($emp['old_basic_cover_si']); + // $insertedIds['pk'] = $this->employeePolicyModel->insert($emp); + // } + $insertedIds = []; foreach ($emp_details as $emp) { - $insertedIds[] = $this->employeePolicyModel->insert($emp); - } + $old_si_value = $emp['old_basic_cover_si']; + $new_si_value = $emp['basic_cover_si']; + + // Determine SI adjustment type + $si_adjustment = ($old_si_value < $new_si_value) ? 1 : 2; + + unset($emp['old_basic_cover_si']); + + // Insert and store PK with adjustment info + $pk = $this->employeePolicyModel->insert($emp); + + $insertedIds[] = [ + 'pk' => $pk, + 'si_adjustment' => $si_adjustment + ]; + } // dd($insertedIds); $this->employeePolicyModel->bulkUpdateForEndorsement($endorsement_details); @@ -3158,7 +3272,6 @@ class EmpDataServiceController extends BaseController 'amount' => $rounded_totals, ]); - $this->myLogger->logme('error', 'SI Enhancement Update Endorsement ID -- Employee count : {data}', ['data' => $emp_count]); $this->myLogger->logme('error', 'SI Enhancement Update Endorsement ID -- Batch File status : {data}', ['data' => $status_val]); @@ -4195,60 +4308,164 @@ class EmpDataServiceController extends BaseController } - public function cashDepositCalculationForSIEnhancement($arrayData) - { - // return $arrayData; + // public function cashDepositCalculationForSIEnhancement($arrayData) + // { + // // return $arrayData; + // if (!empty($arrayData)) { + + // $client_branch_data = $this->clientBranchModel->where('id', $arrayData['client_branch_id'])->first(); + // $units = json_decode($client_branch_data['units']); + + // foreach($units as $unit) + // { + + // $amount = $this->employeePolicyModel->query(" + // SELECT SUM(rata_premimum + gst) AS total_sum + // FROM employee_polices + // JOIN employees ON employees.id = employee_polices.employee_id + // WHERE employees.unit = '$unit' + // AND employee_polices.id IN (" . implode(',', $arrayData['employeeIds']) . ") + // ")->getRow(); + + // if($amount){ + + // $insurer_id = $this->clientPolicyModel->where('id', $arrayData['client_policy_id'])->first(); + // $description = 'The following amount of ' . round($amount->total_sum, 2) . ' has been credited for the ' . $arrayData['count'] . ' employees at ' . remove_underscore_capitalize_first_letter($arrayData['event_name']) . ' to ' . remove_underscore_capitalize_first_letter($arrayData['policy_name']) . '.'; + + // $data = [ + + // 'amount' => $amount->total_sum, + // 'sub_type_id' => 4, + // 'client_id' => $arrayData['client_id'], + // 'client_policy_id' => $arrayData['client_policy_id'], + // 'endorsement_no' => $arrayData['endorsement_no'] ?? null, + // 'cd_ac_no' => $arrayData['cd_ac_no'] ?? null, + // 'insurer_id' => $insurer_id['insurer_id'], + // 'unit' => $unit, + // 'description' => $description, + // 'transaction_type' => 'Debit', + // 'updated_by' => $arrayData['user_id'], + // 'event_name' => $arrayData['event_name'], + // 'is_active' => 1, + // 'cd_ac_pk' => $insurer_id['cd_ac_pk'] + // ]; + + // $response = DepositHelper::saveDeposit($data, $arrayData['user_id']); + // } + // } + + // $msg = "SI Enhancement Cash Deposite Updated Successfully "; + // return [$msg]; + + // // print_r($response); + // // $query = $this->employeePolicyModel->getLastQuery(); + // // echo $query . "
"; + + // } else { + // return 0; + // } + // } + + public function cashDepositCalculationForSIEnhancement($arrayData) + { if (!empty($arrayData)) { $client_branch_data = $this->clientBranchModel->where('id', $arrayData['client_branch_id'])->first(); $units = json_decode($client_branch_data['units']); - foreach($units as $unit) - { + foreach ($units as $unit) { - $amount = $this->employeePolicyModel->query(" - SELECT SUM(rata_premimum + gst) AS total_sum - FROM employee_polices - JOIN employees ON employees.id = employee_polices.employee_id - WHERE employees.unit = '$unit' - AND employee_polices.id IN (" . implode(',', $arrayData['employeeIds']) . ") - ")->getRow(); + $si_enhance_amt = 0; + $si_decrease_amt = 0; - if($amount){ + foreach ($arrayData['employeeIds'] as $value) { - $insurer_id = $this->clientPolicyModel->where('id', $arrayData['client_policy_id'])->first(); - $description = 'The following amount of ' . round($amount->total_sum, 2) . ' has been credited for the ' . $arrayData['count'] . ' employees at ' . remove_underscore_capitalize_first_letter($arrayData['event_name']) . ' to ' . remove_underscore_capitalize_first_letter($arrayData['policy_name']) . '.'; + // If $value is an array, get its elements; otherwise, assign defaults + $pk = is_array($value) ? ($value['pk'] ?? null) : $value; + $si_adjustment = is_array($value) ? ($value['si_adjustment'] ?? null) : $value; + + $query = " + SELECT SUM(rata_premimum + gst) AS total_sum + FROM employee_polices + JOIN employees ON employees.id = employee_polices.employee_id + WHERE employees.unit = '{$unit}' + AND employee_polices.id = '{$pk}' + "; + + $amount = $this->employeePolicyModel->query($query)->getRow(); + + if ($amount && $amount->total_sum > 0) { + if ($si_adjustment == 2) { + $si_decrease_amt += $amount->total_sum; + } else { + $si_enhance_amt += $amount->total_sum; + } + } + } + + // Save Enhancement amount + if ($si_enhance_amt > 0) { + $policy_data = $this->clientPolicyModel->where('id', $arrayData['client_policy_id'])->first(); + + $description = 'An amount of ' . round($si_enhance_amt, 2) . + ' has been debited for ' . $arrayData['count'] . ' employees under ' . + remove_underscore_capitalize_first_letter($arrayData['event_name']) . + ' in ' . remove_underscore_capitalize_first_letter($arrayData['policy_name']) . '.'; $data = [ - - 'amount' => $amount->total_sum, + 'amount' => round($si_enhance_amt, 2), 'sub_type_id' => 4, 'client_id' => $arrayData['client_id'], 'client_policy_id' => $arrayData['client_policy_id'], 'endorsement_no' => $arrayData['endorsement_no'] ?? null, 'cd_ac_no' => $arrayData['cd_ac_no'] ?? null, - 'insurer_id' => $insurer_id['insurer_id'], + 'insurer_id' => $policy_data['insurer_id'], 'unit' => $unit, 'description' => $description, 'transaction_type' => 'Debit', 'updated_by' => $arrayData['user_id'], 'event_name' => $arrayData['event_name'], 'is_active' => 1, - 'cd_ac_pk' => $insurer_id['cd_ac_pk'] + 'cd_ac_pk' => $policy_data['cd_ac_pk'] ]; - $response = DepositHelper::saveDeposit($data, $arrayData['user_id']); + DepositHelper::saveDeposit($data, $arrayData['user_id']); + } + + // Save Decrease amount + if ($si_decrease_amt > 0) { + + $policy_data = $this->clientPolicyModel->where('id', $arrayData['client_policy_id'])->first(); + + $description = 'An amount of ' . round($si_decrease_amt, 2) . + ' has been credited for ' . $arrayData['count'] . ' employees due to a decrease in Sum Insured (SI) under ' . + remove_underscore_capitalize_first_letter($arrayData['event_name']) . + ' in ' . remove_underscore_capitalize_first_letter($arrayData['policy_name']) . '.'; + + $data = [ + 'amount' => round($si_decrease_amt, 2), + 'sub_type_id' => 4, + 'client_id' => $arrayData['client_id'], + 'client_policy_id' => $arrayData['client_policy_id'], + 'endorsement_no' => $arrayData['endorsement_no'] ?? null, + 'cd_ac_no' => $arrayData['cd_ac_no'] ?? null, + 'insurer_id' => $policy_data['insurer_id'], + 'unit' => $unit, + 'description' => $description, + 'transaction_type' => 'Credit', + 'updated_by' => $arrayData['user_id'], + 'event_name' => $arrayData['event_name'], + 'is_active' => 1, + 'cd_ac_pk' => $policy_data['cd_ac_pk'] + ]; + + DepositHelper::saveDeposit($data, $arrayData['user_id']); } } - $msg = "SI Enhancement Cash Deposite Updated Successfully "; + $msg = "SI Adjustment Cash Deposit Updated Successfully."; return [$msg]; - - // print_r($response); - // $query = $this->employeePolicyModel->getLastQuery(); - // echo $query . "
"; - } else { return 0; } diff --git a/app/Controllers/EmployeeController.php b/app/Controllers/EmployeeController.php index 3bf6a341..0005c651 100755 --- a/app/Controllers/EmployeeController.php +++ b/app/Controllers/EmployeeController.php @@ -171,7 +171,7 @@ class EmployeeController extends AdminController return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'no data found'], 200); } else { - return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $file['reason']], 200); + return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $file['reason'], 'is_comparison_skipped' => $file['is_comparison_skipped']], 200); } } @@ -388,13 +388,11 @@ class EmployeeController extends AdminController batch_files.client_branch_id, CASE - WHEN batch_files.status = 'partially success' OR batch_files.status = 'in-progress-partially' THEN - batch_files.error_data - ELSE - NULL + WHEN batch_files.status IN ('partially success', 'in-progress-partially', 'failed-7') + THEN batch_files.error_data + ELSE NULL END AS error_data, - clients.short_name as client_short_name, client_branch.branch_name, client_policy.policy_no, @@ -1193,7 +1191,7 @@ class EmployeeController extends AdminController // --------------- For E-Card Download ----------------------------------------------------------------------------------------------------- - //E-CARD DOWNLOAD FUNCTION USING HTML PRINT + //E-CARD DOWNLOAD FUNCTION USING HTML PRINT ( Not in use ) do not delete public function generateIDCardForEmployeeUsingHtml($rand_string, $people = 0) { // dd($rand_string, $people); @@ -1418,7 +1416,7 @@ class EmployeeController extends AdminController echo $htmlContent; } - //E-CARD DOWNLOAD FUNCTION USING DOM PDF ( CURRENTLY USING THIS ) + //E-CARD DOWNLOAD FUNCTION USING DOM PDF ( CURRENTLY USING THIS ) Dompdf public function generateIDCardForEmployee($rand_string, $people = 0, $mode = 0) { // dd($rand_string, $people); @@ -1470,8 +1468,8 @@ class EmployeeController extends AdminController // Step 3: Prepare template path $template_data_path = WRITEPATH . 'e_card_template/'; // $tpa_short_name = strtolower(str_replace(' ', '_', $get_emp_code_and_client_policy_id['short_name'])) . '.html'; - $tpa_short_name = 'common.html'; - // $tpa_short_name = 'new_ecard.html'; + // $tpa_short_name = 'common.html'; + $tpa_short_name = 'new_ecard.html'; $final_path = $template_data_path . $tpa_short_name; $this->myLogger->logme('error', 'Checking if template file exists at: ' . $final_path); @@ -1495,6 +1493,7 @@ class EmployeeController extends AdminController $value['back_card'] = "Nhance_Ecard_working_1_Back.png"; $placeholders = [ + '{CLIENT_NAME}' => $value['client_name'], '{TPA_ID}' => $value['tpa_id'], '{NAME}' => $value['name'], @@ -1506,9 +1505,6 @@ class EmployeeController extends AdminController '{POLICY_START_DATE}' => date('d-M-Y', strtotime($value['policy_start_date'])), '{POLICY_NO}' => $value['policy_no'], '{INSURER_NAME}' => strtoupper($value['insurer_name']), - '{INSURER_LOGO}' => base_url() . 'public/uploads/logo/' . $value['insurer_logo'], - '{FRONT_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['front_card'], - '{BACK_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['back_card'], '{EMP_ID}' => $value['emp_code'], '{SI_AMT}' => $value['basic_cover_si'], '{CORPORATE_NAME}' => $value['client_name'], @@ -1516,15 +1512,33 @@ class EmployeeController extends AdminController '{TPA_NAME}' => $value['tpa_name'], '{INSURER_BRANCH}' => $value['insurer_branch_city'], '{RELATION}' => $value['relationship'], - '{TPA_LOGO}' => base_url() . 'public/uploads/logo/' . $value['tpa_logo'], - '{MEDI_USER}' => base_url() . 'public/e_card_imgs/medi_uesr.jpg', - '{MEDI_INSURER}' => base_url() . 'public/e_card_imgs/Magma.png', - '{MEDI_BARCODE}' => base_url() . 'public/e_card_imgs/borcode.jpeg', - '{QR_ANDROID}' => base_url() . 'public/e_card_imgs/android.png', - '{QR_IOS}' => base_url() . 'public/e_card_imgs/ios.png', - '{QR_ANDROID_2}' => base_url() . 'public/e_card_imgs/play_store.png', - '{QR_IOS_2}' => base_url() . 'public/e_card_imgs/appstore.png', - '{NHANCE_N_LOGO}' => base_url() . 'public/assets/images/Nhance_Favi.png', + + '{TPA_LOGO}' => getFileIfExists('uploads/logo/' . $value['tpa_logo']), + '{MEDI_USER}' => getFileIfExists('e_card_imgs/medi_uesr.jpg'), + '{MEDI_INSURER}' => getFileIfExists('e_card_imgs/Magma.png'), + '{MEDI_BARCODE}' => getFileIfExists('e_card_imgs/borcode.jpeg'), + '{QR_ANDROID}' => getFileIfExists('e_card_imgs/android.png'), + '{QR_IOS}' => getFileIfExists('e_card_imgs/ios.png'), + '{QR_ANDROID_2}' => getFileIfExists('e_card_imgs/play_store.png'), + '{QR_IOS_2}' => getFileIfExists('e_card_imgs/appstore.png'), + '{NHANCE_N_LOGO}' => getFileIfExists('assets/images/Nhance_Favi.png'), + '{INSURER_LOGO}' => getFileIfExists('uploads/logo/' . $value['insurer_logo']), + '{FRONT_CARD}' => getFileIfExists('uploads/template_bg/' . $value['front_card']), + '{BACK_CARD}' => getFileIfExists('uploads/template_bg/' . $value['back_card']), + + // '{TPA_LOGO}' => base_url() . 'public/uploads/logo/' . $value['tpa_logo'], + // '{MEDI_USER}' => base_url() . 'public/e_card_imgs/medi_uesr.jpg', + // '{MEDI_INSURER}' => base_url() . 'public/e_card_imgs/Magma.png', + // '{MEDI_BARCODE}' => base_url() . 'public/e_card_imgs/borcode.jpeg', + // '{QR_ANDROID}' => base_url() . 'public/e_card_imgs/android.png', + // '{QR_IOS}' => base_url() . 'public/e_card_imgs/ios.png', + // '{QR_ANDROID_2}' => base_url() . 'public/e_card_imgs/play_store.png', + // '{QR_IOS_2}' => base_url() . 'public/e_card_imgs/appstore.png', + // '{NHANCE_N_LOGO}' => base_url() . 'public/assets/images/Nhance_Favi.png', + // '{INSURER_LOGO}' => base_url() . 'public/uploads/logo/' . $value['insurer_logo'], + // '{FRONT_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['front_card'], + // '{BACK_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['back_card'], + ]; $placeholders['{LEVELS}'] = $this->generateAcmAndMForEcard($client_id); @@ -3132,5 +3146,31 @@ class EmployeeController extends AdminController } } + // function for skip the Inception and Member data validation + public function proceedExcelFileDataValidation() + { + $file_id = $this->request->getGet('file_id'); + $not_skiped = $this->request->getGet('not_skiped') ?? null; + + if(!empty($not_skiped)){ + $file_model = new FileModel(); + $file_model->where('id', $file_id)->set(['is_comparison_skipped' => 0])->update(); + $message = "Inception and Member data comparision continuted by the user id : " . get_session_userid(); + $this->myLogger->logme('error', $message); + return $this->respond(['status' => true, 'code' => 200, 'message' => 'Inception and Member data comparision continued'], 200); + } + + if(!empty($file_id)){ + $r = Jobs::addJob(['job_name' => 'excelFileDataValidation','payload' => ['file_id' => $file_id]]); + $message = "Inception and Member data comparision skiped successfully by the user id : " . get_session_userid(); + $this->myLogger->logme('error', $message); + $file_model = new FileModel(); + $file_model->where('id', $file_id)->set(['is_comparison_skipped' => 1])->update(); + return $this->respond(['status' => true, 'code' => 200, 'message' => 'Inception and Member data comparision skiped successfully!'], 200); + }else{ + return $this->respond(['status' => false, 'code' => 500, 'message' => 'Failed to skip the comparison!'], 200); + } + } + } diff --git a/app/Controllers/EmployeeMultiEventServiceController.php b/app/Controllers/EmployeeMultiEventServiceController.php index e3027d01..78216f37 100644 --- a/app/Controllers/EmployeeMultiEventServiceController.php +++ b/app/Controllers/EmployeeMultiEventServiceController.php @@ -26,6 +26,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet; use Kint\Kint; use App\Helpers\ExcelSanitizeHelper; +use App\Models\LeadsModel; class EmployeeMultiEventServiceController extends BaseController { @@ -140,7 +141,7 @@ class EmployeeMultiEventServiceController extends BaseController 'is_mandatory' => ['I', 'A', 'DA'], 'data_type' => 'str', 'format' => null, - 'allowed_values' => ['M', 'F'] + 'allowed_values' => ['M', 'F', 'Male', 'Female', 'male', 'female'] ], 'relationship' => [ 'col_idx' => 5, @@ -524,7 +525,7 @@ class EmployeeMultiEventServiceController extends BaseController 'is_mandatory' => ['I', 'A', 'DA', 'E'], 'data_type' => 'str', 'format' => null, - 'allowed_values' => ['M', 'F'] + 'allowed_values' => ['M', 'F', 'Male', 'Female', 'male', 'female'] ], 'relationship' => [ 'col_idx' => 5, @@ -889,8 +890,108 @@ class EmployeeMultiEventServiceController extends BaseController ] ]; - - + protected $member_data_excel_columns = [ + 'sno' => [ + 'col_idx' => 0, + 'col_cell_name' => 'A', + 'col_name' => 'Sl no', + 'is_mandatory' => false, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'emp_code' => [ + 'col_idx' => 1, + 'col_cell_name' => 'B', + 'col_name' => 'Emp Code', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'name' => [ + 'col_idx' => 2, + 'col_cell_name' => 'C', + 'col_name' => 'Name', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'relationship' => [ + 'col_idx' => 3, + 'col_cell_name' => 'D', + 'col_name' => 'Relationship', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => [ + 'Self', 'Spouse', 'Son', 'Daughter', 'Father', 'Mother', + 'Father-in-law', 'Mother-in-law', + 'self', 'spouse', 'son', 'daughter', 'father', 'mother', + 'father-in-law', 'mother-in-law' + ], + 'custom' => 'check_relationship_for_member_data', + 'params' => ['row', 'relationship', 'columns_to_check'] + ], + 'gender' => [ + 'col_idx' => 4, + 'col_cell_name' => 'E', + 'col_name' => 'Gender', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => ['M', 'F', 'Male', 'Female', 'male', 'female'] + ], + 'dob' => [ + 'col_idx' => 5, + 'col_cell_name' => 'F', + 'col_name' => 'DOB', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => 'd-M-Y', + 'allowed_values' => null, + 'age_validation' => true, + // 'custom' => 'check_dob_diff', + // 'params' => ['row', 'relationship', 'default_age_ratio', 'policy_details'] + ], + 'age' => [ + 'col_idx' => 6, + 'col_cell_name' => 'G', + 'col_name' => 'Age', + 'is_mandatory' => true, + 'data_type' => 'int', + 'format' => null, + 'allowed_values' => null + ], + 'email' => [ + 'col_idx' => 7, + 'col_cell_name' => 'H', + 'col_name' => 'Email', + 'is_mandatory' => false, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'mobile' => [ + 'col_idx' => 8, + 'col_cell_name' => 'I', + 'col_name' => 'Mobile', + 'is_mandatory' => false, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'si' => [ + 'col_idx' => 9, + 'col_cell_name' => 'J', + 'col_name' => 'SI', + 'is_mandatory' => false, + 'data_type' => 'int', + 'format' => null, + 'allowed_values' => null, + ] + ]; public function __construct() { @@ -991,6 +1092,9 @@ class EmployeeMultiEventServiceController extends BaseController $params["action"] = "inception"; $params["file_path"] = $file_paths['inception']; $error[] = $this->excelFileFormatValidation($params); + if (isset($error['error_data']) && count($error['error_data']) == 0) { + $error[] = $this->compareMemberDataAndInceptionData($params); + } } //addition @@ -1357,6 +1461,13 @@ class EmployeeMultiEventServiceController extends BaseController $enrollment_keys = array_keys($enrollment_columns_to_check); } + // for this condition to avoid 5,00,000 to 500000 + if($current_column_action == 'SI'){ + $row[3] = removeNumberFormatting($row[3]); + }else if(in_array($current_column_action, ['I','DA', 'MI', 'A'])){ + $row[6] = removeNumberFormatting($row[6]); + } + //iterate each row for columns validations foreach ($row as $col_key => $col) { $is_mandatory = $columns_to_check[$keys[$col_key]]['is_mandatory']; @@ -1495,6 +1606,16 @@ class EmployeeMultiEventServiceController extends BaseController $columns_to_check = $this->inception_excel_columns; } + $current_column_action = null; + if($file['action'] == 'inception'){ $current_column_action = 'I'; } + else if($file['action'] == 'addition'){ $current_column_action = 'A'; } + else if($file['action'] == 'dependent_addition'){ $current_column_action = 'DA'; } + else if($file['action'] == 'deletion'){ $current_column_action = 'D'; } + else if($file['action'] == 'correction'){ $current_column_action = 'C'; } + else if($file['action'] == 'si_enhancement'){ $current_column_action = 'SI'; } + else if($file['action'] == 'enrollment'){ $current_column_action = 'I'; } + else if($file['action'] == 'missed_inception'){ $current_column_action = 'MI'; } + $columns_to_check = $this->syncColIndex($this->multievent_excel_columns, $columns_to_check); // print_rr($columns_to_check); @@ -1522,7 +1643,7 @@ class EmployeeMultiEventServiceController extends BaseController if (in_array($file['action'], ['inception', 'missed_inception', 'addition', 'dependent_addition', 'deletion', 'correction', 'si_enhancement', 'enrollment'])) // the below funcitons are only for I,DA,A { - $employee_data_group_by_family = data_group_by_family($excel_data, 'excel', ($file['action'] == 'enrollment' ? 'enrollment' : '')); + $employee_data_group_by_family = data_group_by_family($excel_data, 'excel', ($file['action'] == 'enrollment' ? 'enrollment' : ''), $current_column_action); // dd($employee_data_group_by_family); $is_self_available_in_policy_terms = false; if ($policy_details['policy_type_id'] == 3) // GMC parents @@ -1694,6 +1815,16 @@ class EmployeeMultiEventServiceController extends BaseController $columns_to_check = $this->inception_excel_columns; } + $current_column_action = null; + if($file['action'] == 'inception'){ $current_column_action = 'I'; } + else if($file['action'] == 'addition'){ $current_column_action = 'A'; } + else if($file['action'] == 'dependent_addition'){ $current_column_action = 'DA'; } + else if($file['action'] == 'deletion'){ $current_column_action = 'D'; } + else if($file['action'] == 'correction'){ $current_column_action = 'C'; } + else if($file['action'] == 'si_enhancement'){ $current_column_action = 'SI'; } + else if($file['action'] == 'enrollment'){ $current_column_action = 'I'; } + else if($file['action'] == 'missed_inception'){ $current_column_action = 'MI'; } + // get policy and rack details $policy_terms = $this->clientPolicyModel->getPolicyDetails($file['client_id'], $file['policy_id']); $policy_terms = (array) $policy_terms[0]; // convert obj to array @@ -1717,7 +1848,7 @@ class EmployeeMultiEventServiceController extends BaseController //get existing units in the current branch $existing_units = $this->clientBranchModel->getExisitingUnits(client_id: $file['client_id'], client_branch_id: $file['client_branch_id']); - $employee_data_group_by_family = data_group_by_family($excel_data); + $employee_data_group_by_family = data_group_by_family($excel_data, 'excel', '', $current_column_action); // dd($employee_data_group_by_family); foreach ($employee_data_group_by_family as $emp_id => $family) { @@ -2029,6 +2160,9 @@ class EmployeeMultiEventServiceController extends BaseController if (check_row_is_empty_or_null($row)) { break; } + + $row[3] = removeNumberFormatting($row[3]); + // echo '
START- ' . $row[2]; $employee = $this->employeeModel ->where('emp_code', $row[1]) @@ -2038,6 +2172,7 @@ class EmployeeMultiEventServiceController extends BaseController ->where('emp_status', 'active') ->where('is_active', 1) ->first(); + $employee_policy = $this->employeePolicyModel ->where('employee_id', $employee['id']) ->where('client_policy_id', $file['policy_id']) @@ -2052,8 +2187,11 @@ class EmployeeMultiEventServiceController extends BaseController ->where('emp_code', $employee['emp_code']) ->where('name', $employee['name']) ->where('field_name', 'basic_cover_si') + ->where('is_active', 1) + ->where('status !=', 'truncated') ->findAll(); // dd($existing_endorsements); + //make entry in endorsement table if (!count($existing_endorsements)) { //transform data to send @@ -2101,6 +2239,8 @@ class EmployeeMultiEventServiceController extends BaseController $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'], 'emp_code' => $employee['emp_code'], 'table_name' => 'employee_polices', 'actions' => 'si', 'name' => $employee['name'], 'field_name' => 'basic_cover_si', 'old_value' => $employee_policy['basic_cover_si'], 'new_value' => $row[3], 'created_by' => $file['created_by'], 'remarks' => 'general si enhancement', 'group_key' => $group_key, 'file_id' => $file['id'], 'status' => 'pending']); $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'], 'emp_code' => $employee['emp_code'], 'table_name' => 'employee_polices', 'actions' => 'si', 'name' => $employee['name'], 'field_name' => 'premium', 'old_value' => $employee_policy['premium'], 'new_value' => $calculated_data['policy_details']['premium'], 'created_by' => $file['created_by'], 'remarks' => 'general si enhancement', 'group_key' => $group_key, 'file_id' => $file['id'], 'status' => 'pending']); $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'], 'emp_code' => $employee['emp_code'], 'table_name' => 'employee_polices', 'actions' => 'si', 'name' => $employee['name'], 'field_name' => 'si_enhancement_date', 'old_value' => null, 'new_value' => change_date_format($row[4], 'd-M-Y', 'Y-m-d'), 'created_by' => $file['created_by'], 'remarks' => 'general si enhancement', 'group_key' => $group_key, 'file_id' => $file['id'], 'status' => 'pending']); + }else { + $this->myLogger->logme("error", 'Endorsement already exists for this employee ' . json_encode(['file_id' => $file_id, 'emp_code' => $employee['emp_code'], 'emp_name' => $employee['name']])); } } @@ -2125,10 +2265,9 @@ class EmployeeMultiEventServiceController extends BaseController foreach ($familiy_data as $fkey => $value) { if (is_array($value)) { - + if (isset($value['gender'])) { $value['gender'] = normalizeGender($value['gender'] );} if ($file['id'] == null || $value['temp']['source'] == 'excel' || (($file['action'] == 'dependent_addition' && ($value['temp']['premium_type'] == 1 && strtolower($value['relationship']) == 'self') || ($value['temp']['premium_type'] == 2 || $value['temp']['premium_type'] == null)))) //insert data come from excel and from db i.e. ( $file['id'] == null for enrollment data) { - $employee = $this->employeeModel->checkExistingEmp($value, $file['client_branch_id']); $policy_data = $value['policy_details']; $temp = $value['temp']; @@ -2881,6 +3020,135 @@ class EmployeeMultiEventServiceController extends BaseController return $temp; } + // --------- MEMBER DATA AND INCEPTION DATA COMPARISION ------------------------------------------------------------------------ + + public function compareMemberDataAndInceptionData($params) + { + $file_id = $params['file_id'] ?? null; + if (empty($file_id)) { + return ['status' => false, 'msg' => 'File ID is missing']; + } + + // ✅ Get File Data + $file = $this->fileModel->where(['is_active' => 1, 'id' => $file_id])->first(); + if (empty($file)) { + return ['status' => false, 'msg' => 'File not found in DB']; + } + + // ✅ Get Client Policy Data + $client_policy_data = $this->clientPolicyModel->where(['is_active' => 1, 'id' => $file['policy_id']])->first(); + if (empty($client_policy_data)) { + return ['status' => false, 'msg' => 'Client policy data not found in DB (policy_id: ' . $file['policy_id'] . ')']; + } + + // ✅ Get Lead Data + $leadModel = new LeadsModel(); + $lead_data = $leadModel->where(['is_active' => 1, 'id' => $client_policy_data['is_from_lead']])->first(); + if (empty($lead_data)) { + return ['status' => false, 'msg' => 'Lead data not found in DB (lead_id: ' . $client_policy_data['is_from_lead'] . ')']; + } + + // ✅ Define File Paths + // $inception_file_path = !empty($file['file_name']) ? WRITEPATH . "uploads/excel/" . $file['file_name'] : ''; + $member_file_path = !empty($lead_data['file_name']) ? WRITEPATH . "uploads/lead_files/" . $lead_data['file_name'] : ''; + + // ✅ Check Inception File + // if (empty($file['file_name']) || !file_exists($inception_file_path)) { + // $message = empty($file['file_name']) ? "Inception file name is missing" : "Inception physical file not found"; + // $this->myLogger->logme('error', "$message for file id $file_id"); + // $this->fileModel->update($file_id, [ + // 'status' => 'failed', + // 'reason' => json_encode(['error_summary' => [5], 'error_data' => $message]) + // ]); + // return ['error_summary' => [5], 'error_data' => $message]; + // } + + // ✅ Check Member File + if (empty($lead_data['file_name']) || !file_exists($member_file_path)) { + $message = empty($lead_data['file_name']) ? "Member file name is missing" : "Member data physical file not found"; + $this->myLogger->logme('error', "$message for lead id {$lead_data['id']}"); + $this->fileModel->update($file_id, [ + 'status' => 'failed', + 'reason' => json_encode(['error_summary' => [5], 'error_data' => $message]) + ]); + return ['error_summary' => [5], 'error_data' => $message]; + } + + + // ✅ Read Inception Excel + $inception_columns = $this->inception_excel_columns; + $inception_data = json_decode(file_get_contents($params['file_path'] ?? []), true); + // $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inception_file_path); + // $sheet = $spreadsheet->getActiveSheet(); + // $highestRow = $sheet->getHighestDataRow(); + // $allowedColumn = end($inception_columns)['col_cell_name']; + // $inception_data = $sheet->rangeToArray("A1:{$allowedColumn}{$highestRow}"); + // $inception_data = ExcelSanitizeHelper::sanitizeArrayData($inception_data); + + // ✅ Read Member Excel + $member_columns = $this->member_data_excel_columns; + $spreadsheet2 = \PhpOffice\PhpSpreadsheet\IOFactory::load($member_file_path); + $sheet2 = $spreadsheet2->getSheet(0); + $highestRow2 = $sheet2->getHighestDataRow(); + $allowedColumn2 = end($member_columns)['col_cell_name']; + $member_data = $sheet2->rangeToArray("A1:{$allowedColumn2}{$highestRow2}"); + $member_data = ExcelSanitizeHelper::sanitizeArrayData($member_data); + + // dd($inception_data, $member_data); + + // ✅ Compare Inception Data with Member Data + $result = ['error_type' => 2, 'error_summary' => [], 'error_data' => []]; + + $inception_data_count = count($inception_data); + $member_data_count = count($member_data); + + if ($inception_data_count !== $member_data_count) { + $result['error_summary'][] = 15; + $result['error_message'] = " + Inception Data Count: + {$inception_data_count}   + Member Data Count: + {$member_data_count}"; + } + + foreach ($inception_data as $inception_key => $inception_row) { + + // 🔹 If inception row is empty → stop all further processing + if (check_row_is_empty_or_null($inception_row)) { + break; + } + + $match_found = false; + + foreach ($member_data as $member_row) { + if ( + $inception_row[1] == $member_row[1] && // emp_id / emp_code + $inception_row[2] == $member_row[2] && // name_of_emp_dep / name + $inception_row[5] == $member_row[3] && // relationship + normalizeGender($inception_row[4]) == normalizeGender($member_row[4]) && // gender + $inception_row[3] == $member_row[5] && // dob + $inception_row[13] == $member_row[7] && // email + $inception_row[12] == $member_row[8] // phone / mobile + ) { + $match_found = true; + break; + } + } + + if (!$match_found) { + array_push($result['error_summary'], 14); + $result['error_data'][$inception_key]['sno']['error'][] = "This inception row was not found in the member data list."; + } + } + + // ✅ Handle Result + if (!empty($result['error_summary'])) { + $result['error_summary'] = array_count_values($result['error_summary']); + $this->myLogger->logme('error', "File ID $file_id comparison failed"); + } + + return $result; + } } diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index 1b7310b6..83015c20 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -53,6 +53,8 @@ use Illuminate\Http\Request; use App\Controllers\EmployeeServiceController; use App\Models\ClaimFilesModel; +use App\Models\TicketMailTemplateModel; +use Composer\Pcre\Preg; use Kreait\Firebase\Factory; use Kreait\Firebase\Messaging\CloudMessage; use Kreait\Firebase\Messaging\Notification; @@ -90,6 +92,7 @@ class EmployeeRestController extends AdminController protected $hrAccessControlModel; protected $insurerModel; protected $hrFileUploadModel; + protected $ticketMailTemplateModel; public function __construct() @@ -122,6 +125,7 @@ class EmployeeRestController extends AdminController $this->hrAccessControlModel = new HRAccessControlModel(); $this->insurerModel = new InsurerModel(); $this->hrFileUploadModel = new HrFileUploadModel(); + $this->ticketMailTemplateModel = new TicketMailTemplateModel(); } @@ -4174,7 +4178,11 @@ class EmployeeRestController extends AdminController ]; // Save into DB - $this->hrFileUploadModel->insert($data); + $result = $this->hrFileUploadModel->insert($data); + + if($result){ + $this->giveNotificationToClientsAccountManager($data); + } return $this->respondCreated([ 'status' => true, @@ -4188,6 +4196,45 @@ class EmployeeRestController extends AdminController } + private function giveNotificationToClientsAccountManager($data){ + + $client_name = $this->clientModel->where('id',$data['client_id'])->findAll()[0]['client_name'] ?? [] ; + + $account_manager_email = $this->clientRMModel->findAccountManagerEmail($data['client_id']); + + $templateName = "hr_endorsement_template"; + + $mailTemplate = $this->ticketMailTemplateModel->where('template_name', $templateName)->findAll()[0] ?? []; + + if(empty($mailTemplate)){ + //empty mail template please update the template in database or create one..!! + log_message("error","Empty mail template for inception_addition please update the template in database or create one..!!"); + return ; + } + + $data['file_action'] = ucwords(preg_replace("/_/", " ", $data['file_action'])); + + $mailTemplate['mail_content'] = str_replace('%file_action%', $data['file_action'] ?? '', $mailTemplate['mail_content']); + $mailTemplate['mail_content'] = str_replace('%client_name%', $client_name ?? '', $mailTemplate['mail_content']); + $mailTemplate['mail_content'] = str_replace('%policy_no%', $data['policy_no'] ?? '', $mailTemplate['mail_content']); + + $mailTemplate['subject'] = str_replace('%subject%',$data['file_action']??'',$mailTemplate['subject']); + $mailTemplate['subject'] = str_replace('%client_name%',$client_name??'',$mailTemplate['subject']); + + $from_mail = ""; + $to_mail = $account_manager_email; + $subject = $mailTemplate['subject']; + $message = $mailTemplate['mail_content']; + $cc_string = ""; + $attachments = ""; + $reply_to = ""; + $bcc_string = ""; + + + MailHelper::send_email(['from_mail' => $from_mail, 'mail' => $to_mail, 'cc' => $cc_string, 'subject' => $subject, 'message' => $message, 'attachments' => $attachments, 'reply_to' => $reply_to, 'bcc' => $bcc_string]); + + } + public function updateHrFileUploadData() { try { diff --git a/app/Controllers/EmployeeServiceController.php b/app/Controllers/EmployeeServiceController.php index 07bf7ad5..4ccf85a6 100755 --- a/app/Controllers/EmployeeServiceController.php +++ b/app/Controllers/EmployeeServiceController.php @@ -29,7 +29,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet; use Kint\Kint; use App\Helpers\ExcelSanitizeHelper; - +use App\Models\LeadsModel; class EmployeeServiceController extends AdminController { @@ -144,7 +144,7 @@ class EmployeeServiceController extends AdminController 'is_mandatory' => ['I', 'A', 'DA'], 'data_type' => 'str', 'format' => null, - 'allowed_values' => ['M', 'F'] + 'allowed_values' => ['M', 'F', 'Male', 'Female', 'male', 'female', 'MALE', 'FEMALE'] ], 'relationship' => [ 'col_idx' => 5, @@ -529,7 +529,8 @@ class EmployeeServiceController extends AdminController 'is_mandatory' => ['I', 'A', 'DA','E'], 'data_type' => 'str', 'format' => null, - 'allowed_values' => ['M', 'F'] + 'allowed_values' => ['M', 'F', 'Male', 'Female', 'male', 'female', 'MALE', 'FEMALE'] + ], 'relationship' => [ 'col_idx' => 5, @@ -643,21 +644,121 @@ class EmployeeServiceController extends AdminController ]; protected $enrollment_to_inception_mapping = [ - 0 => 0, // enrollment: sno (Sno) -> inception: sno (S.No) - 1 => 1, // enrollment: emp_code (Emp_Code) -> inception: emp_id (EMP ID) - 2 => 2, // enrollment: name (NAME OF EMP/DEP) -> inception: name_of_emp_dep (NAME OF EMP/DEP) - 3 => 8, // enrollment: doj (DOJ) -> inception: doj (DOJ) - 4 => 4, // enrollment: gender (Gender) -> inception: gender (Gender) - 5 => 5, // enrollment: relationship (Relation) -> inception: relationship (RELATIONSHIP) - 6 => 3, // enrollment: dob (DOB) -> inception: dob (DOB) - 7 => 13, // enrollment: email (Email) -> inception: email (Email) - 8 => 12, // enrollment: phone (Mobile) -> inception: phone (Phone) - 9 => 6, // enrollment: basic_cover_si (SI) -> inception: basic_cover_si (BASIC COVER SI) - 10 => 10, // enrollment: band_grade (Grade) -> inception: band_grade (Band/Grade) - 11 => 9 // enrollment: basic_pay (Basic Pay) -> inception: basic_pay (Basic Pay) - ]; - - + 0 => 0, // enrollment: sno (Sno) -> inception: sno (S.No) + 1 => 1, // enrollment: emp_code (Emp_Code) -> inception: emp_id (EMP ID) + 2 => 2, // enrollment: name (NAME OF EMP/DEP) -> inception: name_of_emp_dep (NAME OF EMP/DEP) + 3 => 8, // enrollment: doj (DOJ) -> inception: doj (DOJ) + 4 => 4, // enrollment: gender (Gender) -> inception: gender (Gender) + 5 => 5, // enrollment: relationship (Relation) -> inception: relationship (RELATIONSHIP) + 6 => 3, // enrollment: dob (DOB) -> inception: dob (DOB) + 7 => 13, // enrollment: email (Email) -> inception: email (Email) + 8 => 12, // enrollment: phone (Mobile) -> inception: phone (Phone) + 9 => 6, // enrollment: basic_cover_si (SI) -> inception: basic_cover_si (BASIC COVER SI) + 10 => 10, // enrollment: band_grade (Grade) -> inception: band_grade (Band/Grade) + 11 => 9 // enrollment: basic_pay (Basic Pay) -> inception: basic_pay (Basic Pay) + ]; + protected $member_data_excel_columns = [ + 'sno' => [ + 'col_idx' => 0, + 'col_cell_name' => 'A', + 'col_name' => 'Sl no', + 'is_mandatory' => false, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'emp_code' => [ + 'col_idx' => 1, + 'col_cell_name' => 'B', + 'col_name' => 'Emp Code', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'name' => [ + 'col_idx' => 2, + 'col_cell_name' => 'C', + 'col_name' => 'Name', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'relationship' => [ + 'col_idx' => 3, + 'col_cell_name' => 'D', + 'col_name' => 'Relationship', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => [ + 'Self', 'Spouse', 'Son', 'Daughter', 'Father', 'Mother', + 'Father-in-law', 'Mother-in-law', + 'self', 'spouse', 'son', 'daughter', 'father', 'mother', + 'father-in-law', 'mother-in-law' + ], + 'custom' => 'check_relationship_for_member_data', + 'params' => ['row', 'relationship', 'columns_to_check'] + ], + 'gender' => [ + 'col_idx' => 4, + 'col_cell_name' => 'E', + 'col_name' => 'Gender', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => ['M', 'F', 'Male', 'Female', 'male', 'female', 'MALE', 'FEMALE'] + ], + 'dob' => [ + 'col_idx' => 5, + 'col_cell_name' => 'F', + 'col_name' => 'DOB', + 'is_mandatory' => true, + 'data_type' => 'str', + 'format' => 'd-M-Y', + 'allowed_values' => null, + 'age_validation' => true, + // 'custom' => 'check_dob_diff', + // 'params' => ['row', 'relationship', 'default_age_ratio', 'policy_details'] + ], + 'age' => [ + 'col_idx' => 6, + 'col_cell_name' => 'G', + 'col_name' => 'Age', + 'is_mandatory' => true, + 'data_type' => 'int', + 'format' => null, + 'allowed_values' => null + ], + 'email' => [ + 'col_idx' => 7, + 'col_cell_name' => 'H', + 'col_name' => 'Email', + 'is_mandatory' => false, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'mobile' => [ + 'col_idx' => 8, + 'col_cell_name' => 'I', + 'col_name' => 'Mobile', + 'is_mandatory' => false, + 'data_type' => 'str', + 'format' => null, + 'allowed_values' => null + ], + 'si' => [ + 'col_idx' => 9, + 'col_cell_name' => 'J', + 'col_name' => 'SI', + 'is_mandatory' => false, + 'data_type' => 'int', + 'format' => null, + 'allowed_values' => null, + ] + ]; public function __construct() { @@ -809,6 +910,13 @@ class EmployeeServiceController extends AdminController $enrollment_columns_to_check = $this->enrollment_excel_columns; $enrollment_keys = array_keys($enrollment_columns_to_check); } + + // for this condition to avoid 5,00,000 to 500000 + if($current_column_action == 'SI'){ + $row[3] = removeNumberFormatting($row[3]); + }else if(in_array($current_column_action, ['I','DA', 'MI', 'A'])){ + $row[6] = removeNumberFormatting($row[6]); + } //iterate each row for columns validations foreach ($row as $col_key => $col) @@ -923,7 +1031,14 @@ class EmployeeServiceController extends AdminController } else //trigger next data validation via job queue server - { + { + // check the condition if the policy from the Leads and check the lead id exist in the client policy table + if($file['action'] == 'inception' && $policy_details[0]->policy_entry_from == 3 && !empty($policy_details[0]->is_from_lead)){ + $r = Jobs::addJob(['job_name' => 'compareMemberDataAndInceptionData','payload' => ['file_id' => $file_id]]); + $this->myLogger->logme("error",'compareMemberDataAndInceptionData job pushed'); + return $result; + } + if($file['action'] == 'enrollment' && $file['uploaded_by'] != 1) // if current action is enrollment and uploaded by HR (0 or NULL) call next validation and return result { // dd(); @@ -978,6 +1093,16 @@ class EmployeeServiceController extends AdminController if($file['action'] == 'enrollment'){ $columns_to_check = $this->enrollment_excel_columns; } if($file['action'] == 'missed_inception'){ $columns_to_check = $this->inception_excel_columns; } + $current_column_action = null; + if($file['action'] == 'inception'){ $current_column_action = 'I'; } + else if($file['action'] == 'addition'){ $current_column_action = 'A'; } + else if($file['action'] == 'dependent_addition'){ $current_column_action = 'DA'; } + else if($file['action'] == 'deletion'){ $current_column_action = 'D'; } + else if($file['action'] == 'correction'){ $current_column_action = 'C'; } + else if($file['action'] == 'si_enhancement'){ $current_column_action = 'SI'; } + else if($file['action'] == 'enrollment'){ $current_column_action = 'I'; } + else if($file['action'] == 'missed_inception'){ $current_column_action = 'MI'; } + // get policy and rack details $policy_terms = $this->clientPolicyModel->getPolicyDetails($file['client_id'],$file['policy_id']); $policy_details = (array)$policy_terms[0]; @@ -1008,7 +1133,7 @@ class EmployeeServiceController extends AdminController if(in_array($file['action'],['inception','missed_inception','addition','dependent_addition','deletion','correction','si_enhancement','enrollment']))// the below funcitons are only for I,DA,A { - $employee_data_group_by_family = data_group_by_family($excel_data,'excel',($file['action'] == 'enrollment' ? 'enrollment' : '')); + $employee_data_group_by_family = data_group_by_family($excel_data,'excel',($file['action'] == 'enrollment' ? 'enrollment' : ''), $current_column_action); // dd($employee_data_group_by_family); $is_self_available_in_policy_terms = false; if($policy_details['policy_type_id'] == 3) // GMC parents @@ -1213,6 +1338,16 @@ class EmployeeServiceController extends AdminController if($file['action'] == 'si_enhancement'){ $columns_to_check = $this->si_enhance_excel_columns; } if($file['action'] == 'missed_inception'){ $columns_to_check = $this->inception_excel_columns; } + $current_column_action = null; + if($file['action'] == 'inception'){ $current_column_action = 'I'; } + else if($file['action'] == 'addition'){ $current_column_action = 'A'; } + else if($file['action'] == 'dependent_addition'){ $current_column_action = 'DA'; } + else if($file['action'] == 'deletion'){ $current_column_action = 'D'; } + else if($file['action'] == 'correction'){ $current_column_action = 'C'; } + else if($file['action'] == 'si_enhancement'){ $current_column_action = 'SI'; } + else if($file['action'] == 'enrollment'){ $current_column_action = 'I'; } + else if($file['action'] == 'missed_inception'){ $current_column_action = 'MI'; } + // get policy and rack details $policy_terms = $this->clientPolicyModel->getPolicyDetails($file['client_id'],$file['policy_id']); $policy_terms = (array) $policy_terms[0];// convert obj to array @@ -1236,7 +1371,7 @@ class EmployeeServiceController extends AdminController //get existing units in the current branch $existing_units = $this->clientBranchModel->getExisitingUnits(client_id: $file['client_id'],client_branch_id: $file['client_branch_id']); - $employee_data_group_by_family = data_group_by_family($excel_data); + $employee_data_group_by_family = data_group_by_family($excel_data, 'excel', '', $current_column_action); // dd($employee_data_group_by_family); foreach ($employee_data_group_by_family as $emp_id => $family) { @@ -1542,76 +1677,78 @@ class EmployeeServiceController extends AdminController return true; } - - //enhance of emp + //enhance of emp public function employeesSIEnhanceProcess($params) { - helper('excel_util_helper'); + helper('excel_util_helper'); //get file name $file_id = $params['file_id']; $file = $this->fileModel->find($file_id); + // dd($file); - $file_name_with_path = WRITEPATH."/uploads/excel/".$file['file_name']; + $file_name_with_path = WRITEPATH . "/uploads/excel/" . $file['file_name']; - $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path); + $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path); $sheet = $spreadsheet->getActiveSheet(); - + $highestRowAndColumn = $sheet->getHighestRowAndColumn(); $allowedHighestColumn = end($this->si_enhance_excel_columns); $excel_data = $sheet->rangeToArray('A1:' . $allowedHighestColumn['col_cell_name'] . $highestRowAndColumn['row']); // $excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']); - + unset($excel_data[0]); // dd($excel_data); //get policy slab rates - $slab_details = $this->policiesModel->getPolicySlabRatesForEmpOnboard($file['policy_id'],$file['client_id']); + $slab_details = $this->policiesModel->getPolicySlabRatesForEmpOnboard($file['policy_id'], $file['client_id']); //iterate each row // dd($slab_details); - foreach ($excel_data as $col_key => $row) - { - if(check_row_is_empty_or_null($row)) - { - break; + foreach ($excel_data as $col_key => $row) { + if (check_row_is_empty_or_null($row)) { + break; } + + $row[3] = removeNumberFormatting($row[3]); + // echo '
START- ' . $row[2]; $employee = $this->employeeModel - ->where('emp_code', $row[1]) - ->where('name',$row[2]) - ->where('client_id',$file['client_id']) - ->where('client_branch_id',$file['client_branch_id']) - ->where('emp_status', 'active') - ->where('is_active', 1) - ->first(); + ->where('emp_code', $row[1]) + ->where('name', $row[2]) + ->where('client_id', $file['client_id']) + ->where('client_branch_id', $file['client_branch_id']) + ->where('emp_status', 'active') + ->where('is_active', 1) + ->first(); + $employee_policy = $this->employeePolicyModel - ->where('employee_id',$employee['id']) - ->where('client_policy_id',$file['policy_id']) + ->where('employee_id', $employee['id']) + ->where('client_policy_id', $file['policy_id']) ->where('status', 'active') ->where('is_active', 1) ->first(); // dd($employee, $employee_policy); - $existing_endorsements = $this->empEndorsementModel->where('actions','si') - ->where('table_name','employee_polices') - ->where('endorsement_id is null') - ->where('emp_code',$employee['emp_code']) - ->where('name',$employee['name']) - ->where('field_name','basic_cover_si') - ->findAll(); - // dd($existing_endorsements); - //make entry in endorsement table - if(!count($existing_endorsements)) - { + $existing_endorsements = $this->empEndorsementModel->where('actions', 'si') + ->where('table_name', 'employee_polices') + ->where('endorsement_id is null') + ->where('emp_code', $employee['emp_code']) + ->where('name', $employee['name']) + ->where('field_name', 'basic_cover_si') + ->where('is_active', 1) + ->where('status !=', 'truncated') + ->findAll(); + // dd($existing_endorsements); + + //make entry in endorsement table + if (!count($existing_endorsements)) { //transform data to send //get applicable slab rate for current member relation $pre_rack_rate_name = ''; $applicable_rack_rate_name = ''; $applicable_rack_rate_master = []; - foreach ($slab_details['slab_rates'] as $skey => $slab_value) - { - if($pre_rack_rate_name != $slab_value['rack_rate_name']) - { + foreach ($slab_details['slab_rates'] as $skey => $slab_value) { + if ($pre_rack_rate_name != $slab_value['rack_rate_name']) { $pre_rack_rate_name = $slab_value['rack_rate_name']; $rack_rate_json = json_decode($slab_value['additional_relationship'], true); $relationship_array_key = strtolower(trim($employee['relationship'])); @@ -1624,51 +1761,46 @@ class EmployeeServiceController extends AdminController $relationship_array_key = 'parents-in-law'; } - if(array_key_exists($relationship_array_key, $rack_rate_json) && $rack_rate_json[$relationship_array_key] != 0 && $rack_rate_json[$relationship_array_key] != 'NA') - { + if (array_key_exists($relationship_array_key, $rack_rate_json) && $rack_rate_json[$relationship_array_key] != 0 && $rack_rate_json[$relationship_array_key] != 'NA') { $applicable_rack_rate_name = $slab_value['rack_rate_name']; $applicable_rack_rate_master = $slab_value['grid_master']; break; } } } - + //get max age,max count of the familiy $max_age_and_max_count_of_current_member = $this->employeeModel->getFamiliyCountAndMaxage($employee['emp_code']); //transform SI excel row data as inception excel OR premium calculateable fomart - $data = transform_si_excel_row_to_calculatable_format(employee: $employee,employee_policy: $employee_policy,maxage_and_maxcount: $max_age_and_max_count_of_current_member,slab_details: $slab_details,applicable_slab_name: $applicable_rack_rate_name,augmented_si: $row[3],grid_master: $applicable_rack_rate_master); - $policy_terms = $this->clientPolicyModel->getPolicyDetails($file['client_id'],$file['policy_id']); + $data = transform_si_excel_row_to_calculatable_format(employee: $employee, employee_policy: $employee_policy, maxage_and_maxcount: $max_age_and_max_count_of_current_member, slab_details: $slab_details, applicable_slab_name: $applicable_rack_rate_name, augmented_si: $row[3], grid_master: $applicable_rack_rate_master); + $policy_terms = $this->clientPolicyModel->getPolicyDetails($file['client_id'], $file['policy_id']); $policy_terms = (array) $policy_terms[0]; // dd($policy_terms); //grouping slab details by rack rate name $temp_slab_rates = group_slab_rates_basedon_name($slab_details); - $calculated_data = premium_calculation_manager($data,$policy_terms,$temp_slab_rates,$row[3]); + $calculated_data = premium_calculation_manager($data, $policy_terms, $temp_slab_rates, $row[3]); - $group_key = rand(100000, 999999); - $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'],'emp_code' => $employee['emp_code'],'table_name' => 'employee_polices','actions' => 'si','name' => $employee['name'],'field_name' => 'basic_cover_si','old_value' => $employee_policy['basic_cover_si'],'new_value' => $row[3],'created_by' => $file['created_by'],'remarks' => 'general si enhancement','group_key' => $group_key,'file_id' => $file['id'],'status' => 'pending']); - $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'],'emp_code' => $employee['emp_code'],'table_name' => 'employee_polices','actions' => 'si','name' => $employee['name'],'field_name' => 'premium','old_value' => $employee_policy['premium'],'new_value' => $calculated_data['policy_details']['premium'],'created_by' => $file['created_by'],'remarks' => 'general si enhancement','group_key' => $group_key,'file_id' => $file['id'],'status' => 'pending']); - $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'],'emp_code' => $employee['emp_code'],'table_name' => 'employee_polices','actions' => 'si','name' => $employee['name'],'field_name' => 'si_enhancement_date','old_value' => null,'new_value' => change_date_format($row[4],'d-M-Y','Y-m-d'),'created_by' => $file['created_by'],'remarks' => 'general si enhancement','group_key' => $group_key,'file_id' => $file['id'],'status' => 'pending']); - - + $group_key = rand(100000, 999999); + $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'], 'emp_code' => $employee['emp_code'], 'table_name' => 'employee_polices', 'actions' => 'si', 'name' => $employee['name'], 'field_name' => 'basic_cover_si', 'old_value' => $employee_policy['basic_cover_si'], 'new_value' => $row[3], 'created_by' => $file['created_by'], 'remarks' => 'general si enhancement', 'group_key' => $group_key, 'file_id' => $file['id'], 'status' => 'pending']); + $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'], 'emp_code' => $employee['emp_code'], 'table_name' => 'employee_polices', 'actions' => 'si', 'name' => $employee['name'], 'field_name' => 'premium', 'old_value' => $employee_policy['premium'], 'new_value' => $calculated_data['policy_details']['premium'], 'created_by' => $file['created_by'], 'remarks' => 'general si enhancement', 'group_key' => $group_key, 'file_id' => $file['id'], 'status' => 'pending']); + $this->empEndorsementModel->save(['pk' => (int)$employee_policy['id'], 'emp_code' => $employee['emp_code'], 'table_name' => 'employee_polices', 'actions' => 'si', 'name' => $employee['name'], 'field_name' => 'si_enhancement_date', 'old_value' => null, 'new_value' => change_date_format($row[4], 'd-M-Y', 'Y-m-d'), 'created_by' => $file['created_by'], 'remarks' => 'general si enhancement', 'group_key' => $group_key, 'file_id' => $file['id'], 'status' => 'pending']); + } else { + $this->myLogger->logme("error", 'Endorsement already exists for this employee ' . json_encode(['file_id' => $file_id, 'emp_code' => $employee['emp_code'], 'emp_name' => $employee['name']])); } - - - - } - $this->fileModel->where('id', $file_id)->set(['status' => 'success','reason' => ''])->update(); - $this->myLogger->logme("error",'{file_id} uploaded success',['file_id' => $file_id]); + $this->fileModel->where('id', $file_id)->set(['status' => 'success', 'reason' => ''])->update(); + $this->myLogger->logme("error", '{file_id} uploaded success', ['file_id' => $file_id]); + //set success msg to pull notifications - $this->setPullNotification($this->getFileMetaDataByFileId($file_id,'success')); - return true; + $this->setPullNotification($this->getFileMetaDataByFileId($file_id, 'success')); + return true; } - // insert or update in db for inception addition depent addition - public function employeesOnboardProcess($params) + public function employeesOnboardProcess($params) { // dd($params); @@ -1683,7 +1815,7 @@ class EmployeeServiceController extends AdminController if(is_array($value)) { - + if (isset($value['gender'])) { $value['gender'] = normalizeGender($value['gender'] );} if($file['id'] == null || $value['temp']['source'] == 'excel' || (($file['action'] == 'dependent_addition' && ($value['temp']['premium_type'] == 1 && strtolower($value['relationship']) == 'self') || ($value['temp']['premium_type'] == 2 || $value['temp']['premium_type'] == null)))) //insert data come from excel and from db i.e. ( $file['id'] == null for enrollment data) { @@ -1723,7 +1855,7 @@ class EmployeeServiceController extends AdminController $value['updated_by'] = $file['created_by']; $value['id'] = $employee[0]['id']; $value['emp_status'] = 'active'; - $value['family_floater_key'] = generate_family_floater_key($value['relationship']); + $value['family_floater_key'] = generate_family_floater_key($value['relationship']); $value['client_branch_id'] = $file['client_branch_id']; $value['file_id'] = isset($employee[0]['file_id']) && $employee[0]['file_id'] != '' ? $employee[0]['file_id'] : $file['id'] ; $log_message = 'Update Employee - '.$employee[0]['name'].'('.$employee[0]['emp_code'].') with PK '.$employee[0]['id']; @@ -1872,127 +2004,125 @@ class EmployeeServiceController extends AdminController } -// --------------------------------------------------------------------------------- + // --------------------------------------------------------------------------------- - public function getExcelErrorData($file_id){ + public function getExcelErrorData($file_id) + { - try { - $file = $this->fileModel->find($file_id); - $error_data = json_decode($file['reason']); - // dd($error_data); - // return $error_data; + try { + $file = $this->fileModel->find($file_id); + $error_data = json_decode($file['reason']); + // dd($error_data); + // return $error_data; - $file_name_with_path = WRITEPATH."/uploads/excel/".$file['file_name']; + $file_name_with_path = WRITEPATH."/uploads/excel/".$file['file_name']; - //check the file exist or not - if(!file_exists($file_name_with_path)) - { - $error_message = "File not found"; - $this->myLogger->logme('error',($error_message . ' for file id ' . $file_id)); - return 0; - } - - $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path); - $sheet = $spreadsheet->getActiveSheet(); - - $highestRowAndColumn = $sheet->getHighestRowAndColumn(); - $excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']); - $excelErrorData['excel_header'] = $excel_data[0]; - unset($excel_data[0]); - // echo '
';
-         // Kint::dump($excel_data);
-         if($error_data->error_type == 1){
-
-            $finalArray = [];
-            foreach ($error_data->error_data as $key => $value) {
-    
-                foreach ($value as $key2 => $value2) {
-                    $error_data = $value2->error;
-                    $data = ['value' => $excel_data[$key][$value2->col_idx], 'error'=>$error_data,];
-                    $excel_data[$key][$value2->col_idx] = $data;
-    
-                }
-                array_push($finalArray, $excel_data[$key]);
+            //check the file exist or not
+            if(!file_exists($file_name_with_path))
+            {
+                $error_message = "File not found";
+                $this->myLogger->logme('error',($error_message . ' for file id ' . $file_id));
+                return 0;
             }
-    
-            foreach ($finalArray as $fkey => $value){
-                foreach ($value as $vkey => $arrayData){
-                    if(!is_array($arrayData)){
-                        $data = ['value' => $arrayData];
-                        $finalArray[$fkey][$vkey] =  $data;
+
+            $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
+            $sheet = $spreadsheet->getActiveSheet();
+        
+            $highestRowAndColumn = $sheet->getHighestRowAndColumn();
+            $excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']);
+            $excelErrorData['excel_header'] = $excel_data[0];
+            unset($excel_data[0]);
+            //  echo '
';
+            // Kint::dump($excel_data);
+            if($error_data->error_type == 1){
+
+                $finalArray = [];
+                foreach ($error_data->error_data as $key => $value) {
+        
+                    foreach ($value as $key2 => $value2) {
+                        $error_data = $value2->error;
+                        $data = ['value' => $excel_data[$key][$value2->col_idx], 'error'=>$error_data,];
+                        $excel_data[$key][$value2->col_idx] = $data;
+        
+                    }
+                    array_push($finalArray, $excel_data[$key]);
+                }
+        
+                foreach ($finalArray as $fkey => $value){
+                    foreach ($value as $vkey => $arrayData){
+                        if(!is_array($arrayData)){
+                            $data = ['value' => $arrayData];
+                            $finalArray[$fkey][$vkey] =  $data;
+                        }
                     }
                 }
-            }
-    
-            $excelErrorData['excel_data'] = $finalArray;
-            return $excelErrorData;
+        
+                $excelErrorData['excel_data'] = $finalArray;
+                return $excelErrorData;
 
-         }else if($error_data->error_type == 2){
+            }else if($error_data->error_type == 2){
 
 
-            $allErrors = [];
-            $typeTowArray = [];
+                $allErrors = [];
+                $typeTowArray = [];
 
-            foreach ($error_data->error_data as $index => $item) {
+                foreach ($error_data->error_data as $index => $item) {
 
-                foreach ($item as $field) {
-                    if (!isset($allErrors[$index])) {
-                        $allErrors[$index] = [];
+                    foreach ($item as $field) {
+                        if (!isset($allErrors[$index])) {
+                            $allErrors[$index] = [];
+                        }
+                        $allErrors[$index] = array_merge($allErrors[$index], $field->error);
                     }
-                    $allErrors[$index] = array_merge($allErrors[$index], $field->error);
                 }
-            }
 
-            // dd(array_keys($allErrors));
-            foreach ($allErrors as $key => $value){
-                // echo $key;
-                // print_r($value);
-                foreach($excel_data as $excel_data_index => $excel_data_value)
-                {
-                    if($excel_data_value[0] == $key)
+                // dd(array_keys($allErrors));
+                foreach ($allErrors as $key => $value){
+                    // echo $key;
+                    // print_r($value);
+                    foreach($excel_data as $excel_data_index => $excel_data_value)
                     {
-                        $data = ['value' => $excel_data[$excel_data_index][1], 'error'=>$value,];
-                        $excel_data[$excel_data_index][1] = $data;
-                        array_push($typeTowArray, $excel_data[$excel_data_index]);
-                        break;
+                        if($excel_data_value[0] == $key)
+                        {
+                            $data = ['value' => $excel_data[$excel_data_index][1], 'error'=>$value,];
+                            $excel_data[$excel_data_index][1] = $data;
+                            array_push($typeTowArray, $excel_data[$excel_data_index]);
+                            break;
+                        }
                     }
-                }
-               
                 
-            }
-            // dd($data);
-            foreach ($typeTowArray as $fkey => $value){
-                foreach ($value as $vkey => $arrayData){
-                    if(!is_array($arrayData)){
-                        $data = ['value' => $arrayData];
-                        $typeTowArray[$fkey][$vkey] =  $data;
+                    
+                }
+                // dd($data);
+                foreach ($typeTowArray as $fkey => $value){
+                    foreach ($value as $vkey => $arrayData){
+                        if(!is_array($arrayData)){
+                            $data = ['value' => $arrayData];
+                            $typeTowArray[$fkey][$vkey] =  $data;
+                        }
                     }
                 }
+
+                $excelErrorData['excel_data'] = $typeTowArray;
+                return $excelErrorData;
+
             }
 
-            $excelErrorData['excel_data'] = $typeTowArray;
-            return $excelErrorData;
+            }catch (\Exception $e) {
+                // Handle any exceptions
+                $errorMessage = $e->getMessage();//die();
+                $this->myLogger->logme('error', $errorMessage);
+                return false; // You can return an error response here
+            }
+    }
 
-         }
+    // ---------------------------------------------------------------------------------
 
-        }catch (\Exception $e) {
-            // Handle any exceptions
-            $errorMessage = $e->getMessage();//die();
-            $this->myLogger->logme('error', $errorMessage);
-            return false; // You can return an error response here
-        }
+    public function getFileMetaDataByFileId($file_id, $status = 'success')
+    {
 
-
-
- }
-
-
-// ---------------------------------------------------------------------------------
-
-public function getFileMetaDataByFileId($file_id, $status = 'success'){
-
-       $data = $this->fileModel
+        $data = $this->fileModel
         ->select('files.*, clients.client_name, clients.short_name, policy_type.policy_type as policy_name,client_branch.branch_code')
         ->join('clients', 'clients.id = files.client_id')
         ->join('client_policy', 'client_policy.id = files.policy_id')
@@ -2016,11 +2146,9 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
 
         return ['msg_txt' => $msg_txt, 'user_id' => $user_id, 'url' => $url, 'status' => $status, 'title' => $msg_title];
     }
-
-
-    public function setPullNotification($data){
-
-
+        
+    public function setPullNotification($data)
+    {
         $array = ['message_text' => $data['msg_txt'], 'action_url' => $data['url'], 'msg_status' => $data['status'], 'msg_title' => $data['title']];
         $jsonEncodeData = json_encode($array);
 
@@ -2031,17 +2159,14 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
             'role_id' => NULL,
             'team_id' => NULL,
             'message_type' => '1to1',
-         ];
+        ];
 
- 
-         $this->messageModel->insert($msg_data);
- 
-
-}
+        $this->messageModel->insert($msg_data);
+    }
 
     public function employeesEnrollmentInsert($params)
     {
-        // dd($this->request);
+            // dd($this->request);
             helper('excel_util_helper');
             //get file name
             $file_id = $params['file_id'];
@@ -2059,10 +2184,10 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
             if(!file_exists($file_name_with_path))
             {
                 //file not found  update status and reason 
-                 $message = "Physical file not found";
+                    $message = "Physical file not found";
                 // echo $message;
                 $this->myLogger->logme('error',($message . ' for file id ' . $file_id));
-                 $this->fileModel->where('id', $file_id)->set(['status' => 'failed','reason' => json_encode(['error_summary' => array_count_values([5]),'error_data' => $message])])->update();
+                    $this->fileModel->where('id', $file_id)->set(['status' => 'failed','reason' => json_encode(['error_summary' => array_count_values([5]),'error_data' => $message])])->update();
                 return  array('error_summary' => [5], 'error_data' => $message);
             }
 
@@ -2077,7 +2202,8 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
             $allowedHighestColumn = end($columns_to_check);
             $excel_data = $sheet->rangeToArray('A1:' . $allowedHighestColumn['col_cell_name'] . $highestRowAndColumn['row']);
             // print_r($keys);die();
-             //get existing units in the current branch
+            
+            //get existing units in the current branch
             $existing_units = $this->clientBranchModel->getExisitingUnits(client_id: $file['client_id'],client_branch_id: $file['client_branch_id']);
             //remove header
             unset($excel_data[0]);
@@ -2109,11 +2235,11 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
                     {
                         $temp_unit = $existing_units[0];
                     }
-                   
+                    
                     $value['emp_code'] = $row[1];
                     $value['name'] = $row[2];
                     $value['doj'] = (!empty($row[3]) ? change_date_format($row[3],'d-M-Y','Y-m-d') : null );
-                    $value['gender'] = $row[4];
+                    $value['gender'] = normalizeGender($row[4]);
                     $value['relationship'] = ucfirst(trim($row[5]));
                     $value['dob'] = change_date_format($row[6],'d-M-Y','Y-m-d');
                     $value['email_corporate'] = $row[7];
@@ -2149,10 +2275,10 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
                             $policy_data['date_coverage'] = $row[13] != "" && $row[13] != null ? change_date_format($row[13],'d-M-Y','Y-m-d') : null;
                             $policy_data['client_policy_id'] = $file['policy_id'];
 
-                             $employee = $this->employeeModel->checkExistingEmployee($value,$file['client_branch_id']);
-                             unset($value['temp']);
+                                $employee = $this->employeeModel->checkExistingEmployee($value,$file['client_branch_id']);
+                                unset($value['temp']);
                             //save employee table
-                             // dd($employee['id']);
+                                // dd($employee['id']);
                             if($employee !== null)
                             {
                                 $value['updated_by'] = $file['created_by'];
@@ -2170,11 +2296,11 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
                             
                             $value = ExcelSanitizeHelper::sanitizeArrayData($value);
                             $this->employeeModel->save($value);
-                             if (isset($value['id'])) 
-                             {  $emp_id = $value['id']; } 
-                             else { $emp_id = $this->employeeModel->getInsertID(); 
+                                if (isset($value['id'])) 
+                                {  $emp_id = $value['id']; } 
+                                else { $emp_id = $this->employeeModel->getInsertID(); 
                                     $log_message .= $emp_id;
-                             }
+                                }
 
                             // $emp_id = $this->employeeModel->getInsertID();
                             // if($emp_id != 0){  $log_message .= $emp_id; }
@@ -2232,8 +2358,8 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
                                         'employee_id' => $emp_id,
                                         'mail_type' => 'member_welcome_mail',
                                     ];
-                                   //store email and mail content via helper to send notification
-                                   $emp_emails[] = sendMailNotification::sendMailNotification('member_welcome_mail', $params);
+                                    //store email and mail content via helper to send notification
+                                    $emp_emails[] = sendMailNotification::sendMailNotification('member_welcome_mail', $params);
                                 }
                             }
                 }// endof if row is empty check
@@ -2241,7 +2367,7 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
 
             // dd($emp_emails);
 
-             // for bulk mail queue job push  
+                // for bulk mail queue job push  
             if (!empty($emp_emails) && count($emp_emails) > 0) {
 
                 $emp_emails = array_chunk($emp_emails, 20);
@@ -2259,6 +2385,140 @@ public function getFileMetaDataByFileId($file_id, $status = 'success'){
 
 
             return true;
-    }//end of employeesEnrollmentInsert
+    } //end of employeesEnrollmentInsert
 
+    // --------- MEMBER DATA AND INCEPTION DATA COMPARISION ------------------------------------------------------------------------
+
+    public function compareMemberDataAndInceptionData($params)
+    {
+        $file_id = $params['file_id'] ?? null;
+        if (empty($file_id)) {
+            return ['status' => false, 'msg' => 'File ID is missing'];
+        }
+
+        // ✅ Get File Data
+        $file = $this->fileModel->where(['is_active' => 1, 'id' => $file_id])->first();
+        if (empty($file)) {
+            return ['status' => false, 'msg' => 'File not found in DB'];
+        }
+
+        // ✅ Get Client Policy Data
+        $client_policy_data = $this->clientPolicyModel->where(['is_active' => 1, 'id' => $file['policy_id']])->first();
+        if (empty($client_policy_data)) {
+            return ['status' => false, 'msg' => 'Client policy data not found in DB (policy_id: ' . $file['policy_id'] . ')'];
+        }
+
+        // ✅ Get Lead Data
+        $leadModel = new LeadsModel();
+        $lead_data = $leadModel->where(['is_active' => 1, 'id' => $client_policy_data['is_from_lead']])->first();
+        if (empty($lead_data)) {
+            return ['status' => false, 'msg' => 'Lead data not found in DB (lead_id: ' . $client_policy_data['is_from_lead'] . ')'];
+        }
+
+        // ✅ Define File Paths
+        $inception_file_path = !empty($file['file_name']) ? WRITEPATH . "uploads/excel/" . $file['file_name'] : '';
+        $member_file_path    = !empty($lead_data['file_name']) ? WRITEPATH . "uploads/lead_files/" . $lead_data['file_name'] : '';
+
+        // ✅ Check Inception File
+        if (empty($file['file_name']) || !file_exists($inception_file_path)) {
+            $message = empty($file['file_name']) ? "Inception file name is missing" : "Inception physical file not found";
+            $this->myLogger->logme('error', "$message for file id $file_id");
+            $this->fileModel->update($file_id, [
+                'status' => 'failed',
+                'reason' => json_encode(['error_summary' => [5], 'error_data' => $message])
+            ]);
+            return ['error_summary' => [5], 'error_data' => $message];
+        }
+
+        // ✅ Check Member File
+        if (empty($lead_data['file_name']) || !file_exists($member_file_path)) {
+            $message = empty($lead_data['file_name']) ? "Member file name is missing" : "Member data physical file not found";
+            $this->myLogger->logme('error', "$message for lead id {$lead_data['id']}");
+            $this->fileModel->update($file_id, [
+                'status' => 'failed',
+                'reason' => json_encode(['error_summary' => [5], 'error_data' => $message])
+            ]);
+            return ['error_summary' => [5], 'error_data' => $message];
+        }
+
+
+        // ✅ Read Inception Excel
+        $inception_columns = $this->inception_excel_columns;
+        $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inception_file_path);
+        $sheet = $spreadsheet->getActiveSheet();
+        $highestRow = $sheet->getHighestDataRow();
+        $allowedColumn = end($inception_columns)['col_cell_name'];
+        $inception_data = $sheet->rangeToArray("A1:{$allowedColumn}{$highestRow}");
+        $inception_data = ExcelSanitizeHelper::sanitizeArrayData($inception_data);
+
+        // ✅ Read Member Excel
+        $member_columns = $this->member_data_excel_columns;
+        $spreadsheet2 = \PhpOffice\PhpSpreadsheet\IOFactory::load($member_file_path);
+        $sheet2 = $spreadsheet2->getSheet(0);
+        $highestRow2 = $sheet2->getHighestDataRow();
+        $allowedColumn2 = end($member_columns)['col_cell_name'];
+        $member_data = $sheet2->rangeToArray("A1:{$allowedColumn2}{$highestRow2}");
+        $member_data = ExcelSanitizeHelper::sanitizeArrayData($member_data);
+
+        //  dd($inception_data, $member_data);
+
+        // ✅ Compare Inception Data with Member Data
+        $result = ['error_type' => 2, 'error_summary' => [], 'error_data' => []];
+
+        $inception_data_count = count($inception_data);
+        $member_data_count = count($member_data);
+
+        if ($inception_data_count !== $member_data_count) {
+            $result['error_summary'][] = 15;
+            $result['error_message'] = "
+                Inception Data Count: 
+                {$inception_data_count}  
+                Member Data Count: 
+                {$member_data_count}";
+        }
+
+        foreach ($inception_data as $inception_key => $inception_row) {
+
+            // 🔹 If inception row is empty → stop all further processing
+            if (check_row_is_empty_or_null($inception_row)) {
+                break;
+            }
+
+            $match_found = false;
+
+            foreach ($member_data as $member_row) {
+                if (
+                    $inception_row[1] == $member_row[1] &&  // emp_id / emp_code
+                    $inception_row[2] == $member_row[2] &&  // name_of_emp_dep / name
+                    $inception_row[5] == $member_row[3] &&  // relationship
+                    normalizeGender($inception_row[4]) == normalizeGender($member_row[4]) &&  // gender
+                    $inception_row[3] == $member_row[5] &&  // dob
+                    $inception_row[13] == $member_row[7] && // email
+                    $inception_row[12] == $member_row[8]    // phone / mobile
+                ) {
+                    $match_found = true;
+                    break;
+                }
+            }
+
+            if (!$match_found) {
+                array_push($result['error_summary'], 14);
+                $result['error_data'][$inception_key]['sno']['error'][] = "This inception row was not found in the member data list.";
+            }
+        }
+
+        // ✅ Handle Result
+        if (!empty($result['error_summary'])) {
+            $result['error_summary'] = array_count_values($result['error_summary']);
+            $this->fileModel->update($file_id, [
+                'status' => 'failed',
+                'reason' => json_encode($result)
+            ]);
+            $this->myLogger->logme('error', "File ID $file_id comparison failed");
+        } else {
+            Jobs::addJob(['job_name' => 'excelFileDataValidation', 'payload' => ['file_id' => $file_id]]);
+        }
+
+        return $result;
+    }
 }
\ No newline at end of file
diff --git a/app/Controllers/JobWorker.php b/app/Controllers/JobWorker.php
index 50c9820b..1dbf51b5 100755
--- a/app/Controllers/JobWorker.php
+++ b/app/Controllers/JobWorker.php
@@ -171,6 +171,10 @@ class JobWorker extends AdminController
         'type' => 'CC', // Handler Category
         'handler' => 'App\Controllers\LeadsController',
     ],
+    'compareMemberDataAndInceptionData' => [
+        'type' => 'CC', // Handler Category
+        'handler' => 'App\Controllers\EmployeeServiceController',
+    ],
 ];
 
     
diff --git a/app/Controllers/LeadsController.php b/app/Controllers/LeadsController.php
index 115b5176..731202da 100644
--- a/app/Controllers/LeadsController.php
+++ b/app/Controllers/LeadsController.php
@@ -665,7 +665,10 @@ class LeadsController extends BaseController
             if ($value['lead_form_type'] == 1) {
                 //for this push the job to the  calculateMembersDemography() function
                 $job_details  = new Jobs();
-                $r = Jobs::addJob(['job_name' => 'memberDataListExcelFileFormatValidation', 'payload' => [
+                // $r = Jobs::addJob(['job_name' => 'memberDataListExcelFileFormatValidation', 'payload' => [
+                //     'lead_id' => $insert,
+                // ]]);
+                $r = Jobs::addJob(['job_name' => 'calculateMembersDemography', 'payload' => [
                     'lead_id' => $insert,
                 ]]);
             }
@@ -773,7 +776,7 @@ class LeadsController extends BaseController
 
         $multi_file_data = [];
         foreach ($files as $index => $value) {
-            $file_name = file_Upload($value, $uploadFilePath);
+            $file_name = file_Upload_for_lead($value, $uploadFilePath);
             $multi_file_data[] = [
                 'file_name' => $file_name,
                 'docs_name' => $docs_names[$index],
@@ -809,7 +812,10 @@ class LeadsController extends BaseController
                         if (!empty($lead_form_type) && $lead_form_type == 1 && $key == 0) {
                             //for this push the job to the  calculateMembersDemography() function
                             $job_details  = new Jobs();
-                            $r = Jobs::addJob(['job_name' => 'memberDataListExcelFileFormatValidation', 'payload' => [
+                            // $r = Jobs::addJob(['job_name' => 'memberDataListExcelFileFormatValidation', 'payload' => [
+                            //     'lead_id' => $lead_id,
+                            // ]]);
+                            $r = Jobs::addJob(['job_name' => 'calculateMembersDemography', 'payload' => [
                                 'lead_id' => $lead_id,
                             ]]);
                             log_message('info', "calculateMembersDemography JOB PUSHED");
@@ -1024,14 +1030,7 @@ class LeadsController extends BaseController
         // 3. Optimize lead data query with specific field selection
         $lead_data = $this->leadsModel
             ->select('
-                leads.id, 
-                leads.policy_type_id, 
-                leads.lead_type, 
-                leads.source_policy_id,
-                leads.policy_end_date, 
-                leads.lead_form_type, 
-                leads.created_by, 
-                leads.client_name,
+                leads.*, 
                 lead_files.status as demography_file_status,
                 policy_type.question_json, 
                 policy_type.policy_type, 
@@ -1090,6 +1089,7 @@ class LeadsController extends BaseController
 
         // 7. Define mail templates as constants or config
         $mail_content = $this->getMailTemplate();
+        $placement_mail_content = $this->getMailTemplate('placement');
         $subject = $this->getSubjectTemplate($lead_data);
 
         // 8. Pre-calculate sum assured only for GPA
@@ -1098,7 +1098,7 @@ class LeadsController extends BaseController
         // 9. Transform mail content once
         $data['mail_content'] = $this->transformMailContent($lead_data, $mail_content, $data['page_name']);
         $data['subject'] = $this->transformMailContent($lead_data, $subject, $data['page_name']);
-        $data['placement_mail_content'] = $this->transformMailContent($lead_data, $mail_content, 'Placement');
+        $data['placement_mail_content'] = $this->transformMailContent($lead_data, $placement_mail_content, 'Placement');
         $data['placement_subject'] = $this->transformMailContent($lead_data, $subject, 'Placement');
 
         // 10. Combine related queries
@@ -1151,24 +1151,43 @@ class LeadsController extends BaseController
     }
 
     // 13. Extract mail template to separate method for reusability
-    private function getMailTemplate()
-    {
-        return '
-            

Dear Sir,

-

Greetings From Nhance India!

-

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

-

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

-

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

-

Thank You!


-

Best regards,

+ private function getMailTemplate( $template_type = "" ) + { + if($template_type == 'placement'){ + return ' +

Dear Sir,

+

Greetings From Nhance India!

+

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

+

Kindly request you to issue the policy at the earliest.

+

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

+

Thank You!


+

Best regards,

+ +
+
{{LOGGED_USER_NAME}}
+
Mobile: {{LOGGED_USER_MOBILE}}
+
-
-
{{LOGGED_USER_NAME}}
-
Mobile: {{LOGGED_USER_MOBILE}}
-
- - Nhance Logo - '; + Nhance Logo + '; + }else{ + return ' +

Dear Sir,

+

Greetings From Nhance India!

+

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

+

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

+

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

+

Thank You!


+

Best regards,

+ +
+
{{LOGGED_USER_NAME}}
+
Mobile: {{LOGGED_USER_MOBILE}}
+
+ + Nhance Logo + '; + } } // 14. Extract subject template to separate method @@ -3680,7 +3699,7 @@ class LeadsController extends BaseController private function prepareClientData($data) { return [ - 'client_type' => $data['client_type'] ?? null, + 'client_type' => 1, 'entity_type_id' => $data['entity_type_id'] ?? null, 'client_code' => $data['client_code'] ?? null, 'client_name' => $data['client_name'] ?? null, @@ -3730,6 +3749,8 @@ class LeadsController extends BaseController 'policy_start_date' => $data['policy_start_date'], 'policy_end_date' => $data['policy_end_date'], 'policy_status' => 1, + 'policy_entry_from' => 3, + 'is_from_lead' => $data['id'], ]; $policy_type_id = $data['policy_type_id']; @@ -5273,10 +5294,10 @@ class LeadsController extends BaseController 'filePath' => $fullPath ]; } else { - log_message('warning', 'File name is empty for ID: ' . $id); + log_message('error', 'File name is empty for ID: ' . $id); } } else { - log_message('warning', 'File does not exist at path: ' . $fullPath); + log_message('error', 'File does not exist at path: ' . $fullPath); } } else { log_message('warning', 'No active lead file found for ID: ' . $id . ' and lead_id: ' . $lead_id); diff --git a/app/Controllers/MasterController.php b/app/Controllers/MasterController.php index 9e4a5a08..58618abf 100755 --- a/app/Controllers/MasterController.php +++ b/app/Controllers/MasterController.php @@ -1350,6 +1350,16 @@ class MasterController extends AdminController // === INSERT === if (empty($id)) { + $cd_acc_count = $this->CDMasterModel->where('is_active', 1) + ->where('client_id', $data['client_id']) + ->where('insurer_id', $data['insurer_id']) + ->where('insurer_branch_id', $data['insurer_branch_id']) + ->countAllResults(); + + if($cd_acc_count > 0){ + return $this->respond(['status' => false, 'message' => 'A CD account has already been created for this client, insurer, and insurer branch combination.'], 200); + } + $this->myLogger->logme("error", 'Performing INSERT operation.'); $insert = $this->CDMasterModel->insert($data); $this->myLogger->logme("error", 'Insert result: ' . json_encode($insert)); @@ -1574,6 +1584,15 @@ class MasterController extends AdminController $data['insurer_branch_id'] = $insurer_branch_id; + $cd_acc_count = $this->CDMasterModel->where('is_active', 1) + ->where('client_id', $data['client_id']) + ->where('insurer_id', $data['insurer_id']) + ->where('insurer_branch_id', $data['insurer_branch_id']) + ->countAllResults(); + + if($cd_acc_count > 0){ + return $this->respond(['status' => false, 'message' => 'A CD account has already been created for this client, insurer, and insurer branch combination.'], 200); + } // array with data for CD Traction table $cd_tranction_data = [ @@ -1617,6 +1636,24 @@ class MasterController extends AdminController } } + public function checkDuplicateCdAccount() + { + $data = $this->request->getGet(); + + $cd_acc_count = $this->CDMasterModel + ->where('is_active', 1) + ->where('client_id', $data['client_id']) + ->where('insurer_id', $data['insurer_id']) + ->where('insurer_branch_id', $data['insurer_branch_id']) + ->countAllResults(); + + if($cd_acc_count > 0){ + return $this->respond(['status' => false, 'message' => 'A CD account has already been created for this client, insurer, and insurer branch combination.'], 200); + }else{ + return $this->respond(['status' => true], 200); + } + } + //Vehicle Master data Function diff --git a/app/Controllers/PolicyTransactionController.php b/app/Controllers/PolicyTransactionController.php index 77643f19..bf508a48 100644 --- a/app/Controllers/PolicyTransactionController.php +++ b/app/Controllers/PolicyTransactionController.php @@ -1271,9 +1271,10 @@ class PolicyTransactionController extends BaseController $data['tsi'] = generate_tsi_code($issue_type['issue_type'] ?? 1); - $client_branch_id = $data['client_branch_id']; - if ($data['client_branch_id'] == "") { + if (!isset($data['client_branch_id']) || $data['client_branch_id'] == "") { $client_branch_id = $issue_type['client_branch_id']; + }else{ + $client_branch_id = $data['client_branch_id']; } $data['is_cd_reduce_from_bds'] = (isset($issue_type['policy_type_id']) && $issue_type['policy_type_id'] > 7 && $data['client_type'] == 1) ? 1 : 0; @@ -1431,7 +1432,11 @@ class PolicyTransactionController extends BaseController $pt_id = null; if(!empty($data)){ - $inception_data = $this->policyTransactionModel->where('policy_no', $data['policy_no'])->where('client_id', $data['client_id'])->first(); + $inception_data = $this->policyTransactionModel + ->where('policy_no', $data['policy_no']) + ->where('client_id', $data['client_id']) + ->where('action_type', 'inception') + ->first(); $pt_id = $inception_data['id']; } @@ -2404,8 +2409,8 @@ class PolicyTransactionController extends BaseController // $client_name = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[3]); //clientname from excel - $endorsement_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[2]); //policy_end_date from excel - $endorsement_no = preg_replace( '/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[2]); //policy_end_date from excel + $endorsement_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[2]??''); //policy_end_date from excel + $endorsement_no = preg_replace( '/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[2]??''); //policy_end_date from excel // Kint::dump($excel_key,$policy_no,$endorsement_no,$policy_start_date,$policy_end_date);//die(); foreach ($source_data as $source_key => $source_row) { diff --git a/app/Controllers/TestingController.php b/app/Controllers/TestingController.php index a7cdddd1..98257f4e 100644 --- a/app/Controllers/TestingController.php +++ b/app/Controllers/TestingController.php @@ -362,18 +362,18 @@ class TestingController extends BaseController $pre_clients_list = $this->getNonDuplicatePreClients(); - $log_post_clients_list = $post_clients_list ; + $log_post_clients_list = $post_clients_list; - $log_pre_clients_list = $pre_clients_list ; + $log_pre_clients_list = $pre_clients_list; log_message('error', 'Post Clients to be processed: ' . count($log_post_clients_list)); log_message('error', 'Pre Clients to be processed: ' . count($log_pre_clients_list)); - $matched_Count = 0 ; + $matched_Count = 0; $expected_match_count = min(count($post_clients_list), count($pre_clients_list)); - + if ( !empty($pre_clients_list) && @@ -444,31 +444,27 @@ class TestingController extends BaseController } } - + log_message('error', 'Expected Match Count : ' . $expected_match_count); log_message('error', 'Total Matched Count: ' . $matched_Count); log_message('error', 'Total UnMatched Count: ' . $expected_match_count - $matched_Count); - - - log_message('error','unmatched_reocrds'); + + + log_message('error', 'unmatched_reocrds'); $log_post_clients_list = array_values($log_post_clients_list); $log_pre_clients_list = array_values($log_pre_clients_list); - if( (count($log_pre_clients_list) < count($log_post_clients_list))){ - log_message('error',"unmatched records count from pre- ". count($log_pre_clients_list)); - log_message('error',print_r($log_pre_clients_list,true)); + if ((count($log_pre_clients_list) < count($log_post_clients_list))) { + log_message('error', "unmatched records count from pre- " . count($log_pre_clients_list)); + log_message('error', print_r($log_pre_clients_list, true)); } else { - log_message('error',"unmatched records count from post - ".count($log_post_clients_list)); - log_message('error',print_r($log_post_clients_list,true)); + log_message('error', "unmatched records count from post - " . count($log_post_clients_list)); + log_message('error', print_r($log_post_clients_list, true)); } - - - } + } return $this->response->setJSON(['status' => 'success', 'message' => 'Client and Branch mapping completed.'])->setStatusCode(200); - - } @@ -535,7 +531,7 @@ class TestingController extends BaseController return $results; } public function membervalidation($lead_id = 329) - { + { $lead_controll = new LeadsController(); // $lead_controll->getMemberDataExcelFileErrors(); $res = $lead_controll->memberDataListExcelFileFormatValidation(['lead_id' => $lead_id]); @@ -543,18 +539,81 @@ class TestingController extends BaseController } private $firstNames = [ - 'Rajesh', 'Priya', 'Amit', 'Sneha', 'Vikram', 'Anjali', 'Rahul', 'Deepika', - 'Sanjay', 'Kavita', 'Arun', 'Pooja', 'Manoj', 'Nisha', 'Suresh', 'Meera', - 'Karthik', 'Divya', 'Ravi', 'Lakshmi', 'Anand', 'Swathi', 'Vijay', 'Rekha', - 'Ashok', 'Sangeetha', 'Prakash', 'Uma', 'Ramesh', 'Vani', 'Kumar', 'Radha', - 'Dinesh', 'Shanti', 'Ganesh', 'Parvati', 'Mohan', 'Sita', 'Arjun', 'Geetha' + 'Rajesh', + 'Priya', + 'Amit', + 'Sneha', + 'Vikram', + 'Anjali', + 'Rahul', + 'Deepika', + 'Sanjay', + 'Kavita', + 'Arun', + 'Pooja', + 'Manoj', + 'Nisha', + 'Suresh', + 'Meera', + 'Karthik', + 'Divya', + 'Ravi', + 'Lakshmi', + 'Anand', + 'Swathi', + 'Vijay', + 'Rekha', + 'Ashok', + 'Sangeetha', + 'Prakash', + 'Uma', + 'Ramesh', + 'Vani', + 'Kumar', + 'Radha', + 'Dinesh', + 'Shanti', + 'Ganesh', + 'Parvati', + 'Mohan', + 'Sita', + 'Arjun', + 'Geetha' ]; private $lastNames = [ - 'Kumar', 'Sharma', 'Singh', 'Patel', 'Reddy', 'Nair', 'Iyer', 'Krishnan', - 'Rao', 'Gupta', 'Verma', 'Agarwal', 'Joshi', 'Mehta', 'Desai', 'Pillai', - 'Menon', 'Bhat', 'Naidu', 'Varma', 'Malhotra', 'Kapoor', 'Chopra', 'Saxena', - 'Pandey', 'Mishra', 'Tiwari', 'Dubey', 'Sinha', 'Jain', 'Shah', 'Thakur' + 'Kumar', + 'Sharma', + 'Singh', + 'Patel', + 'Reddy', + 'Nair', + 'Iyer', + 'Krishnan', + 'Rao', + 'Gupta', + 'Verma', + 'Agarwal', + 'Joshi', + 'Mehta', + 'Desai', + 'Pillai', + 'Menon', + 'Bhat', + 'Naidu', + 'Varma', + 'Malhotra', + 'Kapoor', + 'Chopra', + 'Saxena', + 'Pandey', + 'Mishra', + 'Tiwari', + 'Dubey', + 'Sinha', + 'Jain', + 'Shah', + 'Thakur' ]; private $relationships = ['Self', 'Spouse', 'Son', 'Daughter', 'Father', 'Mother']; @@ -611,9 +670,9 @@ class TestingController extends BaseController for ($i = 1; $i <= $totalRecords; $i++) { $row = $i + 1; // Start from row 2 (row 1 is header) - + $record = $this->generateSampleRecord($i); - + $sheet->setCellValue('A' . $row, $record['sl_no']); $sheet->setCellValue('B' . $row, $record['emp_code']); $sheet->setCellValue('C' . $row, $record['name']); @@ -664,33 +723,33 @@ class TestingController extends BaseController $firstName = $this->firstNames[array_rand($this->firstNames)]; $lastName = $this->lastNames[array_rand($this->lastNames)]; $name = $firstName . ' ' . $lastName; - + $relationship = $this->relationships[array_rand($this->relationships)]; $gender = $this->genders[array_rand($this->genders)]; - + // Generate random age between 18 and 65 $age = rand(18, 65); - + // Calculate DOB based on age $year = date('Y') - $age; $month = str_pad(rand(1, 12), 2, '0', STR_PAD_LEFT); $day = str_pad(rand(1, 28), 2, '0', STR_PAD_LEFT); $dob = "{$day}-{$month}-{$year}"; - + // Generate employee code $empCode = 'EMP' . str_pad($index, 6, '0', STR_PAD_LEFT); - + // Generate email $email = strtolower($firstName . '.' . $lastName . $index) . '@' . $this->domains[array_rand($this->domains)]; - + // Generate mobile number (Indian format) $mobile = '+91' . rand(7000000000, 9999999999); - + // Generate insurance amounts $siOptions = [100000, 200000, 300000, 500000, 1000000]; $si = $siOptions[array_rand($siOptions)]; $si_enhancement = rand(0, 1) ? rand(50000, 200000) : 0; - + $proposed_si_1 = $si + rand(100000, 500000); $proposed_si_2 = $proposed_si_1 + rand(100000, 500000); $proposed_si_3 = $proposed_si_2 + rand(100000, 500000); @@ -716,64 +775,67 @@ class TestingController extends BaseController } - public function logo_renaming(){ - - $directory = ROOTPATH . 'public/uploads/logo/'; + public function logo_renaming() + { - if (!is_dir($directory)) { - die("Directory not found: $directory"); + $directory = ROOTPATH . 'public/uploads/logo/'; + + if (!is_dir($directory)) { + die("Directory not found: $directory"); + } + + $files = scandir($directory); + + $client_logo_files = $this->get_client_logo_files(); + + $rename_files = ""; + $failed_rename_files = ""; + + foreach ($files as $file) { + // Skip system entries + if ($file === '.' || $file === '..') { + continue; } - $files = scandir($directory); - $client_logo_files = $this->get_client_logo_files(); + $oldPath = $directory . $file; - $rename_files = ""; - $failed_rename_files = ""; + if (is_file($oldPath) && in_array(trim($file), $client_logo_files)) { - foreach ($files as $file) { - // Skip system entries - if ($file === '.' || $file === '..' ) { - continue; - } - + // Remove all spaces from filename + $newFileName = preg_replace('/\s+|\x{00A0}|\x{200B}|\x{200C}|\x{200D}|\x{FEFF}/u', '', $file); - $oldPath = $directory . $file; + $newPath = $directory . $newFileName; - if (is_file($oldPath) && in_array(trim($file) , $client_logo_files)) { - - // Remove all spaces from filename - $newFileName = preg_replace('/\s+|\x{00A0}|\x{200B}|\x{200C}|\x{200D}|\x{FEFF}/u', '', $file); - - $newPath = $directory . $newFileName; - - // Only rename if the name changed - if ($oldPath !== $newPath) { - if (rename($oldPath, $newPath)) { - $rename_files .= "\n Renamed: $file → $newFileName \n"; - } else { - $failed_rename_files .= "\n Failed file: $file \n"; - } + // Only rename if the name changed + if ($oldPath !== $newPath) { + if (rename($oldPath, $newPath)) { + $rename_files .= "\n Renamed: $file → $newFileName \n"; + } else { + $failed_rename_files .= "\n Failed file: $file \n"; } } } + } - $dbUpdated = $this->update_client_logo_files(); + $dbUpdated = $this->update_client_logo_files(); - log_message('error', 'Renamed Files: ' . $rename_files); - log_message('error', 'Failed Renames: ' . $failed_rename_files); - log_message('error', 'Database Update Status: ' . ($dbUpdated ? 'Success' : 'No changes made')); + log_message('error', 'Renamed Files: ' . $rename_files); + log_message('error', 'Failed Renames: ' . $failed_rename_files); + log_message('error', 'Database Update Status: ' . ($dbUpdated ? 'Success' : 'No changes made')); - return $this->response->setJSON(['status' => 'success', + return $this->response->setJSON([ + 'status' => 'success', 'message' => 'Logo renaming completed. kindly check backend logs for details', 'data' => [ 'renamed_files' => $rename_files, 'failed_renames' => $failed_rename_files ] - ])->setStatusCode(200); + ])->setStatusCode(200); } - public function get_client_logo_files(){ + public function get_client_logo_files() + { $db = \Config\Database::connect(); @@ -783,14 +845,15 @@ class TestingController extends BaseController $results = $query->getResultArray() ?? []; - $files = array_map(function($item) { + $files = array_map(function ($item) { return trim($item['client_logo']); }, $results); return $files; } - public function update_client_logo_files(){ + public function update_client_logo_files() + { $db = \Config\Database::connect(); @@ -803,9 +866,63 @@ class TestingController extends BaseController $query = $db->query($sql); return $db->affectedRows() > 0; - - } + public function createDefaultMailTempalteInDB() + { + $postDB = \Config\Database::connect(); // target DB + $preDB = \Config\Database::connect('preDB'); // source DB + + // Templates to copy + $templateNames = [ + 'member_welcome_mail', + 'member_reminder_mail', + 'member_review_and_summary_mail' + ]; + + + + + foreach ($templateNames as $template) { + + $exists = $postDB->table('notifications') + ->where('client_id', NULL) + ->where('template_name', $template) + ->countAllResults(); + + if ($exists > 0) { + continue; // Skip if already inserted + } + + // Fetch template from preDB + $templateData = $preDB->table('notifications') + ->where('client_id', NULL) + ->where('template_name', $template) + ->get() + ->getRowArray(); + + if (!empty($templateData)) { + + // Remove ID to avoid duplicate primary key issues + unset($templateData['id']); + + // Set created_by and timestamps if needed + $templateData['client_id'] = NULL; + $templateData['created_by'] = 1; + $templateData['cretaed_at'] = date('Y-m-d H:i:s'); + $templateData['updated_by'] = NULL; + $templateData['updated_at'] = NULL; + + // Insert into postDB + $postDB->table('notifications')->insert($templateData); + } + } + + + return $this->response->setJSON(['message'=>"Created Default Mail Tempalte In DB "])->setStatusCode(200); + } + + + } diff --git a/app/Controllers/UserController.php b/app/Controllers/UserController.php index b4d391dc..ec046563 100755 --- a/app/Controllers/UserController.php +++ b/app/Controllers/UserController.php @@ -62,7 +62,7 @@ class UserController extends AdminController // echo '
';
         // print_r($data); die;
         $data['roleData'] = $this->roleModel->select('id, role')->findAll();        
-        $data['teamData'] = $this->teamModel->select('id, name')->findAll();
+        $data['teamData'] = $this->teamModel->select('id, name')->where('is_active',1)->findAll();
         $this->loadLayout('UserList', $data);
     }
 
@@ -156,9 +156,11 @@ class UserController extends AdminController
     public function edit()
     {
 
+        // echo ":/ in 159";  
         if (!$this->request->getPost()) {
             return redirect()->to(base_url('/user/list'));
         } else {
+            // echo ":/ in 163";
             $id = $this->request->getPost('PrimaryKey');
             $teams = $this->request->getPost('team');
             $userData = $this->request->getPost();
@@ -166,6 +168,7 @@ class UserController extends AdminController
             unset($userData['PrimaryKey']);
 
             $existingData = $this->userModel->where('id',$id)->first();;
+            // dd($existingData);die;
 
             // Update data in the 'users' table based on the $id
             $userData['updated_by'] =  get_session_userid();
diff --git a/app/Helpers/excel_util_helper.php b/app/Helpers/excel_util_helper.php
index e608b013..2c7ff2bb 100755
--- a/app/Helpers/excel_util_helper.php
+++ b/app/Helpers/excel_util_helper.php
@@ -109,7 +109,8 @@ if (!function_exists('check_relationship')) {
 
                     $family_floaters = isset($policy_terms['family_floaters']);
                     if ($family_floaters) {
-                        if (isset($relationship[$col]) && $relationship[$col]['gender'] != $row[4]) {
+                        $relation_gender = normalizeGender($row[4]);
+                        if (isset($relationship[$col]) && $relationship[$col]['gender'] != $relation_gender) {
                             $error = "Gender relationship conflict: Expected " . $relationship[$col]['gender'] . ", received $row[4]";
                             return array('status' => false, 'error' => $error);
                         }
@@ -369,13 +370,24 @@ if (!function_exists('check_dob_diff')) {
 }
 
 if (!function_exists('data_group_by_family')) {
-    function data_group_by_family($emp_data, $data_source = 'excel', $action = '')
+    function data_group_by_family($emp_data, $data_source = 'excel', $action = '', $current_column_action = null)
     {
         $result = [];
         // Kint::dump($emp_data);
         foreach ($emp_data as $rkey => $row) {
+
+
+
             if ($data_source == 'excel') {
                 if (!check_row_is_empty_or_null($row)) {
+
+                    // for this condition to avoid 5,00,000 to 500000
+                    if($current_column_action == 'SI'){
+                        $row[3] = removeNumberFormatting($row[3]);
+                    }else if(in_array($current_column_action, ['I','DA', 'MI', 'A'])){
+                        $row[6] = removeNumberFormatting($row[6]);
+                    }
+
                     if ($action == 'enrollment') //if action is enrollment transform current row into inception row, becoz we treat enrollment as inception
                     {
                         $row = transform_enrollment_row_to_inception_row($row);
@@ -637,12 +649,19 @@ if (!function_exists('check_dependent_conflict')) {
 if (!function_exists('generate_relationship_code')) {
     function generate_relationship_code($arr)
     {
-        $gender = ['M' => 1, 'F' => 2];
+        $gender = [
+            'M' => 1, 
+            'Male' => 1, 
+            'male' => 1, 
+            'F' => 2,
+            'Female' => 2,
+            'female' => 2,
+        ];
         $relationship = ['self' => 1, 'spouse' => 2, 'son' => 3, 'daughter' => 4, 'father' => 5, 'mother' => 6, 'father-in-law' => 7, 'mother-in-law' => 8];
         $slug = \Config\Services::slug();
         $relationship_code = $slug->slugify($arr['relationship']);
         $emp_type_code = ($relationship_code == 'self' ? 'EMP_TYP_01' : 'EMP_TYP_03');
-        $relationship_code = $gender[trim($arr['gender'])] . $relationship[trim($relationship_code)];
+        $relationship_code = $gender[trim($arr['gender'])] ?? "" . $relationship[trim($relationship_code)] ?? "";
         return ['relationship_code' => $relationship_code, 'emp_type_code' => $emp_type_code];
     }
 }
@@ -2041,6 +2060,22 @@ if (!function_exists('formatIndianCurrency')) {
     }
 }
 
+if (!function_exists('normalizeGender')) {
+    function normalizeGender($gender)
+    {
+        $gender = strtoupper(trim($gender));
+
+        if (in_array($gender, ['M', 'MALE'])) {
+            return 'M';
+        } elseif (in_array($gender, ['F', 'FEMALE'])) {
+            return 'F';
+        }
+
+        // Optional: return null or original if not recognized
+        return null;
+    }
+}
+
 // ------------- FUNCTION FOR LEAD MEMBER DATA LIST VALIDATIONS --------------------------------------
 
 if (!function_exists('check_columns_name_exist')) {
@@ -2291,8 +2326,8 @@ if (!function_exists('validateFamily')) {
             // Validation 3: Validate spouse gender if spouse exists
             if ($spouseMember !== null) {
 
-                $selfGender = strtoupper(trim($selfMember[4])); // Gender field
-                $spouseGender = strtoupper(trim($spouseMember[4]));
+                $selfGender = normalizeGender(trim($selfMember[4])); // Gender field
+                $spouseGender = normalizeGender(trim($spouseMember[4]));
                 $selfName = $selfMember[2]; // Name field
                 $spouseName = $spouseMember[2];
                 
diff --git a/app/Helpers/sendMailNotification.php b/app/Helpers/sendMailNotification.php
index f9de6b09..a726fe16 100755
--- a/app/Helpers/sendMailNotification.php
+++ b/app/Helpers/sendMailNotification.php
@@ -57,6 +57,13 @@ class sendMailNotification
 
             $mail_content = str_replace(["[[app_link]]", "{{app_link}}"], "Review Details", $mail_content);
             if ($dataToInsert['relationship'] == 'Self' && $mail != null || $mail != '') {
+
+                                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
                 $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content,'bcc'=> $client_data['common_mails'], 'reply_to' => $client_data['reply_to'], 'attachments' => $attachments, 'common' => $common];
             }
             
@@ -89,6 +96,12 @@ class sendMailNotification
             $mail_content = str_replace(["[[member_mobile]]", "{{member_mobile}}"], $employee_mobile_no, $mail_content);
             $mail = $emp_data['email_corporate'];     
 
+                            $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
             $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content, 'bcc'=> $client_data['common_mails'], 'reply_to' => $client_data['reply_to'], 'common' => $common];
 
             return $wholeData;
@@ -139,6 +152,13 @@ class sendMailNotification
             $mail_content = str_replace(["[[ecard_download_link]]", "{{ecard_download_link}}"], "Download Insurance Card", $mail_content);
             $mail_content = str_replace(["[[client_name]]", "{{client_name}}"], $client_data['client_name'], $mail_content);
            
+                            $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
+
             $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content,'bcc'=> $client_data['common_mails'], 'reply_to' => $client_data['reply_to'], 'common' => $common];
 
             return $wholeData;
@@ -523,6 +543,13 @@ class sendMailNotification
                 $mail_content = str_replace(["[[member_mobile]]", "{{member_mobile}}"], $employee_mobile_no, $mail_content);
                 $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content , $mail_content);
 
+                                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
+
                 // print_r($mail_content); die;
 
                 // $mail = "aadhavanvalli@gmail.com";
@@ -825,6 +852,13 @@ class sendMailNotification
                         $full_name = $value['first_name'] .' ' .$value['last_name'];
                         $mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $full_name , $mail_content); 
 
+                                        $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
+
                         $wholeData[] =  ['mail' => $value['email'], 'subject' => $subject,'message'=> $mail_content, 'reply_to' => $client_data['reply_to'], 'common' => $common];
                         // $wholeData[] =  ['mail' => $value['email'], 'subject' => $subject,'message'=> $mail_content, 'bcc'=> $client_data['common_mails'}};
                     }
@@ -1118,6 +1152,11 @@ class sendMailNotification
                 
                 $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content , $mail_content);
 
+                                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
 
                 $hr_mails = $client_data['hr_mails'];
                 $mail_array = explode(',', $hr_mails);
@@ -1182,7 +1221,14 @@ class sendMailNotification
 
             $mail_content = str_replace(["[[app_link]]", "{{app_link}}"], "Review Details", $mail_content);
             
-            if ($mail != null || $mail != '') {
+            if ( isset($mail) && !empty($mail) ) {
+                
+                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
                 $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content,'bcc'=> $client_data['common_mails'], 'reply_to' => $client_data['reply_to'], 'attachments' => $attachments];
             }
             
@@ -1215,6 +1261,13 @@ class sendMailNotification
             if ((isset($notification_data) && $notification_data['enabled'] == 1)) {
 
                 if (isset($mail) && !empty($mail)) {
+
+                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
                     $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content, 'bcc'=> $client_data['common_mails'], 'reply_to' => $client_data['reply_to']];
                 }
 
@@ -1268,6 +1321,12 @@ class sendMailNotification
             $mail_content = str_replace(["[[ecard_download_link]]", "{{ecard_download_link}}"], "Download Insurance Card", $mail_content);
             $mail_content = str_replace(["[[client_name]]", "{{client_name}}"], $client_data['client_name'], $mail_content);
 
+                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
             $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content,'bcc'=> $client_data['common_mails'],'attachments' => $attachments, 'reply_to' => $client_data['reply_to']];
 
             return $wholeData;
@@ -1419,6 +1478,11 @@ class sendMailNotification
                 $mail_content = str_replace(["[[member_mobile]]", "{{member_mobile}}"], $mobile, $mail_content);
                 $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content , $mail_content);
 
+                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
 
                 $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content, 'bcc'=> $client_data['common_mails'], 'reply_to' => $client_data['reply_to']];
 
@@ -1568,6 +1632,13 @@ class sendMailNotification
                 $mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . ' (' . $emp_code . ')' , $mail_content);
                 $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content , $mail_content);
 
+
+                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
+
                 $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content, 'reply_to' => $client_data['reply_to']];
                 
                 return  $wholeData;
@@ -1717,6 +1788,11 @@ class sendMailNotification
                 $mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . ' (' . $emp_code . ')' , $mail_content);
                 $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content , $mail_content);
 
+                $mail_content = preg_replace('/]*>( |\s)*<\/p>/i', '', $mail_content);
+
+                $data['params'] = $params;$data['client_logo'] = $client_logo;
+                $data['mail_content'] = $mail_content;
+                $mail_content = view('mail_template', $data);
                 
                 $wholeData =  ['mail' => $mail, 'subject' => $subject,'message'=> $mail_content, 'reply_to' => $client_data['reply_to']];
 
diff --git a/app/Helpers/utility_helper.php b/app/Helpers/utility_helper.php
index f66229f5..9130a991 100755
--- a/app/Helpers/utility_helper.php
+++ b/app/Helpers/utility_helper.php
@@ -65,6 +65,19 @@ if (!function_exists('file_Upload')) {
     }
 }
 
+if (!function_exists('file_Upload_for_lead')) {
+    function file_Upload_for_lead($fileToUpload, $filepath)
+    {
+        if ($fileToUpload !== null && $fileToUpload->isValid() && !$fileToUpload->hasMoved()) {
+            $fileToUpload->move($filepath);
+            $fileName = $fileToUpload->getName();
+            return $fileName;
+        } else {
+            return "";
+        }
+    }
+}
+
 // if (!function_exists('multi_file_Upload')) {
 //     function multi_file_Upload($fileToUpload, $filepath)
 //     {
@@ -859,3 +872,17 @@ if (!function_exists('expected_amount_calc')) {
         return round($expectedAmount, 2); // Optional: round to 2 decimal places
     }
 }
+
+if (!function_exists('getFileIfExists')) {
+    function getFileIfExists($path)
+    {   
+        return file_exists(FCPATH . $path) ? base_url($path) : '';
+    }
+}
+
+if (!function_exists('removeNumberFormatting')) {
+    function removeNumberFormatting($number)
+    {
+        return (float) str_replace(',', '', trim($number));
+    }
+}
diff --git a/app/Models/ClientPolicyModel.php b/app/Models/ClientPolicyModel.php
index 152cad7f..d3618eb6 100755
--- a/app/Models/ClientPolicyModel.php
+++ b/app/Models/ClientPolicyModel.php
@@ -56,6 +56,7 @@ class ClientPolicyModel extends Model
         "is_lgbtq",
         "placement_json",
         "policy_entry_from",
+        "is_from_lead",
     ];
 
     // Callbacks
diff --git a/app/Models/EmployeePolicyModel.php b/app/Models/EmployeePolicyModel.php
index bea76e50..97aa91d4 100755
--- a/app/Models/EmployeePolicyModel.php
+++ b/app/Models/EmployeePolicyModel.php
@@ -611,6 +611,36 @@ class EmployeePolicyModel extends Model
         $subquery_endorsement_condition = "{$insurer_or_tpa}" === 'tpa' ? "WHERE (endorsement_id IS NOT NULL OR endorsement_id != '')" : "WHERE (endorsement_id IS NULL OR endorsement_id = '')";
 
 
+        /*                     
+            ROUND(sidata.new_si_premium - sidata.old_si_premium, 2) AS difference_premium,
+            ROUND(
+                (sidata.new_si_premium - sidata.old_si_premium) * 
+                (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365,
+                2
+            ) AS pro_rata_premium,
+            ROUND(
+                (
+                (sidata.new_si_premium - sidata.old_si_premium) *
+                (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
+                ) * 0.18,
+                2
+            ) AS gst,
+            ROUND(
+                (
+                (sidata.new_si_premium - sidata.old_si_premium) *
+                (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
+                ) +
+                ROUND(
+                (
+                    (sidata.new_si_premium - sidata.old_si_premium) *
+                    (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
+                ) * 0.18,
+                2
+                ),
+                2
+            ) AS total 
+        */
+
         $query = $this->db->query("
                     SELECT
                         a.id AS endorsement_primarykey,
@@ -643,33 +673,40 @@ class EmployeePolicyModel extends Model
                         sidata.old_si_premium,
                         sidata.date_of_coverage,
                         DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1 AS no_of_days,
-                        ROUND(sidata.new_si_premium - sidata.old_si_premium, 2) AS difference_premium,
+
+                        ROUND(ABS(sidata.new_si_premium - sidata.old_si_premium), 2) AS difference_premium,
                         ROUND(
-                            (sidata.new_si_premium - sidata.old_si_premium) * 
-                            (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365,
+                            ABS(
+                                (sidata.new_si_premium - sidata.old_si_premium) * 
+                                (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
+                            ),
                             2
                         ) AS pro_rata_premium,
                         ROUND(
-                            (
-                            (sidata.new_si_premium - sidata.old_si_premium) *
-                            (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
-                            ) * 0.18,
+                            ABS(
+                                (
+                                    (sidata.new_si_premium - sidata.old_si_premium) *
+                                    (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
+                                ) * 0.18
+                            ),
                             2
                         ) AS gst,
                         ROUND(
-                            (
-                            (sidata.new_si_premium - sidata.old_si_premium) *
-                            (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
-                            ) +
-                            ROUND(
-                            (
-                                (sidata.new_si_premium - sidata.old_si_premium) *
-                                (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
-                            ) * 0.18,
-                            2
+                            ABS(
+                                (
+                                    (sidata.new_si_premium - sidata.old_si_premium) *
+                                    (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
+                                ) +
+                                (
+                                    (
+                                        (sidata.new_si_premium - sidata.old_si_premium) *
+                                        (DATEDIFF(employee_polices.policy_end_date, sidata.date_of_coverage) + 1) / 365
+                                    ) * 0.18
+                                )
                             ),
                             2
                         ) AS total
+
                     FROM
                         emp_endorsement a
                     LEFT JOIN employees ON employees.emp_code = a.emp_code
@@ -1532,8 +1569,15 @@ class EmployeePolicyModel extends Model
                     e.doj, 
                     e.band,
                     TIMESTAMPDIFF(YEAR, e.dob, CURDATE()) AS emp_age,
-                    (SELECT name FROM employees WHERE relationship = "Self" and emp_code = ' . $this->db->escape($emp_code) . ' and client_id = '.$client_id.' LIMIT 1) AS self,
-
+                    (
+                        SELECT name FROM employees 
+                        WHERE relationship = "Self" 
+                        and emp_code = ' . $this->db->escape($emp_code) . ' 
+                        and client_id = '.$client_id.'
+                        and is_active = 1
+                        and emp_status = "active"
+                        LIMIT 1
+                    ) AS self,
 
                     ep.tpa_id, 
                     ep.uhid,
diff --git a/app/Models/FileModel.php b/app/Models/FileModel.php
index ff4f584e..0f72c18f 100755
--- a/app/Models/FileModel.php
+++ b/app/Models/FileModel.php
@@ -22,6 +22,7 @@ class FileModel extends Model
         "uploaded_by",
         "updated_by",
         "hr_file_id",
+        "is_comparison_skipped",
     ];
 
 
diff --git a/app/Models/PolicyTransactionModel.php b/app/Models/PolicyTransactionModel.php
index a9629d73..e9f6e8cc 100644
--- a/app/Models/PolicyTransactionModel.php
+++ b/app/Models/PolicyTransactionModel.php
@@ -1829,24 +1829,35 @@ class PolicyTransactionModel extends Model
         // ==============================
         if ($date_type == 'statement_month' && $start_date != 0 && $end_date != 0) {
             $date_condition = "
-                AND insurer_statements.month >= '{$start_date}'
-                AND insurer_statements.month <= '{$end_date}'
+                AND insurer_statements_oq.month >= '{$start_date}'
+                AND insurer_statements_oq.month <= '{$end_date}'
             ";
         }
 
         // ==============================
         // BASE QUERY
         // ==============================
-        $builder = $this->db->table('policy_transaction')
+
+
+        // ==============================
+        // Without Statement Upload
+        // ==============================
+
+
+        $builder2 = $this->db->table('policy_transaction')
             ->select("
-                policy_transaction.*,
+                policy_transaction.id AS id,
+                policy_transaction.endorsement_no AS endorsement_no,
+                policy_transaction.ref AS ref,
                 DATE_FORMAT(policy_transaction.policy_issue_date, '%d %b %Y') AS policy_issue_date,
-                DATE_FORMAT(
-                    IF(policy_transaction.month IS NULL, 
-                        policy_transaction.policy_issue_date, 
-                        policy_transaction.month
-                    ), '%b %Y'
-                ) AS policy_issue_month,
+
+                DATE_FORMAT( policy_transaction.policy_issue_date,, '%b %Y') AS policy_issue_month,
+
+                CASE
+                    WHEN 1 = 1 THEN 'no statement uploaded'
+                    ELSE 'statement uploaded'
+                END AS statement_uploaded ,
+
 
                 CASE
                     WHEN clients.client_type = 1 THEN 'Group'
@@ -1898,89 +1909,15 @@ class PolicyTransactionModel extends Model
 
                 -- ==============================
                 -- SUBQUERY: Total IRDA Amount
+                -- Alias Agreed Amount ...!!
                 -- ==============================
-                ROUND((
-                    SELECT (
-                        SUM(co_share_stmt_details.actual_bp_brokerage_amt) + 
-                        SUM(co_share_stmt_details.actual_tp_brokerage_amt) + 
-                        SUM(co_share_stmt_details.actual_tep_brokerage_amt) +
-                        SUM(co_share_stmt_details.reward)
-                    )
-                    FROM co_share_stmt_details
-                    JOIN insurer_statements ON co_share_stmt_details.statement_id = insurer_statements.id
-                    WHERE co_share_stmt_details.co_share_id = pt_co_share_details.id
-                    AND co_share_stmt_details.is_active = 1
-                    AND insurer_statements.is_active = 1
-                    {$date_condition}
-                ), 2) AS total_irda_amt,
+                ROUND(pt_co_share_details.exp_amt, 2) AS total_irda_amt,
 
                 -- Reward Only
-                ROUND((
-                    SELECT SUM(co_share_stmt_details.reward)
-                    FROM co_share_stmt_details
-                    JOIN insurer_statements ON co_share_stmt_details.statement_id = insurer_statements.id
-                    WHERE co_share_stmt_details.co_share_id = pt_co_share_details.id
-                    AND co_share_stmt_details.is_active = 1
-                    AND insurer_statements.is_active = 1
-                    {$date_condition}
-                ), 2) AS reward,
+                ROUND(0, 2) AS reward,
 
                 -- Billed Amount
-                ROUND((
-                    SELECT SUM(
-                        COALESCE(co_share_stmt_details.actual_bp_brokerage_amt, 0) +
-                        COALESCE(co_share_stmt_details.actual_tp_brokerage_amt, 0) +
-                        COALESCE(co_share_stmt_details.actual_tep_brokerage_amt, 0) +
-                        COALESCE(co_share_stmt_details.reward, 0)
-                    )
-                    FROM co_share_stmt_details
-                    JOIN pt_co_share_details AS pt_table ON co_share_stmt_details.co_share_id = pt_table.id
-                    JOIN insurer_statements ON co_share_stmt_details.statement_id = insurer_statements.id
-                    WHERE co_share_stmt_details.co_share_id = pt_co_share_details.id
-                    AND co_share_stmt_details.is_active = 1
-                    AND pt_table.is_active = 1
-                    AND insurer_statements.is_active = 1
-                    AND insurer_statements.invoice_status IS NOT NULL
-                    {$date_condition}
-                ), 2) AS billed_amt,
-
-                -- Unbilled Amount
-                ROUND(
-                (
-                    (
-                        SELECT 
-                            SUM(
-                                COALESCE(co_share_stmt_details.actual_bp_brokerage_amt, 0) +
-                                COALESCE(co_share_stmt_details.actual_tp_brokerage_amt, 0) +
-                                COALESCE(co_share_stmt_details.actual_tep_brokerage_amt, 0) +
-                                COALESCE(co_share_stmt_details.reward, 0)
-                            )
-                        FROM co_share_stmt_details
-                        JOIN insurer_statements ON co_share_stmt_details.statement_id = insurer_statements.id
-                        WHERE co_share_stmt_details.co_share_id = pt_co_share_details.id
-                        AND co_share_stmt_details.is_active = 1
-                        {$date_condition}
-                    ) 
-                        -
-                    (
-                        SELECT 
-                            SUM(
-                                COALESCE(co_share_stmt_details.actual_bp_brokerage_amt, 0) +
-                                COALESCE(co_share_stmt_details.actual_tp_brokerage_amt, 0) +
-                                COALESCE(co_share_stmt_details.actual_tep_brokerage_amt, 0) +
-                                COALESCE(co_share_stmt_details.reward, 0)
-                            )
-                        FROM co_share_stmt_details
-                        JOIN pt_co_share_details AS pt_table ON co_share_stmt_details.co_share_id = pt_table.id
-                        JOIN insurer_statements ON co_share_stmt_details.statement_id = insurer_statements.id
-                        WHERE co_share_stmt_details.co_share_id = pt_co_share_details.id
-                        AND co_share_stmt_details.is_active = 1
-                        AND pt_table.is_active = 1
-                        AND insurer_statements.is_active = 1
-                        AND insurer_statements.invoice_status IS NULL
-                        {$date_condition}
-                    )
-                ), 2) AS unbilled_amt,
+                ROUND(0, 2) AS billed_amt,
 
                 created_user.first_name AS user_name,
 
@@ -2012,9 +1949,255 @@ class PolicyTransactionModel extends Model
             ->join('tpa_branch', 'policy_transaction.tpa_branch_id = tpa_branch.id', 'left')
             ->join('user_profiles AS sales_user', 'policy_transaction.sales_generated_by = sales_user.id', 'left')
             ->join('user_profiles AS service_user', 'policy_transaction.serviced_by = service_user.id', 'left')
-            ->join('user_profiles AS created_user', 'policy_transaction.created_by = created_user.id', 'left')
+            ->join('user_profiles AS created_user', 'policy_transaction.created_by = created_user.id', 'left') 
+            
             ->where('policy_transaction.is_active', 1)
-            ->where('pt_co_share_details.is_active', 1);
+            ->where('pt_co_share_details.is_active', 1)
+
+        // ========================================================
+        // GROUP BY Insurer Statement Months
+        // =======================================================
+         ->groupBy('policy_transaction.policy_no , pt_co_share_details.insurer_id ');
+
+        // ==============================
+        // ROLE-BASED FILTERS
+        // ==============================
+        if (
+            (!in_array(get_role_id(), [1, 5])) &&
+            !(
+                in_array(MANAGEMENT_TEAM_ID, user_team()) ||
+                in_array(FINANCE_TEAM_ID, user_team()) ||
+                in_array(BUSINESS_TEAM_ID, user_team())
+            )
+        ) {
+            if (get_role_id() == 4 && in_array(POS_TEAM_ID, user_team())) {
+                $builder2->where('policy_transaction.created_by', get_session_userid());
+            }
+        }
+
+        // ==============================
+        // ADDITIONAL FILTERS
+        // ==============================
+        if (!empty($where)) {
+            log_message('info', 'Where condition: ' . json_encode($where));
+            $builder2->where($where);
+        }
+
+        if ($start_date != 0 && $end_date != 0 && $date_type != 0 && $date_type != 'statement_month') {
+            $startDate = date('Y-m-d 00:00:00', strtotime($start_date));
+            $endDate   = date('Y-m-d 23:59:59', strtotime($end_date));
+
+            $builder2->where("policy_transaction.{$date_type} >=", $startDate)
+                    ->where("policy_transaction.{$date_type} <=", $endDate);
+        }
+
+
+        // ==============================
+        // FILTER BY IDs
+        // ==============================
+        if ($client_id != 0) $builder2->where('policy_transaction.client_id', $client_id);
+        if ($insurer_id != 0) $builder2->where('policy_transaction.insurer_id', $insurer_id);
+        if ($client_branch_id != 0) $builder2->where('policy_transaction.client_branch_id', $client_branch_id);
+        if ($insurer_branch_id != 0) $builder2->where('policy_transaction.insurer_branch_id', $insurer_branch_id);
+        if ($client_policy_id != 0) $builder2->where('policy_transaction.client_policy_id', $client_policy_id);
+        if ($user_id != 0) $builder2->where('policy_transaction.created_by', $user_id);
+        if ($policy_type_id != 0) $builder2->where('client_policy.policy_type_id', $policy_type_id);
+        if ($issuer != 0) $builder2->where('policy_transaction.issuer', $issuer);
+
+        // ==============================
+        // DEFAULT 90-DAY FILTER
+        // ==============================
+        if (
+            $client_id == 0 && 
+            $insurer_id == 0 && 
+            $policy_type_id == 0 && 
+            $date_type == 0 && 
+            $issuer == 0
+        ) {
+            $fromDate = date('Y-m-d', strtotime('-90 days'));
+            $toDate   = date('Y-m-d 23:59:59');
+
+            if (empty($where)) {
+                $builder2->where('policy_transaction.created_at >=', $fromDate)
+                        ->where('policy_transaction.created_at <=', $toDate);
+            }
+        }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        // ==============================
+        // With Statement Upload
+        // ==============================
+
+        $builder = $this->db->table('policy_transaction')
+            ->select("
+                policy_transaction.id AS id,
+                policy_transaction.endorsement_no AS endorsement_no,
+                policy_transaction.ref AS ref,
+                DATE_FORMAT(policy_transaction.policy_issue_date, '%d %b %Y') AS policy_issue_date,
+                DATE_FORMAT(
+                    IF(insurer_statements_oq.month IS NULL, 
+                        policy_transaction.policy_issue_date, 
+                        insurer_statements_oq.month
+                    ), '%b %Y'
+                ) AS policy_issue_month,
+
+                CASE
+                    WHEN insurer_statements_oq.month IS NULL THEN 'no statement uploaded'
+                    ELSE 'statement uploaded'
+                END AS statement_uploaded ,
+
+
+                CASE
+                    WHEN clients.client_type = 1 THEN 'Group'
+                    WHEN clients.client_type = 2 THEN 'Retail'
+                    ELSE '-'
+                END AS client_type,
+
+                CASE
+                    WHEN policy_transaction.revenue_type = 'NA' THEN 'Fresh'
+                    ELSE 'Renewal'
+                END AS revenue_type,
+
+                CASE
+                    WHEN policy_transaction.action_type = 'inception' THEN 'Policy'
+                    ELSE 'Endorsement'
+                END AS action_type,
+
+                clients.client_name AS client_name,
+                clients.short_name AS client_short_name,
+                client_branch.branch_name AS client_branch_name,
+                client_branch.address1 AS client_address,
+                policy_type.policy_type,
+                policy_type.bap,
+                insurers.name AS insurer_name,
+                insurers.short_name AS insurer_short_name,
+                insurer_branch.branch_name AS insurer_branch_name,
+                insurer_branch.branch_code AS insurer_branch_code,
+                user_profiles.first_name AS user_name,
+                vehicle.vehicle_no,
+                tpa.name AS tpa_name,
+                pt_co_share_details.remark AS remarks,
+                pt_co_share_details.cop_amt AS bp_amt,
+                pt_co_share_details.exp_amt,
+                pt_co_share_details.id AS pt_id,
+                sales_user.first_name AS salse_person_name,
+                service_user.first_name AS service_person_name,
+
+                ROUND(pt_co_share_details.cop_amt + pt_co_share_details.cotp_amt + pt_co_share_details.cotep_amt, 2) AS premium_wo_gst,
+                ROUND((ROUND(pt_co_share_details.cop_amt + pt_co_share_details.cotp_amt + pt_co_share_details.cotep_amt, 2) * 18 / 100), 2) AS gst_amount,
+                ROUND(
+                    ROUND(pt_co_share_details.cop_amt + pt_co_share_details.cotp_amt + pt_co_share_details.cotep_amt, 2) + 
+                    ROUND((ROUND(pt_co_share_details.cop_amt + pt_co_share_details.cotp_amt + pt_co_share_details.cotep_amt, 2) * 18 / 100), 2),
+                2) AS total_premium,
+
+                ROUND(pt_co_share_details.cotp_amt + pt_co_share_details.cotep_amt, 2) AS tp_or_ter,
+                DATEDIFF(policy_transaction.policy_end_date, CURDATE()) AS days,
+                (pt_co_share_details.agreed_tp_per + pt_co_share_details.agreed_tep_per) AS agreed_tp_or_ter_per,
+                pt_co_share_details.agreed_bp_per,
+
+                -- ==============================
+                -- SUBQUERY: Total IRDA Amount
+                -- Alias Agreed Amount ...!!
+                -- ==============================
+                ROUND(pt_co_share_details.exp_amt, 2) AS total_irda_amt,
+                -- Reward Only
+                ROUND((
+                    SELECT SUM(co_share_stmt_details.reward)
+                    FROM co_share_stmt_details
+                    JOIN insurer_statements ON co_share_stmt_details.statement_id = insurer_statements.id
+                    WHERE co_share_stmt_details.co_share_id = pt_co_share_details.id
+                    AND co_share_stmt_details.is_active = 1
+                    AND insurer_statements.is_active = 1
+                    AND insurer_statements.month = insurer_statements_oq.month
+                    {$date_condition}
+                    GROUP BY('policy_transaction.policy_no , insurer_statements.month , pt_co_share_details.insurer_id')
+                ), 2) AS reward,
+
+                -- Billed Amount
+                ROUND((
+                    SELECT SUM(
+                        COALESCE(co_share_stmt_details.actual_bp_brokerage_amt, 0) +
+                        COALESCE(co_share_stmt_details.actual_tp_brokerage_amt, 0) +
+                        COALESCE(co_share_stmt_details.actual_tep_brokerage_amt, 0) +
+                        COALESCE(co_share_stmt_details.reward, 0)
+                    )
+                    FROM co_share_stmt_details
+                    JOIN pt_co_share_details AS pt_table ON co_share_stmt_details.co_share_id = pt_table.id
+                    JOIN insurer_statements ON co_share_stmt_details.statement_id = insurer_statements.id
+                    WHERE co_share_stmt_details.co_share_id = pt_co_share_details.id
+                    AND co_share_stmt_details.is_active = 1
+                    AND pt_table.is_active = 1
+                    AND insurer_statements.is_active = 1
+                    AND insurer_statements.invoice_status IS NOT NULL
+                    AND insurer_statements.month = insurer_statements_oq.month
+                    {$date_condition}
+                    GROUP BY('policy_transaction.policy_no , insurer_statements.month , pt_co_share_details.insurer_id')
+                ), 2) AS billed_amt,
+
+                created_user.first_name AS user_name,
+
+                CASE 
+                    WHEN pt_co_share_details.co_share_type IN (0, 1) THEN policy_transaction.policy_no
+                    WHEN pt_co_share_details.co_share_type > 1 THEN 
+                        CASE 
+                            WHEN pt_co_share_details.follower_policy_no IS NULL OR pt_co_share_details.follower_policy_no = '' 
+                            THEN policy_transaction.policy_no
+                            ELSE pt_co_share_details.follower_policy_no
+                        END
+                    ELSE policy_transaction.policy_no
+                END AS policy_no
+            ")
+
+            // ==============================
+            // JOINS
+            // ==============================
+            ->join('pt_co_share_details', 'policy_transaction.id = pt_co_share_details.pt_id', 'left')
+            ->join('clients', 'clients.id = policy_transaction.client_id')
+            ->join('client_branch', 'policy_transaction.client_branch_id = client_branch.id', 'left')
+            ->join('client_policy', 'policy_transaction.client_policy_id = client_policy.id', 'left')
+            ->join('user_profiles', 'policy_transaction.created_by = user_profiles.id', 'left')
+            ->join('vehicle', 'policy_transaction.vehicle_id = vehicle.id', 'left')
+            ->join('policy_type', 'policy_transaction.policy_type_id = policy_type.id', 'left')
+            ->join('insurers', 'pt_co_share_details.insurer_id = insurers.id', 'left')
+            ->join('insurer_branch', 'pt_co_share_details.insurer_branch_id = insurer_branch.id', 'left')
+            ->join('tpa', 'policy_transaction.tpa_id = tpa.id', 'left')
+            ->join('tpa_branch', 'policy_transaction.tpa_branch_id = tpa_branch.id', 'left')
+            ->join('user_profiles AS sales_user', 'policy_transaction.sales_generated_by = sales_user.id', 'left')
+            ->join('user_profiles AS service_user', 'policy_transaction.serviced_by = service_user.id', 'left')
+            ->join('user_profiles AS created_user', 'policy_transaction.created_by = created_user.id', 'left') 
+            
+            
+            ->join('co_share_stmt_details', 'pt_co_share_details.id = co_share_stmt_details.co_share_id','left')
+            ->join('insurer_statements insurer_statements_oq','insurer_statements_oq.id = co_share_stmt_details.statement_id','left')
+            
+            ->where('policy_transaction.is_active', 1)
+            ->where('pt_co_share_details.is_active', 1)
+            ->where('insurer_statements_oq.id IS NOT NULL')
+
+
+        // ========================================================
+        // GROUP BY Insurer Statement Months
+        // =======================================================
+         ->groupBy('policy_transaction.policy_no , pt_co_share_details.insurer_id ,insurer_statements_oq.month');
 
         // ==============================
         // ROLE-BASED FILTERS
@@ -2053,12 +2236,12 @@ class PolicyTransactionModel extends Model
             $startDate = date('Y-m-d', strtotime($start_date));
             $endDate   = date('Y-m-d', strtotime($end_date));
 
-            $builder->join('co_share_stmt_details', 'pt_co_share_details.id = co_share_stmt_details.co_share_id', 'left')
-                    ->join('insurer_statements', 'co_share_stmt_details.statement_id = insurer_statements.id', 'left')
+            $builder->join('co_share_stmt_details cssdfilter', 'pt_co_share_details.id = cssdfilter.co_share_id', 'left')
+                    ->join('insurer_statements', 'cssdfilter.statement_id = insurer_statements.id', 'left')
                     ->where('insurer_statements.is_active', 1)
                     ->where('insurer_statements.month >=', $startDate)
                     ->where('insurer_statements.month <=', $endDate)
-                    ->groupBy('co_share_stmt_details.co_share_id');
+                    ->groupBy('cssdfilter.co_share_id');
         }
 
         // ==============================
@@ -2092,17 +2275,22 @@ class PolicyTransactionModel extends Model
             }
         }
 
-        // ==============================
-        // ORDER & EXECUTION
-        // ==============================
-        $builder->orderBy('policy_transaction.id', 'desc');
 
-        $result = $builder->get()->getResultArray();
 
-        // Uncomment if you need to debug SQL
-        // dd($this->db->getLastQuery());
+
+
+        $sql1 = $builder2->getCompiledSelect();
+        $sql2 = $builder->getCompiledSelect();
+
+       $finalSql = "($sql1) UNION ALL ($sql2) 
+                        ORDER BY policy_no DESC, insurer_branch_name ASC, statement_uploaded ASC,
+                                STR_TO_DATE(policy_issue_month, '%b %Y') ASC";
+
+
+        $result = $this->db->query($finalSql)->getResultArray();
 
         return $result;
+
     }
 
 
diff --git a/app/Views/UserList.php b/app/Views/UserList.php
index 2936af69..82441b22 100755
--- a/app/Views/UserList.php
+++ b/app/Views/UserList.php
@@ -342,6 +342,13 @@ table.dataTable tbody td {
 
 
 
+    get()['userData']->role;
+                                        
+
+    ?>
 
 
     
@@ -511,7 +518,17 @@ table.dataTable tbody td { @@ -522,7 +539,16 @@ table.dataTable tbody td { @@ -673,7 +699,34 @@ table.dataTable tbody td { BDS - All access All access + + Accounts + BDS - Policy Transaction + Policy | Endorsement | Statement Upload + + BDS - Report + TAT wise | ACM Status wise | ACM TAT wise + + + BDS - Policy Report + BDS | Variance | Outstanding | IRDA | Renewal | TAT Band + + + BDS - Pending Actions + Finance Team + + + BDS - Masters + Vehicle | CD | Insurer + + + BDS - Documents + ✓ + + + + POS BDS - Policy Transaction diff --git a/app/Views/batch_list.php b/app/Views/batch_list.php index cbbc1731..d4b69dcf 100755 --- a/app/Views/batch_list.php +++ b/app/Views/batch_list.php @@ -82,14 +82,15 @@ - - + - -   + - + +   + + @@ -98,7 +99,6 @@   - @@ -135,6 +135,11 @@ failed + + + failed + diff --git a/app/Views/cd_master_add_modal.php b/app/Views/cd_master_add_modal.php index c57936c5..9089d35f 100644 --- a/app/Views/cd_master_add_modal.php +++ b/app/Views/cd_master_add_modal.php @@ -46,7 +46,7 @@
- @@ -229,11 +229,11 @@ $('#opening_bal').prop("disabled", false); if(isCdMasterPage == true){ - $('#client_id').val('').change(); - $('#insurer_id_for_cd').val('').change(); - $('#insurer_branch_id').val('').change(); + $('#cd_client_id').val('').select2(); + $('#insurer_id_for_cd').val('').select2(); + $('#insurer_branch_id').val('').select2(); - $('#client_id').prop("disabled", false); + $('#cd_client_id').prop("disabled", false); $('#insurer_id_for_cd').prop("disabled", false); $('#insurer_branch_id').prop("disabled", false); @@ -266,7 +266,7 @@ ); }); - $branchSelect.val('').trigger('change.select2'); + $branchSelect.val('').select2(); } function showCdMasterAddModal(){ @@ -301,5 +301,43 @@ $('#cd_ac_no_for_cd_master').append(option); } + function checkDuplicateCdAccount(){ + + let url = ''; + let client_id = $('#cd_client_id').val(); + let insurer_id = $('#insurer_id_for_cd').val(); + let insurer_branch_id = $('#insurer_branch_id').val(); + console.log({client_id, insurer_id, insurer_branch_id}); + + // Data to send in the AJAX request + let requestData = { + client_id: client_id, + insurer_id: insurer_id, + insurer_branch_id: insurer_branch_id, + }; + + if(client_id != "" && insurer_id != "" && insurer_branch_id != ""){ + // Send AJAX request + sendAjaxRequestForGlobal(url, 'GET', requestData, function(response) { + + console.log('Data fetched successfully:', response); + + if (response.status == true) { + console.log('No dublicate found'); + } else { + + $('#cd_client_id').val('').select2(); + $('#insurer_id_for_cd').val('').select2(); + $('#insurer_branch_id').val('').select2(); + toastr.warning(response.message, 'WARNING'); + } + + }, function(xhr, status, error) { + console.error('Error fetching data:', error); + console.error(xhr.responseText); + toastr.error('An error occurred while checking the CD amount.', 'ERROR'); + }); + } + } \ No newline at end of file diff --git a/app/Views/cd_master_list.php b/app/Views/cd_master_list.php index f9ebba28..466588e9 100755 --- a/app/Views/cd_master_list.php +++ b/app/Views/cd_master_list.php @@ -323,7 +323,7 @@ table.dataTable thead th { $('#cd_client_id').prop("disabled", true); $('#insurer_id_for_cd').val(res.data.insurer_id).change(); $('#insurer_id_for_cd').prop("disabled", true); - $('#insurer_branch_id').val(res.data.insurer_id).change(); + $('#insurer_branch_id').val(res.data.insurer_branch_id).select2(); $('#insurer_branch_id').prop("disabled", true); $('#opening_date').val(res.data.opening_date); $('#cd_ac_no_for_cd_master').val(res.data.cd_ac_no); diff --git a/app/Views/client_policy.php b/app/Views/client_policy.php index 253d690b..080c1e87 100755 --- a/app/Views/client_policy.php +++ b/app/Views/client_policy.php @@ -46,33 +46,40 @@ height: 0; } -.slider { - position: relative; - width: 50px; - height: 25px; - background-color: #fff; - border-radius: 25px; - box-shadow: 0 0 5px rgba(0,0,0,0.2); - transition: 0.3s; +.slider, +.slider_blue { +position: relative; +width: 50px; +height: 25px; +background-color: #fff; +border-radius: 25px; +box-shadow: 0 0 5px rgba(0,0,0,0.2); +transition: 0.3s; } -.slider::before { - content: ""; - position: absolute; - height: 19px; - width: 19px; - left: 3px; - top: 3px; - background-color: #ccc; - border-radius: 50%; - transition: 0.3s; +.slider::before , +.slider_blue::before { +content: ""; +position: absolute; +height: 19px; +width: 19px; +left: 3px; +top: 3px; +background-color: #ccc; +border-radius: 50%; +transition: 0.3s; } input:checked + .slider { background-color: #ff4d4d; /* red when ON */ } -input:checked + .slider::before { +input:checked + .slider_blue { + background-color: #268ef5ff; /* blue when ON */ +} + +input:checked + .slider::before , +input:checked + .slider_blue::before { transform: translateX(25px); background-color: #fff; } @@ -269,23 +276,18 @@ input:checked + .slider::before {
-
-
@@ -842,6 +844,17 @@ input:checked + .slider::before { if(response.status == false && response.insurer_id != 'undefined'){ toastr.warning('The CD Account Number not found.', 'Warning'); + + $('#cd_ac_no').empty(); + $('#cd_ac_no').append($('
diff --git a/app/Views/leads_list.php b/app/Views/leads_list.php index dad5ce01..1762f32c 100644 --- a/app/Views/leads_list.php +++ b/app/Views/leads_list.php @@ -164,7 +164,7 @@ table.dataTable tbody td { -
S.No 
+
S.No  
Lead Type  
Issuer  
Client Type  
@@ -209,8 +209,10 @@ table.dataTable tbody td {