@voyantjs/finance 0.52.1 → 0.52.3
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/dist/action-ledger-drift.d.ts +29 -0
- package/dist/action-ledger-drift.d.ts.map +1 -0
- package/dist/action-ledger-drift.js +163 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/routes-action-ledger.d.ts +181 -0
- package/dist/routes-action-ledger.d.ts.map +1 -0
- package/dist/routes-action-ledger.js +142 -0
- package/dist/routes-documents.d.ts +8 -8
- package/dist/routes-public.d.ts +48 -48
- package/dist/routes-settlement.d.ts +1 -1
- package/dist/routes-shared.d.ts +12 -0
- package/dist/routes-shared.d.ts.map +1 -1
- package/dist/routes.d.ts +288 -217
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +280 -46
- package/dist/schema.d.ts +22 -22
- package/dist/service-action-ledger-accounting.d.ts +77 -0
- package/dist/service-action-ledger-accounting.d.ts.map +1 -0
- package/dist/service-action-ledger-accounting.js +307 -0
- package/dist/service-action-ledger-booking-payments.d.ts +48 -0
- package/dist/service-action-ledger-booking-payments.d.ts.map +1 -0
- package/dist/service-action-ledger-booking-payments.js +178 -0
- package/dist/service-action-ledger-payment-authorizations.d.ts +48 -0
- package/dist/service-action-ledger-payment-authorizations.d.ts.map +1 -0
- package/dist/service-action-ledger-payment-authorizations.js +209 -0
- package/dist/service-action-ledger-payment-sessions.d.ts +83 -0
- package/dist/service-action-ledger-payment-sessions.d.ts.map +1 -0
- package/dist/service-action-ledger-payment-sessions.js +294 -0
- package/dist/service-action-ledger-supplier-payments.d.ts +21 -0
- package/dist/service-action-ledger-supplier-payments.d.ts.map +1 -0
- package/dist/service-action-ledger-supplier-payments.js +70 -0
- package/dist/service-action-ledger.d.ts +6 -0
- package/dist/service-action-ledger.d.ts.map +1 -0
- package/dist/service-action-ledger.js +5 -0
- package/dist/service-booking-create.d.ts +50 -8
- package/dist/service-booking-create.d.ts.map +1 -1
- package/dist/service-booking-create.js +58 -1
- package/dist/service-bookings-dual-create.d.ts +50 -8
- package/dist/service-bookings-dual-create.d.ts.map +1 -1
- package/dist/service-issue.d.ts +42 -12
- package/dist/service-issue.d.ts.map +1 -1
- package/dist/service-issue.js +141 -4
- package/dist/service-public.d.ts +13 -13
- package/dist/service-vouchers.d.ts +10 -10
- package/dist/service.d.ts +291 -279
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +753 -238
- package/dist/validation-billing.d.ts +37 -37
- package/dist/validation-payments.d.ts +102 -102
- package/dist/validation-public.d.ts +45 -45
- package/dist/validation-shared.d.ts +32 -32
- package/dist/validation-vouchers.d.ts +2 -2
- package/package.json +13 -7
package/dist/service.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { appendActionLedgerMutation, } from "@voyantjs/action-ledger";
|
|
1
2
|
import { bookingItems, bookings } from "@voyantjs/bookings/schema";
|
|
2
3
|
import { renderStructuredTemplate } from "@voyantjs/utils/template-renderer";
|
|
3
4
|
import { and, asc, desc, eq, gte, ilike, lte, ne, or, sql } from "drizzle-orm";
|
|
4
5
|
import { bookingGuarantees, bookingItemCommissions, bookingItemTaxLines, bookingPaymentSchedules, creditNoteLineItems, creditNotes, financeNotes, invoiceAttachments, invoiceExternalRefs, invoiceLineItems, invoiceNumberSeries, invoiceRenditions, invoices, invoiceTemplates, paymentAuthorizations, paymentCaptures, paymentInstruments, paymentSessions, payments, supplierPayments, taxClasses, taxPolicyProfiles, taxPolicyRules, taxRegimes, } from "./schema.js";
|
|
6
|
+
import { buildBookingGuaranteeCreateActionLedgerInput, buildBookingGuaranteeDeleteActionLedgerInput, buildBookingGuaranteeUpdateActionLedgerInput, buildBookingPaymentScheduleCreateActionLedgerInput, buildBookingPaymentScheduleDeleteActionLedgerInput, buildBookingPaymentScheduleUpdateActionLedgerInput, buildCreditNoteCreationActionLedgerInput, buildCreditNoteLineItemCreateActionLedgerInput, buildCreditNoteUpdateActionLedgerInput, buildInvoiceDeleteActionLedgerInput, buildInvoiceLineItemCreateActionLedgerInput, buildInvoiceLineItemDeleteActionLedgerInput, buildInvoiceLineItemUpdateActionLedgerInput, buildInvoiceUpdateActionLedgerInput, buildPaymentAuthorizationCreateActionLedgerInput, buildPaymentAuthorizationDeleteActionLedgerInput, buildPaymentAuthorizationUpdateActionLedgerInput, buildPaymentCaptureCreateActionLedgerInput, buildPaymentCaptureDeleteActionLedgerInput, buildPaymentCaptureUpdateActionLedgerInput, buildPaymentInstrumentCreateActionLedgerInput, buildPaymentInstrumentDeleteActionLedgerInput, buildPaymentInstrumentUpdateActionLedgerInput, buildPaymentSessionCancelledActionLedgerInput, buildPaymentSessionCompletionActionLedgerInput, buildPaymentSessionCreateActionLedgerInput, buildPaymentSessionExpiredActionLedgerInput, buildPaymentSessionFailedActionLedgerInput, buildPaymentSessionRequiresRedirectActionLedgerInput, buildPaymentSessionUpdateActionLedgerInput, buildRecordPaymentActionLedgerInput, buildSupplierPaymentCreateActionLedgerInput, buildSupplierPaymentUpdateActionLedgerInput, } from "./service-action-ledger.js";
|
|
5
7
|
import { getFinanceAggregates } from "./service-aggregates.js";
|
|
6
8
|
import { vouchersService } from "./service-vouchers.js";
|
|
9
|
+
export { buildBookingGuaranteeCreateActionLedgerInput, buildBookingGuaranteeDeleteActionLedgerInput, buildBookingGuaranteeUpdateActionLedgerInput, buildBookingPaymentScheduleCreateActionLedgerInput, buildBookingPaymentScheduleDeleteActionLedgerInput, buildBookingPaymentScheduleUpdateActionLedgerInput, buildCreditNoteCreationActionLedgerInput, buildCreditNoteLineItemCreateActionLedgerInput, buildCreditNoteUpdateActionLedgerInput, buildInvoiceDeleteActionLedgerInput, buildInvoiceIssuedActionLedgerInput, buildInvoiceLineItemCreateActionLedgerInput, buildInvoiceLineItemDeleteActionLedgerInput, buildInvoiceLineItemUpdateActionLedgerInput, buildInvoiceUpdateActionLedgerInput, buildPaymentAuthorizationCreateActionLedgerInput, buildPaymentAuthorizationDeleteActionLedgerInput, buildPaymentAuthorizationUpdateActionLedgerInput, buildPaymentCaptureCreateActionLedgerInput, buildPaymentCaptureDeleteActionLedgerInput, buildPaymentCaptureUpdateActionLedgerInput, buildPaymentInstrumentCreateActionLedgerInput, buildPaymentInstrumentDeleteActionLedgerInput, buildPaymentInstrumentUpdateActionLedgerInput, buildPaymentSessionCancelledActionLedgerInput, buildPaymentSessionCompletionActionLedgerInput, buildPaymentSessionCreateActionLedgerInput, buildPaymentSessionExpiredActionLedgerInput, buildPaymentSessionFailedActionLedgerInput, buildPaymentSessionRequiresRedirectActionLedgerInput, buildPaymentSessionUpdateActionLedgerInput, buildRecordPaymentActionLedgerInput, buildSupplierPaymentCreateActionLedgerInput, buildSupplierPaymentUpdateActionLedgerInput, } from "./service-action-ledger.js";
|
|
7
10
|
export class PaymentValidationError extends Error {
|
|
8
11
|
status = 400;
|
|
9
12
|
code = "invalid_request";
|
|
@@ -136,6 +139,24 @@ export function buildPaymentCompletedEvent(session) {
|
|
|
136
139
|
provider: session.provider,
|
|
137
140
|
};
|
|
138
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Normalize `db.execute(sql)` results across drizzle drivers.
|
|
144
|
+
* `drizzle-orm/postgres-js` returns rows directly (an array), while
|
|
145
|
+
* `drizzle-orm/node-postgres` (used by the operator template against a
|
|
146
|
+
* local pg server) and `drizzle-orm/neon-serverless` return pg's
|
|
147
|
+
* `QueryResult<T>` wrapper with `.rows`. Casting to `Array<T>` and
|
|
148
|
+
* calling `.map` blows up under the wrapper shape — surface the rows
|
|
149
|
+
* regardless of which driver is bound.
|
|
150
|
+
*/
|
|
151
|
+
function toRows(result) {
|
|
152
|
+
if (Array.isArray(result))
|
|
153
|
+
return result;
|
|
154
|
+
if (result && typeof result === "object" && "rows" in result) {
|
|
155
|
+
const rows = result.rows;
|
|
156
|
+
return Array.isArray(rows) ? rows : [];
|
|
157
|
+
}
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
139
160
|
function mapRawPayment(row) {
|
|
140
161
|
// Person display name: "First Last", trimmed. Falls back to null when both
|
|
141
162
|
// halves are missing so the UI can swap to organization or hide the field.
|
|
@@ -235,19 +256,59 @@ export const financeService = {
|
|
|
235
256
|
.limit(1);
|
|
236
257
|
return row ?? null;
|
|
237
258
|
},
|
|
238
|
-
async createPaymentInstrument(db, data) {
|
|
239
|
-
const
|
|
259
|
+
async createPaymentInstrument(db, data, runtime = {}) {
|
|
260
|
+
const createInstrument = (writer) => writer.insert(paymentInstruments).values(data).returning();
|
|
261
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
262
|
+
if (actionLedgerContext) {
|
|
263
|
+
const [row] = await db.transaction(async (tx) => {
|
|
264
|
+
const created = await createInstrument(tx);
|
|
265
|
+
if (created[0]) {
|
|
266
|
+
await appendActionLedgerMutation(tx, buildPaymentInstrumentCreateActionLedgerInput(actionLedgerContext, { instrument: created[0] }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
267
|
+
}
|
|
268
|
+
return created;
|
|
269
|
+
});
|
|
270
|
+
return row ?? null;
|
|
271
|
+
}
|
|
272
|
+
const [row] = await createInstrument(db);
|
|
240
273
|
return row ?? null;
|
|
241
274
|
},
|
|
242
|
-
async updatePaymentInstrument(db, id, data) {
|
|
243
|
-
const
|
|
275
|
+
async updatePaymentInstrument(db, id, data, runtime = {}) {
|
|
276
|
+
const updateInstrument = (writer) => writer
|
|
244
277
|
.update(paymentInstruments)
|
|
245
278
|
.set({ ...data, updatedAt: new Date() })
|
|
246
279
|
.where(eq(paymentInstruments.id, id))
|
|
247
280
|
.returning();
|
|
281
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
282
|
+
if (actionLedgerContext) {
|
|
283
|
+
const [row] = await db.transaction(async (tx) => {
|
|
284
|
+
const updated = await updateInstrument(tx);
|
|
285
|
+
if (updated[0]) {
|
|
286
|
+
await appendActionLedgerMutation(tx, buildPaymentInstrumentUpdateActionLedgerInput(actionLedgerContext, { instrument: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
287
|
+
}
|
|
288
|
+
return updated;
|
|
289
|
+
});
|
|
290
|
+
return row ?? null;
|
|
291
|
+
}
|
|
292
|
+
const [row] = await updateInstrument(db);
|
|
248
293
|
return row ?? null;
|
|
249
294
|
},
|
|
250
|
-
async deletePaymentInstrument(db, id) {
|
|
295
|
+
async deletePaymentInstrument(db, id, runtime = {}) {
|
|
296
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
297
|
+
if (actionLedgerContext) {
|
|
298
|
+
return db.transaction(async (tx) => {
|
|
299
|
+
const [existing] = await tx
|
|
300
|
+
.select()
|
|
301
|
+
.from(paymentInstruments)
|
|
302
|
+
.where(eq(paymentInstruments.id, id))
|
|
303
|
+
.limit(1);
|
|
304
|
+
if (!existing) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
await tx.delete(paymentInstruments).where(eq(paymentInstruments.id, id));
|
|
308
|
+
await appendActionLedgerMutation(tx, buildPaymentInstrumentDeleteActionLedgerInput(actionLedgerContext, { instrument: existing }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
309
|
+
return { id: existing.id };
|
|
310
|
+
});
|
|
311
|
+
}
|
|
251
312
|
const [row] = await db
|
|
252
313
|
.delete(paymentInstruments)
|
|
253
314
|
.where(eq(paymentInstruments.id, id))
|
|
@@ -302,7 +363,7 @@ export const financeService = {
|
|
|
302
363
|
const [row] = await db.select().from(paymentSessions).where(eq(paymentSessions.id, id)).limit(1);
|
|
303
364
|
return row ?? null;
|
|
304
365
|
},
|
|
305
|
-
async createPaymentSession(db, data) {
|
|
366
|
+
async createPaymentSession(db, data, runtime = {}) {
|
|
306
367
|
if (data.idempotencyKey) {
|
|
307
368
|
const [existing] = await db
|
|
308
369
|
.select()
|
|
@@ -314,7 +375,7 @@ export const financeService = {
|
|
|
314
375
|
}
|
|
315
376
|
}
|
|
316
377
|
const target = derivePaymentSessionTarget(data);
|
|
317
|
-
const
|
|
378
|
+
const createSession = (writer) => writer
|
|
318
379
|
.insert(paymentSessions)
|
|
319
380
|
.values({
|
|
320
381
|
...data,
|
|
@@ -330,11 +391,23 @@ export const financeService = {
|
|
|
330
391
|
expiresAt: toTimestamp(data.expiresAt),
|
|
331
392
|
})
|
|
332
393
|
.returning();
|
|
394
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
395
|
+
if (actionLedgerContext) {
|
|
396
|
+
const [row] = await db.transaction(async (tx) => {
|
|
397
|
+
const created = await createSession(tx);
|
|
398
|
+
if (created[0]) {
|
|
399
|
+
await appendActionLedgerMutation(tx, await buildPaymentSessionCreateActionLedgerInput(actionLedgerContext, { session: created[0] }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
400
|
+
}
|
|
401
|
+
return created;
|
|
402
|
+
});
|
|
403
|
+
return row ?? null;
|
|
404
|
+
}
|
|
405
|
+
const [row] = await createSession(db);
|
|
333
406
|
return row ?? null;
|
|
334
407
|
},
|
|
335
|
-
async updatePaymentSession(db, id, data) {
|
|
408
|
+
async updatePaymentSession(db, id, data, runtime = {}) {
|
|
336
409
|
const target = derivePaymentSessionTarget(data);
|
|
337
|
-
const
|
|
410
|
+
const updateSession = (writer) => writer
|
|
338
411
|
.update(paymentSessions)
|
|
339
412
|
.set({
|
|
340
413
|
...data,
|
|
@@ -354,10 +427,22 @@ export const financeService = {
|
|
|
354
427
|
})
|
|
355
428
|
.where(eq(paymentSessions.id, id))
|
|
356
429
|
.returning();
|
|
430
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
431
|
+
if (actionLedgerContext) {
|
|
432
|
+
const [row] = await db.transaction(async (tx) => {
|
|
433
|
+
const updated = await updateSession(tx);
|
|
434
|
+
if (updated[0]) {
|
|
435
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionUpdateActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
436
|
+
}
|
|
437
|
+
return updated;
|
|
438
|
+
});
|
|
439
|
+
return row ?? null;
|
|
440
|
+
}
|
|
441
|
+
const [row] = await updateSession(db);
|
|
357
442
|
return row ?? null;
|
|
358
443
|
},
|
|
359
|
-
async markPaymentSessionRequiresRedirect(db, id, data) {
|
|
360
|
-
const
|
|
444
|
+
async markPaymentSessionRequiresRedirect(db, id, data, runtime = {}) {
|
|
445
|
+
const markRequiresRedirect = (writer) => writer
|
|
361
446
|
.update(paymentSessions)
|
|
362
447
|
.set({
|
|
363
448
|
status: "requires_redirect",
|
|
@@ -377,10 +462,22 @@ export const financeService = {
|
|
|
377
462
|
})
|
|
378
463
|
.where(eq(paymentSessions.id, id))
|
|
379
464
|
.returning();
|
|
465
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
466
|
+
if (actionLedgerContext) {
|
|
467
|
+
const [row] = await db.transaction(async (tx) => {
|
|
468
|
+
const updated = await markRequiresRedirect(tx);
|
|
469
|
+
if (updated[0]) {
|
|
470
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionRequiresRedirectActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
471
|
+
}
|
|
472
|
+
return updated;
|
|
473
|
+
});
|
|
474
|
+
return row ?? null;
|
|
475
|
+
}
|
|
476
|
+
const [row] = await markRequiresRedirect(db);
|
|
380
477
|
return row ?? null;
|
|
381
478
|
},
|
|
382
|
-
async failPaymentSession(db, id, data) {
|
|
383
|
-
const
|
|
479
|
+
async failPaymentSession(db, id, data, runtime = {}) {
|
|
480
|
+
const failSession = (writer) => writer
|
|
384
481
|
.update(paymentSessions)
|
|
385
482
|
.set({
|
|
386
483
|
status: "failed",
|
|
@@ -397,10 +494,22 @@ export const financeService = {
|
|
|
397
494
|
})
|
|
398
495
|
.where(eq(paymentSessions.id, id))
|
|
399
496
|
.returning();
|
|
497
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
498
|
+
if (actionLedgerContext) {
|
|
499
|
+
const [row] = await db.transaction(async (tx) => {
|
|
500
|
+
const updated = await failSession(tx);
|
|
501
|
+
if (updated[0]) {
|
|
502
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionFailedActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
503
|
+
}
|
|
504
|
+
return updated;
|
|
505
|
+
});
|
|
506
|
+
return row ?? null;
|
|
507
|
+
}
|
|
508
|
+
const [row] = await failSession(db);
|
|
400
509
|
return row ?? null;
|
|
401
510
|
},
|
|
402
|
-
async cancelPaymentSession(db, id, data) {
|
|
403
|
-
const
|
|
511
|
+
async cancelPaymentSession(db, id, data, runtime = {}) {
|
|
512
|
+
const cancelSession = (writer) => writer
|
|
404
513
|
.update(paymentSessions)
|
|
405
514
|
.set({
|
|
406
515
|
status: "cancelled",
|
|
@@ -412,10 +521,22 @@ export const financeService = {
|
|
|
412
521
|
})
|
|
413
522
|
.where(eq(paymentSessions.id, id))
|
|
414
523
|
.returning();
|
|
524
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
525
|
+
if (actionLedgerContext) {
|
|
526
|
+
const [row] = await db.transaction(async (tx) => {
|
|
527
|
+
const updated = await cancelSession(tx);
|
|
528
|
+
if (updated[0]) {
|
|
529
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionCancelledActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
530
|
+
}
|
|
531
|
+
return updated;
|
|
532
|
+
});
|
|
533
|
+
return row ?? null;
|
|
534
|
+
}
|
|
535
|
+
const [row] = await cancelSession(db);
|
|
415
536
|
return row ?? null;
|
|
416
537
|
},
|
|
417
|
-
async expirePaymentSession(db, id, data) {
|
|
418
|
-
const
|
|
538
|
+
async expirePaymentSession(db, id, data, runtime = {}) {
|
|
539
|
+
const expireSession = (writer) => writer
|
|
419
540
|
.update(paymentSessions)
|
|
420
541
|
.set({
|
|
421
542
|
status: "expired",
|
|
@@ -427,6 +548,18 @@ export const financeService = {
|
|
|
427
548
|
})
|
|
428
549
|
.where(eq(paymentSessions.id, id))
|
|
429
550
|
.returning();
|
|
551
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
552
|
+
if (actionLedgerContext) {
|
|
553
|
+
const [row] = await db.transaction(async (tx) => {
|
|
554
|
+
const updated = await expireSession(tx);
|
|
555
|
+
if (updated[0]) {
|
|
556
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionExpiredActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
557
|
+
}
|
|
558
|
+
return updated;
|
|
559
|
+
});
|
|
560
|
+
return row ?? null;
|
|
561
|
+
}
|
|
562
|
+
const [row] = await expireSession(db);
|
|
430
563
|
return row ?? null;
|
|
431
564
|
},
|
|
432
565
|
async completePaymentSession(db, id, data, runtime = {}) {
|
|
@@ -610,6 +743,15 @@ export const financeService = {
|
|
|
610
743
|
})
|
|
611
744
|
.where(eq(paymentSessions.id, id))
|
|
612
745
|
.returning();
|
|
746
|
+
if (updated && runtime.actionLedgerContext) {
|
|
747
|
+
await appendActionLedgerMutation(tx, await buildPaymentSessionCompletionActionLedgerInput(runtime.actionLedgerContext, {
|
|
748
|
+
session: updated,
|
|
749
|
+
status: data.status,
|
|
750
|
+
paymentId,
|
|
751
|
+
}, {
|
|
752
|
+
authorizationSource: runtime.actionLedgerAuthorizationSource,
|
|
753
|
+
}));
|
|
754
|
+
}
|
|
613
755
|
return {
|
|
614
756
|
updated: updated ?? null,
|
|
615
757
|
settlement: settlementForEmit,
|
|
@@ -674,8 +816,8 @@ export const financeService = {
|
|
|
674
816
|
.limit(1);
|
|
675
817
|
return row ?? null;
|
|
676
818
|
},
|
|
677
|
-
async createPaymentAuthorization(db, data) {
|
|
678
|
-
const
|
|
819
|
+
async createPaymentAuthorization(db, data, runtime = {}) {
|
|
820
|
+
const createAuthorization = (writer) => writer
|
|
679
821
|
.insert(paymentAuthorizations)
|
|
680
822
|
.values({
|
|
681
823
|
...data,
|
|
@@ -684,10 +826,22 @@ export const financeService = {
|
|
|
684
826
|
voidedAt: toTimestamp(data.voidedAt),
|
|
685
827
|
})
|
|
686
828
|
.returning();
|
|
829
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
830
|
+
if (actionLedgerContext) {
|
|
831
|
+
const [row] = await db.transaction(async (tx) => {
|
|
832
|
+
const created = await createAuthorization(tx);
|
|
833
|
+
if (created[0]) {
|
|
834
|
+
await appendActionLedgerMutation(tx, await buildPaymentAuthorizationCreateActionLedgerInput(actionLedgerContext, { authorization: created[0] }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
835
|
+
}
|
|
836
|
+
return created;
|
|
837
|
+
});
|
|
838
|
+
return row ?? null;
|
|
839
|
+
}
|
|
840
|
+
const [row] = await createAuthorization(db);
|
|
687
841
|
return row ?? null;
|
|
688
842
|
},
|
|
689
|
-
async updatePaymentAuthorization(db, id, data) {
|
|
690
|
-
const
|
|
843
|
+
async updatePaymentAuthorization(db, id, data, runtime = {}) {
|
|
844
|
+
const updateAuthorization = (writer) => writer
|
|
691
845
|
.update(paymentAuthorizations)
|
|
692
846
|
.set({
|
|
693
847
|
...data,
|
|
@@ -698,9 +852,37 @@ export const financeService = {
|
|
|
698
852
|
})
|
|
699
853
|
.where(eq(paymentAuthorizations.id, id))
|
|
700
854
|
.returning();
|
|
855
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
856
|
+
if (actionLedgerContext) {
|
|
857
|
+
const [row] = await db.transaction(async (tx) => {
|
|
858
|
+
const updated = await updateAuthorization(tx);
|
|
859
|
+
if (updated[0]) {
|
|
860
|
+
await appendActionLedgerMutation(tx, buildPaymentAuthorizationUpdateActionLedgerInput(actionLedgerContext, { authorization: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
861
|
+
}
|
|
862
|
+
return updated;
|
|
863
|
+
});
|
|
864
|
+
return row ?? null;
|
|
865
|
+
}
|
|
866
|
+
const [row] = await updateAuthorization(db);
|
|
701
867
|
return row ?? null;
|
|
702
868
|
},
|
|
703
|
-
async deletePaymentAuthorization(db, id) {
|
|
869
|
+
async deletePaymentAuthorization(db, id, runtime = {}) {
|
|
870
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
871
|
+
if (actionLedgerContext) {
|
|
872
|
+
return db.transaction(async (tx) => {
|
|
873
|
+
const [existing] = await tx
|
|
874
|
+
.select()
|
|
875
|
+
.from(paymentAuthorizations)
|
|
876
|
+
.where(eq(paymentAuthorizations.id, id))
|
|
877
|
+
.limit(1);
|
|
878
|
+
if (!existing) {
|
|
879
|
+
return null;
|
|
880
|
+
}
|
|
881
|
+
await tx.delete(paymentAuthorizations).where(eq(paymentAuthorizations.id, id));
|
|
882
|
+
await appendActionLedgerMutation(tx, buildPaymentAuthorizationDeleteActionLedgerInput(actionLedgerContext, { authorization: existing }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
883
|
+
return { id: existing.id };
|
|
884
|
+
});
|
|
885
|
+
}
|
|
704
886
|
const [row] = await db
|
|
705
887
|
.delete(paymentAuthorizations)
|
|
706
888
|
.where(eq(paymentAuthorizations.id, id))
|
|
@@ -728,8 +910,8 @@ export const financeService = {
|
|
|
728
910
|
const [row] = await db.select().from(paymentCaptures).where(eq(paymentCaptures.id, id)).limit(1);
|
|
729
911
|
return row ?? null;
|
|
730
912
|
},
|
|
731
|
-
async createPaymentCapture(db, data) {
|
|
732
|
-
const
|
|
913
|
+
async createPaymentCapture(db, data, runtime = {}) {
|
|
914
|
+
const createCapture = (writer) => writer
|
|
733
915
|
.insert(paymentCaptures)
|
|
734
916
|
.values({
|
|
735
917
|
...data,
|
|
@@ -737,10 +919,22 @@ export const financeService = {
|
|
|
737
919
|
settledAt: toTimestamp(data.settledAt),
|
|
738
920
|
})
|
|
739
921
|
.returning();
|
|
922
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
923
|
+
if (actionLedgerContext) {
|
|
924
|
+
const [row] = await db.transaction(async (tx) => {
|
|
925
|
+
const created = await createCapture(tx);
|
|
926
|
+
if (created[0]) {
|
|
927
|
+
await appendActionLedgerMutation(tx, await buildPaymentCaptureCreateActionLedgerInput(actionLedgerContext, { capture: created[0] }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
928
|
+
}
|
|
929
|
+
return created;
|
|
930
|
+
});
|
|
931
|
+
return row ?? null;
|
|
932
|
+
}
|
|
933
|
+
const [row] = await createCapture(db);
|
|
740
934
|
return row ?? null;
|
|
741
935
|
},
|
|
742
|
-
async updatePaymentCapture(db, id, data) {
|
|
743
|
-
const
|
|
936
|
+
async updatePaymentCapture(db, id, data, runtime = {}) {
|
|
937
|
+
const updateCapture = (writer) => writer
|
|
744
938
|
.update(paymentCaptures)
|
|
745
939
|
.set({
|
|
746
940
|
...data,
|
|
@@ -750,9 +944,37 @@ export const financeService = {
|
|
|
750
944
|
})
|
|
751
945
|
.where(eq(paymentCaptures.id, id))
|
|
752
946
|
.returning();
|
|
947
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
948
|
+
if (actionLedgerContext) {
|
|
949
|
+
const [row] = await db.transaction(async (tx) => {
|
|
950
|
+
const updated = await updateCapture(tx);
|
|
951
|
+
if (updated[0]) {
|
|
952
|
+
await appendActionLedgerMutation(tx, buildPaymentCaptureUpdateActionLedgerInput(actionLedgerContext, { capture: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
953
|
+
}
|
|
954
|
+
return updated;
|
|
955
|
+
});
|
|
956
|
+
return row ?? null;
|
|
957
|
+
}
|
|
958
|
+
const [row] = await updateCapture(db);
|
|
753
959
|
return row ?? null;
|
|
754
960
|
},
|
|
755
|
-
async deletePaymentCapture(db, id) {
|
|
961
|
+
async deletePaymentCapture(db, id, runtime = {}) {
|
|
962
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
963
|
+
if (actionLedgerContext) {
|
|
964
|
+
return db.transaction(async (tx) => {
|
|
965
|
+
const [existing] = await tx
|
|
966
|
+
.select()
|
|
967
|
+
.from(paymentCaptures)
|
|
968
|
+
.where(eq(paymentCaptures.id, id))
|
|
969
|
+
.limit(1);
|
|
970
|
+
if (!existing) {
|
|
971
|
+
return null;
|
|
972
|
+
}
|
|
973
|
+
await tx.delete(paymentCaptures).where(eq(paymentCaptures.id, id));
|
|
974
|
+
await appendActionLedgerMutation(tx, buildPaymentCaptureDeleteActionLedgerInput(actionLedgerContext, { capture: existing }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
975
|
+
return { id: existing.id };
|
|
976
|
+
});
|
|
977
|
+
}
|
|
756
978
|
const [row] = await db
|
|
757
979
|
.delete(paymentCaptures)
|
|
758
980
|
.where(eq(paymentCaptures.id, id))
|
|
@@ -766,20 +988,33 @@ export const financeService = {
|
|
|
766
988
|
.where(eq(bookingPaymentSchedules.bookingId, bookingId))
|
|
767
989
|
.orderBy(asc(bookingPaymentSchedules.dueDate), asc(bookingPaymentSchedules.createdAt));
|
|
768
990
|
},
|
|
769
|
-
async createBookingPaymentSchedule(db, bookingId, data) {
|
|
770
|
-
const
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
991
|
+
async createBookingPaymentSchedule(db, bookingId, data, runtime = {}) {
|
|
992
|
+
const createSchedule = async (writer) => {
|
|
993
|
+
const [booking] = await writer
|
|
994
|
+
.select({ id: bookings.id })
|
|
995
|
+
.from(bookings)
|
|
996
|
+
.where(eq(bookings.id, bookingId))
|
|
997
|
+
.limit(1);
|
|
998
|
+
if (!booking) {
|
|
999
|
+
return null;
|
|
1000
|
+
}
|
|
1001
|
+
const [row] = await writer
|
|
1002
|
+
.insert(bookingPaymentSchedules)
|
|
1003
|
+
.values({ ...data, bookingId })
|
|
1004
|
+
.returning();
|
|
1005
|
+
return row ?? null;
|
|
1006
|
+
};
|
|
1007
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1008
|
+
if (actionLedgerContext) {
|
|
1009
|
+
return db.transaction(async (tx) => {
|
|
1010
|
+
const row = await createSchedule(tx);
|
|
1011
|
+
if (row) {
|
|
1012
|
+
await appendActionLedgerMutation(tx, buildBookingPaymentScheduleCreateActionLedgerInput(actionLedgerContext, { schedule: row }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1013
|
+
}
|
|
1014
|
+
return row;
|
|
1015
|
+
});
|
|
777
1016
|
}
|
|
778
|
-
|
|
779
|
-
.insert(bookingPaymentSchedules)
|
|
780
|
-
.values({ ...data, bookingId })
|
|
781
|
-
.returning();
|
|
782
|
-
return row ?? null;
|
|
1017
|
+
return createSchedule(db);
|
|
783
1018
|
},
|
|
784
1019
|
/**
|
|
785
1020
|
* Persist a payment schedule that was already computed elsewhere
|
|
@@ -831,116 +1066,183 @@ export const financeService = {
|
|
|
831
1066
|
});
|
|
832
1067
|
return db.insert(bookingPaymentSchedules).values(rows).returning();
|
|
833
1068
|
},
|
|
834
|
-
async applyDefaultBookingPaymentPlan(db, bookingId, data) {
|
|
835
|
-
const
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
}
|
|
873
|
-
scheduleRows
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
.values(scheduleRows.map((row) => ({
|
|
898
|
-
...row,
|
|
899
|
-
bookingId,
|
|
900
|
-
bookingItemId: row.bookingItemId ?? null,
|
|
901
|
-
notes: row.notes ?? null,
|
|
902
|
-
})))
|
|
903
|
-
.returning();
|
|
904
|
-
if (data.createGuarantee) {
|
|
905
|
-
const depositSchedule = createdSchedules.find((schedule) => schedule.scheduleType === "deposit");
|
|
906
|
-
if (depositSchedule) {
|
|
907
|
-
await db.insert(bookingGuarantees).values({
|
|
908
|
-
bookingId,
|
|
909
|
-
bookingPaymentScheduleId: depositSchedule.id,
|
|
1069
|
+
async applyDefaultBookingPaymentPlan(db, bookingId, data, runtime = {}) {
|
|
1070
|
+
const applyPlan = async (writer) => {
|
|
1071
|
+
const [booking] = await writer
|
|
1072
|
+
.select()
|
|
1073
|
+
.from(bookings)
|
|
1074
|
+
.where(eq(bookings.id, bookingId))
|
|
1075
|
+
.limit(1);
|
|
1076
|
+
if (!booking) {
|
|
1077
|
+
return null;
|
|
1078
|
+
}
|
|
1079
|
+
const totalAmountCents = booking.sellAmountCents ?? 0;
|
|
1080
|
+
if (totalAmountCents <= 0) {
|
|
1081
|
+
return {
|
|
1082
|
+
createdSchedules: [],
|
|
1083
|
+
deletedSchedules: [],
|
|
1084
|
+
createdGuarantee: null,
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
const today = startOfUtcDay(new Date());
|
|
1088
|
+
const depositDueDate = data.depositDueDate ? parseDateString(data.depositDueDate) : today;
|
|
1089
|
+
const startDate = booking.startDate ? parseDateString(booking.startDate) : null;
|
|
1090
|
+
const rawBalanceDueDate = startDate
|
|
1091
|
+
? new Date(startDate.getTime() - data.balanceDueDaysBeforeStart * 24 * 60 * 60 * 1000)
|
|
1092
|
+
: today;
|
|
1093
|
+
const balanceDueDate = rawBalanceDueDate < today ? today : rawBalanceDueDate;
|
|
1094
|
+
let depositAmountCents = 0;
|
|
1095
|
+
if (data.depositMode === "fixed_amount") {
|
|
1096
|
+
depositAmountCents = Math.min(totalAmountCents, data.depositValue);
|
|
1097
|
+
}
|
|
1098
|
+
else if (data.depositMode === "percentage") {
|
|
1099
|
+
depositAmountCents = Math.min(totalAmountCents, Math.round((totalAmountCents * data.depositValue) / 100));
|
|
1100
|
+
}
|
|
1101
|
+
const clearableScheduleWhere = and(eq(bookingPaymentSchedules.bookingId, bookingId), or(eq(bookingPaymentSchedules.status, "pending"), eq(bookingPaymentSchedules.status, "due")));
|
|
1102
|
+
const deletedSchedules = data.clearExistingPending
|
|
1103
|
+
? await writer.select().from(bookingPaymentSchedules).where(clearableScheduleWhere)
|
|
1104
|
+
: [];
|
|
1105
|
+
if (data.clearExistingPending) {
|
|
1106
|
+
await writer.delete(bookingPaymentSchedules).where(clearableScheduleWhere);
|
|
1107
|
+
}
|
|
1108
|
+
const scheduleRows = [];
|
|
1109
|
+
if (depositAmountCents > 0 && depositAmountCents < totalAmountCents) {
|
|
1110
|
+
scheduleRows.push({
|
|
1111
|
+
bookingItemId: null,
|
|
1112
|
+
scheduleType: "deposit",
|
|
1113
|
+
status: depositDueDate <= today ? "due" : "pending",
|
|
1114
|
+
dueDate: toDateString(depositDueDate),
|
|
1115
|
+
currency: booking.sellCurrency,
|
|
1116
|
+
amountCents: depositAmountCents,
|
|
1117
|
+
notes: data.notes ?? null,
|
|
1118
|
+
});
|
|
1119
|
+
scheduleRows.push({
|
|
1120
|
+
bookingItemId: null,
|
|
1121
|
+
scheduleType: "balance",
|
|
1122
|
+
status: balanceDueDate <= today ? "due" : "pending",
|
|
1123
|
+
dueDate: toDateString(balanceDueDate),
|
|
1124
|
+
currency: booking.sellCurrency,
|
|
1125
|
+
amountCents: Math.max(0, totalAmountCents - depositAmountCents),
|
|
1126
|
+
notes: data.notes ?? null,
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
else {
|
|
1130
|
+
const singleDueDate = balanceDueDate <= today ? today : balanceDueDate;
|
|
1131
|
+
scheduleRows.push({
|
|
910
1132
|
bookingItemId: null,
|
|
911
|
-
|
|
912
|
-
status: "pending",
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
amountCents: depositSchedule.amountCents,
|
|
917
|
-
provider: null,
|
|
918
|
-
referenceNumber: null,
|
|
919
|
-
guaranteedAt: null,
|
|
920
|
-
expiresAt: null,
|
|
921
|
-
releasedAt: null,
|
|
1133
|
+
scheduleType: "balance",
|
|
1134
|
+
status: singleDueDate <= today ? "due" : "pending",
|
|
1135
|
+
dueDate: toDateString(singleDueDate),
|
|
1136
|
+
currency: booking.sellCurrency,
|
|
1137
|
+
amountCents: totalAmountCents,
|
|
922
1138
|
notes: data.notes ?? null,
|
|
923
1139
|
});
|
|
924
1140
|
}
|
|
1141
|
+
const createdSchedules = await writer
|
|
1142
|
+
.insert(bookingPaymentSchedules)
|
|
1143
|
+
.values(scheduleRows.map((row) => ({
|
|
1144
|
+
...row,
|
|
1145
|
+
bookingId,
|
|
1146
|
+
bookingItemId: row.bookingItemId ?? null,
|
|
1147
|
+
notes: row.notes ?? null,
|
|
1148
|
+
})))
|
|
1149
|
+
.returning();
|
|
1150
|
+
let createdGuarantee = null;
|
|
1151
|
+
if (data.createGuarantee) {
|
|
1152
|
+
const depositSchedule = createdSchedules.find((schedule) => schedule.scheduleType === "deposit");
|
|
1153
|
+
if (depositSchedule) {
|
|
1154
|
+
const [guarantee] = await writer
|
|
1155
|
+
.insert(bookingGuarantees)
|
|
1156
|
+
.values({
|
|
1157
|
+
bookingId,
|
|
1158
|
+
bookingPaymentScheduleId: depositSchedule.id,
|
|
1159
|
+
bookingItemId: null,
|
|
1160
|
+
guaranteeType: data.guaranteeType,
|
|
1161
|
+
status: "pending",
|
|
1162
|
+
paymentInstrumentId: null,
|
|
1163
|
+
paymentAuthorizationId: null,
|
|
1164
|
+
currency: depositSchedule.currency,
|
|
1165
|
+
amountCents: depositSchedule.amountCents,
|
|
1166
|
+
provider: null,
|
|
1167
|
+
referenceNumber: null,
|
|
1168
|
+
guaranteedAt: null,
|
|
1169
|
+
expiresAt: null,
|
|
1170
|
+
releasedAt: null,
|
|
1171
|
+
notes: data.notes ?? null,
|
|
1172
|
+
})
|
|
1173
|
+
.returning();
|
|
1174
|
+
createdGuarantee = guarantee ?? null;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
return { createdSchedules, deletedSchedules, createdGuarantee };
|
|
1178
|
+
};
|
|
1179
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1180
|
+
if (actionLedgerContext) {
|
|
1181
|
+
const result = await db.transaction(async (tx) => {
|
|
1182
|
+
const applied = await applyPlan(tx);
|
|
1183
|
+
if (!applied) {
|
|
1184
|
+
return null;
|
|
1185
|
+
}
|
|
1186
|
+
for (const schedule of applied.deletedSchedules) {
|
|
1187
|
+
await appendActionLedgerMutation(tx, buildBookingPaymentScheduleDeleteActionLedgerInput(actionLedgerContext, { schedule }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1188
|
+
}
|
|
1189
|
+
for (const schedule of applied.createdSchedules) {
|
|
1190
|
+
await appendActionLedgerMutation(tx, buildBookingPaymentScheduleCreateActionLedgerInput(actionLedgerContext, { schedule }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1191
|
+
}
|
|
1192
|
+
if (applied.createdGuarantee) {
|
|
1193
|
+
await appendActionLedgerMutation(tx, await buildBookingGuaranteeCreateActionLedgerInput(actionLedgerContext, { guarantee: applied.createdGuarantee }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1194
|
+
}
|
|
1195
|
+
return applied.createdSchedules;
|
|
1196
|
+
});
|
|
1197
|
+
return result;
|
|
925
1198
|
}
|
|
926
|
-
|
|
1199
|
+
const result = await applyPlan(db);
|
|
1200
|
+
return result?.createdSchedules ?? null;
|
|
927
1201
|
},
|
|
928
|
-
async updateBookingPaymentSchedule(db, scheduleId, data) {
|
|
929
|
-
const
|
|
1202
|
+
async updateBookingPaymentSchedule(db, scheduleId, data, runtime = {}) {
|
|
1203
|
+
const updateSchedule = (writer) => writer
|
|
930
1204
|
.update(bookingPaymentSchedules)
|
|
931
1205
|
.set({ ...data, updatedAt: new Date() })
|
|
932
1206
|
.where(eq(bookingPaymentSchedules.id, scheduleId))
|
|
933
1207
|
.returning();
|
|
1208
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1209
|
+
if (actionLedgerContext) {
|
|
1210
|
+
const [row] = await db.transaction(async (tx) => {
|
|
1211
|
+
const updated = await updateSchedule(tx);
|
|
1212
|
+
if (updated[0]) {
|
|
1213
|
+
await appendActionLedgerMutation(tx, buildBookingPaymentScheduleUpdateActionLedgerInput(actionLedgerContext, { schedule: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1214
|
+
}
|
|
1215
|
+
return updated;
|
|
1216
|
+
});
|
|
1217
|
+
return row ?? null;
|
|
1218
|
+
}
|
|
1219
|
+
const [row] = await updateSchedule(db);
|
|
934
1220
|
return row ?? null;
|
|
935
1221
|
},
|
|
936
|
-
async deleteBookingPaymentSchedule(db, scheduleId) {
|
|
1222
|
+
async deleteBookingPaymentSchedule(db, scheduleId, runtime = {}) {
|
|
1223
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1224
|
+
if (actionLedgerContext) {
|
|
1225
|
+
return db.transaction(async (tx) => {
|
|
1226
|
+
const [existing] = await tx
|
|
1227
|
+
.select()
|
|
1228
|
+
.from(bookingPaymentSchedules)
|
|
1229
|
+
.where(eq(bookingPaymentSchedules.id, scheduleId))
|
|
1230
|
+
.limit(1);
|
|
1231
|
+
if (!existing) {
|
|
1232
|
+
return null;
|
|
1233
|
+
}
|
|
1234
|
+
await tx.delete(bookingPaymentSchedules).where(eq(bookingPaymentSchedules.id, scheduleId));
|
|
1235
|
+
await appendActionLedgerMutation(tx, buildBookingPaymentScheduleDeleteActionLedgerInput(actionLedgerContext, { schedule: existing }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1236
|
+
return { id: existing.id };
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
937
1239
|
const [row] = await db
|
|
938
1240
|
.delete(bookingPaymentSchedules)
|
|
939
1241
|
.where(eq(bookingPaymentSchedules.id, scheduleId))
|
|
940
1242
|
.returning({ id: bookingPaymentSchedules.id });
|
|
941
1243
|
return row ?? null;
|
|
942
1244
|
},
|
|
943
|
-
async createPaymentSessionFromBookingSchedule(db, scheduleId, data) {
|
|
1245
|
+
async createPaymentSessionFromBookingSchedule(db, scheduleId, data, runtime = {}) {
|
|
944
1246
|
const [schedule] = await db
|
|
945
1247
|
.select()
|
|
946
1248
|
.from(bookingPaymentSchedules)
|
|
@@ -981,9 +1283,9 @@ export const financeService = {
|
|
|
981
1283
|
scheduleType: schedule.scheduleType,
|
|
982
1284
|
dueDate: schedule.dueDate,
|
|
983
1285
|
},
|
|
984
|
-
});
|
|
1286
|
+
}, runtime);
|
|
985
1287
|
},
|
|
986
|
-
async createPaymentSessionFromInvoice(db, invoiceId, data) {
|
|
1288
|
+
async createPaymentSessionFromInvoice(db, invoiceId, data, runtime = {}) {
|
|
987
1289
|
const [invoice] = await db.select().from(invoices).where(eq(invoices.id, invoiceId)).limit(1);
|
|
988
1290
|
if (!invoice) {
|
|
989
1291
|
return null;
|
|
@@ -1022,7 +1324,7 @@ export const financeService = {
|
|
|
1022
1324
|
invoiceType: invoice.invoiceType,
|
|
1023
1325
|
dueDate: invoice.dueDate,
|
|
1024
1326
|
},
|
|
1025
|
-
});
|
|
1327
|
+
}, runtime);
|
|
1026
1328
|
},
|
|
1027
1329
|
listBookingGuarantees(db, bookingId) {
|
|
1028
1330
|
return db
|
|
@@ -1031,38 +1333,51 @@ export const financeService = {
|
|
|
1031
1333
|
.where(eq(bookingGuarantees.bookingId, bookingId))
|
|
1032
1334
|
.orderBy(desc(bookingGuarantees.createdAt));
|
|
1033
1335
|
},
|
|
1034
|
-
async createBookingGuarantee(db, bookingId, data) {
|
|
1035
|
-
const
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1336
|
+
async createBookingGuarantee(db, bookingId, data, runtime = {}) {
|
|
1337
|
+
const createGuarantee = async (writer) => {
|
|
1338
|
+
const [booking] = await writer
|
|
1339
|
+
.select({ id: bookings.id })
|
|
1340
|
+
.from(bookings)
|
|
1341
|
+
.where(eq(bookings.id, bookingId))
|
|
1342
|
+
.limit(1);
|
|
1343
|
+
if (!booking) {
|
|
1344
|
+
return null;
|
|
1345
|
+
}
|
|
1346
|
+
const [row] = await writer
|
|
1347
|
+
.insert(bookingGuarantees)
|
|
1348
|
+
.values({
|
|
1349
|
+
bookingId,
|
|
1350
|
+
bookingPaymentScheduleId: data.bookingPaymentScheduleId ?? null,
|
|
1351
|
+
bookingItemId: data.bookingItemId ?? null,
|
|
1352
|
+
guaranteeType: data.guaranteeType,
|
|
1353
|
+
status: data.status,
|
|
1354
|
+
paymentInstrumentId: data.paymentInstrumentId ?? null,
|
|
1355
|
+
paymentAuthorizationId: data.paymentAuthorizationId ?? null,
|
|
1356
|
+
currency: data.currency ?? null,
|
|
1357
|
+
amountCents: data.amountCents ?? null,
|
|
1358
|
+
provider: data.provider ?? null,
|
|
1359
|
+
referenceNumber: data.referenceNumber ?? null,
|
|
1360
|
+
guaranteedAt: toTimestamp(data.guaranteedAt),
|
|
1361
|
+
expiresAt: toTimestamp(data.expiresAt),
|
|
1362
|
+
releasedAt: toTimestamp(data.releasedAt),
|
|
1363
|
+
notes: data.notes ?? null,
|
|
1364
|
+
})
|
|
1365
|
+
.returning();
|
|
1366
|
+
return row ?? null;
|
|
1367
|
+
};
|
|
1368
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1369
|
+
if (actionLedgerContext) {
|
|
1370
|
+
return db.transaction(async (tx) => {
|
|
1371
|
+
const row = await createGuarantee(tx);
|
|
1372
|
+
if (row) {
|
|
1373
|
+
await appendActionLedgerMutation(tx, await buildBookingGuaranteeCreateActionLedgerInput(actionLedgerContext, { guarantee: row }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1374
|
+
}
|
|
1375
|
+
return row;
|
|
1376
|
+
});
|
|
1042
1377
|
}
|
|
1043
|
-
|
|
1044
|
-
.insert(bookingGuarantees)
|
|
1045
|
-
.values({
|
|
1046
|
-
bookingId,
|
|
1047
|
-
bookingPaymentScheduleId: data.bookingPaymentScheduleId ?? null,
|
|
1048
|
-
bookingItemId: data.bookingItemId ?? null,
|
|
1049
|
-
guaranteeType: data.guaranteeType,
|
|
1050
|
-
status: data.status,
|
|
1051
|
-
paymentInstrumentId: data.paymentInstrumentId ?? null,
|
|
1052
|
-
paymentAuthorizationId: data.paymentAuthorizationId ?? null,
|
|
1053
|
-
currency: data.currency ?? null,
|
|
1054
|
-
amountCents: data.amountCents ?? null,
|
|
1055
|
-
provider: data.provider ?? null,
|
|
1056
|
-
referenceNumber: data.referenceNumber ?? null,
|
|
1057
|
-
guaranteedAt: toTimestamp(data.guaranteedAt),
|
|
1058
|
-
expiresAt: toTimestamp(data.expiresAt),
|
|
1059
|
-
releasedAt: toTimestamp(data.releasedAt),
|
|
1060
|
-
notes: data.notes ?? null,
|
|
1061
|
-
})
|
|
1062
|
-
.returning();
|
|
1063
|
-
return row ?? null;
|
|
1378
|
+
return createGuarantee(db);
|
|
1064
1379
|
},
|
|
1065
|
-
async createPaymentSessionFromBookingGuarantee(db, guaranteeId, data) {
|
|
1380
|
+
async createPaymentSessionFromBookingGuarantee(db, guaranteeId, data, runtime = {}) {
|
|
1066
1381
|
const [guarantee] = await db
|
|
1067
1382
|
.select()
|
|
1068
1383
|
.from(bookingGuarantees)
|
|
@@ -1109,10 +1424,10 @@ export const financeService = {
|
|
|
1109
1424
|
metadata: data.metadata ?? {
|
|
1110
1425
|
guaranteeType: guarantee.guaranteeType,
|
|
1111
1426
|
},
|
|
1112
|
-
});
|
|
1427
|
+
}, runtime);
|
|
1113
1428
|
},
|
|
1114
|
-
async updateBookingGuarantee(db, guaranteeId, data) {
|
|
1115
|
-
const
|
|
1429
|
+
async updateBookingGuarantee(db, guaranteeId, data, runtime = {}) {
|
|
1430
|
+
const updateGuarantee = (writer) => writer
|
|
1116
1431
|
.update(bookingGuarantees)
|
|
1117
1432
|
.set({
|
|
1118
1433
|
...data,
|
|
@@ -1123,9 +1438,37 @@ export const financeService = {
|
|
|
1123
1438
|
})
|
|
1124
1439
|
.where(eq(bookingGuarantees.id, guaranteeId))
|
|
1125
1440
|
.returning();
|
|
1441
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1442
|
+
if (actionLedgerContext) {
|
|
1443
|
+
const [row] = await db.transaction(async (tx) => {
|
|
1444
|
+
const updated = await updateGuarantee(tx);
|
|
1445
|
+
if (updated[0]) {
|
|
1446
|
+
await appendActionLedgerMutation(tx, buildBookingGuaranteeUpdateActionLedgerInput(actionLedgerContext, { guarantee: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1447
|
+
}
|
|
1448
|
+
return updated;
|
|
1449
|
+
});
|
|
1450
|
+
return row ?? null;
|
|
1451
|
+
}
|
|
1452
|
+
const [row] = await updateGuarantee(db);
|
|
1126
1453
|
return row ?? null;
|
|
1127
1454
|
},
|
|
1128
|
-
async deleteBookingGuarantee(db, guaranteeId) {
|
|
1455
|
+
async deleteBookingGuarantee(db, guaranteeId, runtime = {}) {
|
|
1456
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1457
|
+
if (actionLedgerContext) {
|
|
1458
|
+
return db.transaction(async (tx) => {
|
|
1459
|
+
const [existing] = await tx
|
|
1460
|
+
.select()
|
|
1461
|
+
.from(bookingGuarantees)
|
|
1462
|
+
.where(eq(bookingGuarantees.id, guaranteeId))
|
|
1463
|
+
.limit(1);
|
|
1464
|
+
if (!existing) {
|
|
1465
|
+
return null;
|
|
1466
|
+
}
|
|
1467
|
+
await tx.delete(bookingGuarantees).where(eq(bookingGuarantees.id, guaranteeId));
|
|
1468
|
+
await appendActionLedgerMutation(tx, buildBookingGuaranteeDeleteActionLedgerInput(actionLedgerContext, { guarantee: existing }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1469
|
+
return { id: existing.id };
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1129
1472
|
const [row] = await db
|
|
1130
1473
|
.delete(bookingGuarantees)
|
|
1131
1474
|
.where(eq(bookingGuarantees.id, guaranteeId))
|
|
@@ -1311,19 +1654,43 @@ export const financeService = {
|
|
|
1311
1654
|
offset: query.offset,
|
|
1312
1655
|
};
|
|
1313
1656
|
},
|
|
1314
|
-
async createSupplierPayment(db, data) {
|
|
1315
|
-
const
|
|
1657
|
+
async createSupplierPayment(db, data, runtime = {}) {
|
|
1658
|
+
const createPayment = (writer) => writer
|
|
1316
1659
|
.insert(supplierPayments)
|
|
1317
1660
|
.values({ ...data, paymentInstrumentId: data.paymentInstrumentId ?? null })
|
|
1318
1661
|
.returning();
|
|
1662
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1663
|
+
if (actionLedgerContext) {
|
|
1664
|
+
const [row] = await db.transaction(async (tx) => {
|
|
1665
|
+
const created = await createPayment(tx);
|
|
1666
|
+
if (created[0]) {
|
|
1667
|
+
await appendActionLedgerMutation(tx, await buildSupplierPaymentCreateActionLedgerInput(actionLedgerContext, { payment: created[0] }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1668
|
+
}
|
|
1669
|
+
return created;
|
|
1670
|
+
});
|
|
1671
|
+
return row;
|
|
1672
|
+
}
|
|
1673
|
+
const [row] = await createPayment(db);
|
|
1319
1674
|
return row;
|
|
1320
1675
|
},
|
|
1321
|
-
async updateSupplierPayment(db, id, data) {
|
|
1322
|
-
const
|
|
1676
|
+
async updateSupplierPayment(db, id, data, runtime = {}) {
|
|
1677
|
+
const updatePayment = (writer) => writer
|
|
1323
1678
|
.update(supplierPayments)
|
|
1324
1679
|
.set({ ...data, updatedAt: new Date() })
|
|
1325
1680
|
.where(eq(supplierPayments.id, id))
|
|
1326
1681
|
.returning();
|
|
1682
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1683
|
+
if (actionLedgerContext) {
|
|
1684
|
+
const [row] = await db.transaction(async (tx) => {
|
|
1685
|
+
const updated = await updatePayment(tx);
|
|
1686
|
+
if (updated[0]) {
|
|
1687
|
+
await appendActionLedgerMutation(tx, buildSupplierPaymentUpdateActionLedgerInput(actionLedgerContext, { payment: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1688
|
+
}
|
|
1689
|
+
return updated;
|
|
1690
|
+
});
|
|
1691
|
+
return row ?? null;
|
|
1692
|
+
}
|
|
1693
|
+
const [row] = await updatePayment(db);
|
|
1327
1694
|
return row ?? null;
|
|
1328
1695
|
},
|
|
1329
1696
|
async listInvoices(db, query) {
|
|
@@ -1504,15 +1871,41 @@ export const financeService = {
|
|
|
1504
1871
|
const [row] = await db.select().from(invoices).where(eq(invoices.id, id)).limit(1);
|
|
1505
1872
|
return row ?? null;
|
|
1506
1873
|
},
|
|
1507
|
-
async updateInvoice(db, id, data) {
|
|
1508
|
-
const
|
|
1874
|
+
async updateInvoice(db, id, data, runtime = {}) {
|
|
1875
|
+
const updateInvoiceRow = (writer) => writer
|
|
1509
1876
|
.update(invoices)
|
|
1510
1877
|
.set({ ...data, updatedAt: new Date() })
|
|
1511
1878
|
.where(eq(invoices.id, id))
|
|
1512
1879
|
.returning();
|
|
1880
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1881
|
+
if (actionLedgerContext) {
|
|
1882
|
+
return db.transaction(async (tx) => {
|
|
1883
|
+
const [row] = await updateInvoiceRow(tx);
|
|
1884
|
+
if (row) {
|
|
1885
|
+
await appendActionLedgerMutation(tx, buildInvoiceUpdateActionLedgerInput(actionLedgerContext, { invoice: row, changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1886
|
+
}
|
|
1887
|
+
return row ?? null;
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
const [row] = await updateInvoiceRow(db);
|
|
1513
1891
|
return row ?? null;
|
|
1514
1892
|
},
|
|
1515
|
-
async deleteInvoice(db, id) {
|
|
1893
|
+
async deleteInvoice(db, id, runtime = {}) {
|
|
1894
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1895
|
+
if (actionLedgerContext) {
|
|
1896
|
+
return db.transaction(async (tx) => {
|
|
1897
|
+
const [existing] = await tx.select().from(invoices).where(eq(invoices.id, id)).limit(1);
|
|
1898
|
+
if (!existing) {
|
|
1899
|
+
return { status: "not_found" };
|
|
1900
|
+
}
|
|
1901
|
+
if (existing.status !== "draft") {
|
|
1902
|
+
return { status: "not_draft" };
|
|
1903
|
+
}
|
|
1904
|
+
await tx.delete(invoices).where(eq(invoices.id, id));
|
|
1905
|
+
await appendActionLedgerMutation(tx, buildInvoiceDeleteActionLedgerInput(actionLedgerContext, { invoice: existing }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1906
|
+
return { status: "deleted" };
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1516
1909
|
const [existing] = await db
|
|
1517
1910
|
.select({ id: invoices.id, status: invoices.status })
|
|
1518
1911
|
.from(invoices)
|
|
@@ -1534,35 +1927,97 @@ export const financeService = {
|
|
|
1534
1927
|
.where(eq(invoiceLineItems.invoiceId, invoiceId))
|
|
1535
1928
|
.orderBy(asc(invoiceLineItems.sortOrder));
|
|
1536
1929
|
},
|
|
1537
|
-
async createInvoiceLineItem(db, invoiceId, data) {
|
|
1538
|
-
const
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1930
|
+
async createInvoiceLineItem(db, invoiceId, data, runtime = {}) {
|
|
1931
|
+
const createLineItem = async (writer) => {
|
|
1932
|
+
const [invoice] = await writer
|
|
1933
|
+
.select()
|
|
1934
|
+
.from(invoices)
|
|
1935
|
+
.where(eq(invoices.id, invoiceId))
|
|
1936
|
+
.limit(1);
|
|
1937
|
+
if (!invoice) {
|
|
1938
|
+
return null;
|
|
1939
|
+
}
|
|
1940
|
+
const [row] = await writer
|
|
1941
|
+
.insert(invoiceLineItems)
|
|
1942
|
+
.values({ ...data, invoiceId })
|
|
1943
|
+
.returning();
|
|
1944
|
+
return row ? { invoice, lineItem: row } : null;
|
|
1945
|
+
};
|
|
1946
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1947
|
+
if (actionLedgerContext) {
|
|
1948
|
+
const result = await db.transaction(async (tx) => {
|
|
1949
|
+
const created = await createLineItem(tx);
|
|
1950
|
+
if (created) {
|
|
1951
|
+
await appendActionLedgerMutation(tx, buildInvoiceLineItemCreateActionLedgerInput(actionLedgerContext, created, {
|
|
1952
|
+
authorizationSource: runtime.actionLedgerAuthorizationSource,
|
|
1953
|
+
}));
|
|
1954
|
+
}
|
|
1955
|
+
return created;
|
|
1956
|
+
});
|
|
1957
|
+
return result?.lineItem ?? null;
|
|
1545
1958
|
}
|
|
1546
|
-
|
|
1547
|
-
.insert(invoiceLineItems)
|
|
1548
|
-
.values({ ...data, invoiceId })
|
|
1549
|
-
.returning();
|
|
1550
|
-
return row;
|
|
1959
|
+
return (await createLineItem(db))?.lineItem ?? null;
|
|
1551
1960
|
},
|
|
1552
|
-
async updateInvoiceLineItem(db, lineId, data) {
|
|
1553
|
-
const
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1961
|
+
async updateInvoiceLineItem(db, lineId, data, runtime = {}) {
|
|
1962
|
+
const updateLineItem = async (writer) => {
|
|
1963
|
+
const [row] = await writer
|
|
1964
|
+
.update(invoiceLineItems)
|
|
1965
|
+
.set(data)
|
|
1966
|
+
.where(eq(invoiceLineItems.id, lineId))
|
|
1967
|
+
.returning();
|
|
1968
|
+
if (!row) {
|
|
1969
|
+
return null;
|
|
1970
|
+
}
|
|
1971
|
+
const [invoice] = await writer
|
|
1972
|
+
.select()
|
|
1973
|
+
.from(invoices)
|
|
1974
|
+
.where(eq(invoices.id, row.invoiceId))
|
|
1975
|
+
.limit(1);
|
|
1976
|
+
return invoice ? { invoice, lineItem: row } : null;
|
|
1977
|
+
};
|
|
1978
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
1979
|
+
if (actionLedgerContext) {
|
|
1980
|
+
const result = await db.transaction(async (tx) => {
|
|
1981
|
+
const updated = await updateLineItem(tx);
|
|
1982
|
+
if (updated) {
|
|
1983
|
+
await appendActionLedgerMutation(tx, buildInvoiceLineItemUpdateActionLedgerInput(actionLedgerContext, { ...updated, changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
1984
|
+
}
|
|
1985
|
+
return updated;
|
|
1986
|
+
});
|
|
1987
|
+
return result?.lineItem ?? null;
|
|
1988
|
+
}
|
|
1989
|
+
return (await updateLineItem(db))?.lineItem ?? null;
|
|
1559
1990
|
},
|
|
1560
|
-
async deleteInvoiceLineItem(db, lineId) {
|
|
1561
|
-
const
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1991
|
+
async deleteInvoiceLineItem(db, lineId, runtime = {}) {
|
|
1992
|
+
const deleteLineItem = async (writer) => {
|
|
1993
|
+
const [row] = await writer
|
|
1994
|
+
.delete(invoiceLineItems)
|
|
1995
|
+
.where(eq(invoiceLineItems.id, lineId))
|
|
1996
|
+
.returning();
|
|
1997
|
+
if (!row) {
|
|
1998
|
+
return null;
|
|
1999
|
+
}
|
|
2000
|
+
const [invoice] = await writer
|
|
2001
|
+
.select()
|
|
2002
|
+
.from(invoices)
|
|
2003
|
+
.where(eq(invoices.id, row.invoiceId))
|
|
2004
|
+
.limit(1);
|
|
2005
|
+
return invoice ? { invoice, lineItem: row } : null;
|
|
2006
|
+
};
|
|
2007
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
2008
|
+
if (actionLedgerContext) {
|
|
2009
|
+
const result = await db.transaction(async (tx) => {
|
|
2010
|
+
const deleted = await deleteLineItem(tx);
|
|
2011
|
+
if (deleted) {
|
|
2012
|
+
await appendActionLedgerMutation(tx, buildInvoiceLineItemDeleteActionLedgerInput(actionLedgerContext, deleted, {
|
|
2013
|
+
authorizationSource: runtime.actionLedgerAuthorizationSource,
|
|
2014
|
+
}));
|
|
2015
|
+
}
|
|
2016
|
+
return deleted;
|
|
2017
|
+
});
|
|
2018
|
+
return result?.lineItem ?? null;
|
|
2019
|
+
}
|
|
2020
|
+
return (await deleteLineItem(db))?.lineItem ?? null;
|
|
1566
2021
|
},
|
|
1567
2022
|
listPayments(db, invoiceId) {
|
|
1568
2023
|
return db
|
|
@@ -1708,8 +2163,8 @@ export const financeService = {
|
|
|
1708
2163
|
const countResult = await db.execute(sql `
|
|
1709
2164
|
SELECT COUNT(*)::int AS count FROM (${unioned}) all_payments
|
|
1710
2165
|
`);
|
|
1711
|
-
const rows = dataResult;
|
|
1712
|
-
const total = countResult[0]?.count ?? 0;
|
|
2166
|
+
const rows = toRows(dataResult);
|
|
2167
|
+
const total = toRows(countResult)[0]?.count ?? 0;
|
|
1713
2168
|
const data = rows.map(mapRawPayment);
|
|
1714
2169
|
return {
|
|
1715
2170
|
data,
|
|
@@ -1758,7 +2213,7 @@ export const financeService = {
|
|
|
1758
2213
|
WHERE sp.id = ${id}
|
|
1759
2214
|
LIMIT 1
|
|
1760
2215
|
`);
|
|
1761
|
-
const row = result[0];
|
|
2216
|
+
const row = toRows(result)[0];
|
|
1762
2217
|
return row ? mapRawPayment(row) : null;
|
|
1763
2218
|
}
|
|
1764
2219
|
const result = await db.execute(sql `
|
|
@@ -1794,10 +2249,10 @@ export const financeService = {
|
|
|
1794
2249
|
WHERE p.id = ${id}
|
|
1795
2250
|
LIMIT 1
|
|
1796
2251
|
`);
|
|
1797
|
-
const row = result[0];
|
|
2252
|
+
const row = toRows(result)[0];
|
|
1798
2253
|
return row ? mapRawPayment(row) : null;
|
|
1799
2254
|
},
|
|
1800
|
-
async createPayment(db, invoiceId, data) {
|
|
2255
|
+
async createPayment(db, invoiceId, data, runtime = {}) {
|
|
1801
2256
|
const [invoice] = await db.select().from(invoices).where(eq(invoices.id, invoiceId)).limit(1);
|
|
1802
2257
|
if (!invoice) {
|
|
1803
2258
|
return null;
|
|
@@ -1831,6 +2286,14 @@ export const financeService = {
|
|
|
1831
2286
|
.update(invoices)
|
|
1832
2287
|
.set({ paidCents, balanceDueCents, status: newStatus, updatedAt: new Date() })
|
|
1833
2288
|
.where(eq(invoices.id, invoiceId));
|
|
2289
|
+
if (payment && runtime.actionLedgerContext) {
|
|
2290
|
+
await appendActionLedgerMutation(tx, await buildRecordPaymentActionLedgerInput(runtime.actionLedgerContext, {
|
|
2291
|
+
invoice,
|
|
2292
|
+
payment,
|
|
2293
|
+
}, {
|
|
2294
|
+
authorizationSource: runtime.actionLedgerAuthorizationSource,
|
|
2295
|
+
}));
|
|
2296
|
+
}
|
|
1834
2297
|
return payment;
|
|
1835
2298
|
});
|
|
1836
2299
|
},
|
|
@@ -1841,28 +2304,56 @@ export const financeService = {
|
|
|
1841
2304
|
.where(eq(creditNotes.invoiceId, invoiceId))
|
|
1842
2305
|
.orderBy(desc(creditNotes.createdAt));
|
|
1843
2306
|
},
|
|
1844
|
-
async createCreditNote(db, invoiceId, data) {
|
|
1845
|
-
const [invoice] = await db
|
|
1846
|
-
.select({ id: invoices.id })
|
|
1847
|
-
.from(invoices)
|
|
1848
|
-
.where(eq(invoices.id, invoiceId))
|
|
1849
|
-
.limit(1);
|
|
2307
|
+
async createCreditNote(db, invoiceId, data, runtime = {}) {
|
|
2308
|
+
const [invoice] = await db.select().from(invoices).where(eq(invoices.id, invoiceId)).limit(1);
|
|
1850
2309
|
if (!invoice) {
|
|
1851
2310
|
return null;
|
|
1852
2311
|
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
2312
|
+
return db.transaction(async (tx) => {
|
|
2313
|
+
const [row] = await tx
|
|
2314
|
+
.insert(creditNotes)
|
|
2315
|
+
.values({ ...data, invoiceId })
|
|
2316
|
+
.returning();
|
|
2317
|
+
if (row && runtime.actionLedgerContext) {
|
|
2318
|
+
await appendActionLedgerMutation(tx, await buildCreditNoteCreationActionLedgerInput(runtime.actionLedgerContext, {
|
|
2319
|
+
invoice,
|
|
2320
|
+
creditNote: row,
|
|
2321
|
+
}, {
|
|
2322
|
+
authorizationSource: runtime.actionLedgerAuthorizationSource,
|
|
2323
|
+
}));
|
|
2324
|
+
}
|
|
2325
|
+
return row;
|
|
2326
|
+
});
|
|
1858
2327
|
},
|
|
1859
|
-
async updateCreditNote(db, creditNoteId, data) {
|
|
1860
|
-
const
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
2328
|
+
async updateCreditNote(db, creditNoteId, data, runtime = {}) {
|
|
2329
|
+
const updateCreditNoteRow = async (writer) => {
|
|
2330
|
+
const [row] = await writer
|
|
2331
|
+
.update(creditNotes)
|
|
2332
|
+
.set({ ...data, updatedAt: new Date() })
|
|
2333
|
+
.where(eq(creditNotes.id, creditNoteId))
|
|
2334
|
+
.returning();
|
|
2335
|
+
if (!row) {
|
|
2336
|
+
return null;
|
|
2337
|
+
}
|
|
2338
|
+
const [invoice] = await writer
|
|
2339
|
+
.select()
|
|
2340
|
+
.from(invoices)
|
|
2341
|
+
.where(eq(invoices.id, row.invoiceId))
|
|
2342
|
+
.limit(1);
|
|
2343
|
+
return invoice ? { invoice, creditNote: row } : null;
|
|
2344
|
+
};
|
|
2345
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
2346
|
+
if (actionLedgerContext) {
|
|
2347
|
+
const result = await db.transaction(async (tx) => {
|
|
2348
|
+
const updated = await updateCreditNoteRow(tx);
|
|
2349
|
+
if (updated) {
|
|
2350
|
+
await appendActionLedgerMutation(tx, buildCreditNoteUpdateActionLedgerInput(actionLedgerContext, { ...updated, changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
2351
|
+
}
|
|
2352
|
+
return updated;
|
|
2353
|
+
});
|
|
2354
|
+
return result?.creditNote ?? null;
|
|
2355
|
+
}
|
|
2356
|
+
return (await updateCreditNoteRow(db))?.creditNote ?? null;
|
|
1866
2357
|
},
|
|
1867
2358
|
listCreditNoteLineItems(db, creditNoteId) {
|
|
1868
2359
|
return db
|
|
@@ -1871,20 +2362,44 @@ export const financeService = {
|
|
|
1871
2362
|
.where(eq(creditNoteLineItems.creditNoteId, creditNoteId))
|
|
1872
2363
|
.orderBy(asc(creditNoteLineItems.sortOrder));
|
|
1873
2364
|
},
|
|
1874
|
-
async createCreditNoteLineItem(db, creditNoteId, data) {
|
|
1875
|
-
const
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
2365
|
+
async createCreditNoteLineItem(db, creditNoteId, data, runtime = {}) {
|
|
2366
|
+
const createLineItem = async (writer) => {
|
|
2367
|
+
const [creditNote] = await writer
|
|
2368
|
+
.select()
|
|
2369
|
+
.from(creditNotes)
|
|
2370
|
+
.where(eq(creditNotes.id, creditNoteId))
|
|
2371
|
+
.limit(1);
|
|
2372
|
+
if (!creditNote) {
|
|
2373
|
+
return null;
|
|
2374
|
+
}
|
|
2375
|
+
const [invoice] = await writer
|
|
2376
|
+
.select()
|
|
2377
|
+
.from(invoices)
|
|
2378
|
+
.where(eq(invoices.id, creditNote.invoiceId))
|
|
2379
|
+
.limit(1);
|
|
2380
|
+
if (!invoice) {
|
|
2381
|
+
return null;
|
|
2382
|
+
}
|
|
2383
|
+
const [row] = await writer
|
|
2384
|
+
.insert(creditNoteLineItems)
|
|
2385
|
+
.values({ ...data, creditNoteId })
|
|
2386
|
+
.returning();
|
|
2387
|
+
return row ? { invoice, creditNote, lineItem: row } : null;
|
|
2388
|
+
};
|
|
2389
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
2390
|
+
if (actionLedgerContext) {
|
|
2391
|
+
const result = await db.transaction(async (tx) => {
|
|
2392
|
+
const created = await createLineItem(tx);
|
|
2393
|
+
if (created) {
|
|
2394
|
+
await appendActionLedgerMutation(tx, buildCreditNoteLineItemCreateActionLedgerInput(actionLedgerContext, created, {
|
|
2395
|
+
authorizationSource: runtime.actionLedgerAuthorizationSource,
|
|
2396
|
+
}));
|
|
2397
|
+
}
|
|
2398
|
+
return created;
|
|
2399
|
+
});
|
|
2400
|
+
return result?.lineItem ?? null;
|
|
1882
2401
|
}
|
|
1883
|
-
|
|
1884
|
-
.insert(creditNoteLineItems)
|
|
1885
|
-
.values({ ...data, creditNoteId })
|
|
1886
|
-
.returning();
|
|
1887
|
-
return row;
|
|
2402
|
+
return (await createLineItem(db))?.lineItem ?? null;
|
|
1888
2403
|
},
|
|
1889
2404
|
listNotes(db, invoiceId) {
|
|
1890
2405
|
return db
|