umwd-components 0.1.808 → 0.1.809
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.
- package/dist/cjs/src/components/e-commerce/invoice/InvoicePDF.js +1 -1
- package/dist/cjs/tsconfig.build.tsbuildinfo +1 -1
- package/dist/esm/src/components/e-commerce/invoice/InvoicePDF.js +70 -59
- package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
- package/dist/esm/types/components/e-commerce/invoice/InvoicePDFOLD.d.ts +13 -0
- package/package.json +1 -1
|
@@ -15,34 +15,48 @@ import Button from '@mui/material/Button';
|
|
|
15
15
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
16
16
|
import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf';
|
|
17
17
|
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
// Custom hook for PDF renderer with proper error handling and cleanup
|
|
19
|
+
const usePDFRenderer = () => {
|
|
20
|
+
const [pdfComponents, setPdfComponents] = useState(null);
|
|
21
|
+
const [loading, setLoading] = useState(true);
|
|
22
|
+
const [error, setError] = useState(null);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
let isMounted = true;
|
|
25
|
+
const loadPDFRenderer = async () => {
|
|
26
|
+
try {
|
|
27
|
+
const renderer = await import('@react-pdf/renderer');
|
|
28
|
+
if (isMounted) {
|
|
29
|
+
setPdfComponents(renderer);
|
|
30
|
+
setLoading(false);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
console.error("Failed to load PDF renderer:", err);
|
|
35
|
+
if (isMounted) {
|
|
36
|
+
setError("Failed to load PDF components");
|
|
37
|
+
setLoading(false);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
loadPDFRenderer();
|
|
42
|
+
return () => {
|
|
43
|
+
isMounted = false;
|
|
44
|
+
};
|
|
45
|
+
}, []);
|
|
46
|
+
return { pdfComponents, loading, error };
|
|
47
|
+
};
|
|
48
|
+
// Helper function to safely access nested properties
|
|
49
|
+
const safeGet = (obj, path, defaultValue = '') => {
|
|
50
|
+
return path.split('.').reduce((current, key) => current && current[key] !== undefined ? current[key] : defaultValue, obj);
|
|
25
51
|
};
|
|
26
|
-
// TODO Think of a proper solution for theming this file for multiple clients
|
|
27
|
-
// Font.register({
|
|
28
|
-
// family: "Roboto",
|
|
29
|
-
// fonts: [
|
|
30
|
-
// { src: roboto }, // font-style: normal, font-weight: normal
|
|
31
|
-
// { src: robotoBold, fontWeight: "bold" },
|
|
32
|
-
// { src: robotoItalic, fontStyle: "italic" },
|
|
33
|
-
// ],
|
|
34
|
-
// });
|
|
35
52
|
// Styles will be created when PDF renderer is loaded
|
|
36
53
|
const createStyles = (StyleSheet) => StyleSheet.create({
|
|
37
54
|
page: {
|
|
38
55
|
flexDirection: "column",
|
|
39
56
|
backgroundColor: "#E4E4E4",
|
|
40
|
-
// fontFamily: "Roboto",
|
|
41
57
|
},
|
|
42
58
|
header: {
|
|
43
59
|
padding: 10,
|
|
44
|
-
// backgroundColor: lightThemeOptions.palette.primary.main,
|
|
45
|
-
// color: lightThemeOptions.palette.primary.contrastText,
|
|
46
60
|
flexDirection: "row",
|
|
47
61
|
alignItems: "center",
|
|
48
62
|
},
|
|
@@ -73,67 +87,64 @@ const createStyles = (StyleSheet) => StyleSheet.create({
|
|
|
73
87
|
// Create Document Component
|
|
74
88
|
const InvoicePDF = ({ props }) => {
|
|
75
89
|
const { invoice } = props;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
useEffect(() => {
|
|
79
|
-
const initializePDF = async () => {
|
|
80
|
-
const renderer = await loadPDFRenderer();
|
|
81
|
-
if (renderer) {
|
|
82
|
-
setPdfComponents(renderer);
|
|
83
|
-
setStyles(createStyles(renderer.StyleSheet));
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
initializePDF();
|
|
87
|
-
}, []);
|
|
88
|
-
if (!pdfComponents || !styles) {
|
|
90
|
+
const { pdfComponents, loading, error } = usePDFRenderer();
|
|
91
|
+
if (loading) {
|
|
89
92
|
return jsx(CircularProgress, {});
|
|
90
93
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
if (error) {
|
|
95
|
+
return jsxs("div", { children: ["Error loading PDF components: ", error] });
|
|
96
|
+
}
|
|
97
|
+
if (!pdfComponents) {
|
|
98
|
+
return jsx("div", { children: "PDF components not available" });
|
|
99
|
+
}
|
|
100
|
+
// Validate invoice data
|
|
101
|
+
if (!invoice) {
|
|
102
|
+
return jsx("div", { children: "No invoice data provided" });
|
|
103
|
+
}
|
|
104
|
+
const { Document, Page, View, Text, StyleSheet } = pdfComponents;
|
|
105
|
+
const styles = createStyles(StyleSheet);
|
|
106
|
+
const { seller_business_credentials, seller_company_address, buyer_company_address, buyer_business_credentials, type, } = invoice;
|
|
107
|
+
const renderCreditNote = () => (jsx(Document, { title: `credit_${safeGet(invoice, 'invoice_number', 'unknown')}`, children: jsxs(Page, { size: "A4", style: styles.page, children: [jsx(View, { style: styles.header, children: jsx(Text, { style: styles.h1, children: safeGet(seller_business_credentials, 'company_name') }) }), jsx(View, { style: styles.section, children: jsx(Text, { style: styles.h2, children: "CREDIT NOTE" }) }), jsx(View, { style: styles.section, children: jsxs(View, { style: styles.row, children: [jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: styles.h3, children: "BILLING DETAILS" }), jsx(Text, { children: safeGet(buyer_business_credentials, 'company_name') }), jsxs(Text, { children: [safeGet(invoice, 'buyer_first_name'), " ", safeGet(invoice, 'buyer_last_name')] }), jsxs(Text, { children: [safeGet(buyer_company_address, 'street'), " ", safeGet(buyer_company_address, 'street_number'), " ", safeGet(buyer_company_address, 'street_number_addition')] }), jsxs(Text, { children: [safeGet(buyer_company_address, 'postal_code'), " ", safeGet(buyer_company_address, 'city')] })] }), jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: styles.h3, children: "FROM" }), jsx(Text, { children: safeGet(seller_business_credentials, 'company_name') }), jsxs(Text, { children: [safeGet(seller_company_address, 'street'), " ", safeGet(seller_company_address, 'street_number'), " ", safeGet(seller_company_address, 'street_number_addition')] }), jsxs(Text, { children: [safeGet(seller_company_address, 'postal_code'), " ", safeGet(seller_company_address, 'city')] }), jsx(Text, { style: { fontWeight: "bold", marginTop: 10 }, children: "CoC Number" }), jsx(Text, { children: safeGet(seller_business_credentials, 'coc_number') }), jsx(Text, { style: { fontWeight: "bold", marginTop: 10 }, children: "VAT Number" }), jsx(Text, { children: safeGet(seller_business_credentials, 'vat_number') })] })] }) }), jsx(View, { style: styles.section, children: jsxs(View, { style: styles.row, children: [jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Invoice number: " }), jsx(Text, { children: safeGet(invoice, 'invoice_number') })] }), safeGet(invoice, 'customer_reference') && (jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Your reference: " }), jsx(Text, { children: safeGet(invoice, 'customer_reference') })] })), jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Invoice date" }), jsx(Text, { children: safeGet(invoice, 'invoice_date') })] })] }) }), jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.h3, children: "SUMMARY" }), jsxs(View, { style: styles.row, children: [invoice?.admin_items && Array.isArray(invoice.admin_items) && invoice.admin_items.length > 0 && (jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Line Item Number" }) })), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Title" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Amount" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "VAT rate" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Excl. VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Incl. VAT" }) })] }), invoice?.items && Array.isArray(invoice.items) && invoice.items.map((item, index) => (jsx(Fragment$1, { children: jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [item && "product_title" in item ? item.product_title : '', item && "item_description" in item ? item.item_description : ''] }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'quantity') }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [safeGet(item, 'vat_rate'), " %"] }) }), jsx(View, { style: styles.productRowSection, children: item?.price_excl_vat && item?.price_incl_vat && (jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC", " ", (item.price_incl_vat - item.price_excl_vat)?.toFixed(2)] })) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price_excl_vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price_incl_vat', 0)?.toFixed(2)] }) })] }) }, `credit-item-${index}`))), invoice?.admin_items && Array.isArray(invoice.admin_items) && invoice.admin_items.map((item, index) => (jsx(Fragment$1, { children: jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'line_item_number') }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'description') }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'quantity') }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [safeGet(item, 'price.vat_rate'), " %"] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.price', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.price_incl_vat', 0)?.toFixed(2)] }) })] }) }, `credit-admin-item-${index}`)))] }), jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.h3, children: "TOTALS" }), jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "Excl. VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "Incl. VAT" }) })] }), jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'VAT_total', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'total_excl_vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'total_incl_vat', 0)?.toFixed(2)] }) })] })] }), jsx(View, { style: styles.section, children: jsxs(Text, { style: { ...styles.h3, border: "2px solid black", padding: 10 }, children: ["Total: \u20AC ", safeGet(invoice, 'total_incl_vat', 0)?.toFixed(2)] }) })] }) }));
|
|
95
108
|
if (type === "credit") {
|
|
96
109
|
return renderCreditNote();
|
|
97
110
|
}
|
|
98
111
|
if (type === "proforma") {
|
|
99
|
-
return (jsx(Document, { title: `proforma_${invoice
|
|
112
|
+
return (jsx(Document, { title: `proforma_${safeGet(invoice, 'invoice_number', 'unknown')}`, children: jsxs(Page, { size: "A4", style: styles.page, children: [jsx(View, { style: styles.header, children: jsx(Text, { style: styles.h1, children: safeGet(seller_business_credentials, 'company_name') }) }), jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.h2, children: "PROFORMA INVOICE" }), jsx(Text, { style: { fontSize: 10, marginTop: 5 }, children: "This is not a final invoice and cannot be used for tax purposes" })] }), jsx(View, { style: styles.section, children: jsxs(View, { style: styles.row, children: [jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: styles.h3, children: "BILLING DETAILS" }), jsx(Text, { children: safeGet(buyer_business_credentials, 'company_name') }), jsxs(Text, { children: [safeGet(invoice, 'buyer_first_name'), " ", safeGet(invoice, 'buyer_last_name')] }), jsxs(Text, { children: [safeGet(buyer_company_address, 'street'), " ", safeGet(buyer_company_address, 'street_number'), " ", safeGet(buyer_company_address, 'street_number_addition')] }), jsxs(Text, { children: [safeGet(buyer_company_address, 'postal_code'), " ", safeGet(buyer_company_address, 'city')] })] }), jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: styles.h3, children: "FROM" }), jsx(Text, { children: safeGet(seller_business_credentials, 'company_name') }), jsxs(Text, { children: [safeGet(seller_company_address, 'street'), " ", safeGet(seller_company_address, 'street_number'), " ", safeGet(seller_company_address, 'street_number_addition')] }), jsxs(Text, { children: [safeGet(seller_company_address, 'postal_code'), " ", safeGet(seller_company_address, 'city')] }), jsx(Text, { style: { fontWeight: "bold", marginTop: 10 }, children: "CoC Number" }), jsx(Text, { children: safeGet(seller_business_credentials, 'coc_number') }), jsx(Text, { style: { fontWeight: "bold", marginTop: 10 }, children: "VAT Number" }), jsx(Text, { children: safeGet(seller_business_credentials, 'vat_number') })] })] }) }), jsx(View, { style: styles.section, children: jsxs(View, { style: styles.row, children: [jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Invoice number: " }), jsx(Text, { children: safeGet(invoice, 'invoice_number') })] }), safeGet(invoice, 'customer_reference') && (jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Your reference: " }), jsx(Text, { children: safeGet(invoice, 'customer_reference') })] })), jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Invoice date" }), jsx(Text, { children: safeGet(invoice, 'invoice_date') })] })] }) }), jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.h3, children: "SUMMARY" }), jsxs(View, { style: styles.row, children: [invoice?.admin_items && Array.isArray(invoice.admin_items) && invoice.admin_items.length > 0 && (jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Line Item Number" }) })), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Title" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Amount" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "VAT rate" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Excl. VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Incl. VAT" }) })] }), invoice?.items && Array.isArray(invoice.items) && invoice.items.map((item, index) => (jsx(Fragment$1, { children: jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [item && "product_title" in item ? item.product_title : '', item && "item_description" in item ? item.item_description : ''] }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'quantity') }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [safeGet(item, 'vat_rate'), " %"] }) }), jsx(View, { style: styles.productRowSection, children: item?.price_excl_vat && item?.price_incl_vat && (jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC", " ", (item.price_incl_vat - item.price_excl_vat)?.toFixed(2)] })) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price_excl_vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price_incl_vat', 0)?.toFixed(2)] }) })] }) }, `proforma-item-${index}`))), invoice?.admin_items && Array.isArray(invoice.admin_items) && invoice.admin_items.map((item, index) => (jsx(Fragment$1, { children: jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'line_item_number') }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'description') }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'quantity') }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [safeGet(item, 'price.vat_rate'), " %"] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.price', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.price_incl_vat', 0)?.toFixed(2)] }) })] }) }, `proforma-admin-item-${index}`)))] }), jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.h3, children: "TOTALS" }), jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "Excl. VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "Incl. VAT" }) })] }), jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'VAT_total', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'total_excl_vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'total_incl_vat', 0)?.toFixed(2)] }) })] })] }), jsx(View, { style: styles.section, children: jsxs(Text, { style: { ...styles.h3, border: "2px solid black", padding: 10 }, children: ["Total Due: \u20AC ", safeGet(invoice, 'total_incl_vat', 0)?.toFixed(2)] }) })] }) }));
|
|
100
113
|
}
|
|
101
114
|
// Default invoice
|
|
102
|
-
return (jsx(Document, { title: `invoice_${invoice
|
|
115
|
+
return (jsx(Document, { title: `invoice_${safeGet(invoice, 'invoice_number', 'unknown')}`, children: jsxs(Page, { size: "A4", style: styles.page, children: [jsx(View, { style: styles.header, children: jsx(Text, { style: styles.h1, children: safeGet(seller_business_credentials, 'company_name') }) }), jsx(View, { style: styles.section, children: jsx(Text, { style: styles.h2, children: "INVOICE" }) }), jsx(View, { style: styles.section, children: jsxs(View, { style: styles.row, children: [jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: styles.h3, children: "BILLING DETAILS" }), jsx(Text, { children: safeGet(buyer_business_credentials, 'company_name') }), jsxs(Text, { children: [safeGet(invoice, 'buyer_first_name'), " ", safeGet(invoice, 'buyer_last_name')] }), jsxs(Text, { children: [safeGet(buyer_company_address, 'street'), " ", safeGet(buyer_company_address, 'street_number'), " ", safeGet(buyer_company_address, 'street_number_addition')] }), jsxs(Text, { children: [safeGet(buyer_company_address, 'postal_code'), " ", safeGet(buyer_company_address, 'city')] })] }), jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: styles.h3, children: "FROM" }), jsx(Text, { children: safeGet(seller_business_credentials, 'company_name') }), jsxs(Text, { children: [safeGet(seller_company_address, 'street'), " ", safeGet(seller_company_address, 'street_number'), " ", safeGet(seller_company_address, 'street_number_addition')] }), jsxs(Text, { children: [safeGet(seller_company_address, 'postal_code'), " ", safeGet(seller_company_address, 'city')] }), jsx(Text, { style: { fontWeight: "bold", marginTop: 10 }, children: "CoC Number" }), jsx(Text, { children: safeGet(seller_business_credentials, 'coc_number') }), jsx(Text, { style: { fontWeight: "bold", marginTop: 10 }, children: "VAT Number" }), jsx(Text, { children: safeGet(seller_business_credentials, 'vat_number') })] })] }) }), jsx(View, { style: styles.section, children: jsxs(View, { style: styles.row, children: [jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Invoice number: " }), jsx(Text, { children: safeGet(invoice, 'invoice_number') })] }), safeGet(invoice, 'customer_reference') && (jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Your reference: " }), jsx(Text, { children: safeGet(invoice, 'customer_reference') })] })), jsxs(View, { style: styles.rowSection, children: [jsx(Text, { style: { fontWeight: "bold" }, children: "Invoice date" }), jsx(Text, { children: safeGet(invoice, 'invoice_date') })] })] }) }), jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.h3, children: "SUMMARY" }), jsxs(View, { style: styles.row, children: [invoice?.admin_items && Array.isArray(invoice.admin_items) && invoice.admin_items.length > 0 && (jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Line Item Number" }) })), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Title" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Amount" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "VAT rate" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Excl. VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px", fontWeight: "bold" }, children: "Incl. VAT" }) })] }), invoice?.items && Array.isArray(invoice.items) && invoice.items.map((item, index) => (jsx(Fragment$1, { children: jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [item && "product_title" in item ? item.product_title : '', item && "item_description" in item ? item.item_description : ''] }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'quantity') }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [safeGet(item, 'vat_rate'), " %"] }) }), jsx(View, { style: styles.productRowSection, children: item?.price_excl_vat && item?.price_incl_vat && (jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC", " ", (item.price_incl_vat - item.price_excl_vat)?.toFixed(2)] })) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price_excl_vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price_incl_vat', 0)?.toFixed(2)] }) })] }) }, `invoice-item-${index}`))), invoice?.admin_items && Array.isArray(invoice.admin_items) && invoice.admin_items.map((item, index) => (jsx(Fragment$1, { children: jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'line_item_number') }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'description') }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontSize: "10px" }, children: safeGet(item, 'quantity') }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: [safeGet(item, 'price.vat_rate'), " %"] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.price', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { style: { fontSize: "10px" }, children: ["\u20AC ", safeGet(item, 'price.price_incl_vat', 0)?.toFixed(2)] }) })] }) }, `invoice-admin-item-${index}`)))] }), jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.h3, children: "TOTALS" }), jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "Excl. VAT" }) }), jsx(View, { style: styles.productRowSection, children: jsx(Text, { style: { fontWeight: "bold" }, children: "Incl. VAT" }) })] }), jsxs(View, { style: styles.row, children: [jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'VAT_total', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'total_excl_vat', 0)?.toFixed(2)] }) }), jsx(View, { style: styles.productRowSection, children: jsxs(Text, { children: ["\u20AC ", safeGet(invoice, 'total_incl_vat', 0)?.toFixed(2)] }) })] })] }), jsx(View, { style: styles.section, children: jsxs(Text, { style: { ...styles.h3, border: "2px solid black", padding: 10 }, children: ["Total Due: \u20AC ", safeGet(invoice, 'total_incl_vat', 0)?.toFixed(2)] }) })] }) }));
|
|
103
116
|
};
|
|
104
117
|
function InvoiceDownloadLink({ invoice }) {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
const initializePDF = async () => {
|
|
108
|
-
const renderer = await loadPDFRenderer();
|
|
109
|
-
setPdfComponents(renderer);
|
|
110
|
-
};
|
|
111
|
-
initializePDF();
|
|
112
|
-
}, []);
|
|
113
|
-
if (!pdfComponents) {
|
|
118
|
+
const { pdfComponents, loading, error } = usePDFRenderer();
|
|
119
|
+
if (loading || error || !pdfComponents || !invoice) {
|
|
114
120
|
return (jsx(IconButton, { disabled: true, children: jsx(CircularProgress, { size: 20 }) }));
|
|
115
121
|
}
|
|
116
122
|
const { PDFDownloadLink } = pdfComponents;
|
|
117
|
-
|
|
123
|
+
// Add error boundary for PDF generation
|
|
124
|
+
try {
|
|
125
|
+
return (jsx(PDFDownloadLink, { document: jsx(InvoicePDF, { props: { invoice: invoice } }), fileName: `invoice_${safeGet(invoice, 'invoice_number', 'unknown')}`, children: jsx(IconButton, { children: jsx(PictureAsPdfIcon, {}) }) }));
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
console.error('Error creating PDF download link:', err);
|
|
129
|
+
return (jsx(IconButton, { disabled: true, children: jsx(PictureAsPdfIcon, {}) }));
|
|
130
|
+
}
|
|
118
131
|
}
|
|
119
132
|
function InvoicePDFViewer({ invoice }) {
|
|
120
133
|
const [open, setOpen] = useState(false);
|
|
121
|
-
const [
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const renderer = await loadPDFRenderer();
|
|
125
|
-
setPdfComponents(renderer);
|
|
126
|
-
};
|
|
127
|
-
initializePDF();
|
|
128
|
-
}, []);
|
|
129
|
-
if (!pdfComponents) {
|
|
134
|
+
const [pdfError, setPdfError] = useState(null);
|
|
135
|
+
const { pdfComponents, loading, error } = usePDFRenderer();
|
|
136
|
+
if (loading || error || !pdfComponents || !invoice) {
|
|
130
137
|
return (jsx(IconButton, { disabled: true, children: jsx(CircularProgress, { size: 20 }) }));
|
|
131
138
|
}
|
|
132
139
|
const { PDFViewer } = pdfComponents;
|
|
133
|
-
|
|
140
|
+
const handleOpenPDF = () => {
|
|
141
|
+
setPdfError(null);
|
|
142
|
+
setOpen(true);
|
|
143
|
+
};
|
|
144
|
+
return (jsxs(Fragment, { children: [jsx(IconButton, { onClick: handleOpenPDF, children: jsx(PictureAsPdfIcon, {}) }), jsxs(Dialog, { open: open, fullWidth: true, maxWidth: "lg", children: [jsx(DialogContent, { children: pdfError ? (jsxs("div", { children: ["Error rendering PDF: ", pdfError] })) : (jsx(PDFViewer, { style: {
|
|
134
145
|
width: "100%",
|
|
135
146
|
minHeight: "70vh",
|
|
136
|
-
}, children: jsx(InvoicePDF, { props: { invoice: invoice } }) }) }), jsx(DialogActions, { children: jsx(Button, { variant: "contained", onClick: () => setOpen(false), children: "Close" }) })] })] }));
|
|
147
|
+
}, children: jsx(InvoicePDF, { props: { invoice: invoice } }) })) }), jsx(DialogActions, { children: jsx(Button, { variant: "contained", onClick: () => setOpen(false), children: "Close" }) })] })] }));
|
|
137
148
|
}
|
|
138
149
|
|
|
139
150
|
export { InvoiceDownloadLink, InvoicePDFViewer, InvoicePDF as default };
|