ztechno_core 0.0.128 → 0.0.130

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.
@@ -5,5 +5,6 @@ export declare class InvoiceItemsOrm extends ZOrm {
5
5
  constructor(opt: { sqlService: ZSQLService; alias?: string; hashSalt?: string });
6
6
  bulkInsert(items: ZInvoiceItem[]): Promise<void>;
7
7
  findByInvoice(invoice_id: number): Promise<ZInvoiceItem[]>;
8
+ deleteByInvoice(invoice_id: number): Promise<void>;
8
9
  createTable(): Promise<void>;
9
10
  }
@@ -50,6 +50,14 @@ class InvoiceItemsOrm extends orm_1.ZOrm {
50
50
  params: { invoice_id },
51
51
  });
52
52
  }
53
+ async deleteByInvoice(invoice_id) {
54
+ await this.sqlService.query(
55
+ /*SQL*/ `
56
+ DELETE FROM \`${this.alias}\` WHERE invoice_id=:invoice_id
57
+ `,
58
+ { invoice_id },
59
+ );
60
+ }
53
61
  async createTable() {
54
62
  await this.sqlService.query(/*SQL*/ `
55
63
  CREATE TABLE IF NOT EXISTS \`${this.alias}\` (
@@ -38,5 +38,16 @@ export declare class InvoicesOrm extends ZOrm {
38
38
  ): Promise<void>;
39
39
  finalizePayToken(id: number): Promise<void>;
40
40
  incrementTimesSent(id: number): Promise<void>;
41
+ updateMutableFields(
42
+ id: number,
43
+ fields: {
44
+ customer_id?: number;
45
+ mollie_customer_id?: string | null;
46
+ description?: string | null;
47
+ payment_terms?: string | null;
48
+ due_date?: string | null;
49
+ amount_due?: number;
50
+ },
51
+ ): Promise<void>;
41
52
  createTable(): Promise<void>;
42
53
  }
@@ -151,6 +151,37 @@ class InvoicesOrm extends orm_1.ZOrm {
151
151
  { id },
152
152
  );
153
153
  }
154
+ async updateMutableFields(id, fields) {
155
+ const sets = [];
156
+ const params = { id };
157
+ if (fields.customer_id !== undefined) {
158
+ sets.push('customer_id=:customer_id');
159
+ params.customer_id = fields.customer_id;
160
+ }
161
+ if (fields.mollie_customer_id !== undefined) {
162
+ sets.push('mollie_customer_id=:mollie_customer_id');
163
+ params.mollie_customer_id = fields.mollie_customer_id;
164
+ }
165
+ if (fields.description !== undefined) {
166
+ sets.push('description=:description');
167
+ params.description = fields.description;
168
+ }
169
+ if (fields.payment_terms !== undefined) {
170
+ sets.push('payment_terms=:payment_terms');
171
+ params.payment_terms = fields.payment_terms;
172
+ }
173
+ if (fields.due_date !== undefined) {
174
+ sets.push('due_date=:due_date');
175
+ params.due_date = fields.due_date;
176
+ }
177
+ if (fields.amount_due !== undefined) {
178
+ sets.push('amount_due=:amount_due');
179
+ params.amount_due = fields.amount_due;
180
+ }
181
+ if (sets.length === 0) return;
182
+ sets.push('updated_at=NOW()');
183
+ await this.sqlService.query(/*SQL*/ `UPDATE \`${this.alias}\` SET ${sets.join(', ')} WHERE id=:id`, params);
184
+ }
154
185
  async createTable() {
155
186
  await this.sqlService.query(/*SQL*/ `
156
187
  CREATE TABLE IF NOT EXISTS \`${this.alias}\` (
@@ -75,6 +75,12 @@ export declare class InvoiceService {
75
75
  getInvoiceById(invoiceId: number): Promise<ZInvoice | undefined>;
76
76
  listPayments(invoice_id: number): Promise<ZInvoicePayment[]>;
77
77
  getInvoiceItems(invoiceId: number): Promise<ZInvoiceItem[]>;
78
+ updateInvoice(
79
+ invoiceId: number,
80
+ input: Partial<Pick<CreateInvoiceInput, 'customer_id' | 'description' | 'payment_terms' | 'due_date'>> & {
81
+ items?: CreateInvoiceInput['items'];
82
+ },
83
+ ): Promise<ZInvoice>;
78
84
  archiveInvoice(invoiceId: number): Promise<ZInvoice>;
79
85
  duplicateInvoice(
80
86
  sourceInvoiceId: number,
@@ -93,12 +99,6 @@ export declare class InvoiceService {
93
99
  template: Partial<Omit<ZInvoiceItemTemplate, 'id' | 'created_at' | 'updated_at'>>,
94
100
  ): Promise<ZInvoiceItemTemplate>;
95
101
  deleteItemTemplate(id: number): Promise<void>;
96
- createInvoiceWithPayment(input: CreateInvoiceInput): Promise<{
97
- invoice: ZInvoice;
98
- checkoutUrl: string;
99
- payment: import('@mollie/api-client/dist/types/data/payments/Payment').default;
100
- payUrl: string;
101
- }>;
102
102
  createInvoiceFromItems(
103
103
  input: CreateInvoiceInput,
104
104
  overrides?: CreateInvoiceOverrides,
@@ -422,6 +422,38 @@ class InvoiceService {
422
422
  async getInvoiceItems(invoiceId) {
423
423
  return await this.itemsOrm.findByInvoice(invoiceId);
424
424
  }
425
+ async updateInvoice(invoiceId, input) {
426
+ const invoice = await this.invoicesOrm.findById(invoiceId);
427
+ if (!invoice) throw new Error(`Invoice ${invoiceId} not found`);
428
+ if (invoice.status !== 'draft')
429
+ throw new Error(`Invoice ${invoice.invoice_number} cannot be edited (status: ${invoice.status})`);
430
+ if ((invoice.times_sent ?? 0) > 0)
431
+ throw new Error(
432
+ `Invoice ${invoice.invoice_number} cannot be edited (already sent ${invoice.times_sent} time(s))`,
433
+ );
434
+ const updateFields = {};
435
+ if (input.customer_id !== undefined) {
436
+ const customer = await this.opt.customerService.findById(input.customer_id);
437
+ if (!customer) throw new Error(`Customer ${input.customer_id} not found`);
438
+ updateFields.customer_id = input.customer_id;
439
+ updateFields.mollie_customer_id = customer.mollie_customer_id ?? null;
440
+ }
441
+ if ('description' in input) updateFields.description = input.description ?? null;
442
+ if ('payment_terms' in input) updateFields.payment_terms = input.payment_terms ?? null;
443
+ if ('due_date' in input) updateFields.due_date = input.due_date ?? null;
444
+ if (input.items) {
445
+ const { items: calcedItems, amount_due } = this.calcTotals(input.items);
446
+ updateFields.amount_due = amount_due;
447
+ await this.invoicesOrm.updateMutableFields(invoiceId, updateFields);
448
+ await this.itemsOrm.deleteByInvoice(invoiceId);
449
+ await this.itemsOrm.bulkInsert(calcedItems.map((it) => ({ ...it, invoice_id: invoiceId })));
450
+ } else {
451
+ await this.invoicesOrm.updateMutableFields(invoiceId, updateFields);
452
+ }
453
+ const updated = await this.invoicesOrm.findById(invoiceId);
454
+ if (!updated) throw new Error(`Invoice ${invoiceId} not found after update`);
455
+ return updated;
456
+ }
425
457
  // ==================== Archive ====================
426
458
  async archiveInvoice(invoiceId) {
427
459
  const invoice = await this.invoicesOrm.findById(invoiceId);
@@ -470,6 +502,7 @@ class InvoiceService {
470
502
  async deleteItemTemplate(id) {
471
503
  await this.templateOrm.delete(id);
472
504
  }
505
+ /** @internal */
473
506
  async createInvoiceWithPayment(input) {
474
507
  const draft = await this.createInvoiceDraft(input);
475
508
  const payment = await this.createMolliePaymentForInvoice(draft.invoice);
@@ -492,7 +525,7 @@ class InvoiceService {
492
525
  const { items, amount_due } = this.calcTotals(input.items);
493
526
  const useIdMode = this.invoiceNumberMode === 'id';
494
527
  const invoice_number = useIdMode ? `PENDING-${crypto_1.default.randomUUID()}` : await this.generateInvoiceNumber();
495
- const status = overrides?.status ?? 'pending';
528
+ const status = overrides?.status ?? 'draft';
496
529
  const issuedAt = (0, orm_1.formatDatetime)(new Date());
497
530
  const paidAt = overrides?.paid_at ?? (status === 'paid' ? issuedAt : null);
498
531
  const amount_paid = overrides?.amount_paid ?? (status === 'paid' ? amount_due : 0);
@@ -18,6 +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' | 'archived';
21
22
  export type ZInvoiceItem = {
22
23
  id?: number;
23
24
  invoice_id: number;
@@ -53,7 +54,6 @@ export type CreateInvoiceOverrides = {
53
54
  mollie_payment_id?: string | null;
54
55
  checkout_url?: string | null;
55
56
  };
56
- export type ZInvoiceStatus = 'draft' | 'pending' | 'paid' | 'failed' | 'canceled' | 'expired' | 'refunded' | 'archived';
57
57
  export type ZInvoice = {
58
58
  id?: number;
59
59
  invoice_number: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ztechno_core",
3
- "version": "0.0.128",
3
+ "version": "0.0.130",
4
4
  "description": "Core files for ztechno framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",