initial commit
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# 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 as `Quote_XXX_CustomerName.pdf`
|
||||
- **`printQuote()`** (line ~3670): opens PDF blob in new window, triggers `window.print()`
|
||||
|
||||
Both call `generateQuotePDF()` — the only difference is what happens with the returned blob.
|
||||
|
||||
## Button Wiring
|
||||
|
||||
`ensureDownloadPdfBtnListener()` (line ~706):
|
||||
1. Looks for buttons with IDs `download-pdf-btn` or `generate-pdf-btn`
|
||||
2. Falls back to scanning all buttons for text/classes containing "pdf" or "download"
|
||||
3. If still nothing found, dynamically creates a PDF button via `createPdfButton()`
|
||||
|
||||
## generateQuotePDF() Structure
|
||||
|
||||
Location: `quote-tab-manager.js` line ~3727
|
||||
|
||||
1. Dynamically imports jsPDF from CDN: `https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js`
|
||||
2. Accesses via `window.jspdf.jsPDF`
|
||||
3. Validates customer name + services exist
|
||||
4. 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.headerMessage` template 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 `#f8f8f8` rounded-rect background box with `#dcdcdc` border
|
||||
- 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 `#b4b4b4` line
|
||||
- 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.footerMessage` and `appSettings.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.
|
||||
Reference in New Issue
Block a user