CHANGE_MAIL_SEND
This commit is contained in:
parent
4d8edca3b1
commit
1fd983ea7b
@ -169,18 +169,37 @@ class EmployeeController extends AdminController
|
||||
$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,
|
||||
$client_id = $filterData['client_id'] ?? null;
|
||||
$policy_id = $filterData['policy_id'] ?? null;
|
||||
$branch_id = $filterData['branch_id'] ?? null;
|
||||
|
||||
$employees = $this->employeePolicyModel->getPendingApprovalDependents(
|
||||
client_id: $client_id,
|
||||
policy_id: $policy_id,
|
||||
branch_id: $branch_id,
|
||||
);
|
||||
|
||||
// Default: only pending_approval. When ACM filters client + branch + policy → show all statuses.
|
||||
$hasFullFilter = ! empty($client_id) && $client_id != '0'
|
||||
&& ! empty($branch_id) && $branch_id != '0'
|
||||
&& ! empty($policy_id) && $policy_id != '0';
|
||||
|
||||
if (! $hasFullFilter && ! empty($employees)) {
|
||||
$employees = array_values(array_filter($employees, static function ($row) {
|
||||
return strtolower((string) ($row['status'] ?? '')) === 'pending_approval';
|
||||
}));
|
||||
}
|
||||
|
||||
$data['employees'] = $employees;
|
||||
$data['getData'] = [
|
||||
'client_id' => $filterData['client_id'] ?? '0',
|
||||
'policy_id' => $filterData['policy_id'] ?? '0',
|
||||
'branch_id' => $filterData['branch_id'] ?? '0',
|
||||
'client_id' => $client_id ?? '0',
|
||||
'policy_id' => $policy_id ?? '0',
|
||||
'branch_id' => $branch_id ?? '0',
|
||||
'emp_code' => '',
|
||||
'emp_name' => '',
|
||||
'status' => ['pending_approval', 'active', 'rejected'],
|
||||
'status' => $hasFullFilter
|
||||
? ['pending_approval', 'active', 'rejected']
|
||||
: ['pending_approval'],
|
||||
];
|
||||
|
||||
// AJAX filter submit → return table HTML only
|
||||
@ -189,9 +208,9 @@ class EmployeeController extends AdminController
|
||||
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';
|
||||
// Default page load → list pending dependents only
|
||||
$data['tab_name'] = 'Approvals';
|
||||
$data['page_name'] = 'Approvals';
|
||||
$data['default_table_html'] = view('employee_pending_approvals_data_list', $data);
|
||||
|
||||
$this->loadLayout('employee_pending_approvals_list', $data);
|
||||
|
||||
@ -6365,6 +6365,7 @@ class EmployeeRestController extends AdminController
|
||||
if ($data) {
|
||||
|
||||
$Count = 0;
|
||||
$newDependentsForNotification = [];
|
||||
foreach ($data as $item) {
|
||||
|
||||
$self_data = $this->employeeModel
|
||||
@ -6402,6 +6403,18 @@ class EmployeeRestController extends AdminController
|
||||
|
||||
if ($employee) {
|
||||
$Count++;
|
||||
$newDependentsForNotification[] = [
|
||||
'employee_id' => (int) $employee,
|
||||
'emp_code' => (string) ($item->emp_code ?? ''),
|
||||
'dependent_name' => (string) ($item->name ?? ''),
|
||||
'relationship' => (string) ($item->relationship ?? ''),
|
||||
'dob' => (string) ($item->dob ?? ''),
|
||||
'client_id' => (int) ($item->client_id ?? 0),
|
||||
'client_branch_id' => (int) ($item->client_branch_id ?? 0),
|
||||
'client_policy_id' => (int) ($item->client_policy_id ?? 0),
|
||||
'dependent_effective_date' => (string) ($item->dependent_effective_date ?? ''),
|
||||
'created_by_type' => isset($item->hr_id) ? 'HR' : 'USER',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6417,6 +6430,12 @@ class EmployeeRestController extends AdminController
|
||||
|
||||
$this->updatePremiumAmount($data[0]->client_policy_id, $data[0]->emp_code, $data[0]->client_branch_id);
|
||||
|
||||
if (! empty($newDependentsForNotification)) {
|
||||
foreach ($newDependentsForNotification as $dependentNotificationData) {
|
||||
$this->sendDependentAddNotificationMail($dependentNotificationData);
|
||||
}
|
||||
}
|
||||
|
||||
$result = [];
|
||||
return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200);
|
||||
} else {
|
||||
@ -6432,6 +6451,130 @@ class EmployeeRestController extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify client/branch HRs and client account managers when a dependent is added.
|
||||
*/
|
||||
private function sendDependentAddNotificationMail(array $dependentData): void
|
||||
{
|
||||
try {
|
||||
$clientId = (int) ($dependentData['client_id'] ?? 0);
|
||||
$branchId = (int) ($dependentData['client_branch_id'] ?? 0);
|
||||
$clientPolicyId = (int) ($dependentData['client_policy_id'] ?? 0);
|
||||
|
||||
if ($clientId <= 0 || $branchId <= 0 || $clientPolicyId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$db = \Config\Database::connect();
|
||||
|
||||
$clientData = $this->clientModel
|
||||
->select('id, client_name, email')
|
||||
->where('id', $clientId)
|
||||
->first();
|
||||
|
||||
$branchData = $this->clientBranchModel
|
||||
->select('id, branch_name')
|
||||
->where('id', $branchId)
|
||||
->first();
|
||||
|
||||
$policyData = $this->clientPolicyModel
|
||||
->select('id, policy_no')
|
||||
->where('id', $clientPolicyId)
|
||||
->first();
|
||||
|
||||
$selfEmployee = $this->employeeModel
|
||||
->select('name')
|
||||
->where('client_id', $clientId)
|
||||
->where('emp_code', (string) ($dependentData['emp_code'] ?? ''))
|
||||
->where('relationship', 'Self')
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
$branchHrEmails = $db->table('level_contacts')
|
||||
->select('email')
|
||||
->where('ref_id', $branchId)
|
||||
->where('contact_type', 'client')
|
||||
->where('is_active', 1)
|
||||
->where('email IS NOT NULL', null, false)
|
||||
->where("TRIM(email) != ''", null, false)
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$accountManagerEmails = $this->clientRMModel->findAccountManagerEmail($clientId) ?? [];
|
||||
|
||||
$recipientEmails = [];
|
||||
|
||||
if (! empty($clientData['email'])) {
|
||||
$recipientEmails[] = trim((string) $clientData['email']);
|
||||
}
|
||||
|
||||
foreach ($branchHrEmails as $branchHrEmailRow) {
|
||||
$recipientEmails[] = trim((string) ($branchHrEmailRow['email'] ?? ''));
|
||||
}
|
||||
|
||||
if (is_array($accountManagerEmails)) {
|
||||
foreach ($accountManagerEmails as $accountManagerEmail) {
|
||||
$recipientEmails[] = trim((string) $accountManagerEmail);
|
||||
}
|
||||
}
|
||||
|
||||
$recipientEmails = array_values(array_unique(array_filter($recipientEmails, static function ($email) {
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
})));
|
||||
|
||||
if (empty($recipientEmails)) {
|
||||
log_message('info', '[DependentAddMail] No recipient emails found for client_id=' . $clientId . ', branch_id=' . $branchId);
|
||||
return;
|
||||
}
|
||||
|
||||
$clientName = (string) ($clientData['client_name'] ?? '');
|
||||
$branchName = (string) ($branchData['branch_name'] ?? '');
|
||||
$policyNo = (string) ($policyData['policy_no'] ?? '');
|
||||
$employeeName = (string) ($selfEmployee['name'] ?? '');
|
||||
|
||||
$dependentName = (string) ($dependentData['dependent_name'] ?? '');
|
||||
$relationship = (string) ($dependentData['relationship'] ?? '');
|
||||
$dependentDob = ! empty($dependentData['dob']) ? date('d/m/Y', strtotime((string) $dependentData['dob'])) : '-';
|
||||
$effectiveDate = ! empty($dependentData['dependent_effective_date']) ? date('d/m/Y', strtotime((string) $dependentData['dependent_effective_date'])) : '-';
|
||||
$createdByType = (string) ($dependentData['created_by_type'] ?? 'USER');
|
||||
$employeeCode = (string) ($dependentData['emp_code'] ?? '');
|
||||
|
||||
$subject = 'Dependent Added - Approval Required | ' . ($clientName ?: 'Client');
|
||||
|
||||
$message = '
|
||||
<p>Dear ' . esc($employeeName ?: 'Team') . ',</p>
|
||||
<p>A new dependent has been added and is pending for approval.</p>
|
||||
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse: collapse;">
|
||||
<tr><td><strong>Client</strong></td><td>' . esc($clientName) . '</td></tr>
|
||||
<tr><td><strong>Branch</strong></td><td>' . esc($branchName) . '</td></tr>
|
||||
<tr><td><strong>Policy</strong></td><td>' . esc($policyNo) . '</td></tr>
|
||||
<tr><td><strong>Employee</strong></td><td>' . esc($employeeName) . '</td></tr>
|
||||
<tr><td><strong>Employee Code</strong></td><td>' . esc($employeeCode) . '</td></tr>
|
||||
<tr><td><strong>Dependent Name</strong></td><td>' . esc($dependentName) . '</td></tr>
|
||||
<tr><td><strong>Relationship</strong></td><td>' . esc($relationship) . '</td></tr>
|
||||
<tr><td><strong>Date of Birth</strong></td><td>' . esc($dependentDob) . '</td></tr>
|
||||
<tr><td><strong>Effective Date</strong></td><td>' . esc($effectiveDate) . '</td></tr>
|
||||
<tr><td><strong>Added By</strong></td><td>' . esc($createdByType) . '</td></tr>
|
||||
</table>
|
||||
<p>Please review this request in Approvals.</p>
|
||||
';
|
||||
|
||||
$mailPayload = [
|
||||
'mail' => $recipientEmails,
|
||||
'subject' => $subject,
|
||||
'message' => $message,
|
||||
'attachments' => [],
|
||||
'reply_to' => '',
|
||||
];
|
||||
|
||||
$mailResult = MailHelper::send_email($mailPayload);
|
||||
$this->myLogger->logme('info', '[DependentAddMail] mail_result=' . json_encode($mailResult));
|
||||
} catch (\Throwable $th) {
|
||||
log_message('error', '[DependentAddMail] ' . $th->getMessage() . ' in ' . $th->getFile() . ':' . $th->getLine());
|
||||
$this->myLogger->logme('error', '[DependentAddMail] ' . $th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteDependencev2()
|
||||
{
|
||||
try {
|
||||
@ -6707,8 +6850,22 @@ class EmployeeRestController extends AdminController
|
||||
}
|
||||
|
||||
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')
|
||||
->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,
|
||||
employee_polices.processed_by,
|
||||
employee_polices.reject_reason,
|
||||
employee_polices.date_coverage
|
||||
')
|
||||
->join('employees', 'employee_polices.employee_id = employees.id', 'left')
|
||||
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id', 'left')
|
||||
->join('policy_type', 'policy_type.id = client_policy.policy_type_id', 'left')
|
||||
->whereIn('employee_polices.employee_id', $employeeIds)
|
||||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||||
->where('employee_polices.is_active', 1)
|
||||
@ -6755,41 +6912,59 @@ class EmployeeRestController extends AdminController
|
||||
|
||||
$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);
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'Employee not found'], 200);
|
||||
}
|
||||
|
||||
if (($employee['emp_status'] ?? null) === 'active') {
|
||||
$emp_status = strtolower((string) ($employee['emp_status'] ?? ''));
|
||||
|
||||
if ($emp_status === '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);
|
||||
if ($status === 'approved') {
|
||||
if (! in_array($emp_status, ['pending_approval', 'rejected'], true)) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Dependent cannot be approved'], 200);
|
||||
}
|
||||
} elseif ($emp_status !== 'pending_approval') {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Only pending dependents can be rejected'], 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);
|
||||
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'Employee policy not found'], 200);
|
||||
}
|
||||
|
||||
$policy_status = strtolower((string) ($employee_policy['status'] ?? ''));
|
||||
|
||||
if ($status === 'approved') {
|
||||
if (! in_array($policy_status, ['pending_approval', 'rejected'], true)) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Employee policy cannot be approved'], 200);
|
||||
}
|
||||
} elseif ($policy_status !== 'pending_approval') {
|
||||
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Only pending employee policy can be rejected'], 200);
|
||||
}
|
||||
|
||||
if ($status === 'approved') {
|
||||
$employee_update_data = [
|
||||
'updated_by' => $updated_by,
|
||||
'processed_by' => $processed_by_role,
|
||||
'emp_status' => 'active',
|
||||
'updated_by' => $updated_by,
|
||||
'processed_by' => $processed_by_role,
|
||||
'emp_status' => 'active',
|
||||
'is_active' => 1,
|
||||
'reject_reason' => null,
|
||||
];
|
||||
$policy_update_data = [
|
||||
'updated_by' => $updated_by,
|
||||
'processed_by' => $processed_by_role,
|
||||
'status' => 'active',
|
||||
'updated_by' => $updated_by,
|
||||
'processed_by' => $processed_by_role,
|
||||
'status' => 'active',
|
||||
'is_active' => 1,
|
||||
'reject_reason' => null,
|
||||
];
|
||||
} else {
|
||||
$employee_update_data = [
|
||||
@ -6808,11 +6983,7 @@ class EmployeeRestController extends AdminController
|
||||
];
|
||||
}
|
||||
|
||||
$employee_updated = $this->employeeModel
|
||||
->where('id', $employee_id)
|
||||
->where('is_active', 1)
|
||||
->set($employee_update_data)
|
||||
->update();
|
||||
$employee_updated = $this->employeeModel->update($employee_id, $employee_update_data);
|
||||
|
||||
if (!$employee_updated) {
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => 'Failed to update employee status'], 200);
|
||||
@ -6821,7 +6992,6 @@ class EmployeeRestController extends AdminController
|
||||
$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();
|
||||
|
||||
@ -6829,7 +6999,17 @@ class EmployeeRestController extends AdminController
|
||||
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => 'Failed to update employee policy status'], 200);
|
||||
}
|
||||
|
||||
return $this->respond(['status' => 'success', 'code' => 200, 'data' => []], 200);
|
||||
return $this->respond([
|
||||
'status' => 'success',
|
||||
'code' => 200,
|
||||
'message' => $status === 'approved' ? 'Dependent approved successfully' : 'Dependent rejected successfully',
|
||||
'data' => [
|
||||
'employee_id' => $employee_id,
|
||||
'client_policy_id' => $client_policy_id,
|
||||
'status' => $status,
|
||||
'reject_reason' => $status === 'rejected' ? $reject_reason : null,
|
||||
],
|
||||
], 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);
|
||||
|
||||
@ -420,6 +420,7 @@ class EmployeePolicyModel extends Model
|
||||
'emp.emp_status',
|
||||
'emp.is_active as emp_is_active',
|
||||
'emp.reject_reason as emp_reject_reason',
|
||||
'employee_polices.reject_reason as policy_reject_reason',
|
||||
'emp.processed_by as emp_processed_by',
|
||||
'emp.mobile as mobile',
|
||||
'emp.doj',
|
||||
@ -483,6 +484,12 @@ class EmployeePolicyModel extends Model
|
||||
->where('employee_polices.status', 'rejected')
|
||||
->groupEnd()
|
||||
->groupEnd()
|
||||
->orderBy("CASE
|
||||
WHEN employee_polices.status = 'pending_approval' THEN 1
|
||||
WHEN employee_polices.status = 'rejected' THEN 2
|
||||
WHEN employee_polices.status = 'active' THEN 3
|
||||
ELSE 4
|
||||
END", 'ASC', false)
|
||||
->orderBy('employee_polices.updated_at', 'DESC')
|
||||
->orderBy('emp.emp_code', 'ASC')
|
||||
->orderBy('employee_polices.employee_id', 'ASC');
|
||||
|
||||
@ -1,111 +1,242 @@
|
||||
<?php
|
||||
$getData = $getData ?? [];
|
||||
$pro_rata_total = 0;
|
||||
$gst_total = 0;
|
||||
|
||||
if (! function_exists('format_pending_approval_date')) {
|
||||
function format_pending_approval_date($date)
|
||||
{
|
||||
if (empty($date)) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
$timestamp = strtotime((string) $date);
|
||||
|
||||
return $timestamp ? date('d/m/Y', $timestamp) : '-';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
.badge2 { display: inline-block; padding: .25em .4em; font-size: 75%; font-weight: 700; line-height: 1; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25rem; }
|
||||
.badge2-secondary2 { color: #fff; background-color: #187607; }
|
||||
.table-responsive { overflow-x: auto; }
|
||||
#client_list .card-body {
|
||||
padding: 12px 16px 8px;
|
||||
}
|
||||
|
||||
#pending-approvals-table .approval-action-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
line-height: 28px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#pending-approvals-table .employee-meta {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
#pending-approvals-table .employee-meta small {
|
||||
display: block;
|
||||
color: #6c757d;
|
||||
font-size: 11px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
#pending-approvals-table .approval-status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 72px;
|
||||
width: 72px;
|
||||
height: 22px;
|
||||
padding: 0;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
border-radius: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#pending-approvals-table .approval-reject-info {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-left: 6px;
|
||||
color: #dc3545;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#pending-approvals-table .approval-reject-info:hover,
|
||||
#pending-approvals-table .approval-reject-info:focus {
|
||||
color: #00999E;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#pending-approvals-table .approval-reject-tooltip-text {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
bottom: calc(100% + 8px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
min-width: 160px;
|
||||
max-width: 280px;
|
||||
padding: 6px 10px;
|
||||
background: #343a40;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
border-radius: 6px;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
z-index: 9999;
|
||||
pointer-events: none;
|
||||
text-align: left;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
#pending-approvals-table .approval-reject-tooltip-text::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border: 6px solid transparent;
|
||||
border-top-color: #343a40;
|
||||
}
|
||||
|
||||
#pending-approvals-table .approval-reject-info:hover .approval-reject-tooltip-text,
|
||||
#pending-approvals-table .approval-reject-info:focus .approval-reject-tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#pending-approvals-table .badge {
|
||||
font-size: 11px;
|
||||
padding: 3px 8px;
|
||||
}
|
||||
|
||||
#pending-approvals-table tbody td:last-child {
|
||||
overflow: visible !important;
|
||||
text-overflow: clip;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#pending-approvals-table_wrapper .dataTables_scrollBody,
|
||||
#pending-approvals-table_wrapper table.dataTable tbody td:last-child {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
#pending-approvals-table_wrapper .row {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
#pending-approvals-table_wrapper .row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#pending-approvals-table_wrapper .dataTables_filter,
|
||||
#pending-approvals-table_wrapper .dt-buttons {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#pending-approvals-table_wrapper .dataTables_filter label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#pending-approvals-table_wrapper .dataTables_info,
|
||||
#pending-approvals-table_wrapper .dataTables_length label,
|
||||
#pending-approvals-table_wrapper .dataTables_paginate {
|
||||
margin-bottom: 0;
|
||||
padding-top: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#pending-approvals-table_wrapper .dataTables_length select {
|
||||
margin: 0 6px;
|
||||
padding: 2px 6px;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="row" id="client_list">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row" style="padding-bottom: 10px;">
|
||||
<div class="col-6" style="align-self: center;">
|
||||
<h4 style="position: relative;">Pending Approvals</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover m-0 table-centered nowrap w-100" cellspacing="0" id="employee-data-list-table">
|
||||
<table data-custom-table-css="table" class="table table-hover mb-0 nowrap w-100 table-centered m-0" cellspacing="0" id="pending-approvals-table">
|
||||
<thead class="bg-light">
|
||||
<tr>
|
||||
<th>S.No</th>
|
||||
<?php if (($getData['client_id'] ?? '0') != '0' && ($getData['branch_id'] ?? '0') == '0') { ?>
|
||||
<th>Branch</th>
|
||||
<?php } ?>
|
||||
<th>Name</th>
|
||||
<th>EMP Code</th>
|
||||
<th>Relationship</th>
|
||||
<th>Gender</th>
|
||||
<th>Email</th>
|
||||
<th>Mobile</th>
|
||||
<th>Date of Birth</th>
|
||||
<th>Policy name</th>
|
||||
<th>Insurer name</th>
|
||||
<th>TPA ID</th>
|
||||
<th>Risk ID</th>
|
||||
<th>Policy status</th>
|
||||
<th>Processed By</th>
|
||||
<th>Reject Reason</th>
|
||||
<th>(₹)Sum Insured</th>
|
||||
<th>(₹)Premium</th>
|
||||
<th>(₹)Pro Rata Premium</th>
|
||||
<th>(₹)GST</th>
|
||||
<th>Action</th>
|
||||
<th class="font-weight-medium">Employee </th>
|
||||
<th class="font-weight-medium">Dependent </th>
|
||||
<th class="font-weight-medium">Relationship </th>
|
||||
<th class="font-weight-medium">Date Of Birth </th>
|
||||
<th class="font-weight-medium">Dependent Effective Date </th>
|
||||
<th class="font-weight-medium">Policy </th>
|
||||
<th class="font-weight-medium">Status </th>
|
||||
<th class="font-weight-medium text-center">Action </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="font-12">
|
||||
<?php if (! empty($employees)) {
|
||||
foreach ($employees as $key => $employee) {
|
||||
$pro_rata_total += (float) ($employee['rata_premimum'] ?? 0);
|
||||
$gst_total += (float) ($employee['gst'] ?? 0);
|
||||
foreach ($employees as $employee) {
|
||||
$rowStatus = strtolower((string) ($employee['status'] ?? ''));
|
||||
?>
|
||||
<tr>
|
||||
<td><b><?= $key + 1 ?></b></td>
|
||||
<?php if (($getData['client_id'] ?? '0') != '0' && ($getData['branch_id'] ?? '0') == '0') { ?>
|
||||
<td><?= esc($employee['client_branch_name'] ?? '') ?></td>
|
||||
<?php } ?>
|
||||
<td class="employee-meta">
|
||||
<?= esc($employee['self_name'] ?? '-') ?>
|
||||
<small><?= esc($employee['emp_code'] ?? '') ?></small>
|
||||
</td>
|
||||
<td><?= esc($employee['name'] ?? '') ?></td>
|
||||
<td><?= esc($employee['emp_code'] ?? '') ?></td>
|
||||
<td><?= esc($employee['relationship'] ?? '') ?></td>
|
||||
<td><?= esc($employee['gender'] ?? '') ?></td>
|
||||
<td><?= esc($employee['email_corporate'] ?? '') ?></td>
|
||||
<td><?= esc($employee['mobile'] ?? '') ?></td>
|
||||
<td><?= ! empty($employee['dob']) ? date('d/m/Y', strtotime($employee['dob'])) : '-' ?></td>
|
||||
<td><?= esc(($employee['policy_type'] ?? '') . ' - ' . ($employee['policy_no'] ?? '')) ?></td>
|
||||
<td><?= esc($employee['insurer_short_name'] ?? '') ?></td>
|
||||
<td><?= esc($employee['tpa_id'] ?? '') ?></td>
|
||||
<td><?= esc($employee['uhid'] ?? '') ?></td>
|
||||
<td><?= format_pending_approval_date($employee['dob'] ?? null) ?></td>
|
||||
<td><?= format_pending_approval_date($employee['date_coverage'] ?? null) ?></td>
|
||||
<td><?= esc($employee['policy_no'] ?? '') ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$rowStatus = strtolower((string) ($employee['status'] ?? ''));
|
||||
if ($rowStatus === 'pending_approval') {
|
||||
echo '<span class="badge badge-info">Pending Approval</span>';
|
||||
echo '<span class="badge badge-warning approval-status-badge">Pending</span>';
|
||||
} elseif ($rowStatus === 'active') {
|
||||
echo '<span class="badge badge-success">Approved</span>';
|
||||
echo '<span class="badge badge-success approval-status-badge">Approved</span>';
|
||||
} elseif ($rowStatus === 'rejected') {
|
||||
echo '<span class="badge badge-danger">Rejected</span>';
|
||||
echo '<span class="badge badge-danger approval-status-badge">Rejected</span>';
|
||||
} else {
|
||||
echo esc($employee['status'] ?? '');
|
||||
echo esc($employee['status'] ?? '-');
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?= esc($employee['processed_by'] ?? $employee['emp_processed_by'] ?? '-') ?></td>
|
||||
<td><?= esc($employee['reject_reason'] ?? $employee['emp_reject_reason'] ?? '-') ?></td>
|
||||
<td><?= format_indian_number($employee['basic_cover_si'] ?? 0) ?></td>
|
||||
<td><?= format_indian_number($employee['premium'] ?? 0) ?></td>
|
||||
<td><?= format_indian_number($employee['rata_premimum'] ?? 0) ?></td>
|
||||
<td><?= format_indian_number($employee['gst'] ?? 0) ?></td>
|
||||
<td>
|
||||
<td class="text-nowrap text-center">
|
||||
<?php
|
||||
$rejectReason = trim((string) (
|
||||
$employee['reject_reason']
|
||||
?? $employee['emp_reject_reason']
|
||||
?? $employee['policy_reject_reason']
|
||||
?? ''
|
||||
));
|
||||
?>
|
||||
<?php if ($rowStatus === 'pending_approval') { ?>
|
||||
<div class="btn-group dropdown">
|
||||
<a href="javascript:void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm" data-toggle="dropdown" aria-expanded="false">
|
||||
<i class="mdi mdi-dots-horizontal"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<a class="dropdown-item" href="javascript:void(0);"
|
||||
onclick="processPendingDependent('<?= $employee['employee_id'] ?>', '<?= $employee['client_policy_id'] ?>', 'approved')">
|
||||
<i class="mdi mdi-check-circle mr-2 text-success font-18 vertical-middle"></i>Approve
|
||||
</a>
|
||||
<a class="dropdown-item" href="javascript:void(0);"
|
||||
onclick="processPendingDependent('<?= $employee['employee_id'] ?>', '<?= $employee['client_policy_id'] ?>', 'rejected')">
|
||||
<i class="mdi mdi-close-circle mr-2 text-danger font-18 vertical-middle"></i>Reject
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-success approval-action-btn mr-1" title="Approve"
|
||||
onclick="processPendingDependent('<?= $employee['employee_id'] ?>', '<?= $employee['client_policy_id'] ?>', 'approved')">
|
||||
<i class="mdi mdi-check"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger approval-action-btn" title="Reject"
|
||||
onclick="processPendingDependent('<?= $employee['employee_id'] ?>', '<?= $employee['client_policy_id'] ?>', 'rejected')">
|
||||
<i class="mdi mdi-close"></i>
|
||||
</button>
|
||||
<?php } elseif ($rowStatus === 'rejected') { ?>
|
||||
<button type="button" class="btn btn-success approval-action-btn" title="Approve"
|
||||
onclick="processPendingDependent('<?= $employee['employee_id'] ?>', '<?= $employee['client_policy_id'] ?>', 'approved')">
|
||||
<i class="mdi mdi-check"></i>
|
||||
</button>
|
||||
<span class="approval-reject-info" tabindex="0" role="button" aria-label="Reject reason">
|
||||
<i class="mdi mdi-information-outline"></i>
|
||||
<span class="approval-reject-tooltip-text"><?= esc($rejectReason !== '' ? $rejectReason : 'No reject reason provided') ?></span>
|
||||
</span>
|
||||
<?php } else { ?>
|
||||
-
|
||||
<?php } ?>
|
||||
@ -114,15 +245,6 @@ $gst_total = 0;
|
||||
<?php }
|
||||
} ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="<?= (($getData['client_id'] ?? '0') != '0' && ($getData['branch_id'] ?? '0') == '0') ? 18 : 17 ?>"></th>
|
||||
<th>Total</th>
|
||||
<th><?= format_indian_number($pro_rata_total) ?></th>
|
||||
<th><?= format_indian_number($gst_total) ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -131,11 +253,78 @@ $gst_total = 0;
|
||||
</div>
|
||||
|
||||
<script>
|
||||
if ($.fn.DataTable && !$.fn.DataTable.isDataTable('#employee-data-list-table')) {
|
||||
$('#employee-data-list-table').DataTable({
|
||||
scrollX: true,
|
||||
function initPendingApprovalsDataTable() {
|
||||
if (!$.fn.DataTable) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $table = $('#pending-approvals-table');
|
||||
if (!$table.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($.fn.DataTable.isDataTable('#pending-approvals-table')) {
|
||||
$table.DataTable().destroy();
|
||||
}
|
||||
|
||||
if (typeof nhanceListDataTableBeforeInit === 'function') {
|
||||
nhanceListDataTableBeforeInit();
|
||||
}
|
||||
|
||||
var dtOptions = {
|
||||
dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" +
|
||||
"<'row'<'col-sm-12'tr>>" +
|
||||
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
|
||||
order: [],
|
||||
pageLength: 25
|
||||
});
|
||||
pageLength: 10,
|
||||
lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
|
||||
buttons: [
|
||||
{
|
||||
extend: 'excel',
|
||||
text: '<i class="mdi mdi-file-excel"></i><span class="btn-custom"> EXCEL </span>',
|
||||
className: 'btn app-btn-secondary',
|
||||
title: 'Approvals',
|
||||
sheetName: 'Approvals',
|
||||
exportOptions: {
|
||||
columns: [0, 1, 2, 3, 4, 5, 6],
|
||||
format: {
|
||||
body: function (data, row, column, node) {
|
||||
var $node = $(node);
|
||||
if (column === 0) {
|
||||
var name = $node.clone().children().remove().end().text().trim();
|
||||
var code = $node.find('small').text().trim();
|
||||
return code ? (name + ' (' + code + ')') : name;
|
||||
}
|
||||
return $node.text().replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
language: {
|
||||
search: `
|
||||
<div class="datatable-search-wrapper" style="position:relative; display:inline-block;">
|
||||
_INPUT_
|
||||
<i class="mdi mdi-magnify datatable-search-icon"
|
||||
style="position:absolute; right:10px; top:50%; transform:translateY(-50%); color:#666;"></i>
|
||||
</div>`,
|
||||
searchPlaceholder: "Search",
|
||||
emptyTable: '<div class="text-center text-muted">No approval records found</div>'
|
||||
}
|
||||
};
|
||||
|
||||
var pendingApprovalsTable = typeof nhanceMergeListDataTableOptions === 'function'
|
||||
? $table.DataTable(nhanceMergeListDataTableOptions(dtOptions))
|
||||
: $table.DataTable(dtOptions);
|
||||
|
||||
if (typeof nhanceListDataTableAfterInit === 'function') {
|
||||
nhanceListDataTableAfterInit();
|
||||
}
|
||||
|
||||
if (typeof nhanceListDataTableBindAdjust === 'function') {
|
||||
nhanceListDataTableBindAdjust(pendingApprovalsTable);
|
||||
}
|
||||
}
|
||||
|
||||
initPendingApprovalsDataTable();
|
||||
</script>
|
||||
|
||||
@ -110,92 +110,26 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
initPendingApprovalsDataTable();
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$("#clients").select2({
|
||||
width: '100%',
|
||||
placeholder: 'Select'
|
||||
});
|
||||
$("#branch_id").select2({
|
||||
width: '100%',
|
||||
placeholder: 'Select'
|
||||
});
|
||||
$("#policies").select2({
|
||||
width: '100%',
|
||||
placeholder: 'Select'
|
||||
});
|
||||
|
||||
$("textarea.select2-search__field").attr('rows', '1');
|
||||
$("textarea.select2-search__field").css('resize', 'none');
|
||||
|
||||
getClientAndBranchAndPolicy();
|
||||
setTimeout(function() {
|
||||
init();
|
||||
@ -214,6 +148,17 @@
|
||||
policy_list = res.policy_data;
|
||||
policy_list_by_client = res.policyListByClient;
|
||||
appendClients(client_list);
|
||||
|
||||
if (client_id && client_id !== '0' && branch_list[client_id]) {
|
||||
appendBranch(branch_list[client_id]);
|
||||
}
|
||||
|
||||
if (client_id && client_id !== '0' && client_branch_id && client_branch_id !== '0') {
|
||||
var initialPolicies = (policy_list_by_client[client_id] || []).filter(function(item) {
|
||||
return String(item.client_branch_id) === String(client_branch_id);
|
||||
});
|
||||
appendPolicies(initialPolicies);
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
@ -235,6 +180,7 @@
|
||||
}
|
||||
$('#clients').append(option);
|
||||
});
|
||||
$('#clients').trigger('change.select2');
|
||||
}
|
||||
|
||||
function appendBranch(data) {
|
||||
@ -253,6 +199,7 @@
|
||||
}
|
||||
$('#branch_id').append(option);
|
||||
});
|
||||
$('#branch_id').trigger('change.select2');
|
||||
}
|
||||
|
||||
function appendPolicies(data) {
|
||||
@ -273,6 +220,7 @@
|
||||
}
|
||||
$('#policies').append(option);
|
||||
});
|
||||
$('#policies').trigger('change.select2');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
@ -281,6 +229,8 @@
|
||||
$('#branch_id').append($('<option>', { value: '0', text: 'Select'}));
|
||||
$('#policies').empty();
|
||||
$('#policies').append($('<option>', { value: '0', text: 'Select' }));
|
||||
$('#branch_id').trigger('change.select2');
|
||||
$('#policies').trigger('change.select2');
|
||||
|
||||
var selectedClient = $(this).val();
|
||||
var filteredBranch = branch_list[selectedClient];
|
||||
@ -294,10 +244,10 @@
|
||||
var selectedClient = $('#clients').val();
|
||||
var filteredPoliciesByClient = policy_list_by_client[selectedClient] || [];
|
||||
var filteredPoliciesByBranch = filteredPoliciesByClient.filter(function(item) {
|
||||
return item.client_branch_id === selectedBranch;
|
||||
return String(item.client_branch_id) === String(selectedBranch);
|
||||
});
|
||||
appendPolicies(filteredPoliciesByBranch);
|
||||
if (Array.isArray(filteredPoliciesByBranch) && filteredPoliciesByBranch.length === 0) {
|
||||
if (Array.isArray(filteredPoliciesByBranch) && filteredPoliciesByBranch.length === 0 && selectedBranch && selectedBranch !== '0') {
|
||||
toastr.warning('No policies found for the selected client branch.');
|
||||
}
|
||||
});
|
||||
@ -363,7 +313,7 @@
|
||||
if (status === 'rejected') {
|
||||
Swal.fire({
|
||||
title: 'Reject Dependent',
|
||||
html: '<p class="mb-2">Please enter the reject reason.</p>',
|
||||
html: '<p class="mb-2">Please enter the reject reason. <span class="text-danger">*</span></p>',
|
||||
input: 'textarea',
|
||||
inputPlaceholder: 'Reject reason...',
|
||||
inputAttributes: {
|
||||
@ -374,6 +324,14 @@
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Reject',
|
||||
cancelButtonText: 'Cancel',
|
||||
preConfirm: (value) => {
|
||||
var reason = String(value || '').trim();
|
||||
if (!reason) {
|
||||
Swal.showValidationMessage('Reject reason is required');
|
||||
return false;
|
||||
}
|
||||
return reason;
|
||||
},
|
||||
inputValidator: (value) => {
|
||||
if (!value || !String(value).trim()) {
|
||||
return 'Reject reason is required';
|
||||
@ -383,7 +341,7 @@
|
||||
if (!result.isConfirmed) {
|
||||
return;
|
||||
}
|
||||
submitPendingDependent(employeeId, clientPolicyId, status, String(result.value).trim());
|
||||
submitPendingDependent(employeeId, clientPolicyId, status, String(result.value || '').trim());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2006,7 +2006,7 @@ body[data-sidebar-size="condensed"] .footer {
|
||||
<a href="<?= base_url('/employee/list') ?>">View Members</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?= base_url('/employee/pending-approvals') ?>">View Pending Approvals</a>
|
||||
<a href="<?= base_url('/employee/pending-approvals') ?>">Approvals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?= base_url('/employee/endorsement-list') ?>">View Endorsement</a>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user