diff --git a/packages/invoice-dashboard/src/lib/view-requests.svelte b/packages/invoice-dashboard/src/lib/view-requests.svelte index 1e66c1d0..8b6a6fce 100644 --- a/packages/invoice-dashboard/src/lib/view-requests.svelte +++ b/packages/invoice-dashboard/src/lib/view-requests.svelte @@ -521,10 +521,9 @@ try { await exportToPDF( request, - // FIXME: Use a non deprecated function - currencyManager.from( - request.currencyInfo.value, - request.currencyInfo.network + getCurrencyFromManager( + request.currencyInfo, + currencyManager ), config.logo ); diff --git a/packages/invoice-dashboard/src/utils/generateInvoice.ts b/packages/invoice-dashboard/src/utils/generateInvoice.ts index 760383a3..18f61d0f 100644 --- a/packages/invoice-dashboard/src/utils/generateInvoice.ts +++ b/packages/invoice-dashboard/src/utils/generateInvoice.ts @@ -23,72 +23,65 @@ export const exportToPDF = async ( ) => { await ensureHtml2PdfLoaded(); + const formatDate = (date: string | undefined) => { + return date ? new Date(date).toLocaleDateString() : "-"; + }; + + const renderAddress = (info: any) => { + const parts = [ + info?.address?.["street-address"], + info?.address?.locality, + info?.address?.["postal-code"], + info?.address?.["country-name"], + ].filter(Boolean); + return parts.length > 0 ? parts.join(", ") : "-"; + }; + const content = ` + -
+
- Logo + ${logo ? `Logo` : ""}
-

Issued on ${new Date( - invoice.contentData.creationDate - ).toLocaleDateString()}

-

Payment due by ${new Date( - invoice.contentData.paymentTerms.dueDate - ).toLocaleDateString()}

+

Issued on ${formatDate(invoice.contentData?.creationDate)}

+

Payment due by ${formatDate(invoice.contentData?.paymentTerms?.dueDate)}

-

INVOICE #${ - invoice.contentData.invoiceNumber +

INVOICE #${ + invoice.contentData?.invoiceNumber || "-" }

From:
-

${invoice.payee.value}

- ${invoice.contentData.sellerInfo.firstName ?? ""} ${ - invoice.contentData.sellerInfo.lastName ?? "" - }
- ${invoice.contentData.sellerInfo.address["street-address"] ?? ""}
- ${invoice.contentData.sellerInfo.address.locality ?? ""}${ - invoice.contentData.sellerInfo.address.locality ? "," : "" - } ${invoice.contentData.sellerInfo.address["postal-code"] ?? ""}
- ${invoice.contentData.sellerInfo.address["country-name"] ?? ""}
- ${ - invoice.contentData.sellerInfo.taxRegistration - ? `VAT: ${invoice.contentData.sellerInfo.taxRegistration}` - : "" - }
+

${invoice.payee?.value || "-"}

+ ${invoice.contentData?.sellerInfo?.firstName || ""} ${invoice.contentData?.sellerInfo?.lastName || ""}
+ ${renderAddress(invoice.contentData?.sellerInfo)}
+ ${invoice.contentData?.sellerInfo?.taxRegistration ? `VAT: ${invoice.contentData.sellerInfo.taxRegistration}` : ""}
To:
-

${invoice.payer.value}

- ${invoice.contentData.buyerInfo.firstName ?? ""} ${ - invoice.contentData.buyerInfo.lastName ?? "" - }
- ${invoice.contentData.buyerInfo.address["street-address"] ?? ""}
- ${invoice.contentData.buyerInfo.address.locality ?? ""}${ - invoice.contentData.sellerInfo.address.locality ? "," : "" - } ${invoice.contentData.buyerInfo.address["postal-code"] ?? ""}
- ${invoice.contentData.buyerInfo.address["country-name"] ?? ""}
- ${ - invoice.contentData.buyerInfo.taxRegistration - ? `VAT: ${invoice.contentData.buyerInfo.taxRegistration}` - : "" - }
+

${invoice.payer?.value || "-"}

+ ${invoice.contentData?.buyerInfo?.firstName || ""} ${invoice.contentData?.buyerInfo?.lastName || ""}
+ ${renderAddress(invoice.contentData?.buyerInfo)}
+ ${invoice.contentData?.buyerInfo?.taxRegistration ? `VAT: ${invoice.contentData.buyerInfo.taxRegistration}` : ""}
- Payment Chain: ${invoice.currencyInfo.network}
- Invoice Currency: ${invoice.currency}
+ Payment Chain: ${invoice.currencyInfo?.network || "-"}
+ Invoice Currency: ${invoice.currency || "-"}
Invoice Type: Regular Invoice
@@ -104,31 +97,33 @@ export const exportToPDF = async ( - ${invoice.contentData.invoiceItems + ${(invoice.contentData?.invoiceItems || []) .map( (item: any) => ` - ${ - item.name + ${item.name || "-"} + ${item.quantity || "-"} + ${ + item.unitPrice + ? formatUnits(BigInt(item.unitPrice), currency?.decimals || 0) + : "-" } ${ - item.quantity + item.discount + ? formatUnits(BigInt(item.discount), currency?.decimals || 0) + : "-" } - ${formatUnits( - item.unitPrice, - currency.decimals - )} - ${formatUnits( - item.discount, - currency.decimals - )} ${ - item.tax.amount - }% - ${formatUnits( - calculateItemTotal(item), - currency?.decimals - )} + item.tax?.amount ? `${item.tax.amount}%` : "-" + } + ${ + item + ? formatUnits( + BigInt(calculateItemTotal(item)), + currency?.decimals || 0 + ) + : "-" + } ` ) @@ -137,18 +132,19 @@ export const exportToPDF = async ( Due: - ${formatUnits( - invoice.expectedAmount, - currency.decimals - )} ${invoice.currency} + ${ + invoice.expectedAmount + ? `${formatUnits(BigInt(invoice.expectedAmount), currency?.decimals || 0)} ${invoice.currency || ""}` + : "-" + } ${ - invoice.contentData.note + invoice.contentData?.note ? `
-

Memo:

+

Note:

${invoice.contentData.note}

` : "" @@ -160,11 +156,25 @@ export const exportToPDF = async ( const opt = { margin: 10, - filename: `invoice-${invoice.contentData.invoiceNumber}.PDF`, - image: { type: "jpeg", quality: 0.98 }, - html2canvas: { scale: 2 }, - jsPDF: { unit: "mm", format: "a4", orientation: "portrait" }, + filename: `invoice-${invoice.contentData?.invoiceNumber || "unknown"}.pdf`, + html2canvas: { + scale: 2, + useCORS: true, + letterRendering: true, + }, + jsPDF: { + unit: "mm", + format: "a4", + orientation: "portrait", + compress: true, + }, }; - window.html2pdf().from(content).set(opt).save(); + const element = document.createElement("div"); + element.innerHTML = content; + document.body.appendChild(element); + + await window.html2pdf().from(element).set(opt).save(); + + document.body.removeChild(element); };