ztechno_core 0.0.128 → 0.0.129

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,
@@ -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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ztechno_core",
3
- "version": "0.0.128",
3
+ "version": "0.0.129",
4
4
  "description": "Core files for ztechno framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",