From 36d457a5ca13779402fe42e600573b343195b816 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:25:57 +0000 Subject: [PATCH 1/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/lib/invoice-pdf.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/invoice-pdf.ts b/src/lib/invoice-pdf.ts index bef4564..d95fea4 100644 --- a/src/lib/invoice-pdf.ts +++ b/src/lib/invoice-pdf.ts @@ -275,14 +275,15 @@ export async function downloadInvoicePdf(input: InvoicePdfInput, filename: strin ty += 11; } - // Info card (right) — key/value rows + // Info card (right) — key/value rows. + // "Case No." is shown directly under the invoice number for quick reference. const infoRows: Array<[string, string]> = [ ["Inv. Number", input.invoice.number], ]; - if (input.invoice.matter) infoRows.push(["Matter", input.invoice.matter]); + if (input.invoice.caseNumber) infoRows.push(["Case No.", input.invoice.caseNumber]); infoRows.push(["Date of Issue", formatDate(input.invoice.issueDate)]); if (input.invoice.terms) infoRows.push(["Terms", input.invoice.terms]); - if (input.invoice.dueDate) infoRows.push(["Date Due", formatDate(input.invoice.dueDate)]); + if (input.invoice.dueDate) infoRows.push(["Date Due", formatDate(input.invoke.dueDate ?? input.invoice.dueDate)]); const rowH = 18; const infoTop = y - 4; From ec8356144fa8b094dac9ec3f6837fbac8a6874a8 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:26:05 +0000 Subject: [PATCH 2/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/lib/invoice-pdf.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/invoice-pdf.ts b/src/lib/invoice-pdf.ts index d95fea4..c81caa6 100644 --- a/src/lib/invoice-pdf.ts +++ b/src/lib/invoice-pdf.ts @@ -56,6 +56,7 @@ export interface InvoicePdfInput { status: string; notes?: string | null; matter?: string | null; + caseNumber?: string | null; terms?: string | null; }; groups: InvoiceCaseGroup[]; From 30a347b596af2839cc6fd3069d46bd3533abe464 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:26:13 +0000 Subject: [PATCH 3/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/lib/invoice-pdf.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/invoice-pdf.ts b/src/lib/invoice-pdf.ts index c81caa6..2fda269 100644 --- a/src/lib/invoice-pdf.ts +++ b/src/lib/invoice-pdf.ts @@ -284,7 +284,7 @@ export async function downloadInvoicePdf(input: InvoicePdfInput, filename: strin if (input.invoice.caseNumber) infoRows.push(["Case No.", input.invoice.caseNumber]); infoRows.push(["Date of Issue", formatDate(input.invoice.issueDate)]); if (input.invoice.terms) infoRows.push(["Terms", input.invoice.terms]); - if (input.invoice.dueDate) infoRows.push(["Date Due", formatDate(input.invoke.dueDate ?? input.invoice.dueDate)]); + if (input.invoice.dueDate) infoRows.push(["Date Due", formatDate(input.invoice.dueDate)]); const rowH = 18; const infoTop = y - 4; From 1ba96ce43325c27498f81291add19e833ba9896d Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:26:22 +0000 Subject: [PATCH 4/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/lib/invoice-pdf.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/invoice-pdf.ts b/src/lib/invoice-pdf.ts index 2fda269..b4bc7ad 100644 --- a/src/lib/invoice-pdf.ts +++ b/src/lib/invoice-pdf.ts @@ -370,7 +370,8 @@ export async function downloadInvoicePdf(input: InvoicePdfInput, filename: strin const multipleCases = input.groups.length > 1; for (const g of input.groups) { - if (multipleCases) drawCaseHeader(g); + // Always show the case name above its charges (per-case subtotal only when >1 case). + drawCaseHeader(g); for (const item of g.items) { const isNonBillable = item.billable === false; From d6076097a41fe44418938c735c0ea4d6aed5320d Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:26:31 +0000 Subject: [PATCH 5/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/invoices.$invoiceId.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/invoices.$invoiceId.tsx b/src/routes/invoices.$invoiceId.tsx index d12784c..83bea10 100644 --- a/src/routes/invoices.$invoiceId.tsx +++ b/src/routes/invoices.$invoiceId.tsx @@ -207,6 +207,7 @@ function InvoiceDetail() { status: invoice.status, notes: invoice.notes, matter: groups.length === 1 ? (groups[0].caseRow?.title ?? null) : null, + caseNumber: groups.length === 1 ? (groups[0].caseRow?.case_number ?? null) : null, }, groups: groups.map((g) => ({ caseNumber: g.caseRow?.case_number ?? "—",