feat(clinical): favourite diagnosis API — weight range support, no-filter fallbacks, and channel report summaries#21453
Conversation
…from clinical queue When an OPD prescription is written in Prescriptions Given on the EMR visit page (emr/opd_visit.xhtml) and the user clicks Pharmacy Bill on the clinical queue (clinical/clinical_queue.xhtml), the prescribed medicines now load automatically onto the retail sale bill - matching the inward flow where admission prescriptions are converted to pharmacy dispensing notes. Root cause: PracticeBookingController.issuePharmacyBill() loaded the encounter medicines and iterated them with an empty loop body - the conversion to bill items was never implemented. Only the patient, referring doctor and prescription text (as a comment) reached the retail sale page. Changes: - PharmacySaleController.addBillItemsFromEncounterMedicines(): converts each VisitMedicine prescription to a bill item. Resolves dispensable item and quantity via PrescriptionToItemService (qty defaults to 1 when the prescription is incomplete so the pharmacist adjusts it on the page), auto-picks an earliest-expiry (FEFO) in-date stock batch from the logged-in user's department, resolving VMP/VTM prescriptions to candidate AMPs via PharmacyBean.resolveAmps(). - Items are added through the existing addBillItemSingleItem() so all retail-sale safeguards apply unchanged: expiry check, stock quantity check, duplicate batch check, UserStock locking and allergy check. - Dose, frequency, duration and comment are carried onto the bill item's prescription so bill descriptions and drug label printing work as in the inward discharge issue flow. - Medicines that cannot be auto-added (no stock, conversion failure, duplicate batch) are reported in a visible warning, never silently dropped. - PracticeBookingController.issuePharmacyBill(): replaced the empty placeholder loop with a call to the new conversion method. Mirrors PharmacySaleBhtController.prepareDischargeIssueFromPrescriptions (issue #21334) for the OPD retail sale path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ility Rework clinical/clinical_queue.xhtml to follow the project UI and accessibility-first guidelines: - Replace the h:panelGrid filter layout with a responsive Bootstrap row/col grid; labels bound to inputs via p:outputLabel for=... - Add stable ids to every actionable control (btnProcess, btnVisit, btnMarkPresent, btnMarkAbsent, btnEditVisit, btnViewVisit, btnOpdBill, btnPharmacyBill) and descriptive title attributes that include the patient name and queue number, so Playwright/automation can target individual rows. - Cap both speciality and doctor autocompletes with maxResults="20" and add placeholders. - Date/doctor filter changes now re-render the whole queue form (render=":queueForm") instead of a single resolved component id. - DataTables: add widgetVar and rowKey, pagination (25 rows, bottom, hidden when not needed), emptyMessage texts, and a row highlight for absent patients in the To Complete tab. - To Complete tab gains Age, Phone and a Waiting/Absent status badge column; both tab titles show live session counts. - Consistent icon set and button styling (success/info/danger/warning variants) across row actions; growl shows message details. JSF-only change - no Java modifications. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o favourite medicines API - Add GET /clinical/favourite_medicines/entities/diagnoses to search ClinicalEntity records (Disease_or_Syndrome) for use as forItemName - Support type=FavouriteMedicine (default) / type=FavouriteDiagnosis on create, search, and by-id endpoints - Resolve forItemName to a diagnosis for FavouriteDiagnosis templates, with "did you mean" suggestions on mismatch - Register the new endpoint and capability in CapabilityStatementResource and the AI chat module listing Closes #21452
…ourite diagnosis/medicine, and channel report cashier summaries - FavouriteMedicineApiService: add fromKg/toKg weight range fields to templates; make age range optional when weight range is provided; validate weight ranges - PatientEncounterController: add method 4 (no age/weight filter) fallback so favourites load even when patient DOB/weight aren't recorded; validate a medicine is selected before 'Add Favourite'; fall back to FavouriteDiagnosis template directly when no separate FavouriteMedicine config exists - PastPatientEncounterController: detect legacy prescriptions persisted with null or VisitDocument type via DocumentTemplateType.Prescription, default new prescriptions to VisitPrescription type - PracticeBookingController: separate prescriptionHtml (rich text) from plain comment via htmlToPlainText(); clear stale prescription when switching encounters - ChannelReportTempController: add fetchBillsTotal, fetchCashiers, fetchUserRows, fetchDateRangeRows with WebUser/agency support for cashier-based channel reporting - FavouriteMedicineApi: serialize fromKg/toKg in API responses - PharmacyBean: fallback VMP lookup via direct VMP.VTM_ID when VirtualProductIngredient join table is unpopulated - Privileges/UserPrivilageController: add PharmacyItemNameEdit privilege - pharmacy_bill_retail_sale.xhtml: add toggleable prescription preview panel rendering prescriptionHtml - lab_vmp/vtm, store_atm/vtm XHTML: gate Add/Edit/Save buttons behind PharmacyItemNameEdit privilege - opd_visit.xhtml: process acMedicine + dose/frequency/duration fields when adding a favourite, so the current selection is captured Co-Authored-By: Claude <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 1 minute and 57 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR extends the clinical and pharmacy subsystems with three major themes: adding FavouriteDiagnosis API support for diagnosis-driven medicine recommendations, standardizing prescription typing and integrating encounter medicines into pharmacy retail sales, introducing a new pharmacy edit privilege with UI enforcement, and restructuring the clinical queue UI with paginated tables and improved filtering. ChangesFavouriteDiagnosis API and Type-Aware Template Management
Prescription Typing Standardization and Encounter Favorite Selection
Pharmacy Encounter Billing from Prescriptions
PharmacyItemNameEdit Privilege Enforcement
Clinical Queue Page Restructure and Table Rebuild
Sequence Diagram(s)sequenceDiagram
participant Client
participant FavouriteMedicineApi
participant FavouriteMedicineService
participant ClinicalEntityFacade
participant DiagnosisRepository
Client->>FavouriteMedicineApi: GET /favourite_medicines/entities/diagnoses?query=URTI
FavouriteMedicineApi->>FavouriteMedicineService: searchDiagnoses(query)
FavouriteMedicineService->>ClinicalEntityFacade: findByNameLike(query, SymanticType.Disease_or_Syndrome)
ClinicalEntityFacade->>DiagnosisRepository: JPQL disease_or_syndrome filtered query
DiagnosisRepository-->>ClinicalEntityFacade: List<ClinicalEntity> diagnoses
ClinicalEntityFacade-->>FavouriteMedicineService: matched diagnosis records
FavouriteMedicineService-->>FavouriteMedicineApi: List<ClinicalEntity>
FavouriteMedicineApi-->>Client: JSON response with type=FavouriteDiagnosis, forItem=diagnosis
sequenceDiagram
participant PatientEncounter
participant PracticeBooking
participant PharmacySale
participant PrescriptionToItemService
participant PharmacyBean
PatientEncounter->>PatientEncounter: fillEncounterPrescreptions()
PatientEncounter-->>PatientEncounter: List of VisitPrescription + legacy
PracticeBooking->>PracticeBooking: issuePharmacyBill(opdVisit)
PracticeBooking->>PharmacySale: prescriptionHtml = HTML
PracticeBooking->>PharmacySale: addBillItemsFromEncounterMedicines(medicines)
PharmacySale->>PrescriptionToItemService: convert each medicine
PrescriptionToItemService-->>PharmacySale: conversion results
PharmacySale->>PharmacyBean: resolveAmps(item)
PharmacyBean-->>PharmacySale: list of dispensable items
PharmacySale->>PharmacySale: findFefoStockForPrescribedItem()
PharmacySale->>PharmacySale: addBillItemSingleItem() per item
PharmacySale-->>PharmacySale: retail sale bill ready with medicines+prescription
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR validation failed because local JNDI names (jdbc/coop, jdbc/rhAuditDS)
were committed in the branch history instead of the CI/CD placeholders
(${JDBC_DATASOURCE}, ${JDBC_AUDIT_DATASOURCE}).
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9f7b6ddaf3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/main/java/com/divudi/service/clinical/FavouriteMedicineApiService.java (1)
233-235:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPreserve
IllegalArgumentExceptioninstead of wrapping everything asRuntimeException.These catch blocks convert new request-validation failures (invalid
type, age/weight ranges, etc.) into 500 errors, which breaks client error semantics.Proposed fix
- } catch (Exception e) { + } catch (IllegalArgumentException e) { + throw e; + } catch (Exception e) { throw new RuntimeException("Failed to create favourite medicine: " + e.getMessage(), e); }- } catch (Exception e) { + } catch (IllegalArgumentException e) { + throw e; + } catch (Exception e) { throw new RuntimeException("Failed to search favourite medicines: " + e.getMessage(), e); }- } catch (Exception e) { + } catch (IllegalArgumentException e) { + throw e; + } catch (Exception e) { throw new RuntimeException("Failed to update favourite medicine: " + e.getMessage(), e); }Also applies to: 357-359, 455-457
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/divudi/service/clinical/FavouriteMedicineApiService.java` around lines 233 - 235, The catch blocks in FavouriteMedicineApiService that currently do "catch (Exception e) { throw new RuntimeException(..., e); }" (seen around the create/update/delete flows at the three occurrences) are converting client validation failures like IllegalArgumentException into 500s; update each of those catch sites to preserve IllegalArgumentException by rethrowing it unchanged (or throw it as-is) and only wrap/translate other unexpected Exceptions into RuntimeException (or an appropriate server error). Locate the catch blocks in the FavouriteMedicineApiService class (the create/update/delete handlers around the reported spots) and replace the single broad catch with a two-branch handling: catch IllegalArgumentException and rethrow, then catch Exception and wrap as before.src/main/java/com/divudi/ws/clinical/FavouriteMedicineApi.java (1)
110-134:⚠️ Potential issue | 🟠 Major | ⚡ Quick winReturn 400 for invalid search
typeinstead of 500.Now that
typeis accepted in query params, invalid values should be treated as client input errors. The current handler maps them to 500.Proposed fix
public Response searchFavouriteMedicines() { try { @@ return successResponse(responseData); + } catch (IllegalArgumentException e) { + return errorResponse("Invalid request: " + e.getMessage(), 400); } catch (Exception e) { return errorResponse("An error occurred: " + e.getMessage(), 500); } }Also applies to: 1008-1012
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/divudi/ws/clinical/FavouriteMedicineApi.java` around lines 110 - 134, The handler searchFavouriteMedicines currently maps invalid query 'type' values to a 500; validate the 'type' earlier (in parseSearchParams or immediately after it) and return a 400 Bad Request when the value is unknown/invalid. Concretely, update parseSearchParams (or add a small validation in searchFavouriteMedicines) to detect invalid 'type' and throw an IllegalArgumentException or return a validation error, then catch that specific exception (or check the validation result) and call errorResponse(..., 400) instead of letting it propagate to the generic 500 handler; apply the same change to the other similar handler mentioned (the block around lines 1008-1012) so invalid client input consistently returns 400.
🧹 Nitpick comments (2)
src/main/java/com/divudi/bean/channel/ChannelReportTempController.java (1)
448-479: ⚖️ Poor tradeoffConsider batching queries to reduce database round-trips.
This method executes 9 database queries per cashier (3 bill-type counts + 6 sum queries). For reports with many cashiers, this compounds quickly (e.g., 10 cashiers = 90 queries). A single aggregate query with GROUP BY could fetch all metrics in one round-trip.
This is acceptable for small user counts but may become a bottleneck at scale.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/divudi/bean/channel/ChannelReportTempController.java` around lines 448 - 479, fetchUserRows currently calls fetchBillsTotal repeatedly per cashier (inside fetchUserRows and via fetchCashiers), causing N*9 DB queries; replace this with a single aggregated query: add a new DAO/service method (e.g., fetchAggregatedBillMetrics or fetchBillMetricsByUser) that accepts the same filters (fDate, tDate, bts, bill type distinctions and flags used in fetchBillsTotal) and returns per-WebUser aggregates (billCount, canceledCount, refundCount, netTotal, hosTotal) in one GROUP BY webUser result (or a Map<WebUser, Metrics>); then modify fetchUserRows to call that new method once, iterate the returned aggregates to build ChannelSummeryUserRow objects, set totals (tbc, tcc, trc, tht, tst) and only call fetchCashiers to preserve order/filtering if needed—this reduces DB round-trips by consolidating the 9 per-user fetchBillsTotal calls into a single grouped query.src/main/java/com/divudi/bean/clinical/PatientEncounterController.java (1)
1511-1512: ⚡ Quick winRemove debug
System.out.printlnstatements before merging.The method contains numerous debug statements (approximately 40+) throughout
addFavouriteDiagnosis(). These should be removed or converted to proper logging at an appropriate level (e.g.,FINEorDEBUG) before production.Example locations to clean up
Lines containing
System.out.println("DEBUG: ...)throughout the method body (1511-1778).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/divudi/bean/clinical/PatientEncounterController.java` around lines 1511 - 1512, The method addFavouriteDiagnosis() contains many System.out.println debug statements (e.g., those printing patient and selectedDiagnosis) that must be removed before merging; replace them with proper logger calls (use the existing logger instance or create a private static final Logger) at an appropriate level (FINE/DEBUG) or delete them entirely, ensuring you update all occurrences inside addFavouriteDiagnosis() and any helper methods referenced there so no System.out.println calls remain and contextual info uses logger.debug/logger.fine with patient.getPerson().getNameWithTitle(), selectedDiagnosis.getName(), and other referenced variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/divudi/bean/channel/ChannelReportTempController.java`:
- Around line 251-259: Check for null on the Bill variable b before calling
b.getClass() (move the null-guard to the top of the method or before these class
checks) and replace the direct getClass() comparisons with safer instanceof
checks for BilledBill, CancelledBill, and RefundBill; additionally ensure you
always append a date filter to the sql by adding a fallback date clause (e.g.,
"and b.createdAt between :fromDate and :toDate") when none of the specific
bill-type conditions match so the query cannot return unbounded results.
In `@src/main/java/com/divudi/bean/clinical/PracticeBookingController.java`:
- Around line 387-391: The PharmacySaleController is session-scoped and its
preBill must be cleared before auto-loading a new encounter; update
PracticeBookingController so that after obtaining the PharmacySaleController
(via getPharmacySaleController()) and before seeding patient/prescription/bill
items (i.e. before calling addBillItemsFromEncounterMedicines), call the
controller's resetAll() or clearBill() method to clear previous draft state
(preBill, comments, payments, and stock locks), then proceed to
addBillItemsFromEncounterMedicines(encounterMedicines).
In `@src/main/java/com/divudi/bean/pharmacy/PharmacySaleController.java`:
- Around line 1877-1892: The code currently defaults to requiredQty=1 when
calculateItemAndQuantity fails or throws; instead, mirror the discharge
conversion flow by treating failed or exceptional conversions as "skip
conversion" and do not auto-add a qty=1. Specifically, in the block that calls
prescriptionToItemService.calculateItemAndQuantity(sourcePrescription) (and
handles PrescriptionToItemService.PrescriptionToItemResult), only set
dispensableItem and calculatedQty when result != null && result.isSuccess(); if
result is null, !isSuccess(), or an exception occurs, clear/leave
dispensableItem null (or set a flag) and avoid computing requiredQty = 1.0 so
downstream logic that relies on dispensableItem/requiredQty will skip adding the
item instead of billing one unit.
In `@src/main/webapp/clinical/clinical_queue.xhtml`:
- Around line 231-234: Replace the stale global encounter binding and bind the
pharmacy patient from the selected row object instead: change the second
<f:setPropertyActionListener> that currently sets
target="#{pharmacySaleController.patient}" with
value="#{practiceBookingController.opdVisit.patient}" to use the row variable
(bsc) patient (e.g. value="#{bsc.patient}") so pharmacySaleController.patient is
populated from the clicked row rather than
practiceBookingController.opdVisit.patient.
- Around line 21-78: The form filterForm allows Enter to submit unintentionally;
guard it by adding a key handler on the <h:form id="filterForm"> to prevent
default when Enter is pressed (e.g., onkeydown checking event.key === 'Enter' or
keyCode === 13 and calling event.preventDefault()), leaving the Process button
(btnProcess) as the explicit submit trigger and keeping existing listeners
(practiceBookingController.listCompleteAndToCompleteBillSessions) and
autocomplete/calendar components (calSessionDate, acSpeciality, acStaff)
unchanged.
- Around line 212-235: The OPD and Pharmacy bill buttons (p:commandButton
id="btnOpdBill" calling practiceBookingController.issueServices() and
id="btnPharmacyBill" calling practiceBookingController.issuePharmacyBill() /
actionListener pharmacySaleController.resetAll()) lack double-submit protection;
add a client-side JavaScript confirm prompt to both buttons (e.g., onclick that
returns confirm(...)) to require explicit user confirmation before submission,
and implement a server-side re-entrancy guard inside the target methods
(practiceBookingController.issueServices and
practiceBookingController.issuePharmacyBill) that checks and sets a short-lived
in-memory or DB flag on billSession (or the underlying booking/bill entity) to
ignore duplicate requests if already processing/completed; ensure the
f:setPropertyActionListener usages for billSession and
pharmacySaleController.patient remain but only proceed when the server-side
guard permits execution.
In `@src/main/webapp/pharmacy/pharmacy_bill_retail_sale.xhtml`:
- Line 958: The view currently renders unescaped HTML via h:outputText
value="#{pharmacySaleController.prescriptionHtml}" escape="false", which allows
XSS; change the page to render only a sanitized/allowlisted HTML property (e.g.,
prescriptionHtmlSafe) or re-enable escaping (escape="true") and move
sanitization into the controller; in PharmacySaleController add a getter that
returns a sanitized version of prescriptionHtml using a trusted sanitizer (OWASP
HTML Sanitizer or a strict allowlist), expose that sanitized property to the
view and replace escape="false" with the safe property (or keep escape enabled)
so only cleaned markup is rendered.
---
Outside diff comments:
In `@src/main/java/com/divudi/service/clinical/FavouriteMedicineApiService.java`:
- Around line 233-235: The catch blocks in FavouriteMedicineApiService that
currently do "catch (Exception e) { throw new RuntimeException(..., e); }" (seen
around the create/update/delete flows at the three occurrences) are converting
client validation failures like IllegalArgumentException into 500s; update each
of those catch sites to preserve IllegalArgumentException by rethrowing it
unchanged (or throw it as-is) and only wrap/translate other unexpected
Exceptions into RuntimeException (or an appropriate server error). Locate the
catch blocks in the FavouriteMedicineApiService class (the create/update/delete
handlers around the reported spots) and replace the single broad catch with a
two-branch handling: catch IllegalArgumentException and rethrow, then catch
Exception and wrap as before.
In `@src/main/java/com/divudi/ws/clinical/FavouriteMedicineApi.java`:
- Around line 110-134: The handler searchFavouriteMedicines currently maps
invalid query 'type' values to a 500; validate the 'type' earlier (in
parseSearchParams or immediately after it) and return a 400 Bad Request when the
value is unknown/invalid. Concretely, update parseSearchParams (or add a small
validation in searchFavouriteMedicines) to detect invalid 'type' and throw an
IllegalArgumentException or return a validation error, then catch that specific
exception (or check the validation result) and call errorResponse(..., 400)
instead of letting it propagate to the generic 500 handler; apply the same
change to the other similar handler mentioned (the block around lines 1008-1012)
so invalid client input consistently returns 400.
---
Nitpick comments:
In `@src/main/java/com/divudi/bean/channel/ChannelReportTempController.java`:
- Around line 448-479: fetchUserRows currently calls fetchBillsTotal repeatedly
per cashier (inside fetchUserRows and via fetchCashiers), causing N*9 DB
queries; replace this with a single aggregated query: add a new DAO/service
method (e.g., fetchAggregatedBillMetrics or fetchBillMetricsByUser) that accepts
the same filters (fDate, tDate, bts, bill type distinctions and flags used in
fetchBillsTotal) and returns per-WebUser aggregates (billCount, canceledCount,
refundCount, netTotal, hosTotal) in one GROUP BY webUser result (or a
Map<WebUser, Metrics>); then modify fetchUserRows to call that new method once,
iterate the returned aggregates to build ChannelSummeryUserRow objects, set
totals (tbc, tcc, trc, tht, tst) and only call fetchCashiers to preserve
order/filtering if needed—this reduces DB round-trips by consolidating the 9
per-user fetchBillsTotal calls into a single grouped query.
In `@src/main/java/com/divudi/bean/clinical/PatientEncounterController.java`:
- Around line 1511-1512: The method addFavouriteDiagnosis() contains many
System.out.println debug statements (e.g., those printing patient and
selectedDiagnosis) that must be removed before merging; replace them with proper
logger calls (use the existing logger instance or create a private static final
Logger) at an appropriate level (FINE/DEBUG) or delete them entirely, ensuring
you update all occurrences inside addFavouriteDiagnosis() and any helper methods
referenced there so no System.out.println calls remain and contextual info uses
logger.debug/logger.fine with patient.getPerson().getNameWithTitle(),
selectedDiagnosis.getName(), and other referenced variables.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 718eb4b1-88c2-44ad-a78b-9a73f61d694f
📒 Files selected for processing (20)
src/main/java/com/divudi/bean/channel/ChannelReportTempController.javasrc/main/java/com/divudi/bean/clinical/PastPatientEncounterController.javasrc/main/java/com/divudi/bean/clinical/PatientEncounterController.javasrc/main/java/com/divudi/bean/clinical/PracticeBookingController.javasrc/main/java/com/divudi/bean/common/UserPrivilageController.javasrc/main/java/com/divudi/bean/pharmacy/PharmacySaleController.javasrc/main/java/com/divudi/core/data/Privileges.javasrc/main/java/com/divudi/core/data/dto/clinical/FavouriteMedicineCreateRequestDTO.javasrc/main/java/com/divudi/ejb/PharmacyBean.javasrc/main/java/com/divudi/service/AnthropicApiService.javasrc/main/java/com/divudi/service/clinical/FavouriteMedicineApiService.javasrc/main/java/com/divudi/ws/clinical/FavouriteMedicineApi.javasrc/main/java/com/divudi/ws/common/CapabilityStatementResource.javasrc/main/webapp/clinical/clinical_queue.xhtmlsrc/main/webapp/emr/opd_visit.xhtmlsrc/main/webapp/pharmacy/admin/lab_vmp.xhtmlsrc/main/webapp/pharmacy/admin/lab_vtm.xhtmlsrc/main/webapp/pharmacy/admin/store_atm.xhtmlsrc/main/webapp/pharmacy/admin/store_vtm.xhtmlsrc/main/webapp/pharmacy/pharmacy_bill_retail_sale.xhtml
- ChannelReportTempController.java: guard b.getClass() calls at lines 251-259 behind a null check — consistent with the existing null guard at line 280 - clinical_queue.xhtml: add onclick=this.disabled=true on btnOpdBill and btnPharmacyBill to prevent accidental double-issue - clinical_queue.xhtml: bind pharmacySaleController.patient from bsc.bill.patient (selected row) rather than the stale practiceBookingController.opdVisit.patient Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/webapp/clinical/clinical_queue.xhtml`:
- Line 218: Remove the client-side disabling that breaks non-AJAX JSF form
submits: locate the p:commandButton(s) using onclick="this.disabled=true;" (the
primary form submit buttons with ajax="false") and remove that onclick
attribute; instead implement double-submit prevention via a confirm() dialog on
the client or add server-side re-entrancy guard logic in the backing bean (e.g.,
a submission-in-progress flag checked/updated in the action method). Also remove
the same onclick pattern on the other occurrence noted (the second button
instance) so the button name/value is preserved on POST.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7200585d-22f6-445e-ad62-95622d83f86b
📒 Files selected for processing (2)
src/main/java/com/divudi/bean/channel/ChannelReportTempController.javasrc/main/webapp/clinical/clinical_queue.xhtml
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/java/com/divudi/bean/channel/ChannelReportTempController.java
…m guard
Replace `onclick="this.disabled=true;"` on btnOpdBill and btnPharmacyBill
with `onclick="if (!confirm('…')) return false;"` per the codebase UI
guidelines (developer_docs/ui/comprehensive-ui-guidelines.md §358–363).
Disabling the button synchronously in onclick before the form POST fires
excludes the button's name/value from the request, potentially breaking
JSF action dispatch on ajax=false PrimeFaces command buttons.
Co-Authored-By: Claude <noreply@anthropic.com>
Summary
Completes the favourite diagnosis/medicine API work described in #21452, adding weight range support to the API, no-filter fallbacks for clinical workflows when patient age/weight aren't recorded, channel report cashier summaries, a new pharmacy privilege, and several clinical workflow fixes.
Changes
Favourite Medicine/Diagnosis API
FavouriteMedicineApiServicenow acceptsfromKg/toKgfields; age range is made optional when weight range is providedFavouriteMedicineApiserializesfromKg/toKgin JSON responsesClinical Workflow (OPD Visit)
PatientEncounterControlleradds a method 4 fallback that loads favourite configurations even when patient DOB/weight aren't recorded, so doctors still get suggestionsFavouriteMedicineconfig exists for a diagnosis-recommended medicine, theFavouriteDiagnosistemplate's own dose/frequency/duration is used directlyPatientEncounterControllerandPastPatientEncounterControllernow detect prescriptions saved with legacynullorVisitDocumenttype by checkingDocumentTemplateType.Prescription; new prescriptions default toVisitPrescriptionPrescription → Pharmacy
PracticeBookingControllernow setsprescriptionHtml(rich Quill HTML) and converts it to plain text for the bill comment viahtmlToPlainText()pharmacy_bill_retail_sale.xhtmlshows a toggleable panel rendering the prescription HTMLChannel Reports
ChannelReportTempControlleraddsfetchBillsTotal,fetchBillsTotalSessoin,fetchCashiers,fetchUserRows,fetchDateRangeRowswith WebUser/agency supportPharmacy Administration
PharmacyItemNameEdit— registered inPrivilegesenum,getCategory(), andUserPrivilageControllertree; gates Add/Edit/Save on VMP/VTM/ATM admin pagesPharmacyBeanfalls back to directVMP.VTM_IDwhenVirtualProductIngredientjoin table is unpopulatedCloses #21452
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Security