@voyant-travel/finance 0.151.4 → 0.152.0

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.
Files changed (50) hide show
  1. package/dist/booking-lifecycle.d.ts +13 -0
  2. package/dist/booking-lifecycle.d.ts.map +1 -0
  3. package/dist/booking-lifecycle.js +64 -0
  4. package/dist/booking-schedule/subscriber-runtime.d.ts +20 -0
  5. package/dist/booking-schedule/subscriber-runtime.d.ts.map +1 -0
  6. package/dist/booking-schedule/subscriber-runtime.js +39 -0
  7. package/dist/booking-tax.d.ts +31 -21
  8. package/dist/booking-tax.d.ts.map +1 -1
  9. package/dist/booking-tax.js +84 -13
  10. package/dist/index.d.ts +6 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +37 -7
  13. package/dist/mcp-runtime.d.ts +3 -0
  14. package/dist/mcp-runtime.d.ts.map +1 -0
  15. package/dist/mcp-runtime.js +16 -0
  16. package/dist/payment-schedule/routes.d.ts +1 -0
  17. package/dist/payment-schedule/routes.d.ts.map +1 -1
  18. package/dist/payment-schedule/routes.js +32 -0
  19. package/dist/routes-action-ledger.d.ts +19 -19
  20. package/dist/routes-booking-billing.d.ts +30 -30
  21. package/dist/routes-booking-create.d.ts.map +1 -1
  22. package/dist/routes-booking-create.js +2 -0
  23. package/dist/routes-booking-reads.d.ts +11 -11
  24. package/dist/routes-invoice-core.d.ts +11 -11
  25. package/dist/routes-public.d.ts +24 -24
  26. package/dist/routes-public.d.ts.map +1 -1
  27. package/dist/routes-public.js +12 -0
  28. package/dist/routes-reference-data.d.ts +15 -15
  29. package/dist/routes-reports.d.ts +11 -11
  30. package/dist/routes-settlement.d.ts +11 -11
  31. package/dist/routes-supplier-invoices.d.ts +20 -20
  32. package/dist/routes.d.ts +78 -78
  33. package/dist/runtime-contributor.d.ts +7 -0
  34. package/dist/runtime-contributor.d.ts.map +1 -0
  35. package/dist/runtime-contributor.js +17 -0
  36. package/dist/runtime-port.d.ts +70 -0
  37. package/dist/runtime-port.d.ts.map +1 -0
  38. package/dist/runtime-port.js +47 -0
  39. package/dist/runtime.d.ts +10 -0
  40. package/dist/runtime.d.ts.map +1 -0
  41. package/dist/runtime.js +98 -0
  42. package/dist/stale-booking-holds-runtime.d.ts +9 -0
  43. package/dist/stale-booking-holds-runtime.d.ts.map +1 -0
  44. package/dist/stale-booking-holds-runtime.js +25 -0
  45. package/dist/voyant.d.ts.map +1 -1
  46. package/dist/voyant.js +156 -8
  47. package/openapi/admin/booking-tax.json +86 -0
  48. package/openapi/admin/finance.json +36583 -0
  49. package/openapi/storefront/finance.json +3678 -0
  50. package/package.json +45 -17
@@ -0,0 +1,98 @@
1
+ import { createVoyantDataFxExchangeRateResolver, } from "./invoice-fx.js";
2
+ /** Compose Finance's main HTTP runtime from generic host and selected providers. */
3
+ export function createFinanceRuntime(host, notifications, checkoutPaymentStarters, invoiceSettlementPollerProviders = []) {
4
+ const { primitives } = host;
5
+ return {
6
+ resolveDocumentDownloadUrl: primitives.storage.downloadUrl,
7
+ resolveInvoiceExchangeRateResolver: (bindings) => createExchangeRateResolver(primitives, bindings),
8
+ invoiceSettlementPollers: aggregateFinanceInvoiceSettlementPollers(invoiceSettlementPollerProviders),
9
+ invoiceDueDateResolver: ({ issueDate, dueDate, bookingPaymentSchedule }) => bookingPaymentSchedule && dueDate < issueDate ? issueDate : dueDate,
10
+ resolveNotificationDispatcher: notifications.resolveNotificationDispatcher,
11
+ resolvePaymentStarters: (bindings) => checkoutPaymentStarters?.resolvePaymentStarters(bindings) ?? {},
12
+ resolveBankTransferDetails: (bindings) => resolveBankTransferDetails(primitives.env(bindings)),
13
+ resolvePublicCheckoutBaseUrl: (bindings) => resolvePublicCheckoutBaseUrl(primitives.env(bindings)),
14
+ listBookingReminderRuns: notifications.listBookingReminderRuns,
15
+ };
16
+ }
17
+ /** Compose Finance's payment schedule from statically selected domain providers. */
18
+ export function createFinanceBookingScheduleRuntime(host, settings, distribution, accommodations, cruises, inventory) {
19
+ const paymentPolicy = inventory.createPaymentPolicyRuntime({
20
+ resolveSupplierPolicy: distribution.resolveSupplierPolicy,
21
+ resolveSupplierPolicyById: distribution.resolveSupplierPolicyById,
22
+ resolveVerticalListingPolicy: async (db, bookingId) => (await cruises.resolveBookingPolicy(db, bookingId)) ??
23
+ accommodations.resolveBookingPolicy(db, bookingId),
24
+ resolveVerticalListingPolicyForEntity: async (db, context) => (await cruises.resolveEntityPolicy(db, context)) ??
25
+ accommodations.resolveEntityPolicy(db, context),
26
+ resolveVerticalSupplierPolicyForEntity: async (db, context) => {
27
+ const supplierId = await cruises.resolveSupplierId(db, context);
28
+ return supplierId ? distribution.resolveSupplierPolicyById(db, supplierId) : null;
29
+ },
30
+ });
31
+ return {
32
+ options: {
33
+ resolveDb: (context) => host.primitives.database.fromContext(context),
34
+ resolveOperatorDefaultPaymentPolicy: settings.resolveOperatorDefaultPaymentPolicy,
35
+ ...paymentPolicy,
36
+ stampPolicySourceOnBooking: inventory.stampPolicySourceOnBooking,
37
+ readPolicySourceFromInternalNotes: inventory.readPolicySourceFromInternalNotes,
38
+ },
39
+ withDb: (bindings, operation) => host.primitives.database.transaction(bindings, (database) => operation(database)),
40
+ };
41
+ }
42
+ export function createFinanceBookingTaxRuntime(settings) {
43
+ return {
44
+ resolveBookingTaxSettings: settings.resolveBookingTaxSettings,
45
+ updateBookingTaxSettings: settings.updateBookingTaxSettings,
46
+ };
47
+ }
48
+ function createExchangeRateResolver(primitives, bindings) {
49
+ const env = primitives.env(bindings);
50
+ const apiKey = nonEmpty(env.VOYANT_DATA_API_KEY) ??
51
+ (env.VOYANT_ADMIN_AUTH_MODE === "voyant-cloud"
52
+ ? (nonEmpty(env.VOYANT_API_KEY) ?? nonEmpty(env.VOYANT_CLOUD_API_KEY))
53
+ : undefined);
54
+ if (!apiKey)
55
+ return undefined;
56
+ return createVoyantDataFxExchangeRateResolver({
57
+ apiKey,
58
+ baseUrl: nonEmpty(env.VOYANT_CLOUD_API_URL),
59
+ });
60
+ }
61
+ export function aggregateFinanceInvoiceSettlementPollers(providers) {
62
+ const pollers = {};
63
+ for (const provider of [...providers].sort((left, right) => left.provider < right.provider ? -1 : left.provider > right.provider ? 1 : 0)) {
64
+ if (Object.hasOwn(pollers, provider.provider)) {
65
+ throw new Error(`Finance invoice settlement poller provider "${provider.provider}" was selected more than once.`);
66
+ }
67
+ pollers[provider.provider] = provider.poller;
68
+ }
69
+ return Object.freeze(pollers);
70
+ }
71
+ function resolveBankTransferDetails(env) {
72
+ const beneficiary = stringValue(env.BANK_TRANSFER_BENEFICIARY);
73
+ const iban = stringValue(env.BANK_TRANSFER_IBAN);
74
+ if (!beneficiary || !iban)
75
+ return null;
76
+ return {
77
+ provider: "bank-transfer",
78
+ beneficiary,
79
+ iban,
80
+ bankName: stringValue(env.BANK_TRANSFER_BANK_NAME) ?? null,
81
+ notes: stringValue(env.BANK_TRANSFER_NOTES) ?? null,
82
+ };
83
+ }
84
+ function resolvePublicCheckoutBaseUrl(env) {
85
+ return (nonEmpty(env.PUBLIC_CHECKOUT_BASE_URL) ??
86
+ nonEmpty(env.DASH_BASE_URL) ??
87
+ nonEmpty(env.APP_URL)?.replace(/\/api\/?$/, "") ??
88
+ null);
89
+ }
90
+ function nonEmpty(value) {
91
+ if (typeof value !== "string")
92
+ return undefined;
93
+ const trimmed = value.trim();
94
+ return trimmed || undefined;
95
+ }
96
+ function stringValue(value) {
97
+ return typeof value === "string" ? value : undefined;
98
+ }
@@ -0,0 +1,9 @@
1
+ import type { BookingsExpireStaleHoldsWorkflowRuntime } from "@voyant-travel/bookings/workflow-runtime";
2
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
3
+ export interface FinanceStaleBookingHoldsRuntimeOptions {
4
+ resolveDb: () => PostgresJsDatabase | Promise<PostgresJsDatabase>;
5
+ userId?: string;
6
+ }
7
+ /** Finance-owned effects required when Bookings expires stale holds. */
8
+ export declare function createFinanceStaleBookingHoldsRuntime(options: FinanceStaleBookingHoldsRuntimeOptions): BookingsExpireStaleHoldsWorkflowRuntime;
9
+ //# sourceMappingURL=stale-booking-holds-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-booking-holds-runtime.d.ts","sourceRoot":"","sources":["../src/stale-booking-holds-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,0CAA0C,CAAA;AAEvG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAKjE,MAAM,WAAW,sCAAsC;IACrD,SAAS,EAAE,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wEAAwE;AACxE,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,sCAAsC,GAC9C,uCAAuC,CAyBzC"}
@@ -0,0 +1,25 @@
1
+ import { and, eq, inArray } from "drizzle-orm";
2
+ import { closeTerminalBookingPaymentSchedules } from "./booking-lifecycle.js";
3
+ import { paymentSessions } from "./schema.js";
4
+ import { financeService } from "./service.js";
5
+ /** Finance-owned effects required when Bookings expires stale holds. */
6
+ export function createFinanceStaleBookingHoldsRuntime(options) {
7
+ return {
8
+ resolveDb: options.resolveDb,
9
+ resolveRuntime: () => ({
10
+ expirePaymentSessionsForBooking: async (db, bookingId) => {
11
+ const staleSessions = await db
12
+ .select({ id: paymentSessions.id })
13
+ .from(paymentSessions)
14
+ .where(and(eq(paymentSessions.bookingId, bookingId), inArray(paymentSessions.status, ["pending", "requires_redirect", "processing"])));
15
+ for (const session of staleSessions) {
16
+ await financeService.expirePaymentSession(db, session.id, {
17
+ notes: "Booking hold expired",
18
+ });
19
+ }
20
+ },
21
+ closePaymentSchedulesForBooking: closeTerminalBookingPaymentSchedules,
22
+ }),
23
+ userId: options.userId,
24
+ };
25
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"voyant.d.ts","sourceRoot":"","sources":["../src/voyant.ts"],"names":[],"mappings":"AAOA,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,uDAgL9B,CAAA;AAEF,eAAO,MAAM,6BAA6B,uDAmBxC,CAAA;AAEF,eAAO,MAAM,iCAAiC,uDAmB5C,CAAA;AAEF,eAAO,MAAM,kCAAkC,uDA6B7C,CAAA;AAEF,eAAe,mBAAmB,CAAA"}
1
+ {"version":3,"file":"voyant.d.ts","sourceRoot":"","sources":["../src/voyant.ts"],"names":[],"mappings":"AAkBA,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,uDAsS9B,CAAA;AAEF,eAAO,MAAM,6BAA6B,uDAsBxC,CAAA;AAEF,eAAO,MAAM,iCAAiC,uDAoB5C,CAAA;AAEF,eAAO,MAAM,kCAAkC,uDAsD7C,CAAA;AAEF,eAAe,mBAAmB,CAAA"}
package/dist/voyant.js CHANGED
@@ -1,4 +1,5 @@
1
- import { defineExtension, defineModule } from "@voyant-travel/core/project";
1
+ import { defineExtension, defineModule, requirePort } from "@voyant-travel/core/project";
2
+ import { financeAccommodationsPaymentPolicyRuntimePort, financeCheckoutPaymentStartersRuntimePort, financeCruisesPaymentPolicyRuntimePort, financeDistributionPaymentPolicyRuntimePort, financeHostRuntimePort, financeInventoryPaymentPolicyRuntimePort, financeInvoiceSettlementPollerRuntimePort, financeNotificationsRuntimePort, financeOperatorSettingsRuntimePort, } from "./runtime-port.js";
2
3
  const financeAdminRuntime = {
3
4
  entry: "@voyant-travel/finance-react/admin",
4
5
  export: "createFinanceAdminExtension",
@@ -8,12 +9,23 @@ export const financeVoyantModule = defineModule({
8
9
  id: "@voyant-travel/finance",
9
10
  packageName: "@voyant-travel/finance",
10
11
  localId: "finance",
12
+ runtime: { entry: "@voyant-travel/finance", export: "createFinanceVoyantRuntime" },
13
+ runtimePorts: [
14
+ requirePort(financeHostRuntimePort),
15
+ requirePort(financeNotificationsRuntimePort),
16
+ requirePort(financeCheckoutPaymentStartersRuntimePort, { optional: true }),
17
+ requirePort(financeInvoiceSettlementPollerRuntimePort, {
18
+ optional: true,
19
+ cardinality: "many",
20
+ }),
21
+ ],
11
22
  provides: { capabilities: ["finance.payment-sessions"] },
12
23
  api: [
13
24
  {
14
25
  id: "@voyant-travel/finance#api.admin",
15
26
  surface: "admin",
16
27
  mount: "finance",
28
+ openapi: { document: "finance" },
17
29
  transactional: true,
18
30
  runtime: {
19
31
  entry: "@voyant-travel/finance",
@@ -24,6 +36,7 @@ export const financeVoyantModule = defineModule({
24
36
  id: "@voyant-travel/finance#api.public",
25
37
  surface: "public",
26
38
  mount: "finance",
39
+ openapi: { document: "finance" },
27
40
  anonymous: ["/bookings", "/collections", "/payment-sessions", "/accountant", "/vouchers"],
28
41
  transactional: true,
29
42
  runtime: {
@@ -63,44 +76,125 @@ export const financeVoyantModule = defineModule({
63
76
  },
64
77
  ],
65
78
  events: [
66
- { id: "@voyant-travel/finance#event.invoice.issued", eventType: "invoice.issued" },
79
+ {
80
+ id: "@voyant-travel/finance#event.invoice.issued",
81
+ eventType: "invoice.issued",
82
+ version: "1.0.0",
83
+ payloadSchema: { type: "object", additionalProperties: true },
84
+ visibility: "internal",
85
+ audit: { sourceModule: "finance", category: "domain" },
86
+ },
67
87
  {
68
88
  id: "@voyant-travel/finance#event.invoice.proforma.issued",
69
89
  eventType: "invoice.proforma.issued",
90
+ version: "1.0.0",
91
+ payloadSchema: { type: "object", additionalProperties: true },
92
+ visibility: "internal",
93
+ audit: { sourceModule: "finance", category: "domain" },
70
94
  },
71
95
  {
72
96
  id: "@voyant-travel/finance#event.invoice.proforma.converted",
73
97
  eventType: "invoice.proforma.converted",
98
+ version: "1.0.0",
99
+ payloadSchema: { type: "object", additionalProperties: true },
100
+ visibility: "internal",
101
+ audit: { sourceModule: "finance", category: "domain" },
102
+ },
103
+ {
104
+ id: "@voyant-travel/finance#event.invoice.voided",
105
+ eventType: "invoice.voided",
106
+ version: "1.0.0",
107
+ payloadSchema: { type: "object", additionalProperties: true },
108
+ visibility: "internal",
109
+ audit: { sourceModule: "finance", category: "domain" },
110
+ },
111
+ {
112
+ id: "@voyant-travel/finance#event.invoice.settled",
113
+ eventType: "invoice.settled",
114
+ version: "1.0.0",
115
+ payloadSchema: { type: "object", additionalProperties: true },
116
+ visibility: "internal",
117
+ audit: { sourceModule: "finance", category: "domain" },
118
+ },
119
+ {
120
+ id: "@voyant-travel/finance#event.invoice.rendered",
121
+ eventType: "invoice.rendered",
122
+ version: "1.0.0",
123
+ payloadSchema: { type: "object", additionalProperties: true },
124
+ visibility: "internal",
125
+ audit: { sourceModule: "finance", category: "domain" },
74
126
  },
75
- { id: "@voyant-travel/finance#event.invoice.voided", eventType: "invoice.voided" },
76
- { id: "@voyant-travel/finance#event.invoice.settled", eventType: "invoice.settled" },
77
- { id: "@voyant-travel/finance#event.invoice.rendered", eventType: "invoice.rendered" },
78
127
  {
79
128
  id: "@voyant-travel/finance#event.invoice.document.generated",
80
129
  eventType: "invoice.document.generated",
130
+ version: "1.0.0",
131
+ payloadSchema: { type: "object", additionalProperties: true },
132
+ visibility: "internal",
133
+ audit: { sourceModule: "finance", category: "domain" },
81
134
  },
82
135
  {
83
136
  id: "@voyant-travel/finance#event.invoice.payment.recorded",
84
137
  eventType: "invoice.payment.recorded",
138
+ version: "1.0.0",
139
+ payloadSchema: { type: "object", additionalProperties: true },
140
+ visibility: "internal",
141
+ audit: { sourceModule: "finance", category: "domain" },
142
+ },
143
+ {
144
+ id: "@voyant-travel/finance#event.payment.completed",
145
+ eventType: "payment.completed",
146
+ version: "1.0.0",
147
+ payloadSchema: { type: "object", additionalProperties: true },
148
+ visibility: "internal",
149
+ audit: { sourceModule: "finance", category: "domain" },
150
+ },
151
+ {
152
+ id: "@voyant-travel/finance#event.booking.created",
153
+ eventType: "booking.created",
154
+ version: "1.0.0",
155
+ payloadSchema: { type: "object", additionalProperties: true },
156
+ visibility: "internal",
157
+ audit: { sourceModule: "finance", category: "domain" },
158
+ },
159
+ {
160
+ id: "@voyant-travel/finance#event.booking.confirmed",
161
+ eventType: "booking.confirmed",
162
+ version: "1.0.0",
163
+ payloadSchema: { type: "object", additionalProperties: true },
164
+ visibility: "internal",
165
+ audit: { sourceModule: "finance", category: "domain" },
85
166
  },
86
- { id: "@voyant-travel/finance#event.payment.completed", eventType: "payment.completed" },
87
- { id: "@voyant-travel/finance#event.booking.created", eventType: "booking.created" },
88
- { id: "@voyant-travel/finance#event.booking.confirmed", eventType: "booking.confirmed" },
89
167
  {
90
168
  id: "@voyant-travel/finance#event.booking.dual-created",
91
169
  eventType: "booking.dual-created",
170
+ version: "1.0.0",
171
+ payloadSchema: { type: "object", additionalProperties: true },
172
+ visibility: "internal",
173
+ audit: { sourceModule: "finance", category: "domain" },
92
174
  },
93
175
  {
94
176
  id: "@voyant-travel/finance#event.booking-create.rejected",
95
177
  eventType: "booking_create.rejected",
178
+ version: "1.0.0",
179
+ payloadSchema: { type: "object", additionalProperties: true },
180
+ visibility: "internal",
181
+ audit: { sourceModule: "finance", category: "domain" },
96
182
  },
97
183
  {
98
184
  id: "@voyant-travel/finance#event.booking.contract-document.requested",
99
185
  eventType: "booking.contract_document.requested",
186
+ version: "1.0.0",
187
+ payloadSchema: { type: "object", additionalProperties: true },
188
+ visibility: "internal",
189
+ audit: { sourceModule: "finance", category: "domain" },
100
190
  },
101
191
  {
102
192
  id: "@voyant-travel/finance#event.booking-payment-schedule.paid",
103
193
  eventType: "booking_payment_schedule.paid",
194
+ version: "1.0.0",
195
+ payloadSchema: { type: "object", additionalProperties: true },
196
+ visibility: "internal",
197
+ audit: { sourceModule: "finance", category: "domain" },
104
198
  },
105
199
  ],
106
200
  setupMigrations: [
@@ -121,6 +215,11 @@ export const financeVoyantModule = defineModule({
121
215
  resource: "finance",
122
216
  actions: ["read", "write", "refund", "void"],
123
217
  },
218
+ {
219
+ id: "@voyant-travel/finance#access.transactions",
220
+ resource: "transactions",
221
+ actions: ["read", "write"],
222
+ },
124
223
  ],
125
224
  },
126
225
  tools: [
@@ -129,21 +228,40 @@ export const financeVoyantModule = defineModule({
129
228
  name: "list_invoices",
130
229
  runtime: { entry: "@voyant-travel/finance/tools", export: "listInvoicesTool" },
131
230
  requiredScopes: ["finance:read"],
231
+ context: ["finance"],
132
232
  },
133
233
  {
134
234
  id: "@voyant-travel/finance#tool.get-invoice",
135
235
  name: "get_invoice",
136
236
  runtime: { entry: "@voyant-travel/finance/tools", export: "getInvoiceTool" },
137
237
  requiredScopes: ["finance:read"],
238
+ context: ["finance"],
138
239
  },
139
240
  {
140
241
  id: "@voyant-travel/finance#tool.void-invoice",
141
242
  name: "void_invoice",
142
243
  runtime: { entry: "@voyant-travel/finance/tools", export: "voidInvoiceTool" },
143
244
  requiredScopes: ["finance:void"],
245
+ context: ["finance"],
144
246
  },
145
247
  ],
146
248
  admin: {
249
+ compositionOrder: 40,
250
+ runtime: {
251
+ entry: "@voyant-travel/finance-react/admin",
252
+ export: "createSelectedFinanceAdminExtension",
253
+ },
254
+ copy: [
255
+ {
256
+ id: "@voyant-travel/finance#admin.copy",
257
+ namespace: "finance.admin",
258
+ fallbackLocale: "en",
259
+ runtime: {
260
+ entry: "@voyant-travel/finance-react/i18n",
261
+ export: "financeUiMessageDefinitions",
262
+ },
263
+ },
264
+ ],
147
265
  routes: [
148
266
  ["index", "/finance"],
149
267
  ["invoices-index", "/finance/invoices"],
@@ -160,6 +278,7 @@ export const financeVoyantModule = defineModule({
160
278
  runtime: financeAdminRuntime,
161
279
  })),
162
280
  contributions: [
281
+ ["booking-payment-controller", "booking.details.payment-controller"],
163
282
  ["booking-invoices", "booking.details.invoices-tab"],
164
283
  ["booking-pending-payment-sessions", "booking.details.finance-start"],
165
284
  ["booking-payment-policy", "booking.details.finance-end"],
@@ -181,11 +300,14 @@ export const financeBookingTaxVoyantPlugin = defineExtension({
181
300
  id: "@voyant-travel/finance#booking-tax-extension",
182
301
  packageName: "@voyant-travel/finance",
183
302
  localId: "finance.booking-tax-extension",
303
+ runtime: { entry: "@voyant-travel/finance", export: "createBookingTaxVoyantRuntime" },
304
+ runtimePorts: [requirePort(financeOperatorSettingsRuntimePort)],
184
305
  api: [
185
306
  {
186
307
  id: "@voyant-travel/finance#booking-tax-extension.api",
187
308
  surface: "admin",
188
309
  mount: "bookings",
310
+ openapi: { document: "booking-tax" },
189
311
  transactional: true,
190
312
  runtime: {
191
313
  entry: "@voyant-travel/finance",
@@ -206,6 +328,7 @@ export const financeBookingsCreateVoyantPlugin = defineExtension({
206
328
  id: "@voyant-travel/finance#bookings-create-extension.api",
207
329
  surface: "admin",
208
330
  mount: "bookings",
331
+ openapi: { document: "bookings" },
209
332
  transactional: true,
210
333
  runtime: {
211
334
  entry: "@voyant-travel/finance",
@@ -221,11 +344,24 @@ export const financeBookingScheduleVoyantPlugin = defineExtension({
221
344
  id: "@voyant-travel/finance#booking-schedule-extension",
222
345
  packageName: "@voyant-travel/finance",
223
346
  localId: "finance.booking-schedule-extension",
347
+ runtime: {
348
+ entry: "@voyant-travel/finance",
349
+ export: "createBookingScheduleVoyantRuntime",
350
+ },
351
+ runtimePorts: [
352
+ requirePort(financeHostRuntimePort),
353
+ requirePort(financeOperatorSettingsRuntimePort),
354
+ requirePort(financeDistributionPaymentPolicyRuntimePort),
355
+ requirePort(financeAccommodationsPaymentPolicyRuntimePort),
356
+ requirePort(financeCruisesPaymentPolicyRuntimePort),
357
+ requirePort(financeInventoryPaymentPolicyRuntimePort),
358
+ ],
224
359
  api: [
225
360
  {
226
361
  id: "@voyant-travel/finance#booking-schedule-extension.api.admin",
227
362
  surface: "admin",
228
363
  mount: "bookings",
364
+ openapi: { document: "bookings" },
229
365
  transactional: true,
230
366
  runtime: {
231
367
  entry: "@voyant-travel/finance",
@@ -236,6 +372,7 @@ export const financeBookingScheduleVoyantPlugin = defineExtension({
236
372
  id: "@voyant-travel/finance#booking-schedule-extension.api.public",
237
373
  surface: "public",
238
374
  mount: "payment-policy",
375
+ openapi: { document: "bookings" },
239
376
  anonymous: true,
240
377
  runtime: {
241
378
  entry: "@voyant-travel/finance",
@@ -243,6 +380,17 @@ export const financeBookingScheduleVoyantPlugin = defineExtension({
243
380
  },
244
381
  },
245
382
  ],
383
+ subscribers: [
384
+ {
385
+ id: "@voyant-travel/finance#subscriber.booking-schedule-confirmed",
386
+ eventType: "booking.confirmed",
387
+ source: "@voyant-travel/finance/booking-schedule-subscriber",
388
+ runtime: {
389
+ entry: "./booking-schedule-subscriber",
390
+ export: "bookingScheduleConfirmedSubscriber",
391
+ },
392
+ },
393
+ ],
246
394
  meta: {
247
395
  ownership: "package",
248
396
  },
@@ -0,0 +1,86 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "Booking Tax API",
5
+ "version": "1.0.0"
6
+ },
7
+ "paths": {
8
+ "/v1/admin/bookings/tax-settings": {
9
+ "get": {
10
+ "summary": "Get booking tax settings",
11
+ "x-voyant-api-id": "@voyant-travel/finance#booking-tax-extension.api",
12
+ "responses": {
13
+ "200": {
14
+ "description": "The effective booking tax settings",
15
+ "content": {
16
+ "application/json": {
17
+ "schema": {
18
+ "type": "object",
19
+ "required": ["data"],
20
+ "properties": { "data": { "$ref": "#/components/schemas/BookingTaxSettings" } }
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ },
27
+ "patch": {
28
+ "summary": "Update booking tax settings",
29
+ "x-voyant-api-id": "@voyant-travel/finance#booking-tax-extension.api",
30
+ "requestBody": {
31
+ "required": true,
32
+ "content": {
33
+ "application/json": {
34
+ "schema": {
35
+ "type": "object",
36
+ "properties": {
37
+ "taxPriceMode": { "type": "string", "enum": ["inclusive", "exclusive"] },
38
+ "taxPolicyProfileId": { "type": ["string", "null"] }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ },
44
+ "responses": {
45
+ "200": { "description": "The updated booking tax settings" },
46
+ "409": { "description": "This deployment does not support tax setting updates" }
47
+ }
48
+ }
49
+ },
50
+ "/v1/admin/bookings/tax-preview": {
51
+ "post": {
52
+ "summary": "Preview tax for a booking item subtotal",
53
+ "x-voyant-api-id": "@voyant-travel/finance#booking-tax-extension.api",
54
+ "requestBody": {
55
+ "required": true,
56
+ "content": {
57
+ "application/json": {
58
+ "schema": {
59
+ "type": "object",
60
+ "required": ["productId", "subtotalCents", "currency"],
61
+ "properties": {
62
+ "productId": { "type": "string", "minLength": 1 },
63
+ "subtotalCents": { "type": "integer", "minimum": 0 },
64
+ "currency": { "type": "string", "minLength": 3, "maxLength": 8 }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ },
70
+ "responses": { "200": { "description": "The calculated tax preview" } }
71
+ }
72
+ }
73
+ },
74
+ "components": {
75
+ "schemas": {
76
+ "BookingTaxSettings": {
77
+ "type": "object",
78
+ "required": ["taxPriceMode", "taxPolicyProfileId"],
79
+ "properties": {
80
+ "taxPriceMode": { "type": "string", "enum": ["inclusive", "exclusive"] },
81
+ "taxPolicyProfileId": { "type": ["string", "null"] }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }