2091 lines
63 KiB
PHP
2091 lines
63 KiB
PHP
<?php
|
|
namespace App\Models;
|
|
|
|
use CodeIgniter\Model;
|
|
|
|
/**
|
|
* Claims Collection V2 dashboard KPIs (from metabase_raw_queries.csv).
|
|
* Each Metabase question maps to one public method.
|
|
*/
|
|
class ClaimsCollectionV2DashboardModel extends Model
|
|
{
|
|
protected $DBGroup = 'default';
|
|
|
|
/**
|
|
* Metabase question id => PHP method name.
|
|
*/
|
|
public const KPI_MAP = [
|
|
181 => 'policy_exposure_summary',
|
|
185 => 'premium_as_on_date',
|
|
186 => 'claims_experience_summary',
|
|
190 => 'claim_amount_by_gender',
|
|
191 => 'age_band',
|
|
194 => 'top_5_hospitals_by_incurred_amount',
|
|
197 => 'claims_incidence_rate',
|
|
198 => 'policy_start_date',
|
|
199 => 'policy_end_date',
|
|
200 => 'insurer',
|
|
201 => 'tpa',
|
|
203 => 'earned_premium',
|
|
204 => 'total_claims',
|
|
206 => 'incurred_amount',
|
|
207 => 'incurred_ratio',
|
|
208 => 'projected_claims',
|
|
209 => 'projected_ratio',
|
|
213 => 'total_reimbursement_amount',
|
|
214 => 'total_reimbursement_amt_pct',
|
|
215 => 'cashless_claim_amt',
|
|
216 => 'cashless_claim_amt_pct',
|
|
217 => 'total_incurred_by_city',
|
|
219 => 'claim_amount_by_claim_status',
|
|
220 => 'hospitals_in_detail',
|
|
221 => 'hospital_city_wise_si_limit_pregnancy',
|
|
224 => 's_pregnancy_normal_delivery_exceeded_amt',
|
|
225 => 's_pregnancy_c_sec_avg_exceeded_amt',
|
|
228 => 'cataract_exceeded_claim_amount',
|
|
229 => 'cataract_avg_exceeded_amount',
|
|
230 => 'hospital_city_wise_si_limit_cataract',
|
|
231 => 'total_incurred_by_cliam_status',
|
|
];
|
|
|
|
/**
|
|
* Human-readable KPI labels (Metabase name).
|
|
*/
|
|
public const KPI_LABELS = [
|
|
'policy_exposure_summary' => 'POLICY & EXPOSURE SUMMARY',
|
|
'premium_as_on_date' => 'PREMIUM AS ON DATE',
|
|
'claims_experience_summary' => 'CLAIMS EXPERIENCE SUMMARY',
|
|
'claim_amount_by_gender' => 'Claim Amount by Gender',
|
|
'age_band' => 'Age Band',
|
|
'top_5_hospitals_by_incurred_amount' => 'Top 5 Hospitals by Incurred amount',
|
|
'claims_incidence_rate' => 'Claims Incidence Rate',
|
|
'policy_start_date' => 'Policy Start Date',
|
|
'policy_end_date' => 'Policy End Date',
|
|
'insurer' => 'Insurer',
|
|
'tpa' => 'TPA',
|
|
'earned_premium' => 'Earned Premium',
|
|
'total_claims' => 'Total Claims',
|
|
'incurred_amount' => 'Incurred Amount',
|
|
'incurred_ratio' => 'Incurred Ratio',
|
|
'projected_claims' => 'Projected Claims',
|
|
'projected_ratio' => 'Projected Ratio',
|
|
'total_reimbursement_amount' => 'Total Reimbursement Amount',
|
|
'total_reimbursement_amt_pct' => 'Total Reimbursement Amt %',
|
|
'cashless_claim_amt' => 'Cashless Claim Amt',
|
|
'cashless_claim_amt_pct' => 'Cashless Claim Amt %',
|
|
'total_incurred_by_city' => 'Total Incurred by city',
|
|
'claim_amount_by_claim_status' => 'Claim Amount by Claim Status',
|
|
'hospitals_in_detail' => 'Hospitals in detail',
|
|
'hospital_city_wise_si_limit_pregnancy' => 'Hospital city wise SI Limit - Pregnancy',
|
|
's_pregnancy_normal_delivery_exceeded_amt' => 'S-PREGNANCY - NORMAL DELIVERY Exceeded Amt',
|
|
's_pregnancy_c_sec_avg_exceeded_amt' => 'S-Pregnancy C-Sec avg exceeded amt',
|
|
'cataract_exceeded_claim_amount' => 'Cataract exceeded claim amount',
|
|
'cataract_avg_exceeded_amount' => 'Cataract avg exceeded amount',
|
|
'hospital_city_wise_si_limit_cataract' => 'Hospital city wise SI Limit - Cataract',
|
|
'total_incurred_by_cliam_status' => 'Total Incurred by Cliam Status ',
|
|
];
|
|
|
|
protected function runKpiQuery(string $sql, int $policyId): array
|
|
{
|
|
// Metabase export may contain literal \t / \n in CSV — normalize for MySQL.
|
|
$sql = str_replace(['\\t', '\\n', '\\r'], ["\t", "\n", "\r"], $sql);
|
|
|
|
$db = \Config\Database::connect($this->DBGroup);
|
|
$query = $db->query($sql, ['policy_id' => $policyId]);
|
|
|
|
return $query->getResultArray();
|
|
}
|
|
|
|
public function getKpi(string $method, int $policyId): array
|
|
{
|
|
if (!method_exists($this, $method)) {
|
|
return [];
|
|
}
|
|
return $this->{$method}($policyId);
|
|
}
|
|
|
|
public function getAllKpis(int $policyId): array
|
|
{
|
|
$out = [];
|
|
foreach (self::KPI_MAP as $id => $method) {
|
|
$out[$method] = [
|
|
'id' => (int) $id,
|
|
'label' => self::KPI_LABELS[$method] ?? $method,
|
|
'rows' => $this->getKpi($method, $policyId),
|
|
];
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
/** Metabase #181: POLICY & EXPOSURE SUMMARY */
|
|
public function policy_exposure_summary(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
cp.policy_start_date,
|
|
cp.policy_end_date,
|
|
i.name AS insurer_name,
|
|
t.name AS tpa_name
|
|
FROM client_policy cp
|
|
LEFT JOIN insurers i ON i.id = cp.insurer_id
|
|
LEFT JOIN tpa t ON t.id = cp.tpa_id
|
|
WHERE cp.id = :policy_id:
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #185: PREMIUM AS ON DATE */
|
|
public function premium_as_on_date(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
CONCAT('💰 ', FORMAT(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN LOWER(e.change_event) = '%inception%'
|
|
THEN ep.rata_premimum
|
|
WHEN LOWER(e.change_event) NOT LIKE '%inception%'
|
|
AND (ep.date_of_exit IS NULL OR ep.date_of_exit = '')
|
|
THEN ep.rata_premimum
|
|
WHEN ep.date_of_exit IS NOT NULL
|
|
AND ep.date_of_exit != ''
|
|
AND ep.claim_status = 0
|
|
THEN -ep.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
, 0)) AS premium_as_on_date
|
|
|
|
FROM employee_polices ep
|
|
JOIN employees e ON e.id = ep.employee_id
|
|
WHERE ep.client_policy_id = :policy_id:
|
|
AND ep.is_active = 1;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #186: CLAIMS EXPERIENCE SUMMARY */
|
|
public function claims_experience_summary(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
/* run days */
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
) AS run_days,
|
|
|
|
/* earned premium */
|
|
FORMAT(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) AS earned_premium,
|
|
|
|
/* claims reported */
|
|
FORMAT(COUNT(tm.id), 0) AS claims_reported,
|
|
\t\t/* incurred claims count */
|
|
\tFORMAT(
|
|
\t SUM(
|
|
\t CASE
|
|
\t WHEN tcs.claim_status IN ('Settled', 'Paid') THEN 1
|
|
\t WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied') THEN 1
|
|
\t ELSE 0
|
|
\t END
|
|
\t )
|
|
, 0) AS incurred_claims,
|
|
|
|
/* incurred amount */
|
|
FORMAT(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
, 0) AS incurred_amount,
|
|
|
|
/* incurred ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) * 100
|
|
, 2)
|
|
, '%') AS incurred_ratio,
|
|
|
|
/* rejection rate */
|
|
CONCAT(
|
|
ROUND(
|
|
SUM(CASE WHEN tcs.claim_status IN ('Rejected', 'Denied') THEN 1 ELSE 0 END)
|
|
/ NULLIF(COUNT(tm.id), 0) * 100
|
|
, 2)
|
|
, '%') AS rejection_rate,
|
|
|
|
/* projected claims */
|
|
FORMAT(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
, 0) AS projected_claims,
|
|
|
|
/* projected ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
)
|
|
/ NULLIF(prem.premium_as_on_date, 0) * 100
|
|
, 2)
|
|
, '%') AS projected_ratio
|
|
|
|
FROM client_policy cp
|
|
|
|
JOIN (
|
|
SELECT
|
|
ep2.client_policy_id,
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN e2.change_event = 'inception'
|
|
THEN ep2.rata_premimum
|
|
WHEN e2.change_event != 'inception'
|
|
AND (ep2.date_of_exit IS NULL OR ep2.date_of_exit = '')
|
|
THEN ep2.rata_premimum
|
|
WHEN ep2.date_of_exit IS NOT NULL
|
|
AND ep2.date_of_exit != ''
|
|
AND ep2.claim_status = 0
|
|
THEN -ep2.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0) AS premium_as_on_date
|
|
FROM employee_polices ep2
|
|
JOIN employees e2 ON e2.id = ep2.employee_id
|
|
WHERE ep2.client_policy_id = :policy_id:
|
|
AND ep2.is_active = 1
|
|
GROUP BY ep2.client_policy_id
|
|
) prem ON prem.client_policy_id = cp.id
|
|
|
|
JOIN ticket_master tm
|
|
ON tm.client_policy_id = cp.id
|
|
AND tm.is_active = 1
|
|
|
|
JOIN ticket_claim_status tcs
|
|
ON tcs.id = tm.claim_status_id
|
|
|
|
WHERE cp.id = :policy_id:
|
|
|
|
GROUP BY cp.id, cp.policy_start_date, prem.premium_as_on_date;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #190: Claim Amount by Gender */
|
|
public function claim_amount_by_gender(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(e.gender, 'Unknown') AS gender,
|
|
COUNT(tm.id) AS claim_count,
|
|
CONCAT(ROUND(COUNT(tm.id) / totals.total_count * 100, 2), '%')
|
|
AS count_pct,
|
|
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
AS claim_value,
|
|
CONCAT(ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(totals.total_value, 0) * 100
|
|
, 2), '%') AS value_pct
|
|
FROM ticket_master tm
|
|
JOIN employees e ON e.id = tm.emp_id
|
|
JOIN (
|
|
SELECT
|
|
COUNT(id) AS total_count,
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id: AND is_active = 1
|
|
) totals ON 1=1
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
GROUP BY e.gender, totals.total_count, totals.total_value
|
|
ORDER BY claim_count DESC;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #191: Age Band */
|
|
public function age_band(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
WITH age_slabs AS (
|
|
SELECT '0-18' AS age_band, 0 AS min_age, 18 AS max_age UNION ALL
|
|
SELECT '19-25', 19, 25 UNION ALL
|
|
SELECT '26-35', 26, 35 UNION ALL
|
|
SELECT '36-45', 36, 45 UNION ALL
|
|
SELECT '46-55', 46, 55 UNION ALL
|
|
SELECT '56-65', 56, 65 UNION ALL
|
|
SELECT '66-75', 66, 75 UNION ALL
|
|
SELECT '75+', 76, 200
|
|
),
|
|
|
|
base AS (
|
|
SELECT
|
|
TIMESTAMPDIFF(YEAR, e.dob, cp.policy_end_date) AS age,
|
|
tm.claim_amount
|
|
FROM ticket_master tm
|
|
JOIN employees e ON e.id = tm.insured_emp_id
|
|
\tJOIN client_policy cp ON tm.client_policy_id = cp.id
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
),
|
|
|
|
totals AS (
|
|
SELECT
|
|
COUNT(*) AS total_count,
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
)
|
|
|
|
SELECT
|
|
s.age_band,
|
|
|
|
COUNT(b.age) AS claim_count,
|
|
|
|
ROUND(COUNT(b.age) / NULLIF(t.total_count, 0) * 100, 2) AS count_pct,
|
|
|
|
COALESCE(SUM(CAST(NULLIF(b.claim_amount, '') AS DECIMAL(15,2))), 0) AS claim_value,
|
|
|
|
ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(b.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(t.total_value, 0) * 100
|
|
, 2) AS value_pct
|
|
|
|
FROM age_slabs s
|
|
|
|
LEFT JOIN base b
|
|
ON b.age BETWEEN s.min_age AND s.max_age
|
|
|
|
CROSS JOIN totals t
|
|
|
|
GROUP BY s.age_band, s.min_age, t.total_count, t.total_value
|
|
|
|
ORDER BY s.min_age;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #194: Top 5 Hospitals by Incurred amount */
|
|
public function top_5_hospitals_by_incurred_amount(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(tm.hospital_name, 'Not Specified') AS hospital_name,
|
|
COALESCE(tm.hospital_city, '-') AS hospital_city,
|
|
COALESCE(tm.hospital_state, '-') AS hospital_state,
|
|
|
|
COUNT(tm.id) AS claim_count,
|
|
|
|
ROUND(
|
|
COUNT(tm.id) / totals.total_count * 100,
|
|
2
|
|
) AS count_pct,
|
|
|
|
COALESCE(
|
|
SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))),
|
|
0
|
|
) AS claim_value,
|
|
|
|
ROUND(
|
|
COALESCE(
|
|
SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))),
|
|
0
|
|
) / NULLIF(totals.total_value, 0) * 100,
|
|
2
|
|
) AS value_pct
|
|
|
|
FROM ticket_master tm
|
|
|
|
JOIN (
|
|
SELECT
|
|
COUNT(id) AS total_count,
|
|
|
|
COALESCE(
|
|
SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))),
|
|
0
|
|
) AS total_value
|
|
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
) totals ON 1=1
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND tm.hospital_name IS NOT NULL
|
|
|
|
GROUP BY
|
|
tm.hospital_name,
|
|
tm.hospital_city,
|
|
tm.hospital_state,
|
|
totals.total_count,
|
|
totals.total_value
|
|
|
|
ORDER BY claim_count DESC
|
|
|
|
LIMIT 5;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #197: Claims Incidence Rate */
|
|
public function claims_incidence_rate(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
CONCAT(
|
|
ROUND(
|
|
COUNT(tm.id) / NULLIF(lives.current_lives, 0) * 100
|
|
, 2)
|
|
, '%') AS claims_incidence_rate
|
|
FROM ticket_master tm
|
|
JOIN (
|
|
SELECT COUNT(DISTINCT ep.employee_id) AS current_lives
|
|
FROM employee_polices ep
|
|
JOIN employees e ON e.id = ep.employee_id
|
|
WHERE ep.client_policy_id = :policy_id:
|
|
AND ep.status = 'active'
|
|
AND ep.is_active = 1
|
|
AND e.emp_status = 'active'
|
|
AND e.is_active = 1
|
|
) lives ON 1=1
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #198: Policy Start Date */
|
|
public function policy_start_date(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
CONCAT(DATE_FORMAT(cp.policy_start_date, '%d %b, %Y'), ' 📅') AS policy_start_date,
|
|
-- cp.policy_start_date,
|
|
cp.policy_end_date,
|
|
i.name AS insurer_name,
|
|
t.name AS tpa_name
|
|
FROM client_policy cp
|
|
LEFT JOIN insurers i ON i.id = cp.insurer_id
|
|
LEFT JOIN tpa t ON t.id = cp.tpa_id
|
|
WHERE cp.id = :policy_id:
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #199: Policy End Date */
|
|
public function policy_end_date(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
cp.policy_start_date,CONCAT(DATE_FORMAT(cp.policy_end_date, '%d %b, %Y'), ' 📅') AS policy_end_date,
|
|
-- cp.policy_end_date,
|
|
i.name AS insurer_name,
|
|
t.name AS tpa_name
|
|
FROM client_policy cp
|
|
LEFT JOIN insurers i ON i.id = cp.insurer_id
|
|
LEFT JOIN tpa t ON t.id = cp.tpa_id
|
|
WHERE cp.id = :policy_id:
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #200: Insurer */
|
|
public function insurer(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
cp.policy_start_date,
|
|
cp.policy_end_date,
|
|
i.name AS insurer_name,
|
|
t.short_name AS tpa_name
|
|
FROM client_policy cp
|
|
LEFT JOIN insurers i ON i.id = cp.insurer_id
|
|
LEFT JOIN tpa t ON t.id = cp.tpa_id
|
|
WHERE cp.id = :policy_id:
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #201: TPA */
|
|
public function tpa(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
cp.policy_start_date,
|
|
cp.policy_end_date,
|
|
i.name AS insurer_name,
|
|
t.name AS tpa_name
|
|
FROM client_policy cp
|
|
LEFT JOIN insurers i ON i.id = cp.insurer_id
|
|
LEFT JOIN tpa t ON t.id = cp.tpa_id
|
|
WHERE cp.id = :policy_id:
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #203: Earned Premium */
|
|
public function earned_premium(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
|
|
|
|
/* earned premium */
|
|
|
|
CONCAT('💵 ', FORMAT( (prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
,0))AS earned_premium
|
|
FROM client_policy cp
|
|
|
|
JOIN (
|
|
SELECT
|
|
ep2.client_policy_id,
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN e2.change_event = 'inception'
|
|
THEN ep2.rata_premimum
|
|
WHEN e2.change_event != 'inception'
|
|
AND (ep2.date_of_exit IS NULL OR ep2.date_of_exit = '')
|
|
THEN ep2.rata_premimum
|
|
WHEN ep2.date_of_exit IS NOT NULL
|
|
AND ep2.date_of_exit != ''
|
|
AND ep2.claim_status = 0
|
|
THEN -ep2.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0) AS premium_as_on_date
|
|
FROM employee_polices ep2
|
|
JOIN employees e2 ON e2.id = ep2.employee_id
|
|
WHERE ep2.client_policy_id = :policy_id:
|
|
AND ep2.is_active = 1
|
|
GROUP BY ep2.client_policy_id
|
|
) prem ON prem.client_policy_id = cp.id
|
|
|
|
JOIN ticket_master tm
|
|
ON tm.client_policy_id = cp.id
|
|
AND tm.is_active = 1
|
|
|
|
JOIN ticket_claim_status tcs
|
|
ON tcs.id = tm.claim_status_id
|
|
|
|
WHERE cp.id = :policy_id:
|
|
|
|
GROUP BY cp.id, cp.policy_start_date, prem.premium_as_on_date;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #204: Total Claims */
|
|
public function total_claims(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
/* run days */
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
) AS run_days,
|
|
|
|
/* earned premium */
|
|
FORMAT(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) AS earned_premium,
|
|
|
|
/* claims reported */
|
|
FORMAT(COUNT(tm.id), 0) AS claims_reported,
|
|
\t\t/* incurred claims count */
|
|
\tFORMAT(
|
|
\t SUM(
|
|
\t CASE
|
|
\t WHEN tcs.claim_status IN ('Settled', 'Paid') THEN 1
|
|
\t WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied') THEN 1
|
|
\t ELSE 0
|
|
\t END
|
|
\t )
|
|
, 0) AS incurred_claims,
|
|
|
|
/* incurred amount */
|
|
FORMAT(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
, 0) AS incurred_amount,
|
|
|
|
/* incurred ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) * 100
|
|
, 2)
|
|
, '%') AS incurred_ratio,
|
|
|
|
/* rejection rate */
|
|
CONCAT(
|
|
ROUND(
|
|
SUM(CASE WHEN tcs.claim_status IN ('Rejected', 'Denied') THEN 1 ELSE 0 END)
|
|
/ NULLIF(COUNT(tm.id), 0) * 100
|
|
, 2)
|
|
, '%') AS rejection_rate,
|
|
|
|
/* projected claims */
|
|
FORMAT(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
, 0) AS projected_claims,
|
|
|
|
/* projected ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
)
|
|
/ NULLIF(prem.premium_as_on_date, 0) * 100
|
|
, 2)
|
|
, '%') AS projected_ratio
|
|
|
|
FROM client_policy cp
|
|
|
|
JOIN (
|
|
SELECT
|
|
ep2.client_policy_id,
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN e2.change_event = 'inception'
|
|
THEN ep2.rata_premimum
|
|
WHEN e2.change_event != 'inception'
|
|
AND (ep2.date_of_exit IS NULL OR ep2.date_of_exit = '')
|
|
THEN ep2.rata_premimum
|
|
WHEN ep2.date_of_exit IS NOT NULL
|
|
AND ep2.date_of_exit != ''
|
|
AND ep2.claim_status = 0
|
|
THEN -ep2.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0) AS premium_as_on_date
|
|
FROM employee_polices ep2
|
|
JOIN employees e2 ON e2.id = ep2.employee_id
|
|
WHERE ep2.client_policy_id = :policy_id:
|
|
AND ep2.is_active = 1
|
|
GROUP BY ep2.client_policy_id
|
|
) prem ON prem.client_policy_id = cp.id
|
|
|
|
JOIN ticket_master tm
|
|
ON tm.client_policy_id = cp.id
|
|
AND tm.is_active = 1
|
|
|
|
JOIN ticket_claim_status tcs
|
|
ON tcs.id = tm.claim_status_id
|
|
|
|
WHERE cp.id = :policy_id:
|
|
|
|
GROUP BY cp.id, cp.policy_start_date, prem.premium_as_on_date;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #206: Incurred Amount */
|
|
public function incurred_amount(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
/* run days */
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
) AS run_days,
|
|
|
|
/* earned premium */
|
|
FORMAT(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) AS earned_premium,
|
|
|
|
/* claims reported */
|
|
FORMAT(COUNT(tm.id), 0) AS claims_reported,
|
|
\t\t/* incurred claims count */
|
|
\tFORMAT(
|
|
\t SUM(
|
|
\t CASE
|
|
\t WHEN tcs.claim_status IN ('Settled', 'Paid') THEN 1
|
|
\t WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied') THEN 1
|
|
\t ELSE 0
|
|
\t END
|
|
\t )
|
|
, 0) AS incurred_claims,
|
|
|
|
/* incurred amount */
|
|
FORMAT(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
, 0) AS incurred_amount,
|
|
|
|
/* incurred ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) * 100
|
|
, 2)
|
|
, '%') AS incurred_ratio,
|
|
|
|
/* rejection rate */
|
|
CONCAT(
|
|
ROUND(
|
|
SUM(CASE WHEN tcs.claim_status IN ('Rejected', 'Denied') THEN 1 ELSE 0 END)
|
|
/ NULLIF(COUNT(tm.id), 0) * 100
|
|
, 2)
|
|
, '%') AS rejection_rate,
|
|
|
|
/* projected claims */
|
|
FORMAT(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
, 0) AS projected_claims,
|
|
|
|
/* projected ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
)
|
|
/ NULLIF(prem.premium_as_on_date, 0) * 100
|
|
, 2)
|
|
, '%') AS projected_ratio
|
|
|
|
FROM client_policy cp
|
|
|
|
JOIN (
|
|
SELECT
|
|
ep2.client_policy_id,
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN e2.change_event = 'inception'
|
|
THEN ep2.rata_premimum
|
|
WHEN e2.change_event != 'inception'
|
|
AND (ep2.date_of_exit IS NULL OR ep2.date_of_exit = '')
|
|
THEN ep2.rata_premimum
|
|
WHEN ep2.date_of_exit IS NOT NULL
|
|
AND ep2.date_of_exit != ''
|
|
AND ep2.claim_status = 0
|
|
THEN -ep2.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0) AS premium_as_on_date
|
|
FROM employee_polices ep2
|
|
JOIN employees e2 ON e2.id = ep2.employee_id
|
|
WHERE ep2.client_policy_id = :policy_id:
|
|
AND ep2.is_active = 1
|
|
GROUP BY ep2.client_policy_id
|
|
) prem ON prem.client_policy_id = cp.id
|
|
|
|
JOIN ticket_master tm
|
|
ON tm.client_policy_id = cp.id
|
|
AND tm.is_active = 1
|
|
|
|
JOIN ticket_claim_status tcs
|
|
ON tcs.id = tm.claim_status_id
|
|
|
|
WHERE cp.id = :policy_id:
|
|
|
|
GROUP BY cp.id, cp.policy_start_date, prem.premium_as_on_date;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #207: Incurred Ratio */
|
|
public function incurred_ratio(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
/* run days */
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
) AS run_days,
|
|
|
|
/* earned premium */
|
|
FORMAT(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) AS earned_premium,
|
|
|
|
/* claims reported */
|
|
FORMAT(COUNT(tm.id), 0) AS claims_reported,
|
|
\t\t/* incurred claims count */
|
|
\tFORMAT(
|
|
\t SUM(
|
|
\t CASE
|
|
\t WHEN tcs.claim_status IN ('Settled', 'Paid') THEN 1
|
|
\t WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied') THEN 1
|
|
\t ELSE 0
|
|
\t END
|
|
\t )
|
|
, 0) AS incurred_claims,
|
|
|
|
/* incurred amount */
|
|
FORMAT(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
, 0) AS incurred_amount,
|
|
|
|
/* incurred ratio */
|
|
CONCAT('💹 ',
|
|
ROUND(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) * 100
|
|
, 2)
|
|
, '%') AS incurred_ratio,
|
|
|
|
/* rejection rate */
|
|
CONCAT(
|
|
ROUND(
|
|
SUM(CASE WHEN tcs.claim_status IN ('Rejected', 'Denied') THEN 1 ELSE 0 END)
|
|
/ NULLIF(COUNT(tm.id), 0) * 100
|
|
, 2)
|
|
, '%') AS rejection_rate,
|
|
|
|
/* projected claims */
|
|
FORMAT(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
, 0) AS projected_claims,
|
|
|
|
/* projected ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
)
|
|
/ NULLIF(prem.premium_as_on_date, 0) * 100
|
|
, 2)
|
|
, '%') AS projected_ratio
|
|
|
|
FROM client_policy cp
|
|
|
|
JOIN (
|
|
SELECT
|
|
ep2.client_policy_id,
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN e2.change_event = 'inception'
|
|
THEN ep2.rata_premimum
|
|
WHEN e2.change_event != 'inception'
|
|
AND (ep2.date_of_exit IS NULL OR ep2.date_of_exit = '')
|
|
THEN ep2.rata_premimum
|
|
WHEN ep2.date_of_exit IS NOT NULL
|
|
AND ep2.date_of_exit != ''
|
|
AND ep2.claim_status = 0
|
|
THEN -ep2.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0) AS premium_as_on_date
|
|
FROM employee_polices ep2
|
|
JOIN employees e2 ON e2.id = ep2.employee_id
|
|
WHERE ep2.client_policy_id = :policy_id:
|
|
AND ep2.is_active = 1
|
|
GROUP BY ep2.client_policy_id
|
|
) prem ON prem.client_policy_id = cp.id
|
|
|
|
JOIN ticket_master tm
|
|
ON tm.client_policy_id = cp.id
|
|
AND tm.is_active = 1
|
|
|
|
JOIN ticket_claim_status tcs
|
|
ON tcs.id = tm.claim_status_id
|
|
|
|
WHERE cp.id = :policy_id:
|
|
|
|
GROUP BY cp.id, cp.policy_start_date, prem.premium_as_on_date;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #208: Projected Claims */
|
|
public function projected_claims(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
/* run days */
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
) AS run_days,
|
|
|
|
/* earned premium */
|
|
FORMAT(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) AS earned_premium,
|
|
|
|
/* claims reported */
|
|
FORMAT(COUNT(tm.id), 0) AS claims_reported,
|
|
\t\t/* incurred claims count */
|
|
\tFORMAT(
|
|
\t SUM(
|
|
\t CASE
|
|
\t WHEN tcs.claim_status IN ('Settled', 'Paid') THEN 1
|
|
\t WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied') THEN 1
|
|
\t ELSE 0
|
|
\t END
|
|
\t )
|
|
, 0) AS incurred_claims,
|
|
|
|
/* incurred amount */
|
|
FORMAT(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
, 0) AS incurred_amount,
|
|
|
|
/* incurred ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) * 100
|
|
, 2)
|
|
, '%') AS incurred_ratio,
|
|
|
|
/* rejection rate */
|
|
CONCAT(
|
|
ROUND(
|
|
SUM(CASE WHEN tcs.claim_status IN ('Rejected', 'Denied') THEN 1 ELSE 0 END)
|
|
/ NULLIF(COUNT(tm.id), 0) * 100
|
|
, 2)
|
|
, '%') AS rejection_rate,
|
|
|
|
/* projected claims */
|
|
|
|
CONCAT('🎯 ', FORMAT(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
, 0)) AS projected_claims,
|
|
|
|
/* projected ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
)
|
|
/ NULLIF(prem.premium_as_on_date, 0) * 100
|
|
, 2)
|
|
, '%') AS projected_ratio
|
|
|
|
FROM client_policy cp
|
|
|
|
JOIN (
|
|
SELECT
|
|
ep2.client_policy_id,
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN e2.change_event = 'inception'
|
|
THEN ep2.rata_premimum
|
|
WHEN e2.change_event != 'inception'
|
|
AND (ep2.date_of_exit IS NULL OR ep2.date_of_exit = '')
|
|
THEN ep2.rata_premimum
|
|
WHEN ep2.date_of_exit IS NOT NULL
|
|
AND ep2.date_of_exit != ''
|
|
AND ep2.claim_status = 0
|
|
THEN -ep2.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0) AS premium_as_on_date
|
|
FROM employee_polices ep2
|
|
JOIN employees e2 ON e2.id = ep2.employee_id
|
|
WHERE ep2.client_policy_id = :policy_id:
|
|
AND ep2.is_active = 1
|
|
GROUP BY ep2.client_policy_id
|
|
) prem ON prem.client_policy_id = cp.id
|
|
|
|
JOIN ticket_master tm
|
|
ON tm.client_policy_id = cp.id
|
|
AND tm.is_active = 1
|
|
|
|
JOIN ticket_claim_status tcs
|
|
ON tcs.id = tm.claim_status_id
|
|
|
|
WHERE cp.id = :policy_id:
|
|
|
|
GROUP BY cp.id, cp.policy_start_date, prem.premium_as_on_date;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #209: Projected Ratio */
|
|
public function projected_ratio(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
/* run days */
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
) AS run_days,
|
|
|
|
/* earned premium */
|
|
FORMAT(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) AS earned_premium,
|
|
|
|
/* claims reported */
|
|
FORMAT(COUNT(tm.id), 0) AS claims_reported,
|
|
\t\t/* incurred claims count */
|
|
\tFORMAT(
|
|
\t SUM(
|
|
\t CASE
|
|
\t WHEN tcs.claim_status IN ('Settled', 'Paid') THEN 1
|
|
\t WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied') THEN 1
|
|
\t ELSE 0
|
|
\t END
|
|
\t )
|
|
, 0) AS incurred_claims,
|
|
|
|
/* incurred amount */
|
|
FORMAT(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
, 0) AS incurred_amount,
|
|
|
|
/* incurred ratio */
|
|
CONCAT(
|
|
ROUND(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
(prem.premium_as_on_date / 365)
|
|
* DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
)
|
|
, 0) * 100
|
|
, 2)
|
|
, '%') AS incurred_ratio,
|
|
|
|
/* rejection rate */
|
|
CONCAT(
|
|
ROUND(
|
|
SUM(CASE WHEN tcs.claim_status IN ('Rejected', 'Denied') THEN 1 ELSE 0 END)
|
|
/ NULLIF(COUNT(tm.id), 0) * 100
|
|
, 2)
|
|
, '%') AS rejection_rate,
|
|
|
|
/* projected claims */
|
|
FORMAT(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
, 0) AS projected_claims,
|
|
|
|
/* projected ratio */
|
|
CONCAT('💹 ',
|
|
ROUND(
|
|
(
|
|
(
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN tcs.claim_status IN ('Settled', 'Paid')
|
|
THEN CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
WHEN tcs.claim_status NOT IN ('Settled', 'Paid', 'Rejected', 'Denied')
|
|
THEN CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
), 0)
|
|
/ NULLIF(
|
|
DATEDIFF(
|
|
MAX(COALESCE(tm.claim_dump_date, cp.policy_end_date)),
|
|
cp.policy_start_date
|
|
), 0
|
|
)
|
|
* 365
|
|
) * 1.10
|
|
)
|
|
/ NULLIF(prem.premium_as_on_date, 0) * 100
|
|
, 2)
|
|
, '%') AS projected_ratio
|
|
|
|
FROM client_policy cp
|
|
|
|
JOIN (
|
|
SELECT
|
|
ep2.client_policy_id,
|
|
COALESCE(SUM(
|
|
CASE
|
|
WHEN e2.change_event = 'inception'
|
|
THEN ep2.rata_premimum
|
|
WHEN e2.change_event != 'inception'
|
|
AND (ep2.date_of_exit IS NULL OR ep2.date_of_exit = '')
|
|
THEN ep2.rata_premimum
|
|
WHEN ep2.date_of_exit IS NOT NULL
|
|
AND ep2.date_of_exit != ''
|
|
AND ep2.claim_status = 0
|
|
THEN -ep2.rata_premimum
|
|
ELSE 0
|
|
END
|
|
), 0) AS premium_as_on_date
|
|
FROM employee_polices ep2
|
|
JOIN employees e2 ON e2.id = ep2.employee_id
|
|
WHERE ep2.client_policy_id = :policy_id:
|
|
AND ep2.is_active = 1
|
|
GROUP BY ep2.client_policy_id
|
|
) prem ON prem.client_policy_id = cp.id
|
|
|
|
JOIN ticket_master tm
|
|
ON tm.client_policy_id = cp.id
|
|
AND tm.is_active = 1
|
|
|
|
JOIN ticket_claim_status tcs
|
|
ON tcs.id = tm.claim_status_id
|
|
|
|
WHERE cp.id = :policy_id:
|
|
|
|
GROUP BY cp.id, cp.policy_start_date, prem.premium_as_on_date;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #213: Total Reimbursement Amount */
|
|
public function total_reimbursement_amount(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0) AS claim_value,
|
|
|
|
ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(totals.total_value, 0) * 100
|
|
, 2) AS value_pct
|
|
|
|
FROM ticket_master tm
|
|
|
|
JOIN (
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
) totals ON 1=1
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND (
|
|
tm.tpa_claim_type IS NULL
|
|
OR TRIM(LOWER(tm.tpa_claim_type)) IN ('unknown', 'reimbursement', '')
|
|
);
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #214: Total Reimbursement Amt % */
|
|
public function total_reimbursement_amt_pct(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0) AS claim_value,
|
|
|
|
ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(totals.total_value, 0) * 100
|
|
, 2) AS value_pct
|
|
|
|
FROM ticket_master tm
|
|
|
|
JOIN (
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
) totals ON 1=1
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND (
|
|
tm.tpa_claim_type IS NULL
|
|
OR TRIM(LOWER(tm.tpa_claim_type)) IN ('unknown', 'reimbursement', '')
|
|
);
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #215: Cashless Claim Amt */
|
|
public function cashless_claim_amt(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0) AS claim_value,
|
|
|
|
ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(totals.total_value, 0) * 100
|
|
, 2) AS value_pct
|
|
|
|
FROM ticket_master tm
|
|
|
|
JOIN (
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
) totals ON 1=1
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND TRIM(LOWER(tm.tpa_claim_type)) = 'cashless';
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #216: Cashless Claim Amt % */
|
|
public function cashless_claim_amt_pct(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0) AS claim_value,
|
|
|
|
ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(totals.total_value, 0) * 100
|
|
, 2) AS value_pct
|
|
|
|
FROM ticket_master tm
|
|
|
|
JOIN (
|
|
SELECT
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
) totals ON 1=1
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND TRIM(LOWER(tm.tpa_claim_type)) = 'cashless';
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #217: Total Incurred by city */
|
|
public function total_incurred_by_city(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(tm.hospital_name, 'Not Specified') AS hospital_name,
|
|
COALESCE(tm.hospital_city, '-') AS hospital_city,
|
|
COALESCE(tm.hospital_state, '-') AS hospital_state,
|
|
|
|
COUNT(tm.id) AS claim_count,
|
|
|
|
ROUND(
|
|
COUNT(tm.id) / totals.total_count * 100,
|
|
2
|
|
) AS count_pct,
|
|
|
|
COALESCE(
|
|
SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))),
|
|
0
|
|
) AS claim_value,
|
|
|
|
ROUND(
|
|
COALESCE(
|
|
SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))),
|
|
0
|
|
) / NULLIF(totals.total_value, 0) * 100,
|
|
2
|
|
) AS value_pct
|
|
|
|
FROM ticket_master tm
|
|
|
|
JOIN (
|
|
SELECT
|
|
COUNT(id) AS total_count,
|
|
|
|
COALESCE(
|
|
SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))),
|
|
0
|
|
) AS total_value
|
|
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
) totals ON 1=1
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND tm.hospital_name IS NOT NULL
|
|
|
|
GROUP BY
|
|
tm.hospital_name,
|
|
tm.hospital_city,
|
|
tm.hospital_state,
|
|
totals.total_count,
|
|
totals.total_value
|
|
|
|
ORDER BY claim_count DESC
|
|
|
|
LIMIT 5;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #219: Claim Amount by Claim Status */
|
|
public function claim_amount_by_claim_status(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(tcs.display_name, 'Unknown') AS claim_status,
|
|
COUNT(tm.id) AS claim_count,
|
|
CONCAT(ROUND(COUNT(tm.id) / totals.total_count * 100, 2), '%')
|
|
AS count_pct,
|
|
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
AS claim_value,
|
|
CONCAT(ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(totals.total_value, 0) * 100
|
|
, 2), '%') AS value_pct
|
|
FROM ticket_master tm
|
|
JOIN ticket_claim_status tcs ON tcs.id = tm.claim_status_id
|
|
JOIN (
|
|
SELECT
|
|
COUNT(id) AS total_count,
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id: AND is_active = 1
|
|
) totals ON 1=1
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
GROUP BY tcs.display_name, totals.total_count, totals.total_value
|
|
ORDER BY claim_count DESC;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #220: Hospitals in detail */
|
|
public function hospitals_in_detail(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(NULLIF(TRIM(tm.hospital_name), ''), 'Not Specified') AS hospital_name,
|
|
|
|
COALESCE(NULLIF(TRIM(tm.hospital_city), ''), '-') AS hospital_city,
|
|
|
|
COALESCE(NULLIF(TRIM(tm.hospital_state), ''), '-') AS hospital_state,
|
|
|
|
COUNT(tm.id) AS claim_count,
|
|
|
|
CAST(
|
|
GREATEST(
|
|
ROUND(
|
|
(
|
|
COUNT(tm.id) / NULLIF(totals.total_count, 0)
|
|
) * 100,
|
|
2
|
|
),
|
|
0.01
|
|
) AS DECIMAL(10,2)
|
|
) AS count_pct,
|
|
|
|
CAST(
|
|
COALESCE(
|
|
SUM(
|
|
CASE
|
|
WHEN TRIM(tm.claim_amount) REGEXP '^[0-9]+(\\\\.[0-9]+)?$'
|
|
THEN CAST(TRIM(tm.claim_amount) AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
),
|
|
0
|
|
) AS DECIMAL(15,2)
|
|
) AS claim_value,
|
|
|
|
CAST(
|
|
GREATEST(
|
|
ROUND(
|
|
(
|
|
COALESCE(
|
|
SUM(
|
|
CASE
|
|
WHEN TRIM(tm.claim_amount) REGEXP '^[0-9]+(\\\\.[0-9]+)?$'
|
|
THEN CAST(TRIM(tm.claim_amount) AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
),
|
|
0
|
|
) / NULLIF(totals.total_value, 0)
|
|
) * 100,
|
|
2
|
|
),
|
|
0.01
|
|
) AS DECIMAL(10,2)
|
|
) AS value_pct
|
|
|
|
FROM ticket_master tm
|
|
|
|
JOIN (
|
|
SELECT
|
|
COUNT(id) AS total_count,
|
|
|
|
CAST(
|
|
COALESCE(
|
|
SUM(
|
|
CASE
|
|
WHEN TRIM(claim_amount) REGEXP '^[0-9]+(\\\\.[0-9]+)?$'
|
|
THEN CAST(TRIM(claim_amount) AS DECIMAL(15,2))
|
|
ELSE 0
|
|
END
|
|
),
|
|
0
|
|
) AS DECIMAL(15,2)
|
|
) AS total_value
|
|
|
|
FROM ticket_master
|
|
|
|
WHERE client_policy_id = :policy_id:
|
|
AND is_active = 1
|
|
|
|
) totals ON 1 = 1
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND NULLIF(TRIM(tm.hospital_name), '') IS NOT NULL
|
|
|
|
GROUP BY
|
|
tm.hospital_name,
|
|
tm.hospital_city,
|
|
tm.hospital_state
|
|
|
|
ORDER BY claim_count DESC;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #221: Hospital city wise SI Limit - Pregnancy */
|
|
public function hospital_city_wise_si_limit_pregnancy(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(tm.hospital_city, 'Not Specified') AS hospital_city,
|
|
\tCOALESCE(tm.hospital_name, 'Not Specified') AS hospital_name,
|
|
COUNT(tm.id) AS `Claim Count`,
|
|
|
|
FORMAT(
|
|
COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),
|
|
0),
|
|
0) AS `SUM OF CLAIMED AMOUNT`,
|
|
|
|
CASE
|
|
WHEN COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),
|
|
0)
|
|
>
|
|
COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(ep.basic_cover_si, '') AS DECIMAL(15,2))
|
|
),
|
|
0)
|
|
THEN 'Exceeded'
|
|
ELSE 'Within Limit'
|
|
END AS `CLAIM STATUS LIMIT`
|
|
|
|
FROM ticket_master tm
|
|
|
|
INNER JOIN employee_polices ep
|
|
ON ep.employee_id = tm.emp_id
|
|
AND ep.client_policy_id = tm.client_policy_id
|
|
AND ep.is_active = 1
|
|
AND ep.status = 'active'
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND tm.hospital_name IS NOT NULL
|
|
|
|
/* Pregnancy Related Conditions */
|
|
AND (
|
|
LOWER(tm.tpa_ailments) LIKE '%pregnancy%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%maternal%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%gestational%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%delivery%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%cesarean%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%caesarean%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%c-section%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%spontaneous delivery%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%normal delivery%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%forceps%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%vaccum extractor%'
|
|
)
|
|
|
|
GROUP BY tm.hospital_city,tm.hospital_name
|
|
|
|
ORDER BY
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
) DESC;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #224: S-PREGNANCY - NORMAL DELIVERY Exceeded Amt */
|
|
public function s_pregnancy_normal_delivery_exceeded_amt(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
'SINGLE PREGNANCY - NORMAL DELIVERY' AS diagnosis,
|
|
|
|
COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),0) AS exceeded_claim_amount
|
|
|
|
FROM ticket_master tm
|
|
|
|
INNER JOIN employee_polices ep
|
|
ON ep.employee_id = tm.emp_id
|
|
AND ep.client_policy_id = tm.client_policy_id
|
|
AND ep.is_active = 1
|
|
AND ep.status = 'active'
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
|
|
AND (
|
|
LOWER(tm.tpa_ailments) LIKE '%spontaneous delivery%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%normal delivery%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%forceps%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%vaccum extractor%'
|
|
)
|
|
|
|
AND CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
>
|
|
CAST(NULLIF(ep.basic_cover_si, '') AS DECIMAL(15,2));
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #225: S-Pregnancy C-Sec avg exceeded amt */
|
|
public function s_pregnancy_c_sec_avg_exceeded_amt(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
'SINGLE PREGNANCY - CAESAREAN DELIVERY' AS diagnosis,
|
|
|
|
COALESCE(
|
|
AVG(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),
|
|
2) AS avg_exceeded_amount
|
|
|
|
FROM ticket_master tm
|
|
|
|
INNER JOIN employee_polices ep
|
|
ON ep.employee_id = tm.emp_id
|
|
AND ep.client_policy_id = tm.client_policy_id
|
|
AND ep.is_active = 1
|
|
AND ep.status = 'active'
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
|
|
AND (
|
|
LOWER(tm.tpa_ailments) LIKE '%cesarean%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%caesarean%'
|
|
OR LOWER(tm.tpa_ailments) LIKE '%c-section%'
|
|
)
|
|
|
|
AND CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
>
|
|
CAST(NULLIF(ep.basic_cover_si, '') AS DECIMAL(15,2));
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #228: Cataract exceeded claim amount */
|
|
public function cataract_exceeded_claim_amount(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
'CATARACT' AS diagnosis,
|
|
|
|
|
|
COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),
|
|
0) AS exceeded_claim_amount
|
|
|
|
FROM ticket_master tm
|
|
|
|
INNER JOIN employee_polices ep
|
|
ON ep.employee_id = tm.emp_id
|
|
AND ep.client_policy_id = tm.client_policy_id
|
|
AND ep.is_active = 1
|
|
AND ep.status = 'active'
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
|
|
AND LOWER(tm.tpa_ailments) LIKE '%cataract%'
|
|
|
|
AND CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
>
|
|
CAST(NULLIF(ep.basic_cover_si, '') AS DECIMAL(15,2));
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #229: Cataract avg exceeded amount */
|
|
public function cataract_avg_exceeded_amount(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
'CATARACT' AS diagnosis,
|
|
|
|
FORMAT(
|
|
COALESCE(
|
|
AVG(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),
|
|
0),
|
|
2) AS avg_exceeded_claim_amount
|
|
|
|
FROM ticket_master tm
|
|
|
|
INNER JOIN employee_polices ep
|
|
ON ep.employee_id = tm.emp_id
|
|
AND ep.client_policy_id = tm.client_policy_id
|
|
AND ep.is_active = 1
|
|
AND ep.status = 'active'
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
|
|
AND LOWER(tm.tpa_ailments) LIKE '%cataract%'
|
|
|
|
AND CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
>
|
|
CAST(NULLIF(ep.basic_cover_si, '') AS DECIMAL(15,2));
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #230: Hospital city wise SI Limit - Cataract */
|
|
public function hospital_city_wise_si_limit_cataract(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
\tCOALESCE(tm.hospital_city, 'Not Specified') AS hospital_city,
|
|
COALESCE(tm.hospital_name, 'Not Specified') AS hospital_name,
|
|
|
|
COUNT(tm.id) AS claim_count,
|
|
|
|
FORMAT(
|
|
COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),
|
|
0),
|
|
0) AS `SUM OF CLAIMED AMOUNT`,
|
|
|
|
CASE
|
|
WHEN COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
),
|
|
0)
|
|
>
|
|
COALESCE(
|
|
SUM(
|
|
CAST(NULLIF(ep.basic_cover_si, '') AS DECIMAL(15,2))
|
|
),
|
|
0)
|
|
THEN 'Exceeded'
|
|
ELSE 'Within Limit'
|
|
END AS `CLAIM STATUS LIMIT`
|
|
|
|
FROM ticket_master tm
|
|
|
|
INNER JOIN employee_polices ep
|
|
ON ep.employee_id = tm.emp_id
|
|
AND ep.client_policy_id = tm.client_policy_id
|
|
AND ep.is_active = 1
|
|
AND ep.status = 'active'
|
|
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
AND tm.hospital_name IS NOT NULL
|
|
|
|
/* Cataract Related */
|
|
AND LOWER(tm.tpa_ailments) LIKE '%cataract%'
|
|
|
|
GROUP BY tm.hospital_city,tm.hospital_name
|
|
|
|
ORDER BY
|
|
SUM(
|
|
CAST(NULLIF(tm.approved_amount, '') AS DECIMAL(15,2))
|
|
) DESC;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
/** Metabase #231: Total Incurred by Cliam Status */
|
|
public function total_incurred_by_cliam_status(int $policyId): array
|
|
{
|
|
$sql = <<<'SQL'
|
|
SELECT
|
|
COALESCE(tcs.display_name, 'Unknown') AS `Claim Status`,
|
|
-- COUNT(tm.id) AS claim_count,
|
|
-- CONCAT(ROUND(COUNT(tm.id) / totals.total_count * 100, 2), '%')
|
|
-- AS count_pct,
|
|
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
AS `Total Incurred Amount`,
|
|
CONCAT(ROUND(
|
|
COALESCE(SUM(CAST(NULLIF(tm.claim_amount, '') AS DECIMAL(15,2))), 0)
|
|
/ NULLIF(totals.total_value, 0) * 100
|
|
, 2), '%') AS `Value PCT`
|
|
FROM ticket_master tm
|
|
JOIN ticket_claim_status tcs ON tcs.id = tm.claim_status_id
|
|
JOIN (
|
|
SELECT
|
|
COUNT(id) AS total_count,
|
|
COALESCE(SUM(CAST(NULLIF(claim_amount, '') AS DECIMAL(15,2))), 0) AS total_value
|
|
FROM ticket_master
|
|
WHERE client_policy_id = :policy_id: AND is_active = 1
|
|
) totals ON 1=1
|
|
WHERE tm.client_policy_id = :policy_id:
|
|
AND tm.is_active = 1
|
|
GROUP BY tcs.display_name, totals.total_count, totals.total_value
|
|
-- ORDER BY claim_count DESC;
|
|
SQL;
|
|
return $this->runKpiQuery($sql, $policyId);
|
|
}
|
|
|
|
}
|