2.8 KiB
2.8 KiB
Quote PDF Generation (quote-tab-manager.js)
Entry Points
Two user actions, both in quote-tab-manager.js:
downloadPdf()(line ~3696): creates download link, triggers save asQuote_XXX_CustomerName.pdfprintQuote()(line ~3670): opens PDF blob in new window, triggerswindow.print()
Both call generateQuotePDF() — the only difference is what happens with the returned blob.
Button Wiring
ensureDownloadPdfBtnListener() (line ~706):
- Looks for buttons with IDs
download-pdf-btnorgenerate-pdf-btn - Falls back to scanning all buttons for text/classes containing "pdf" or "download"
- If still nothing found, dynamically creates a PDF button via
createPdfButton()
generateQuotePDF() Structure
Location: quote-tab-manager.js line ~3727
- Dynamically imports jsPDF from CDN:
https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js - Accesses via
window.jspdf.jsPDF - Validates customer name + services exist
- Builds PDF with these sections:
Header (two-column layout)
- Left column: "SERVICE PROVIDER" label, business name/address/phone, service advisor
- Right column: "CUSTOMER INFORMATION" label, name/vehicle/RO#/mileage/VIN/date
- Bold separator line between header and content
Personalized Message
- Uses
appSettings.headerMessagetemplate with{customerName}and{vehicleInfo}placeholders - Split to fit content width
Services Section
- Split into "SERVICES APPROVED" and "POSTPONED SERVICES" if mixed decisions exist
- Each service: green "✓ CUSTOMER APPROVED" or red "✗ CUSTOMER DECLINED" badge
- Service name: bold, 10px (reduced from 12px)
- Price: right-aligned
- Priority header (if prioritized):
[CRITICAL],[SAFETY],[RECOMMENDED],[MAINTENANCE],[OPTIONAL] - Recommendation level text
- Service explanation (split to fit width)
- Parts/aftermarket notes
- Light gray separator between services
Pricing Summary (totals box)
- Subtle
#f8f8f8rounded-rect background box with#dcdcdcborder - 45% width from right margin
- Line items (9px, labels in gray
#646464): Subtotal, Approved (green), Discount (green with − sign), Shop charge, Tax - Separator: 0.5px
#b4b4b4line - TOTAL: bold 10px
- Row spacing: 8px throughout
Shop Charge Note
- Positioned at
boxBottomY + 10— must stay after the box's visual boundary - 8px font, gray, prefixed with
*
Footer
- Light gray separator line
- Centered
appSettings.footerMessageandappSettings.quoteFooterNote - Page numbers: "Page X of Y" at bottom right
Key Design Choice
technicianNotes are deliberately excluded from PDFs — they're internal AI context notes, not customer-facing.
Invoice PDF (repair-orders.js)
Separate from quotes. printInvoice() at line ~1340 in repair-orders.js calls generateInvoicePDF() which also uses jsPDF but with a different layout.