From 6566ec0b77475fb2d192e7101555c2c5e8d8a21e Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Fri, 4 Sep 2026 05:51:12 +0530 Subject: [PATCH] fix(abdm): handle missing optional params, catch location query exceptions, and safely boot billing controller in IPD discharge preview --- app/Controllers/AbdmGateway.php | 180 ++++++++++++++++++++---------- app/Controllers/Ipd_discharge.php | 123 +++++++++++++------- 2 files changed, 202 insertions(+), 101 deletions(-) diff --git a/app/Controllers/AbdmGateway.php b/app/Controllers/AbdmGateway.php index a4894b8..c34d5f7 100644 --- a/app/Controllers/AbdmGateway.php +++ b/app/Controllers/AbdmGateway.php @@ -2592,29 +2592,48 @@ class AbdmGateway extends BaseController $patientId = (int) ($this->request->getGet('patient_id') ?? $this->request->getPost('patient_id') ?? 0); $abhaId = trim((string) ($this->request->getGet('abha_id') ?? $this->request->getPost('abha_id') ?? '')); - if ($ipdId <= 0 || $patientId <= 0 || $abhaId === '') { + if ($ipdId <= 0) { return $this->response->setStatusCode(400)->setJSON([ 'status' => 'error', - 'message' => 'ipd_id, patient_id and abha_id are required.', + 'message' => 'ipd_id is required.', ]); } - $fhirPayload = $this->buildIpdDischargeGatewayPayload($ipdId, $patientId, $abhaId); - if ($fhirPayload === null) { - return $this->response->setStatusCode(404)->setJSON([ + if ($patientId <= 0 && $this->db && $this->db->tableExists('ipd_master')) { + $ipdRow = $this->db->table('ipd_master')->where('id', $ipdId)->get(1)->getRowArray() ?? []; + $patientId = (int) ($ipdRow['p_id'] ?? $ipdRow['patient_id'] ?? 0); + } + + if ($abhaId === '' && $patientId > 0) { + $ident = $this->resolvePatientAbhaIdentity($patientId); + $abhaId = $ident['abha_address'] ?: $ident['abha_id']; + } + + try { + $fhirPayload = $this->buildIpdDischargeGatewayPayload($ipdId, $patientId, $abhaId); + if ($fhirPayload === null) { + return $this->response->setStatusCode(404)->setJSON([ + 'status' => 'error', + 'message' => 'Unable to prepare IPD discharge FHIR payload.', + ]); + } + $bundle = (array) ($fhirPayload['bundle'] ?? []); + + return $this->response->setJSON([ + 'status' => 'ok', + 'ipd_id' => $ipdId, + 'patient_id' => $patientId, + 'abha_id' => $abhaId, + 'bundle' => $bundle, + ]); + } catch (\Throwable $e) { + log_message('error', 'ipdDischargeFhirPreview error for IPD #' . $ipdId . ': ' . $e->getMessage() . "\n" . $e->getTraceAsString()); + + return $this->response->setStatusCode(500)->setJSON([ 'status' => 'error', - 'message' => 'Unable to prepare IPD discharge FHIR payload.', + 'message' => 'Error generating IPD discharge FHIR: ' . $e->getMessage(), ]); } - $bundle = (array) ($fhirPayload['bundle'] ?? []); - - return $this->response->setJSON([ - 'status' => 'ok', - 'ipd_id' => $ipdId, - 'patient_id' => $patientId, - 'abha_id' => $abhaId, - 'bundle' => $bundle, - ]); } /** @@ -2622,15 +2641,19 @@ class AbdmGateway extends BaseController */ private function buildIpdDischargeGatewayPayload(int $ipdId, int $patientId, string $preferredAbhaId = ''): ?array { - $ipdRow = $this->db->tableExists('ipd_master') + $ipdRow = ($this->db && $this->db->tableExists('ipd_master')) ? ($this->db->table('ipd_master')->where('id', $ipdId)->get(1)->getRowArray() ?? []) : []; if (empty($ipdRow)) { return null; } + if ($patientId <= 0) { + $patientId = (int) ($ipdRow['p_id'] ?? $ipdRow['patient_id'] ?? 0); + } + $patientRow = []; - if ($patientId > 0 && $this->db->tableExists('patient_master')) { + if ($patientId > 0 && $this->db && $this->db->tableExists('patient_master')) { $patientRow = $this->db->table('patient_master')->where('id', $patientId)->get(1)->getRowArray() ?? []; } @@ -3022,53 +3045,87 @@ class AbdmGateway extends BaseController $wardName = ''; $roomName = ''; - if ($ipdId > 0) { - if ($this->db->tableExists('bed_master')) { - $row = $this->db->table('bed_master bm') - ->select('bm.bed_number, wm.ward_name, wm.ward_type') - ->join('ward_master wm', 'wm.id = bm.ward_id', 'left') - ->where('bm.current_ipd_id', $ipdId) - ->limit(1) - ->get() - ->getRowArray(); - if (! empty($row)) { - $bedNo = trim((string) ($row['bed_number'] ?? '')); - $wardName = trim((string) ($row['ward_name'] ?? $row['ward_type'] ?? '')); + if ($ipdId > 0 && $this->db) { + try { + if ($this->db->tableExists('bed_master')) { + $builder = $this->db->table('bed_master bm') + ->select('bm.bed_number'); + if ($this->db->tableExists('ward_master')) { + $builder->select('wm.ward_name, wm.ward_type') + ->join('ward_master wm', 'wm.id = bm.ward_id', 'left'); + } + $row = $builder->where('bm.current_ipd_id', $ipdId) + ->limit(1) + ->get() + ->getRowArray(); + if (! empty($row)) { + $bedNo = trim((string) ($row['bed_number'] ?? '')); + $wardName = trim((string) ($row['ward_name'] ?? $row['ward_type'] ?? '')); + } + } + } catch (\Throwable $e) { + } + + if ($bedNo === '') { + try { + if ($this->db->tableExists('bed_assignment_history')) { + $builder = $this->db->table('bed_assignment_history bah'); + if ($this->db->tableExists('bed_master')) { + $builder->select('bm.bed_number') + ->join('bed_master bm', 'bm.id = bah.bed_id', 'left'); + } + if ($this->db->tableExists('ward_master')) { + $builder->select('wm.ward_name, wm.ward_type') + ->join('ward_master wm', 'wm.id = bah.ward_id', 'left'); + } + $bahRow = $builder->where('bah.ipd_id', $ipdId) + ->orderBy('bah.id', 'DESC') + ->limit(1) + ->get() + ->getRowArray(); + if (! empty($bahRow)) { + $bedNo = trim((string) ($bahRow['bed_number'] ?? '')); + $wardName = trim((string) ($bahRow['ward_name'] ?? $bahRow['ward_type'] ?? '')); + } + } + } catch (\Throwable $e) { } } - if ($bedNo === '' && $this->db->tableExists('bed_assignment_history')) { - $bahRow = $this->db->table('bed_assignment_history bah') - ->select('bm.bed_number, wm.ward_name, wm.ward_type') - ->join('bed_master bm', 'bm.id = bah.bed_id', 'left') - ->join('ward_master wm', 'wm.id = bah.ward_id', 'left') - ->where('bah.ipd_id', $ipdId) - ->orderBy('bah.id', 'DESC') - ->limit(1) - ->get() - ->getRowArray(); - if (! empty($bahRow)) { - $bedNo = trim((string) ($bahRow['bed_number'] ?? '')); - $wardName = trim((string) ($bahRow['ward_name'] ?? $bahRow['ward_type'] ?? '')); + + if ($bedNo === '') { + try { + if ($this->db->tableExists('ward_beds')) { + $builder = $this->db->table('ward_beds wb') + ->select('wb.bed_number'); + if ($this->db->tableExists('ward_master')) { + $builder->select('wm.ward_name') + ->join('ward_master wm', 'wm.id = wb.ward_id', 'left'); + } + $wbRow = $builder->where('wb.ipd_id', $ipdId) + ->limit(1) + ->get() + ->getRowArray(); + if (! empty($wbRow)) { + $bedNo = trim((string) ($wbRow['bed_number'] ?? '')); + $wardName = trim((string) ($wbRow['ward_name'] ?? '')); + } + } + } catch (\Throwable $e) { } } - if ($bedNo === '' && $this->db->tableExists('ward_beds')) { - $wbRow = $this->db->table('ward_beds wb') - ->select('wb.bed_number, wm.ward_name') - ->join('ward_master wm', 'wm.id = wb.ward_id', 'left') - ->where('wb.ipd_id', $ipdId) - ->limit(1) - ->get() - ->getRowArray(); - if (! empty($wbRow)) { - $bedNo = trim((string) ($wbRow['bed_number'] ?? '')); - $wardName = trim((string) ($wbRow['ward_name'] ?? '')); + + if ($bedNo === '' || $roomName === '') { + try { + if ($this->db->tableExists('ipd_master')) { + $ipd = $this->db->table('ipd_master')->where('id', $ipdId)->get(1)->getRowArray() ?? []; + if ($bedNo === '') { + $bedNo = trim((string) ($ipd['bed_no'] ?? $ipd['bed_id'] ?? '')); + } + $roomName = trim((string) ($ipd['room_no'] ?? $ipd['room_id'] ?? '')); + } + } catch (\Throwable $e) { } } - if ($bedNo === '' && $this->db->tableExists('ipd_master')) { - $ipd = $this->db->table('ipd_master')->where('id', $ipdId)->get(1)->getRowArray() ?? []; - $bedNo = trim((string) ($ipd['bed_no'] ?? $ipd['bed_id'] ?? '')); - $roomName = trim((string) ($ipd['room_no'] ?? $ipd['room_id'] ?? '')); - } } $parts = []; @@ -3102,7 +3159,12 @@ class AbdmGateway extends BaseController $billPath = $directory . DIRECTORY_SEPARATOR . 'ipd-bill.pdf'; if (! is_file($billPath) || filesize($billPath) === 0) { try { - (new \App\Controllers\Billing\Ipd())->generateIpdBillPdfBinary($ipdId, 1, true); + $billingCtrl = new \App\Controllers\Billing\Ipd(); + $request = \Config\Services::request(); + $response = \Config\Services::response(); + $logger = \Config\Services::logger(); + $billingCtrl->initController($request, $response, $logger); + $billingCtrl->generateIpdBillPdfBinary($ipdId, 1, true); } catch (\Throwable $e) { log_message('error', 'Auto-generating IPD Bill PDF failed for IPD {ipd}: {msg}', [ 'ipd' => $ipdId, diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php index 8472318..34adc21 100644 --- a/app/Controllers/Ipd_discharge.php +++ b/app/Controllers/Ipd_discharge.php @@ -8703,7 +8703,12 @@ class Ipd_discharge extends BaseController $billPath = $directory . DIRECTORY_SEPARATOR . 'ipd-bill.pdf'; if (! is_file($billPath) || filesize($billPath) === 0) { try { - (new \App\Controllers\Billing\Ipd())->generateIpdBillPdfBinary($ipdId, 1, true); + $billingCtrl = new \App\Controllers\Billing\Ipd(); + $request = \Config\Services::request(); + $response = \Config\Services::response(); + $logger = \Config\Services::logger(); + $billingCtrl->initController($request, $response, $logger); + $billingCtrl->generateIpdBillPdfBinary($ipdId, 1, true); } catch (\Throwable $e) { log_message('error', 'Auto-generating IPD Bill PDF failed for IPD {ipd}: {msg}', [ 'ipd' => $ipdId, @@ -9448,53 +9453,87 @@ class Ipd_discharge extends BaseController $wardName = ''; $roomName = ''; - if ($ipdId > 0) { - if ($this->db->tableExists('bed_master')) { - $row = $this->db->table('bed_master bm') - ->select('bm.bed_number, wm.ward_name, wm.ward_type') - ->join('ward_master wm', 'wm.id = bm.ward_id', 'left') - ->where('bm.current_ipd_id', $ipdId) - ->limit(1) - ->get() - ->getRowArray(); - if (! empty($row)) { - $bedNo = trim((string) ($row['bed_number'] ?? '')); - $wardName = trim((string) ($row['ward_name'] ?? $row['ward_type'] ?? '')); + if ($ipdId > 0 && $this->db) { + try { + if ($this->db->tableExists('bed_master')) { + $builder = $this->db->table('bed_master bm') + ->select('bm.bed_number'); + if ($this->db->tableExists('ward_master')) { + $builder->select('wm.ward_name, wm.ward_type') + ->join('ward_master wm', 'wm.id = bm.ward_id', 'left'); + } + $row = $builder->where('bm.current_ipd_id', $ipdId) + ->limit(1) + ->get() + ->getRowArray(); + if (! empty($row)) { + $bedNo = trim((string) ($row['bed_number'] ?? '')); + $wardName = trim((string) ($row['ward_name'] ?? $row['ward_type'] ?? '')); + } + } + } catch (\Throwable $e) { + } + + if ($bedNo === '') { + try { + if ($this->db->tableExists('bed_assignment_history')) { + $builder = $this->db->table('bed_assignment_history bah'); + if ($this->db->tableExists('bed_master')) { + $builder->select('bm.bed_number') + ->join('bed_master bm', 'bm.id = bah.bed_id', 'left'); + } + if ($this->db->tableExists('ward_master')) { + $builder->select('wm.ward_name, wm.ward_type') + ->join('ward_master wm', 'wm.id = bah.ward_id', 'left'); + } + $bahRow = $builder->where('bah.ipd_id', $ipdId) + ->orderBy('bah.id', 'DESC') + ->limit(1) + ->get() + ->getRowArray(); + if (! empty($bahRow)) { + $bedNo = trim((string) ($bahRow['bed_number'] ?? '')); + $wardName = trim((string) ($bahRow['ward_name'] ?? $bahRow['ward_type'] ?? '')); + } + } + } catch (\Throwable $e) { } } - if ($bedNo === '' && $this->db->tableExists('bed_assignment_history')) { - $bahRow = $this->db->table('bed_assignment_history bah') - ->select('bm.bed_number, wm.ward_name, wm.ward_type') - ->join('bed_master bm', 'bm.id = bah.bed_id', 'left') - ->join('ward_master wm', 'wm.id = bah.ward_id', 'left') - ->where('bah.ipd_id', $ipdId) - ->orderBy('bah.id', 'DESC') - ->limit(1) - ->get() - ->getRowArray(); - if (! empty($bahRow)) { - $bedNo = trim((string) ($bahRow['bed_number'] ?? '')); - $wardName = trim((string) ($bahRow['ward_name'] ?? $bahRow['ward_type'] ?? '')); + + if ($bedNo === '') { + try { + if ($this->db->tableExists('ward_beds')) { + $builder = $this->db->table('ward_beds wb') + ->select('wb.bed_number'); + if ($this->db->tableExists('ward_master')) { + $builder->select('wm.ward_name') + ->join('ward_master wm', 'wm.id = wb.ward_id', 'left'); + } + $wbRow = $builder->where('wb.ipd_id', $ipdId) + ->limit(1) + ->get() + ->getRowArray(); + if (! empty($wbRow)) { + $bedNo = trim((string) ($wbRow['bed_number'] ?? '')); + $wardName = trim((string) ($wbRow['ward_name'] ?? '')); + } + } + } catch (\Throwable $e) { } } - if ($bedNo === '' && $this->db->tableExists('ward_beds')) { - $wbRow = $this->db->table('ward_beds wb') - ->select('wb.bed_number, wm.ward_name') - ->join('ward_master wm', 'wm.id = wb.ward_id', 'left') - ->where('wb.ipd_id', $ipdId) - ->limit(1) - ->get() - ->getRowArray(); - if (! empty($wbRow)) { - $bedNo = trim((string) ($wbRow['bed_number'] ?? '')); - $wardName = trim((string) ($wbRow['ward_name'] ?? '')); + + if ($bedNo === '' || $roomName === '') { + try { + if ($this->db->tableExists('ipd_master')) { + $ipd = $this->db->table('ipd_master')->where('id', $ipdId)->get(1)->getRowArray() ?? []; + if ($bedNo === '') { + $bedNo = trim((string) ($ipd['bed_no'] ?? $ipd['bed_id'] ?? '')); + } + $roomName = trim((string) ($ipd['room_no'] ?? $ipd['room_id'] ?? '')); + } + } catch (\Throwable $e) { } } - if ($bedNo === '' && $this->db->tableExists('ipd_master')) { - $ipd = $this->db->table('ipd_master')->where('id', $ipdId)->get(1)->getRowArray() ?? []; - $bedNo = trim((string) ($ipd['bed_no'] ?? $ipd['bed_id'] ?? '')); - $roomName = trim((string) ($ipd['room_no'] ?? $ipd['room_id'] ?? '')); - } } $parts = [];