# Invoice PDF Customization

**Date:** 2026-05-31  
**Status:** Draft  
**Spec:** 135  
**Tier:** All tiers  
**Depends on:** `invoices-core`, `invoice-settings-page`, `foundation-auth-rbac`  
**Referenced by:** `invoices-core`, `invoice-settings-page`

---

## Overview

Spec 15 (`invoices-core`) generates PDF invoices but does not specify the PDF template or appearance options. Spec 125 (`invoice-settings-page`) covers operational defaults. This spec defines the PDF template customization settings at `/settings/invoicing/pdf-template` — layout selection, column configuration, and branding.

---

## Route

`/settings/invoicing/pdf-template` — sub-route of `/settings/invoicing` (admin only). Accessible as a tab within the invoice settings page (spec 125).

---

## Page Layout

Split-panel: settings on left, live PDF preview on right.

```
┌──────────────────────────────────────────────────────────────┐
│  Settings > Invoicing > PDF Template                         │
│                                                              │
│  ┌─────────────────────────┐  ┌──────────────────────────┐  │
│  │  Layout                  │  │  PREVIEW                 │  │
│  │                          │  │                          │  │
│  │  ● Classic (recommended) │  │  ┌────────────────────┐  │  │
│  │  ○ Modern (header right) │  │  │ [LOGO]     Acme Co │  │  │
│  │  ○ Minimal (no logo)     │  │  │                    │  │  │
│  │                          │  │  │ INVOICE            │  │  │
│  │  Columns                 │  │  │ INV-0001           │  │  │
│  │  ☑ Description           │  │  │ Issue: 01.06.2026  │  │  │
│  │  ☑ Quantity              │  │  │ Due:   30.06.2026  │  │  │
│  │  ☑ Unit price            │  │  │                    │  │  │
│  │  ☑ Tax rate per line     │  │  │ Bill to:           │  │  │
│  │  ☑ Amount                │  │  │ Dana Cohen         │  │  │
│  │  ☐ Project               │  │  │ Acme Corp          │  │  │
│  │  ☐ SKU / item code       │  │  │                    │  │  │
│  │                          │  │  │ ─────────────────  │  │  │
│  │  Accent color            │  │  │ Design    1  ₪2K   │  │  │
│  │  [█ #006b6b_____] [Pick] │  │  │ Dev       1  ₪8K   │  │  │
│  │  (from var(--accent) by  │  │  │           VAT ₪1.7K│  │  │
│  │   default)               │  │  │           ₪11.7K   │  │  │
│  │                          │  │  │                    │  │  │
│  │  Date format             │  │  │ Thank you for your │  │  │
│  │  ● DD.MM.YYYY (Israeli)  │  │  │ business!          │  │  │
│  │  ○ YYYY-MM-DD (ISO)      │  │  └────────────────────┘  │  │
│  │  ○ Month D, YYYY         │  │                          │  │
│  │                          │  │  [Download sample PDF]   │  │
│  │  [Save template]         │  └──────────────────────────┘  │
│  └─────────────────────────┘                                  │
└──────────────────────────────────────────────────────────────┘
```

Preview updates live as settings change (client-side render; full PDF download for final check).

---

## Layout Templates

Three layouts (stored as template name; actual rendering in PDF generation service):

**Classic** — standard A4:
- Logo top-left, business name/address top-right
- Large "INVOICE" heading
- Bill-to section below header
- Line items table (full width)
- Totals bottom-right
- Footer text bottom-center

**Modern** — contemporary right-aligned:
- Business identity panel on the right side
- Bold accent stripe at top
- Left-aligned bill-to section

**Minimal** — plain for professional services:
- No logo section
- Monochrome, no accent color
- Compact header

---

## Column Configuration

| Column | Default visible | Description |
|--------|----------------|-------------|
| Description | ✓ | Item/service name and description |
| Quantity | ✓ | Units, hours, or count |
| Unit price | ✓ | Price per unit |
| Tax rate | ✓ | VAT % per line |
| Amount | ✓ | Quantity × unit price (ex. tax) |
| Project | ✗ | Project name (useful for multi-project invoices) |
| SKU / item code | ✗ | Product library SKU (spec `product-service-library`) |

---

## Accent Color

Accent color used for: table header row, dividers, total row background, page header stripe.

Default: `#006b6b` (teal, matching system accent). Override here saves to `tenant_settings.invoice_pdf_accent_hex`.

---

## Schema Delta

```sql
ALTER TABLE tenant_settings
  ADD COLUMN invoice_pdf_layout TEXT NOT NULL DEFAULT 'classic'
    CHECK (invoice_pdf_layout IN ('classic', 'modern', 'minimal')),
  ADD COLUMN invoice_pdf_show_project BOOLEAN NOT NULL DEFAULT false,
  ADD COLUMN invoice_pdf_show_sku BOOLEAN NOT NULL DEFAULT false,
  ADD COLUMN invoice_pdf_date_format TEXT NOT NULL DEFAULT 'dd.MM.yyyy'
    CHECK (invoice_pdf_date_format IN ('dd.MM.yyyy', 'yyyy-MM-dd', 'MMMM d, yyyy')),
  ADD COLUMN invoice_pdf_accent_hex TEXT;  -- null = use system default
```

---

## PDF Generation Integration

PDF generator (spec 15) reads `tenant_settings` at generation time:
- Layout name → select React/HTML template
- Column visibility → pass as props to line-items table component
- Date format → format all dates in the document
- Accent hex → inline CSS custom property override in PDF HTML

---

## API

```
GET /api/settings/invoicing/pdf-template
    → get current PDF template settings
      Requires: admin

PATCH /api/settings/invoicing/pdf-template
      body: { invoice_pdf_layout?, invoice_pdf_show_project?,
              invoice_pdf_show_sku?, invoice_pdf_date_format?,
              invoice_pdf_accent_hex? }
      Requires: admin

GET /api/settings/invoicing/pdf-template/preview
    → generate sample PDF with current settings
      Returns: PDF binary (sample data, not a real invoice)
      Requires: admin
```

---

## Architecture Decisions

| Decision | Choice | Reason |
|----------|--------|--------|
| 3 fixed layouts | Not freeform template editor | Custom template editing requires HTML/CSS knowledge and creates support burden; 3 layouts cover 95% of needs |
| Live preview on left | Not separate preview tab | Instant visual feedback reduces save-and-check cycles |
| Accent hex stored separately | Not using OKLCH token | PDF generation uses a headless browser or React-PDF; OKLCH CSS custom properties aren't supported in all PDF renderers; hex is portable |
| Column toggles | Not fixed columns | Different industries need different columns (consultants don't need SKU; product businesses do) |
