nhance/app/Controllers/ClaimReportDashboardController.php
2026-07-29 11:15:54 +05:30

278 lines
9.0 KiB
PHP

<?php
namespace App\Controllers;
use App\Models\ClaimReportDashboardModel;
use App\Models\ClaimsCollectionV2DashboardModel;
use App\Models\ClaimDumpFileModel;
use App\Libraries\ClaimReportSyncService;
use CodeIgniter\API\ResponseTrait;
/**
* Claims Collection dashboard API using claim_report (falls back to ticket_master).
*/
class ClaimReportDashboardController extends BaseController
{
use ResponseTrait;
/**
* Resolve policy id from request; optional $fallback (e.g. route default for debug only).
*/
protected function resolvePolicyId(?int $fallback = null): int
{
$id = (int) (
$this->request->getGet('client_policy')
?? $this->request->getGet('client_policy_id')
?? $this->request->getPost('client_policy')
?? $this->request->getPost('client_policy_id')
?? 0
);
if ($id > 0) {
return $id;
}
if ($fallback !== null && $fallback > 0) {
return $fallback;
}
return 0;
}
/**
* Resolve KPI by Metabase numeric id or method slug.
*/
protected function resolveKpiMethod(string $kpiKey): ?string
{
$kpiKey = trim($kpiKey);
if ($kpiKey === '') {
return null;
}
if (in_array($kpiKey, ClaimsCollectionV2DashboardModel::KPI_MAP, true)) {
return $kpiKey;
}
if (ctype_digit($kpiKey)) {
$id = (int) $kpiKey;
return ClaimsCollectionV2DashboardModel::KPI_MAP[$id] ?? null;
}
return null;
}
/**
* JSON: single KPI by slug or Metabase id.
*/
public function kpi(string $kpiMethod = '')
{
$policyId = $this->resolvePolicyId();
if ($policyId <= 0) {
return $this->respond([
'status' => false,
'message' => 'client_policy or client_policy_id is required.',
], 422);
}
$kpiMethod = $this->resolveKpiMethod($kpiMethod);
if ($kpiMethod === null) {
return $this->respond([
'status' => false,
'message' => 'Unknown KPI. Pass Metabase id or method slug.',
'allowed' => ClaimsCollectionV2DashboardModel::KPI_MAP,
], 404);
}
$model = new ClaimReportDashboardModel();
$metabaseId = array_search($kpiMethod, ClaimsCollectionV2DashboardModel::KPI_MAP, true);
return $this->respond([
'status' => true,
'policy_id' => $policyId,
'claims_source' => $model->resolveClaimsTable($policyId),
'kpi_id' => $metabaseId !== false ? (int) $metabaseId : null,
'kpi' => $kpiMethod,
'label' => ClaimsCollectionV2DashboardModel::KPI_LABELS[$kpiMethod] ?? $kpiMethod,
'rows' => $model->getKpi($kpiMethod, $policyId),
]);
}
/**
* JSON: all KPIs.
*/
public function all()
{
$policyId = $this->resolvePolicyId();
if ($policyId <= 0) {
return $this->respond([
'status' => false,
'message' => 'client_policy or client_policy_id is required.',
], 422);
}
$generatedAt = (new ClaimDumpFileModel())->getGeneratedAtForPolicy($policyId);
// if ($generatedAt === null) {
// return $this->respond([
// 'status' => false,
// 'message' => 'claim_dump_date is mandatory. No claim dump date found for this policy.',
// ], 422);
// }
$model = new ClaimReportDashboardModel();
$data = $model->getAllKpis($policyId);
$source = $data['_meta']['claims_source'] ?? $model->resolveClaimsTable($policyId);
unset($data['_meta']);
return $this->respond([
'status' => true,
'policy_id' => $policyId,
'claims_source' => $source,
'generated_at' => $generatedAt,
'data' => $data,
]);
}
/**
* Admin preview UI — KPI grid for manual testing.
*/
public function preview(int $policyId = 4687)
{
$policyId = $this->resolvePolicyId($policyId);
$path = $this->request->getUri()->getPath();
$isJwt = stripos($path, 'employeeRest') !== false;
$prefix = $isJwt ? 'employeeRest/claims-collection-report' : 'util/claims-collection-report';
return view('claims_collection_v2_dashboard', [
'policy_id' => $policyId,
'kpi_map' => ClaimsCollectionV2DashboardModel::KPI_MAP,
'kpi_labels' => ClaimsCollectionV2DashboardModel::KPI_LABELS,
'api_all_url' => base_url($prefix . '/all'),
'api_kpi_url' => base_url($prefix . '/kpi'),
]);
}
/**
* Admin check only: raw JSON on screen (no dashboard UI).
*/
public function debug(int $policyId = 4687)
{
$policyId = $this->resolvePolicyId($policyId);
if ($policyId <= 0) {
return $this->response
->setStatusCode(422)
->setBody('client_policy or client_policy_id is required.');
}
$model = new ClaimReportDashboardModel();
$data = $model->getAllKpis($policyId);
$source = $data['_meta']['claims_source'] ?? $model->resolveClaimsTable($policyId);
unset($data['_meta']);
$body = json_encode([
'status' => true,
'policy_id' => $policyId,
'claims_source' => $source,
'data' => $data,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
return $this->response
->setHeader('Content-Type', 'application/json; charset=UTF-8')
->setBody($body);
}
/**
* Run claim report sync via URL (authMVC / JWT).
* Uses ClaimReportSyncService directly (no spark/CLI).
*
* Query params (all optional):
* client_policy / client_policy_id
* tpa=icici|abhi|mediassist|fhpl|rcare|vidal|all
* limit=500
* phase1=true → TPA dump tables only (skip ticket_master)
* ticket_only=1 → ticket_master only (ignored if phase1=true)
*/
public function sync()
{
@set_time_limit(0);
@ini_set('max_execution_time', '0');
$policyId = $this->resolvePolicyId();
$tpa = strtolower(trim((string) ($this->request->getGet('tpa') ?? $this->request->getPost('tpa') ?? 'all')));
$limit = (int) ($this->request->getGet('limit') ?? $this->request->getPost('limit') ?? 500);
$ticketOnly = $this->isTruthyParam('ticket_only');
$phase1Only = $this->isTruthyParam('phase1');
$allowedTpa = ['all', 'vidal', 'abhi', 'mediassist', 'fhpl', 'rcare', 'icici'];
if ($tpa === '' || ! in_array($tpa, $allowedTpa, true)) {
return $this->respond([
'status' => false,
'message' => 'Invalid tpa. Allowed: ' . implode(', ', $allowedTpa),
], 422);
}
if ($limit <= 0) {
$limit = 500;
}
if ($limit > 5000) {
$limit = 5000;
}
$startedAt = date('Y-m-d H:i:s');
try {
$result = (new ClaimReportSyncService())->sync(
$policyId,
$tpa,
$limit,
$ticketOnly,
$phase1Only
);
} catch (\Throwable $e) {
return $this->respond([
'status' => false,
'message' => 'Sync failed: ' . $e->getMessage(),
'policy_id' => $policyId > 0 ? $policyId : null,
'tpa' => $tpa,
'limit' => $limit,
'phase1' => $phase1Only,
'ticket_only' => $ticketOnly,
'started_at' => $startedAt,
], 500);
}
$ok = ! empty($result['status']);
return $this->respond([
'status' => $ok,
'message' => $result['message'] ?? ($ok ? 'Sync completed.' : 'Sync failed.'),
'policy_id' => $policyId > 0 ? $policyId : null,
'tpa' => $tpa,
'limit' => $limit,
'phase1' => $phase1Only,
'ticket_only' => $ticketOnly && ! $phase1Only,
'started_at' => $startedAt,
'finished_at' => date('Y-m-d H:i:s'),
'summary' => $result['summary'] ?? null,
'phases' => $result['phases'] ?? [],
'tpa_results' => $result['tpa_results'] ?? [],
'logs' => $result['logs'] ?? [],
], $ok ? 200 : 500);
}
/**
* True when GET/POST param is 1/true/yes (case-insensitive).
*/
protected function isTruthyParam(string $name): bool
{
$raw = $this->request->getGet($name) ?? $this->request->getPost($name);
if ($raw === null) {
return false;
}
return in_array(strtolower(trim((string) $raw)), ['1', 'true', 'yes'], true);
}
}