- 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