Integrate Final Diagnosis with canonical disease master data and add reusable My/Master template CRUD for discharge narrative sections, including summary investigations, course, other advice, and discharge summary.
Restore surgery and procedure bindings after SPA updates, validate procedure dates without SQL errors, and prevent medicine autocomplete Enter from submitting while preserving layout and autofill.
Load referral master data into patient registration/edit screens, persist patient referby, expose searchable referral inputs in patient and IPD forms, and make referral title editable as free text in referral master CRUD.
- Fix groupWorkflowRowsIntoSessions() to correlate workflow rows by stable
request_id/abdm_consent_request_id instead of chronological proximity to
the newest CONSENT_REQUEST row. Background polling reconciles all
historical sessions in one batch, so older sessions' rows previously got
silently merged into the newest session, causing 'Show Data' to display
an unrelated older session's single facility instead of all consented
facilities.
- Skip synthetic orphan sessions (stray rows with no owning CONSENT_REQUEST)
in getAbdmConsentRequestsList()/getAbdmConsentArtifactDetail() so they
don't show as phantom history rows or get picked as 'most recent'.
- Fix abdm_documents() consent_request_id filter to match all known sibling
artifact IDs for a session (via abdm_hiu_consent_artifacts), not just an
exact single artifact id, so all facilities under one consent request
appear together.
- Fix CreateAbdmHiuConsentArtifacts migration: reduce VARCHAR(180) to
VARCHAR(100) on consent_request_id/artifact_id to satisfy MySQL's
1000-byte composite key length limit (was silently failing to migrate).
- Add fetchAllArtifactsAfterGrant() cascade in M3HiuWorkflowService to fetch
every known artifact under a granted consent, used by both the cron poll
and a new abdm_check_live_status() endpoint/button.
- getLatestAbdmSyncSnapshot() session-scoping fix to avoid an older granted
session masking a newer in-progress one.
- Relabel Dr. Joshi Clinic documents (previously mislabeled 'Test Hospital'
from the HIP's own FHIR bundle Organization name).
Abha::verifyOtp() and Abha::verifyCommOtp() were overwriting the
user-typed, OTP-verified mobile number with whatever the ABDM bridge's
verify-otp response echoed back for 'mobile'. Many bridge responses
(especially plain mobile-OTP verification, as opposed to Aadhaar eKYC)
do not echo the mobile at all, so it silently became empty and was
never saved to patient_master.mphone1 during ABHA Register (By ABHA
Number / QR / Facility QR / Mobile OTP) or ABHA Create/Verify.
Fix: fall back to the originally submitted/verified mobile when the
gateway response omits it. Also updated Patient_V.php JS (Verify ABHA
tab, ABHA Register Method 1 and Method 4) to resend the mobile number
along with the verify_comm_otp call so the server has it available.
Address/email are unaffected by this bug: those fields are already
mapped via applyAbhaMetaColumns() when present, but the ABDM mobile-OTP
verification API generally doesn't return KYC demographic data (that
only comes from the Aadhaar-eKYC flow) - so they may legitimately
stay blank for phone-based registration methods.
- New Patient::abdm_content_request_custom(int \) endpoint builds a custom
consent{} block (purpose, hiTypes, permission.dateRange, dataEraseAt) from
user-submitted hi_types[]/date_from/date_to/purpose form fields, instead of
always using M3HiuWorkflowService::buildDefaultConsent()'s hardcoded
OPConsultation+DiagnosticReport / 365-day defaults. Reuses the existing
requester/hiu-id resolution and hiTypes normalization already built into
preparePayloadForOperation() for the consent_request operation, so no
M3HiuWorkflowService changes were needed.
- New route (POST) patient/abdm_content_request_custom/(:num).
- New 'Custom Request' button + '#abdmCustomConsentModal' form
(Patient_Profile_Opd_V.php) with HI type checkboxes (OPConsultation,
DiagnosticReport, Prescription, DischargeSummary, HealthDocument,
ImmunizationRecord, Wellness, Invoice), Valid From/To date inputs
(defaulted to today-365d..today), and a Purpose text field. On submit,
reuses the existing auto-flow polling loop (runAutoFlowStep) with the
returned request_id to track status through to data fetch.
- Live-verified end-to-end on patient 11 (Devender Singh): submitted a
request for OPConsultation + DiagnosticReport + Prescription; sandbox
granted only OPConsultation/DiagnosticReport, and the Phase 1 consent
detail modal correctly showed Prescription as DENIED alongside the two
GRANTED types, confirming the partial-grant per-HI-type breakdown works
correctly end-to-end.
- New Patient::getAbdmConsentArtifactDetail() helper builds a requested-vs-granted
HI type breakdown for a patient's current ABDM consent artifact, using the
bridge-team-confirmed 'Option A' model: overall status is single-valued
(GRANTED/REVOKED/EXPIRED/DENIED), per-type status is derived by comparing the
requested hiTypes (from the saved consent_request request_json) against the
granted hi_types array (already flattened onto responses by
M3HiuGatewayClient). No bridge changes or DB migrations required.
- New Patient::abdm_consent_detail(int \) JSON endpoint + route
patient/abdm_consent_detail/(:num).
- New 'View Consent' link + Bootstrap modal on the OPD ABDM tab
(Patient_Profile_Opd_V.php) rendering a lifecycle stepper, consent metadata
(Consent ID, Purpose, Valid From/To, Erase Date), and a per-HI-type table
(Document Type / Permission / Status / Timestamp).
- Fixed a bug found during live testing: once a consent reaches COMPLETED
(after a successful data_fetch), the highest-priority workflow row has no
hi_types field (it's a FHIR data bundle), which was causing all granted
types to show as DENIED. Now searches workflow history for the most recent
row that actually carries the granted hi_types payload.
- Live-verified against patient 15 (Meera Bisht): both requested HI types
(OPConsultation, DiagnosticReport) correctly show GRANTED with timestamps.
- M3HiuDocumentRepository::persistFromDataFetch no longer includes the
per-call request_id in the document dedup hash. request_id is unique
every time data_fetch runs, so it was causing a brand-new duplicate
row to be inserted on every re-fetch of the exact same ABDM document.
Now dedup key is transaction_id + consent_ref + care_context_reference
+ bundle_id, which stays stable across repeated fetches -> re-fetches
UPDATE the existing row instead of duplicating it.
- Added Patient::abdm_content_fetch_only() + route
billing/patient/abdm_content_fetch_only/(id): a lightweight action for
when consent is already GRANTED/COMPLETED. It calls data_fetch directly
using the saved consent reference, skipping consent_request + reconcile
polling entirely, avoiding unnecessary bridge calls/noise.
- Patient_Profile_Opd_V.php: added a 'Fetch Records' button that only
appears once consent phase is GRANTED or COMPLETED, wired to the new
endpoint; on success it refreshes the document list in place. The
original 'Fetch ABDM Records' button still owns the full consent
request -> reconcile -> fetch flow and already stops/re-enables
correctly on DENIED/FAILED (verified, no change needed there).
- One-time cleanup: deduped existing abdm_hiu_documents rows in dev DB
(13 -> 3) and recomputed doc_hash with the new stable key.
- add facility QR support and OPD queue bridge fixes
- support care-context push warnings for lab, radiology, IPD and remaining HI types
- improve ABHA patient matching and diagnosis autocomplete performance
- clean up webcam streams on page navigation
- Update isIpdDischargedInvoice to check ONLY ipd_status field (remove fallback checks)
- Add IPD status toggle UI in discharge panel (Active/Discharged control)
- Create toggleIpdStatus controller method with permission check
- Add billing.ipd.status.manage permission for controlling bill edit lock
- Allows editing bills when needed by toggling status independently of discharge_date
- Auto-releases bed when setting status to discharged
- Change colspan from 3 to 4 (normal mode) and 4 to 5 (discount mode)
- Ensures Gross Total, Net Amount, Payment Recd., Balance amounts appear in Amount column
- Fixes blank cells in Rate column by properly spanning Description through Rate columns
- Fix dose columns showing IDs instead of labels (OD, BID, TDS, etc.)
- Add Rx-Group functionality with modal, search, and bulk add
- Add substitute medicine suggestions with one-click use
- Improve medicine autocomplete with debouncing and scope=all
- Load dose master maps in controller and pass to view
- Match OPD Consult UI/UX patterns for consistency
ISSUE 2: After clicking 'Save Discharge Advice', CKEditor turns into plain textarea
ROOT CAUSE: initInstructionTools() was not re-initializing CKEditor after AJAX section reload
- When user clicks button with data-reload-section='section-instructions'
- Form submits via AJAX, returns updated HTML
- Section content replaced with new HTML
- initInstructionTools() called but did NOT restore CKEditor
- Fields remain as plain textareas
SOLUTION: Added CKEditor re-initialization to initInstructionTools()
Changes to discharge_create.php initInstructionTools():
1. Check if CKEDITOR is available
2. Destroy existing instances first (instruction_other, instruction_remark)
3. Re-create CKEditor for both fields with same config
4. Prevents duplicate instances and ensures editors work after reload
TESTING:
- Type in instruction_remark or instruction_other
- Click 'Save Discharge Advice'
- After reload, both fields should still be CKEditor (not textarea)
- Can continue editing with toolbar
NOTE: Issue 1 (data mixing between fields) requires separate investigation
User can test with: php check_instruction_data.php to see actual DB values
ISSUE: Medicines were being saved twice - once via Add button AJAX, and again when clicking 'Save Discharge Advice' button.
ROOT CAUSE:
1. Legacy code in save_main handler (lines 5489-5538) read 'discharge_medicine_json' POST field
2. JavaScript serializeDischargeMedicineTable() collected all medicine table rows into JSON
3. On form submit (Save Discharge Advice), JSON was sent and controller re-inserted all medicines
4. Result: duplicate entries in ipd_discharge_prescrption_prescribed table
SOLUTION:
- DISABLED controller code that processes discharge_medicine_json in save_main handler
- DISABLED JavaScript call to serializeDischargeMedicineTable() on form submit
- Medicines now saved ONLY via Add button AJAX (action='add_drug')
- Save Discharge Advice button now only saves dietary advice, instructions, review after, etc.
TESTING:
1. Add medicines via Add button (saves immediately)
2. Click Save Discharge Advice (does NOT save medicines again)
3. No duplicate entries in database
Medicine Save Behavior Change:
- Previously: Medicines added to table locally, saved on 'Save Discharge Advice' click
- Now: AJAX auto-save immediately when '+ADD / Update' button is clicked
- Matches OPD Consult Form workflow (instant save on add)
Implementation:
- Modified btn_discharge_med_add click handler to make AJAX POST
- POST parameters: action='add_drug', ajax_mode='json', new_drug_name, new_drug_type,
new_drug_dose, new_drug_when, new_drug_freq, new_drug_day, new_drug_qty, new_drug_remark
- Controller add_drug action already existed - now returns JSON when ajax_mode='json'
- On success: adds row to table, clears form, shows 'Medicine saved successfully'
- On failure: shows error message from server
- CSRF token updated after each AJAX call
Remove Button Behavior:
- Remove button now shows confirmation dialog
- Warns user: 'This will only remove from current view. Reload to see saved medicines.'
- Note: Remove action is NOT yet AJAX - full page reload shows actual DB state
- Future enhancement: make Remove button also AJAX (action='remove_drug')
Technical Notes:
- Kept discharge_medicine_json serialization as backup (unused now, but harmless)
- Medicine data: med_id=0 marks client-added medicines
- Success check: data.update === 1
- Error handling: network timeout 30s, shows xhr.status on fail
- Form fields cleared after successful save
- Focus returns to medicine name field for next entry
User Benefits:
- Instant feedback - no need to scroll down and click 'Save Discharge Advice'
- Medicines immediately persisted to database
- Can add multiple medicines in quick succession
- Consistent with OPD prescription workflow
- Reduced risk of data loss (saves immediately vs. waiting for form submit)
Medicine Saving Fix (MAJOR):
- Add hidden field 'discharge_medicine_json' to capture medicine table data
- Add serializeDischargeMedicineTable() function to convert DOM table to JSON before form submit
- Hook serialization into form submit event (before syncEditorValues)
- Update controller to process discharge_medicine_json in save_main action
- Insert medicines into ipd_discharge_prescrption_prescribed or ipd_discharge_prescription_prescribed table
- Medicine data now persists on page reload
CKEditor Integration:
- Initialize CKEditor for 'instruction_other' (Other Advice) field
- Initialize CKEditor for 'instruction_remark' (Discharge Summary) field
- Add simplified toolbar: Bold, Italic, Underline, Lists, Undo/Redo
- Properly destroy existing instances before re-initialization
- Height: 120px for Other Advice, 150px for Discharge Summary
Review After Quick Select Buttons:
- Add getNextVisitOptions() method to Ipd_discharge controller (copied from Opd_prescription)
- Add resolveFirstField() helper method
- Pass next_visit_options array to view
- Render quick select buttons: '3 Days (09-06-2026)', '1 Week (13-06-2026)', etc.
- Add JavaScript handler: click button → populate #discharge_review_after input
- Change Review After field from col-md-4 to col-md-6 for better layout
- Add col-md-12 wrapper for button row with flex-wrap gap-2 layout
Technical Details:
- Medicine JSON structure: {med_type, med_name, dosage, dosage_when, dosage_freq, no_of_days, qty, remark}
- JSON processing includes column existence checks for flexibility
- Quick select buttons use data-value attribute for value insertion
- Falls back to hardcoded date options if opd_nextvisit table missing
- Medicine insert uses med_id=0 to mark client-added medicines
User Workflow:
1. Add medicines → shown in table (Type, Medicine, Dose labels, Duration formatted)
2. Click 'Save Discharge Advice' → medicines serialize to JSON → POST to controller
3. Controller parses JSON → inserts to database → medicines persist on reload
4. Other Advice/Discharge Summary now have rich text editing (bold, lists, etc.)
5. Review After: click '1 Week (13-06-2026)' button → auto-fills input
Medicine Table Improvements:
- Swap column order: Type column now appears before Medicine Name
- Display dose labels (text) instead of numeric IDs for Dose, When, Freq
- Auto-format duration: numeric values get 'days' suffix (e.g., '5' -> '5 days')
- Single day shows 'day' (singular), multiple days show 'days' (plural)
- Preserve custom duration formats like '1 month' or '3 doses'
Section Rename:
- Change 'Discharge Instructions / Advice' to 'Discharge Summary'
- Updated in card header, navigation menu, and form label
- Better reflects comprehensive discharge information
Technical:
- Use doseMasterCache to resolve ID->label for Dose/When/Freq/Route
- Regex check for numeric-only duration values before formatting
- Maintain backward compatibility with existing data
- Change from rx_group_medicine_suggest to Opd_prescription/medicine_search endpoint
- Match OPD Consult Form data source and behavior
- Auto-fill Type, Dose, When, Frequency, Route, Days, Qty, and Remark from medicine master
- Add ensureDoseOption helper to handle current values not in dropdown list
- Store medicine rows for auto-fill on selection
- Improved user experience with comprehensive auto-complete
- Replace simple text inputs with advanced prescription form
- Add medicine autocomplete with datalist suggestions
- Add dropdown selects for Dose, When, Frequency, and Route from dose masters
- Integrate with existing Opd_prescription/rx_group_dose_masters endpoint
- Add medicine type auto-fill from medicine database
- Add quick-fill buttons for common values (BF/AF/WF, OD/BD/TDS/HS, 3/5/7 Days)
- Improve UI with two-column layout: medicine list table (left) + add form (right)
- Add real-time medicine suggestions via rx_group_medicine_suggest endpoint
- Support Remove All functionality
- Dynamic table row add/remove with proper event binding
- Better UX matching OPD Consult Form prescription interface
- Updated Patient::search() to only render view with search query
- Created Patient::search_ajax() method for DataTables AJAX endpoint
- Implemented server-side processing with pagination, sorting, and filtering
- Results ordered by Last Visit DESC by default
- Retrieves all patient data from patient_master table
- Added proper SQL escaping to prevent injection
- Updated Patient_Search_V.php to use DataTables with AJAX remote data
- Added DataTables configuration with 25 rows per page default
- Supports dynamic length menu (10, 25, 50, 100, All)
- Added route for billing/patient/search_ajax endpoint
- Improved user experience with loading spinner and customized messages
IMPROVEMENT: Increased modal size for better readability
Changed modal-dialog from default to modal-lg
- Provides more space for SNOMED CT and ICD code fields
- Better readability for field labels and help text
- More comfortable data entry experience
- Consistent with other modals in the system
FEATURE: Quick-add functionality for Course/Treatment master terms
NEW COMPONENTS:
1. Course master table: ipd_discharge_course_master
- term_name, term_code, icd_code, is_active
- Auto-creates on first use
2. Controller endpoints in Ipd_discharge.php:
- course_master_lookup() - AJAX autocomplete search
- course_master_list() - Full list with filters
- course_master_save() - Create/update records
- course_master_delete() - Remove records
3. Routes added to Config/Routes.php:
- Ipd_discharge/course_master_lookup (GET)
- Ipd_discharge/course_master_list (GET)
- Ipd_discharge/course_master_save (POST)
- Ipd_discharge/course_master_delete (POST)
VIEW CHANGES (discharge_create.php):
- Course input now uses input-group layout
- Green 'Save in Master' button added
- Custom dropdown for autocomplete with code badges
- Hidden field: new_course_master_id
- JavaScript: initCourseAutocomplete() function
- Integrated with existing quickAddTermModal
QUICK-ADD MODAL ENHANCEMENT:
- Now supports 3 types: surgery, procedure, course
- Dynamic endpoint selection based on type
- Course type uses course_master_save endpoint
- Auto-populates course input and master_id on save
AUTOCOMPLETE FEATURES:
- Type 2+ characters → searches course_master table
- Dropdown shows: Name + SNOMED/ICD code badges
- Arrow key navigation (Up/Down/Enter/Escape)
- Click or Enter to select
- Hover highlighting with visual feedback
- 300ms debounce for performance
WORKFLOW:
1. Type course/treatment name
2. See dropdown with existing terms (if any)
3. Click 'Save in Master' to add new term
4. Modal opens with name pre-filled
5. Enter SNOMED/ICD codes (optional)
6. Save → Auto-populates input + master_id
7. Click '+ADD Row' to add to discharge
BENEFITS:
- Consistent UI across Surgery/Procedure/Course sections
- Fast term entry without leaving form
- Master library builds during workflow
- ABDM compliance with code support
- Reusable terms across discharges
FEATURE: Quick-add functionality for Surgery and Procedure master terms
NEW COMPONENTS:
1. 'Save in Master' buttons next to Surgery/Procedure inputs
2. Quick-add modal with SNOMED CT and ICD code fields
3. Instant save without opening full Master CRUD modal
4. Auto-populate input and master_id after save
UI CHANGES:
- Surgery/Procedure inputs now use input-group layout
- Green 'Save in Master' button with plus-circle icon
- Quick-add modal opens when clicking button
- Name field auto-filled from input (read-only in modal)
- Optional SNOMED CT code and ICD code fields
- Success message shown before auto-close
WORKFLOW:
1. User types new surgery/procedure name in input
2. Click 'Save in Master' button
3. Modal opens with name pre-filled
4. Enter SNOMED/ICD codes (optional)
5. Click 'Save in Master' in modal
6. Record saves to ipd_discharge_surgery_master table
7. Input filled with saved name
8. master_id hidden field populated
9. Modal closes automatically
10. User can now click '+ADD Row' to add to discharge
BENEFITS:
- No need to open full Master CRUD modal for quick adds
- SNOMED/ICD codes can be added during workflow
- Faster data entry for new terms
- Master table stays organized and updated
- ABDM compliance maintained with code support
COMPLETED ALL TODO ITEMS:
✅ Task 1: Enhanced Surgery autocomplete with SNOMED/ICD codes
✅ Task 2: Enhanced Procedure autocomplete with SNOMED/ICD codes
✅ Task 3: Verified Master CRUD integration (modal already working)
✅ Task 4: Created comprehensive testing documentation
KEY FIXES:
- Removed conflicting bindSurgeryTermLookup() calls from initSurgeryTools()
- Old datalist code no longer interferes with new custom dropdown
- Both autocompletes work independently with separate dropdown containers
TESTING DOCUMENT INCLUDES:
- 10 detailed test scenarios with expected results
- Database verification queries
- Troubleshooting guide
- Edge case handling
- Performance checks
- User acceptance checklist
- Future enhancement suggestions
FILE: SURGERY_PROCEDURE_AUTOCOMPLETE_TESTING.md
Ready for QA testing and user acceptance.
FEATURE: Enhanced Surgery and Procedure autocomplete with code display
IMPROVEMENTS:
1. Replaced basic datalist with custom dropdown
2. Display SNOMED codes (term_code) and ICD codes in dropdown items
3. Show codes as badges: blue for SNOMED, gray for ICD
4. Keyboard navigation (Arrow Up/Down, Enter, Escape)
5. Hover highlighting with visual feedback
6. Store master_id in hidden field for database linking
HOW IT WORKS:
- Type 2+ characters → searches ipd_discharge_surgery_master table
- Dropdown shows: Name + Code badges
- Click or Enter → selects item and fills input
- Arrow keys navigate through suggestions
- Escape closes dropdown
UI:
- Name displayed prominently (bold)
- Codes shown as colored badges below name
- Blue badge: SNOMED/term code
- Gray badge: ICD code
- Hover: light gray background
- Keyboard highlight: blue background, white text
Makes it easy to find and select surgeries/procedures from master
with their ABDM codes visible for verification.