Merge pull request 'fix: Exported PO must include line item optional description' (#23) from claude/issue-8 into master

Reviewed-on: #23
This commit is contained in:
shad0w 2026-06-18 22:32:27 +00:00
commit 69901ba079

View file

@ -91,7 +91,9 @@ export async function GET(request: NextRequest, { params }: Props) {
const gstAmt = taxable * gstRate;
const li_ = li as typeof li & { name?: string };
const desc = li_.name ?? li.description ?? "";
return { sn: i + 1, desc, unit: li.unit, qty, unitPrice, gstRate, taxable, gstAmt, total: taxable + gstAmt };
// When both name and description exist, include the optional description separately
const optionalDesc = li_.name && li.description ? li.description : "";
return { sn: i + 1, desc, optionalDesc, unit: li.unit, qty, unitPrice, gstRate, taxable, gstAmt, total: taxable + gstAmt };
});
const totalTaxable = items.reduce((s, i) => s + i.taxable, 0);
@ -349,15 +351,18 @@ export async function GET(request: NextRequest, { params }: Props) {
for (let idx = 0; idx < BODY_ROWS; idx++) {
const r = HDR_ROW + 1 + idx;
// 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 descLen = (items[idx]?.desc ?? "").length + (items[idx]?.optionalDesc ?? "").length;
ws.getRow(r).height = descLen > 40 || items[idx]?.optionalDesc ? 32 : 20;
const item = items[idx];
const fillAlt = idx % 2 === 1
? { type: "pattern" as const, pattern: "solid" as const, fgColor: { argb: "FFFAFAFA" } }
: undefined;
sc(r, 1, item?.sn ?? null, { font: fBase, fill: fillAlt, border: bordAll, align: alignC });
sc(r, 2, item?.desc ?? "", { font: fBase, fill: fillAlt, border: bordAll, align: alignL });
const xlsxDesc = item
? (item.optionalDesc ? `${item.desc}\n${item.optionalDesc}` : item.desc)
: "";
sc(r, 2, xlsxDesc, { font: fBase, fill: fillAlt, border: bordAll, align: alignL });
ws.mergeCells(`B${r}:C${r}`);
sc(r, 4, item?.unit ?? "", { font: fBase, fill: fillAlt, border: bordAll, align: alignC });
sc(r, 5, item ? item.qty : null, { font: fBase, fill: fillAlt, border: bordAll, align: alignR, numFmt: NUM_FMT });
@ -467,7 +472,7 @@ export async function GET(request: NextRequest, { params }: Props) {
const itemRows = items.map((item, i) => `
<tr style="background:${i % 2 === 0 ? "#fff" : "#fafafa"}">
<td style="text-align:center">${item.sn}</td>
<td>${item.desc}</td>
<td>${item.desc}${item.optionalDesc ? `<br/><span style="font-size:7.5pt;color:#666;font-style:italic">${item.optionalDesc}</span>` : ""}</td>
<td style="text-align:center">${item.unit}</td>
<td style="text-align:right">${fmtNum(item.qty, item.qty % 1 === 0 ? 0 : 3)}</td>
<td style="text-align:right">${fmtNum(item.unitPrice)}</td>