From d68fc257a299cf021d82473ab9cbc4e31836a41b Mon Sep 17 00:00:00 2001 From: Thomas Joise Date: Sun, 19 Jul 2026 17:48:18 +0530 Subject: [PATCH] fix(docs): summary line for legacy imports + tidy Record-payment panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tax invoice line table: APEX-imported documents carry only totals (0 lines), so the table printed blank with just the grand total. Add a display-only fallback summary line derived from the doc's own totals — description from the doc-number's module prefix, qty 1, rate = taxable, GST% back-computed. Issued docs unchanged (immutability). New HQ documents already carry full line detail; unaffected. - DocumentView: the Record-payment form dropped in bare between the share row and the PDF. Wrap it in a titled card with a Close button so it reads as a clean section. Co-Authored-By: Claude Fable 5 --- apps/hq-web/src/pages/DocumentView.tsx | 14 +++++++++---- apps/hq/src/templates.ts | 27 +++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/apps/hq-web/src/pages/DocumentView.tsx b/apps/hq-web/src/pages/DocumentView.tsx index fb75d51..c87ace0 100644 --- a/apps/hq-web/src/pages/DocumentView.tsx +++ b/apps/hq-web/src/pages/DocumentView.tsx @@ -219,10 +219,16 @@ export function DocumentView() { {paying && ( - { setPaying(false); full.reload() }} - /> +
+
+

Record payment {doc.docNo !== null ? `— ${doc.docNo}` : ''}

+ +
+ { setPaying(false); full.reload() }} + /> +
)} {pdfErr !== undefined && PDF preview unavailable: {pdfErr}} diff --git a/apps/hq/src/templates.ts b/apps/hq/src/templates.ts index c504049..39a978d 100644 --- a/apps/hq/src/templates.ts +++ b/apps/hq/src/templates.ts @@ -74,6 +74,29 @@ function lineRow(l: BillLine, i: number, contents: string[]): string { ` } +/** + * Legacy APEX-imported documents carry only totals (no per-line detail). Rather than print + * a blank line table, show ONE summary line derived from the document's own stored totals: + * description from the doc-number's module prefix (e.g. "SMS/2024/10057" → "SMS"), qty 1, + * rate = taxable, and the GST% back-computed from the tax on the taxable value. Display-only + * — issued documents are never modified (immutability rule). + */ +function fallbackLineRow(doc: Doc): string { + const tax = doc.cgstPaise + doc.sgstPaise + doc.igstPaise + const rateBp = doc.taxablePaise > 0 ? Math.round((tax / doc.taxablePaise) * 10000) : 0 + const label = doc.docNo !== null && doc.docNo.includes('/') ? doc.docNo.split('/')[0]! : 'Software services' + return ` + 1 + ${esc(label)} + — + 1 + ${formatINR(doc.taxablePaise)} + ${formatINR(doc.taxablePaise)} + ${rateBp / 100}% + ${formatINR(doc.payablePaise)} + ` +} + function totalsRows(doc: Doc): string { const rows: [string, Paise][] = [['Taxable Value', doc.taxablePaise]] if (doc.igstPaise > 0) { @@ -254,7 +277,9 @@ export function documentHtml(doc: Doc, client: Client, company: Record - ${doc.payload.lines.map((l, i) => lineRow(l, i, doc.payload.lineContents?.[i] ?? [])).join('\n')} + ${doc.payload.lines.length > 0 + ? doc.payload.lines.map((l, i) => lineRow(l, i, doc.payload.lineContents?.[i] ?? [])).join('\n') + : fallbackLineRow(doc)} `}