Executive Summary
The Moon ERP LIS printing system is currently built as four isolated rendering pipelines running in parallel. This fragmentation leads to major functional drift: the exact same medical request prints with different data structures, missing comments, or omitted signatures depending on the UI action or portal the user interacts with.
While the legacy Classic PDF engine (jsPDF-based) is functionally robust—correctly rendering branch stamps, branch signatures, medical comments, and respecting dynamic header configuration rules—it lacks modern styling and QR support. Conversely, the HTML Templates (Editorial, Bento, Monochrome, etc.) look clean but fail on safety metrics (silent page truncation, completely dropped comments, missing stamps).
The Unification Mandate:
The core strategy must treat the Classic PDF pipeline as the functional source of truth. All modern HTML templates must be refactored to consume the exact same layout features, stamp triggers, static/dynamic comment arrays, and pagination parameters as Classic, retaining only their distinct visual stylesheets.
Mapping the Four Rendering Engines
The diagram below highlights how data enters the print orchestrator and divides into divergent pathways:
❌ Old Styling: Rigid coordinates, monochrome, no QR codes.
❌ Bad Build: No stamps, 0 comments, silent page truncation, popup blockers trap downloads.
Comparative Feature Matrix
| Feature / Printing Rule | Classic PDF | Editorial | Bento | Monochrome | Spectrum | Document |
|---|---|---|---|---|---|---|
| Official Branch Stamp | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
| Authorized Branch Signature | ✓ | ✗ | ✗ | ✗ | ✗ | ◐ |
| Dynamic Header Config | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ |
| Comments (Row/Static/General) | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
| Histo custom section ordering | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
| Paging (No Truncation) | ✓ | ✗ | ◐ | ◐ | ✗ | ◐ |
| Abnormal Result Coloring | ✗ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Verified Badge Enforced on Status | ✓ | ✓ | ✗ | ✓ | ✗ | ✓ |
* Note on Paging: Bento, Monochrome, and Document overflow naturally but omit page numbers, running headers, or footer overlaps, whereas Editorial and Spectrum silently clip all overflow content using CSS overflow rules.
overflow: hidden styling heights on A4 layouts. If a patient's lab request contains multiple panels exceeding a single A4 page, the remaining results are silently deleted from the printed PDF without triggering UI warnings, leading to actual medical data omission.
page-break-inside: avoid for tabular rows, thead { display: table-header-group; } for repeating patient headers across page bounds), and enforce physical browser print loops.
row.comment, static test-code interpretations, and the request collective comment data.comments) have no rendering nodes in any of the 5 HTML layouts. Critical warning annotations added by validating staff are invisible on these templates.
entered) are printed as verified. To worsen this, Bento and Spectrum templates hardcode a green "Verified" badge over all result tables, even when printing drafts.
released only. If an authorized draft print is executed (using `includeDraft`), inject a prominent, semi-transparent diagonal "DRAFT / DRAFT" watermark across the entire page, and conditionally display the "Verified" badge only when status is strictly released.
ReportSettings), which governs showing QR codes, toggling signature blocks, presenting comparative previous results, and rendering legal licensing credentials, is never read in the Classic engine. Furthermore, the HTML engine signature rejects the parameter entirely, making all settings dead in the frontend.
hide_from_print flags, and reads incorrect backend setting keys (e.g., lis_report_*).
buildHeaderFields(), ensuring uniform field visibility settings.
null to the caller. This causes the calling result and preview screens to throw a false error message ("No printable results found") despite the print job being sent. Additionally, popup blocker events are not handled.
histoSectionOrder parameter to the HTML service, and iterate over sections dynamically inside HTML layouts.
report_show_previous is enabled.
'default', which does not map to any template. The HTML renderer falls back to Editorial, bypassing the correct fallback (Classic PDF).
'classic' and align fallback mechanisms in `lis-html-report.service.ts`.
hide_from_print setting hides specific package items from patient outputs. This is only implemented in the staff print workflow, meaning hidden items are still visible when printing from the Print Queue or patient portals.
NotoSansArabic font. Requesting bold text for comments fails silently. Additionally, patient header fields are hardcoded to English (with typos, like "Reffering No.") regardless of language settings.
disk_zone) is only rendered by the Document template. Other templates omit this value. In Classic, a large culture table can overflow the page and overlap footer signatures.
disk_zone and page-break rules.
Unify Core Print Rules
Timeline: Week 1- Stamps & Signatures: Inject unified stamp/signature elements into the HTML layouts, correcting signature mappings.
- Comment Ingestion: Add comments (row, static, general) to the HTML templates.
- Paging Adjustments: Remove
overflow: hiddenfrom HTML layouts and configure CSS Paged Media selectors. - Status Enforcement: Restrict printing to
releasedresults, and add draft watermarks for authorized draft prints.
Consolidate Routing and Settings
Timeline: Weeks 2–3- Settings Integration: Enable the
ReportSettingspayload inside the HTML layouts, binding toggles to layout elements. - Print Queue Consolidation: Reroute collective printing through the main `LisPrintReportService` pipeline, deprecating duplicate logic.
- Unified Querying: Route patient portals through `LisPrintReportService` to align reference range rules.
Enforce Quality Controls
Timeline: Weeks 4+- Strict Template Contract: Implement a TypeScript interface defining the required fields for all layouts.
- Server-Side Migration: Replace DomPDF with a headless browser instance to render the unified HTML layouts.
- Asset Embedding: Package all web fonts as local, base64-encoded CSS assets.
Technical Review: Migrating Legacy Classic PDF to HTML
Once Phase 1 and Phase 2 are complete, the development team recommends migrating the legacy Classic layout to the HTML engine. This will consolidate the system under a single HTML/CSS renderer, simplifying maintenance.
- Single Engine: Code updates apply globally.
- Easy Maintenance: Standard HTML/CSS is easier to manage than custom jsPDF canvas coordinates.
- Consistent Outputs: Guarantees matching layout structures across screen views, printouts, and server downloads.
- CSS Paged Media: Requires styling expertise to prevent page overflows.
- Visual Matching: Pathologists expect exact visual alignment, requiring precise style adjustments.
- Server Rendering: Headless browsers require extra server-side resources compared to DomPDF.
Overview of LIS Print Ecosystem
Beyond medical diagnostic reports, the laboratory system manages two other critical printing workflows: financial tax invoices and thermal barcode labels.
Handles A4 invoices and 80mm thermal receipts. Uses Laravel PDF on the backend to apply tax calculations.
Generates barcode labels for specimen tubes. Supports ZPL/EPL formats for thermal printers (Zebra, etc.).