Order Bill Communication & PDF Templates
Overview
Order bills support four communication channels, each backed by a communication_template record seeded via migration. The system also allows per-client custom templates without any code changes.
Restaurant bills also support PDF/HTML and thermal ESC/POS output. These use different template kinds and data bindings.
Sale parallel (reference)
| Template | documentType | templateContentKind | Data binding |
|---|---|---|---|
| Sale — Standard A4 | sale | pdf_html | Sale PDF context (SalePdfData) |
| Sale Receipt — Thermal 80mm | saleReceiptThermal | thermal_escpos_dsl | sale_receipt payload |
| Order Bill Receipt — PDF 80mm | orderBill | pdf_html | receipt.* + currency.symbol |
| Order Bill Receipt — Thermal 80mm | orderBillReceiptThermal | thermal_escpos_dsl | order_bill_receipt payload |
| Order Bill — Legacy PDF | orderBill | file fallback only | OrderBillPdfContext (flat bill fields) |
Order bill receipt PDF (new)
The Order Bill Receipt — PDF 80mm template mirrors the thermal receipt layout but renders as HTML/PDF for download, email attachments, or browser print.
| Asset | Location |
|---|---|
| HTML template (runtime) | apps/backend/src/pdf/infrastructure/templates/order-bill-receipt.template.html |
| HTML template (DB seed copy) | packages/backend/database/src/templates/order-bill-receipt.template.html |
| Preview sample JSON | packages/backend/database/src/templates/order-bill-receipt-preview-sample.json |
| Migration (system template seed) | packages/backend/database/src/migrations/2026-06-15t12-00-00-seed-order-bill-receipt-pdf-template.mjs |
| Payload builder (single source of truth) | DocumentPrintPayloadRepository.buildOrderBillReceiptPayload |
| Extra data for PDF merge | OrderBillReceiptPdfExtraDataService |
| Preview fixture API | GET /pdf/templates/order-bill-receipt-pdf-preview-fixture |
Data binding
PDF generation merges two layers:
- Legacy context —
OrderBillDataTransformer(flat fields fororder-bill.template.html) - Receipt context —
extraDatafrombuildOrderBillReceiptPayload:receipt.*— same shape as thermal (withoutkind)currency.symbol—Qfor GTQ, otherwise{code}logoDataUrl/qrDataUrl— from embed service (top-level, same as legacy)
Use {{escape receipt.businessName}} for merchant-controlled strings in HTML.
Template Management UI
In Template Editor, for templates with documentType=orderBill, templateContentKind=pdf_html, and templateFormat=receipt_thermal_80mm, Load default fetches the server fixture from /pdf/templates/order-bill-receipt-pdf-preview-fixture.
The legacy Order Bill file fallback (order-bill.template.html) remains the default when no DB template is selected; it uses the flat bill context, not receipt.*.
Thermal ESC/POS (unchanged)
| Template | Location |
|---|---|
| Thermal DSL file | apps/backend/src/pdf/infrastructure/templates/order-bill-receipt-thermal.template.txt |
| Line builder (programmatic) | packages/receipt-layout/src/document/build-document-lines.ts — buildOrderBillReceiptLines |
Thermal templates use documentType=orderBillReceiptThermal and the thermal preview fixture endpoint.
Communication templates (email/SMS)
| Template | Location |
|---|---|
| Migration (all 4 templates) | packages/backend/database/src/migrations/2026-04-17t01-00-00-order-bill-communication-templates.mjs |
| Legacy PDF/HTML (flat context) | apps/backend/src/pdf/infrastructure/templates/order-bill.template.html |
Important: Migrations that use
ON CONFLICT DO NOTHINGwill not update records already in the DB. To change an existing seeded template, write a new migration with an explicitUPDATE, or run SQL manually per environment.
Per-client custom templates (no code changes)
The system supports per-business template overrides. communication_template has a business_id column; findByCode(code, businessId) prefers business-scoped records over system defaults.
For PDF templates, upload or duplicate a template in Template Management, set documentType to orderBill, and choose the receipt PDF format when customizing the 80mm layout.