ztechno_core 0.0.132 → 0.0.133
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/lib/mollie/orm/invoice_status_log_orm.js +2 -2
- package/lib/mollie/orm/invoices_orm.d.ts +3 -0
- package/lib/mollie/orm/invoices_orm.js +25 -1
- package/lib/mollie/services/invoice_service.d.ts +2 -1
- package/lib/mollie/services/invoice_service.js +34 -15
- package/lib/mollie/types/mollie_types.d.ts +2 -1
- package/package.json +1 -1
|
@@ -36,8 +36,8 @@ class InvoiceStatusLogOrm extends orm_1.ZOrm {
|
|
|
36
36
|
CREATE TABLE IF NOT EXISTS \`${this.alias}\` (
|
|
37
37
|
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
38
38
|
invoice_id BIGINT UNSIGNED NOT NULL,
|
|
39
|
-
from_status ENUM('draft','pending','paid','failed','canceled','expired','refunded'
|
|
40
|
-
to_status ENUM('draft','pending','paid','failed','canceled','expired','refunded'
|
|
39
|
+
from_status ENUM('draft','pending','paid','failed','canceled','expired','refunded') NULL,
|
|
40
|
+
to_status ENUM('draft','pending','paid','failed','canceled','expired','refunded') NOT NULL,
|
|
41
41
|
actor_type ENUM('webhook','system','admin') NOT NULL,
|
|
42
42
|
mollie_payment_id VARCHAR(64) NULL,
|
|
43
43
|
note VARCHAR(512) NULL,
|
|
@@ -54,6 +54,9 @@ export declare class InvoicesOrm extends ZOrm {
|
|
|
54
54
|
): Promise<void>;
|
|
55
55
|
finalizePayToken(id: number): Promise<void>;
|
|
56
56
|
incrementTimesSent(id: number): Promise<void>;
|
|
57
|
+
setArchivedAt(id: number): Promise<void>;
|
|
58
|
+
clearArchivedAt(id: number): Promise<void>;
|
|
59
|
+
isArchived(invoice: ZInvoice): boolean;
|
|
57
60
|
updateMutableFields(
|
|
58
61
|
id: number,
|
|
59
62
|
fields: {
|
|
@@ -190,6 +190,29 @@ class InvoicesOrm extends orm_1.ZOrm {
|
|
|
190
190
|
{ id },
|
|
191
191
|
);
|
|
192
192
|
}
|
|
193
|
+
async setArchivedAt(id) {
|
|
194
|
+
await this.sqlService.query(
|
|
195
|
+
/*SQL*/ `
|
|
196
|
+
UPDATE \`${this.alias}\`
|
|
197
|
+
SET archived_at=NOW(), updated_at=NOW()
|
|
198
|
+
WHERE id=:id
|
|
199
|
+
`,
|
|
200
|
+
{ id },
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
async clearArchivedAt(id) {
|
|
204
|
+
await this.sqlService.query(
|
|
205
|
+
/*SQL*/ `
|
|
206
|
+
UPDATE \`${this.alias}\`
|
|
207
|
+
SET archived_at=NULL, updated_at=NOW()
|
|
208
|
+
WHERE id=:id
|
|
209
|
+
`,
|
|
210
|
+
{ id },
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
isArchived(invoice) {
|
|
214
|
+
return invoice.archived_at != null;
|
|
215
|
+
}
|
|
193
216
|
async updateMutableFields(id, fields) {
|
|
194
217
|
const sets = [];
|
|
195
218
|
const params = { id };
|
|
@@ -235,7 +258,7 @@ class InvoicesOrm extends orm_1.ZOrm {
|
|
|
235
258
|
pay_token_hash CHAR(64),
|
|
236
259
|
pay_token_expires_at DATETIME,
|
|
237
260
|
pay_token_finalized_at DATETIME,
|
|
238
|
-
status ENUM('draft','pending','paid','failed','canceled','expired','refunded'
|
|
261
|
+
status ENUM('draft','pending','paid','failed','canceled','expired','refunded') NOT NULL DEFAULT 'draft',
|
|
239
262
|
amount_due DECIMAL(12,2) NOT NULL,
|
|
240
263
|
amount_paid DECIMAL(12,2) NOT NULL DEFAULT 0,
|
|
241
264
|
currency CHAR(3) NOT NULL DEFAULT 'EUR',
|
|
@@ -246,6 +269,7 @@ class InvoicesOrm extends orm_1.ZOrm {
|
|
|
246
269
|
paid_at DATETIME,
|
|
247
270
|
checkout_url VARCHAR(512),
|
|
248
271
|
times_sent INT NOT NULL DEFAULT 0,
|
|
272
|
+
archived_at DATETIME NULL,
|
|
249
273
|
metadata JSON NULL,
|
|
250
274
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
251
275
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
@@ -50,7 +50,7 @@ export declare class InvoiceService {
|
|
|
50
50
|
private ensureSubscriptionInvoiceSchema;
|
|
51
51
|
private ensureSubsidyItemTypeSchema;
|
|
52
52
|
private ensureSentCountSchema;
|
|
53
|
-
private
|
|
53
|
+
private ensureArchivedAtSchema;
|
|
54
54
|
private ensureInvoicePaymentSchema;
|
|
55
55
|
private generateInvoiceNumber;
|
|
56
56
|
private getWebhookUrl;
|
|
@@ -88,6 +88,7 @@ export declare class InvoiceService {
|
|
|
88
88
|
},
|
|
89
89
|
): Promise<ZInvoice>;
|
|
90
90
|
archiveInvoice(invoiceId: number): Promise<ZInvoice>;
|
|
91
|
+
unarchiveInvoice(invoiceId: number): Promise<ZInvoice>;
|
|
91
92
|
duplicateInvoice(
|
|
92
93
|
sourceInvoiceId: number,
|
|
93
94
|
customerId: number,
|
|
@@ -70,7 +70,7 @@ class InvoiceService {
|
|
|
70
70
|
await this.ensureInvoicePaymentSchema();
|
|
71
71
|
await this.ensureSubsidyItemTypeSchema();
|
|
72
72
|
await this.ensureSentCountSchema();
|
|
73
|
-
await this.
|
|
73
|
+
await this.ensureArchivedAtSchema();
|
|
74
74
|
}
|
|
75
75
|
async ensurePayTokenSchema() {
|
|
76
76
|
const table = this.invoicesOrm.alias;
|
|
@@ -142,17 +142,14 @@ class InvoiceService {
|
|
|
142
142
|
);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
async
|
|
145
|
+
async ensureArchivedAtSchema() {
|
|
146
146
|
const table = this.invoicesOrm.alias;
|
|
147
147
|
const rows = await this.opt.sqlService.exec({
|
|
148
|
-
query: `SELECT
|
|
148
|
+
query: `SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=:schema AND TABLE_NAME=:tableName AND COLUMN_NAME='archived_at' LIMIT 1`,
|
|
149
149
|
params: { schema: this.opt.sqlService.database, tableName: table },
|
|
150
150
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
await this.opt.sqlService.query(
|
|
154
|
-
`ALTER TABLE \`${table}\` MODIFY COLUMN status ENUM('draft','pending','paid','failed','canceled','expired','refunded','archived') NOT NULL DEFAULT 'draft'`,
|
|
155
|
-
);
|
|
151
|
+
if (!rows?.[0]) {
|
|
152
|
+
await this.opt.sqlService.query(`ALTER TABLE \`${table}\` ADD COLUMN archived_at DATETIME NULL AFTER times_sent`);
|
|
156
153
|
}
|
|
157
154
|
}
|
|
158
155
|
async ensureInvoicePaymentSchema() {
|
|
@@ -451,6 +448,8 @@ class InvoiceService {
|
|
|
451
448
|
if (!invoice) throw new Error(`Invoice ${invoiceId} not found`);
|
|
452
449
|
if (invoice.status !== 'draft')
|
|
453
450
|
throw new Error(`Invoice ${invoice.invoice_number} cannot be edited (status: ${invoice.status})`);
|
|
451
|
+
if (this.invoicesOrm.isArchived(invoice))
|
|
452
|
+
throw new Error(`Invoice ${invoice.invoice_number} cannot be edited (archived)`);
|
|
454
453
|
if ((invoice.times_sent ?? 0) > 0)
|
|
455
454
|
throw new Error(
|
|
456
455
|
`Invoice ${invoice.invoice_number} cannot be edited (already sent ${invoice.times_sent} time(s))`,
|
|
@@ -484,16 +483,36 @@ class InvoiceService {
|
|
|
484
483
|
if (!invoice) {
|
|
485
484
|
throw new Error(`Invoice ${invoiceId} not found`);
|
|
486
485
|
}
|
|
487
|
-
if (invoice
|
|
488
|
-
|
|
486
|
+
if (this.invoicesOrm.isArchived(invoice)) {
|
|
487
|
+
return invoice;
|
|
489
488
|
}
|
|
490
|
-
|
|
489
|
+
await this.invoicesOrm.setArchivedAt(invoiceId);
|
|
490
|
+
// Audit log: record archive event
|
|
491
|
+
await this.invoiceStatusLogOrm.insert({
|
|
492
|
+
invoice_id: invoiceId,
|
|
493
|
+
from_status: invoice.status,
|
|
494
|
+
to_status: invoice.status,
|
|
495
|
+
actor_type: 'admin',
|
|
496
|
+
note: 'Invoice archived (archived_at set)',
|
|
497
|
+
});
|
|
498
|
+
return await this.invoicesOrm.findById(invoiceId);
|
|
499
|
+
}
|
|
500
|
+
async unarchiveInvoice(invoiceId) {
|
|
501
|
+
const invoice = await this.invoicesOrm.findById(invoiceId);
|
|
502
|
+
if (!invoice) {
|
|
503
|
+
throw new Error(`Invoice ${invoiceId} not found`);
|
|
504
|
+
}
|
|
505
|
+
if (!this.invoicesOrm.isArchived(invoice)) {
|
|
491
506
|
return invoice;
|
|
492
507
|
}
|
|
493
|
-
await this.invoicesOrm.
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
508
|
+
await this.invoicesOrm.clearArchivedAt(invoiceId);
|
|
509
|
+
// Audit log: record unarchive event
|
|
510
|
+
await this.invoiceStatusLogOrm.insert({
|
|
511
|
+
invoice_id: invoiceId,
|
|
512
|
+
from_status: invoice.status,
|
|
513
|
+
to_status: invoice.status,
|
|
514
|
+
actor_type: 'admin',
|
|
515
|
+
note: 'Invoice unarchived (archived_at cleared)',
|
|
497
516
|
});
|
|
498
517
|
return await this.invoicesOrm.findById(invoiceId);
|
|
499
518
|
}
|
|
@@ -18,7 +18,7 @@ export type ZCustomer = {
|
|
|
18
18
|
updated_at?: string | Date;
|
|
19
19
|
};
|
|
20
20
|
export type ZInvoiceItemType = 'service' | 'subsidy';
|
|
21
|
-
export type ZInvoiceStatus = 'draft' | 'pending' | 'paid' | 'failed' | 'canceled' | 'expired' | 'refunded'
|
|
21
|
+
export type ZInvoiceStatus = 'draft' | 'pending' | 'paid' | 'failed' | 'canceled' | 'expired' | 'refunded';
|
|
22
22
|
export type ZInvoiceItem = {
|
|
23
23
|
id?: number;
|
|
24
24
|
invoice_id: number;
|
|
@@ -77,6 +77,7 @@ export type ZInvoice = {
|
|
|
77
77
|
paid_at?: string | null;
|
|
78
78
|
checkout_url?: string | null;
|
|
79
79
|
times_sent?: number;
|
|
80
|
+
archived_at?: string | null;
|
|
80
81
|
metadata?: any;
|
|
81
82
|
created_at?: string | Date;
|
|
82
83
|
updated_at?: string | Date;
|