diff --git a/app/Config/AuthGroups.php b/app/Config/AuthGroups.php index 367e071..011bbbf 100644 --- a/app/Config/AuthGroups.php +++ b/app/Config/AuthGroups.php @@ -131,6 +131,7 @@ class AuthGroups extends ShieldAuthGroups 'billing.ipd.admission.edit' => 'Can edit IPD admission details (date, mode, department, refer, doctors, contact, clinical notes)', 'billing.ipd.bill.print' => 'Can print IPD bill variants', 'billing.ipd.discharge.edit' => 'Can edit IPD discharge process details (discount, extra charges, status, date, time)', + 'billing.ipd.status.manage' => 'Can toggle IPD status between Active and Discharged (controls bill edit lock)', 'settings.bed_status.view' => 'Can view bed status and bed management screens', 'settings.charges.access' => 'Can access charges settings', 'reports.access' => 'Can access reports section', diff --git a/app/Controllers/Billing/Ipd.php b/app/Controllers/Billing/Ipd.php index 84b1454..4195bb9 100644 --- a/app/Controllers/Billing/Ipd.php +++ b/app/Controllers/Billing/Ipd.php @@ -879,6 +879,57 @@ class Ipd extends BaseController return $this->buildDischargeProcessResponse($ipdId, 'Discharge status updated.'); } + public function toggleIpdStatus(int $ipdId) + { + $permission = $this->requireAnyPermission([ + 'billing.ipd.status.manage', + ]); + if ($permission) { + return $permission; + } + + if (! $this->request->isAJAX()) { + return $this->response->setStatusCode(400)->setJSON(['update' => 0, 'message' => 'Invalid request']); + } + + $fieldMap = $this->getIpdFieldMap(); + if (! isset($fieldMap['ipd_status'])) { + return $this->response->setStatusCode(422)->setJSON([ + 'update' => 0, + 'message' => 'ipd_status field not available in schema' + ]); + } + + $newStatus = (int) ($this->request->getPost('ipd_status') ?? -1); + if ($newStatus !== 0 && $newStatus !== 1) { + return $this->response->setStatusCode(422)->setJSON([ + 'update' => 0, + 'message' => 'Invalid status value (must be 0 or 1)' + ]); + } + + // Get current status + $currentIpd = $this->ipdModel->getById($ipdId); + if (! $currentIpd) { + return $this->response->setStatusCode(404)->setJSON(['update' => 0, 'message' => 'IPD not found']); + } + + $currentStatus = (int) ($currentIpd['ipd_status'] ?? 0); + + // Update status + $update = ['ipd_status' => $newStatus]; + $this->ipdEditModel->updateIpd($update, $ipdId); + + // Release bed when setting to discharged (status = 1) + if ($newStatus === 1 && $currentStatus === 0) { + $this->ipdEditModel->releaseBed($ipdId); + } + + $statusText = $newStatus === 0 ? 'Active (Bills unlocked)' : 'Discharged (Bills locked)'; + + return $this->buildDischargeProcessResponse($ipdId, 'IPD status set to: ' . $statusText); + } + public function billPrint(int $ipdId, int $mode = 1) { $permission = $this->requireAnyPermission([ diff --git a/app/Controllers/Medical.php b/app/Controllers/Medical.php index 23c3991..1b2be6d 100644 --- a/app/Controllers/Medical.php +++ b/app/Controllers/Medical.php @@ -3511,21 +3511,10 @@ class Medical extends BaseController return false; } - foreach (['ipd_status', 'discharge_status', 'discharg_status', 'is_discharged'] as $statusCol) { - if (in_array($statusCol, $ipdFields, true) && (int) ($ipd[$statusCol] ?? 0) !== 0) { - return true; - } - } - - foreach (['discharge_date', 'discharge_datetime', 'discharged_at'] as $dateCol) { - if (! in_array($dateCol, $ipdFields, true)) { - continue; - } - - $value = trim((string) ($ipd[$dateCol] ?? '')); - if ($value !== '' && $value !== '0000-00-00' && $value !== '0000-00-00 00:00:00') { - return true; - } + // PRIMARY CHECK ONLY: ipd_status = 1 means discharged + // No fallback checks - this gives flexibility to edit bills even if discharge_date is set + if (in_array('ipd_status', $ipdFields, true)) { + return (int) ($ipd['ipd_status'] ?? 0) === 1; } return false; diff --git a/app/Views/billing/ipd/panel_discharge.php b/app/Views/billing/ipd/panel_discharge.php index ea6ba42..a848ecf 100644 --- a/app/Views/billing/ipd/panel_discharge.php +++ b/app/Views/billing/ipd/panel_discharge.php @@ -22,6 +22,25 @@ if (strlen($dischargeTime) > 5) { } ?> +ipd_status ?? 0); +$canManageIpdStatus = auth()->user()?->can('billing.ipd.status.manage') ?? false; +?> + + +