ztechno_core 0.0.114 → 0.0.116
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.
|
@@ -8,6 +8,7 @@ export declare class InvoicesOrm extends ZOrm {
|
|
|
8
8
|
affectedRows: number;
|
|
9
9
|
}>;
|
|
10
10
|
findById(id: number): Promise<ZInvoice>;
|
|
11
|
+
updateInvoiceNumber(id: number, invoice_number: string): Promise<void>;
|
|
11
12
|
findByInvoiceNumber(invoice_number: string): Promise<ZInvoice>;
|
|
12
13
|
findByPayTokenHash(pay_token_hash: string): Promise<ZInvoice>;
|
|
13
14
|
findAll(): Promise<ZInvoice[]>;
|
|
@@ -46,6 +46,14 @@ class InvoicesOrm extends orm_1.ZOrm {
|
|
|
46
46
|
});
|
|
47
47
|
return res[0];
|
|
48
48
|
}
|
|
49
|
+
async updateInvoiceNumber(id, invoice_number) {
|
|
50
|
+
await this.sqlService.query(
|
|
51
|
+
/*SQL*/ `
|
|
52
|
+
UPDATE \`${this.alias}\` SET invoice_number=:invoice_number, updated_at=NOW() WHERE id=:id
|
|
53
|
+
`,
|
|
54
|
+
{ id, invoice_number },
|
|
55
|
+
);
|
|
56
|
+
}
|
|
49
57
|
async findByInvoiceNumber(invoice_number) {
|
|
50
58
|
const res = await this.sqlService.exec({
|
|
51
59
|
query: `SELECT * FROM \`${this.alias}\` WHERE invoice_number=:invoice_number LIMIT 1`,
|
|
@@ -22,6 +22,8 @@ export declare class InvoiceService {
|
|
|
22
22
|
private payTokenSecret;
|
|
23
23
|
private payTokenLifetimeMs;
|
|
24
24
|
private mailService;
|
|
25
|
+
private invoiceNumberMode;
|
|
26
|
+
private invoiceNumberFormat;
|
|
25
27
|
private get config();
|
|
26
28
|
private get baseUrl();
|
|
27
29
|
constructor(opt: {
|
|
@@ -31,6 +33,8 @@ export declare class InvoiceService {
|
|
|
31
33
|
mailService: ZMailService;
|
|
32
34
|
siteConfig: Omit<RenderData, 'context'>;
|
|
33
35
|
payTokenSecret: string;
|
|
36
|
+
invoiceNumberMode?: 'sequence' | 'id';
|
|
37
|
+
invoiceNumberFormat?: (id: number) => string;
|
|
34
38
|
});
|
|
35
39
|
autoInit(): Promise<void>;
|
|
36
40
|
private ensurePayTokenSchema;
|
|
@@ -34,6 +34,8 @@ class InvoiceService {
|
|
|
34
34
|
this.subscriptionsOrm = new subscriptions_orm_1.SubscriptionsOrm({ sqlService: opt.sqlService });
|
|
35
35
|
this.subscriptionItemsOrm = new subscription_items_orm_1.SubscriptionItemsOrm({ sqlService: opt.sqlService });
|
|
36
36
|
this.mailService = opt.mailService;
|
|
37
|
+
this.invoiceNumberMode = opt.invoiceNumberMode ?? 'sequence';
|
|
38
|
+
this.invoiceNumberFormat = opt.invoiceNumberFormat ?? ((id) => `INV-${id.toString().padStart(6, '0')}`);
|
|
37
39
|
}
|
|
38
40
|
async autoInit() {
|
|
39
41
|
await this.invoicesOrm.ensureTableExists();
|
|
@@ -407,7 +409,8 @@ class InvoiceService {
|
|
|
407
409
|
throw new Error(`Customer ${customer.id} missing mollie_customer_id`);
|
|
408
410
|
}
|
|
409
411
|
const { items, amount_due } = this.calcTotals(input.items);
|
|
410
|
-
const
|
|
412
|
+
const useIdMode = this.invoiceNumberMode === 'id';
|
|
413
|
+
const invoice_number = useIdMode ? `PENDING-${crypto_1.default.randomUUID()}` : await this.generateInvoiceNumber();
|
|
411
414
|
const status = overrides?.status ?? 'pending';
|
|
412
415
|
const issuedAt = (0, orm_1.formatDatetime)(new Date());
|
|
413
416
|
const paidAt = overrides?.paid_at ?? (status === 'paid' ? issuedAt : null);
|
|
@@ -435,8 +438,17 @@ class InvoiceService {
|
|
|
435
438
|
checkout_url: overrides?.checkout_url ?? null,
|
|
436
439
|
metadata: input.metadata ?? null,
|
|
437
440
|
};
|
|
438
|
-
await this.invoicesOrm.create(invoicePayload);
|
|
439
|
-
|
|
441
|
+
const createResult = await this.invoicesOrm.create(invoicePayload);
|
|
442
|
+
let savedInvoice;
|
|
443
|
+
if (useIdMode) {
|
|
444
|
+
const insertId = createResult.insertId;
|
|
445
|
+
if (!insertId) throw new Error('Failed to get insertId for id-based invoice numbering');
|
|
446
|
+
const finalNumber = this.invoiceNumberFormat(insertId);
|
|
447
|
+
await this.invoicesOrm.updateInvoiceNumber(insertId, finalNumber);
|
|
448
|
+
savedInvoice = await this.invoicesOrm.findById(insertId);
|
|
449
|
+
} else {
|
|
450
|
+
savedInvoice = await this.invoicesOrm.findByInvoiceNumber(invoice_number);
|
|
451
|
+
}
|
|
440
452
|
if (!savedInvoice) {
|
|
441
453
|
throw new Error('Failed to persist invoice');
|
|
442
454
|
}
|
|
@@ -805,18 +817,18 @@ class InvoiceService {
|
|
|
805
817
|
const footerStartY = P.y + 10;
|
|
806
818
|
// LEFT COLUMN: Description + Payment terms
|
|
807
819
|
P.y = footerStartY;
|
|
808
|
-
if (invoice.
|
|
820
|
+
if (invoice.payment_terms) {
|
|
809
821
|
P.size(10).bold();
|
|
810
|
-
P.text('
|
|
822
|
+
P.text('Betalingsvoorwaarden:', 50, { width: 260 }, 12);
|
|
811
823
|
P.normal();
|
|
812
|
-
P.text(invoice.
|
|
813
|
-
P.skip(4);
|
|
824
|
+
P.text(invoice.payment_terms, 50, { width: 260 }, 12);
|
|
814
825
|
}
|
|
815
|
-
if (invoice.
|
|
826
|
+
if (invoice.description) {
|
|
816
827
|
P.size(10).bold();
|
|
817
|
-
P.text('
|
|
828
|
+
P.text('Omschrijving:', 50, { width: 260 }, 12);
|
|
818
829
|
P.normal();
|
|
819
|
-
P.text(invoice.
|
|
830
|
+
P.text(invoice.description, 50, { width: 260 }, 12);
|
|
831
|
+
P.skip(4);
|
|
820
832
|
}
|
|
821
833
|
const leftColEndY = P.y;
|
|
822
834
|
// RIGHT COLUMN: Bank details
|