Reduced sizes:
- Table width: 100% to 60%
- Debug text: 10px to 8px
- Triangle: 18px to 12px
- Number boxes: 14px to 10px with 3px padding
- Border: 3px to 2px for selected
- Labels: uniform 7px font
- Reduced all margins and spacing
Still maintains clear B&W visibility with triangle, gray background, and bold border.
PROBLEM: Emojis don't render in PDF (showing as empty boxes)
SOLUTION:
- Use down-pointing triangle (▼) using HTML entity ▼
- This Unicode character renders properly in mPDF/PDF generators
- Darker gray background (#cccccc) for better B&W visibility
- Bold 3px border on selected box
- Larger font and padding for selected number
Visual indicators that work in B&W printing:
- Triangle (▼) above selected level
- Dark gray shading on selected box
- Bold border on selected box
- Bold text for selected label
PROBLEM: Color coding not visible in black & white printers
SOLUTION:
- Added emoji indicators: 😊😐😣😖😭 for pain levels 0-4
- Changed colors to black/white/gray for B&W compatibility
- Emoji shows above selected pain level (larger size)
- Bold 3px border on selected box (visible in B&W)
- Light gray background on selected box
Now pain scale is clear even in monochrome printing!
PROBLEM: Static pains_scale_0-4.png files all look identical (just gradient)
so users can't tell which pain level is selected.
SOLUTION: Comment out PNG file checking code to force use of dynamic HTML
with arrow indicator, colored backgrounds, and bold borders.
Now {{painscale_img}} will show:
- Debug line: 'Pain Level: X - Label'
- Down arrow (▼) above selected level
- Colored background (green to red) on selected box
- Bold 3px border on selected box
- Different pain values will have visibly different displays
- Add 'Pain Level: X - Label' text above pain scale for debugging
- Helps identify if pain_value is being read correctly from database
- Fix comparison to use strict equality check for ===
- User can now see which pain level is actually being rendered
- Change checkmark to down arrow (▼) for better visibility in PDFs
- Increase arrow size to 20px and make it bold
- Use white background for non-selected boxes for stronger contrast
- Add thick black border (3px) on selected level for emphasis
- Selected box shows colored background with white text
- Increase selected label text size and make it bold black
- Clear visual distinction between selected (value 2 vs 4) levels now
- Add fallback to 'logo.png' when H_logo is not set in database or constants
- Prevents {{H_logo}} placeholder from appearing as literal text in print/PDF
- Resolves 400 Bad Request error when browser tries to load unreplaced placeholder
- Ensures prescription templates always have a valid logo path
- Add checkmark (✓) above the selected pain intensity level
- Use color gradient from green (No Pain) to red (Worst) for better visual clarity
- Highlight selected level with colored background and white text
- Thicker border on selected level for better emphasis
- Bold label text for selected intensity
- Makes pain scale selection immediately visible in printed/PDF prescriptions
- Add billing.patient.edit-name-anytime permission to AuthGroups
- Update patient edit time restriction from 12 hours to 24 hours
- Modify Person_Edit_V to check for edit-name-anytime permission
- Admin can now edit patient name field (input_name) even after 24-hour window
Modified {{investigation}} to show both:
1. Textarea content (advise_investigation_notes) if present
2. Comma-separated test list from opd_prescription_investigation table
Both sources combined with newline separator when both exist.
{{Tadvise_test_list}} still available separately for backward compatibility.
Example combined output:
USG WHOLE ABDOMEN
CECT ABDOMEN
PAC
COMPLETE CARDIAC CHECK UP
PAP SMEAR
CBC (Complete Blood Count), ECG (Electrocardiogram), HBA1C, HBSAG, HCV, HIV I & II (Elisa), Liver Function Test (LFT), PT/INR, Renal Function Test (RFT), Urine Routine & Microscopy, X-Ray Chest (PA View)
Changed placeholder behavior to match user requirements:
- {{investigation}} = textarea content (advise_investigation_notes) only
- {{Tadvise_test_list}} = comma-separated test names from table
Removed HTML bullet list formatting. Now outputs plain comma-separated text.
Example output:
CBC (Complete Blood Count), ECG (Electrocardiogram), HBA1C, HBSAG, HCV,
HIV I & II (Elisa), Liver Function Test (LFT), PT/INR, Renal Function Test (RFT),
Urine Routine & Microscopy, X-Ray Chest (PA View)
Both placeholders are independent and can show content simultaneously.
When opd_prescription_investigation table is empty but investigation
textarea has content, parse textarea content (split by newlines) to
populate the test list.
This handles cases where tests are entered as free-text in the
"Advise Investigation" textarea instead of selecting from master list.
Parsing logic:
- Try rx_investigations table first
- If empty, split investigation textarea by newlines
- Filter out empty lines and 'null' values
- Build HTML bullet list from either source
Example textarea content:
USG WHOLE ABDOMEN
CECT ABDOMEN
PAC
COMPLETE CARDIAC CHECK UP
PAP SMEAR
Will render as:
• USG WHOLE ABDOMEN
• CECT ABDOMEN
• PAC
• COMPLETE CARDIAC CHECK UP
• PAP SMEAR
Added try-catch around mPDF WriteHTML to catch rendering errors.
Changed debug_html mode to output as text/html for better preview.
Logs mPDF errors and returns user-friendly error message.
This will help diagnose blank page issues with {{Tadvise_test_list}} placeholder.
Previous implementation only built test list when investigation textarea
was empty, preventing {{Tadvise_test_list}} from showing when textarea
had content.
Changes:
- Separated test list building from textarea population logic
- {{Tadvise_test_list}} now always populates when rx_investigations exists
- {{investigation}} still gets comma-separated fallback when textarea empty
- Both placeholders now work independently
Test list HTML output format:
<ul style="margin:3px 0 0 16px;padding:0;list-style-type:disc;">
<li>CBC (Complete Blood Count)</li>
<li>ECG (Electrocardiogram)</li>
<li>HBA1C</li>
</ul>
Created new OPD template placeholder to display investigation test names
as a formatted HTML list, separate from the textarea {{investigation}}.
Changes:
- app/Controllers/Opd.php:
* Added $rxInvestigationTestList variable in buildLegacyDashboardTemplateVars()
* Builds HTML <ul> list from rx_investigations test names
* Added 'Tadvise_test_list' token to return array
- app/Views/billing/opd_template_builder.php:
* Added 'Tadvise_test_list' to $opdConsultSet placeholder list
* Now appears in "OPD Consult" group in template builder
Usage in OPD templates:
- {{investigation}} = comma-separated test names (for textarea)
- {{Tadvise_test_list}} = formatted HTML bullet list of test names (for print/display)
Example output:
<ul style="margin:3px 0 0 16px;padding:0;list-style-type:disc;">
<li>CBC (Complete Blood Count)</li>
<li>USG WHOLE ABDOMEN</li>
<li>ECG (Electrocardiogram)</li>
</ul>
Root cause: 50k+ invoices had insurance_case_id='0', and MySQL string comparison '0'='C26060004997' matched (both convert to numeric 0).
Fix: Exclude NULL/empty/'0' insurance_case_id before comparison in:
- getOrganizationCaseInvoiceRows() union query
- updateOrgTotals() aggregate queries
Result: Case C26060004997 now returns 9 rows instead of 56,786 (memory crash fixed)
- FhirR4Builder: rewrite buildLabReportBundle() with DiagnosticReportLab
profile, structured Observation valueQuantity/valueString, reference
ranges, interpretation codes, Binary+DocumentReference for HTML report,
Encounter resource, HFR-based bundle identifier system
- FhirR4Builder: rewrite buildDischargeSummaryBundle() with optional
Practitioner/Organization params, structured ABDM sections (chief
complaints 422843007, medical history 1003642006, investigations
721981007, procedures 1003640003, medications 721912009, follow-up
736271009), HFR-based bundle identifier system
- AbdmGateway: shareIpdDischargeBundle() now builds a real
DischargeSummaryRecord FHIR bundle and posts via pushRecord()
(POST /v3/records/push) instead of the stale shareIpdDischargeBundle()
- AbdmGateway: shareDiagnosisReportBundle() now builds a real
DiagnosticReportRecord FHIR bundle and posts via pushRecord()
instead of the stale shareDiagnosisReportBundle()
- AbdmGateway: add getHospitalProfileForFhir() and mapLabTypeToTitle()
helpers; fix pre-existing undefined \ bug in
getActiveConsentRecord()
- Add ABDM_FHIR reference package, AbdmBridgeLog controller/view,
bridge record migration, debug scripts and misc UI/settings updates
- POST Opd_prescription/fhir_bundle_submit endpoint:
loads stored FHIR bundle, fetches patient/OPD/doctor context,
calls EAtriaBridgeConnector::pushRecord to push to bridge
- Standalone preview page (/Opd_prescription/fhir_bundle_preview/N):
added Submit to ABDM Bridge button with CSRF-safe AJAX + inline
success/error alert
- FHIR modal in task_board.php: added Submit to ABDM button next
to Copy JSON; JS reads _fhirOpdId/_fhirSessionId and posts to
fhir_bundle_submit with CSRF token refresh
- Add separate Save Settings button below User Settings card
- Create myProfileSaveSettings controller method for dedicated settings save
- Settings save endpoint: POST /my-profile/save-settings
- Validates sidebar_auto_hide_seconds (0-60 range)
- Provides immediate feedback: success/error message display
- Separate from profile photo and password updates
- Message auto-hides after 2 seconds on success
- Create user_settings table to store individual user preferences
- UserSettings model for get/set/delete user setting values
- Home::myProfile loads user settings with hospital defaults fallback
- Home::myProfileSave persists user settings to DB
- my_profile.php adds Sidebar Auto-Hide Delay field (0-60 seconds)
- welcome_message.php checks user settings first, then hospital default
- Setting value 0 = auto-hide disabled; blank = use hospital default
- Extensible table design for future user settings (color theme, etc)
- Safe delete for empty IPD charge groups with CSRF-safe AJAX
- Migration: add sort_order to ipd_item_type (backfilled)
- Sort order UI on create/edit/list views; persist in controller/model
- Up/Down swap buttons on group list (AJAX swap endpoint + CSRF refresh)
- Fix 500 on edit screen: restore missing getItemTypeById() in ItemIpdModel
- IpdBillingModel: propagate sort_order ordering to ipd-charges and bill-details tabs
- Billing IPD Charges tab: Bedside Clinical/Nursing Charge and Doctor Visit Charge panels now collapsible, start collapsed