FIX_DASHBOARD_OPTIMIZATIONS
This commit is contained in:
parent
9895cb6181
commit
9e241db7a4
@ -116,6 +116,8 @@ $routes->group("/user", ["filter" => "authMVC"], function ($routes) {
|
||||
|
||||
$routes->group("/dashboard", ["filter" => "authMVC"], function ($routes) {
|
||||
$routes->get("view", "DashboardController::dashboard");
|
||||
$routes->get("claims-dash", "DashboardController::claimsDashFragment");
|
||||
$routes->get("leads-dash", "DashboardController::leadsDashFragment");
|
||||
$routes->get('get-notification', 'DashboardController::getDashboardNotifications');
|
||||
$routes->get('acknowledge-notification/(:segment)', 'DashboardController::acknowledgeMessage/$1');
|
||||
$routes->get('get-pending-action', 'PendingActionsController::getPendingActions');
|
||||
|
||||
@ -191,105 +191,101 @@ class DashboardController extends AdminController
|
||||
|
||||
public function dashboard()
|
||||
{
|
||||
|
||||
$data = [];
|
||||
$roleId = get_role_id();
|
||||
$teams = user_team();
|
||||
|
||||
if (in_array(get_role_id(), [1, 2, 3, 5]) || (in_array(MANAGEMENT_TEAM_ID, user_team()) || in_array(FINANCE_TEAM_ID, user_team()) || in_array(BUSINESS_TEAM_ID, user_team()))) {
|
||||
$showPending = in_array($roleId, [1, 2, 3, 5]);
|
||||
$showClaims = ($roleId == STAFF_ROLE_ID && in_array(CLAIMS_TEAM_ID, $teams)) || in_array($roleId, [1, 5]);
|
||||
$showLeads = ($roleId == STAFF_ROLE_ID && in_array(ENROLLMENT_TEAM_ID, $teams)) || in_array($roleId, [1, 5]);
|
||||
|
||||
$db = db_connect();
|
||||
$sql = "SELECT
|
||||
clients.id AS client_id,
|
||||
clients.client_name,
|
||||
clients.short_name,
|
||||
client_branch.id AS client_branch_id,
|
||||
client_branch.branch_name,
|
||||
client_branch.branch_code,
|
||||
|
||||
COUNT(employees.id) AS total_employees,
|
||||
SUM(CASE WHEN employees.emp_status = 'draft' THEN 1 ELSE 0 END) AS draft_count,
|
||||
SUM(CASE WHEN employees.emp_status IN ('enrolled', 'active') THEN 1 ELSE 0 END) AS enrolled_count,
|
||||
|
||||
SUM(CASE WHEN auth_history.user_id IS NOT NULL THEN 1 ELSE 0 END) AS logged_in_count,
|
||||
SUM(CASE WHEN auth_history.user_id IS NULL THEN 1 ELSE 0 END) AS not_logged_in_count,
|
||||
|
||||
CASE
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM client_policy
|
||||
WHERE client_policy.client_branch_id = client_branch.id
|
||||
AND client_policy.is_active = 1
|
||||
AND client_policy.open_for_enrollment = 1
|
||||
) THEN 1
|
||||
ELSE 0
|
||||
END AS open_or_close_enrollment
|
||||
|
||||
FROM clients
|
||||
LEFT JOIN client_branch ON clients.id = client_branch.client_id
|
||||
LEFT JOIN employees ON client_branch.id = employees.client_branch_id
|
||||
LEFT JOIN (
|
||||
SELECT user_id, user_type
|
||||
FROM auth_history
|
||||
WHERE user_type = 'employee'
|
||||
GROUP BY user_id
|
||||
) AS auth_history ON employees.id = auth_history.user_id
|
||||
|
||||
WHERE employees.relationship = 'Self'
|
||||
AND employees.emp_status IN ('draft', 'enrolled', 'active')
|
||||
AND employees.is_active = 1
|
||||
AND clients.is_active = 1
|
||||
AND client_branch.is_active = 1
|
||||
|
||||
GROUP BY clients.id, client_branch.id";
|
||||
|
||||
$query = $db->query($sql);
|
||||
$results = $query->getResultArray();
|
||||
|
||||
$pendingActionsController = new PendingActionsController;
|
||||
$pendingActionsData = $pendingActionsController->getPendingActionsForDashBoard();
|
||||
|
||||
//BDS dashboard data
|
||||
// $businessTeamData = $this->policyTransactionModel->getBusinessReportList();
|
||||
// $financeTeamData = $this->policyTransactionModel->getFinanceReportList();
|
||||
// $businessTeamStatusData = $this->data_construct_for_bds($businessTeamData);
|
||||
// $financeTeamStatusData = $this->data_construct_for_bds($financeTeamData);
|
||||
$businessTeamData = [];
|
||||
$financeTeamData = [];
|
||||
$businessTeamStatusData = [];
|
||||
$financeTeamStatusData = [];
|
||||
|
||||
$data['client_branch_emp_list'] = $results;
|
||||
$session = \Config\Services::session();
|
||||
// $session->set('enrollment_data', json_encode($data));
|
||||
|
||||
$data['pendingActionsData'] = $pendingActionsData;
|
||||
$data['businessTeamCount'] = count($businessTeamData) ?? 0;
|
||||
$data['financeTeamCount'] = count($financeTeamData) ?? 0;
|
||||
$data['businessTeamStatusData'] = $businessTeamStatusData;
|
||||
$data['financeTeamStatusData'] = $financeTeamStatusData;
|
||||
$data['policyStatus'] = $this->policyStatus;
|
||||
$data['colorShades'] = $this->colorShades;
|
||||
if ($showPending) {
|
||||
$defaultPane = 'pending';
|
||||
} elseif ($showClaims) {
|
||||
$defaultPane = 'claims';
|
||||
} elseif ($showLeads) {
|
||||
$defaultPane = 'leads';
|
||||
} else {
|
||||
$defaultPane = null;
|
||||
}
|
||||
if ((get_role_id() == STAFF_ROLE_ID && in_array(CLAIMS_TEAM_ID,user_team())) || in_array(get_role_id(),[1,5])){
|
||||
|
||||
if ($showPending) {
|
||||
$pendingActionsController = new PendingActionsController();
|
||||
$data['pendingActionsData'] = $pendingActionsController->getPendingActionsForDashBoard();
|
||||
$data['businessTeamCount'] = 0;
|
||||
$data['financeTeamCount'] = 0;
|
||||
$data['businessTeamStatusData'] = [];
|
||||
$data['financeTeamStatusData'] = [];
|
||||
$data['policyStatus'] = $this->policyStatus;
|
||||
$data['colorShades'] = $this->colorShades;
|
||||
}
|
||||
|
||||
// Only the default tab loads with the page; other tabs fetch on click.
|
||||
$data['lazy_load_claims'] = $showClaims && $defaultPane !== 'claims';
|
||||
$data['lazy_load_leads'] = $showLeads && $defaultPane !== 'leads';
|
||||
|
||||
if ($showClaims && !$data['lazy_load_claims']) {
|
||||
$data['claim_data'] = $this->getClaimData();
|
||||
$data['colorShades'] = $this->colorShades;
|
||||
|
||||
$data['colorShades'] = $this->colorShades;
|
||||
}
|
||||
if ((get_role_id() == STAFF_ROLE_ID && in_array(ENROLLMENT_TEAM_ID,user_team())) || in_array(get_role_id(),[1,5])){
|
||||
|
||||
if ($showLeads && !$data['lazy_load_leads']) {
|
||||
$data['lead_data'] = $this->leadModel->getDashData();
|
||||
$data['bds_renewal'] = $this->policyTransactionModel->getBDSRenewalData();
|
||||
$data['colorShades'] = $this->colorShades;
|
||||
|
||||
$data['colorShades'] = $this->colorShades;
|
||||
}
|
||||
|
||||
// dd(get_role_id(),user_team());
|
||||
// dd($data);
|
||||
$data['tab_name'] = 'Dashboard';
|
||||
$data['page_name'] = 'Dashboard';
|
||||
|
||||
echo view('layout/header', $data);
|
||||
echo view('layout/header', $data);
|
||||
echo view('DashBoard', $data);
|
||||
echo view('layout/footer');
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML fragment for Claims dashboard tab (loaded on tab click).
|
||||
*/
|
||||
public function claimsDashFragment()
|
||||
{
|
||||
$roleId = get_role_id();
|
||||
$teams = user_team();
|
||||
$allowed = ($roleId == STAFF_ROLE_ID && in_array(CLAIMS_TEAM_ID, $teams)) || in_array($roleId, [1, 5]);
|
||||
if (!$allowed) {
|
||||
return $this->response->setStatusCode(403)->setBody('Forbidden');
|
||||
}
|
||||
|
||||
$data = [
|
||||
'claim_data' => $this->getClaimData(),
|
||||
'colorShades' => $this->colorShades,
|
||||
'dash_claims_pane_active' => 'active show',
|
||||
];
|
||||
|
||||
return $this->response->setBody(view('claims_dash', $data));
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML fragment for Leads / BDS Renewals dashboard tab (loaded on tab click).
|
||||
*/
|
||||
public function leadsDashFragment()
|
||||
{
|
||||
$roleId = get_role_id();
|
||||
$teams = user_team();
|
||||
$allowed = ($roleId == STAFF_ROLE_ID && in_array(ENROLLMENT_TEAM_ID, $teams)) || in_array($roleId, [1, 5]);
|
||||
if (!$allowed) {
|
||||
return $this->response->setStatusCode(403)->setBody('Forbidden');
|
||||
}
|
||||
|
||||
$data = [
|
||||
'lead_data' => $this->leadModel->getDashData(),
|
||||
'bds_renewal' => $this->policyTransactionModel->getBDSRenewalData(),
|
||||
'colorShades' => $this->colorShades,
|
||||
'dash_leads_pane_active' => 'active show',
|
||||
];
|
||||
|
||||
return $this->response->setBody(view('leads_dash', $data));
|
||||
}
|
||||
|
||||
|
||||
public function getClaimData()
|
||||
{
|
||||
|
||||
@ -97,115 +97,292 @@ class PendingActionsController extends AdminController
|
||||
return $data;
|
||||
}
|
||||
|
||||
//for only COUNT
|
||||
/**
|
||||
* Dashboard counts only — avoids loading full pending-action rowsets.
|
||||
* Cached briefly so repeated dashboard hits don't re-run heavy aggregations.
|
||||
*/
|
||||
public function getPendingActionsForDashBoard()
|
||||
{
|
||||
$tpa = $this->getPendingActionForTPAIDEmpty();
|
||||
$uhid = $this->getPendingActionForUHIDEmpty();
|
||||
$deletion = $this->getPendingActionForDeletion();
|
||||
$inception = $this->getPendingActionForInception();
|
||||
$ticketData = $this->getTicketsDataForDashBoard();
|
||||
$correction = $this->getPendingActionForCorrection();
|
||||
$si_enhancement = $this->getPendingActionForSIEnhancement();
|
||||
$PolicyRenewalData = $this->getPolicyRenewalDataForAllClient();
|
||||
|
||||
$uhid_export_count = [];
|
||||
$uhid_not_export_count = [];
|
||||
foreach ($uhid as $value) {
|
||||
if($value['batch_export_count'] == 1){
|
||||
$uhid_export_count[] = $value['batch_export_count'];
|
||||
}else{
|
||||
$uhid_not_export_count[] = $value['batch_export_count'];
|
||||
}
|
||||
}
|
||||
$tpa_export_count = [];
|
||||
$tpa_not_export_count = [];
|
||||
foreach ($tpa as $value) {
|
||||
if($value['batch_export_count'] == 1){
|
||||
$tpa_export_count[] = $value['batch_export_count'];
|
||||
}else{
|
||||
$tpa_not_export_count[] = $value['batch_export_count'];
|
||||
}
|
||||
}
|
||||
$deletion_export_count = [];
|
||||
$deletion_not_export_count = [];
|
||||
foreach ($deletion as $value) {
|
||||
if($value['batch_export_count'] == 1){
|
||||
$deletion_export_count[] = $value['batch_export_count'];
|
||||
}else{
|
||||
$deletion_not_export_count[] = $value['batch_export_count'];
|
||||
}
|
||||
}
|
||||
$correction_export_count = [];
|
||||
$correction_not_export_count = [];
|
||||
foreach ($correction as $value) {
|
||||
if($value['batch_export_count'] == 1){
|
||||
$correction_export_count[] = $value['batch_export_count'];
|
||||
}else{
|
||||
$correction_not_export_count[] = $value['batch_export_count'];
|
||||
}
|
||||
}
|
||||
$si_export_count = [];
|
||||
$si_not_export_count = [];
|
||||
foreach ($si_enhancement as $value) {
|
||||
if($value['batch_export_count'] == 1){
|
||||
$si_export_count[] = $value['batch_export_count'];
|
||||
}else{
|
||||
$si_not_export_count[] = $value['batch_export_count'];
|
||||
}
|
||||
$cache = \Config\Services::cache();
|
||||
$cacheKey = 'dashboard_pending_actions_counts_v2';
|
||||
$cached = $cache->get($cacheKey);
|
||||
if (is_array($cached)) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
// dd($uhid_export_count, $tpa_export_count ,$deletion_export_count, $correction_export_count, $si_export_count, $ticketData, $inception, $si_enhancement, $correction, $deletion, $tpa, $uhid, $PolicyRenewalData);
|
||||
|
||||
$inception = count($inception);
|
||||
$correction = count($correction);
|
||||
$si_enhancement = count($si_enhancement);
|
||||
$deletion = count($deletion);
|
||||
$tpa = count($tpa);
|
||||
$uhid = count($uhid);
|
||||
$PolicyRenewalData = count($PolicyRenewalData);
|
||||
$ticketData = count($ticketData);
|
||||
|
||||
$uhid_export_count = count($uhid_export_count);
|
||||
$tpa_export_count = count($tpa_export_count);
|
||||
$deletion_export_count = count($deletion_export_count);
|
||||
$correction_export_count = count($correction_export_count);
|
||||
$si_export_count = count($si_export_count);
|
||||
|
||||
$uhid_not_export_count = count($uhid_not_export_count);
|
||||
$tpa_not_export_count = count($tpa_not_export_count);
|
||||
$deletion_not_export_count = count($deletion_not_export_count);
|
||||
$correction_not_export_count = count($correction_not_export_count);
|
||||
$si_not_export_count = count($si_not_export_count);
|
||||
|
||||
|
||||
// dd($inception, $si_enhancement, $correction, $deletion, $tpa, $uhid, $PolicyRenewalData);
|
||||
$uhidCounts = $this->countPendingUhidForDashboard();
|
||||
$tpaCounts = $this->countPendingTpaForDashboard();
|
||||
$correctionCounts = $this->countPendingCorrectionForDashboard();
|
||||
$deletionCounts = $this->countPendingDeletionForDashboard();
|
||||
$siCounts = $this->countPendingSiForDashboard();
|
||||
|
||||
$data = [
|
||||
'inception' => $inception,
|
||||
'correction' => $correction,
|
||||
'si_enhancement' => $si_enhancement,
|
||||
'deletion' => $deletion,
|
||||
'tpa' => $tpa,
|
||||
'uhid' => $uhid,
|
||||
'PolicyRenewalData' => $PolicyRenewalData,
|
||||
'ticketData' => $ticketData,
|
||||
|
||||
'uhid_export_count' => $uhid_export_count,
|
||||
'tpa_export_count' => $tpa_export_count,
|
||||
'deletion_export_count' => $deletion_export_count,
|
||||
'correction_export_count' => $correction_export_count,
|
||||
'si_export_count' => $si_export_count,
|
||||
|
||||
'uhid_not_export_count' => $uhid_not_export_count,
|
||||
'tpa_not_export_count' => $tpa_not_export_count,
|
||||
'deletion_not_export_count' => $deletion_not_export_count,
|
||||
'correction_not_export_count' => $correction_not_export_count,
|
||||
'si_not_export_count' => $si_not_export_count,
|
||||
'inception' => $this->countPendingInceptionForDashboard(),
|
||||
'correction' => $correctionCounts['total'],
|
||||
'si_enhancement' => $siCounts['total'],
|
||||
'deletion' => $deletionCounts['total'],
|
||||
'tpa' => $tpaCounts['total'],
|
||||
'uhid' => $uhidCounts['total'],
|
||||
'PolicyRenewalData' => $this->countPolicyRenewalForDashboard(),
|
||||
'ticketData' => $this->countTicketsForDashboard(),
|
||||
'uhid_export_count' => $uhidCounts['export_count'],
|
||||
'tpa_export_count' => $tpaCounts['export_count'],
|
||||
'deletion_export_count' => $deletionCounts['export_count'],
|
||||
'correction_export_count' => $correctionCounts['export_count'],
|
||||
'si_export_count' => $siCounts['export_count'],
|
||||
'uhid_not_export_count' => $uhidCounts['not_export_count'],
|
||||
'tpa_not_export_count' => $tpaCounts['not_export_count'],
|
||||
'deletion_not_export_count' => $deletionCounts['not_export_count'],
|
||||
'correction_not_export_count' => $correctionCounts['not_export_count'],
|
||||
'si_not_export_count' => $siCounts['not_export_count'],
|
||||
];
|
||||
|
||||
$cache->save($cacheKey, $data, 60);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function countPendingInceptionForDashboard(): int
|
||||
{
|
||||
// NOT EXISTS avoids scanning employee_polices for every open policy via LEFT JOIN + HAVING.
|
||||
$sql = "
|
||||
SELECT COUNT(*) AS cnt
|
||||
FROM client_policy cp
|
||||
INNER JOIN clients ON cp.client_id = clients.id
|
||||
INNER JOIN client_branch cb ON cb.id = cp.client_branch_id
|
||||
INNER JOIN policy_type ON cp.policy_type_id = policy_type.id
|
||||
WHERE cp.is_active = 1
|
||||
AND cp.open_for_enrollment = 1
|
||||
AND cp.is_addon = 1
|
||||
AND cp.policy_status = 1
|
||||
AND cp.inception_type = 1
|
||||
AND cp.policy_type_id IN (1, 2, 3)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM employee_polices ep
|
||||
WHERE ep.client_policy_id = cp.id
|
||||
AND ep.is_active = 1
|
||||
)
|
||||
";
|
||||
|
||||
return (int) ($this->db->query($sql)->getRowArray()['cnt'] ?? 0);
|
||||
}
|
||||
|
||||
private function countPendingUhidForDashboard(): array
|
||||
{
|
||||
// Aggregate batch_files once, then join — correlated COUNT per policy was acceptable but JOIN scales better.
|
||||
$sql = "
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) = 1 THEN 1 ELSE 0 END) AS export_count,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) != 1 THEN 1 ELSE 0 END) AS not_export_count
|
||||
FROM (
|
||||
SELECT ep.client_policy_id
|
||||
FROM employee_polices ep
|
||||
INNER JOIN client_policy cp
|
||||
ON ep.client_policy_id = cp.id
|
||||
AND cp.is_active = 1
|
||||
AND cp.policy_status = 1
|
||||
INNER JOIN clients c ON c.id = cp.client_id
|
||||
INNER JOIN client_branch cb ON cb.id = cp.client_branch_id
|
||||
INNER JOIN policy_type ON policy_type.id = cp.policy_type_id
|
||||
WHERE ep.uhid IS NULL
|
||||
AND ep.status = 'active'
|
||||
AND ep.is_active = 1
|
||||
GROUP BY ep.client_policy_id
|
||||
) AS pending
|
||||
LEFT JOIN (
|
||||
SELECT client_policy_id, COUNT(*) AS export_cnt
|
||||
FROM batch_files
|
||||
WHERE actions = 'export'
|
||||
AND event_type = 'inception'
|
||||
AND insurer_or_tpa = 'insurer'
|
||||
GROUP BY client_policy_id
|
||||
) AS bf ON bf.client_policy_id = pending.client_policy_id
|
||||
";
|
||||
|
||||
return $this->normalizeExportCounts($this->db->query($sql)->getRowArray());
|
||||
}
|
||||
|
||||
private function countPendingTpaForDashboard(): array
|
||||
{
|
||||
$sql = "
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) = 1 THEN 1 ELSE 0 END) AS export_count,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) != 1 THEN 1 ELSE 0 END) AS not_export_count
|
||||
FROM (
|
||||
SELECT employee_polices.client_policy_id
|
||||
FROM employee_polices
|
||||
INNER JOIN client_policy
|
||||
ON employee_polices.client_policy_id = client_policy.id
|
||||
AND client_policy.is_active = 1
|
||||
AND client_policy.policy_status = 1
|
||||
INNER JOIN clients ON clients.id = client_policy.client_id
|
||||
INNER JOIN client_branch ON client_branch.id = client_policy.client_branch_id
|
||||
INNER JOIN policy_type ON policy_type.id = client_policy.policy_type_id
|
||||
WHERE employee_polices.tpa_id IS NULL
|
||||
AND employee_polices.uhid IS NOT NULL
|
||||
AND employee_polices.status = 'active'
|
||||
AND employee_polices.is_active = 1
|
||||
GROUP BY employee_polices.client_policy_id
|
||||
) AS pending
|
||||
LEFT JOIN (
|
||||
SELECT client_policy_id, COUNT(*) AS export_cnt
|
||||
FROM batch_files
|
||||
WHERE actions = 'export'
|
||||
AND event_type = 'inception'
|
||||
AND insurer_or_tpa = 'tpa'
|
||||
GROUP BY client_policy_id
|
||||
) AS bf ON bf.client_policy_id = pending.client_policy_id
|
||||
";
|
||||
|
||||
return $this->normalizeExportCounts($this->db->query($sql)->getRowArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Start from pending emp_endorsement rows — NOT from all clients with EXISTS
|
||||
* (EXISTS over every client was hanging for minutes on staging ~500k policies).
|
||||
*/
|
||||
private function countPendingCorrectionForDashboard(): array
|
||||
{
|
||||
$sql = "
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) = 1 THEN 1 ELSE 0 END) AS export_count,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) != 1 THEN 1 ELSE 0 END) AS not_export_count
|
||||
FROM (
|
||||
SELECT e.client_id
|
||||
FROM emp_endorsement ee
|
||||
INNER JOIN employees e
|
||||
ON ee.pk = e.id
|
||||
AND e.is_active = 1
|
||||
AND e.emp_status = 'active'
|
||||
WHERE ee.actions = 'c'
|
||||
AND ee.is_active = 1
|
||||
AND ee.status = 'pending'
|
||||
AND ee.endorsement_id IS NULL
|
||||
GROUP BY e.client_id
|
||||
) AS pending
|
||||
LEFT JOIN (
|
||||
SELECT client_id, COUNT(*) AS export_cnt
|
||||
FROM batch_files
|
||||
WHERE actions = 'export'
|
||||
AND event_type = 'correction'
|
||||
AND insurer_or_tpa = 'tpa'
|
||||
GROUP BY client_id
|
||||
) AS bf ON bf.client_id = pending.client_id
|
||||
";
|
||||
|
||||
return $this->normalizeExportCounts($this->db->query($sql)->getRowArray());
|
||||
}
|
||||
|
||||
private function countPendingDeletionForDashboard(): array
|
||||
{
|
||||
$sql = "
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) = 1 THEN 1 ELSE 0 END) AS export_count,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) != 1 THEN 1 ELSE 0 END) AS not_export_count
|
||||
FROM (
|
||||
SELECT cp.client_id
|
||||
FROM emp_endorsement ee
|
||||
INNER JOIN employee_polices ep
|
||||
ON ee.pk = ep.id
|
||||
AND ep.is_active = 1
|
||||
AND ep.status = 'active'
|
||||
INNER JOIN client_policy cp
|
||||
ON ep.client_policy_id = cp.id
|
||||
AND cp.is_active = 1
|
||||
AND cp.policy_status = 1
|
||||
WHERE ee.actions = 'd'
|
||||
AND ee.is_active = 1
|
||||
AND ee.status = 'pending'
|
||||
AND ee.endorsement_id IS NULL
|
||||
AND ee.table_name = 'employee_polices'
|
||||
GROUP BY cp.client_id
|
||||
) AS pending
|
||||
LEFT JOIN (
|
||||
SELECT client_id, COUNT(*) AS export_cnt
|
||||
FROM batch_files
|
||||
WHERE actions = 'export'
|
||||
AND event_type = 'deletion'
|
||||
AND insurer_or_tpa = 'insurer'
|
||||
GROUP BY client_id
|
||||
) AS bf ON bf.client_id = pending.client_id
|
||||
";
|
||||
|
||||
return $this->normalizeExportCounts($this->db->query($sql)->getRowArray());
|
||||
}
|
||||
|
||||
private function countPendingSiForDashboard(): array
|
||||
{
|
||||
$sql = "
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) = 1 THEN 1 ELSE 0 END) AS export_count,
|
||||
SUM(CASE WHEN COALESCE(bf.export_cnt, 0) != 1 THEN 1 ELSE 0 END) AS not_export_count
|
||||
FROM (
|
||||
SELECT cp.client_id
|
||||
FROM emp_endorsement ee
|
||||
INNER JOIN employee_polices ep
|
||||
ON ee.pk = ep.id
|
||||
AND ep.is_active = 1
|
||||
AND ep.status = 'active'
|
||||
INNER JOIN client_policy cp
|
||||
ON ep.client_policy_id = cp.id
|
||||
AND cp.is_active = 1
|
||||
AND cp.policy_status = 1
|
||||
WHERE ee.actions = 'si'
|
||||
AND ee.is_active = 1
|
||||
AND ee.status = 'pending'
|
||||
AND ee.endorsement_id IS NULL
|
||||
GROUP BY cp.client_id
|
||||
) AS pending
|
||||
LEFT JOIN (
|
||||
SELECT client_id, COUNT(*) AS export_cnt
|
||||
FROM batch_files
|
||||
WHERE actions = 'export'
|
||||
AND event_type = 'si_enhancement'
|
||||
AND insurer_or_tpa = 'tpa'
|
||||
GROUP BY client_id
|
||||
) AS bf ON bf.client_id = pending.client_id
|
||||
";
|
||||
|
||||
return $this->normalizeExportCounts($this->db->query($sql)->getRowArray());
|
||||
}
|
||||
|
||||
private function countPolicyRenewalForDashboard(): int
|
||||
{
|
||||
return (int) $this->clientPolicyModel
|
||||
->join('clients', 'clients.id = client_policy.client_id')
|
||||
->join('client_branch', 'client_branch.id = client_policy.client_branch_id')
|
||||
->where('client_policy.is_active', 1)
|
||||
->where('client_policy.policy_status', 0)
|
||||
->where('clients.is_active', 1)
|
||||
->where('client_branch.is_active', 1)
|
||||
->where('client_policy.policy_end_date < DATE_ADD(CURDATE(), INTERVAL 2 MONTH)', null, false)
|
||||
->countAllResults();
|
||||
}
|
||||
|
||||
private function countTicketsForDashboard(): int
|
||||
{
|
||||
return (int) $this->db->table('hdz_tickets')
|
||||
->join('hdz_status', 'hdz_status.id = hdz_tickets.status')
|
||||
->where('hdz_status.active', 1)
|
||||
->where('hdz_tickets.status !=', 5)
|
||||
->countAllResults();
|
||||
}
|
||||
|
||||
private function normalizeExportCounts(?array $row): array
|
||||
{
|
||||
return [
|
||||
'total' => (int) ($row['total'] ?? 0),
|
||||
'export_count' => (int) ($row['export_count'] ?? 0),
|
||||
'not_export_count' => (int) ($row['not_export_count'] ?? 0),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2186,42 +2186,44 @@
|
||||
// Increase GROUP_CONCAT limit
|
||||
$this->db->query("SET SESSION group_concat_max_len = 1000000;");
|
||||
|
||||
$builder = $this->db->table('policy_transaction pt');
|
||||
// NOT EXISTS avoids a self-join that balloons on large policy_transaction tables.
|
||||
$sql = "
|
||||
SELECT
|
||||
SUM(CASE WHEN pt.policy_end_date < CURDATE() THEN 1 ELSE 0 END) AS Expired,
|
||||
SUM(CASE WHEN pt.policy_end_date BETWEEN CURDATE() AND (CURDATE() + INTERVAL 1 MONTH) THEN 1 ELSE 0 END) AS `Renewal Pending`,
|
||||
GROUP_CONCAT(CASE WHEN pt.policy_end_date < CURDATE() THEN pt.id ELSE NULL END) AS Expired_ids,
|
||||
GROUP_CONCAT(CASE WHEN pt.policy_end_date BETWEEN CURDATE() AND (CURDATE() + INTERVAL 1 MONTH) THEN pt.id ELSE NULL END) AS Renewal_Pending_ids
|
||||
FROM policy_transaction pt
|
||||
WHERE pt.policy_end_date IS NOT NULL
|
||||
AND pt.is_active = 1
|
||||
AND (
|
||||
pt.policy_end_date < CURDATE()
|
||||
OR pt.policy_end_date BETWEEN CURDATE() AND (CURDATE() + INTERVAL 1 MONTH)
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM policy_transaction renewed
|
||||
WHERE renewed.source_client_policy_id = pt.client_policy_id
|
||||
AND renewed.client_id = pt.client_id
|
||||
AND renewed.client_branch_id = pt.client_branch_id
|
||||
)
|
||||
";
|
||||
|
||||
$builder->select([
|
||||
'SUM(CASE WHEN pt.policy_end_date < CURDATE() THEN 1 ELSE 0 END) AS Expired',
|
||||
'SUM(CASE WHEN pt.policy_end_date BETWEEN CURDATE() AND (CURDATE() + INTERVAL 1 MONTH) THEN 1 ELSE 0 END) AS `Renewal Pending`',
|
||||
'GROUP_CONCAT(CASE WHEN pt.policy_end_date < CURDATE() THEN pt.id ELSE NULL END) AS Expired_ids',
|
||||
'GROUP_CONCAT(CASE WHEN pt.policy_end_date BETWEEN CURDATE() AND (CURDATE() + INTERVAL 1 MONTH) THEN pt.id ELSE NULL END) AS Renewal_Pending_ids'
|
||||
]);
|
||||
$builder->where("pt.policy_end_date IS NOT NULL", null, false);
|
||||
$builder->where('pt.is_active', 1);
|
||||
$result = $this->db->query($sql)->getResultArray();
|
||||
$row = $result[0] ?? [
|
||||
'Expired' => 0,
|
||||
'Renewal Pending' => 0,
|
||||
'Expired_ids' => null,
|
||||
'Renewal_Pending_ids' => null,
|
||||
];
|
||||
|
||||
// Self join to check if a policy has been renewed
|
||||
$builder->join('policy_transaction renewed', 'renewed.source_client_policy_id = pt.client_policy_id and renewed.client_id = pt.client_id and renewed.client_branch_id = pt.client_branch_id', 'left');
|
||||
$total = (int) ($row['Expired'] ?? 0) + (int) ($row['Renewal Pending'] ?? 0);
|
||||
|
||||
// Filter for expired or expiring policies
|
||||
$builder->where("(pt.policy_end_date < CURDATE() OR pt.policy_end_date BETWEEN CURDATE() AND (CURDATE() + INTERVAL 1 MONTH))", null, false);
|
||||
$row['Expired_ids'] = $row['Expired_ids'] ?: [];
|
||||
$row['Renewal Pending_ids'] = $row['Renewal_Pending_ids'] ?: [];
|
||||
$row['total'] = $total;
|
||||
|
||||
$builder->where('renewed.id IS NULL', null, false);
|
||||
$query = $builder->get();
|
||||
$result = $query->getResultArray();
|
||||
|
||||
$total = 0;
|
||||
foreach ($result[0] as $key => $value) {
|
||||
if ($key !== 'Expired_ids' && $key !== 'Renewal_Pending_ids') {
|
||||
$total += $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure ID fields are arrays (not null)
|
||||
$result[0]['Expired_ids'] = $result[0]['Expired_ids'] ? $result[0]['Expired_ids'] : [];
|
||||
$result[0]['Renewal Pending_ids'] = $result[0]['Renewal_Pending_ids'] ? $result[0]['Renewal_Pending_ids'] : [];
|
||||
|
||||
// Add total count
|
||||
$result[0]['total'] = $total;
|
||||
|
||||
return $result[0];
|
||||
return $row;
|
||||
}
|
||||
|
||||
public function reportBDSNew(
|
||||
|
||||
@ -878,25 +878,37 @@ class TicketMasterModel extends Model
|
||||
public function getDashData($claim_statuses, $limit)
|
||||
{
|
||||
$finalResults = [];
|
||||
if (empty($claim_statuses)) {
|
||||
return $finalResults;
|
||||
}
|
||||
|
||||
foreach ($claim_statuses as $typeId => $statuses) {
|
||||
// Get all active, non-null claim status tickets for this type
|
||||
$builder = $this->db->table('ticket_master tm')
|
||||
->select('tm.id, tm.ticket_type_id, tcs.claim_status, th.last_claim_status_change')
|
||||
->join('ticket_claim_status tcs', 'tm.claim_status_id = tcs.id', 'left')
|
||||
->join(
|
||||
'(SELECT ticket_id, MAX(created_at) AS last_claim_status_change
|
||||
$typeIds = array_map('intval', array_keys($claim_statuses));
|
||||
|
||||
// One history aggregate + one ticket pull for all types (was 4 full scans).
|
||||
$builder = $this->db->table('ticket_master tm')
|
||||
->select('tm.id, tm.ticket_type_id, tcs.claim_status, th.last_claim_status_change')
|
||||
->join('ticket_claim_status tcs', 'tm.claim_status_id = tcs.id', 'left')
|
||||
->join(
|
||||
'(SELECT ticket_id, MAX(created_at) AS last_claim_status_change
|
||||
FROM ticket_history
|
||||
WHERE field_name = \'claim_status_id\'
|
||||
GROUP BY ticket_id) th',
|
||||
'tm.id = th.ticket_id',
|
||||
'left'
|
||||
)
|
||||
->where('tm.ticket_type_id', $typeId)
|
||||
->where('tm.is_active', 1)
|
||||
->where('tm.claim_status_id IS NOT NULL');
|
||||
'tm.id = th.ticket_id',
|
||||
'left'
|
||||
)
|
||||
->whereIn('tm.ticket_type_id', $typeIds)
|
||||
->where('tm.is_active', 1)
|
||||
->where('tm.claim_status_id IS NOT NULL');
|
||||
|
||||
$results = $builder->get()->getResultArray();
|
||||
$allRows = $builder->get()->getResultArray();
|
||||
|
||||
$rowsByType = [];
|
||||
foreach ($allRows as $row) {
|
||||
$rowsByType[$row['ticket_type_id']][] = $row;
|
||||
}
|
||||
|
||||
foreach ($claim_statuses as $typeId => $statuses) {
|
||||
$results = $rowsByType[$typeId] ?? [];
|
||||
|
||||
$summary = [
|
||||
'ticket_type_id' => $typeId,
|
||||
@ -912,7 +924,6 @@ class TicketMasterModel extends Model
|
||||
$threshold = date('Y-m-d H:i:s', strtotime("-{$dateLimit} days"));
|
||||
|
||||
$ticketIds = [];
|
||||
// dd($results);
|
||||
foreach ($results as $row) {
|
||||
if (
|
||||
$row['claim_status'] === $status &&
|
||||
@ -928,17 +939,14 @@ class TicketMasterModel extends Model
|
||||
}
|
||||
|
||||
$total++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Convert ticket IDs array to a comma-separated string
|
||||
$summary[$alias . '_ids'] = implode(',', $ticketIds);
|
||||
}
|
||||
|
||||
$summary['total'] = $total;
|
||||
|
||||
// Add approved but not settled IDs and count
|
||||
$approvedNotSettled = $this->getNotSettledbutApprovedCount($typeId);
|
||||
$summary['approved_not_settled'] = $approvedNotSettled['count'];
|
||||
$summary['approved_not_settled_ids'] = $approvedNotSettled['ticket_ids'];
|
||||
@ -946,7 +954,6 @@ class TicketMasterModel extends Model
|
||||
$finalResults[$typeId] = $summary;
|
||||
}
|
||||
|
||||
// dd($finalResults);
|
||||
return $finalResults;
|
||||
}
|
||||
|
||||
|
||||
@ -259,7 +259,7 @@
|
||||
// $isActive = get_role_id() == STAFF_ROLE_ID && in_array(ENROLLMENT_TEAM_ID,user_team()) ? 'active show' : '';
|
||||
?> -->
|
||||
<li class="nav-item d-flex justify-content-center align-items-center ">
|
||||
<a href="#leads-dash-tab " data-toggle="tab" aria-expanded="true" class="nav-link px-3 py-1 dash-anchor nav-dash" id="leads_tab" >
|
||||
<a href="#leads-dash-tab" data-toggle="tab" aria-expanded="true" class="nav-link px-3 py-1 dash-anchor nav-dash" id="leads_tab" >
|
||||
<img src="<?= base_url() . "public"; ?>/assets/images/inactive_leads_and_bds_renewal.png" alt="Logo" height="14" class="inactive_leads">
|
||||
<img src="<?= base_url() . "public"; ?>/assets/images/active_leads_and_bds_renewal.png" alt="Logo" height="14"
|
||||
class="active_leads " style="display:none;">
|
||||
@ -277,14 +277,28 @@
|
||||
<div class="tab-content tab-content-styles">
|
||||
|
||||
<?php if ((get_role_id() == STAFF_ROLE_ID && in_array(CLAIMS_TEAM_ID,user_team())) || in_array(get_role_id(),[1,5])) :?>
|
||||
<?php include("claims_dash.php") ?>
|
||||
<?php if (!empty($lazy_load_claims)) : ?>
|
||||
<div class="tab-pane fade <?= $dash_claims_pane_active ?>" id="claims-dash-tab"
|
||||
data-dash-lazy-url="<?= esc(base_url('dashboard/claims-dash'), 'attr') ?>">
|
||||
<div class="text-center p-5 text-muted dash-lazy-placeholder">Click to load claims…</div>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<?php include("claims_dash.php") ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(in_array(get_role_id(), [1,2,3,5]) || (get_role_id() == 4 && in_array(MANAGEMENT_TEAM_ID, user_team()) || in_array(FINANCE_TEAM_ID, user_team()) || in_array(BUSINESS_TEAM_ID, user_team()))) { ?>
|
||||
<!-- <?php //include('bds_dash.php'); ?> -->
|
||||
<?php } ?>
|
||||
<?php if ((get_role_id() == STAFF_ROLE_ID && in_array(ENROLLMENT_TEAM_ID,user_team())) || in_array(get_role_id(),[1,5])) :?>
|
||||
<?php include("leads_dash.php") ?>
|
||||
<?php if (!empty($lazy_load_leads)) : ?>
|
||||
<div class="tab-pane fade <?= $dash_leads_pane_active ?>" id="leads-dash-tab"
|
||||
data-dash-lazy-url="<?= esc(base_url('dashboard/leads-dash'), 'attr') ?>">
|
||||
<div class="text-center p-5 text-muted dash-lazy-placeholder">Click to load opportunities…</div>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<?php include("leads_dash.php") ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(in_array(get_role_id(), [1,2,3,5])) { ?>
|
||||
@ -307,6 +321,64 @@
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
function injectDashTabHtml($pane, html) {
|
||||
var nodes = $.parseHTML(html, document, true) || [];
|
||||
var $nodes = $(nodes);
|
||||
var styles = $nodes.filter('style').add($nodes.find('style'));
|
||||
styles.each(function () {
|
||||
var css = this.textContent || '';
|
||||
if (css && !$('style[data-dash-lazy-css="' + $pane.attr('id') + '"]').length) {
|
||||
$('<style>', { 'data-dash-lazy-css': $pane.attr('id'), text: css }).appendTo('head');
|
||||
}
|
||||
});
|
||||
var $newPane = $nodes.filter('.tab-pane').add($nodes.find('.tab-pane')).first();
|
||||
var innerHtml = $newPane.length ? $newPane.html() : html;
|
||||
$pane
|
||||
.removeAttr('data-dash-lazy-url')
|
||||
.html(innerHtml)
|
||||
.addClass('active show');
|
||||
}
|
||||
|
||||
function loadDashTabOnDemand($pane) {
|
||||
var url = $pane.attr('data-dash-lazy-url');
|
||||
if (!url || $pane.data('dash-lazy-loading')) {
|
||||
return;
|
||||
}
|
||||
$pane.data('dash-lazy-loading', true);
|
||||
$pane.html('<div class="text-center p-5 text-muted dash-lazy-placeholder">Loading…</div>');
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
method: 'GET',
|
||||
dataType: 'html',
|
||||
timeout: 120000
|
||||
}).done(function (html) {
|
||||
injectDashTabHtml($pane, html);
|
||||
}).fail(function (xhr) {
|
||||
$pane.data('dash-lazy-loading', false);
|
||||
$pane.attr('data-dash-lazy-url', url);
|
||||
var msg = 'Failed to load (' + (xhr.status || 'timeout') + '). Click the tab again to retry.';
|
||||
$pane.html('<div class="text-center p-5 text-danger dash-lazy-placeholder">' + msg + '</div>');
|
||||
});
|
||||
}
|
||||
|
||||
// Load tab data when the user clicks Claims / Opportunities.
|
||||
$(document).on('click', '#claims_tab, #leads_tab', function () {
|
||||
var target = ($(this).attr('href') || '').trim();
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
var $pane = $(target);
|
||||
if ($pane.length && $pane.attr('data-dash-lazy-url')) {
|
||||
loadDashTabOnDemand($pane);
|
||||
}
|
||||
});
|
||||
|
||||
// If Claims/Leads is the default visible pane, load it once after paint.
|
||||
$('.tab-pane.active[data-dash-lazy-url]').each(function () {
|
||||
loadDashTabOnDemand($(this));
|
||||
});
|
||||
|
||||
$('.nav-link').click(function(){
|
||||
|
||||
//image of tabs by default inactive before particular click
|
||||
|
||||
@ -197,12 +197,9 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row d-flex align-items-center">
|
||||
<div class="goBack" style="padding-left: 25px;">
|
||||
<a href="#" onclick="hideAndShowTile('2')" ><b><i class="mdi mdi-chevron-left mdi-36px chevron-left-dash"></i></b> </a>
|
||||
</div>
|
||||
<div class="goBack" style="display: none;padding-left: 15px;">
|
||||
<a href="#" id="current_tile">Current Tile : </a>
|
||||
<div class="row d-flex align-items-center">
|
||||
<div class="goBack" style="display: none; padding-left: 25px;">
|
||||
<a href="#" onclick="hideAndShowTile('2')" title="Back"><b><i class="mdi mdi-chevron-left mdi-36px chevron-left-dash"></i></b></a>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
@ -317,16 +314,6 @@
|
||||
|
||||
$('.claimTypeTile').hide();
|
||||
$('.claimStatusTitle_'+claimType).show();
|
||||
|
||||
if (claimType == 1) {
|
||||
$('#current_tile').text(" GMC");
|
||||
} else if (claimType == 2) {
|
||||
$('#current_tile').text(" GPA");
|
||||
} else if (claimType == 3) {
|
||||
$('#current_tile').text(" EDLI");
|
||||
} else if (claimType == 4) {
|
||||
$('#current_tile').text(" GTLI");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -188,12 +188,9 @@
|
||||
|
||||
|
||||
|
||||
<div class="row d-flex align-items-center">
|
||||
<div class="status_tile" style="padding-left: 25px;">
|
||||
<a href="#" onclick="hide_and_show_tile('2')" ><b><i class="mdi mdi-chevron-left mdi-36px chevron-left-dash"></i></b> </a>
|
||||
</div>
|
||||
<div class="status_tile" style="padding-left: 15px;">
|
||||
<a href="#" id="main_tile">Current Tile : </a>
|
||||
<div class="row d-flex align-items-center">
|
||||
<div class="status_tile" style="display: none; padding-left: 25px;">
|
||||
<a href="#" onclick="hide_and_show_tile('2')" title="Back"><b><i class="mdi mdi-chevron-left mdi-36px chevron-left-dash"></i></b></a>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
@ -344,13 +341,9 @@
|
||||
|
||||
if (type == 1 && leadType != null && leadType == 1) {
|
||||
$('.leadStatusTitle_1').show();
|
||||
$('#main_tile').text("Opportunities");
|
||||
|
||||
}
|
||||
if (type == 1 && leadType != null && leadType == 2) {
|
||||
$('.leadStatusTitle_2').show();
|
||||
$("#main_tile").text(" BDS Renewals");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user