@voyant-travel/finance 0.158.0 → 0.161.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.
- package/README.md +23 -0
- package/dist/invoice-issue-authorization.d.ts +69 -0
- package/dist/invoice-issue-authorization.js +156 -0
- package/dist/mcp-runtime.js +262 -2
- package/dist/refund-authorization.d.ts +68 -0
- package/dist/refund-authorization.js +184 -0
- package/dist/routes-invoice-issue.js +10 -76
- package/dist/routes-runtime.d.ts +1 -0
- package/dist/routes-shared.d.ts +1 -0
- package/dist/service-action-ledger-accounting.d.ts +22 -0
- package/dist/service-action-ledger-accounting.js +59 -45
- package/dist/service-booking-create.d.ts +2 -0
- package/dist/service-booking-create.js +3 -1
- package/dist/service-bookings-dual-create.d.ts +2 -0
- package/dist/service-invoice-credit-notes.d.ts +15 -0
- package/dist/service-invoice-credit-notes.js +20 -0
- package/dist/service-invoices.d.ts +15 -0
- package/dist/service-issue.d.ts +14 -0
- package/dist/service-issue.js +95 -2
- package/dist/service-shared.d.ts +12 -0
- package/dist/service.d.ts +15 -0
- package/dist/tools.d.ts +933 -3
- package/dist/tools.js +262 -11
- package/dist/voyant-admin.d.ts +4 -0
- package/dist/voyant-admin.js +1 -0
- package/dist/voyant.js +84 -12
- package/package.json +10 -10
package/dist/tools.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Finance agent tools on the framework tool contract. Thin
|
|
3
|
-
*
|
|
2
|
+
* Finance agent tools on the framework tool contract. Thin wrappers over the
|
|
3
|
+
* existing finance service; the service is injected on the tool context
|
|
4
4
|
* by intersection so this module stays deployment-agnostic.
|
|
5
|
+
* Refunds are issued through the credit-note service after action approval.
|
|
5
6
|
*/
|
|
6
|
-
import { defineTool, READ_ONLY_RISK, requireService } from "@voyant-travel/tools";
|
|
7
|
+
import { defineTool, READ_ONLY_RISK, requireService, ToolError, } from "@voyant-travel/tools";
|
|
8
|
+
import { listResponseSchema } from "@voyant-travel/types";
|
|
7
9
|
import { z } from "zod";
|
|
8
|
-
import {
|
|
10
|
+
import { creditNoteSchema, invoiceDetailSchema, invoiceListItemSchema, invoiceSchema, } from "./routes-invoice-schemas.js";
|
|
11
|
+
import { bookingCreateSchema } from "./service-booking-create.js";
|
|
12
|
+
import { insertCreditNoteSchema, invoiceFromBookingSchema, invoiceListQuerySchema, } from "./validation.js";
|
|
13
|
+
const voidInvoiceResultSchema = z.discriminatedUnion("status", [
|
|
14
|
+
z.object({ status: z.literal("not_found") }),
|
|
15
|
+
z.object({ status: z.literal("already_void"), invoice: invoiceSchema }),
|
|
16
|
+
z.object({ status: z.literal("draft"), invoice: invoiceSchema }),
|
|
17
|
+
z.object({ status: z.literal("invalid_status"), invoice: invoiceSchema }),
|
|
18
|
+
z.object({ status: z.literal("has_payments"), invoice: invoiceSchema }),
|
|
19
|
+
z.object({ status: z.literal("has_credit_notes"), invoice: invoiceSchema }),
|
|
20
|
+
z.object({ status: z.literal("voided"), invoice: invoiceSchema }),
|
|
21
|
+
]);
|
|
9
22
|
function finance(ctx) {
|
|
10
23
|
return requireService(ctx.finance, "finance");
|
|
11
24
|
}
|
|
@@ -13,12 +26,12 @@ export const listInvoicesTool = defineTool({
|
|
|
13
26
|
name: "list_invoices",
|
|
14
27
|
description: "List invoices with filters and pagination. Read-only.",
|
|
15
28
|
inputSchema: invoiceListQuerySchema,
|
|
16
|
-
outputSchema:
|
|
29
|
+
outputSchema: listResponseSchema(invoiceListItemSchema),
|
|
17
30
|
requiredScopes: ["finance:read"],
|
|
18
31
|
tier: "read",
|
|
19
32
|
riskPolicy: READ_ONLY_RISK,
|
|
20
33
|
async handler(query, ctx) {
|
|
21
|
-
return finance(ctx).listInvoices(query);
|
|
34
|
+
return parseJsonResult(listResponseSchema(invoiceListItemSchema), await finance(ctx).listInvoices(query));
|
|
22
35
|
},
|
|
23
36
|
});
|
|
24
37
|
const getInvoiceArgs = z.object({ id: z.string().min(1).describe("The invoice id.") });
|
|
@@ -26,12 +39,12 @@ export const getInvoiceTool = defineTool({
|
|
|
26
39
|
name: "get_invoice",
|
|
27
40
|
description: "Read a single invoice by id. Read-only.",
|
|
28
41
|
inputSchema: getInvoiceArgs,
|
|
29
|
-
outputSchema:
|
|
42
|
+
outputSchema: invoiceDetailSchema.nullable(),
|
|
30
43
|
requiredScopes: ["finance:read"],
|
|
31
44
|
tier: "read",
|
|
32
45
|
riskPolicy: READ_ONLY_RISK,
|
|
33
46
|
async handler({ id }, ctx) {
|
|
34
|
-
return finance(ctx).getInvoiceById(id);
|
|
47
|
+
return parseJsonResult(invoiceDetailSchema.nullable(), await finance(ctx).getInvoiceById(id));
|
|
35
48
|
},
|
|
36
49
|
});
|
|
37
50
|
const voidInvoiceArgs = z.object({
|
|
@@ -42,7 +55,7 @@ export const voidInvoiceTool = defineTool({
|
|
|
42
55
|
name: "void_invoice",
|
|
43
56
|
description: "Void an invoice (irreversible). Returns a not-found status when the invoice does not exist.",
|
|
44
57
|
inputSchema: voidInvoiceArgs,
|
|
45
|
-
outputSchema:
|
|
58
|
+
outputSchema: voidInvoiceResultSchema,
|
|
46
59
|
requiredScopes: ["finance:void"],
|
|
47
60
|
tier: "destructive",
|
|
48
61
|
riskPolicy: {
|
|
@@ -52,7 +65,245 @@ export const voidInvoiceTool = defineTool({
|
|
|
52
65
|
confirmationRequired: true,
|
|
53
66
|
},
|
|
54
67
|
async handler({ id, reason }, ctx) {
|
|
55
|
-
return finance(ctx).voidInvoice(id, { reason });
|
|
68
|
+
return parseJsonResult(voidInvoiceResultSchema, await finance(ctx).voidInvoice(id, { reason }));
|
|
56
69
|
},
|
|
57
70
|
});
|
|
58
|
-
export const
|
|
71
|
+
export const issueInvoiceRefundInputSchema = insertCreditNoteSchema.omit({ status: true }).extend({
|
|
72
|
+
invoiceId: z.string().min(1).describe("Invoice that receives the issued credit note."),
|
|
73
|
+
idempotencyKey: z
|
|
74
|
+
.string()
|
|
75
|
+
.trim()
|
|
76
|
+
.min(1)
|
|
77
|
+
.describe("Stable key used when requesting approval and replaying the command."),
|
|
78
|
+
approvalId: z
|
|
79
|
+
.string()
|
|
80
|
+
.trim()
|
|
81
|
+
.min(1)
|
|
82
|
+
.optional()
|
|
83
|
+
.describe("Approval id returned after the prior request is approved."),
|
|
84
|
+
});
|
|
85
|
+
const pendingFinanceApprovalSchema = z.object({
|
|
86
|
+
status: z.literal("approval_required"),
|
|
87
|
+
requestedAction: z.object({
|
|
88
|
+
id: z.string(),
|
|
89
|
+
status: z.string(),
|
|
90
|
+
actionName: z.string(),
|
|
91
|
+
targetType: z.string(),
|
|
92
|
+
targetId: z.string(),
|
|
93
|
+
}),
|
|
94
|
+
approval: z.object({
|
|
95
|
+
id: z.string(),
|
|
96
|
+
status: z.string(),
|
|
97
|
+
requestedActionId: z.string(),
|
|
98
|
+
policyName: z.string(),
|
|
99
|
+
policyVersion: z.string(),
|
|
100
|
+
riskSnapshot: z.string(),
|
|
101
|
+
reasonCode: z.string(),
|
|
102
|
+
expiresAt: z.string().datetime().nullable(),
|
|
103
|
+
createdAt: z.string().datetime(),
|
|
104
|
+
}),
|
|
105
|
+
replayed: z.boolean(),
|
|
106
|
+
});
|
|
107
|
+
export const issueInvoiceRefundOutputSchema = z.union([
|
|
108
|
+
pendingFinanceApprovalSchema,
|
|
109
|
+
z.object({ status: z.literal("issued"), creditNote: creditNoteSchema, replayed: z.boolean() }),
|
|
110
|
+
]);
|
|
111
|
+
export const issueInvoiceRefundTool = defineTool({
|
|
112
|
+
owner: "@voyant-travel/finance",
|
|
113
|
+
capabilityId: "@voyant-travel/finance#tool.issue-invoice-refund",
|
|
114
|
+
capabilityVersion: "v1",
|
|
115
|
+
name: "issue_invoice_refund",
|
|
116
|
+
description: "Request approval to refund an invoice by issuing a credit note, or execute the exact approved request.",
|
|
117
|
+
inputSchema: issueInvoiceRefundInputSchema,
|
|
118
|
+
outputSchema: issueInvoiceRefundOutputSchema,
|
|
119
|
+
requiredScopes: ["finance:refund"],
|
|
120
|
+
audience: { source: "grant", allowed: ["staff"] },
|
|
121
|
+
tier: "destructive",
|
|
122
|
+
riskPolicy: {
|
|
123
|
+
destructive: true,
|
|
124
|
+
reversible: false,
|
|
125
|
+
dryRunSupported: false,
|
|
126
|
+
confirmationRequired: true,
|
|
127
|
+
sideEffects: ["refund", "data-write"],
|
|
128
|
+
},
|
|
129
|
+
annotations: { idempotentHint: true },
|
|
130
|
+
actionPolicyEnforcement: "handler",
|
|
131
|
+
async handler(input, ctx) {
|
|
132
|
+
return issueInvoiceRefundOutputSchema.parse(await finance(ctx).issueInvoiceRefund(input));
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
const bookingCreateSummarySchema = z.object({
|
|
136
|
+
status: z.literal("created"),
|
|
137
|
+
booking: z.object({
|
|
138
|
+
id: z.string(),
|
|
139
|
+
bookingNumber: z.string(),
|
|
140
|
+
status: z.string(),
|
|
141
|
+
currency: z.string(),
|
|
142
|
+
amountCents: z.number().int().nullable(),
|
|
143
|
+
pax: z.number().int().nullable(),
|
|
144
|
+
}),
|
|
145
|
+
travelerIds: z.array(z.string()),
|
|
146
|
+
paymentSchedules: z.array(z.object({
|
|
147
|
+
id: z.string(),
|
|
148
|
+
scheduleType: z.string(),
|
|
149
|
+
status: z.string(),
|
|
150
|
+
dueDate: z.string(),
|
|
151
|
+
currency: z.string(),
|
|
152
|
+
amountCents: z.number().int(),
|
|
153
|
+
})),
|
|
154
|
+
invoice: z
|
|
155
|
+
.object({
|
|
156
|
+
id: z.string(),
|
|
157
|
+
invoiceNumber: z.string(),
|
|
158
|
+
invoiceType: z.string(),
|
|
159
|
+
status: z.string(),
|
|
160
|
+
})
|
|
161
|
+
.nullable(),
|
|
162
|
+
invoiceDocument: z.discriminatedUnion("status", [
|
|
163
|
+
z.object({ status: z.literal("requested"), renditionId: z.string().nullable() }),
|
|
164
|
+
z.object({ status: z.literal("generated"), renditionId: z.string() }),
|
|
165
|
+
z.object({ status: z.enum(["not_requested", "not_available", "failed"]) }),
|
|
166
|
+
]),
|
|
167
|
+
paymentIds: z.array(z.string()),
|
|
168
|
+
groupId: z.string().nullable(),
|
|
169
|
+
travelCreditRedemptionId: z.string().nullable(),
|
|
170
|
+
});
|
|
171
|
+
export const createBookingToolInputSchema = z.object({
|
|
172
|
+
booking: bookingCreateSchema.describe("The atomic product/slot booking command, including travelers, room/item lines, and schedules."),
|
|
173
|
+
});
|
|
174
|
+
export const createBookingTool = defineTool({
|
|
175
|
+
owner: "@voyant-travel/finance",
|
|
176
|
+
capabilityId: "@voyant-travel/finance#bookings-create-extension.tool.create-booking",
|
|
177
|
+
capabilityVersion: "v1",
|
|
178
|
+
name: "create_booking",
|
|
179
|
+
aliases: ["bookings_create"],
|
|
180
|
+
description: "Atomically create a booking from a product or slot with travelers, room/item lines, payment schedules, optional credit, group membership, and invoice documents.",
|
|
181
|
+
inputSchema: createBookingToolInputSchema,
|
|
182
|
+
outputSchema: bookingCreateSummarySchema,
|
|
183
|
+
requiredScopes: ["bookings:write", "finance:write"],
|
|
184
|
+
audience: { source: "grant", allowed: ["staff"] },
|
|
185
|
+
tier: "destructive",
|
|
186
|
+
riskPolicy: {
|
|
187
|
+
destructive: false,
|
|
188
|
+
reversible: true,
|
|
189
|
+
dryRunSupported: false,
|
|
190
|
+
confirmationRequired: true,
|
|
191
|
+
sideEffects: ["data-write", "external-booking", "payment"],
|
|
192
|
+
},
|
|
193
|
+
async handler({ booking }, ctx) {
|
|
194
|
+
const outcome = await finance(ctx).createBooking(booking);
|
|
195
|
+
if (outcome.status !== "ok") {
|
|
196
|
+
throw bookingCreateToolError(outcome);
|
|
197
|
+
}
|
|
198
|
+
const result = outcome.result;
|
|
199
|
+
return {
|
|
200
|
+
status: "created",
|
|
201
|
+
booking: {
|
|
202
|
+
id: result.booking.id,
|
|
203
|
+
bookingNumber: result.booking.bookingNumber,
|
|
204
|
+
status: result.booking.status,
|
|
205
|
+
currency: result.booking.sellCurrency,
|
|
206
|
+
amountCents: result.booking.sellAmountCents,
|
|
207
|
+
pax: result.booking.pax,
|
|
208
|
+
},
|
|
209
|
+
travelerIds: result.travelers.map((traveler) => traveler.id),
|
|
210
|
+
paymentSchedules: result.paymentSchedules.map((schedule) => ({
|
|
211
|
+
id: schedule.id,
|
|
212
|
+
scheduleType: schedule.scheduleType,
|
|
213
|
+
status: schedule.status,
|
|
214
|
+
dueDate: schedule.dueDate,
|
|
215
|
+
currency: schedule.currency,
|
|
216
|
+
amountCents: schedule.amountCents,
|
|
217
|
+
})),
|
|
218
|
+
invoice: result.invoice
|
|
219
|
+
? {
|
|
220
|
+
id: result.invoice.id,
|
|
221
|
+
invoiceNumber: result.invoice.invoiceNumber,
|
|
222
|
+
invoiceType: result.invoice.invoiceType,
|
|
223
|
+
status: result.invoice.status,
|
|
224
|
+
}
|
|
225
|
+
: null,
|
|
226
|
+
invoiceDocument: result.invoiceDocument,
|
|
227
|
+
paymentIds: result.payments.map((payment) => payment.id),
|
|
228
|
+
groupId: result.groupMembership?.groupId ?? null,
|
|
229
|
+
travelCreditRedemptionId: result.travelCreditRedemption?.redemption.id ?? null,
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
export const financeBookingsCreateTools = [createBookingTool];
|
|
234
|
+
export const issueInvoiceFromBookingToolInputSchema = z.object({
|
|
235
|
+
command: invoiceFromBookingSchema.describe("The exact invoice or proforma issue command."),
|
|
236
|
+
idempotencyKey: z
|
|
237
|
+
.string()
|
|
238
|
+
.trim()
|
|
239
|
+
.min(1)
|
|
240
|
+
.describe("Stable key used when requesting approval and replaying the exact command."),
|
|
241
|
+
approvalId: z
|
|
242
|
+
.string()
|
|
243
|
+
.trim()
|
|
244
|
+
.min(1)
|
|
245
|
+
.optional()
|
|
246
|
+
.describe("Approval id returned after the exact prior command is approved."),
|
|
247
|
+
});
|
|
248
|
+
export const issueInvoiceFromBookingToolOutputSchema = z.union([
|
|
249
|
+
pendingFinanceApprovalSchema,
|
|
250
|
+
z.object({ status: z.literal("issued"), invoice: invoiceSchema, replayed: z.boolean() }),
|
|
251
|
+
]);
|
|
252
|
+
export const issueInvoiceFromBookingTool = defineTool({
|
|
253
|
+
owner: "@voyant-travel/finance",
|
|
254
|
+
capabilityId: "@voyant-travel/finance#tool.issue-invoice-from-booking",
|
|
255
|
+
capabilityVersion: "v1",
|
|
256
|
+
name: "issue_invoice_from_booking",
|
|
257
|
+
aliases: ["invoices_issue_from_booking"],
|
|
258
|
+
description: "Request approval to create and issue an invoice or proforma from a booking, or execute and idempotently replay the exact approved command.",
|
|
259
|
+
inputSchema: issueInvoiceFromBookingToolInputSchema,
|
|
260
|
+
outputSchema: issueInvoiceFromBookingToolOutputSchema,
|
|
261
|
+
requiredScopes: ["finance:write", "bookings:read"],
|
|
262
|
+
audience: { source: "grant", allowed: ["staff"] },
|
|
263
|
+
actionPolicyEnforcement: "handler",
|
|
264
|
+
tier: "destructive",
|
|
265
|
+
riskPolicy: {
|
|
266
|
+
destructive: false,
|
|
267
|
+
reversible: false,
|
|
268
|
+
dryRunSupported: false,
|
|
269
|
+
confirmationRequired: true,
|
|
270
|
+
sideEffects: ["data-write"],
|
|
271
|
+
},
|
|
272
|
+
annotations: { idempotentHint: true },
|
|
273
|
+
async handler(input, ctx) {
|
|
274
|
+
return issueInvoiceFromBookingToolOutputSchema.parse(await finance(ctx).issueInvoiceFromBooking(input));
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
export const financeTools = [
|
|
278
|
+
listInvoicesTool,
|
|
279
|
+
getInvoiceTool,
|
|
280
|
+
voidInvoiceTool,
|
|
281
|
+
issueInvoiceRefundTool,
|
|
282
|
+
issueInvoiceFromBookingTool,
|
|
283
|
+
];
|
|
284
|
+
function parseJsonResult(schema, value) {
|
|
285
|
+
return schema.parse(toJsonValue(value));
|
|
286
|
+
}
|
|
287
|
+
function bookingCreateToolError(outcome) {
|
|
288
|
+
switch (outcome.status) {
|
|
289
|
+
case "product_not_found":
|
|
290
|
+
case "travel_credit_not_found":
|
|
291
|
+
case "group_not_found":
|
|
292
|
+
return new ToolError(`Booking create failed: ${outcome.status}`, "NOT_FOUND", { outcome });
|
|
293
|
+
default:
|
|
294
|
+
return new ToolError(`Booking create rejected: ${outcome.status}`, "INVALID_INPUT", {
|
|
295
|
+
outcome,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function toJsonValue(value) {
|
|
300
|
+
if (value instanceof Date)
|
|
301
|
+
return value.toISOString();
|
|
302
|
+
if (Array.isArray(value))
|
|
303
|
+
return value.map(toJsonValue);
|
|
304
|
+
if (typeof value !== "object" || value === null)
|
|
305
|
+
return value;
|
|
306
|
+
return Object.fromEntries(Object.entries(value)
|
|
307
|
+
.map(([key, nested]) => [key, toJsonValue(nested)])
|
|
308
|
+
.filter(([, nested]) => nested !== undefined));
|
|
309
|
+
}
|
package/dist/voyant-admin.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/** Static admin contribution metadata used by the Finance deployment manifest. */
|
|
2
2
|
export declare const financeVoyantAdmin: {
|
|
3
3
|
readonly compositionOrder: 40;
|
|
4
|
+
readonly setupSteps: readonly [{
|
|
5
|
+
readonly id: "@voyant-travel/finance#setup.fiscal-settings";
|
|
6
|
+
readonly skippable: true;
|
|
7
|
+
}];
|
|
4
8
|
readonly runtime: {
|
|
5
9
|
readonly entry: "@voyant-travel/finance-react/admin";
|
|
6
10
|
readonly export: "createSelectedFinanceAdminExtension";
|
package/dist/voyant-admin.js
CHANGED
|
@@ -5,6 +5,7 @@ const financeAdminRuntime = {
|
|
|
5
5
|
/** Static admin contribution metadata used by the Finance deployment manifest. */
|
|
6
6
|
export const financeVoyantAdmin = {
|
|
7
7
|
compositionOrder: 40,
|
|
8
|
+
setupSteps: [{ id: "@voyant-travel/finance#setup.fiscal-settings", skippable: true }],
|
|
8
9
|
runtime: {
|
|
9
10
|
entry: "@voyant-travel/finance-react/admin",
|
|
10
11
|
export: "createSelectedFinanceAdminExtension",
|
package/dist/voyant.js
CHANGED
|
@@ -3,7 +3,7 @@ import { bookingsFinanceRuntimePort } from "@voyant-travel/bookings/runtime-port
|
|
|
3
3
|
import { defineExtension, defineModule, providePort, requirePort, } from "@voyant-travel/core/project";
|
|
4
4
|
import { financeAccommodationsPaymentPolicyRuntimePort, financeCheckoutPaymentStartersRuntimePort, financeCruisesPaymentPolicyRuntimePort, financeDistributionPaymentPolicyRuntimePort, financeHostRuntimePort, financeInventoryPaymentPolicyRuntimePort, financeInvoiceSettlementPollerRuntimePort, financeNotificationsRuntimePort, financeOperatorSettingsRuntimePort, } from "./runtime-port.js";
|
|
5
5
|
import { financeVoyantAdmin } from "./voyant-admin.js";
|
|
6
|
-
import {
|
|
6
|
+
import { bookingContractDocumentRequestedPayloadSchema, bookingCreatedPayloadSchema, bookingCreateRejectedPayloadSchema, bookingDualCreatedPayloadSchema, bookingPaymentSchedulePaidPayloadSchema, invoiceDocumentGeneratedPayloadSchema, invoiceIssuedPayloadSchema, invoicePaymentRecordedPayloadSchema, invoiceProformaConvertedPayloadSchema, invoiceRenderedPayloadSchema, invoiceSettledPayloadSchema, invoiceVoidedPayloadSchema, paymentCompletedPayloadSchema, } from "./voyant-event-schemas.js";
|
|
7
7
|
/** Import-cheap deployment declaration owned by the finance package. */
|
|
8
8
|
export const financeVoyantModule = defineModule({
|
|
9
9
|
id: "@voyant-travel/finance",
|
|
@@ -20,7 +20,7 @@ export const financeVoyantModule = defineModule({
|
|
|
20
20
|
}),
|
|
21
21
|
],
|
|
22
22
|
provides: {
|
|
23
|
-
capabilities: ["finance.payment-sessions"],
|
|
23
|
+
capabilities: ["finance.data-owner", "finance.payment-sessions"],
|
|
24
24
|
ports: [
|
|
25
25
|
providePort(actionLedgerFinanceDriftRuntimePort),
|
|
26
26
|
providePort(bookingsFinanceRuntimePort),
|
|
@@ -173,14 +173,6 @@ export const financeVoyantModule = defineModule({
|
|
|
173
173
|
visibility: "internal",
|
|
174
174
|
audit: { sourceModule: "finance", category: "domain" },
|
|
175
175
|
},
|
|
176
|
-
{
|
|
177
|
-
id: "@voyant-travel/finance#event.booking.confirmed",
|
|
178
|
-
eventType: "booking.confirmed",
|
|
179
|
-
version: "1.0.0",
|
|
180
|
-
payloadSchema: bookingConfirmedPayloadSchema,
|
|
181
|
-
visibility: "internal",
|
|
182
|
-
audit: { sourceModule: "finance", category: "domain" },
|
|
183
|
-
},
|
|
184
176
|
{
|
|
185
177
|
id: "@voyant-travel/finance#event.booking.dual-created",
|
|
186
178
|
eventType: "booking.dual-created",
|
|
@@ -246,8 +238,8 @@ export const financeVoyantModule = defineModule({
|
|
|
246
238
|
},
|
|
247
239
|
{
|
|
248
240
|
action: "refund",
|
|
249
|
-
label: "
|
|
250
|
-
description: "Issue
|
|
241
|
+
label: "Issue invoice refunds",
|
|
242
|
+
description: "Issue a credit note against an eligible invoice.",
|
|
251
243
|
sensitive: true,
|
|
252
244
|
},
|
|
253
245
|
{
|
|
@@ -285,6 +277,25 @@ export const financeVoyantModule = defineModule({
|
|
|
285
277
|
context: ["finance"],
|
|
286
278
|
risk: "critical",
|
|
287
279
|
},
|
|
280
|
+
{
|
|
281
|
+
id: "@voyant-travel/finance#tool.issue-invoice-refund",
|
|
282
|
+
name: "issue_invoice_refund",
|
|
283
|
+
runtime: { entry: "@voyant-travel/finance/tools", export: "issueInvoiceRefundTool" },
|
|
284
|
+
requiredScopes: ["finance:refund"],
|
|
285
|
+
context: ["finance"],
|
|
286
|
+
risk: "critical",
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
id: "@voyant-travel/finance#tool.issue-invoice-from-booking",
|
|
290
|
+
name: "issue_invoice_from_booking",
|
|
291
|
+
runtime: {
|
|
292
|
+
entry: "@voyant-travel/finance/tools",
|
|
293
|
+
export: "issueInvoiceFromBookingTool",
|
|
294
|
+
},
|
|
295
|
+
requiredScopes: ["finance:write", "bookings:read"],
|
|
296
|
+
context: ["finance"],
|
|
297
|
+
risk: "high",
|
|
298
|
+
},
|
|
288
299
|
],
|
|
289
300
|
actions: [
|
|
290
301
|
{
|
|
@@ -301,6 +312,38 @@ export const financeVoyantModule = defineModule({
|
|
|
301
312
|
reversible: false,
|
|
302
313
|
from: { tools: ["@voyant-travel/finance#tool.void-invoice"] },
|
|
303
314
|
},
|
|
315
|
+
{
|
|
316
|
+
id: "@voyant-travel/finance#action.issue-invoice-refund",
|
|
317
|
+
capabilityId: "finance:refund",
|
|
318
|
+
version: "v1",
|
|
319
|
+
kind: "execute",
|
|
320
|
+
targetType: "invoice",
|
|
321
|
+
resource: "finance",
|
|
322
|
+
action: "refund",
|
|
323
|
+
requiredScopes: ["finance:refund"],
|
|
324
|
+
risk: "critical",
|
|
325
|
+
ledger: "required",
|
|
326
|
+
approval: "required",
|
|
327
|
+
reversible: false,
|
|
328
|
+
allowedActorTypes: ["staff", "system"],
|
|
329
|
+
from: { tools: ["@voyant-travel/finance#tool.issue-invoice-refund"] },
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
id: "@voyant-travel/finance#action.issue-invoice-from-booking",
|
|
333
|
+
capabilityId: "finance:invoice-issue-from-booking",
|
|
334
|
+
version: "v1",
|
|
335
|
+
kind: "execute",
|
|
336
|
+
targetType: "booking",
|
|
337
|
+
resource: "finance",
|
|
338
|
+
action: "write",
|
|
339
|
+
requiredScopes: ["finance:write", "bookings:read"],
|
|
340
|
+
risk: "high",
|
|
341
|
+
ledger: "required",
|
|
342
|
+
approval: "required",
|
|
343
|
+
reversible: false,
|
|
344
|
+
allowedActorTypes: ["staff", "system"],
|
|
345
|
+
from: { tools: ["@voyant-travel/finance#tool.issue-invoice-from-booking"] },
|
|
346
|
+
},
|
|
304
347
|
],
|
|
305
348
|
admin: financeVoyantAdmin,
|
|
306
349
|
presentations: [
|
|
@@ -359,6 +402,35 @@ export const financeBookingsCreateVoyantPlugin = defineExtension({
|
|
|
359
402
|
},
|
|
360
403
|
},
|
|
361
404
|
],
|
|
405
|
+
tools: [
|
|
406
|
+
{
|
|
407
|
+
id: "@voyant-travel/finance#bookings-create-extension.tool.create-booking",
|
|
408
|
+
name: "create_booking",
|
|
409
|
+
runtime: { entry: "@voyant-travel/finance/tools", export: "createBookingTool" },
|
|
410
|
+
requiredScopes: ["bookings:write", "finance:write"],
|
|
411
|
+
context: ["finance"],
|
|
412
|
+
risk: "high",
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
actions: [
|
|
416
|
+
{
|
|
417
|
+
id: "@voyant-travel/finance#bookings-create-extension.action.create-booking",
|
|
418
|
+
version: "v1",
|
|
419
|
+
kind: "execute",
|
|
420
|
+
targetType: "booking",
|
|
421
|
+
resource: "bookings",
|
|
422
|
+
action: "write",
|
|
423
|
+
requiredScopes: ["bookings:write", "finance:write"],
|
|
424
|
+
risk: "high",
|
|
425
|
+
ledger: "required",
|
|
426
|
+
approval: "never",
|
|
427
|
+
reversible: true,
|
|
428
|
+
allowedActorTypes: ["staff"],
|
|
429
|
+
from: {
|
|
430
|
+
tools: ["@voyant-travel/finance#bookings-create-extension.tool.create-booking"],
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
],
|
|
362
434
|
meta: {
|
|
363
435
|
ownership: "package",
|
|
364
436
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyant-travel/finance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.161.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -145,17 +145,17 @@
|
|
|
145
145
|
"fflate": "^0.8.2",
|
|
146
146
|
"hono": "^4.12.27",
|
|
147
147
|
"zod": "^4.4.3",
|
|
148
|
-
"@voyant-travel/action-ledger": "^0.
|
|
149
|
-
"@voyant-travel/bookings": "^0.
|
|
150
|
-
"@voyant-travel/core": "^0.
|
|
151
|
-
"@voyant-travel/db": "^0.114.
|
|
152
|
-
"@voyant-travel/finance-contracts": "^0.106.1",
|
|
148
|
+
"@voyant-travel/action-ledger": "^0.109.1",
|
|
149
|
+
"@voyant-travel/bookings": "^0.161.0",
|
|
150
|
+
"@voyant-travel/core": "^0.124.0",
|
|
151
|
+
"@voyant-travel/db": "^0.114.7",
|
|
153
152
|
"@voyant-travel/types": "^0.109.2",
|
|
154
|
-
"@voyant-travel/
|
|
155
|
-
"@voyant-travel/
|
|
153
|
+
"@voyant-travel/finance-contracts": "^0.106.1",
|
|
154
|
+
"@voyant-travel/hono": "^0.127.2",
|
|
155
|
+
"@voyant-travel/public-document-delivery": "^0.3.7",
|
|
156
|
+
"@voyant-travel/storage": "^0.110.2",
|
|
156
157
|
"@voyant-travel/utils": "^0.107.1",
|
|
157
|
-
"@voyant-travel/
|
|
158
|
-
"@voyant-travel/tools": "^0.2.1"
|
|
158
|
+
"@voyant-travel/tools": "^0.3.0"
|
|
159
159
|
},
|
|
160
160
|
"devDependencies": {
|
|
161
161
|
"drizzle-kit": "^0.31.10",
|