From f23e613b08e303eb2af5cbe665f059daecf866c2 Mon Sep 17 00:00:00 2001 From: buddhika Date: Sun, 14 Jun 2026 15:50:42 +0530 Subject: [PATCH 1/2] fix: re-fetch PatientRoom from DB before admin discharge validation BhtSummeryController is @SessionScoped, so patientEncounter.currentPatientRoom is a stale in-memory entity loaded at page-open time. After the user performs room discharge, the DB record is updated but the session-held Java object still has dischargedAt=null, causing the discharge() guard to block administrative discharge even when the room is fully discharged in the DB. Fix: call patientRoomFacade.find() to get a fresh PatientRoom before checking dischargedAt, bypassing the stale session-scoped reference. Closes #21480 Co-Authored-By: Claude Sonnet 4.6 --- .../java/com/divudi/bean/inward/BhtSummeryController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/divudi/bean/inward/BhtSummeryController.java b/src/main/java/com/divudi/bean/inward/BhtSummeryController.java index 5486c5ab8d..20efa9e677 100644 --- a/src/main/java/com/divudi/bean/inward/BhtSummeryController.java +++ b/src/main/java/com/divudi/bean/inward/BhtSummeryController.java @@ -1731,7 +1731,11 @@ public void discharge() { if (getPatientEncounter().getAdmissionType() != null && getPatientEncounter().getAdmissionType().isRoomChargesAllowed()) { - if (getPatientEncounter().getCurrentPatientRoom() != null && getPatientEncounter().getCurrentPatientRoom().getDischargedAt() == null) { + PatientRoom currentRoom = getPatientEncounter().getCurrentPatientRoom(); + if (currentRoom != null) { + currentRoom = patientRoomFacade.find(currentRoom.getId()); + } + if (currentRoom != null && currentRoom.getDischargedAt() == null) { JsfUtil.addErrorMessage("Cannot discharge patient: the current room has not been discharged. " + "Please discharge the room first to record an accurate billing end time."); return; } From b171dc197782281d4cffed7ee43cd0b92470f7a4 Mon Sep 17 00:00:00 2001 From: buddhika Date: Sun, 14 Jun 2026 16:38:46 +0530 Subject: [PATCH 2/2] fix: re-fetch PatientEncounter to get authoritative currentPatientRoom FK Previous fix re-fetched the PatientRoom by the session-cached FK, but that FK itself can be stale when a room change happens after the Interim Bill page loads: RoomChangeController updates PatientEncounter.currentPatientRoom in the DB, but the session-scoped object still holds the old room reference. Checking the old room (which is already discharged) lets the guard pass while the new current room is still active. Fix: fetch a fresh PatientEncounter via patientEncounterFacade.find() to obtain the authoritative currentPatientRoom FK from the DB/L2 cache, then check that room's dischargedAt. This covers both the simple room-discharge-before-admin- discharge scenario and the room-change-then-admin-discharge scenario. Addresses Codex review comment on PR #21481. Co-Authored-By: Claude Sonnet 4.6 --- .../com/divudi/bean/inward/BhtSummeryController.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/divudi/bean/inward/BhtSummeryController.java b/src/main/java/com/divudi/bean/inward/BhtSummeryController.java index 20efa9e677..808a186f5a 100644 --- a/src/main/java/com/divudi/bean/inward/BhtSummeryController.java +++ b/src/main/java/com/divudi/bean/inward/BhtSummeryController.java @@ -1731,10 +1731,13 @@ public void discharge() { if (getPatientEncounter().getAdmissionType() != null && getPatientEncounter().getAdmissionType().isRoomChargesAllowed()) { - PatientRoom currentRoom = getPatientEncounter().getCurrentPatientRoom(); - if (currentRoom != null) { - currentRoom = patientRoomFacade.find(currentRoom.getId()); - } + // Re-fetch the encounter from the DB/L2 cache to get the authoritative currentPatientRoom FK. + // The session-scoped patientEncounter may be stale: a room change via RoomChangeController + // updates PatientEncounter.currentPatientRoom in the DB but not in this session object, + // so reading currentPatientRoom directly from the session would check the OLD room (which + // is already discharged) and incorrectly let the guard pass while the new room is still active. + PatientEncounter freshEncounter = patientEncounterFacade.find(getPatientEncounter().getId()); + PatientRoom currentRoom = freshEncounter != null ? freshEncounter.getCurrentPatientRoom() : null; if (currentRoom != null && currentRoom.getDischargedAt() == null) { JsfUtil.addErrorMessage("Cannot discharge patient: the current room has not been discharged. " + "Please discharge the room first to record an accurate billing end time."); return;