From 9efb1792c7ca97582366524131e327358ac67e7b Mon Sep 17 00:00:00 2001 From: Horacio Daniel Ros Date: Thu, 13 Aug 2026 20:25:00 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20mejorar=20generaci=C3=B3n=20de=20report?= =?UTF-8?q?es=20PDF=20con=20logo=20y=20tabla=20de=20movimientos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[clientId]/account/movements/page.tsx | 66 +++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/txclient/src/app/admin/(client-profile)/org/[oid]/client/[clientId]/account/movements/page.tsx b/txclient/src/app/admin/(client-profile)/org/[oid]/client/[clientId]/account/movements/page.tsx index c7b3d16..d855d34 100644 --- a/txclient/src/app/admin/(client-profile)/org/[oid]/client/[clientId]/account/movements/page.tsx +++ b/txclient/src/app/admin/(client-profile)/org/[oid]/client/[clientId]/account/movements/page.tsx @@ -183,14 +183,72 @@ export default function ClientAccountMovementsList() { const pdfFonts = (await import("pdfmake/build/vfs_fonts")) as any; pdfMake.vfs = pdfFonts.pdfMake ? pdfFonts.pdfMake.vfs : pdfFonts.vfs; - // Simplified report generation for brevity + let logoDataUrl = ""; + try { + const response = await fetch("/favicon512.png"); + const blob = await response.blob(); + logoDataUrl = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result as string); + reader.readAsDataURL(blob); + }); + } catch (e) { } + + const finalBalance = report.data.length > 0 + ? report.data[report.data.length - 1].balance + : report.balance; + + const tableBody = [ + [ + { text: "Fecha", bold: true }, + { text: "Descripción", bold: true }, + { text: "Crédito", bold: true, alignment: "right" }, + { text: "Débito", bold: true, alignment: "right" }, + { text: "Saldo", bold: true, alignment: "right" }, + ], + ...report.data.map((item) => [ + dayjs(item.date).format("DD/MM/YYYY"), + item.description || "-", + { text: item.credit ? formatPrice(item.credit) : "-", alignment: "right" }, + { text: item.debit ? formatPrice(item.debit) : "-", alignment: "right" }, + { text: formatPrice(item.balance), alignment: "right" }, + ]), + ]; + const docDefinition: any = { + pageOrientation: "landscape", + pageMargins: [30, 30, 30, 30], + defaultStyle: { + fontSize: 9, + }, content: [ - { text: "Resumen de Cuenta Corriente", fontSize: 18, bold: true, margin: [0, 0, 0, 10] }, + { + columns: [ + { text: "Resumen de Cuenta Corriente", fontSize: 18, bold: true, margin: [0, 0, 0, 10], width: "*" }, + ...(logoDataUrl ? [{ image: logoDataUrl, width: 45, margin: [0, 0, 0, 10], alignment: "right" }] : []), + ], + }, + { text: report.organizacionName, margin: [0, 0, 0, 5] }, { text: `Cliente: ${report.clientName}`, margin: [0, 0, 0, 5] }, { text: `Período: ${filterDateFrom.format("DD/MM/YYYY")} al ${filterDateTo.format("DD/MM/YYYY")}`, margin: [0, 0, 0, 20] }, - { text: "PDF Generado con Éxito", bold: true } - ] + report.data.length > 0 + ? { + table: { + headerRows: 1, + widths: ["auto", "*", "auto", "auto", "auto"], + body: tableBody, + }, + layout: "lightHorizontalLines", + margin: [0, 0, 0, 16], + } + : { text: "No hay movimientos en el período seleccionado.", italics: true, margin: [0, 0, 0, 16] }, + { + columns: [ + { text: "" }, + { text: `Saldo final del período: ${formatPrice(finalBalance)}`, bold: true, alignment: "right" }, + ], + }, + ], }; if ((window as any).Android && (window as any).Android.savePdf) {