Skip to main content

PDF Templates

How to customize Pilot's PDF Templates

Written by Mykyta Medvediev

PDF Templates

PDF generation for invoices, statements, and work tickets is done using the handlebars library.

Using HTML and embedding variables in {{my_variable}} format, you can fully customize the PDF templates.


How to update the default PDF templates

  1. Go to PDF Templates in Settings.

  2. Click the template you want to update.

  3. Update the template using your custom HTML and the variables provided.

  4. Click Save.


How to use Handlebars syntax

Nested variables

To access nested variables, use dot (.) notation.

Example — accessing case_number in the Work Ticket template:

{{case.case_number}}

Arrays

To access variables in an array, iterate using #each.

Example — accessing case_line_items in the Work Ticket template:

{{#each case.case_line_items}}   <tr>     <td>{{this.name}}</td>     <td>{{this.quantity}}</td>     <td>{{this.notation}}</td>     <td>{{this.shade}}</td>   </tr> {{/each}}

Work Ticket Template

Algorithm

If the left page exceeds 750px in height:

  • We find the section at the 750px mark.

  • Every section at that location and below moves to the next page (right side).

  • If the right side overflows, the overflow moves to the next page.

A section is defined as any <div></div> that is a direct child of:

<div class="ticket-left" id="content-left">

Work Ticket Variables

Each variable below is nested under its parent object.

For example:

  • case_number is accessed as: {{case.case_number}}

  • patient_name is accessed as: {{case.patient_name}}


Case

Variable

Notes

case_number

patient_name

patient

patient_first_name

patient_last_name

pan_number

casePan

case_type

status

doctor_notes

due_date

ship_date

shippedDate

order_date

createdAt

teeth_chart_svg

Notation graphic

case_source

Where the order came from, e.g. "iTero". Empty on manual cases

source_case_number

Order number in that source

invoiced_date

ship_date_day_of_week

e.g. "Tuesday"

current_round

Round number, or R<n> for remakes

case_scans.number_of_scans_in_version_1

Count of valid scan files in version 1

QR Code:

<div id="qrcode"></div>

Case Production Tasks — {{case.case_production_tasks}} (Array)

Variable

name

idBarcodeUrl

{{#each case.case_production_tasks}}   {{name}}   {{idBarcodeUrl}} {{/each}}

Customer — {{case.customer.*}}

Variable

hold_reason

case_warning

phone_number

emails

Array of live email addresses

emails_display

Comma-separated string

case_count

Total cases for the customer

custom_fields

Array, same shape as case.custom_fields

notes

Array: text, is_pinned, is_visible_on_case, color, created_at, created_by_user.* (same user fields as case notes)

Clinical Preferences — {{case.customer.clinical_preferences}} (Array)

Variable

preference

restorationType

value

icon

iconDataUrl


Doctor — {{case.doctor.*}}

Variable

name

first_name

last_name

status

new_doctor


Office — {{case.office.*}}

Variable

name

address

group


Billing Account — {{case.billing_account.*}}

Variable

name

email

phone_number

address


Billing Lab — {{case.billing_lab.*}}

Variable

name


Case Line Items — {{case.case_line_items}} (Array)

Variable

name

notation

shade

stump_shade

quantity

is_remake

product_rate

discount_amount

subtotal

total

product.name

product.description

product.customer_display_name

{{#each case.case_line_items}}   {{name}}   {{notation}}   {{quantity}} {{/each}}

Custom Fields

{{case.custom_fields}}

Case Tags

Format

Variable

Array

{{case.case_tags}}

Comma-separated string

{{case.case_tags_display}}


Scanner Order — {{case.scanner_order.*}}

Variable

order_number

order_date

portal_type

scan_number_custom_field

scanner_portal_custom_field


Linked Case — {{case.linked_case.*}}

If a linked case exists:

Variable

case_number

custom_fields

doctor_notes

tasks_techs

Comma-separated list of techs on production tasks

invoiced_date

scanner_order.order_number

scanner_order.order_date

case_production_tasks

Array: name, tech_name, deadline, idBarcodeUrl, idBarcodeEncoded

Case Notes — {{case.case_notes.*}}

If a linked case exists:

Variable

text

is_pinned

created_at

created_by_user.full_name

created_by_user.first_name

created_by_user.last_name

created_by_user.username

QR code for linked case:

<div id="qrcode-linked-to-case-url"></div>

Scanner Order — {{case.scanner_order.*}}

Variable

order_number

order_date

portal_type

scanner.name

scanner.scanner_type

scanner.id

Case Production Tasks — {{case.case_production_tasks.*}}

Variable

name

tech_name

deadline

idBarcodeUrl


Organization

Variable

name

logo

address

address_street

Line 1 plus line 2

address_city_state_zip

phone


System Variables

Variable

current_time

day_of_week

Current day, in the org's time zone


Invoice Template

Invoice Variables

Variable

Notes

case_number

patient_name

patient

balance

discount_amount

tax_amount

total_amount

status

paid → balance = 0; past due → based on payment terms

terms

invoice_date

invoice_due_date


Office

Variable

name

address


Doctor

Variable

name


Billing Account — {{invoice.billing_account.*}}

Variable

name

email

phone_number

address


Case Line Items (Array)

Variable

name

notation

shade

stump_shade

quantity

is_remake

product_rate

discount_amount

subtotal

total


Organization

Variable

logo

name

address


Statement Template

Statement Variables

Variable

Notes

start_date

end_date

due_date

previous_balance

balance

total_invoiced

total_credited

total_paid

total_unapplied

has_credits

credit_balance

amount_due

Calculated as previous_balance + total_invoiced - total_paid + total_credited. If the result is negative, it is automatically set to 0.

raw_amount_due

Calculated as previous_balance + total_invoiced - total_paid + total_credited. Unlike amount_due, negative values are preserved and no minimum value is applied.


Doctor

Variable

name


Office

Variable

name

address


Billing Account — {{statement.billing_account.*}}

Variable

name

email

phone_number

address

Full address

address_line_1

address_line_2

address_city

address_state

address_country

Billing Lab

Variable

name

custom fields


Statement Lines (Array)

Variable

date

type

reference

amount

running_balance

invoice.case.patient_name

Nested

invoice.doctor.name

Nested


Invoices (Array)

Variable

case_number

status

invoice_date

invoice_due_date

balance

tax_amount

discount_amount

total_amount

Doctor

Variable

name

Office

Variable

name

address

Case Line Items (Array)

Variable

name

notation

shade

stump_shade

quantity

is_remake

product_rate

discount_amount

subtotal

total


Organization

Variable

logo

name

address

phone

Did this answer your question?