From 6763a604212c3cc14ef32f885a7e4166933e74f6 Mon Sep 17 00:00:00 2001 From: Hardik Date: Sun, 31 May 2026 02:29:33 +0530 Subject: [PATCH] fix(export): widen columns and increase row heights to prevent cell cutoff Co-Authored-By: Claude Sonnet 4.6 --- App/app/api/po/[id]/export/route.ts | 82 +++++++++++++++-------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/App/app/api/po/[id]/export/route.ts b/App/app/api/po/[id]/export/route.ts index 535f1e2..761fa8e 100644 --- a/App/app/api/po/[id]/export/route.ts +++ b/App/app/api/po/[id]/export/route.ts @@ -170,15 +170,15 @@ export async function GET(request: NextRequest, { params }: Props) { // ── Column widths (A-I) ───────────────────────────────────────────────── ws.columns = [ - { width: 20 }, // A - { width: 4 }, // B - { width: 22 }, // C - { width: 10 }, // D - { width: 7 }, // E - { width: 16 }, // F - { width: 7 }, // G - { width: 7 }, // H - { width: 16 }, // I + { width: 22 }, // A — label column ("Cost Centre", "Vendor Name…") + { width: 4 }, // B — spacer; A:B merge = 26 for labels + { width: 28 }, // C — main content / descriptions + { width: 15 }, // D — secondary labels ("Accounting Code", "Unit") + { width: 8 }, // E — small values (Qty, etc.) + { width: 15 }, // F — unit price + { width: 15 }, // G — labels "Requested By" / "Taxable cost" (was 7 — caused cutoff) + { width: 8 }, // H — GST% + { width: 16 }, // I — Total cost ]; // ── Style constants ───────────────────────────────────────────────────── @@ -227,10 +227,10 @@ export async function GET(request: NextRequest, { params }: Props) { } // ── Row heights ───────────────────────────────────────────────────────── - ws.getRow(1).height = 22; - ws.getRow(2).height = 14; - ws.getRow(3).height = 14; - ws.getRow(4).height = 18; + ws.getRow(1).height = 24; // Company name + ws.getRow(2).height = 16; // Address + ws.getRow(3).height = 14; // Tel / Email + ws.getRow(4).height = 20; // PURCHASE ORDER title // ══ ROW 1: Company name ═════════════════════════════════════════════════ sc(1, 1, CO_NAME, { font: fTitle, align: alignC }); @@ -251,7 +251,7 @@ export async function GET(request: NextRequest, { params }: Props) { ws.getRow(4).border = { top: thin(), bottom: thin() }; // ══ ROW 5: PO Number & Date ══════════════════════════════════════════════ - ws.getRow(5).height = 16; + ws.getRow(5).height = 18; sc(5, 1, "Purchase Order No:", { font: fBold, fill: fillLbl, border: bordAll, align: alignL }); ws.mergeCells("A5:B5"); sc(5, 3, po.poNumber, { font: { ...fBold, color: { argb: "FF1A1A1A" } }, border: bordAll, align: alignL }); @@ -260,7 +260,7 @@ export async function GET(request: NextRequest, { params }: Props) { sc(5, 9, fmtDate(po.createdAt), { font: fBase, border: bordAll, align: alignL }); // ══ ROW 6: PI / Quotation ════════════════════════════════════════════════ - ws.getRow(6).height = 14; + ws.getRow(6).height = 16; sc(6, 1, "Performa Invoice / Quotation No:", { font: fBold, fill: fillLbl, border: bordAll, align: alignL }); ws.mergeCells("A6:B6"); sc(6, 3, piNo, { font: fBase, border: bordAll, align: alignL }); @@ -269,41 +269,41 @@ export async function GET(request: NextRequest, { params }: Props) { ws.mergeCells("G6:H6"); sc(6, 9, piDate, { font: fBase, border: bordAll, align: alignL }); - // ══ ROW 7: Cost Centre / Account / Requested By ═══════════════════════ - ws.getRow(7).height = 14; - sc(7, 1, "Cost Centre", { font: fBold, fill: fillLbl, border: bordAll, align: alignL }); + // ══ ROW 7: Cost Centre / Accounting Code / Requested By ══════════════ + ws.getRow(7).height = 18; + sc(7, 1, "Cost Centre", { font: fBold, fill: fillLbl, border: bordAll, align: alignL }); ws.mergeCells("A7:B7"); - sc(7, 3, "Pelagia Marine Services Pvt. Ltd.", { font: fBase, border: bordAll, align: alignL }); - sc(7, 4, "Accounting Code", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); - ws.mergeCells("D7:E7"); - sc(7, 6, po.account.code, { font: fBase, border: bordAll, align: alignC }); - sc(7, 7, "Requested By", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); - sc(7, 8, po.submitter.name, { font: fBase, border: bordAll, align: alignL }); + sc(7, 3, CO_NAME, { font: fBase, border: bordAll, align: alignL }); + ws.mergeCells("C7:D7"); // span C+D so company name has room + sc(7, 5, "Accounting Code",{ font: fBold, fill: fillLbl, border: bordAll, align: alignC }); + sc(7, 6, po.account.code, { font: fBase, border: bordAll, align: alignC }); + sc(7, 7, "Requested By", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); + sc(7, 8, po.submitter.name,{ font: fBase, border: bordAll, align: alignL }); ws.mergeCells("H7:I7"); - // ══ ROW 8: Requisition / Approved By ═════════════════════════════════ - ws.getRow(8).height = 14; - sc(8, 1, "Cost Centre/Office Requisition Number", { font: fBold, fill: fillLbl, border: bordAll, align: alignL }); + // ══ ROW 8: Requisition / Reqn. Date / Approved By ════════════════════ + ws.getRow(8).height = 18; + sc(8, 1, "Cost Centre/Office Requisition No.",{ font: fBold, fill: fillLbl, border: bordAll, align: alignL }); ws.mergeCells("A8:B8"); - sc(8, 3, reqNo, { font: fBase, border: bordAll, align: alignL }); - sc(8, 4, "Reqn. Date", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); - ws.mergeCells("D8:E8"); - sc(8, 6, reqDate, { font: fBase, border: bordAll, align: alignC }); - sc(8, 7, "Approved By", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); - sc(8, 8, approvedBy, { font: fBase, border: bordAll, align: alignL }); + sc(8, 3, reqNo, { font: fBase, border: bordAll, align: alignL }); + ws.mergeCells("C8:D8"); + sc(8, 5, "Reqn. Date", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); + sc(8, 6, reqDate, { font: fBase, border: bordAll, align: alignC }); + sc(8, 7, "Approved By", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); + sc(8, 8, approvedBy, { font: fBase, border: bordAll, align: alignL }); ws.mergeCells("H8:I8"); // ══ ROWS 9-10: Place of Delivery (2-row span) ═══════════════════════ - ws.getRow(9).height = 14; - ws.getRow(10).height = 14; + ws.getRow(9).height = 20; + ws.getRow(10).height = 20; sc(9, 1, "Place of Delivery", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); ws.mergeCells("A9:B10"); sc(9, 3, delivery, { font: fBase, border: bordAll, align: alignL }); ws.mergeCells("C9:I10"); // ══ ROWS 11-12: Invoice Details (2-row span) ════════════════════════ - ws.getRow(11).height = 14; - ws.getRow(12).height = 13; + ws.getRow(11).height = 18; + ws.getRow(12).height = 16; sc(11, 1, "Invoice Details", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); ws.mergeCells("A11:B12"); sc(11, 3, INV_ADDR, { font: fSmall, border: { top: thin(), left: thin(), right: thin() }, align: alignL }); @@ -312,7 +312,7 @@ export async function GET(request: NextRequest, { params }: Props) { ws.mergeCells("C12:I12"); // ══ ROW 13: Vendor Name & Address ═══════════════════════════════════ - ws.getRow(13).height = 28; + ws.getRow(13).height = 32; sc(13, 1, "Vendor Name & Address", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); ws.mergeCells("A13:B13"); sc(13, 3, po.vendor?.name ?? "—", { font: fBold, border: bordAll, align: alignL }); @@ -320,7 +320,7 @@ export async function GET(request: NextRequest, { params }: Props) { ws.mergeCells("D13:I13"); // ══ ROW 14: Contact ═════════════════════════════════════════════════ - ws.getRow(14).height = 14; + ws.getRow(14).height = 18; sc(14, 1, "Contact Person name / mobile no.", { font: fBold, fill: fillLbl, border: bordAll, align: alignC }); ws.mergeCells("A14:B14"); sc(14, 3, vendorContact, { font: fSmall, border: bordAll, align: alignL }); @@ -345,7 +345,9 @@ export async function GET(request: NextRequest, { params }: Props) { const BODY_ROWS = Math.max(items.length, 7); // reserve at least 7 rows for (let idx = 0; idx < BODY_ROWS; idx++) { const r = HDR_ROW + 1 + idx; - ws.getRow(r).height = 15; + // Taller rows: long item names + potential description sub-line need room + const descLen = (items[idx]?.desc ?? "").length; + ws.getRow(r).height = descLen > 40 ? 28 : 20; const item = items[idx]; const fillAlt = idx % 2 === 1 ? { type: "pattern" as const, pattern: "solid" as const, fgColor: { argb: "FFFAFAFA" } }