@powerhousedao/contributor-billing 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"InvoicePDF.d.ts","sourceRoot":"","sources":["../../../editors/invoice/InvoicePDF.tsx"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,EAIb,MAAM,wCAAwC,CAAC;AA4ShD,UAAU,eAAe;IACvB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAoThD,CAAC"}
1
+ {"version":3,"file":"InvoicePDF.d.ts","sourceRoot":"","sources":["../../../editors/invoice/InvoicePDF.tsx"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,EAIb,MAAM,wCAAwC,CAAC;AA4ShD,UAAU,eAAe;IACvB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA2ZhD,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Document, Page, Text, View, StyleSheet, Image, } from "@react-pdf/renderer";
3
- import powerhouseLogo from "./assets/powerhouseLogo.png";
2
+ import { Document, Page, Text, View, StyleSheet, } from "@react-pdf/renderer";
4
3
  import countries from "world-countries";
5
4
  const countriesArray = countries;
6
5
  function getCountryName(countryCode) {
@@ -283,55 +282,98 @@ function formatNumber(value) {
283
282
  });
284
283
  }
285
284
  export const InvoicePDF = ({ invoice, fiatMode, }) => {
286
- console.log(invoice);
287
- return (_jsx(Document, { children: _jsxs(Page, { size: "A4", style: styles.pageBackground, children: [_jsxs(View, { style: styles.page, children: [_jsxs(View, { style: {
288
- flexDirection: "row",
289
- justifyContent: "space-between",
290
- alignItems: "flex-start",
291
- }, children: [_jsxs(View, { style: { flexDirection: "column", alignItems: "flex-start" }, children: [_jsx(Image, { style: styles.logo, src: powerhouseLogo }), _jsxs(View, { children: [_jsx(Text, { style: styles.invoiceLabel, children: "Invoice number" }), _jsx(Text, { style: styles.invoiceNumber, children: invoice.invoiceNo })] })] }), _jsxs(View, { style: { alignItems: "flex-end" }, children: [_jsxs(Text, { style: styles.invoiceLabel, children: ["Invoice of (", invoice.currency, ")"] }), _jsx(Text, { style: [
292
- styles.invoiceNumber,
293
- { fontSize: 18, fontWeight: "bold" },
294
- ], children: formatNumber(invoice.totalPriceTaxIncl) })] })] }), _jsxs(View, { style: {
295
- flexDirection: "row",
296
- justifyContent: "space-between",
297
- marginTop: 20,
298
- }, children: [_jsxs(View, { style: { width: "45%" }, children: [_jsx(Text, { style: styles.sectionTitle, children: "Issuer" }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Name:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.name })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Tax/Corp ID:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.id?.taxId ||
299
- invoice.issuer
300
- .id?.corpRegId ||
301
- "" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.streetAddress || "" })] }), invoice.issuer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, children: [invoice.issuer.address?.city || "", ",", " ", getCountryName(invoice.issuer.address?.country || "") || ""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.postalCode || "00000" })] }), invoice.issuer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.contactInfo.email })] }))] }), _jsxs(View, { style: { width: "45%" }, children: [_jsx(Text, { style: styles.sectionTitle, children: "Payer" }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Name:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.name })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Tax/Corp ID:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.id?.taxId ||
302
- invoice.payer
303
- .id?.corpRegId ||
304
- "" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.streetAddress || "" })] }), invoice.payer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, children: [invoice.payer.address?.city || "", ",", " ", getCountryName(invoice.payer.address?.country || "") || ""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.postalCode || "00000" })] }), invoice.payer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.contactInfo.email })] }))] }), _jsxs(View, { style: {
305
- width: "30%",
306
- alignItems: "flex-end",
307
- textAlign: "right",
308
- }, children: [_jsxs(View, { style: { marginBottom: 18, width: "100%" }, children: [_jsx(Text, { style: {
309
- color: "#9ea0a2",
310
- fontSize: 12,
311
- textAlign: "right",
312
- fontFamily: "Helvetica",
313
- fontWeight: "normal",
314
- }, children: "Invoice date" }), _jsx(Text, { style: {
315
- fontWeight: 4,
316
- fontSize: 12,
317
- textAlign: "right",
318
- color: "#000",
319
- fontFamily: "Helvetica",
320
- }, children: formatDate(invoice.dateIssued) })] }), _jsxs(View, { style: { marginBottom: 18, width: "100%" }, children: [_jsx(Text, { style: {
321
- color: "#9ea0a2",
322
- fontSize: 12,
323
- textAlign: "right",
324
- fontFamily: "Helvetica",
325
- fontWeight: "normal",
326
- }, children: "Due date" }), _jsx(Text, { style: {
327
- fontWeight: 4,
328
- fontSize: 12,
329
- textAlign: "right",
330
- color: "#000",
331
- fontFamily: "Helvetica",
332
- }, children: formatDate(invoice.dateDue) })] })] })] }), _jsxs(View, { style: [styles.paymentSection, { marginLeft: 0 }], children: [_jsx(Text, { style: styles.sectionTitle, children: "Payment Information" }), fiatMode ? (_jsxs("div", { children: [_jsx(PaymentSectionFiat, { paymentRouting: invoice.issuer.paymentRouting }), invoice.issuer.paymentRouting?.bank?.memo && (_jsxs(Text, { style: [styles.companyInfo, { marginTop: 20 }], children: ["Memo: ", invoice.issuer.paymentRouting?.bank?.memo || "", " "] }))] })) : (_jsx(PaymentSectionCrypto, { paymentRouting: invoice.issuer.paymentRouting }))] }), _jsxs(View, { style: styles.table, children: [_jsxs(View, { style: styles.tableHeader, children: [_jsx(Text, { style: styles.tableCol40, children: "Description" }), _jsx(Text, { style: styles.tableCol15, children: "Quantity" }), _jsx(Text, { style: styles.tableCol15, children: "Unit Price" }), _jsx(Text, { style: styles.tableCol15, children: "Tax" }), _jsx(Text, { style: styles.tableCol15, children: "Total" })] }), invoice.lineItems.map((item, index) => (_jsx(InvoiceLineItem, { item: item, currency: invoice.currency }, index)))] }), _jsxs(View, { style: styles.totals, children: [_jsxs(View, { style: styles.totalRow, children: [_jsx(Text, { style: styles.totalLabel, children: "Subtotal" }), _jsx(Text, { style: styles.totalValue, children: formatCurrency(invoice.lineItems.reduce((sum, item) => sum + item.quantity * item.unitPriceTaxExcl, 0), invoice.currency) })] }), _jsxs(View, { style: styles.totalRow, children: [_jsx(Text, { style: styles.totalLabel, children: "Tax" }), _jsx(Text, { style: styles.totalValue, children: formatCurrency(invoice.lineItems.reduce((sum, item) => sum +
333
- item.quantity *
334
- (item.unitPriceTaxIncl - item.unitPriceTaxExcl), 0), invoice.currency) })] }), _jsxs(View, { style: styles.totalRowBold, children: [_jsx(Text, { style: styles.totalLabelBold, children: "Total" }), _jsx(Text, { style: styles.totalValueBold, children: formatCurrency(invoice.lineItems.reduce((sum, item) => sum + item.quantity * item.unitPriceTaxIncl, 0), invoice.currency) })] })] })] }), _jsxs(View, { style: { marginLeft: 40 }, children: [_jsx(Text, { style: styles.termsTitle, children: "Terms & Conditions" }), _jsx(Text, { style: styles.termsText, children: "Please pay within 30 days of receiving this invoice." })] })] }) }));
285
+ const MAX_ITEMS_FIRST_PAGE = 15;
286
+ const MAX_ITEMS_OTHER_PAGES = 20;
287
+ // Helper to chunk line items with different first page size
288
+ function chunkLineItems(lineItems, firstPageSize, otherPageSize) {
289
+ if (lineItems.length <= firstPageSize)
290
+ return [lineItems];
291
+ const chunks = [lineItems.slice(0, firstPageSize)];
292
+ let i = firstPageSize;
293
+ while (i < lineItems.length) {
294
+ chunks.push(lineItems.slice(i, i + otherPageSize));
295
+ i += otherPageSize;
296
+ }
297
+ return chunks;
298
+ }
299
+ const lineItemChunks = chunkLineItems(invoice.lineItems, MAX_ITEMS_FIRST_PAGE, MAX_ITEMS_OTHER_PAGES);
300
+ const totalPages = lineItemChunks.length;
301
+ return (_jsx(Document, { children: lineItemChunks.map((items, pageIndex) => (_jsxs(Page, { size: "A4", style: styles.pageBackground, children: [_jsxs(View, { style: styles.page, children: [pageIndex === 0 && (_jsxs(_Fragment, { children: [_jsxs(View, { style: {
302
+ flexDirection: "row",
303
+ justifyContent: "space-between",
304
+ alignItems: "flex-start",
305
+ }, children: [_jsxs(View, { style: {
306
+ flexDirection: "column",
307
+ alignItems: "flex-start",
308
+ }, children: [_jsx(Text, { style: { fontSize: 20, fontWeight: "bold" }, children: invoice.issuer.name }), _jsxs(View, { children: [_jsx(Text, { style: styles.invoiceLabel, children: "Invoice number" }), _jsx(Text, { style: styles.invoiceNumber, children: invoice.invoiceNo })] })] }), _jsxs(View, { style: { alignItems: "flex-end" }, children: [_jsxs(Text, { style: styles.invoiceLabel, children: ["Invoice of (", invoice.currency, ")"] }), _jsx(Text, { style: [
309
+ styles.invoiceNumber,
310
+ { fontSize: 18, fontWeight: "bold" },
311
+ ], children: formatNumber(invoice.totalPriceTaxIncl) })] })] }), _jsxs(View, { style: {
312
+ flexDirection: "row",
313
+ justifyContent: "space-between",
314
+ marginTop: 20,
315
+ }, children: [_jsxs(View, { style: { width: "45%" }, children: [_jsx(Text, { style: styles.sectionTitle, children: "Issuer" }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Name:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.name })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Tax/Corp ID:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.id
316
+ ?.taxId ||
317
+ invoice.issuer
318
+ .id?.corpRegId ||
319
+ "" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.streetAddress || "" })] }), invoice.issuer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, children: [invoice.issuer.address?.city || "", ",", " ", getCountryName(invoice.issuer.address?.country || "") || ""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.address?.postalCode || "00000" })] }), invoice.issuer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.issuer.contactInfo.email })] }))] }), _jsxs(View, { style: { width: "45%" }, children: [_jsx(Text, { style: styles.sectionTitle, children: "Payer" }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Name:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.name })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Tax/Corp ID:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.id?.taxId ||
320
+ invoice.payer
321
+ .id?.corpRegId ||
322
+ "" })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Address:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.streetAddress || "" })] }), invoice.payer.address?.extendedAddress && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.extendedAddress || "" })] })), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel }), _jsxs(Text, { style: styles.companyInfo, children: [invoice.payer.address?.city || "", ",", " ", getCountryName(invoice.payer.address?.country || "") ||
323
+ ""] })] }), _jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Postcode:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.address?.postalCode || "00000" })] }), invoice.payer.contactInfo?.email && (_jsxs(View, { style: styles.row, children: [_jsx(Text, { style: styles.companyInfoLabel, children: "Email:" }), _jsx(Text, { style: styles.companyInfo, children: invoice.payer.contactInfo.email })] }))] }), _jsxs(View, { style: {
324
+ width: "30%",
325
+ alignItems: "flex-end",
326
+ textAlign: "right",
327
+ }, children: [_jsxs(View, { style: { marginBottom: 5, width: "100%" }, children: [_jsx(Text, { style: {
328
+ color: "#9ea0a2",
329
+ fontSize: 12,
330
+ textAlign: "right",
331
+ fontFamily: "Helvetica",
332
+ fontWeight: "normal",
333
+ }, children: "Invoice date" }), _jsx(Text, { style: {
334
+ fontWeight: 4,
335
+ fontSize: 12,
336
+ textAlign: "right",
337
+ color: "#000",
338
+ fontFamily: "Helvetica",
339
+ }, children: formatDate(invoice.dateIssued) })] }), invoice.dateDelivered && (_jsxs(View, { style: { marginBottom: 5, width: "100%" }, children: [_jsx(Text, { style: {
340
+ color: "#9ea0a2",
341
+ fontSize: 12,
342
+ textAlign: "right",
343
+ fontFamily: "Helvetica",
344
+ fontWeight: "normal",
345
+ }, children: "Delivery date" }), _jsx(Text, { style: {
346
+ fontWeight: 4,
347
+ fontSize: 12,
348
+ textAlign: "right",
349
+ color: "#000",
350
+ fontFamily: "Helvetica",
351
+ }, children: formatDate(invoice.dateDelivered) })] })), _jsxs(View, { style: { marginBottom: 5, width: "100%" }, children: [_jsx(Text, { style: {
352
+ color: "#9ea0a2",
353
+ fontSize: 12,
354
+ textAlign: "right",
355
+ fontFamily: "Helvetica",
356
+ fontWeight: "normal",
357
+ }, children: "Due date" }), _jsx(Text, { style: {
358
+ fontWeight: 4,
359
+ fontSize: 12,
360
+ textAlign: "right",
361
+ color: "#000",
362
+ fontFamily: "Helvetica",
363
+ }, children: formatDate(invoice.dateDue) })] })] })] }), _jsxs(View, { style: [styles.paymentSection, { marginLeft: 0 }], children: [_jsx(Text, { style: styles.sectionTitle, children: "Payment Information" }), fiatMode ? (_jsxs("div", { children: [_jsx(PaymentSectionFiat, { paymentRouting: invoice.issuer.paymentRouting }), invoice.issuer.paymentRouting?.bank?.memo && (_jsxs(Text, { style: [styles.companyInfo, { marginTop: 20 }], children: ["Memo:", " ", invoice.issuer.paymentRouting?.bank?.memo || "", " "] }))] })) : (_jsx(PaymentSectionCrypto, { paymentRouting: invoice.issuer.paymentRouting }))] })] })), _jsxs(View, { style: styles.table, children: [_jsxs(View, { style: styles.tableHeader, children: [_jsx(Text, { style: styles.tableCol40, children: "Description" }), _jsx(Text, { style: styles.tableCol15, children: "Quantity" }), _jsx(Text, { style: styles.tableCol15, children: "Unit Price" }), _jsx(Text, { style: styles.tableCol15, children: "Tax" }), _jsx(Text, { style: styles.tableCol15, children: "Total" })] }), items.map((item, index) => (_jsx(InvoiceLineItem, { item: item, currency: invoice.currency }, index + pageIndex * 1000)))] }), pageIndex === totalPages - 1 && (_jsx(_Fragment, { children: _jsxs(View, { style: styles.totals, children: [_jsxs(View, { style: styles.totalRow, children: [_jsx(Text, { style: styles.totalLabel, children: "Subtotal" }), _jsx(Text, { style: styles.totalValue, children: formatCurrency(invoice.lineItems.reduce((sum, item) => sum + item.quantity * item.unitPriceTaxExcl, 0), invoice.currency) })] }), _jsxs(View, { style: styles.totalRow, children: [_jsx(Text, { style: styles.totalLabel, children: "Tax" }), _jsx(Text, { style: styles.totalValue, children: formatCurrency(invoice.lineItems.reduce((sum, item) => sum +
364
+ item.quantity *
365
+ (item.unitPriceTaxIncl - item.unitPriceTaxExcl), 0), invoice.currency) })] }), _jsxs(View, { style: styles.totalRowBold, children: [_jsx(Text, { style: styles.totalLabelBold, children: "Total" }), _jsx(Text, { style: styles.totalValueBold, children: formatCurrency(invoice.lineItems.reduce((sum, item) => sum + item.quantity * item.unitPriceTaxIncl, 0), invoice.currency) })] })] }) }))] }), _jsxs(View, { style: {
366
+ marginLeft: 40,
367
+ flexDirection: "row",
368
+ alignItems: "center",
369
+ justifyContent: "space-between",
370
+ width: "90%",
371
+ }, children: [_jsxs(View, { children: [_jsx(Text, { style: styles.termsTitle, children: "Terms & Conditions" }), _jsx(Text, { style: styles.termsText, children: "Please pay within 30 days of receiving this invoice." })] }), _jsx(Text, { style: {
372
+ fontSize: 10,
373
+ color: "#6B7280",
374
+ textAlign: "right",
375
+ flex: 1,
376
+ }, children: `${pageIndex + 1}/${totalPages}` })] })] }, pageIndex))) }));
335
377
  };
336
378
  // New component for issuer and payer sections
337
379
  const InvoiceSection = ({ title, data, }) => (_jsxs(View, { style: styles.gridColumn, children: [_jsx(Text, { style: styles.sectionTitle, children: title }), title === "Issuer" && (_jsxs(_Fragment, { children: [_jsx(InvoiceField, { label: "Issue Date", value: formatDate(data.dateIssued) }), _jsx(InvoiceField, { label: "Delivery Date", value: formatDate(data.dateDelivered) })] })), title === "Payer" && (_jsx(InvoiceField, { label: "Due Date", value: formatDate(data.dateDue) })), _jsx(InvoiceField, { label: "Name", value: data.name }), _jsx(InvoiceField, { label: data.id?.taxId ? "Tax ID" : data.id?.corpRegId ? "Corp. Reg" : "", value: data.id?.taxId || data.id?.corpRegId || "" }), _jsx(InvoiceField, { label: "Address", value: data.address?.streetAddress || "" }), _jsx(InvoiceField, { label: "City", value: data.address?.city || "" }), _jsx(InvoiceField, { label: "Country", value: getCountryName(data.address?.country || "") || "" }), _jsx(InvoiceField, { label: "Email", value: data.contactInfo?.email || "" })] }));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powerhousedao/contributor-billing",
3
3
  "description": "Document models that help contributors of open organisations get paid anonymously for their work on a monthly basis.",
4
- "version": "0.0.5",
4
+ "version": "0.0.6",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "files": [