payload-clienthub 0.0.1

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.
Files changed (50) hide show
  1. package/README.md +90 -0
  2. package/dist/components/invoice-pdf.d.ts +60 -0
  3. package/dist/components/invoice-pdf.d.ts.map +1 -0
  4. package/dist/components/invoice-pdf.js +254 -0
  5. package/dist/components/invoice-pdf.js.map +1 -0
  6. package/dist/components/swiss-qr-bill.d.ts +74 -0
  7. package/dist/components/swiss-qr-bill.d.ts.map +1 -0
  8. package/dist/components/swiss-qr-bill.js +326 -0
  9. package/dist/components/swiss-qr-bill.js.map +1 -0
  10. package/dist/const.d.ts +12 -0
  11. package/dist/const.d.ts.map +1 -0
  12. package/dist/const.js +12 -0
  13. package/dist/const.js.map +1 -0
  14. package/dist/endpoints/process-all-clients.d.ts +4 -0
  15. package/dist/endpoints/process-all-clients.d.ts.map +1 -0
  16. package/dist/endpoints/process-all-clients.js +55 -0
  17. package/dist/endpoints/process-all-clients.js.map +1 -0
  18. package/dist/entities.d.ts +16 -0
  19. package/dist/entities.d.ts.map +1 -0
  20. package/dist/entities.js +425 -0
  21. package/dist/entities.js.map +1 -0
  22. package/dist/exports/client.d.ts +2 -0
  23. package/dist/exports/client.d.ts.map +1 -0
  24. package/dist/exports/client.js +2 -0
  25. package/dist/exports/client.js.map +1 -0
  26. package/dist/exports/rsc.d.ts +2 -0
  27. package/dist/exports/rsc.d.ts.map +1 -0
  28. package/dist/exports/rsc.js +2 -0
  29. package/dist/exports/rsc.js.map +1 -0
  30. package/dist/index.d.ts +14 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +38 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/payload-types.d.ts +459 -0
  35. package/dist/payload-types.d.ts.map +1 -0
  36. package/dist/translations.d.ts +183 -0
  37. package/dist/translations.d.ts.map +1 -0
  38. package/dist/translations.js +242 -0
  39. package/dist/translations.js.map +1 -0
  40. package/dist/types.d.ts +3 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/utils/authentication.d.ts +3 -0
  43. package/dist/utils/authentication.d.ts.map +1 -0
  44. package/dist/utils/authentication.js +5 -0
  45. package/dist/utils/authentication.js.map +1 -0
  46. package/dist/utils/process-client-invoice.d.ts +13 -0
  47. package/dist/utils/process-client-invoice.d.ts.map +1 -0
  48. package/dist/utils/process-client-invoice.js +193 -0
  49. package/dist/utils/process-client-invoice.js.map +1 -0
  50. package/package.json +84 -0
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # payload-clienthub
2
+
3
+ Automatic monthly invoicing with PDF generation, Swiss QR Bill support, and multi-language email delivery for Payload CMS.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/payload-clienthub)](https://www.npmjs.com/package/payload-clienthub)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+
8
+ ## Overview
9
+
10
+ payload-clienthub adds a full invoicing workflow to Payload -- clients, services, and invoices are managed as collections. Recurring services are automatically detected when due, rendered as localized PDF invoices (with Swiss QR Bill support), and emailed to each client. A single endpoint processes all clients at once, so you can wire it up to a scheduler and forget about it.
11
+
12
+ **Features**
13
+
14
+ - **Client & service management** -- track clients, contacts, and one-time/monthly/yearly services.
15
+ - **PDF invoices** -- generated with itemized line items, company branding, and Swiss QR Bill payment slips for CH-based companies.
16
+ - **Multi-language** -- invoices and emails are localized in DE, FR, IT, and EN.
17
+ - **Batch endpoint** -- one endpoint processes all clients at once; authenticate with a shared secret to call it from any scheduler.
18
+
19
+ ## Installation
20
+
21
+ ```sh
22
+ pnpm add payload-clienthub
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```ts
28
+ // payload.config.ts
29
+ import { buildConfig } from 'payload';
30
+ import { clienthubPlugin } from 'payload-clienthub';
31
+
32
+ export default buildConfig({
33
+ // ...
34
+ plugins: [
35
+ clienthubPlugin({
36
+ cronSecret: process.env.CRON_SECRET!,
37
+ }),
38
+ ],
39
+ });
40
+ ```
41
+
42
+ Trigger invoice generation for all clients by calling the batch endpoint (e.g. from a monthly scheduler):
43
+
44
+ ```sh
45
+ curl -H "Authorization: Bearer $CRON_SECRET" \
46
+ https://your-app.com/api/plugin-invoices/process-all-clients
47
+ ```
48
+
49
+ ### Options
50
+
51
+ | Option | Type | Default | Description |
52
+ |--------|------|---------|-------------|
53
+ | `cronSecret` | `string` | — | Required. Shared secret used to authenticate batch requests via the `Authorization: Bearer` header. |
54
+ | `clientsCollectionSlug` | `CollectionSlug` | `'clients'` | Slug for the auto-created clients collection. |
55
+ | `servicesCollectionSlug` | `CollectionSlug` | `'services'` | Slug for the auto-created services collection. |
56
+ | `invoicesCollectionSlug` | `CollectionSlug` | `'invoices'` | Slug for the auto-created invoices collection. |
57
+ | `invoicePdfsCollectionSlug` | `CollectionSlug` | `'invoice-pdfs'` | Slug for the auto-created invoice PDFs upload collection. |
58
+ | `onError` | `(error: Error, context: { operation: string; metadata?: Record<string, unknown> }) => void` | `console.error` | Custom error handler called when PDF generation or email delivery fails. |
59
+
60
+ ## Contributing
61
+
62
+ This plugin lives in the [payload-plugins](https://github.com/davincicoding-org/payload-plugins) monorepo.
63
+
64
+ ### Development
65
+
66
+ ```sh
67
+ pnpm install
68
+
69
+ # watch this plugin for changes
70
+ pnpm --filter payload-clienthub dev
71
+
72
+ # run the Payload dev app (in a second terminal)
73
+ pnpm --filter sandbox dev
74
+ ```
75
+
76
+ The `sandbox/` directory is a Next.js + Payload app that imports plugins via `workspace:*` — use it to test changes locally.
77
+
78
+ ### Code quality
79
+
80
+ - **Formatting & linting** — handled by [Biome](https://biomejs.dev/), enforced on commit via husky + lint-staged.
81
+ - **Commits** — must follow [Conventional Commits](https://www.conventionalcommits.org/) with a valid scope (e.g. `fix(payload-clienthub): ...`).
82
+ - **Changesets** — please include a [changeset](https://github.com/changesets/changesets) in your PR by running `pnpm release`.
83
+
84
+ ### Issues & PRs
85
+
86
+ Bug reports and feature requests are welcome — [open an issue](https://github.com/davincicoding-org/payload-plugins/issues).
87
+
88
+ ## License
89
+
90
+ MIT
@@ -0,0 +1,60 @@
1
+ import { SwissQRBillLabels } from './swiss-qr-bill';
2
+ export interface InvoicePdfData {
3
+ invoiceNumber: string;
4
+ date: string;
5
+ paymentTerms: string;
6
+ client: {
7
+ name: string;
8
+ address: string;
9
+ zip: string;
10
+ city: string;
11
+ country: string;
12
+ };
13
+ company: {
14
+ name: string;
15
+ address: string;
16
+ zip: string;
17
+ city: string;
18
+ country: string;
19
+ website: string;
20
+ uid: string;
21
+ contact: {
22
+ name: string;
23
+ email: string;
24
+ phone: string;
25
+ };
26
+ bank: {
27
+ name: string;
28
+ iban: string;
29
+ bic: string;
30
+ };
31
+ logo: string | undefined | null;
32
+ };
33
+ items: Array<{
34
+ description: string;
35
+ cost: number;
36
+ }>;
37
+ total: number;
38
+ /** Reference number for QR Bill (optional) */
39
+ reference?: string;
40
+ /** Message for QR Bill (optional) */
41
+ message?: string;
42
+ /** Pre-translated labels */
43
+ labels: {
44
+ title: string;
45
+ invoiceNumber: string;
46
+ date: string;
47
+ paymentTerms: string;
48
+ greeting: string;
49
+ greetingBody: string;
50
+ tableService: string;
51
+ tableCost: string;
52
+ tableTotal: string;
53
+ footerCreditor: string;
54
+ footerContact: string;
55
+ footerBank: string;
56
+ qrBill: SwissQRBillLabels;
57
+ };
58
+ }
59
+ export declare function generateInvoicePdf(data: InvoicePdfData): Promise<Buffer>;
60
+ //# sourceMappingURL=invoice-pdf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice-pdf.d.ts","sourceRoot":"","sources":["../../src/components/invoice-pdf.tsx"],"names":[],"mappings":"AAWA,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QACF,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;QACF,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;KACjC,CAAC;IACF,KAAK,EAAE,KAAK,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,iBAAiB,CAAC;KAC3B,CAAC;CACH;AAyHD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,CAAC,CA4CjB"}
@@ -0,0 +1,254 @@
1
+ import { jsx as t, jsxs as l } from "react/jsx-runtime";
2
+ import { StyleSheet as w, renderToBuffer as B, Document as C, Page as T, View as n, Image as x, Text as o, Link as f } from "@react-pdf/renderer";
3
+ import { createElement as D } from "react";
4
+ import { prepareSwissQRBill as R, SwissQRBill as S } from "./swiss-qr-bill.js";
5
+ const g = new Intl.NumberFormat("de-CH", {
6
+ style: "currency",
7
+ currency: "CHF"
8
+ });
9
+ function q({ data: r }) {
10
+ const {
11
+ invoiceNumber: d,
12
+ date: s,
13
+ paymentTerms: m,
14
+ client: a,
15
+ company: i,
16
+ items: b,
17
+ total: u,
18
+ qrBill: h,
19
+ labels: c
20
+ } = r;
21
+ return /* @__PURE__ */ t(C, { title: `${c.title} ${d}`, children: /* @__PURE__ */ l(T, { size: "A4", style: e.page, children: [
22
+ /* @__PURE__ */ l(n, { style: e.header, children: [
23
+ /* @__PURE__ */ l(n, { style: e.headerLeft, children: [
24
+ i.logo ? /* @__PURE__ */ t(x, { src: i.logo, style: e.logo }) : null,
25
+ /* @__PURE__ */ t(o, { style: e.title, children: c.title })
26
+ ] }),
27
+ /* @__PURE__ */ l(n, { style: e.headerRight, children: [
28
+ /* @__PURE__ */ l(o, { style: e.headerRow, children: [
29
+ c.invoiceNumber,
30
+ ": ",
31
+ d
32
+ ] }),
33
+ /* @__PURE__ */ l(o, { style: e.headerRow, children: [
34
+ c.date,
35
+ ": ",
36
+ s
37
+ ] }),
38
+ /* @__PURE__ */ l(o, { style: e.headerRow, children: [
39
+ c.paymentTerms,
40
+ ": ",
41
+ m
42
+ ] })
43
+ ] })
44
+ ] }),
45
+ /* @__PURE__ */ l(n, { style: e.clientSection, children: [
46
+ /* @__PURE__ */ t(o, { style: e.clientName, children: a.name }),
47
+ /* @__PURE__ */ t(o, { children: a.address }),
48
+ /* @__PURE__ */ l(o, { children: [
49
+ a.zip,
50
+ " ",
51
+ a.city
52
+ ] })
53
+ ] }),
54
+ /* @__PURE__ */ l(n, { style: e.table, children: [
55
+ /* @__PURE__ */ l(n, { style: e.tableHeader, children: [
56
+ /* @__PURE__ */ t(o, { style: e.col1, children: "#" }),
57
+ /* @__PURE__ */ t(o, { style: e.col2, children: c.tableService }),
58
+ /* @__PURE__ */ t(o, { style: e.col3, children: c.tableCost })
59
+ ] }),
60
+ b.map((y, p) => /* @__PURE__ */ l(n, { style: e.tableRow, children: [
61
+ /* @__PURE__ */ t(o, { style: e.col1, children: p + 1 }),
62
+ /* @__PURE__ */ t(o, { style: e.col2, children: y.description }),
63
+ /* @__PURE__ */ t(o, { style: e.col3, children: g.format(y.cost) })
64
+ ] }, `${y.description}-${p}`)),
65
+ /* @__PURE__ */ l(n, { style: e.totalRow, children: [
66
+ /* @__PURE__ */ t(o, { style: e.col1 }),
67
+ /* @__PURE__ */ t(o, { style: e.col2, children: c.tableTotal }),
68
+ /* @__PURE__ */ t(o, { style: e.col3, children: g.format(u) })
69
+ ] })
70
+ ] }),
71
+ h ? /* @__PURE__ */ t(n, { style: e.qrBillContainer, children: /* @__PURE__ */ t(
72
+ S,
73
+ {
74
+ data: h.data,
75
+ labels: c.qrBill,
76
+ qrCodeDataUrl: h.qrCodeDataUrl
77
+ }
78
+ ) }) : /* @__PURE__ */ l(n, { style: e.footer, children: [
79
+ /* @__PURE__ */ l(n, { style: e.footerCol, children: [
80
+ /* @__PURE__ */ t(o, { style: e.footerTitle, children: c.footerCreditor }),
81
+ /* @__PURE__ */ t(o, { children: i.name }),
82
+ /* @__PURE__ */ t(o, { children: i.address }),
83
+ /* @__PURE__ */ t(o, { children: i.uid }),
84
+ /* @__PURE__ */ t(f, { href: i.website, children: new URL(i.website).hostname })
85
+ ] }),
86
+ /* @__PURE__ */ l(n, { style: e.footerCol, children: [
87
+ /* @__PURE__ */ t(o, { style: e.footerTitle, children: c.footerContact }),
88
+ /* @__PURE__ */ t(o, { children: i.contact.name }),
89
+ /* @__PURE__ */ t(o, { children: i.contact.phone }),
90
+ /* @__PURE__ */ t(f, { href: `mailto:${i.contact.email}`, children: i.contact.email })
91
+ ] }),
92
+ /* @__PURE__ */ l(n, { style: e.footerCol, children: [
93
+ /* @__PURE__ */ t(o, { style: e.footerTitle, children: c.footerBank }),
94
+ /* @__PURE__ */ t(o, { children: i.bank.iban }),
95
+ /* @__PURE__ */ l(o, { children: [
96
+ i.bank.name,
97
+ " (",
98
+ i.bank.bic,
99
+ ")"
100
+ ] })
101
+ ] })
102
+ ] })
103
+ ] }) });
104
+ }
105
+ async function $(r) {
106
+ let d = { ...r };
107
+ if (r.company.country === "CH") {
108
+ const m = {
109
+ creditor: {
110
+ iban: r.company.bank.iban,
111
+ name: r.company.name,
112
+ address: r.company.address.split(`
113
+ `)[0] ?? r.company.address,
114
+ zip: r.company.zip,
115
+ city: r.company.city,
116
+ country: r.company.country
117
+ },
118
+ amount: r.total,
119
+ currency: "CHF",
120
+ debtor: {
121
+ name: r.client.name,
122
+ address: r.client.address.split(`
123
+ `)[0] ?? r.client.address,
124
+ zip: r.client.zip,
125
+ city: r.client.city,
126
+ country: r.client.country
127
+ },
128
+ reference: r.reference,
129
+ message: r.message ?? `${r.labels.title} ${r.invoiceNumber}`
130
+ }, a = await R(m);
131
+ d = {
132
+ ...r,
133
+ qrBill: {
134
+ data: a.data,
135
+ qrCodeDataUrl: a.qrCodeDataUrl
136
+ }
137
+ };
138
+ }
139
+ const s = D(q, {
140
+ data: d
141
+ });
142
+ return B(
143
+ s
144
+ );
145
+ }
146
+ const e = w.create({
147
+ page: {
148
+ padding: 40,
149
+ fontSize: 10,
150
+ fontFamily: "Helvetica"
151
+ },
152
+ header: {
153
+ flexDirection: "row",
154
+ justifyContent: "space-between",
155
+ alignItems: "flex-start",
156
+ marginBottom: 40
157
+ },
158
+ headerLeft: {
159
+ flexDirection: "column"
160
+ },
161
+ logo: {
162
+ width: 140,
163
+ height: 12,
164
+ objectFit: "contain",
165
+ marginBottom: 8
166
+ },
167
+ title: {
168
+ fontSize: 24,
169
+ fontWeight: "bold",
170
+ marginTop: 4
171
+ },
172
+ headerRight: {
173
+ textAlign: "right"
174
+ },
175
+ headerRow: {
176
+ marginBottom: 4
177
+ },
178
+ clientSection: {
179
+ marginBottom: 24
180
+ },
181
+ clientName: {
182
+ fontSize: 12,
183
+ fontWeight: "bold",
184
+ marginBottom: 8
185
+ },
186
+ greeting: {
187
+ marginBottom: 24
188
+ },
189
+ table: {
190
+ marginTop: 16,
191
+ marginBottom: 24
192
+ },
193
+ tableHeader: {
194
+ flexDirection: "row",
195
+ borderBottomWidth: 1,
196
+ borderBottomColor: "#000",
197
+ paddingBottom: 8,
198
+ marginBottom: 8,
199
+ fontWeight: "bold"
200
+ },
201
+ tableRow: {
202
+ flexDirection: "row",
203
+ paddingVertical: 6,
204
+ borderBottomWidth: 0.5,
205
+ borderBottomColor: "#ccc"
206
+ },
207
+ col1: { width: "8%" },
208
+ col2: { width: "72%" },
209
+ col3: { width: "20%", textAlign: "right" },
210
+ totalRow: {
211
+ flexDirection: "row",
212
+ marginTop: 16,
213
+ paddingTop: 8,
214
+ borderTopWidth: 1,
215
+ borderTopColor: "#000",
216
+ fontWeight: "bold"
217
+ },
218
+ closing: {
219
+ marginTop: 32,
220
+ marginBottom: 16
221
+ },
222
+ footer: {
223
+ position: "absolute",
224
+ bottom: 40,
225
+ left: 40,
226
+ right: 40,
227
+ flexDirection: "row",
228
+ borderTopWidth: 1,
229
+ borderTopColor: "#ccc",
230
+ paddingTop: 16,
231
+ marginTop: 40
232
+ },
233
+ qrBillContainer: {
234
+ marginTop: "auto",
235
+ // Push to bottom if space available
236
+ marginLeft: -40,
237
+ // Compensate for page padding
238
+ marginRight: -40,
239
+ marginBottom: -40
240
+ },
241
+ footerCol: {
242
+ flex: 1
243
+ },
244
+ footerTitle: {
245
+ fontSize: 8,
246
+ textTransform: "uppercase",
247
+ marginBottom: 4,
248
+ color: "#666"
249
+ }
250
+ });
251
+ export {
252
+ $ as generateInvoicePdf
253
+ };
254
+ //# sourceMappingURL=invoice-pdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoice-pdf.js","sources":["../../src/components/invoice-pdf.tsx"],"sourcesContent":["import {\n Document,\n Image,\n Link,\n Page,\n renderToBuffer,\n StyleSheet,\n Text,\n View,\n} from '@react-pdf/renderer';\nimport { createElement } from 'react';\nimport {\n prepareSwissQRBill,\n SwissQRBill,\n type SwissQRBillData,\n type SwissQRBillLabels,\n} from './swiss-qr-bill';\n\nexport interface InvoicePdfData {\n invoiceNumber: string;\n date: string;\n paymentTerms: string;\n client: {\n name: string;\n address: string;\n zip: string;\n city: string;\n country: string;\n };\n company: {\n name: string;\n address: string;\n zip: string;\n city: string;\n country: string;\n website: string;\n uid: string;\n contact: {\n name: string;\n email: string;\n phone: string;\n };\n bank: {\n name: string;\n iban: string;\n bic: string;\n };\n logo: string | undefined | null;\n };\n items: Array<{\n description: string;\n cost: number;\n }>;\n total: number;\n /** Reference number for QR Bill (optional) */\n reference?: string;\n /** Message for QR Bill (optional) */\n message?: string;\n /** Pre-translated labels */\n labels: {\n title: string;\n invoiceNumber: string;\n date: string;\n paymentTerms: string;\n greeting: string;\n greetingBody: string;\n tableService: string;\n tableCost: string;\n tableTotal: string;\n footerCreditor: string;\n footerContact: string;\n footerBank: string;\n qrBill: SwissQRBillLabels;\n };\n}\n\n/** Internal data with pre-generated QR code */\ninterface InvoiceDocumentData extends InvoicePdfData {\n qrBill?: {\n data: SwissQRBillData;\n qrCodeDataUrl: string;\n };\n}\n\nconst currency = new Intl.NumberFormat('de-CH', {\n style: 'currency',\n currency: 'CHF',\n});\n\nfunction InvoiceDocument({ data }: { data: InvoiceDocumentData }) {\n const {\n invoiceNumber,\n date,\n paymentTerms,\n client,\n company,\n items,\n total,\n qrBill,\n labels,\n } = data;\n\n return (\n <Document title={`${labels.title} ${invoiceNumber}`}>\n <Page size=\"A4\" style={styles.page}>\n <View style={styles.header}>\n <View style={styles.headerLeft}>\n {company.logo ? (\n <Image src={company.logo} style={styles.logo} />\n ) : null}\n <Text style={styles.title}>{labels.title}</Text>\n </View>\n <View style={styles.headerRight}>\n <Text style={styles.headerRow}>\n {labels.invoiceNumber}: {invoiceNumber}\n </Text>\n <Text style={styles.headerRow}>\n {labels.date}: {date}\n </Text>\n <Text style={styles.headerRow}>\n {labels.paymentTerms}: {paymentTerms}\n </Text>\n </View>\n </View>\n\n <View style={styles.clientSection}>\n <Text style={styles.clientName}>{client.name}</Text>\n <Text>{client.address}</Text>\n <Text>\n {client.zip} {client.city}\n </Text>\n </View>\n\n <View style={styles.table}>\n <View style={styles.tableHeader}>\n <Text style={styles.col1}>#</Text>\n <Text style={styles.col2}>{labels.tableService}</Text>\n <Text style={styles.col3}>{labels.tableCost}</Text>\n </View>\n {items.map((item, index) => (\n <View key={`${item.description}-${index}`} style={styles.tableRow}>\n <Text style={styles.col1}>{index + 1}</Text>\n <Text style={styles.col2}>{item.description}</Text>\n <Text style={styles.col3}>{currency.format(item.cost)}</Text>\n </View>\n ))}\n <View style={styles.totalRow}>\n <Text style={styles.col1} />\n <Text style={styles.col2}>{labels.tableTotal}</Text>\n <Text style={styles.col3}>{currency.format(total)}</Text>\n </View>\n </View>\n\n {/* Swiss QR Bill or Legacy Footer */}\n {qrBill ? (\n <View style={styles.qrBillContainer}>\n <SwissQRBill\n data={qrBill.data}\n labels={labels.qrBill}\n qrCodeDataUrl={qrBill.qrCodeDataUrl}\n />\n </View>\n ) : (\n <View style={styles.footer}>\n <View style={styles.footerCol}>\n <Text style={styles.footerTitle}>{labels.footerCreditor}</Text>\n <Text>{company.name}</Text>\n <Text>{company.address}</Text>\n <Text>{company.uid}</Text>\n <Link href={company.website}>\n {new URL(company.website).hostname}\n </Link>\n </View>\n <View style={styles.footerCol}>\n <Text style={styles.footerTitle}>{labels.footerContact}</Text>\n <Text>{company.contact.name}</Text>\n <Text>{company.contact.phone}</Text>\n <Link href={`mailto:${company.contact.email}`}>\n {company.contact.email}\n </Link>\n </View>\n <View style={styles.footerCol}>\n <Text style={styles.footerTitle}>{labels.footerBank}</Text>\n <Text>{company.bank.iban}</Text>\n <Text>\n {company.bank.name} ({company.bank.bic})\n </Text>\n </View>\n </View>\n )}\n </Page>\n </Document>\n );\n}\n\nexport async function generateInvoicePdf(\n data: InvoicePdfData,\n): Promise<Buffer> {\n let documentData: InvoiceDocumentData = { ...data };\n\n // Prepare Swiss QR Bill if structured addresses are available and enabled\n if (data.company.country === 'CH') {\n const qrBillData: SwissQRBillData = {\n creditor: {\n iban: data.company.bank.iban,\n name: data.company.name,\n address: data.company.address.split('\\n')[0] ?? data.company.address,\n zip: data.company.zip,\n city: data.company.city,\n country: data.company.country,\n },\n amount: data.total,\n currency: 'CHF',\n debtor: {\n name: data.client.name,\n address: data.client.address.split('\\n')[0] ?? data.client.address,\n zip: data.client.zip,\n city: data.client.city,\n country: data.client.country,\n },\n reference: data.reference,\n message: data.message ?? `${data.labels.title} ${data.invoiceNumber}`,\n };\n\n const prepared = await prepareSwissQRBill(qrBillData);\n\n documentData = {\n ...data,\n qrBill: {\n data: prepared.data,\n qrCodeDataUrl: prepared.qrCodeDataUrl,\n },\n };\n }\n\n const documentElement = createElement(InvoiceDocument, {\n data: documentData,\n });\n return renderToBuffer(\n documentElement as Parameters<typeof renderToBuffer>[0],\n ) as Promise<Buffer>;\n}\n\nconst styles = StyleSheet.create({\n page: {\n padding: 40,\n fontSize: 10,\n fontFamily: 'Helvetica',\n },\n header: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n marginBottom: 40,\n },\n headerLeft: {\n flexDirection: 'column',\n },\n logo: {\n width: 140,\n height: 12,\n objectFit: 'contain',\n marginBottom: 8,\n },\n title: {\n fontSize: 24,\n fontWeight: 'bold',\n marginTop: 4,\n },\n headerRight: {\n textAlign: 'right',\n },\n headerRow: {\n marginBottom: 4,\n },\n clientSection: {\n marginBottom: 24,\n },\n clientName: {\n fontSize: 12,\n fontWeight: 'bold',\n marginBottom: 8,\n },\n greeting: {\n marginBottom: 24,\n },\n table: {\n marginTop: 16,\n marginBottom: 24,\n },\n tableHeader: {\n flexDirection: 'row',\n borderBottomWidth: 1,\n borderBottomColor: '#000',\n paddingBottom: 8,\n marginBottom: 8,\n fontWeight: 'bold',\n },\n tableRow: {\n flexDirection: 'row',\n paddingVertical: 6,\n borderBottomWidth: 0.5,\n borderBottomColor: '#ccc',\n },\n col1: { width: '8%' },\n col2: { width: '72%' },\n col3: { width: '20%', textAlign: 'right' },\n totalRow: {\n flexDirection: 'row',\n marginTop: 16,\n paddingTop: 8,\n borderTopWidth: 1,\n borderTopColor: '#000',\n fontWeight: 'bold',\n },\n closing: {\n marginTop: 32,\n marginBottom: 16,\n },\n footer: {\n position: 'absolute',\n bottom: 40,\n left: 40,\n right: 40,\n flexDirection: 'row',\n borderTopWidth: 1,\n borderTopColor: '#ccc',\n paddingTop: 16,\n marginTop: 40,\n },\n qrBillContainer: {\n marginTop: 'auto', // Push to bottom if space available\n marginLeft: -40, // Compensate for page padding\n marginRight: -40,\n marginBottom: -40,\n },\n footerCol: {\n flex: 1,\n },\n footerTitle: {\n fontSize: 8,\n textTransform: 'uppercase',\n marginBottom: 4,\n color: '#666',\n },\n});\n"],"names":["currency","InvoiceDocument","data","invoiceNumber","date","paymentTerms","client","company","items","total","qrBill","labels","jsx","Document","Page","styles","jsxs","View","Image","Text","item","index","SwissQRBill","Link","generateInvoicePdf","documentData","qrBillData","prepared","prepareSwissQRBill","documentElement","createElement","renderToBuffer","StyleSheet"],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ export interface SwissQRBillData {
2
+ /** Creditor information */
3
+ creditor: {
4
+ /** IBAN or QR-IBAN (21 characters, CH/LI only) */
5
+ iban: string;
6
+ /** Name (max 70 characters) */
7
+ name: string;
8
+ /** Street and building number (max 70 characters) */
9
+ address: string;
10
+ /** Postal code (max 16 characters) */
11
+ zip: string;
12
+ /** City (max 35 characters) */
13
+ city: string;
14
+ /** Country code (2 characters, e.g., "CH") */
15
+ country: string;
16
+ };
17
+ /** Amount (optional, max 12 digits including decimals) */
18
+ amount?: number;
19
+ /** Currency: CHF or EUR */
20
+ currency: 'CHF' | 'EUR';
21
+ /** Debtor information (optional) */
22
+ debtor?: {
23
+ /** Name (max 70 characters) */
24
+ name: string;
25
+ /** Street and building number (max 70 characters) */
26
+ address: string;
27
+ /** Postal code (max 16 characters) */
28
+ zip: string;
29
+ /** City (max 35 characters) */
30
+ city: string;
31
+ /** Country code (2 characters) */
32
+ country: string;
33
+ };
34
+ /** Reference number (QR reference or Creditor Reference, max 27 characters) */
35
+ reference?: string;
36
+ /** Additional information / message (max 140 characters) */
37
+ message?: string;
38
+ }
39
+ /** Pre-translated labels for Swiss QR Bill */
40
+ export interface SwissQRBillLabels {
41
+ paymentPart: string;
42
+ receipt: string;
43
+ account: string;
44
+ reference: string;
45
+ additionalInfo: string;
46
+ payableBy: string;
47
+ payableByBlank: string;
48
+ currency: string;
49
+ amount: string;
50
+ acceptancePoint: string;
51
+ }
52
+ /**
53
+ * Generate Swiss QR Code with Swiss Cross overlay as base64 data URL
54
+ */
55
+ export declare function generateSwissQRCode(data: SwissQRBillData): Promise<string>;
56
+ export interface SwissQRBillProps {
57
+ data: SwissQRBillData;
58
+ qrCodeDataUrl: string;
59
+ labels: SwissQRBillLabels;
60
+ }
61
+ /**
62
+ * Swiss QR Bill component for react-pdf
63
+ * Flexible height - flows with document content
64
+ */
65
+ export declare function SwissQRBill({ data, qrCodeDataUrl, labels }: SwissQRBillProps): import("react/jsx-runtime").JSX.Element;
66
+ /**
67
+ * Helper to prepare Swiss QR Bill data and generate QR code
68
+ * Call this before rendering to get the qrCodeDataUrl
69
+ */
70
+ export declare function prepareSwissQRBill(data: SwissQRBillData): Promise<{
71
+ data: SwissQRBillData;
72
+ qrCodeDataUrl: string;
73
+ }>;
74
+ //# sourceMappingURL=swiss-qr-bill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swiss-qr-bill.d.ts","sourceRoot":"","sources":["../../src/components/swiss-qr-bill.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,QAAQ,EAAE;QACR,kDAAkD;QAClD,IAAI,EAAE,MAAM,CAAC;QACb,+BAA+B;QAC/B,IAAI,EAAE,MAAM,CAAC;QACb,qDAAqD;QACrD,OAAO,EAAE,MAAM,CAAC;QAChB,sCAAsC;QACtC,GAAG,EAAE,MAAM,CAAC;QACZ,+BAA+B;QAC/B,IAAI,EAAE,MAAM,CAAC;QACb,8CAA8C;QAC9C,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,KAAK,GAAG,KAAK,CAAC;IACxB,oCAAoC;IACpC,MAAM,CAAC,EAAE;QACP,+BAA+B;QAC/B,IAAI,EAAE,MAAM,CAAC;QACb,qDAAqD;QACrD,OAAO,EAAE,MAAM,CAAC;QAChB,sCAAsC;QACtC,GAAG,EAAE,MAAM,CAAC;QACZ,+BAA+B;QAC/B,IAAI,EAAE,MAAM,CAAC;QACb,kCAAkC;QAClC,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,8CAA8C;AAC9C,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAgFD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,CAAC,CAejB;AAgMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAkK5E;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAG3D"}