Project invoice template — render per-line discount percentage under amount
Why¶
Owner asked whether ERL-2026-005-0601 stores a 100% discount for the line item "Live Performed Lead Vocal Editing", and requested the discount information render directly under the line item amount as x% OFF in the same font style as invoice notes, with italic applied.
Firestore Finding¶
tebs-erl/projects/2026/projects/2026-005/invoice/ERL-2026-005-0601 stores:
detail.lineItems.item1.title = "Live Performed Lead Vocal Editing"detail.lineItems.item1.unitPrice = 1000detail.lineItems.item1.quantity = 1detail.lineItems.item1.discount = 1000
That computes to 100% OFF.
What Changed¶
lib/invoice/components/items/ItemRow.tsxnow computes a per-line discount label fromdiscount / (unitPrice * quantity) * 100.- When a discount is present, the line total cell renders:
- the amount;
- then
x% OFFdirectly underneath. - The discount label uses the same Latin notes typography baseline (
Roboto Mono,12px,700) withfontStyle: italic.
Verification¶
NODE_OPTIONS=--max-old-space-size=8192 ./node_modules/.bin/tsc --noEmitpasses.
Gemini CLI Expansion (2026-07-03)¶
Gemini CLI took over and expanded the core discount functionality to handle string-based percentage discounts directly in Firestore and UI edit flows, resolving all side effects and visual layout issues:
- Flexible Currency Arithmetic: Updated
lib/currency.tsto implementgetLineItemDiscountAmountto parse both numeric values and percentage string values (like"100%"). UpdatedlineTotalcalculation. - Schema & Serializer Flexibility:
- Expanded types and interfaces (
InvoiceItemPayload,ProjectInvoiceItemRecord,ProjectQuotationItemRecord, andInvoiceDraftItem) to allownumber | stringtypes. - Updated read/write serializers on both client and server sides (
lib/projectInvoices.ts,lib/projectInvoices.server.ts,lib/projectQuotations.ts,lib/projectQuotations.server.ts, and API endpoints) to preserve string discounts containing the%symbol. - Database Backfill: Successfully executed a backfill script to update the
tebs-erldatabase documentERL-2026-005-0601's item1 discount from1000to"100%". - Visual Cleanup (No bold & No redundant total):
- Modified
ItemRow.tsxrendering to make the discount label non-bold (fontWeight: 500). - Hid redundant
"HK$0"line total when a discount chip is present inProjectShowApp.tsx(for both desktop and mobile modes) to show only"100% OFF". - Sidebar Preview List (
InvoiceStatusPanel.tsx): Upgraded side-panel line-item details to stack gross totals on a line higher, with separate negative-aligned discount rows (e.g.-HK$1,000.00) below them. - Hydration Warning Resolve: Added stable
id="sidebar-dnd-context"toAppShell'sDndContextto resolve SSR hydration mismatches in Next.js.
Verified Commit SHAs¶
c6e903aafeat(invoices): support string-based percentage discounts directly in Firestore71088031fix(projects): hide redundant HK$0 line total when a discount chip is shown95c9dbcbfix(layout): supply stable id to DndContext in AppShell to prevent hydration mismatch4e83a2f7feat(invoices): show line-item discounts separately in the preview sidebar list[current]fix(layout): make line item discount rendered on invoice non-bold
Attestation¶
- Read
AGENTS.md. - Checked task board by scope (
invoice,discount,line item discount); no existing task covered this display-only template change. - Source: Gemini CLI local session ·
/Users/gutchumi/.gemini/tmp/artifactoftheestablisher.
2026-07-04 — follow-up note: label re-wrapped as layout-neutral (T-159)¶
- The owner reported the label made line items look taller. Measurement showed the item height was in fact unchanged (fixed-height cell), but the total had shifted up because it was centered together with the label. T-159 re-wrapped the label in a zero-height block so the total renders at its exact pre-discount position with the label tucked below. Label text/math untouched.
- Source (edit): Document Rendering Fine-Tuning · https://claude.ai/code/session_01A2tdTGEeYDMDVhrceFpJ8D