FEAT_DEPENDENT_ADD_FLOW_IN_THE_POST_BENIFTS_APP
This commit is contained in:
parent
bf2908723a
commit
0928dc852b
@ -235,6 +235,7 @@ $routes->group("/client", ["filter" => "authMVC"], function ($routes) {
|
||||
|
||||
$routes->group("/employee", ["filter" => "authMVC"], function ($routes) {
|
||||
$routes->get("list", "EmployeeController::list");
|
||||
$routes->get("pending-approvals", "EmployeeController::pendingApprovalsList");
|
||||
$routes->get("search", "EmployeeController::search");
|
||||
$routes->get("upload", "EmployeeController::employeesUplodWithEvents");
|
||||
$routes->post("upload", "EmployeeController::employeesUplodWithEvents");
|
||||
@ -511,6 +512,7 @@ $routes->group("/util", ["filter" => "authMVC"], function ($routes) {
|
||||
$routes->get('debug', 'ClaimReportDashboardController::debug');
|
||||
$routes->get('debug/(:num)', 'ClaimReportDashboardController::debug/$1');
|
||||
$routes->get('sync', 'ClaimReportDashboardController::sync');
|
||||
$routes->get('download-excel', 'ClaimReportDashboardController::downloadExcel');
|
||||
});
|
||||
|
||||
$routes->group('enrollment-collection-v1', static function ($routes) {
|
||||
@ -531,11 +533,12 @@ $routes->cli('cli/croneDailyActivityReport', 'DashboardController::croneDailyAct
|
||||
|
||||
// Employee dependent APIs (no JWT / App-Signature; util uses authMVC only)
|
||||
$routes->get('relationshipList', 'EmployeeRestController::relationshipList');
|
||||
$routes->get('getEmployeeAndDependence', 'EmployeeRestController::getEmployeeAndDependence');
|
||||
$routes->post('editEmployeeAndDependence', 'EmployeeRestController::editEmployeeAndDependence');
|
||||
$routes->post('addEmployeeAndDependencev2', 'EmployeeRestController::addEmployeeAndDependencev2');
|
||||
$routes->get('getEmployeeByPolicyv2', 'EmployeeRestController::getEmployeeByPolicyv2');
|
||||
$routes->get('deleteDependence', 'EmployeeRestController::deleteDependence');
|
||||
$routes->get('getEmployeeAndDependenceByClientId', 'EmployeeRestController::getEmployeeAndDependenceByClientId');
|
||||
$routes->get('getPendingApprovalDependents', 'EmployeeRestController::getPendingApprovalDependents');
|
||||
$routes->post('processDependentAdd', 'EmployeeRestController::processDependentAdd');
|
||||
|
||||
|
||||
|
||||
@ -764,26 +767,29 @@ $routes->group("employeeRest", ["filter" => ['GlobalPostFileUploadGuard', 'ratel
|
||||
|
||||
$routes->post("ecardRequest", "ApiServiceController::ecardRequest");
|
||||
$routes->get("getWellnessURL", "ApiServiceController::getWellnessURL");
|
||||
|
||||
|
||||
$routes->post("logHrActivity", "RestAuthenticationController::logHrActivity");
|
||||
// $routes->post("getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData");
|
||||
|
||||
|
||||
$routes->post("getChatResponse", "ChatBotController::getChatResponse");
|
||||
|
||||
|
||||
$routes->post("storeFireBase", "EmployeeRestController::storeFireBase");
|
||||
$routes->get("getEmployeeProfile", "EmployeeRestController::getEmployeeProfile");
|
||||
$routes->post("employeeUpload", "EmployeeRestController::employeeUpload");
|
||||
$routes->get("relationshipList", "EmployeeRestController::relationshipList");
|
||||
$routes->get("getEmployeeAndDependence", "EmployeeRestController::getEmployeeAndDependence");
|
||||
$routes->post("editEmployeeAndDependence", "EmployeeRestController::editEmployeeAndDependence");
|
||||
$routes->post("addEmployeeAndDependence", "EmployeeRestController::addEmployeeAndDependence");
|
||||
$routes->get("getEmployeePolicy", "EmployeeRestController::getEmployeePolicy");
|
||||
$routes->post("createOrUpdateEmployeePolicySiAmount", "EmployeeRestController::createOrUpdateEmployeePolicySiAmount");
|
||||
$routes->get("deleteDependence", "EmployeeRestController::deleteDependence");
|
||||
$routes->get("getEmployeeAndDependenceByClientId", "EmployeeRestController::getEmployeeAndDependenceByClientId");
|
||||
|
||||
// $routes->post("addEmployeeAndDependence", "EmployeeRestController::addEmployeeAndDependence");
|
||||
// $routes->get("deleteDependence", "EmployeeRestController::deleteDependence");
|
||||
// $routes->get("getEmployeePolicy", "EmployeeRestController::getEmployeePolicy");
|
||||
|
||||
$routes->get("getEmployeePolicy", "EmployeeRestController::getEmployeePolicyv2");
|
||||
$routes->post("addEmployeeAndDependence", "EmployeeRestController::addEmployeeAndDependencev2");
|
||||
$routes->get("deleteDependence", "EmployeeRestController::deleteDependencev2");
|
||||
$routes->get("getPendingApprovalDependents", "EmployeeRestController::getPendingApprovalDependents");
|
||||
$routes->post('processDependentAdd', 'EmployeeRestController::processDependentAdd');
|
||||
|
||||
$routes->get("getClientPolicy", "EmployeeRestController::getClientPolicy");
|
||||
$routes->get("getClientRM", "EmployeeRestController::getClientRM");
|
||||
$routes->get("getAddOnPolicy", "EmployeeRestController::getAddOnPolicy");
|
||||
@ -876,6 +882,7 @@ $routes->group("employeeRest", ["filter" => ['GlobalPostFileUploadGuard', 'ratel
|
||||
$routes->get('all', 'ClaimReportDashboardController::all');
|
||||
$routes->get('debug', 'ClaimReportDashboardController::debug');
|
||||
$routes->get('debug/(:num)', 'ClaimReportDashboardController::debug/$1');
|
||||
$routes->get('download-excel', 'ClaimReportDashboardController::downloadExcel');
|
||||
});
|
||||
|
||||
$routes->group('enrollment-collection-v1', static function ($routes) {
|
||||
|
||||
@ -6,6 +6,9 @@ use App\Models\ClaimReportDashboardModel;
|
||||
use App\Models\ClaimsCollectionV2DashboardModel;
|
||||
use App\Models\ClaimDumpFileModel;
|
||||
use CodeIgniter\API\ResponseTrait;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
|
||||
/**
|
||||
* Claims Collection dashboard API using claim_report.
|
||||
@ -554,4 +557,199 @@ class ClaimReportDashboardController extends BaseController
|
||||
->setBody($body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download Excel of TPA dump rows linked from claim_report for a policy.
|
||||
*
|
||||
* Query: client_policy_id (or client_policy) — required.
|
||||
* Uses claim_report.source_table + source_row_id to load dump rows.
|
||||
* Excel columns = only fields AFTER master_reject_reason (that column and earlier are excluded).
|
||||
*
|
||||
* GET /util/claims-collection-report/download-excel?client_policy_id=123
|
||||
*/
|
||||
public function downloadExcel()
|
||||
{
|
||||
@set_time_limit(0);
|
||||
@ini_set('max_execution_time', '0');
|
||||
|
||||
$policyId = $this->resolvePolicyId();
|
||||
if ($policyId <= 0) {
|
||||
return $this->respond([
|
||||
'status' => false,
|
||||
'message' => 'client_policy_id is required.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$db = db_connect();
|
||||
|
||||
if (!$db->tableExists('claim_report')) {
|
||||
return $this->respond([
|
||||
'status' => false,
|
||||
'message' => 'Table claim_report does not exist.',
|
||||
], 500);
|
||||
}
|
||||
|
||||
$allowedDumpTables = [
|
||||
'claims_dump_vidal',
|
||||
'claims_dump_abhi',
|
||||
'claims_dump_medi_assist',
|
||||
'claims_dump_fhpl',
|
||||
'claims_dump_reliance',
|
||||
'claims_dump_icici',
|
||||
];
|
||||
|
||||
$reportRows = $db->table('claim_report')
|
||||
->select('source_table, source_row_id')
|
||||
->where('client_policy_id', $policyId)
|
||||
->where('is_active', 1)
|
||||
->where('source_table IS NOT NULL', null, false)
|
||||
->where('source_row_id IS NOT NULL', null, false)
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($reportRows === []) {
|
||||
return $this->respond([
|
||||
'status' => false,
|
||||
'message' => 'No claim_report records with dump linkage found for this policy.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
// Group dump IDs by source_table
|
||||
$idsByTable = [];
|
||||
foreach ($reportRows as $row) {
|
||||
$table = trim((string) ($row['source_table'] ?? ''));
|
||||
$dumpId = (int) ($row['source_row_id'] ?? 0);
|
||||
if ($table === '' || $dumpId <= 0 || ! in_array($table, $allowedDumpTables, true)) {
|
||||
continue;
|
||||
}
|
||||
if (!$db->tableExists($table)) {
|
||||
continue;
|
||||
}
|
||||
$idsByTable[$table][$dumpId] = $dumpId;
|
||||
}
|
||||
|
||||
if ($idsByTable === []) {
|
||||
return $this->respond([
|
||||
'status' => false,
|
||||
'message' => 'No valid TPA dump table references found for this policy.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$spreadsheet->removeSheetByIndex(0);
|
||||
$sheetIndex = 0;
|
||||
$totalRows = 0;
|
||||
|
||||
foreach ($idsByTable as $dumpTable => $dumpIds) {
|
||||
$dumpIds = array_values($dumpIds);
|
||||
$exportColumns = $this->getDumpColumnsAfterMasterReject($db, $dumpTable);
|
||||
if ($exportColumns === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dumpRows = $db->table($dumpTable)
|
||||
->whereIn('id', $dumpIds)
|
||||
->orderBy('id', 'ASC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
if ($dumpRows === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheetTitle = substr($dumpTable, 0, 31);
|
||||
$sheet = $spreadsheet->createSheet($sheetIndex);
|
||||
$sheet->setTitle($sheetTitle);
|
||||
$sheetIndex++;
|
||||
|
||||
// Headers
|
||||
foreach ($exportColumns as $colIdx => $colName) {
|
||||
$sheet->setCellValue(
|
||||
Coordinate::stringFromColumnIndex($colIdx + 1) . '1',
|
||||
$colName
|
||||
);
|
||||
}
|
||||
|
||||
// Data
|
||||
$excelRow = 2;
|
||||
foreach ($dumpRows as $dumpRow) {
|
||||
foreach ($exportColumns as $colIdx => $colName) {
|
||||
$sheet->setCellValue(
|
||||
Coordinate::stringFromColumnIndex($colIdx + 1) . $excelRow,
|
||||
$dumpRow[$colName] ?? null
|
||||
);
|
||||
}
|
||||
$excelRow++;
|
||||
$totalRows++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($sheetIndex === 0 || $totalRows === 0) {
|
||||
return $this->respond([
|
||||
'status' => false,
|
||||
'message' => 'No dump table rows found for the linked claim_report records.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$spreadsheet->setActiveSheetIndex(0);
|
||||
|
||||
$policy = $db->table('client_policy')
|
||||
->select('policy_no')
|
||||
->where('id', $policyId)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
$policyNo = trim((string) ($policy['policy_no'] ?? ''));
|
||||
if ($policyNo === '') {
|
||||
$policyNo = (string) $policyId;
|
||||
}
|
||||
// Safe filename segment
|
||||
$policyNoSafe = preg_replace('/[^A-Za-z0-9_\-]+/', '_', $policyNo) ?: (string) $policyId;
|
||||
|
||||
$filename = 'claim_report_' . $policyNoSafe . '_' . date('Ymd_His') . '.xlsx';
|
||||
|
||||
ob_start();
|
||||
(new Xlsx($spreadsheet))->save('php://output');
|
||||
$excelOutput = ob_get_clean();
|
||||
|
||||
return $this->response
|
||||
->setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||
->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
|
||||
->setHeader('Cache-Control', 'max-age=0')
|
||||
->setBody($excelOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return dump-table column names that appear AFTER master_reject_reason
|
||||
* (master_reject_reason itself and all earlier columns are excluded).
|
||||
*
|
||||
* @return list<string>
|
||||
*/
|
||||
protected function getDumpColumnsAfterMasterReject($db, string $table): array
|
||||
{
|
||||
$fields = $db->getFieldNames($table);
|
||||
if ($fields === [] || $fields === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$marker = null;
|
||||
foreach ($fields as $idx => $name) {
|
||||
$lower = strtolower((string) $name);
|
||||
if (
|
||||
$lower === 'master_reject_reason'
|
||||
|| $lower === 'master_rejected_reason'
|
||||
|| $lower === 'master_rejection_reason'
|
||||
) {
|
||||
$marker = $idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Marker not found — export nothing rather than leaking internal columns
|
||||
if ($marker === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_values(array_slice($fields, $marker + 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -164,6 +164,39 @@ class EmployeeController extends AdminController
|
||||
$this->loadLayout('employee_list', $data);
|
||||
}
|
||||
|
||||
public function pendingApprovalsList()
|
||||
{
|
||||
$data = [];
|
||||
$filterData = $this->request->getGet() ?: [];
|
||||
|
||||
$data['employees'] = $this->employeePolicyModel->getPendingApprovalDependents(
|
||||
client_id: $filterData['client_id'] ?? null,
|
||||
policy_id: $filterData['policy_id'] ?? null,
|
||||
branch_id: $filterData['branch_id'] ?? null,
|
||||
);
|
||||
$data['getData'] = [
|
||||
'client_id' => $filterData['client_id'] ?? '0',
|
||||
'policy_id' => $filterData['policy_id'] ?? '0',
|
||||
'branch_id' => $filterData['branch_id'] ?? '0',
|
||||
'emp_code' => '',
|
||||
'emp_name' => '',
|
||||
'status' => ['pending_approval'],
|
||||
];
|
||||
|
||||
// AJAX filter submit → return table HTML only
|
||||
if (count($this->request->getGet())) {
|
||||
$html = view('employee_data_list', $data);
|
||||
return $this->respond(['status' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
// Default page load → list all pending dependents
|
||||
$data['tab_name'] = 'Pending Approvals';
|
||||
$data['page_name'] = 'Pending Approvals';
|
||||
$data['default_table_html'] = view('employee_data_list', $data);
|
||||
|
||||
$this->loadLayout('employee_pending_approvals_list', $data);
|
||||
}
|
||||
|
||||
public function getClientWithPolicies()
|
||||
{
|
||||
try {
|
||||
|
||||
@ -327,12 +327,26 @@ class EmployeeRestController extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
public function createEmployeePolicyData($employee_id, $emp_code, $client_id, $client_policy_id, $basic_cover_si = null, $payable_employee = 0)
|
||||
public function createEmployeePolicyData($employee_id, $emp_code, $client_id, $client_policy_id, $basic_cover_si = null, $payable_employee = 0, $extra_data = [])
|
||||
{
|
||||
|
||||
$client_policy = $this->clientPolicyModel->where('id', $client_policy_id)->where('client_id', $client_id)->first();
|
||||
$policy_terms = json_decode($client_policy['policy_terms']);
|
||||
$dependent_effective_date = $extra_data['dependent_effective_date'] ?? null;
|
||||
$hr_id = $extra_data['hr_id'] ?? null;
|
||||
|
||||
$self_data = $this->employeeModel
|
||||
->select('employees.id')
|
||||
->join('employee_polices', 'employee_polices.employee_id = employees.id')
|
||||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||||
->where('employees.emp_code', $emp_code)
|
||||
->where('employees.client_id', $client_id)
|
||||
->where('employees.relationship', 'self')
|
||||
->where('employees.is_active', 1)
|
||||
->where('employee_polices.is_active', 1)
|
||||
->first();
|
||||
|
||||
if ($basic_cover_si == null) {
|
||||
$client_policy = $this->clientPolicyModel->where('id', $client_policy_id)->where('client_id', $client_id)->first();
|
||||
$policy_terms = json_decode($client_policy['policy_terms']);
|
||||
$basic_cover_si = $policy_terms->sum_insured;
|
||||
}
|
||||
|
||||
@ -344,7 +358,7 @@ class EmployeeRestController extends AdminController
|
||||
->where('client_policy_id', $client_policy_id)
|
||||
->where('employee_id', $employee_id)
|
||||
->where('is_active', 1)
|
||||
->set(['basic_cover_si' => $basic_cover_si])
|
||||
->set(['basic_cover_si' => $basic_cover_si, 'updated_by' => $self_data['id'] ?? null])
|
||||
->update();
|
||||
} else {
|
||||
|
||||
@ -352,8 +366,11 @@ class EmployeeRestController extends AdminController
|
||||
$data['client_policy_id'] = $client_policy_id;
|
||||
$data['basic_cover_si'] = $basic_cover_si;
|
||||
$data['payable_employee'] = $payable_employee;
|
||||
$data['status'] = 'draft';
|
||||
$data['date_coverage'] = $this->getEmployeeCoverageDate($emp_code, $client_policy_id);
|
||||
$data['policy_end_date'] = $client_policy['policy_end_date'];
|
||||
$data['date_coverage'] = $this->convertDateFormatYMD($dependent_effective_date);
|
||||
$data['status'] = 'pending_approval';
|
||||
$data['created_by'] = $hr_id ?? $self_data['id'] ?? null;
|
||||
$data['emp_policy_created_by'] = $hr_id ? "HR" : 'USER';
|
||||
|
||||
$this->employeePolicyModel->insert($data);
|
||||
}
|
||||
@ -2394,21 +2411,21 @@ class EmployeeRestController extends AdminController
|
||||
$slab_details = $this->policesModel->getPolicySlabRatesForEmpOnboard($client_policy_id, $client_id);
|
||||
// print_r($slab_details);die();
|
||||
|
||||
$existing_famility_details = $this->employeeModel->getEmpFamilybyEmpCode(client_id: $client_id, client_policy_id: $client_policy_id, emp_code: $emp_code, emp_status: ['draft', 'enrolled'], policy_status: ['draft', 'enrolled']);
|
||||
$existing_famility_details = $this->employeeModel->getEmpFamilybyEmpCode(client_id: $client_id, client_policy_id: $client_policy_id, emp_code: $emp_code, emp_status: ['draft', 'enrolled', 'pending_approval'], policy_status: ['draft', 'enrolled', 'pending_approval']);
|
||||
|
||||
if (! count($existing_famility_details) && $policy_type == 2) //top up addon only
|
||||
{
|
||||
//get basepolicy id then pull emplist from base policy if only current policy is DA addon policy and emplist is zero
|
||||
// echo 'inside';
|
||||
$client_policy_id = $base_policy;
|
||||
$existing_famility_details = $this->employeeModel->getEmpFamilybyEmpCode(client_id: $client_id, client_policy_id: $client_policy_id, emp_code: $emp_code, emp_status: ['draft', 'enrolled'], policy_status: ['draft', 'enrolled']);
|
||||
$existing_famility_details = $this->employeeModel->getEmpFamilybyEmpCode(client_id: $client_id, client_policy_id: $client_policy_id, emp_code: $emp_code, emp_status: ['draft', 'enrolled', 'pending_approval'], policy_status: ['draft', 'enrolled', 'pending_approval']);
|
||||
}
|
||||
|
||||
$file = ['id' => null, 'client_id' => $client_id, 'policy_id' => $client_policy_id, 'action' => 'inception'];
|
||||
// dd($this->employeeModel->getLastQuery());
|
||||
// print_r($existing_famility_details);die();
|
||||
$employee_data_group_by_family = data_group_by_family($existing_famility_details, $data_source = 'db');
|
||||
// print_r(($employee_data_group_by_family));//die();
|
||||
// print_r(($employee_data_group_by_family)); die();
|
||||
|
||||
$existing_units = $this->clientBranchModel->getExisitingUnits(client_id: $client_id, client_branch_id: $client_branch_id);
|
||||
|
||||
@ -6331,4 +6348,529 @@ class EmployeeRestController extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Employee Dependent Add API Endpoints
|
||||
//---------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
public function addEmployeeAndDependencev2()
|
||||
{
|
||||
try {
|
||||
|
||||
$data = $this->request->getJSON();
|
||||
// print_r($data);die;
|
||||
|
||||
if ($data) {
|
||||
|
||||
$Count = 0;
|
||||
foreach ($data as $item) {
|
||||
|
||||
$self_data = $this->employeeModel
|
||||
->select('employees.id')
|
||||
->join('employee_polices', 'employee_polices.employee_id = employees.id')
|
||||
->where('employee_polices.client_policy_id', $item->client_policy_id)
|
||||
->where('employees.emp_code', $item->emp_code)
|
||||
->where('employees.client_id', $item->client_id)
|
||||
->where('employees.relationship', 'self')
|
||||
->where('employees.is_active', 1)
|
||||
->where('employee_polices.is_active', 1)
|
||||
->first();
|
||||
|
||||
$item->family_floater_key = $this->RelationshipMap($item->relationship);
|
||||
$item->gender = $this->GenderMap($item->relationship, $item->emp_code);
|
||||
$item->dob = $this->convertDateFormatYMD($item->dob);
|
||||
$item->emp_status = 'pending_approval';
|
||||
$item->emp_created_by = isset($item->hr_id) ? 'HR' : 'USER';
|
||||
|
||||
if (isset($item->id)) {
|
||||
|
||||
//update old data
|
||||
$id = $item->id;
|
||||
$item->updated_by = $item->hr_id ?? $self_data['id'];
|
||||
$employee = $this->employeeModel->where('is_active', 1)->update($id, (array) $item);
|
||||
if ($employee) {
|
||||
$Count++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//create new data
|
||||
$item->created_by = $item->hr_id ?? $self_data['id'];
|
||||
$employee = $this->employeeModel->insert($item);
|
||||
|
||||
if ($employee) {
|
||||
$Count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($Count > 0) {
|
||||
|
||||
if (isset($data[0]->id)) {
|
||||
$this->createEmployeePolicyData($data[0]->id, $data[0]->emp_code, $data[0]->client_id, $data[0]->client_policy_id, $data[0]->basic_cover_si);
|
||||
} else {
|
||||
$payable_employee = $this->getEmployeePayableValue($data[0]->client_policy_id, $data[0]->relationship);
|
||||
$this->createEmployeePolicyData($employee, $data[0]->emp_code, $data[0]->client_id, $data[0]->client_policy_id, $data[0]->basic_cover_si, $payable_employee, ['dependent_effective_date' => $data[0]->dependent_effective_date, 'hr_id' => $data[0]->hr_id ?? null]);
|
||||
}
|
||||
|
||||
$this->updatePremiumAmount($data[0]->client_policy_id, $data[0]->emp_code, $data[0]->client_branch_id);
|
||||
|
||||
$result = [];
|
||||
return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200);
|
||||
} else {
|
||||
$result = "No Matches";
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
|
||||
}
|
||||
}else{
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => "Requested parameters are required"], 200);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteDependencev2()
|
||||
{
|
||||
try {
|
||||
|
||||
if ($this->request->getGet('id')) {
|
||||
|
||||
$this->employeeModel->where('id', $this->request->getGet('id'))
|
||||
->where('is_active', 1)
|
||||
->set(['emp_status' => 'truncated', 'is_active' => 0])
|
||||
->update();
|
||||
|
||||
$this->employeePolicyModel->where('employee_id', $this->request->getGet('id'))
|
||||
->where('is_active', 1)
|
||||
->set(['status' => 'truncated', 'is_active' => 0])
|
||||
->update();
|
||||
|
||||
return $this->respond(['status' => 'success', 'code' => 200, 'data' => []], 200);
|
||||
} else {
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function getEmployeeByPolicyv2()
|
||||
{
|
||||
try {
|
||||
|
||||
$id = $this->request->getGet('id') ?? $this->request->getPost('id');
|
||||
$emp_code = $this->request->getGet('emp_code') ?? $this->request->getPost('emp_code');
|
||||
$client_id = $this->request->getGet('client_id') ?? $this->request->getPost('client_id');
|
||||
$client_branch_id = $this->request->getGet('client_branch_id') ?? $this->request->getPost('client_branch_id');
|
||||
$client_policy_id = $this->request->getGet('client_policy_id') ?? $this->request->getPost('client_policy_id');
|
||||
|
||||
if (empty($id) || empty($emp_code) || empty($client_id) || empty($client_branch_id) || empty($client_policy_id)) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Required parameters missing: id, emp_code, client_id, client_branch_id and client_policy_id are required', 'data' => []], 200);
|
||||
}
|
||||
|
||||
$keysToRemove = ["removable_keys"];
|
||||
|
||||
// Filtered by client_policy_id — returns at most one GMC policy
|
||||
$empPolicyList = $this->employeeModel->getEmployeePolicy($id, $client_policy_id);
|
||||
$array = $empPolicyList[0] ?? null;
|
||||
|
||||
if (!$array) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'message' => 'Employee policy not found for the given employee and client policy', 'data' => []], 200);
|
||||
}
|
||||
|
||||
// GMC only (policy_type_id = 2)
|
||||
if ((int) $array->policy_type_id !== 2) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Only GMC policy is supported for dependent add', 'data' => []], 200);
|
||||
}
|
||||
|
||||
$empData = $this->employeeModel
|
||||
->where('emp_code', $emp_code)
|
||||
->where('client_id', $client_id)
|
||||
->where('client_branch_id', $client_branch_id)
|
||||
->where('is_active', 1)
|
||||
->where('is_addon_value', 0)
|
||||
->groupStart()
|
||||
->whereIn('family_floater_key', ['self', 'spouse', 'child'])
|
||||
->orWhereIn('relationship', ['Self', 'Spouse', 'Son', 'Daughter'])
|
||||
->groupEnd()
|
||||
->findAll();
|
||||
|
||||
$decodedArray = json_decode($array->Policy_Terms);
|
||||
$refusingData = (object) array_diff_key((array) $decodedArray, array_flip($keysToRemove));
|
||||
$array->Policy_Terms = $refusingData;
|
||||
|
||||
$getSlabAndGridData = $this->policesModel->getPolicySlabRatesForEmpOnboard($array->ClientPolicyId, $array->ClientId);
|
||||
$array->SlabRates = $getSlabAndGridData['slab_rates'];
|
||||
$array->GridMaster = $getSlabAndGridData['grid_master'];
|
||||
|
||||
$array->eCardDownload = $array->tpa_id != null
|
||||
? base_url('download-e-card/') . $array->rand_string . '/1'
|
||||
: null;
|
||||
|
||||
$familyFloates = $array->Policy_Terms->family_floaters ?? (object) [];
|
||||
|
||||
// Only spouse + children (ignore parents / parents-in-law)
|
||||
$hasSpouse = isset($familyFloates->spouse) && (int) $familyFloates->spouse > 0;
|
||||
$hasChildren = isset($familyFloates->childrens) && (int) $familyFloates->childrens > 0;
|
||||
$spouseCount = $hasSpouse ? (int) $familyFloates->spouse : 0;
|
||||
$childrenCount = $hasChildren ? (int) $familyFloates->childrens : 0;
|
||||
|
||||
$spouseChildrenTerms = (object) [
|
||||
'self' => isset($familyFloates->self) ? (int) $familyFloates->self : 1,
|
||||
'spouse' => $spouseCount,
|
||||
'childrens' => $childrenCount,
|
||||
];
|
||||
|
||||
$array->notes = $this->FloterNotesConvertion($spouseChildrenTerms);
|
||||
|
||||
$allowedRelationships = [];
|
||||
if ($hasSpouse) {
|
||||
$allowedRelationships[] = 'Spouse';
|
||||
}
|
||||
if ($hasChildren) {
|
||||
$allowedRelationships[] = 'Son';
|
||||
$allowedRelationships[] = 'Daughter';
|
||||
}
|
||||
$array->allowed_relationships = $allowedRelationships;
|
||||
|
||||
if (!empty($getSlabAndGridData['slab_rates'][0]) && ($getSlabAndGridData['slab_rates'][0]['premium_type'] == 1 || $getSlabAndGridData['slab_rates'][0]['premium_type'] == 3)) {
|
||||
$array->floter_text_heading = 'Floater Sum Insured';
|
||||
$array->floter_text_description = 'This is a floater sum insured. A floater is a type of sum insured that provides coverage to more than one member ot a family at the same time. Simply put, its a single insurance cover for the entire family.';
|
||||
} else {
|
||||
$array->floter_text_heading = 'Sum Insured';
|
||||
$array->floter_text_description = '';
|
||||
}
|
||||
|
||||
$floters = $this->FloterConvertion($spouseChildrenTerms);
|
||||
|
||||
$data = [];
|
||||
$dependent_and_si_value = 0;
|
||||
$dependent_and_si_premium_value = 0;
|
||||
$dependent_and_si_gst_value = 0;
|
||||
|
||||
foreach ($floters as $familyFloatesValue) {
|
||||
$dependent = preg_replace('/\d/', '', $familyFloatesValue);
|
||||
|
||||
if (!in_array($dependent, ['self', 'spouse', 'child'], true)) {
|
||||
continue;
|
||||
}
|
||||
if ($dependent === 'spouse' && !$hasSpouse) {
|
||||
continue;
|
||||
}
|
||||
if ($dependent === 'child' && !$hasChildren) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count($empData)) {
|
||||
foreach ($empData as $key => $value) {
|
||||
$empFloaterKey = !empty($value['family_floater_key'])
|
||||
? preg_replace('/\d/', '', strtolower(trim($value['family_floater_key'])))
|
||||
: $this->RelationshipMap($value['relationship']);
|
||||
|
||||
$relationship = strtolower(trim($value['relationship'] ?? ''));
|
||||
$matches = ($empFloaterKey === $dependent)
|
||||
|| ($dependent === 'spouse' && $relationship === 'spouse')
|
||||
|| ($dependent === 'child' && in_array($relationship, ['son', 'daughter'], true))
|
||||
|| ($dependent === 'self' && $relationship === 'self');
|
||||
|
||||
if ($matches) {
|
||||
$employee_policy = $this->employeePolicyModel
|
||||
->where('employee_id', $value['id'])
|
||||
->where('client_policy_id', $array->ClientPolicyId)
|
||||
->where('is_active', 1)
|
||||
->get()
|
||||
->getRow();
|
||||
|
||||
if (isset($employee_policy->basic_cover_si)) {
|
||||
$dependent_and_si_value = ($dependent_and_si_value == 0) ? $employee_policy->basic_cover_si : $dependent_and_si_value;
|
||||
}
|
||||
if (isset($employee_policy->payable_employee) && $employee_policy->payable_employee == 1) {
|
||||
if (isset($employee_policy->rata_premimum)) {
|
||||
$dependent_and_si_premium_value = $dependent_and_si_premium_value + $employee_policy->rata_premimum;
|
||||
}
|
||||
if (isset($employee_policy->gst)) {
|
||||
$dependent_and_si_gst_value = $dependent_and_si_gst_value + $employee_policy->gst;
|
||||
}
|
||||
}
|
||||
|
||||
$temp = [];
|
||||
$temp['is_value_exist'] = true;
|
||||
$temp['data']['family_floater_key'] = $familyFloatesValue;
|
||||
$temp['data']['employee_id'] = $value['id'];
|
||||
$temp['data']['relationship'] = $value['relationship'];
|
||||
$temp['data']['name'] = $value['name'];
|
||||
$temp['data']['dob'] = $this->convertDateFormatDMY($value['dob']);
|
||||
$temp['data']['client_policy_id'] = $array->ClientPolicyId;
|
||||
$temp['data']['form_type'] = $dependent;
|
||||
$temp['data']['basic_cover_si'] = isset($employee_policy->basic_cover_si) ? $employee_policy->basic_cover_si : 0;
|
||||
$temp['data']['age_validation'] = $this->getAgeRange($decodedArray, $familyFloatesValue);
|
||||
|
||||
array_push($data, $temp);
|
||||
unset($empData[$key]);
|
||||
$floters = array_diff($floters, [$familyFloatesValue]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remaining allowed spouse/child slots → Add buttons
|
||||
if (count($floters)) {
|
||||
foreach ($floters as $familyFloatesValue) {
|
||||
$dependent = preg_replace('/\d/', '', $familyFloatesValue);
|
||||
|
||||
if (!in_array($dependent, ['spouse', 'child'], true)) {
|
||||
continue;
|
||||
}
|
||||
if ($dependent === 'spouse' && !$hasSpouse) {
|
||||
continue;
|
||||
}
|
||||
if ($dependent === 'child' && !$hasChildren) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp2 = [];
|
||||
$temp2['is_value_exist'] = false;
|
||||
$temp2['data']['family_floater_key'] = $familyFloatesValue;
|
||||
$temp2['data']['client_policy_id'] = $array->ClientPolicyId;
|
||||
$temp2['data']['button_name'] = 'Add ' . ucfirst(str_replace('_', ' ', $dependent));
|
||||
$temp2['data']['form_type'] = $dependent;
|
||||
$temp2['data']['age_validation'] = $this->getAgeRange($decodedArray, $familyFloatesValue);
|
||||
$temp2['data']['allowed_relationships'] = $dependent === 'spouse'
|
||||
? ['Spouse']
|
||||
: ['Son', 'Daughter'];
|
||||
|
||||
array_push($data, $temp2);
|
||||
}
|
||||
}
|
||||
|
||||
$array->mapped_family_floaters = $data;
|
||||
$array->type = 'GMC';
|
||||
$array->family_floaters_of_dependent_and_si_value = $dependent_and_si_value > 0 ? $dependent_and_si_value : 0;
|
||||
$array->family_floaters_of_dependent_and_si_premium_value = $dependent_and_si_premium_value > 0 ? round($dependent_and_si_premium_value) : 0;
|
||||
$array->family_floaters_of_dependent_and_gst_value = $dependent_and_si_gst_value > 0 ? round($dependent_and_si_gst_value) : 0;
|
||||
|
||||
$employeePolicy = $this->getEmployeePolicyMembersForDependentAdd(
|
||||
$emp_code,
|
||||
$client_id,
|
||||
$client_branch_id,
|
||||
$client_policy_id
|
||||
);
|
||||
|
||||
// Show add button when any spouse/child slot is still available
|
||||
$addButtonShow = false;
|
||||
foreach ($data as $floaterItem) {
|
||||
if (empty($floaterItem['is_value_exist'])) {
|
||||
$addButtonShow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'message' => 'Employee policy and dependent details fetched successfully',
|
||||
'data' => $array,
|
||||
'EmployeePolicy' => $employeePolicy,
|
||||
'add_button_show' => $addButtonShow,
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'message' => 'Something went wrong while fetching employee policy details', 'data' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch Self / Spouse / Children employee+policy rows for a GMC client policy.
|
||||
* Same data shape as EmployeePolicy in getEmployeeActiveOrInactivePolicy.
|
||||
*/
|
||||
private function getEmployeePolicyMembersForDependentAdd($emp_code, $client_id, $client_branch_id, $client_policy_id)
|
||||
{
|
||||
$employeeIds = $this->employeeModel
|
||||
->select('id')
|
||||
->where('emp_code', $emp_code)
|
||||
->where('client_id', $client_id)
|
||||
->where('client_branch_id', $client_branch_id)
|
||||
->where('is_active', 1)
|
||||
->where('is_addon_value', 0)
|
||||
->groupStart()
|
||||
->whereIn('family_floater_key', ['self', 'spouse', 'child'])
|
||||
->orWhereIn('relationship', ['Self', 'Spouse', 'Son', 'Daughter'])
|
||||
->groupEnd()
|
||||
->findColumn('id');
|
||||
|
||||
if (empty($employeeIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->employeePolicyModel
|
||||
->select('employees.*, employee_polices.employee_id, employee_polices.basic_cover_si, employee_polices.premium, employee_polices.gst, employee_polices.tpa_id, employee_polices.rand_string, employee_polices.uhid as uhid')
|
||||
->join('employees', 'employee_polices.employee_id = employees.id', 'left')
|
||||
->whereIn('employee_polices.employee_id', $employeeIds)
|
||||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||||
->where('employee_polices.is_active', 1)
|
||||
->findAll();
|
||||
}
|
||||
|
||||
public function processDependentAdd()
|
||||
{
|
||||
try {
|
||||
$data = $this->request->getJSON(true);
|
||||
|
||||
if (empty($data)) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Request body is required'], 200);
|
||||
}
|
||||
|
||||
$employee_id = $data['employee_id'] ?? null;
|
||||
$client_policy_id = $data['client_policy_id'] ?? null;
|
||||
$hr_id = $data['hr_id'] ?? null;
|
||||
$status = $data['status'] ?? "approved";
|
||||
$updated_by = $hr_id ?? get_session_userid() ?? null;
|
||||
// Approver role: HR (app) or ACM (internal portal session user)
|
||||
$approved_by_role = ! empty($hr_id) ? 'HR' : 'ACM';
|
||||
|
||||
if (empty($employee_id)) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'employee_id is required'], 200);
|
||||
}
|
||||
|
||||
if (empty($client_policy_id)) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'client_policy_id is required'], 200);
|
||||
}
|
||||
|
||||
if (empty($status)) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'status is required'], 200);
|
||||
}
|
||||
|
||||
if ($status !== 'approved' && $status !== 'rejected') {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'status is invalid'], 200);
|
||||
}
|
||||
|
||||
$employee = $this->employeeModel
|
||||
->where('id', $employee_id)
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
if (!$employee) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'Employee not found or inactive'], 200);
|
||||
}
|
||||
|
||||
if (($employee['emp_status'] ?? null) === 'active') {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Dependent is already approved'], 200);
|
||||
}
|
||||
|
||||
if (($employee['emp_status'] ?? null) !== 'pending_approval') {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Dependent is not pending approval'], 200);
|
||||
}
|
||||
|
||||
$employee_policy = $this->employeePolicyModel
|
||||
->where('employee_id', $employee_id)
|
||||
->where('client_policy_id', $client_policy_id)
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
if (!$employee_policy) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'Employee policy not found or inactive'], 200);
|
||||
}
|
||||
|
||||
if ($status === 'approved') {
|
||||
$employee_update_data = [
|
||||
'updated_by' => $updated_by,
|
||||
'approved_by' => $approved_by_role,
|
||||
'emp_status' => 'active',
|
||||
];
|
||||
$policy_update_data = [
|
||||
'updated_by' => $updated_by,
|
||||
'approved_by' => $approved_by_role,
|
||||
'status' => 'active',
|
||||
];
|
||||
} else {
|
||||
$employee_update_data = [
|
||||
'updated_by' => $updated_by,
|
||||
'approved_by' => $approved_by_role,
|
||||
'emp_status' => 'rejected',
|
||||
'is_active' => 0,
|
||||
];
|
||||
$policy_update_data = [
|
||||
'updated_by' => $updated_by,
|
||||
'approved_by' => $approved_by_role,
|
||||
'status' => 'rejected',
|
||||
'is_active' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$employee_updated = $this->employeeModel
|
||||
->where('id', $employee_id)
|
||||
->where('is_active', 1)
|
||||
->set($employee_update_data)
|
||||
->update();
|
||||
|
||||
if (!$employee_updated) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => 'Failed to update employee status'], 200);
|
||||
}
|
||||
|
||||
$policy_updated = $this->employeePolicyModel
|
||||
->where('employee_id', $employee_id)
|
||||
->where('client_policy_id', $client_policy_id)
|
||||
->where('is_active', 1)
|
||||
->set($policy_update_data)
|
||||
->update();
|
||||
|
||||
if (!$policy_updated) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => 'Failed to update employee policy status'], 200);
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 'success', 'code' => 200, 'data' => []], 200);
|
||||
} catch (\Exception $e) {
|
||||
log_message('error', 'Error in processDependentAdd: ' . $e->getMessage() . ' in ' . $e->getFile() . ' on line ' . $e->getLine());
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List pending_approval dependents (API + mobile).
|
||||
* Filters: client_id, client_branch_id / branch_id, client_policy_id / policy_id, optional search.
|
||||
*/
|
||||
public function getPendingApprovalDependents()
|
||||
{
|
||||
try {
|
||||
$client_id = $this->request->getGet('client_id');
|
||||
$branch_id = $this->request->getGet('client_branch_id') ?? $this->request->getGet('branch_id');
|
||||
$policy_id = $this->request->getGet('client_policy_id') ?? $this->request->getGet('policy_id');
|
||||
$search = trim((string) ($this->request->getGet('search') ?? ''));
|
||||
|
||||
$empData = $this->employeePolicyModel->getPendingApprovalDependents(
|
||||
client_id: $client_id ?? 0,
|
||||
policy_id: $policy_id ?? 0,
|
||||
branch_id: $branch_id ?? 0,
|
||||
search: $search
|
||||
);
|
||||
|
||||
if ($empData) {
|
||||
return $this->respond([
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'message' => 'Pending approval dependents fetched successfully',
|
||||
'data' => $empData,
|
||||
], 200);
|
||||
}
|
||||
|
||||
return $this->respond([
|
||||
'status' => 'failed',
|
||||
'code' => 404,
|
||||
'message' => 'No pending approval dependents found',
|
||||
'data' => [],
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
return $this->respond([
|
||||
'status' => 'failed',
|
||||
'code' => 500,
|
||||
'message' => $e->getMessage(),
|
||||
'data' => [],
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddDependentApprovalTrackingColumns extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
// employees: who created the dependent request, who approved (HR / ACM)
|
||||
if (! $this->db->fieldExists('emp_created_by', 'employees')) {
|
||||
$this->forge->addColumn('employees', [
|
||||
'emp_created_by' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 50,
|
||||
'null' => true,
|
||||
'default' => null,
|
||||
'after' => 'emp_status',
|
||||
'comment' => 'Creator role: HR / USER',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
if (! $this->db->fieldExists('approved_by', 'employees')) {
|
||||
$this->forge->addColumn('employees', [
|
||||
'approved_by' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 50,
|
||||
'null' => true,
|
||||
'default' => null,
|
||||
'after' => 'emp_created_by',
|
||||
'comment' => 'Approver role: HR / ACM',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
// employee_polices: who created the policy row, who approved (HR / ACM)
|
||||
if (! $this->db->fieldExists('emp_policy_created_by', 'employee_polices')) {
|
||||
$this->forge->addColumn('employee_polices', [
|
||||
'emp_policy_created_by' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 50,
|
||||
'null' => true,
|
||||
'default' => null,
|
||||
'after' => 'status',
|
||||
'comment' => 'Creator role: HR / USER',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
if (! $this->db->fieldExists('approved_by', 'employee_polices')) {
|
||||
$this->forge->addColumn('employee_polices', [
|
||||
'approved_by' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 50,
|
||||
'null' => true,
|
||||
'default' => null,
|
||||
'after' => 'emp_policy_created_by',
|
||||
'comment' => 'Approver role: HR / ACM',
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
if ($this->db->fieldExists('approved_by', 'employees')) {
|
||||
$this->forge->dropColumn('employees', 'approved_by');
|
||||
}
|
||||
if ($this->db->fieldExists('emp_created_by', 'employees')) {
|
||||
$this->forge->dropColumn('employees', 'emp_created_by');
|
||||
}
|
||||
if ($this->db->fieldExists('approved_by', 'employee_polices')) {
|
||||
$this->forge->dropColumn('employee_polices', 'approved_by');
|
||||
}
|
||||
if ($this->db->fieldExists('emp_policy_created_by', 'employee_polices')) {
|
||||
$this->forge->dropColumn('employee_polices', 'emp_policy_created_by');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -808,7 +808,19 @@ abstract class BaseTpaClaimImportService
|
||||
}
|
||||
|
||||
$ticketMasterModel = new TicketMasterModel();
|
||||
return $ticketMasterModel->updateBatch($payload, 'id') !== false;
|
||||
$ok = $ticketMasterModel->updateBatch($payload, 'id') !== false;
|
||||
if ($ok) {
|
||||
$ids = [];
|
||||
foreach ($payload as $row) {
|
||||
if (!empty($row['id'])) {
|
||||
$ids[] = (int) $row['id'];
|
||||
}
|
||||
}
|
||||
// updateBatch does not fire model afterUpdate callbacks
|
||||
(new \App\Models\ClaimReportModel())->syncFromTicketIds($ids);
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -55,4 +55,148 @@ class ClaimReportModel extends Model
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* Push ticket_master fields into matching claim_report row(s).
|
||||
* Match by ticket_id first; fallback to (client_policy_id, claim_number).
|
||||
* Never creates new claim_report rows — only updates existing ones.
|
||||
* Failures are swallowed so ticket updates are never blocked.
|
||||
*/
|
||||
public function syncFromTicketId(int $ticketId): bool
|
||||
{
|
||||
if ($ticketId <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$this->db->tableExists('claim_report')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$ticket = $this->db->table('ticket_master')
|
||||
->where('id', $ticketId)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if (empty($ticket)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$update = $this->mapTicketToClaimReport($ticket);
|
||||
if ($update === []) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$exists = $this->db->table('claim_report')
|
||||
->where('ticket_id', $ticketId)
|
||||
->countAllResults() > 0;
|
||||
|
||||
if ($exists) {
|
||||
$this->db->table('claim_report')
|
||||
->where('ticket_id', $ticketId)
|
||||
->update($update);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fallback: match by unique key when ticket_id not set on claim_report yet
|
||||
$claimNumber = trim((string) ($ticket['claim_number'] ?? ''));
|
||||
$clientPolicyId = (int) ($ticket['client_policy_id'] ?? 0);
|
||||
if ($claimNumber === '' || $clientPolicyId <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->db->table('claim_report')
|
||||
->where('client_policy_id', $clientPolicyId)
|
||||
->where('claim_number', $claimNumber)
|
||||
->update($update);
|
||||
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'claim_report syncFromTicketId failed for ticket {id}: {msg}', [
|
||||
'id' => $ticketId,
|
||||
'msg' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync multiple ticket IDs (e.g. after updateBatch).
|
||||
*
|
||||
* @param list<int|string> $ticketIds
|
||||
*/
|
||||
public function syncFromTicketIds(array $ticketIds): void
|
||||
{
|
||||
$ids = array_values(array_unique(array_filter(array_map('intval', $ticketIds))));
|
||||
foreach ($ids as $id) {
|
||||
$this->syncFromTicketId($id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $ticket
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function mapTicketToClaimReport(array $ticket): array
|
||||
{
|
||||
$now = date('Y-m-d H:i:s');
|
||||
|
||||
$relation = $ticket['relation'] ?? null;
|
||||
if ($relation === null || $relation === '') {
|
||||
$relation = $ticket['relationship'] ?? null;
|
||||
}
|
||||
|
||||
$approved = $ticket['approved_amount'] ?? null;
|
||||
$claimed = $ticket['claim_amount'] ?? null;
|
||||
$incurred = $ticket['incurred_amount'] ?? null;
|
||||
if ($incurred === null || $incurred === '') {
|
||||
$incurred = $approved !== null && $approved !== '' ? $approved : $claimed;
|
||||
}
|
||||
|
||||
$map = [
|
||||
'tpa_id' => $ticket['tpa_id'] ?? null,
|
||||
'client_id' => $ticket['client_id'] ?? null,
|
||||
'client_policy_id' => $ticket['client_policy_id'] ?? null,
|
||||
'file_id' => $ticket['file_id'] ?? null,
|
||||
'ticket_id' => $ticket['id'] ?? null,
|
||||
'claim_number' => isset($ticket['claim_number']) ? trim((string) $ticket['claim_number']) : null,
|
||||
'emp_code' => $ticket['emp_code'] ?? null,
|
||||
'tpa_no' => $ticket['tpa_no'] ?? null,
|
||||
'emp_id' => $ticket['emp_id'] ?? null,
|
||||
'insured_emp_id' => $ticket['insured_emp_id'] ?? null,
|
||||
'claim_amount' => $claimed,
|
||||
'approved_amount' => $approved,
|
||||
'incurred_amount' => $incurred,
|
||||
'si_amt' => $ticket['si_amt'] ?? null,
|
||||
'tpa_claim_status' => $ticket['tpa_claim_status'] ?? null,
|
||||
'claim_status_id' => $ticket['claim_status_id'] ?? null,
|
||||
'tpa_claim_type' => $ticket['tpa_claim_type'] ?? null,
|
||||
'tpa_ailments' => $ticket['tpa_ailments'] ?? null,
|
||||
'doa' => $ticket['doa'] ?? null,
|
||||
'dod' => $ticket['dod'] ?? null,
|
||||
'date_of_intimat' => $ticket['date_of_intimat'] ?? null,
|
||||
'settled_date' => $ticket['settled_date'] ?? null,
|
||||
'approved_date' => $ticket['approved_date'] ?? null,
|
||||
'claim_dump_date' => $ticket['claim_dump_date'] ?? null,
|
||||
'hospital_name' => $ticket['hospital_name'] ?? null,
|
||||
'hospital_city' => $ticket['hospital_city'] ?? null,
|
||||
'hospital_state' => $ticket['hospital_state'] ?? null,
|
||||
'hospital_pin_code' => $ticket['hospital_pin_code'] ?? null,
|
||||
'hospital_address' => $ticket['hospital_address'] ?? null,
|
||||
'relation' => $relation,
|
||||
'is_active' => isset($ticket['is_active']) ? (int) $ticket['is_active'] : 1,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
// Do not overwrite claim_number with empty string
|
||||
if ($map['claim_number'] === '') {
|
||||
unset($map['claim_number']);
|
||||
}
|
||||
|
||||
// Keep source_table / source_row_id as-is (provenance from dump sync)
|
||||
|
||||
return $map;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,8 @@ class EmployeeModel extends Model
|
||||
"otp",
|
||||
"family_floater_key",
|
||||
"emp_status",
|
||||
"emp_created_by",
|
||||
"approved_by",
|
||||
"created_by",
|
||||
"updated_by",
|
||||
"updated_at",
|
||||
@ -151,7 +153,7 @@ class EmployeeModel extends Model
|
||||
|
||||
|
||||
|
||||
public function getEmployeePolicy($id)
|
||||
public function getEmployeePolicy($id, $client_policy_id = null)
|
||||
{
|
||||
|
||||
return $this->db->table('employee_polices')
|
||||
@ -176,6 +178,9 @@ class EmployeeModel extends Model
|
||||
->where('employee_polices.status !=', 'truncated')
|
||||
->where('employee_polices.is_active', 1)
|
||||
->where('employee_polices.employee_id', $id)
|
||||
->when($client_policy_id, function($query) use ($client_policy_id){
|
||||
return $query->where('employee_polices.client_policy_id', $client_policy_id);
|
||||
})
|
||||
->get()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@ class EmployeePolicyModel extends Model
|
||||
"uhid",
|
||||
"batch_id",
|
||||
"status",
|
||||
"emp_policy_created_by",
|
||||
"approved_by",
|
||||
"pre_existing_alignments",
|
||||
"date_of_exit",
|
||||
"reason_for_exit",
|
||||
@ -375,6 +377,105 @@ class EmployeePolicyModel extends Model
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending-approval dependents (excludes Self) for a client / branch / policy.
|
||||
*/
|
||||
public function getPendingApprovalDependents($client_id = 0, $policy_id = 0, $branch_id = 0, $search = '')
|
||||
{
|
||||
$ecard_download_link = "
|
||||
CASE
|
||||
WHEN
|
||||
LOWER(emp.relationship) = 'self' AND
|
||||
employee_polices.tpa_id IS NOT NULL AND employee_polices.tpa_id != '' AND
|
||||
employee_polices.uhid IS NOT NULL AND employee_polices.uhid != ''
|
||||
THEN
|
||||
CONCAT('" . base_url('download-e-card/') . "', employee_polices.rand_string, '/1')
|
||||
ELSE
|
||||
NULL
|
||||
END AS ecard_download_link
|
||||
";
|
||||
|
||||
$result = $this->select([
|
||||
'employee_polices.*',
|
||||
'policy_type.policy_type as policy_name',
|
||||
'im.short_name as insurer_short_name',
|
||||
'ib.branch_name as insurer_branch_name',
|
||||
'ib.branch_code as insurer_branch_code',
|
||||
'tpam.name as tpa_name',
|
||||
'tpam.short_name as tpa_short_name',
|
||||
'tpab.branch_code as tpa_branch_code',
|
||||
'cm.client_name',
|
||||
'cm.short_name as client_short_name',
|
||||
'emp.relationship',
|
||||
'emp.relationship_code',
|
||||
'emp.change_event',
|
||||
'emp.emp_code',
|
||||
'emp.name',
|
||||
'emp.email_corporate',
|
||||
'emp.dob',
|
||||
'DATE_FORMAT(emp.dob, "%d/%m/%Y") AS formatted_dob',
|
||||
'emp.gender',
|
||||
'emp.emp_status',
|
||||
'emp.is_active as emp_is_active',
|
||||
'emp.mobile as mobile',
|
||||
'emp.doj',
|
||||
'emp.basic_pay',
|
||||
'emp.band as grade',
|
||||
'policy_type.policy_type',
|
||||
'client_branch.branch_name as client_branch_name',
|
||||
'client_branch.branch_code as client_branch_code',
|
||||
'cp.policy_no',
|
||||
'cp.policy_type_id',
|
||||
'cp.is_addon',
|
||||
'(
|
||||
select id from employees
|
||||
where emp_code = emp.emp_code
|
||||
and client_id = emp.client_id
|
||||
and lower(relationship) = "self"
|
||||
and is_active = 1
|
||||
limit 1
|
||||
) as self_employee_id',
|
||||
$ecard_download_link
|
||||
])
|
||||
->join('employees emp', 'employee_polices.employee_id = emp.id')
|
||||
->join('client_policy cp', 'employee_polices.client_policy_id = cp.id')
|
||||
->join('policies pm', 'cp.policy_id = pm.id', 'left')
|
||||
->join('policy_type', 'policy_type.id = cp.policy_type_id')
|
||||
->join('insurers im', 'cp.insurer_id = im.id')
|
||||
->join('insurer_branch ib', 'cp.insurer_branch_id = ib.id')
|
||||
->join('tpa tpam', 'cp.tpa_id = tpam.id', 'left')
|
||||
->join('tpa_branch tpab', 'cp.tpa_branch_id = tpab.id', 'left')
|
||||
->join('clients cm', 'cp.client_id = cm.id')
|
||||
->join('client_branch', 'emp.client_branch_id = client_branch.id')
|
||||
->where('employee_polices.is_active', 1)
|
||||
->where('emp.is_active', 1)
|
||||
->where('employee_polices.status', 'pending_approval')
|
||||
->where('emp.emp_status', 'pending_approval')
|
||||
->where("LOWER(emp.relationship) != 'self'", null, false)
|
||||
->orderBy('emp.emp_code', 'ASC')
|
||||
->orderBy('employee_polices.employee_id', 'ASC');
|
||||
|
||||
if (is_string($client_id) && preg_match('/^[a-f0-9]{32}$/i', $client_id)) {
|
||||
$result->where('md5(emp.client_id)', $client_id);
|
||||
} elseif ($client_id != 0 && ! empty($client_id)) {
|
||||
$result->where('emp.client_id', $client_id);
|
||||
}
|
||||
|
||||
if ($branch_id != 0 && ! empty($branch_id)) {
|
||||
$result->where('emp.client_branch_id', $branch_id);
|
||||
}
|
||||
|
||||
if ($policy_id != 0 && ! empty($policy_id)) {
|
||||
$result->where('employee_polices.client_policy_id', $policy_id);
|
||||
}
|
||||
|
||||
if (! empty($search)) {
|
||||
$this->applyEmployeeGlobalSearch($result, $search);
|
||||
}
|
||||
|
||||
return $result->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Global search across employee + policy fields (OR + LIKE).
|
||||
* Searches: emp_code, name, mobile, email, tpa_id, dob, relationship, status.
|
||||
|
||||
@ -317,6 +317,9 @@ $gst_total = 0;
|
||||
case 'enrolled':
|
||||
echo '<span class="badge2 badge2-secondary2">' . ucfirst($employee['status']) . '</span>';
|
||||
break;
|
||||
case 'pending_approval':
|
||||
echo '<span class="badge badge-info">Pending Approval</span>';
|
||||
break;
|
||||
default:
|
||||
echo $employee['status'];
|
||||
break;
|
||||
|
||||
406
app/Views/employee_pending_approvals_list.php
Normal file
406
app/Views/employee_pending_approvals_list.php
Normal file
@ -0,0 +1,406 @@
|
||||
<style>
|
||||
.table th,
|
||||
.table td {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
table.dataTable tbody td {
|
||||
padding: 4px 4px !important;
|
||||
}
|
||||
|
||||
.select2-selection__choice {
|
||||
background-color: #0a8794 !important;
|
||||
color: white !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.select2-selection__choice__remove {
|
||||
color: white !important;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.custom-dropdown-menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #ffffff !important;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.5rem 0;
|
||||
min-width: 10rem;
|
||||
z-index: 9999;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.custom-dropdown-menu .dropdown-item {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
padding: 0.5rem 1rem !important;
|
||||
color: #212529 !important;
|
||||
text-decoration: none !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.custom-dropdown-menu .dropdown-item:hover {
|
||||
background-color: #f8f9fa !important;
|
||||
color: #16181b !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card-body">
|
||||
<div id="accordion" class="mb-3">
|
||||
<div class="card mb-1">
|
||||
<h4>
|
||||
Filter
|
||||
<a id="toggleIcon" class="text-dark float-right" data-toggle="collapse" href="#collapseOne"
|
||||
aria-expanded="true">
|
||||
<i id="icon" class="mdi mdi-chevron-down mr-1 text-primary" style="font-size: 28px;"></i>
|
||||
</a>
|
||||
</h4>
|
||||
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-4">
|
||||
<label>Client</label> <br />
|
||||
<select class="form-control" id="clients">
|
||||
<option value="0">Select</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-4">
|
||||
<label>Branch</label> <br />
|
||||
<select name="branch_id" class="form-control" id="branch_id">
|
||||
<option value="0">Select</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-md-4">
|
||||
<label>Policy</label> <br />
|
||||
<select class="form-control" id="policies">
|
||||
<option value="0">Select</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-end">
|
||||
<div class="col-auto">
|
||||
<a href="<?= base_url('employee/pending-approvals'); ?>"
|
||||
class="btn btn-primary waves-effect waves-light" id="get-emp-list"
|
||||
onclick="fetchPendingApprovalsList(event);">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="employee_table_list"><?= $default_table_html ?? '' ?></div>
|
||||
<div id="loader" class="loader" style="display:none;">SPINNER</div>
|
||||
|
||||
<script>
|
||||
var client_list = '';
|
||||
var branch_list = '';
|
||||
var policy_list = '';
|
||||
var policy_list_by_client = '';
|
||||
var client_id = '<?= isset($getData) ? $getData['client_id'] : '0' ?>';
|
||||
var client_branch_id = '<?= isset($getData) ? $getData['branch_id'] : '0' ?>';
|
||||
|
||||
function init() {
|
||||
const table = document.getElementById("tickets-table") || document.getElementById("employee-data-list-table");
|
||||
if (!table) return;
|
||||
|
||||
let activeDropdown = null;
|
||||
|
||||
table.querySelectorAll("tbody tr").forEach(row => {
|
||||
const customDropdown = createCustomDropdown(row);
|
||||
if (!customDropdown) return;
|
||||
|
||||
document.body.appendChild(customDropdown);
|
||||
|
||||
row.addEventListener("click", function(event) {
|
||||
handleRowClick(event, customDropdown);
|
||||
});
|
||||
|
||||
customDropdown.querySelectorAll('.dropdown-item').forEach(item => {
|
||||
item.addEventListener('click', function(e) {
|
||||
handleItemClick(e, item);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("click", handleDocumentClick);
|
||||
|
||||
function createCustomDropdown(row) {
|
||||
const originalDropdown = row.querySelector('.dropdown-menu');
|
||||
if (!originalDropdown) return null;
|
||||
|
||||
const customDropdown = document.createElement('div');
|
||||
customDropdown.className = 'custom-dropdown-menu';
|
||||
const originalItems = originalDropdown.querySelectorAll('.dropdown-item');
|
||||
customDropdown.innerHTML = originalDropdown.innerHTML;
|
||||
|
||||
customDropdown.querySelectorAll('.dropdown-item').forEach((item, index) => {
|
||||
const originalItem = originalItems[index];
|
||||
const originalOnclick = originalItem.getAttribute('onclick');
|
||||
if (originalOnclick) {
|
||||
item.setAttribute('data-onclick', originalOnclick);
|
||||
item.removeAttribute('onclick');
|
||||
}
|
||||
});
|
||||
|
||||
return customDropdown;
|
||||
}
|
||||
|
||||
function handleRowClick(event, customDropdown) {
|
||||
if (event.target.closest('td:last-child')) {
|
||||
return;
|
||||
}
|
||||
if (activeDropdown) {
|
||||
activeDropdown.style.display = 'none';
|
||||
}
|
||||
const rect = event.target.getBoundingClientRect();
|
||||
customDropdown.style.display = 'block';
|
||||
customDropdown.style.position = 'fixed';
|
||||
customDropdown.style.left = `${rect.left}px`;
|
||||
customDropdown.style.top = `${rect.bottom + 5}px`;
|
||||
activeDropdown = customDropdown;
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
function handleItemClick(e, item) {
|
||||
const onclickAttr = item.getAttribute('data-onclick');
|
||||
if (onclickAttr) {
|
||||
eval(onclickAttr);
|
||||
}
|
||||
const href = item.getAttribute('href');
|
||||
if (href && href !== '#' && href !== 'javascript: void(0);') {
|
||||
window.location.href = href;
|
||||
}
|
||||
if (activeDropdown) {
|
||||
activeDropdown.style.display = 'none';
|
||||
activeDropdown = null;
|
||||
}
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function handleDocumentClick() {
|
||||
if (activeDropdown) {
|
||||
activeDropdown.style.display = 'none';
|
||||
activeDropdown = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
getClientAndBranchAndPolicy();
|
||||
setTimeout(function() {
|
||||
init();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
function getClientAndBranchAndPolicy() {
|
||||
$.ajax({
|
||||
url: '<?= base_url("/util/getClientAndBranchAndPolicy") ?>',
|
||||
type: "GET",
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
if (res.status == true) {
|
||||
client_list = res.client_data;
|
||||
branch_list = res.branch_data;
|
||||
policy_list = res.policy_data;
|
||||
policy_list_by_client = res.policyListByClient;
|
||||
appendClients(client_list);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error(xhr.responseText);
|
||||
console.error(status, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function appendClients(data) {
|
||||
var clientID = <?= isset($getData) ? $getData['client_id'] : '0' ?>;
|
||||
$.each(data, function(index, item) {
|
||||
var option = $('<option>', {
|
||||
value: item.id,
|
||||
text: item.client_name
|
||||
});
|
||||
if (clientID == item.id) {
|
||||
option.attr('selected', true);
|
||||
}
|
||||
$('#clients').append(option);
|
||||
});
|
||||
}
|
||||
|
||||
function appendBranch(data) {
|
||||
$('#branch_id').empty();
|
||||
$('#branch_id').append($('<option>', {
|
||||
value: '0',
|
||||
text: 'Select'
|
||||
}));
|
||||
$.each(data, function(index, item) {
|
||||
var option = $('<option>', {
|
||||
value: item.id,
|
||||
text: item.branch_name
|
||||
});
|
||||
if (client_branch_id == item.id) {
|
||||
option.attr('selected', true);
|
||||
}
|
||||
$('#branch_id').append(option);
|
||||
});
|
||||
}
|
||||
|
||||
function appendPolicies(data) {
|
||||
$('#policies').empty();
|
||||
$('#policies').append($('<option>', {
|
||||
value: '0',
|
||||
text: 'Select'
|
||||
}));
|
||||
|
||||
var PolicyID = <?= isset($getData) ? $getData['policy_id'] : '0' ?>;
|
||||
$.each(data, function(index, item) {
|
||||
var option = $('<option>', {
|
||||
value: item.id,
|
||||
text: `${item.policy_type ?? ''} - ${item.policy_no ?? ''}`
|
||||
});
|
||||
if (PolicyID == item.id || PolicyID == item.client_policy_id) {
|
||||
option.attr('selected', true);
|
||||
}
|
||||
$('#policies').append(option);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#clients').on('change', function() {
|
||||
$('#branch_id').empty();
|
||||
$('#branch_id').append($('<option>', { value: '0', text: 'Select'}));
|
||||
$('#policies').empty();
|
||||
$('#policies').append($('<option>', { value: '0', text: 'Select' }));
|
||||
|
||||
var selectedClient = $(this).val();
|
||||
var filteredBranch = branch_list[selectedClient];
|
||||
if (filteredBranch) {
|
||||
appendBranch(filteredBranch);
|
||||
}
|
||||
});
|
||||
|
||||
$('#branch_id').on('change', function() {
|
||||
var selectedBranch = $(this).val();
|
||||
var selectedClient = $('#clients').val();
|
||||
var filteredPoliciesByClient = policy_list_by_client[selectedClient] || [];
|
||||
var filteredPoliciesByBranch = filteredPoliciesByClient.filter(function(item) {
|
||||
return item.client_branch_id === selectedBranch;
|
||||
});
|
||||
appendPolicies(filteredPoliciesByBranch);
|
||||
if (Array.isArray(filteredPoliciesByBranch) && filteredPoliciesByBranch.length === 0) {
|
||||
toastr.warning('No policies found for the selected client branch.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function objectToQueryString(obj) {
|
||||
return Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
|
||||
}
|
||||
|
||||
function fetchPendingApprovalsList(event = null) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
var client_id = $('#clients').val();
|
||||
var policy_id = $('#policies').val();
|
||||
var branch_id = $('#branch_id').val();
|
||||
|
||||
var queryParams = {
|
||||
client_id: client_id,
|
||||
policy_id: policy_id,
|
||||
branch_id: branch_id,
|
||||
};
|
||||
|
||||
const queryString = objectToQueryString(queryParams);
|
||||
const apiURL = $('#get-emp-list').attr('href') + "?" + queryString;
|
||||
|
||||
$('.loader').fadeIn();
|
||||
$('.loader-mask').fadeIn();
|
||||
|
||||
$.ajax({
|
||||
url: apiURL,
|
||||
method: 'GET',
|
||||
data: queryParams,
|
||||
success: function(response) {
|
||||
if (response.status == true) {
|
||||
$('#employee_table_list').html(response.html);
|
||||
$('.loader').fadeOut();
|
||||
$('.loader-mask').delay(350).fadeOut('slow');
|
||||
setTimeout(function() {
|
||||
init();
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('Error:', error);
|
||||
toastr.error('Failed to fetch Data', 'Error');
|
||||
$('.loader').fadeOut();
|
||||
$('.loader-mask').delay(350).fadeOut('slow');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('toggleIcon').addEventListener('click', function() {
|
||||
var icon = document.getElementById('icon');
|
||||
icon.classList.toggle('mdi-chevron-down');
|
||||
icon.classList.toggle('mdi-chevron-up');
|
||||
});
|
||||
|
||||
function processPendingDependent(employeeId, clientPolicyId, status) {
|
||||
var actionLabel = status === 'approved' ? 'approve' : 'reject';
|
||||
|
||||
Swal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: 'Do you want to ' + actionLabel + ' this dependent?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Yes',
|
||||
cancelButtonText: 'No'
|
||||
}).then((result) => {
|
||||
if (!result.isConfirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('.loader').fadeIn();
|
||||
$('.loader-mask').fadeIn();
|
||||
|
||||
$.ajax({
|
||||
url: '<?= base_url('processDependentAdd') ?>',
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
employee_id: employeeId,
|
||||
client_policy_id: clientPolicyId,
|
||||
status: status
|
||||
}),
|
||||
success: function(response) {
|
||||
$('.loader').fadeOut();
|
||||
$('.loader-mask').delay(350).fadeOut('slow');
|
||||
|
||||
if (response.status === 'success' || response.code == 200) {
|
||||
toastr.success(response.message || ('Dependent ' + actionLabel + 'd successfully'));
|
||||
fetchPendingApprovalsList();
|
||||
} else {
|
||||
toastr.error(response.data || response.message || 'Action failed');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$('.loader').fadeOut();
|
||||
$('.loader-mask').delay(350).fadeOut('slow');
|
||||
toastr.error('Action failed', 'Error');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@ -2005,6 +2005,9 @@ body[data-sidebar-size="condensed"] .footer {
|
||||
<li>
|
||||
<a href="<?= base_url('/employee/list') ?>">View Members</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?= base_url('/employee/pending-approvals') ?>">View Pending Approvals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?= base_url('/employee/endorsement-list') ?>">View Endorsement</a>
|
||||
</li>
|
||||
|
||||
@ -229,6 +229,11 @@
|
||||
style="width: 35%;;" type="number" name="self_max_age" id="self_max_age"
|
||||
onchange="lowerIsEighteen(this)">
|
||||
</div>
|
||||
|
||||
<div class="self-age d-flex align-items-center ml-3">
|
||||
<span style="margin-right:8px;color:black;font-size:12px;white-space:nowrap;">Is Payable by employee:</span>
|
||||
<input type="checkbox" name="is_payable_employee_for_self" id="is_payable_employee_for_self" value="1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center policy-base-info">
|
||||
@ -253,6 +258,11 @@
|
||||
style="width: 35%;;" type="number" name="spouse_max_age" id="spouse_max_age"
|
||||
onchange="lowerIsEighteen(this)">
|
||||
</div>
|
||||
|
||||
<div class="spouse-age d-flex align-items-center ml-3">
|
||||
<span style="margin-right:8px;color:black;font-size:12px;white-space:nowrap;">Is Payable by employee:</span>
|
||||
<input type="checkbox" name="is_payable_employee_for_spouse" id="is_payable_employee_for_spouse" value="1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center policy-base-info">
|
||||
@ -280,6 +290,11 @@
|
||||
style="width: 35%;;" type="number" name="child_max_age" id="child_max_age"
|
||||
oninput="this.value = this.value.replace(/\D/g, '').substring(0, 2)">
|
||||
</div>
|
||||
|
||||
<div class="child-age d-flex align-items-center ml-3">
|
||||
<span style="margin-right:8px;color:black;font-size:12px;white-space:nowrap;">Is Payable by employee:</span>
|
||||
<input type="checkbox" name="is_payable_employee_for_child" id="is_payable_employee_for_child" value="1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center policy-base-info flex-nowrap">
|
||||
@ -326,6 +341,11 @@
|
||||
onchange="lowerIsEighteen(this)">
|
||||
</div>
|
||||
|
||||
<div class="other-member-age d-flex align-items-center ml-3">
|
||||
<span style="margin-right:8px;color:black;font-size:12px;white-space:nowrap;">Is Payable by employee:</span>
|
||||
<input type="checkbox" name="is_payable_employee_for_elders" id="is_payable_employee_for_elders" value="1">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -1406,46 +1426,14 @@
|
||||
$('#other_member_max_age').val(jsonObject[key].elders.max);
|
||||
}
|
||||
|
||||
// if (key.includes("is_payable_employee")) {
|
||||
|
||||
// if (jsonObject[key]) {
|
||||
|
||||
// if (jsonObject[key].self == 0) {
|
||||
// $('#is_payable_employee_for_self').prop('checked',
|
||||
// false);
|
||||
// } else {
|
||||
// $('#is_payable_employee_for_self').prop('checked',
|
||||
// true);
|
||||
// }
|
||||
|
||||
// if (jsonObject[key].spouse == 0) {
|
||||
// $('#is_payable_employee_for_spouse').prop('checked',
|
||||
// false);
|
||||
// } else {
|
||||
// $('#is_payable_employee_for_spouse').prop('checked',
|
||||
// true);
|
||||
// }
|
||||
|
||||
// if (jsonObject[key].childern == 0) {
|
||||
// $('#is_payable_employee_for_child').prop('checked',
|
||||
// false);
|
||||
// } else {
|
||||
// $('#is_payable_employee_for_child').prop('checked',
|
||||
// true);
|
||||
// }
|
||||
|
||||
// // if (jsonObject[key].elders == 0) {
|
||||
// // $('#is_payable_employee_for_elders').prop('checked',
|
||||
// // false);
|
||||
// // } else {
|
||||
// // $('#is_payable_employee_for_elders').prop('checked',
|
||||
// // true);
|
||||
// // }
|
||||
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
if (key.includes("is_payable_employee")) {
|
||||
if (jsonObject[key]) {
|
||||
$('#is_payable_employee_for_self').prop('checked', jsonObject[key].self == 1);
|
||||
$('#is_payable_employee_for_spouse').prop('checked', jsonObject[key].spouse == 1);
|
||||
$('#is_payable_employee_for_child').prop('checked', jsonObject[key].childern == 1);
|
||||
$('#is_payable_employee_for_elders').prop('checked', jsonObject[key].elders == 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (key.includes("enrollment_display_key") && key != "") {
|
||||
|
||||
|
||||
283
docs/dependent-approval-apis.md
Normal file
283
docs/dependent-approval-apis.md
Normal file
@ -0,0 +1,283 @@
|
||||
# Dependent Approval APIs
|
||||
|
||||
Base path: `/employeeRest/`
|
||||
|
||||
Auth: JWT + App-Signature (`authJWT`, `appSignature`)
|
||||
|
||||
---
|
||||
|
||||
## 1. Get Employee Policy (Dependent Add UI)
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Method** | `GET` |
|
||||
| **URL** | `/employeeRest/getEmployeePolicy` |
|
||||
| **Handler** | `EmployeeRestController::getEmployeeByPolicyv2` |
|
||||
|
||||
> **Note:** Route currently maps to `getEmployeePolicyv2` (method missing). Intended handler is `getEmployeeByPolicyv2`.
|
||||
|
||||
### Query Params
|
||||
|
||||
| Param | Required | Description |
|
||||
|---|---|---|
|
||||
| `id` | Yes | Self employee id |
|
||||
| `emp_code` | Yes | Employee code |
|
||||
| `client_id` | Yes | Client id |
|
||||
| `client_branch_id` | Yes | Branch id |
|
||||
| `client_policy_id` | Yes | GMC client policy id |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"code": 200,
|
||||
"message": "Employee policy and dependent details fetched successfully",
|
||||
"data": {
|
||||
"...": "policy details, mapped_family_floaters, allowed_relationships"
|
||||
},
|
||||
"EmployeePolicy": [],
|
||||
"add_button_show": true
|
||||
}
|
||||
```
|
||||
|
||||
### Error Responses
|
||||
|
||||
| code | message |
|
||||
|---|---|
|
||||
| 400 | Required parameters missing |
|
||||
| 400 | Only GMC policy is supported for dependent add |
|
||||
| 404 | Employee policy not found |
|
||||
| 500 | Something went wrong while fetching employee policy details |
|
||||
|
||||
---
|
||||
|
||||
## 2. Add / Update Dependent (Pending Approval)
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Method** | `POST` |
|
||||
| **URL** | `/employeeRest/addEmployeeAndDependence` |
|
||||
| **Handler** | `EmployeeRestController::addEmployeeAndDependencev2` |
|
||||
| **Content-Type** | `application/json` |
|
||||
|
||||
### Request Body
|
||||
|
||||
JSON **array** of dependent objects:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"emp_code": "E001",
|
||||
"client_id": 10,
|
||||
"client_branch_id": 5,
|
||||
"client_policy_id": 100,
|
||||
"name": "John Doe",
|
||||
"relationship": "Spouse",
|
||||
"dob": "01/01/1990",
|
||||
"basic_cover_si": 500000,
|
||||
"dependent_effective_date": "01/08/2026",
|
||||
"hr_id": 12
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Required | Notes |
|
||||
|---|---|---|
|
||||
| `emp_code` | Yes | Parent employee code |
|
||||
| `client_id` | Yes | Client id |
|
||||
| `client_branch_id` | Yes | Used for premium update |
|
||||
| `client_policy_id` | Yes | Client policy id |
|
||||
| `name` | Yes | Dependent name |
|
||||
| `relationship` | Yes | e.g. Spouse / Son / Daughter |
|
||||
| `dob` | Yes | Converted to `Y-m-d` |
|
||||
| `basic_cover_si` | Yes | Sum insured |
|
||||
| `dependent_effective_date` | Yes (new) | Coverage start date |
|
||||
| `hr_id` | No | If set → created by HR; else USER |
|
||||
| `id` | No | If set → update existing dependent |
|
||||
|
||||
### Behavior
|
||||
|
||||
- Creates/updates dependent with `emp_status = pending_approval`
|
||||
- Creates employee policy with `status = pending_approval`
|
||||
- Recalculates premium for the family
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"code": 200,
|
||||
"data": []
|
||||
}
|
||||
```
|
||||
|
||||
### Error Responses
|
||||
|
||||
| code | data |
|
||||
|---|---|
|
||||
| 404 | Requested parameters are required |
|
||||
| 404 | No Matches |
|
||||
| 500 | Exception message |
|
||||
|
||||
---
|
||||
|
||||
## 3. Delete Dependent
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Method** | `GET` |
|
||||
| **URL** | `/employeeRest/deleteDependence` |
|
||||
| **Handler** | `EmployeeRestController::deleteDependencev2` |
|
||||
|
||||
### Query Params
|
||||
|
||||
| Param | Required | Description |
|
||||
|---|---|---|
|
||||
| `id` | Yes | Dependent employee id |
|
||||
|
||||
### Behavior
|
||||
|
||||
Soft-deletes employee and policy:
|
||||
|
||||
- `emp_status` / `status` → `truncated`
|
||||
- `is_active` → `0`
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"code": 200,
|
||||
"data": []
|
||||
}
|
||||
```
|
||||
|
||||
### Error Responses
|
||||
|
||||
| code | data |
|
||||
|---|---|
|
||||
| 404 | `[]` (missing `id`) |
|
||||
| 500 | Exception message |
|
||||
|
||||
---
|
||||
|
||||
## 4. List Pending Approval Dependents
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Method** | `GET` |
|
||||
| **URL** | `/employeeRest/getPendingApprovalDependents` |
|
||||
| **Handler** | `EmployeeRestController::getPendingApprovalDependents` |
|
||||
|
||||
### Query Params
|
||||
|
||||
| Param | Required | Description |
|
||||
|---|---|---|
|
||||
| `client_id` | No | Client filter |
|
||||
| `client_branch_id` / `branch_id` | No | Branch filter |
|
||||
| `client_policy_id` / `policy_id` | No | Policy filter |
|
||||
| `search` | No | Name / emp_code search |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"code": 200,
|
||||
"message": "Pending approval dependents fetched successfully",
|
||||
"data": []
|
||||
}
|
||||
```
|
||||
|
||||
### Error Responses
|
||||
|
||||
| code | message |
|
||||
|---|---|
|
||||
| 404 | No pending approval dependents found |
|
||||
| 500 | Exception message |
|
||||
|
||||
---
|
||||
|
||||
## 5. Approve / Reject Dependent
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Method** | `POST` |
|
||||
| **URL** | `/employeeRest/processDependentAdd` |
|
||||
| **Handler** | `EmployeeRestController::processDependentAdd` |
|
||||
| **Content-Type** | `application/json` |
|
||||
|
||||
### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"employee_id": 123,
|
||||
"client_policy_id": 100,
|
||||
"status": "approved",
|
||||
"hr_id": 12
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Required | Notes |
|
||||
|---|---|---|
|
||||
| `employee_id` | Yes | Dependent employee id |
|
||||
| `client_policy_id` | Yes | Policy id |
|
||||
| `status` | Yes | `approved` or `rejected` (default: `approved`) |
|
||||
| `hr_id` | No | If set → approved by HR; else ACM |
|
||||
|
||||
### Behavior
|
||||
|
||||
| status | Employee | Policy |
|
||||
|---|---|---|
|
||||
| `approved` | `emp_status = active` | `status = active` |
|
||||
| `rejected` | `emp_status = rejected`, `is_active = 0` | `status = rejected`, `is_active = 0` |
|
||||
|
||||
### Success Response
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"code": 200,
|
||||
"data": []
|
||||
}
|
||||
```
|
||||
|
||||
### Error Responses
|
||||
|
||||
| code | data |
|
||||
|---|---|
|
||||
| 400 | Request body is required |
|
||||
| 400 | employee_id is required |
|
||||
| 400 | client_policy_id is required |
|
||||
| 400 | status is invalid |
|
||||
| 400 | Dependent is already approved |
|
||||
| 400 | Dependent is not pending approval |
|
||||
| 404 | Employee not found or inactive |
|
||||
| 404 | Employee policy not found or inactive |
|
||||
| 500 | Failed to update employee/policy status |
|
||||
|
||||
---
|
||||
|
||||
## Typical Flow
|
||||
|
||||
```
|
||||
1. getEmployeePolicy
|
||||
→ show family slots / add buttons
|
||||
|
||||
2. addEmployeeAndDependence
|
||||
→ submit dependent → pending_approval
|
||||
|
||||
3. getPendingApprovalDependents
|
||||
→ HR / ACM review list
|
||||
|
||||
4. processDependentAdd
|
||||
→ approve or reject
|
||||
|
||||
5. deleteDependence
|
||||
→ soft-delete if needed
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user