@voyant-travel/finance 0.119.5
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/LICENSE +201 -0
- package/README.md +192 -0
- 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 +166 -0
- package/dist/booking-tax.d.ts +124 -0
- package/dist/booking-tax.d.ts.map +1 -0
- package/dist/booking-tax.js +264 -0
- package/dist/checkout-routes.d.ts +1154 -0
- package/dist/checkout-routes.d.ts.map +1 -0
- package/dist/checkout-routes.js +116 -0
- package/dist/checkout-service-plan.d.ts +137 -0
- package/dist/checkout-service-plan.d.ts.map +1 -0
- package/dist/checkout-service-plan.js +119 -0
- package/dist/checkout-service.d.ts +9 -0
- package/dist/checkout-service.d.ts.map +1 -0
- package/dist/checkout-service.js +324 -0
- package/dist/checkout-validation.d.ts +1682 -0
- package/dist/checkout-validation.d.ts.map +1 -0
- package/dist/checkout-validation.js +228 -0
- package/dist/document-download.d.ts +3 -0
- package/dist/document-download.d.ts.map +1 -0
- package/dist/document-download.js +1 -0
- package/dist/fx-money.d.ts +17 -0
- package/dist/fx-money.d.ts.map +1 -0
- package/dist/fx-money.js +194 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/invoice-fx.d.ts +134 -0
- package/dist/invoice-fx.d.ts.map +1 -0
- package/dist/invoice-fx.js +240 -0
- package/dist/invoice-number-errors.d.ts +2 -0
- package/dist/invoice-number-errors.d.ts.map +1 -0
- package/dist/invoice-number-errors.js +58 -0
- package/dist/markets-ref.d.ts +149 -0
- package/dist/markets-ref.d.ts.map +1 -0
- package/dist/markets-ref.js +17 -0
- package/dist/payment-link.d.ts +23 -0
- package/dist/payment-link.d.ts.map +1 -0
- package/dist/payment-link.js +30 -0
- package/dist/payment-policy.d.ts +113 -0
- package/dist/payment-policy.d.ts.map +1 -0
- package/dist/payment-policy.js +193 -0
- package/dist/route-runtime.d.ts +22 -0
- package/dist/route-runtime.d.ts.map +1 -0
- package/dist/route-runtime.js +18 -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-booking-billing.d.ts +852 -0
- package/dist/routes-booking-billing.d.ts.map +1 -0
- package/dist/routes-booking-billing.js +223 -0
- package/dist/routes-booking-create.d.ts +3 -0
- package/dist/routes-booking-create.d.ts.map +1 -0
- package/dist/routes-booking-create.js +194 -0
- package/dist/routes-booking-reads.d.ts +46 -0
- package/dist/routes-booking-reads.d.ts.map +1 -0
- package/dist/routes-booking-reads.js +20 -0
- package/dist/routes-documents.d.ts +195 -0
- package/dist/routes-documents.d.ts.map +1 -0
- package/dist/routes-documents.js +93 -0
- package/dist/routes-invoice-core.d.ts +794 -0
- package/dist/routes-invoice-core.d.ts.map +1 -0
- package/dist/routes-invoice-core.js +238 -0
- package/dist/routes-invoice-documents.d.ts +401 -0
- package/dist/routes-invoice-documents.d.ts.map +1 -0
- package/dist/routes-invoice-documents.js +91 -0
- package/dist/routes-invoice-issue.d.ts +384 -0
- package/dist/routes-invoice-issue.d.ts.map +1 -0
- package/dist/routes-invoice-issue.js +208 -0
- package/dist/routes-payment-processing.d.ts +1193 -0
- package/dist/routes-payment-processing.d.ts.map +1 -0
- package/dist/routes-payment-processing.js +238 -0
- package/dist/routes-payments.d.ts +309 -0
- package/dist/routes-payments.d.ts.map +1 -0
- package/dist/routes-payments.js +94 -0
- package/dist/routes-public.d.ts +1948 -0
- package/dist/routes-public.d.ts.map +1 -0
- package/dist/routes-public.js +275 -0
- package/dist/routes-reference-data.d.ts +977 -0
- package/dist/routes-reference-data.d.ts.map +1 -0
- package/dist/routes-reference-data.js +191 -0
- package/dist/routes-reports.d.ts +344 -0
- package/dist/routes-reports.d.ts.map +1 -0
- package/dist/routes-reports.js +93 -0
- package/dist/routes-runtime.d.ts +71 -0
- package/dist/routes-runtime.d.ts.map +1 -0
- package/dist/routes-runtime.js +59 -0
- package/dist/routes-settlement.d.ts +67 -0
- package/dist/routes-settlement.d.ts.map +1 -0
- package/dist/routes-settlement.js +23 -0
- package/dist/routes-shared.d.ts +35 -0
- package/dist/routes-shared.d.ts.map +1 -0
- package/dist/routes-shared.js +10 -0
- package/dist/routes-supplier-invoices.d.ts +778 -0
- package/dist/routes-supplier-invoices.d.ts.map +1 -0
- package/dist/routes-supplier-invoices.js +159 -0
- package/dist/routes-vouchers.d.ts +228 -0
- package/dist/routes-vouchers.d.ts.map +1 -0
- package/dist/routes-vouchers.js +54 -0
- package/dist/routes.d.ts +5577 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +44 -0
- package/dist/schema/booking-billing.d.ts +1006 -0
- package/dist/schema/booking-billing.d.ts.map +1 -0
- package/dist/schema/booking-billing.js +106 -0
- package/dist/schema/enums.d.ts +48 -0
- package/dist/schema/enums.d.ts.map +1 -0
- package/dist/schema/enums.js +237 -0
- package/dist/schema/invoice-documents.d.ts +1245 -0
- package/dist/schema/invoice-documents.d.ts.map +1 -0
- package/dist/schema/invoice-documents.js +140 -0
- package/dist/schema/payment-instruments.d.ts +418 -0
- package/dist/schema/payment-instruments.d.ts.map +1 -0
- package/dist/schema/payment-instruments.js +45 -0
- package/dist/schema/payment-processing.d.ts +563 -0
- package/dist/schema/payment-processing.d.ts.map +1 -0
- package/dist/schema/payment-processing.js +65 -0
- package/dist/schema/payment-sessions.d.ts +728 -0
- package/dist/schema/payment-sessions.d.ts.map +1 -0
- package/dist/schema/payment-sessions.js +79 -0
- package/dist/schema/receivables.d.ts +1474 -0
- package/dist/schema/receivables.d.ts.map +1 -0
- package/dist/schema/receivables.js +179 -0
- package/dist/schema/relations.d.ts +82 -0
- package/dist/schema/relations.d.ts.map +1 -0
- package/dist/schema/relations.js +144 -0
- package/dist/schema/supplier-invoices.d.ts +1619 -0
- package/dist/schema/supplier-invoices.d.ts.map +1 -0
- package/dist/schema/supplier-invoices.js +228 -0
- package/dist/schema/tax.d.ts +712 -0
- package/dist/schema/tax.d.ts.map +1 -0
- package/dist/schema/tax.js +98 -0
- package/dist/schema/vouchers.d.ts +444 -0
- package/dist/schema/vouchers.d.ts.map +1 -0
- package/dist/schema/vouchers.js +64 -0
- package/dist/schema.d.ts +12 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +11 -0
- package/dist/service-accountant-shares.d.ts +106 -0
- package/dist/service-accountant-shares.d.ts.map +1 -0
- package/dist/service-accountant-shares.js +331 -0
- package/dist/service-action-ledger-accounting.d.ts +104 -0
- package/dist/service-action-ledger-accounting.d.ts.map +1 -0
- package/dist/service-action-ledger-accounting.js +386 -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-bookings.d.ts +44 -0
- package/dist/service-action-ledger-bookings.d.ts.map +1 -0
- package/dist/service-action-ledger-bookings.js +81 -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-invoices.d.ts +27 -0
- package/dist/service-action-ledger-supplier-invoices.d.ts.map +1 -0
- package/dist/service-action-ledger-supplier-invoices.js +111 -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 +97 -0
- package/dist/service-action-ledger.d.ts +7 -0
- package/dist/service-action-ledger.d.ts.map +1 -0
- package/dist/service-action-ledger.js +6 -0
- package/dist/service-aggregates.d.ts +96 -0
- package/dist/service-aggregates.d.ts.map +1 -0
- package/dist/service-aggregates.js +294 -0
- package/dist/service-booking-billing.d.ts +2322 -0
- package/dist/service-booking-billing.d.ts.map +1 -0
- package/dist/service-booking-billing.js +8 -0
- package/dist/service-booking-create.d.ts +410 -0
- package/dist/service-booking-create.d.ts.map +1 -0
- package/dist/service-booking-create.js +1256 -0
- package/dist/service-booking-guarantees.d.ts +725 -0
- package/dist/service-booking-guarantees.d.ts.map +1 -0
- package/dist/service-booking-guarantees.js +153 -0
- package/dist/service-booking-item-billing.d.ts +1062 -0
- package/dist/service-booking-item-billing.d.ts.map +1 -0
- package/dist/service-booking-item-billing.js +77 -0
- package/dist/service-booking-payment-schedules.d.ts +557 -0
- package/dist/service-booking-payment-schedules.d.ts.map +1 -0
- package/dist/service-booking-payment-schedules.js +372 -0
- package/dist/service-bookings-dual-create.d.ts +308 -0
- package/dist/service-bookings-dual-create.d.ts.map +1 -0
- package/dist/service-bookings-dual-create.js +131 -0
- package/dist/service-boundary-sql.d.ts +6 -0
- package/dist/service-boundary-sql.d.ts.map +1 -0
- package/dist/service-boundary-sql.js +15 -0
- package/dist/service-cost-categories.d.ts +26 -0
- package/dist/service-cost-categories.d.ts.map +1 -0
- package/dist/service-cost-categories.js +76 -0
- package/dist/service-documents.d.ts +80 -0
- package/dist/service-documents.d.ts.map +1 -0
- package/dist/service-documents.js +228 -0
- package/dist/service-invoice-artifacts.d.ts +246 -0
- package/dist/service-invoice-artifacts.d.ts.map +1 -0
- package/dist/service-invoice-artifacts.js +277 -0
- package/dist/service-invoice-core.d.ts +405 -0
- package/dist/service-invoice-core.d.ts.map +1 -0
- package/dist/service-invoice-core.js +290 -0
- package/dist/service-invoice-credit-notes.d.ts +973 -0
- package/dist/service-invoice-credit-notes.d.ts.map +1 -0
- package/dist/service-invoice-credit-notes.js +142 -0
- package/dist/service-invoice-from-booking.d.ts +41 -0
- package/dist/service-invoice-from-booking.d.ts.map +1 -0
- package/dist/service-invoice-from-booking.js +267 -0
- package/dist/service-invoice-line-items.d.ts +432 -0
- package/dist/service-invoice-line-items.d.ts.map +1 -0
- package/dist/service-invoice-line-items.js +102 -0
- package/dist/service-invoice-numbering.d.ts +227 -0
- package/dist/service-invoice-numbering.d.ts.map +1 -0
- package/dist/service-invoice-numbering.js +260 -0
- package/dist/service-invoice-payments.d.ts +673 -0
- package/dist/service-invoice-payments.d.ts.map +1 -0
- package/dist/service-invoice-payments.js +398 -0
- package/dist/service-invoices.d.ts +2501 -0
- package/dist/service-invoices.d.ts.map +1 -0
- package/dist/service-invoices.js +12 -0
- package/dist/service-issue.d.ts +207 -0
- package/dist/service-issue.d.ts.map +1 -0
- package/dist/service-issue.js +431 -0
- package/dist/service-payment-authorizations.d.ts +164 -0
- package/dist/service-payment-authorizations.d.ts.map +1 -0
- package/dist/service-payment-authorizations.js +227 -0
- package/dist/service-payment-instruments.d.ts +116 -0
- package/dist/service-payment-instruments.d.ts.map +1 -0
- package/dist/service-payment-instruments.js +99 -0
- package/dist/service-payment-processing.d.ts +676 -0
- package/dist/service-payment-processing.d.ts.map +1 -0
- package/dist/service-payment-processing.js +10 -0
- package/dist/service-payment-session-completion.d.ts +48 -0
- package/dist/service-payment-session-completion.d.ts.map +1 -0
- package/dist/service-payment-session-completion.js +238 -0
- package/dist/service-payment-sessions.d.ts +361 -0
- package/dist/service-payment-sessions.d.ts.map +1 -0
- package/dist/service-payment-sessions.js +280 -0
- package/dist/service-profitability.d.ts +114 -0
- package/dist/service-profitability.d.ts.map +1 -0
- package/dist/service-profitability.js +794 -0
- package/dist/service-public.d.ts +553 -0
- package/dist/service-public.d.ts.map +1 -0
- package/dist/service-public.js +583 -0
- package/dist/service-reference-data.d.ts +272 -0
- package/dist/service-reference-data.d.ts.map +1 -0
- package/dist/service-reference-data.js +280 -0
- package/dist/service-rendition-wait.d.ts +38 -0
- package/dist/service-rendition-wait.d.ts.map +1 -0
- package/dist/service-rendition-wait.js +67 -0
- package/dist/service-reports.d.ts +37 -0
- package/dist/service-reports.d.ts.map +1 -0
- package/dist/service-reports.js +62 -0
- package/dist/service-settlement.d.ts +46 -0
- package/dist/service-settlement.d.ts.map +1 -0
- package/dist/service-settlement.js +185 -0
- package/dist/service-shared.d.ts +541 -0
- package/dist/service-shared.d.ts.map +1 -0
- package/dist/service-shared.js +764 -0
- package/dist/service-supplier-invoices.d.ts +871 -0
- package/dist/service-supplier-invoices.d.ts.map +1 -0
- package/dist/service-supplier-invoices.js +744 -0
- package/dist/service-supplier-payments.d.ts +69 -0
- package/dist/service-supplier-payments.d.ts.map +1 -0
- package/dist/service-supplier-payments.js +136 -0
- package/dist/service-vouchers-migration.d.ts +44 -0
- package/dist/service-vouchers-migration.d.ts.map +1 -0
- package/dist/service-vouchers-migration.js +148 -0
- package/dist/service-vouchers.d.ts +157 -0
- package/dist/service-vouchers.d.ts.map +1 -0
- package/dist/service-vouchers.js +191 -0
- package/dist/service.d.ts +6490 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +29 -0
- package/dist/validation-billing.d.ts +2 -0
- package/dist/validation-billing.d.ts.map +1 -0
- package/dist/validation-billing.js +1 -0
- package/dist/validation-payments.d.ts +2 -0
- package/dist/validation-payments.d.ts.map +1 -0
- package/dist/validation-payments.js +1 -0
- package/dist/validation-public.d.ts +2 -0
- package/dist/validation-public.d.ts.map +1 -0
- package/dist/validation-public.js +1 -0
- package/dist/validation-shared.d.ts +2 -0
- package/dist/validation-shared.d.ts.map +1 -0
- package/dist/validation-shared.js +1 -0
- package/dist/validation-vouchers.d.ts +2 -0
- package/dist/validation-vouchers.d.ts.map +1 -0
- package/dist/validation-vouchers.js +1 -0
- package/dist/validation.d.ts +2 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +1 -0
- package/package.json +121 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { and, appendActionLedgerMutation, buildPaymentSessionCancelledActionLedgerInput, buildPaymentSessionCreateActionLedgerInput, buildPaymentSessionExpiredActionLedgerInput, buildPaymentSessionFailedActionLedgerInput, buildPaymentSessionRequiresRedirectActionLedgerInput, buildPaymentSessionUpdateActionLedgerInput, derivePaymentSessionTarget, desc, eq, paginate, paymentSessions, sql, toTimestamp, } from "./service-shared.js";
|
|
2
|
+
function derivePaymentSessionTargetColumns(data) {
|
|
3
|
+
const explicitTarget = "target" in data ? data.target : undefined;
|
|
4
|
+
if (!explicitTarget)
|
|
5
|
+
return {};
|
|
6
|
+
switch (explicitTarget.type) {
|
|
7
|
+
case "booking":
|
|
8
|
+
return { bookingId: explicitTarget.bookingId };
|
|
9
|
+
case "invoice":
|
|
10
|
+
return { invoiceId: explicitTarget.invoiceId };
|
|
11
|
+
case "booking_payment_schedule":
|
|
12
|
+
return { bookingPaymentScheduleId: explicitTarget.bookingPaymentScheduleId };
|
|
13
|
+
case "booking_guarantee":
|
|
14
|
+
return { bookingGuaranteeId: explicitTarget.bookingGuaranteeId };
|
|
15
|
+
case "legacy_order":
|
|
16
|
+
return { orderId: explicitTarget.legacyOrderId };
|
|
17
|
+
default:
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export const financePaymentSessionService = {
|
|
22
|
+
async listPaymentSessions(db, query) {
|
|
23
|
+
const conditions = [];
|
|
24
|
+
if (query.bookingId)
|
|
25
|
+
conditions.push(eq(paymentSessions.bookingId, query.bookingId));
|
|
26
|
+
if (query.legacyOrderId)
|
|
27
|
+
conditions.push(eq(paymentSessions.orderId, query.legacyOrderId));
|
|
28
|
+
if (query.invoiceId)
|
|
29
|
+
conditions.push(eq(paymentSessions.invoiceId, query.invoiceId));
|
|
30
|
+
if (query.bookingPaymentScheduleId) {
|
|
31
|
+
conditions.push(eq(paymentSessions.bookingPaymentScheduleId, query.bookingPaymentScheduleId));
|
|
32
|
+
}
|
|
33
|
+
if (query.bookingGuaranteeId) {
|
|
34
|
+
conditions.push(eq(paymentSessions.bookingGuaranteeId, query.bookingGuaranteeId));
|
|
35
|
+
}
|
|
36
|
+
if (query.targetType)
|
|
37
|
+
conditions.push(eq(paymentSessions.targetType, query.targetType));
|
|
38
|
+
if (query.status)
|
|
39
|
+
conditions.push(eq(paymentSessions.status, query.status));
|
|
40
|
+
if (query.provider)
|
|
41
|
+
conditions.push(eq(paymentSessions.provider, query.provider));
|
|
42
|
+
if (query.providerSessionId) {
|
|
43
|
+
conditions.push(eq(paymentSessions.providerSessionId, query.providerSessionId));
|
|
44
|
+
}
|
|
45
|
+
if (query.providerPaymentId) {
|
|
46
|
+
conditions.push(eq(paymentSessions.providerPaymentId, query.providerPaymentId));
|
|
47
|
+
}
|
|
48
|
+
if (query.externalReference) {
|
|
49
|
+
conditions.push(eq(paymentSessions.externalReference, query.externalReference));
|
|
50
|
+
}
|
|
51
|
+
if (query.clientReference) {
|
|
52
|
+
conditions.push(eq(paymentSessions.clientReference, query.clientReference));
|
|
53
|
+
}
|
|
54
|
+
if (query.idempotencyKey) {
|
|
55
|
+
conditions.push(eq(paymentSessions.idempotencyKey, query.idempotencyKey));
|
|
56
|
+
}
|
|
57
|
+
const where = conditions.length ? and(...conditions) : undefined;
|
|
58
|
+
return paginate(db
|
|
59
|
+
.select()
|
|
60
|
+
.from(paymentSessions)
|
|
61
|
+
.where(where)
|
|
62
|
+
.limit(query.limit)
|
|
63
|
+
.offset(query.offset)
|
|
64
|
+
.orderBy(desc(paymentSessions.createdAt)), db.select({ total: sql `count(*)::int` }).from(paymentSessions).where(where), query.limit, query.offset);
|
|
65
|
+
},
|
|
66
|
+
async getPaymentSessionById(db, id) {
|
|
67
|
+
const [row] = await db.select().from(paymentSessions).where(eq(paymentSessions.id, id)).limit(1);
|
|
68
|
+
return row ?? null;
|
|
69
|
+
},
|
|
70
|
+
async createPaymentSession(db, data, runtime = {}) {
|
|
71
|
+
if (data.idempotencyKey) {
|
|
72
|
+
const [existing] = await db
|
|
73
|
+
.select()
|
|
74
|
+
.from(paymentSessions)
|
|
75
|
+
.where(eq(paymentSessions.idempotencyKey, data.idempotencyKey))
|
|
76
|
+
.limit(1);
|
|
77
|
+
if (existing) {
|
|
78
|
+
return existing;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const target = derivePaymentSessionTarget(data);
|
|
82
|
+
const targetColumns = derivePaymentSessionTargetColumns(data);
|
|
83
|
+
const { legacyOrderId, target: _explicitTarget, provenance: _provenance, ...sessionData } = data;
|
|
84
|
+
const resolvedLegacyOrderId = legacyOrderId ?? null;
|
|
85
|
+
const createSession = (writer) => writer
|
|
86
|
+
.insert(paymentSessions)
|
|
87
|
+
.values({
|
|
88
|
+
...sessionData,
|
|
89
|
+
...targetColumns,
|
|
90
|
+
...target,
|
|
91
|
+
orderId: targetColumns.orderId ?? resolvedLegacyOrderId,
|
|
92
|
+
paymentInstrumentId: data.paymentInstrumentId ?? null,
|
|
93
|
+
paymentAuthorizationId: data.paymentAuthorizationId ?? null,
|
|
94
|
+
paymentCaptureId: data.paymentCaptureId ?? null,
|
|
95
|
+
paymentId: data.paymentId ?? null,
|
|
96
|
+
completedAt: toTimestamp(data.completedAt),
|
|
97
|
+
failedAt: toTimestamp(data.failedAt),
|
|
98
|
+
cancelledAt: toTimestamp(data.cancelledAt),
|
|
99
|
+
expiredAt: toTimestamp(data.expiredAt),
|
|
100
|
+
expiresAt: toTimestamp(data.expiresAt),
|
|
101
|
+
})
|
|
102
|
+
.returning();
|
|
103
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
104
|
+
if (actionLedgerContext) {
|
|
105
|
+
const [row] = await db.transaction(async (tx) => {
|
|
106
|
+
const created = await createSession(tx);
|
|
107
|
+
if (created[0]) {
|
|
108
|
+
await appendActionLedgerMutation(tx, await buildPaymentSessionCreateActionLedgerInput(actionLedgerContext, { session: created[0] }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
109
|
+
}
|
|
110
|
+
return created;
|
|
111
|
+
});
|
|
112
|
+
return row ?? null;
|
|
113
|
+
}
|
|
114
|
+
const [row] = await createSession(db);
|
|
115
|
+
return row ?? null;
|
|
116
|
+
},
|
|
117
|
+
async updatePaymentSession(db, id, data, runtime = {}) {
|
|
118
|
+
const target = derivePaymentSessionTarget(data);
|
|
119
|
+
const targetColumns = derivePaymentSessionTargetColumns(data);
|
|
120
|
+
const { legacyOrderId, target: _explicitTarget, provenance: _provenance, ...sessionData } = data;
|
|
121
|
+
const resolvedLegacyOrderId = legacyOrderId;
|
|
122
|
+
const updateSession = (writer) => writer
|
|
123
|
+
.update(paymentSessions)
|
|
124
|
+
.set({
|
|
125
|
+
...sessionData,
|
|
126
|
+
...targetColumns,
|
|
127
|
+
...target,
|
|
128
|
+
orderId: targetColumns.orderId ??
|
|
129
|
+
(resolvedLegacyOrderId === undefined ? undefined : (resolvedLegacyOrderId ?? null)),
|
|
130
|
+
paymentInstrumentId: data.paymentInstrumentId === undefined ? undefined : (data.paymentInstrumentId ?? null),
|
|
131
|
+
paymentAuthorizationId: data.paymentAuthorizationId === undefined
|
|
132
|
+
? undefined
|
|
133
|
+
: (data.paymentAuthorizationId ?? null),
|
|
134
|
+
paymentCaptureId: data.paymentCaptureId === undefined ? undefined : (data.paymentCaptureId ?? null),
|
|
135
|
+
paymentId: data.paymentId === undefined ? undefined : (data.paymentId ?? null),
|
|
136
|
+
completedAt: data.completedAt === undefined ? undefined : toTimestamp(data.completedAt),
|
|
137
|
+
failedAt: data.failedAt === undefined ? undefined : toTimestamp(data.failedAt),
|
|
138
|
+
cancelledAt: data.cancelledAt === undefined ? undefined : toTimestamp(data.cancelledAt),
|
|
139
|
+
expiredAt: data.expiredAt === undefined ? undefined : toTimestamp(data.expiredAt),
|
|
140
|
+
expiresAt: data.expiresAt === undefined ? undefined : toTimestamp(data.expiresAt),
|
|
141
|
+
updatedAt: new Date(),
|
|
142
|
+
})
|
|
143
|
+
.where(eq(paymentSessions.id, id))
|
|
144
|
+
.returning();
|
|
145
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
146
|
+
if (actionLedgerContext) {
|
|
147
|
+
const [row] = await db.transaction(async (tx) => {
|
|
148
|
+
const updated = await updateSession(tx);
|
|
149
|
+
if (updated[0]) {
|
|
150
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionUpdateActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
151
|
+
}
|
|
152
|
+
return updated;
|
|
153
|
+
});
|
|
154
|
+
return row ?? null;
|
|
155
|
+
}
|
|
156
|
+
const [row] = await updateSession(db);
|
|
157
|
+
return row ?? null;
|
|
158
|
+
},
|
|
159
|
+
async markPaymentSessionRequiresRedirect(db, id, data, runtime = {}) {
|
|
160
|
+
const markRequiresRedirect = (writer) => writer
|
|
161
|
+
.update(paymentSessions)
|
|
162
|
+
.set({
|
|
163
|
+
status: "requires_redirect",
|
|
164
|
+
provider: data.provider ?? undefined,
|
|
165
|
+
providerSessionId: data.providerSessionId ?? undefined,
|
|
166
|
+
providerPaymentId: data.providerPaymentId ?? undefined,
|
|
167
|
+
externalReference: data.externalReference ?? undefined,
|
|
168
|
+
redirectUrl: data.redirectUrl,
|
|
169
|
+
returnUrl: data.returnUrl ?? undefined,
|
|
170
|
+
cancelUrl: data.cancelUrl ?? undefined,
|
|
171
|
+
callbackUrl: data.callbackUrl ?? undefined,
|
|
172
|
+
expiresAt: data.expiresAt === undefined ? undefined : toTimestamp(data.expiresAt),
|
|
173
|
+
providerPayload: data.providerPayload ?? undefined,
|
|
174
|
+
metadata: data.metadata ?? undefined,
|
|
175
|
+
notes: data.notes ?? undefined,
|
|
176
|
+
updatedAt: new Date(),
|
|
177
|
+
})
|
|
178
|
+
.where(eq(paymentSessions.id, id))
|
|
179
|
+
.returning();
|
|
180
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
181
|
+
if (actionLedgerContext) {
|
|
182
|
+
const [row] = await db.transaction(async (tx) => {
|
|
183
|
+
const updated = await markRequiresRedirect(tx);
|
|
184
|
+
if (updated[0]) {
|
|
185
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionRequiresRedirectActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
186
|
+
}
|
|
187
|
+
return updated;
|
|
188
|
+
});
|
|
189
|
+
return row ?? null;
|
|
190
|
+
}
|
|
191
|
+
const [row] = await markRequiresRedirect(db);
|
|
192
|
+
return row ?? null;
|
|
193
|
+
},
|
|
194
|
+
async failPaymentSession(db, id, data, runtime = {}) {
|
|
195
|
+
const failSession = (writer) => writer
|
|
196
|
+
.update(paymentSessions)
|
|
197
|
+
.set({
|
|
198
|
+
status: "failed",
|
|
199
|
+
providerSessionId: data.providerSessionId ?? undefined,
|
|
200
|
+
providerPaymentId: data.providerPaymentId ?? undefined,
|
|
201
|
+
externalReference: data.externalReference ?? undefined,
|
|
202
|
+
failureCode: data.failureCode ?? undefined,
|
|
203
|
+
failureMessage: data.failureMessage ?? undefined,
|
|
204
|
+
failedAt: new Date(),
|
|
205
|
+
providerPayload: data.providerPayload ?? undefined,
|
|
206
|
+
metadata: data.metadata ?? undefined,
|
|
207
|
+
notes: data.notes ?? undefined,
|
|
208
|
+
updatedAt: new Date(),
|
|
209
|
+
})
|
|
210
|
+
.where(eq(paymentSessions.id, id))
|
|
211
|
+
.returning();
|
|
212
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
213
|
+
if (actionLedgerContext) {
|
|
214
|
+
const [row] = await db.transaction(async (tx) => {
|
|
215
|
+
const updated = await failSession(tx);
|
|
216
|
+
if (updated[0]) {
|
|
217
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionFailedActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
218
|
+
}
|
|
219
|
+
return updated;
|
|
220
|
+
});
|
|
221
|
+
return row ?? null;
|
|
222
|
+
}
|
|
223
|
+
const [row] = await failSession(db);
|
|
224
|
+
return row ?? null;
|
|
225
|
+
},
|
|
226
|
+
async cancelPaymentSession(db, id, data, runtime = {}) {
|
|
227
|
+
const cancelSession = (writer) => writer
|
|
228
|
+
.update(paymentSessions)
|
|
229
|
+
.set({
|
|
230
|
+
status: "cancelled",
|
|
231
|
+
cancelledAt: data.cancelledAt ? toTimestamp(data.cancelledAt) : new Date(),
|
|
232
|
+
providerPayload: data.providerPayload ?? undefined,
|
|
233
|
+
metadata: data.metadata ?? undefined,
|
|
234
|
+
notes: data.notes ?? undefined,
|
|
235
|
+
updatedAt: new Date(),
|
|
236
|
+
})
|
|
237
|
+
.where(eq(paymentSessions.id, id))
|
|
238
|
+
.returning();
|
|
239
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
240
|
+
if (actionLedgerContext) {
|
|
241
|
+
const [row] = await db.transaction(async (tx) => {
|
|
242
|
+
const updated = await cancelSession(tx);
|
|
243
|
+
if (updated[0]) {
|
|
244
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionCancelledActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
245
|
+
}
|
|
246
|
+
return updated;
|
|
247
|
+
});
|
|
248
|
+
return row ?? null;
|
|
249
|
+
}
|
|
250
|
+
const [row] = await cancelSession(db);
|
|
251
|
+
return row ?? null;
|
|
252
|
+
},
|
|
253
|
+
async expirePaymentSession(db, id, data, runtime = {}) {
|
|
254
|
+
const expireSession = (writer) => writer
|
|
255
|
+
.update(paymentSessions)
|
|
256
|
+
.set({
|
|
257
|
+
status: "expired",
|
|
258
|
+
expiredAt: data.expiredAt ? toTimestamp(data.expiredAt) : new Date(),
|
|
259
|
+
providerPayload: data.providerPayload ?? undefined,
|
|
260
|
+
metadata: data.metadata ?? undefined,
|
|
261
|
+
notes: data.notes ?? undefined,
|
|
262
|
+
updatedAt: new Date(),
|
|
263
|
+
})
|
|
264
|
+
.where(eq(paymentSessions.id, id))
|
|
265
|
+
.returning();
|
|
266
|
+
const actionLedgerContext = runtime.actionLedgerContext;
|
|
267
|
+
if (actionLedgerContext) {
|
|
268
|
+
const [row] = await db.transaction(async (tx) => {
|
|
269
|
+
const updated = await expireSession(tx);
|
|
270
|
+
if (updated[0]) {
|
|
271
|
+
await appendActionLedgerMutation(tx, buildPaymentSessionExpiredActionLedgerInput(actionLedgerContext, { session: updated[0], changes: data }, { authorizationSource: runtime.actionLedgerAuthorizationSource }));
|
|
272
|
+
}
|
|
273
|
+
return updated;
|
|
274
|
+
});
|
|
275
|
+
return row ?? null;
|
|
276
|
+
}
|
|
277
|
+
const [row] = await expireSession(db);
|
|
278
|
+
return row ?? null;
|
|
279
|
+
},
|
|
280
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { DepartureProfitabilityQuery, ProductProfitabilityQuery, TravelerProfitabilityQuery } from "@voyant-travel/finance-contracts";
|
|
2
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
|
+
import { type InvoiceFxOptions } from "./invoice-fx.js";
|
|
4
|
+
/**
|
|
5
|
+
* FX runtime for the profitability read model. Carries the operator FX settings
|
|
6
|
+
* (which name the accounting base currency, default "RON") and the exchange-rate
|
|
7
|
+
* resolver used to convert legacy, un-snapshotted rows. Threaded from the finance
|
|
8
|
+
* route runtime so the rollup matches how invoices were snapshotted at write time.
|
|
9
|
+
*/
|
|
10
|
+
export type ProfitabilityFxRuntime = InvoiceFxOptions;
|
|
11
|
+
/**
|
|
12
|
+
* Profitability read model (RFC §8). Computed on read, never stored. Amounts are
|
|
13
|
+
* grouped **per currency** and never summed across currencies (no FX in v1).
|
|
14
|
+
*
|
|
15
|
+
* - Revenue = issued customer invoices (AR), attributed to a departure by
|
|
16
|
+
* splitting each booking's invoiced total across its departures in proportion
|
|
17
|
+
* to the departures' booked sell amounts (`booking_items`). Credit notes net
|
|
18
|
+
* the revenue down.
|
|
19
|
+
* - Actual cost = `supplier_cost_allocations` targeted at the departure/product.
|
|
20
|
+
* - Planned cost = `booking_items.totalCostAmountCents` (what we expected to pay).
|
|
21
|
+
* - Profit = revenue − actual cost. Variance = planned − actual cost.
|
|
22
|
+
*/
|
|
23
|
+
export interface ProfitabilityCostByServiceType {
|
|
24
|
+
serviceType: string;
|
|
25
|
+
currency: string;
|
|
26
|
+
amountCents: number;
|
|
27
|
+
}
|
|
28
|
+
export interface ProfitabilityUnattributed {
|
|
29
|
+
currency: string;
|
|
30
|
+
amountCents: number;
|
|
31
|
+
}
|
|
32
|
+
export interface DepartureProfitabilityRow {
|
|
33
|
+
departureId: string;
|
|
34
|
+
departureLabel: string | null;
|
|
35
|
+
productId: string | null;
|
|
36
|
+
productName: string | null;
|
|
37
|
+
departureDate: string | null;
|
|
38
|
+
currency: string;
|
|
39
|
+
revenueCents: number;
|
|
40
|
+
actualCostCents: number;
|
|
41
|
+
plannedCostCents: number;
|
|
42
|
+
profitCents: number;
|
|
43
|
+
marginPercent: number | null;
|
|
44
|
+
varianceCents: number;
|
|
45
|
+
}
|
|
46
|
+
export interface DepartureProfitabilityBaseRollup {
|
|
47
|
+
currency: string;
|
|
48
|
+
rows: DepartureProfitabilityRow[];
|
|
49
|
+
costByServiceType: ProfitabilityCostByServiceType[];
|
|
50
|
+
unattributedCents: number;
|
|
51
|
+
/** Source currencies with no resolvable FX rate — excluded from the rollup. */
|
|
52
|
+
unconvertibleCurrencies: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface DepartureProfitabilityReport {
|
|
55
|
+
rows: DepartureProfitabilityRow[];
|
|
56
|
+
costByServiceType: ProfitabilityCostByServiceType[];
|
|
57
|
+
unattributed: ProfitabilityUnattributed[];
|
|
58
|
+
base?: DepartureProfitabilityBaseRollup;
|
|
59
|
+
}
|
|
60
|
+
export interface ProductProfitabilityRow {
|
|
61
|
+
productId: string;
|
|
62
|
+
productName: string | null;
|
|
63
|
+
currency: string;
|
|
64
|
+
departureCount: number;
|
|
65
|
+
revenueCents: number;
|
|
66
|
+
actualCostCents: number;
|
|
67
|
+
plannedCostCents: number;
|
|
68
|
+
profitCents: number;
|
|
69
|
+
marginPercent: number | null;
|
|
70
|
+
varianceCents: number;
|
|
71
|
+
}
|
|
72
|
+
export interface ProductProfitabilityBaseRollup {
|
|
73
|
+
currency: string;
|
|
74
|
+
rows: ProductProfitabilityRow[];
|
|
75
|
+
costByServiceType: ProfitabilityCostByServiceType[];
|
|
76
|
+
unattributedCents: number;
|
|
77
|
+
unconvertibleCurrencies: string[];
|
|
78
|
+
}
|
|
79
|
+
export interface ProductProfitabilityReport {
|
|
80
|
+
rows: ProductProfitabilityRow[];
|
|
81
|
+
costByServiceType: ProfitabilityCostByServiceType[];
|
|
82
|
+
unattributed: ProfitabilityUnattributed[];
|
|
83
|
+
base?: ProductProfitabilityBaseRollup;
|
|
84
|
+
}
|
|
85
|
+
export declare function getDepartureProfitability(db: PostgresJsDatabase, query: DepartureProfitabilityQuery, options?: ProfitabilityFxRuntime): Promise<DepartureProfitabilityReport>;
|
|
86
|
+
export declare function getProductProfitability(db: PostgresJsDatabase, query: ProductProfitabilityQuery, options?: ProfitabilityFxRuntime): Promise<ProductProfitabilityReport>;
|
|
87
|
+
export interface TravelerProfitabilityRow {
|
|
88
|
+
travelerId: string;
|
|
89
|
+
travelerName: string;
|
|
90
|
+
bookingId: string;
|
|
91
|
+
currency: string;
|
|
92
|
+
revenueCents: number;
|
|
93
|
+
actualCostCents: number;
|
|
94
|
+
plannedCostCents: number;
|
|
95
|
+
profitCents: number;
|
|
96
|
+
marginPercent: number | null;
|
|
97
|
+
varianceCents: number;
|
|
98
|
+
}
|
|
99
|
+
export interface TravelerProfitabilityReport {
|
|
100
|
+
departureId: string;
|
|
101
|
+
currency: string;
|
|
102
|
+
travelerCount: number;
|
|
103
|
+
rows: TravelerProfitabilityRow[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Derive per-traveller P&L for one departure in a single currency. Revenue is a
|
|
107
|
+
* booking's departure-attributed invoiced AR split equally across that booking's
|
|
108
|
+
* travellers; planned cost likewise; actual departure cost is split equally
|
|
109
|
+
* across all the departure's travellers (`equal` method — `per_pax` parity).
|
|
110
|
+
*/
|
|
111
|
+
export declare function getTravelerProfitability(db: PostgresJsDatabase, query: TravelerProfitabilityQuery): Promise<TravelerProfitabilityReport>;
|
|
112
|
+
export declare function buildDepartureProfitabilityCsv(report: DepartureProfitabilityReport): string;
|
|
113
|
+
export declare function buildProductProfitabilityCsv(report: ProductProfitabilityReport): string;
|
|
114
|
+
//# sourceMappingURL=service-profitability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-profitability.d.ts","sourceRoot":"","sources":["../src/service-profitability.ts"],"names":[],"mappings":"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"}
|