ztechno_core 0.0.105 → 0.0.108
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/core/crypto_service.d.ts +23 -0
- package/lib/core/crypto_service.js +100 -0
- package/lib/core/engine_base.d.ts +11 -0
- package/lib/core/engine_base.js +9 -0
- package/lib/core/index.d.ts +14 -0
- package/lib/core/index.js +101 -0
- package/lib/core/mail_service.d.ts +85 -0
- package/lib/core/mail_service.js +156 -0
- package/lib/core/orm/mail_blacklist_orm.d.ts +21 -0
- package/lib/core/orm/mail_blacklist_orm.js +79 -0
- package/lib/core/orm/orm.d.ts +27 -0
- package/lib/core/orm/orm.js +67 -0
- package/lib/core/sql_service.d.ts +195 -0
- package/lib/core/sql_service.js +333 -0
- package/lib/core/translate_service.d.ts +48 -0
- package/lib/core/translate_service.js +913 -0
- package/lib/core/types/crypto_types.d.ts +4 -0
- package/lib/core/types/crypto_types.js +2 -0
- package/lib/core/types/mail_types.d.ts +95 -0
- package/lib/core/types/mail_types.js +2 -0
- package/lib/core/types/site_config.d.ts +46 -0
- package/lib/core/types/site_config.js +2 -0
- package/lib/core/types/translate_types.d.ts +69 -0
- package/lib/core/types/translate_types.js +46 -0
- package/lib/core/types/user_types.d.ts +41 -0
- package/lib/core/types/user_types.js +2 -0
- package/lib/core/user_service.d.ts +87 -0
- package/lib/core/user_service.js +216 -0
- package/lib/express/index.d.ts +1 -0
- package/lib/express/index.js +18 -0
- package/lib/index.d.ts +17 -8
- package/lib/index.js +60 -16
- package/lib/mollie/index.d.ts +5 -0
- package/lib/mollie/index.js +62 -0
- package/lib/mollie/orm/customers_orm.d.ts +16 -0
- package/lib/mollie/orm/customers_orm.js +115 -0
- package/lib/mollie/orm/invoice_items_orm.d.ts +9 -0
- package/lib/mollie/orm/invoice_items_orm.js +71 -0
- package/lib/mollie/orm/invoice_payments_orm.d.ts +10 -0
- package/lib/mollie/orm/invoice_payments_orm.js +70 -0
- package/lib/mollie/orm/invoices_orm.d.ts +40 -0
- package/lib/mollie/orm/invoices_orm.js +172 -0
- package/lib/mollie/orm/subscription_items_orm.d.ts +9 -0
- package/lib/mollie/orm/subscription_items_orm.js +45 -0
- package/lib/mollie/orm/subscriptions_orm.d.ts +17 -0
- package/lib/mollie/orm/subscriptions_orm.js +122 -0
- package/lib/mollie/services/customer_service.d.ts +14 -0
- package/lib/mollie/services/customer_service.js +53 -0
- package/lib/mollie/services/invoice_service.d.ts +102 -0
- package/lib/mollie/services/invoice_service.js +866 -0
- package/lib/mollie/services/mollie_service.d.ts +42 -0
- package/lib/mollie/services/mollie_service.js +370 -0
- package/lib/mollie/services/subscription_service.d.ts +32 -0
- package/lib/mollie/services/subscription_service.js +134 -0
- package/lib/mollie/types/internal_types.d.ts +19 -0
- package/lib/mollie/types/internal_types.js +2 -0
- package/lib/mollie/types/mollie_types.d.ts +187 -0
- package/lib/mollie/types/mollie_types.js +3 -0
- package/lib/mollie/util/subscription_utils.d.ts +8 -0
- package/lib/mollie/util/subscription_utils.js +37 -0
- package/lib/schema/MySQLSchemaExtractor.d.ts +1 -1
- package/lib/schema/MySQLSchemaImporter.d.ts +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
exports.InvoicesOrm = void 0;
|
|
4
|
+
const orm_1 = require('../../core/orm/orm');
|
|
5
|
+
class InvoicesOrm extends orm_1.ZOrm {
|
|
6
|
+
constructor(opt) {
|
|
7
|
+
super({ sqlService: opt.sqlService, alias: opt.alias ?? 'mollie_invoices' });
|
|
8
|
+
}
|
|
9
|
+
async create(invoice) {
|
|
10
|
+
const res = await this.sqlService.query(
|
|
11
|
+
/*SQL*/ `
|
|
12
|
+
INSERT INTO \`${this.alias}\`
|
|
13
|
+
(invoice_number, customer_id, subscription_id, subscription_period_start, subscription_period_end, mollie_customer_id, mollie_payment_id, pay_token_hash, pay_token_expires_at, pay_token_finalized_at, status, amount_due, amount_paid, currency, description, payment_terms, due_date, issued_at, paid_at, checkout_url, metadata)
|
|
14
|
+
VALUES
|
|
15
|
+
(:invoice_number, :customer_id, :subscription_id, :subscription_period_start, :subscription_period_end, :mollie_customer_id, :mollie_payment_id, :pay_token_hash, :pay_token_expires_at, :pay_token_finalized_at, :status, :amount_due, :amount_paid, :currency, :description, :payment_terms, :due_date, :issued_at, :paid_at, :checkout_url, :metadata)
|
|
16
|
+
ON DUPLICATE KEY UPDATE
|
|
17
|
+
subscription_id=VALUES(subscription_id),
|
|
18
|
+
subscription_period_start=VALUES(subscription_period_start),
|
|
19
|
+
subscription_period_end=VALUES(subscription_period_end),
|
|
20
|
+
mollie_customer_id=VALUES(mollie_customer_id),
|
|
21
|
+
mollie_payment_id=VALUES(mollie_payment_id),
|
|
22
|
+
pay_token_hash=VALUES(pay_token_hash),
|
|
23
|
+
pay_token_expires_at=VALUES(pay_token_expires_at),
|
|
24
|
+
pay_token_finalized_at=VALUES(pay_token_finalized_at),
|
|
25
|
+
status=VALUES(status),
|
|
26
|
+
amount_due=VALUES(amount_due),
|
|
27
|
+
amount_paid=VALUES(amount_paid),
|
|
28
|
+
currency=VALUES(currency),
|
|
29
|
+
description=VALUES(description),
|
|
30
|
+
payment_terms=VALUES(payment_terms),
|
|
31
|
+
due_date=VALUES(due_date),
|
|
32
|
+
issued_at=VALUES(issued_at),
|
|
33
|
+
paid_at=VALUES(paid_at),
|
|
34
|
+
checkout_url=VALUES(checkout_url),
|
|
35
|
+
metadata=VALUES(metadata),
|
|
36
|
+
updated_at=NOW()
|
|
37
|
+
`,
|
|
38
|
+
invoice,
|
|
39
|
+
);
|
|
40
|
+
return res;
|
|
41
|
+
}
|
|
42
|
+
async findById(id) {
|
|
43
|
+
const res = await this.sqlService.exec({
|
|
44
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE id=:id LIMIT 1`,
|
|
45
|
+
params: { id },
|
|
46
|
+
});
|
|
47
|
+
return res[0];
|
|
48
|
+
}
|
|
49
|
+
async findByInvoiceNumber(invoice_number) {
|
|
50
|
+
const res = await this.sqlService.exec({
|
|
51
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE invoice_number=:invoice_number LIMIT 1`,
|
|
52
|
+
params: { invoice_number },
|
|
53
|
+
});
|
|
54
|
+
return res[0];
|
|
55
|
+
}
|
|
56
|
+
async findByPayTokenHash(pay_token_hash) {
|
|
57
|
+
const res = await this.sqlService.exec({
|
|
58
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE pay_token_hash=:pay_token_hash LIMIT 1`,
|
|
59
|
+
params: { pay_token_hash },
|
|
60
|
+
});
|
|
61
|
+
return res[0];
|
|
62
|
+
}
|
|
63
|
+
async findAll() {
|
|
64
|
+
return await this.sqlService.exec({ query: `SELECT * FROM \`${this.alias}\` ORDER BY created_at DESC` });
|
|
65
|
+
}
|
|
66
|
+
async findLastByYear(year) {
|
|
67
|
+
const res = await this.sqlService.exec({
|
|
68
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE invoice_number LIKE :pattern ORDER BY invoice_number DESC LIMIT 1`,
|
|
69
|
+
params: { pattern: `INV-${year}-%` },
|
|
70
|
+
});
|
|
71
|
+
return res[0];
|
|
72
|
+
}
|
|
73
|
+
async updateStatus(id, status, amount_paid, paid_at) {
|
|
74
|
+
await this.sqlService.query(
|
|
75
|
+
/*SQL*/ `
|
|
76
|
+
UPDATE \`${this.alias}\`
|
|
77
|
+
SET status=:status, amount_paid=COALESCE(:amount_paid, amount_paid), paid_at=COALESCE(:paid_at, paid_at), updated_at=NOW()
|
|
78
|
+
WHERE id=:id
|
|
79
|
+
`,
|
|
80
|
+
{ id, status, amount_paid: amount_paid ?? null, paid_at: paid_at ?? null },
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
async updatePaymentRef(id, payload) {
|
|
84
|
+
await this.sqlService.query(
|
|
85
|
+
/*SQL*/ `
|
|
86
|
+
UPDATE \`${this.alias}\`
|
|
87
|
+
SET
|
|
88
|
+
mollie_payment_id=COALESCE(:mollie_payment_id, mollie_payment_id),
|
|
89
|
+
checkout_url=COALESCE(:checkout_url, checkout_url),
|
|
90
|
+
updated_at=NOW()
|
|
91
|
+
WHERE id=:id
|
|
92
|
+
`,
|
|
93
|
+
{ id, mollie_payment_id: payload.mollie_payment_id ?? null, checkout_url: payload.checkout_url ?? null },
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
async updateSubscriptionPeriod(id, payload) {
|
|
97
|
+
await this.sqlService.query(
|
|
98
|
+
/*SQL*/ `
|
|
99
|
+
UPDATE \`${this.alias}\`
|
|
100
|
+
SET
|
|
101
|
+
subscription_id=COALESCE(:subscription_id, subscription_id),
|
|
102
|
+
subscription_period_start=COALESCE(:subscription_period_start, subscription_period_start),
|
|
103
|
+
subscription_period_end=COALESCE(:subscription_period_end, subscription_period_end),
|
|
104
|
+
updated_at=NOW()
|
|
105
|
+
WHERE id=:id
|
|
106
|
+
`,
|
|
107
|
+
{
|
|
108
|
+
id,
|
|
109
|
+
subscription_id: payload.subscription_id ?? null,
|
|
110
|
+
subscription_period_start: payload.subscription_period_start ?? null,
|
|
111
|
+
subscription_period_end: payload.subscription_period_end ?? null,
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
async setPayToken(id, payload) {
|
|
116
|
+
await this.sqlService.query(
|
|
117
|
+
/*SQL*/ `
|
|
118
|
+
UPDATE \`${this.alias}\`
|
|
119
|
+
SET pay_token_hash=:pay_token_hash, pay_token_expires_at=:pay_token_expires_at, pay_token_finalized_at=NULL, updated_at=NOW()
|
|
120
|
+
WHERE id=:id
|
|
121
|
+
`,
|
|
122
|
+
{ id, ...payload },
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
async finalizePayToken(id) {
|
|
126
|
+
await this.sqlService.query(
|
|
127
|
+
/*SQL*/ `
|
|
128
|
+
UPDATE \`${this.alias}\`
|
|
129
|
+
SET pay_token_finalized_at=NOW(), updated_at=NOW()
|
|
130
|
+
WHERE id=:id
|
|
131
|
+
`,
|
|
132
|
+
{ id },
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
async createTable() {
|
|
136
|
+
await this.sqlService.query(/*SQL*/ `
|
|
137
|
+
CREATE TABLE IF NOT EXISTS \`${this.alias}\` (
|
|
138
|
+
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
139
|
+
invoice_number VARCHAR(32) NOT NULL,
|
|
140
|
+
customer_id BIGINT UNSIGNED NOT NULL,
|
|
141
|
+
subscription_id BIGINT UNSIGNED NULL,
|
|
142
|
+
subscription_period_start DATETIME,
|
|
143
|
+
subscription_period_end DATETIME,
|
|
144
|
+
mollie_customer_id VARCHAR(64),
|
|
145
|
+
mollie_payment_id VARCHAR(64),
|
|
146
|
+
pay_token_hash CHAR(64),
|
|
147
|
+
pay_token_expires_at DATETIME,
|
|
148
|
+
pay_token_finalized_at DATETIME,
|
|
149
|
+
status ENUM('draft','pending','paid','failed','canceled','expired','refunded') NOT NULL DEFAULT 'draft',
|
|
150
|
+
amount_due DECIMAL(12,2) NOT NULL,
|
|
151
|
+
amount_paid DECIMAL(12,2) NOT NULL DEFAULT 0,
|
|
152
|
+
currency CHAR(3) NOT NULL DEFAULT 'EUR',
|
|
153
|
+
description VARCHAR(512),
|
|
154
|
+
payment_terms VARCHAR(255),
|
|
155
|
+
due_date DATE,
|
|
156
|
+
issued_at DATETIME,
|
|
157
|
+
paid_at DATETIME,
|
|
158
|
+
checkout_url VARCHAR(512),
|
|
159
|
+
metadata JSON NULL,
|
|
160
|
+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
161
|
+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
162
|
+
UNIQUE KEY uq_invoice_number (invoice_number),
|
|
163
|
+
UNIQUE KEY uq_invoices_pay_token_hash (pay_token_hash),
|
|
164
|
+
KEY idx_invoices_customer (customer_id),
|
|
165
|
+
KEY idx_invoices_subscription (subscription_id),
|
|
166
|
+
KEY idx_invoices_status (status),
|
|
167
|
+
KEY idx_invoices_due (due_date)
|
|
168
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
169
|
+
`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.InvoicesOrm = InvoicesOrm;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ZOrm } from '../../core/orm/orm';
|
|
2
|
+
import { ZSQLService } from '../../core/sql_service';
|
|
3
|
+
import { ZSubscriptionItem } from '../types/mollie_types';
|
|
4
|
+
export declare class SubscriptionItemsOrm extends ZOrm {
|
|
5
|
+
constructor(opt: { sqlService: ZSQLService; alias?: string });
|
|
6
|
+
bulkInsert(items: ZSubscriptionItem[]): Promise<void>;
|
|
7
|
+
findBySubscription(subscription_id: number): Promise<ZSubscriptionItem[]>;
|
|
8
|
+
createTable(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
exports.SubscriptionItemsOrm = void 0;
|
|
4
|
+
const orm_1 = require('../../core/orm/orm');
|
|
5
|
+
class SubscriptionItemsOrm extends orm_1.ZOrm {
|
|
6
|
+
constructor(opt) {
|
|
7
|
+
super({ sqlService: opt.sqlService, alias: opt.alias ?? 'mollie_subscription_items' });
|
|
8
|
+
}
|
|
9
|
+
async bulkInsert(items) {
|
|
10
|
+
for (const item of items) {
|
|
11
|
+
await this.sqlService.query(
|
|
12
|
+
/*SQL*/ `
|
|
13
|
+
INSERT INTO \`${this.alias}\`
|
|
14
|
+
(subscription_id, description, quantity, unit_price, vat_rate, total_ex_vat, total_inc_vat, sort_order)
|
|
15
|
+
VALUES
|
|
16
|
+
(:subscription_id, :description, :quantity, :unit_price, :vat_rate, :total_ex_vat, :total_inc_vat, :sort_order)
|
|
17
|
+
`,
|
|
18
|
+
item,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async findBySubscription(subscription_id) {
|
|
23
|
+
return await this.sqlService.exec({
|
|
24
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE subscription_id=:subscription_id ORDER BY sort_order, id`,
|
|
25
|
+
params: { subscription_id },
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async createTable() {
|
|
29
|
+
await this.sqlService.query(/*SQL*/ `
|
|
30
|
+
CREATE TABLE IF NOT EXISTS \`${this.alias}\` (
|
|
31
|
+
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
32
|
+
subscription_id BIGINT UNSIGNED NOT NULL,
|
|
33
|
+
description VARCHAR(255) NOT NULL,
|
|
34
|
+
quantity DECIMAL(10,2) NOT NULL DEFAULT 1,
|
|
35
|
+
unit_price DECIMAL(12,2) NOT NULL,
|
|
36
|
+
vat_rate DECIMAL(5,2) NOT NULL DEFAULT 0.00,
|
|
37
|
+
total_ex_vat DECIMAL(12,2) NOT NULL,
|
|
38
|
+
total_inc_vat DECIMAL(12,2) NOT NULL,
|
|
39
|
+
sort_order SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
|
40
|
+
KEY idx_subscription_items_subscription (subscription_id)
|
|
41
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
42
|
+
`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.SubscriptionItemsOrm = SubscriptionItemsOrm;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ZOrm } from '../../core/orm/orm';
|
|
2
|
+
import { ZSQLService } from '../../core/sql_service';
|
|
3
|
+
import { ZSubscription } from '../types/mollie_types';
|
|
4
|
+
export declare class SubscriptionsOrm extends ZOrm {
|
|
5
|
+
constructor(opt: { sqlService: ZSQLService; alias?: string; hashSalt?: string });
|
|
6
|
+
create(subscription: Omit<ZSubscription, 'id' | 'created_at' | 'updated_at'>): Promise<{
|
|
7
|
+
insertId: number;
|
|
8
|
+
affectedRows: number;
|
|
9
|
+
}>;
|
|
10
|
+
update(id: number, payload: Partial<Omit<ZSubscription, 'id' | 'created_at' | 'updated_at'>>): Promise<void>;
|
|
11
|
+
findById(id: number): Promise<ZSubscription>;
|
|
12
|
+
findByMollieSubscriptionId(mollie_subscription_id: string): Promise<ZSubscription>;
|
|
13
|
+
findByCustomer(customer_id: number): Promise<ZSubscription[]>;
|
|
14
|
+
findLatestByCustomer(customer_id: number): Promise<ZSubscription>;
|
|
15
|
+
findAll(): Promise<ZSubscription[]>;
|
|
16
|
+
createTable(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
exports.SubscriptionsOrm = void 0;
|
|
4
|
+
const orm_1 = require('../../core/orm/orm');
|
|
5
|
+
class SubscriptionsOrm extends orm_1.ZOrm {
|
|
6
|
+
constructor(opt) {
|
|
7
|
+
super({ sqlService: opt.sqlService, alias: opt.alias || 'mollie_subscriptions' });
|
|
8
|
+
}
|
|
9
|
+
async create(subscription) {
|
|
10
|
+
const res = await this.sqlService.query(
|
|
11
|
+
/*SQL*/ `
|
|
12
|
+
INSERT INTO \`${this.alias}\`
|
|
13
|
+
(customer_id, mollie_customer_id, mollie_subscription_id, status, \`interval\`, description, amount, currency, mandate_id, next_payment_date, canceled_at, metadata)
|
|
14
|
+
VALUES
|
|
15
|
+
(:customer_id, :mollie_customer_id, :mollie_subscription_id, :status, :interval, :description, :amount, :currency, :mandate_id, :next_payment_date, :canceled_at, :metadata)
|
|
16
|
+
ON DUPLICATE KEY UPDATE
|
|
17
|
+
mollie_customer_id=VALUES(mollie_customer_id),
|
|
18
|
+
mollie_subscription_id=VALUES(mollie_subscription_id),
|
|
19
|
+
status=VALUES(status),
|
|
20
|
+
\`interval\`=VALUES(\`interval\`),
|
|
21
|
+
description=VALUES(description),
|
|
22
|
+
amount=VALUES(amount),
|
|
23
|
+
currency=VALUES(currency),
|
|
24
|
+
mandate_id=VALUES(mandate_id),
|
|
25
|
+
next_payment_date=VALUES(next_payment_date),
|
|
26
|
+
canceled_at=VALUES(canceled_at),
|
|
27
|
+
metadata=VALUES(metadata),
|
|
28
|
+
updated_at=NOW()
|
|
29
|
+
`,
|
|
30
|
+
subscription,
|
|
31
|
+
);
|
|
32
|
+
return res;
|
|
33
|
+
}
|
|
34
|
+
async update(id, payload) {
|
|
35
|
+
const fields = [];
|
|
36
|
+
const params = { id };
|
|
37
|
+
const allowed = [
|
|
38
|
+
'customer_id',
|
|
39
|
+
'mollie_customer_id',
|
|
40
|
+
'mollie_subscription_id',
|
|
41
|
+
'status',
|
|
42
|
+
'interval',
|
|
43
|
+
'description',
|
|
44
|
+
'amount',
|
|
45
|
+
'currency',
|
|
46
|
+
'mandate_id',
|
|
47
|
+
'next_payment_date',
|
|
48
|
+
'canceled_at',
|
|
49
|
+
'metadata',
|
|
50
|
+
];
|
|
51
|
+
for (const field of allowed) {
|
|
52
|
+
if (field in payload) {
|
|
53
|
+
fields.push(`\`${field}\`=:${field}`);
|
|
54
|
+
params[field] = payload[field];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (fields.length === 0) return;
|
|
58
|
+
await this.sqlService.query(
|
|
59
|
+
/*SQL*/ `
|
|
60
|
+
UPDATE \`${this.alias}\`
|
|
61
|
+
SET ${fields.join(', ')}, updated_at=NOW()
|
|
62
|
+
WHERE id=:id
|
|
63
|
+
`,
|
|
64
|
+
params,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
async findById(id) {
|
|
68
|
+
const res = await this.sqlService.exec({
|
|
69
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE id=:id LIMIT 1`,
|
|
70
|
+
params: { id },
|
|
71
|
+
});
|
|
72
|
+
return res[0];
|
|
73
|
+
}
|
|
74
|
+
async findByMollieSubscriptionId(mollie_subscription_id) {
|
|
75
|
+
const res = await this.sqlService.exec({
|
|
76
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE mollie_subscription_id=:mollie_subscription_id LIMIT 1`,
|
|
77
|
+
params: { mollie_subscription_id },
|
|
78
|
+
});
|
|
79
|
+
return res[0];
|
|
80
|
+
}
|
|
81
|
+
async findByCustomer(customer_id) {
|
|
82
|
+
return await this.sqlService.exec({
|
|
83
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE customer_id=:customer_id ORDER BY created_at DESC`,
|
|
84
|
+
params: { customer_id },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async findLatestByCustomer(customer_id) {
|
|
88
|
+
const res = await this.sqlService.exec({
|
|
89
|
+
query: `SELECT * FROM \`${this.alias}\` WHERE customer_id=:customer_id ORDER BY id DESC LIMIT 1`,
|
|
90
|
+
params: { customer_id },
|
|
91
|
+
});
|
|
92
|
+
return res[0];
|
|
93
|
+
}
|
|
94
|
+
async findAll() {
|
|
95
|
+
return await this.sqlService.exec({ query: `SELECT * FROM \`${this.alias}\` ORDER BY created_at DESC` });
|
|
96
|
+
}
|
|
97
|
+
async createTable() {
|
|
98
|
+
await this.sqlService.query(/*SQL*/ `
|
|
99
|
+
CREATE TABLE IF NOT EXISTS \`${this.alias}\` (
|
|
100
|
+
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
101
|
+
customer_id BIGINT UNSIGNED NOT NULL,
|
|
102
|
+
mollie_customer_id VARCHAR(64),
|
|
103
|
+
mollie_subscription_id VARCHAR(64),
|
|
104
|
+
status ENUM('setup_pending','pending','active','canceled','suspended','completed') NOT NULL DEFAULT 'setup_pending',
|
|
105
|
+
\`interval\` VARCHAR(64) NOT NULL,
|
|
106
|
+
description VARCHAR(512),
|
|
107
|
+
amount DECIMAL(12,2) NOT NULL,
|
|
108
|
+
currency CHAR(3) NOT NULL DEFAULT 'EUR',
|
|
109
|
+
mandate_id VARCHAR(64),
|
|
110
|
+
next_payment_date DATETIME,
|
|
111
|
+
canceled_at DATETIME,
|
|
112
|
+
metadata JSON NULL,
|
|
113
|
+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
114
|
+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
115
|
+
UNIQUE KEY uq_subscription_mollie (mollie_subscription_id),
|
|
116
|
+
KEY idx_subscription_customer (customer_id),
|
|
117
|
+
KEY idx_subscription_status (status)
|
|
118
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
|
119
|
+
`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.SubscriptionsOrm = SubscriptionsOrm;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ZSQLService } from '../../core/sql_service';
|
|
2
|
+
import { ZCustomer } from '../types/mollie_types';
|
|
3
|
+
import { CustomersOrm } from '../orm/customers_orm';
|
|
4
|
+
import { MollieService } from './mollie_service';
|
|
5
|
+
export declare class CustomerService {
|
|
6
|
+
private opt;
|
|
7
|
+
protected orm: CustomersOrm;
|
|
8
|
+
constructor(opt: { sqlService: ZSQLService; mollieService: MollieService });
|
|
9
|
+
autoInit(): Promise<void>;
|
|
10
|
+
list(): Promise<ZCustomer[]>;
|
|
11
|
+
findById(id: number): Promise<ZCustomer | undefined>;
|
|
12
|
+
upsert(customer: Omit<ZCustomer, 'id' | 'created_at' | 'updated_at'>): Promise<ZCustomer>;
|
|
13
|
+
update(id: number, customer: Partial<Omit<ZCustomer, 'id' | 'created_at' | 'updated_at'>>): Promise<ZCustomer>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
exports.CustomerService = void 0;
|
|
4
|
+
const customers_orm_1 = require('../orm/customers_orm');
|
|
5
|
+
class CustomerService {
|
|
6
|
+
constructor(opt) {
|
|
7
|
+
this.opt = opt;
|
|
8
|
+
this.orm = new customers_orm_1.CustomersOrm({ sqlService: opt.sqlService });
|
|
9
|
+
}
|
|
10
|
+
async autoInit() {
|
|
11
|
+
await this.orm.ensureTableExists();
|
|
12
|
+
}
|
|
13
|
+
async list() {
|
|
14
|
+
return await this.orm.findAll();
|
|
15
|
+
}
|
|
16
|
+
async findById(id) {
|
|
17
|
+
return await this.orm.findById(id);
|
|
18
|
+
}
|
|
19
|
+
async upsert(customer) {
|
|
20
|
+
const existing = await this.orm.findByEmail(customer.email);
|
|
21
|
+
const mollie_customer_id = existing?.mollie_customer_id
|
|
22
|
+
? existing.mollie_customer_id
|
|
23
|
+
: (
|
|
24
|
+
await this.opt.mollieService.createCustomer({
|
|
25
|
+
name: customer.name,
|
|
26
|
+
email: customer.email,
|
|
27
|
+
locale: customer.locale ?? undefined,
|
|
28
|
+
metadata: {
|
|
29
|
+
...(customer.metadata ?? {}),
|
|
30
|
+
company: customer.company ?? undefined,
|
|
31
|
+
phone: customer.phone ?? undefined,
|
|
32
|
+
btw_nummer: customer.btw_nummer ?? undefined,
|
|
33
|
+
address_line1: customer.address_line1 ?? undefined,
|
|
34
|
+
address_line2: customer.address_line2 ?? undefined,
|
|
35
|
+
postal_code: customer.postal_code ?? undefined,
|
|
36
|
+
city: customer.city ?? undefined,
|
|
37
|
+
country: customer.country ?? undefined,
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
).id;
|
|
41
|
+
await this.orm.create({ ...existing, ...customer, mollie_customer_id });
|
|
42
|
+
return await this.orm.findByEmail(customer.email);
|
|
43
|
+
}
|
|
44
|
+
async update(id, customer) {
|
|
45
|
+
const existing = await this.orm.findById(id);
|
|
46
|
+
if (!existing) {
|
|
47
|
+
throw new Error(`Customer ${id} not found`);
|
|
48
|
+
}
|
|
49
|
+
await this.orm.update(id, customer);
|
|
50
|
+
return await this.orm.findById(id);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.CustomerService = CustomerService;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { CustomerService } from './customer_service';
|
|
3
|
+
import { RenderData } from '../../core/types/site_config';
|
|
4
|
+
import { ZMailService } from '../../core/mail_service';
|
|
5
|
+
import { MollieService } from './mollie_service';
|
|
6
|
+
import { ZSQLService } from '../../core/sql_service';
|
|
7
|
+
import {
|
|
8
|
+
ZInvoice,
|
|
9
|
+
CreateInvoiceInput,
|
|
10
|
+
ZInvoicePayment,
|
|
11
|
+
CreateInvoiceOverrides,
|
|
12
|
+
ZIssuedPayToken,
|
|
13
|
+
ZPayResolveResult,
|
|
14
|
+
} from '../types/mollie_types';
|
|
15
|
+
export declare class InvoiceService {
|
|
16
|
+
private opt;
|
|
17
|
+
private invoicesOrm;
|
|
18
|
+
private itemsOrm;
|
|
19
|
+
private paymentsOrm;
|
|
20
|
+
private subscriptionsOrm;
|
|
21
|
+
private subscriptionItemsOrm;
|
|
22
|
+
private payTokenSecret;
|
|
23
|
+
private payTokenLifetimeMs;
|
|
24
|
+
private mailService;
|
|
25
|
+
private get config();
|
|
26
|
+
private get baseUrl();
|
|
27
|
+
constructor(opt: {
|
|
28
|
+
sqlService: ZSQLService;
|
|
29
|
+
mollieService: MollieService;
|
|
30
|
+
customerService: CustomerService;
|
|
31
|
+
mailService: ZMailService;
|
|
32
|
+
siteConfig: Omit<RenderData, 'context'>;
|
|
33
|
+
payTokenSecret: string;
|
|
34
|
+
});
|
|
35
|
+
autoInit(): Promise<void>;
|
|
36
|
+
private ensurePayTokenSchema;
|
|
37
|
+
private ensureSubscriptionInvoiceSchema;
|
|
38
|
+
private ensureSubsidyItemTypeSchema;
|
|
39
|
+
private ensureInvoicePaymentSchema;
|
|
40
|
+
private generateInvoiceNumber;
|
|
41
|
+
private getWebhookUrl;
|
|
42
|
+
private signPayTokenRaw;
|
|
43
|
+
private buildPayToken;
|
|
44
|
+
private parseSignedPayToken;
|
|
45
|
+
private verifySignedPayToken;
|
|
46
|
+
private hashPayTokenRaw;
|
|
47
|
+
private getInvoiceBundle;
|
|
48
|
+
private formatMoney;
|
|
49
|
+
private calcTotals;
|
|
50
|
+
private createPayTokenRaw;
|
|
51
|
+
private isInvoicePaid;
|
|
52
|
+
private isInvoiceFinalizedForPay;
|
|
53
|
+
private isTokenExpired;
|
|
54
|
+
createMolliePaymentForInvoice(
|
|
55
|
+
invoice: ZInvoice,
|
|
56
|
+
opt?: {
|
|
57
|
+
sequenceType?: 'oneoff' | 'first' | 'recurring';
|
|
58
|
+
mandateId?: string | null;
|
|
59
|
+
metadata?: Record<string, any>;
|
|
60
|
+
},
|
|
61
|
+
): Promise<import('@mollie/api-client/dist/types/data/payments/Payment').default>;
|
|
62
|
+
private issueOrRotatePayToken;
|
|
63
|
+
ensurePayLink(invoiceId: number): Promise<ZIssuedPayToken>;
|
|
64
|
+
resolvePayToken(token: string): Promise<ZPayResolveResult>;
|
|
65
|
+
listInvoices(): Promise<ZInvoice[]>;
|
|
66
|
+
getInvoiceById(invoiceId: number): Promise<ZInvoice | undefined>;
|
|
67
|
+
listPayments(invoice_id: number): Promise<ZInvoicePayment[]>;
|
|
68
|
+
createInvoiceWithPayment(input: CreateInvoiceInput): Promise<{
|
|
69
|
+
invoice: ZInvoice;
|
|
70
|
+
checkoutUrl: string;
|
|
71
|
+
payment: import('@mollie/api-client/dist/types/data/payments/Payment').default;
|
|
72
|
+
payUrl: string;
|
|
73
|
+
}>;
|
|
74
|
+
createInvoiceFromItems(
|
|
75
|
+
input: CreateInvoiceInput,
|
|
76
|
+
overrides?: CreateInvoiceOverrides,
|
|
77
|
+
): Promise<{
|
|
78
|
+
invoice: ZInvoice;
|
|
79
|
+
pay: ZIssuedPayToken;
|
|
80
|
+
}>;
|
|
81
|
+
createInvoiceDraft(input: CreateInvoiceInput): Promise<{
|
|
82
|
+
invoice: ZInvoice;
|
|
83
|
+
pay: ZIssuedPayToken;
|
|
84
|
+
}>;
|
|
85
|
+
syncPayment(paymentId: string): Promise<{
|
|
86
|
+
invoiceId: number;
|
|
87
|
+
status: 'failed' | 'canceled' | 'pending' | 'expired' | 'paid' | 'refunded';
|
|
88
|
+
}>;
|
|
89
|
+
generateInvoicePdfBuffer(invoiceId: number): Promise<Buffer>;
|
|
90
|
+
sendInvoiceEmail(
|
|
91
|
+
invoiceId: number,
|
|
92
|
+
recipient?: string,
|
|
93
|
+
opt?: {
|
|
94
|
+
mode?: 'invoice' | 'receipt';
|
|
95
|
+
},
|
|
96
|
+
): Promise<{
|
|
97
|
+
invoice_number: string;
|
|
98
|
+
recipient: string;
|
|
99
|
+
payUrl: string;
|
|
100
|
+
payTokenExpiresAt: string;
|
|
101
|
+
}>;
|
|
102
|
+
}
|