@voyant-travel/finance 0.138.4 → 0.138.6

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 (34) hide show
  1. package/dist/routes-invoice-core.d.ts +95 -11
  2. package/dist/routes-invoice-core.d.ts.map +1 -1
  3. package/dist/routes-invoice-core.js +137 -43
  4. package/dist/routes-invoice-issue.d.ts.map +1 -1
  5. package/dist/routes-invoice-issue.js +27 -2
  6. package/dist/routes-payments.d.ts +83 -0
  7. package/dist/routes-payments.d.ts.map +1 -1
  8. package/dist/routes-payments.js +66 -23
  9. package/dist/routes-reference-data.d.ts.map +1 -1
  10. package/dist/routes-reference-data.js +23 -3
  11. package/dist/routes-supplier-invoices.d.ts +72 -0
  12. package/dist/routes-supplier-invoices.d.ts.map +1 -1
  13. package/dist/routes-supplier-invoices.js +47 -13
  14. package/dist/routes.d.ts +178 -11
  15. package/dist/routes.d.ts.map +1 -1
  16. package/dist/service-invoice-core.d.ts.map +1 -1
  17. package/dist/service-invoice-core.js +55 -4
  18. package/dist/service-invoice-credit-notes.d.ts.map +1 -1
  19. package/dist/service-invoice-credit-notes.js +49 -1
  20. package/dist/service-invoice-line-items.d.ts.map +1 -1
  21. package/dist/service-invoice-line-items.js +28 -1
  22. package/dist/service-invoice-payments.d.ts.map +1 -1
  23. package/dist/service-invoice-payments.js +27 -1
  24. package/dist/service-reference-data.d.ts.map +1 -1
  25. package/dist/service-reference-data.js +26 -0
  26. package/dist/service-shared.d.ts +9 -0
  27. package/dist/service-shared.d.ts.map +1 -1
  28. package/dist/service-shared.js +12 -0
  29. package/dist/service-supplier-invoices.d.ts +3 -1
  30. package/dist/service-supplier-invoices.d.ts.map +1 -1
  31. package/dist/service-supplier-invoices.js +89 -0
  32. package/dist/service-supplier-payments.d.ts.map +1 -1
  33. package/dist/service-supplier-payments.js +62 -1
  34. package/package.json +5 -5
@@ -274,6 +274,29 @@ export declare const financeInvoiceCoreRoutes: OpenAPIHono<Env, import("hono/typ
274
274
  };
275
275
  outputFormat: "json";
276
276
  status: 400;
277
+ } | {
278
+ input: {
279
+ param: {
280
+ id: string;
281
+ };
282
+ } & {
283
+ json: {
284
+ creditNoteNumber: string;
285
+ amountCents: number;
286
+ currency: string;
287
+ reason: string;
288
+ status?: "draft" | "issued" | "applied" | undefined;
289
+ baseCurrency?: string | null | undefined;
290
+ baseAmountCents?: number | null | undefined;
291
+ fxRateSetId?: string | null | undefined;
292
+ notes?: string | null | undefined;
293
+ };
294
+ };
295
+ output: {
296
+ error: string;
297
+ };
298
+ outputFormat: "json";
299
+ status: 409;
277
300
  } | {
278
301
  input: {
279
302
  param: {
@@ -363,6 +386,30 @@ export declare const financeInvoiceCoreRoutes: OpenAPIHono<Env, import("hono/typ
363
386
  };
364
387
  outputFormat: "json";
365
388
  status: 400;
389
+ } | {
390
+ input: {
391
+ param: {
392
+ id: string;
393
+ creditNoteId: string;
394
+ };
395
+ } & {
396
+ json: {
397
+ creditNoteNumber?: string | undefined;
398
+ status?: "draft" | "issued" | "applied" | undefined;
399
+ amountCents?: number | undefined;
400
+ currency?: string | undefined;
401
+ baseCurrency?: string | null | undefined;
402
+ baseAmountCents?: number | null | undefined;
403
+ fxRateSetId?: string | null | undefined;
404
+ reason?: string | undefined;
405
+ notes?: string | null | undefined;
406
+ };
407
+ };
408
+ output: {
409
+ error: string;
410
+ };
411
+ outputFormat: "json";
412
+ status: 409;
366
413
  } | {
367
414
  input: {
368
415
  param: {
@@ -1005,6 +1052,43 @@ export declare const financeInvoiceCoreRoutes: OpenAPIHono<Env, import("hono/typ
1005
1052
  };
1006
1053
  outputFormat: "json";
1007
1054
  status: 400;
1055
+ } | {
1056
+ input: {
1057
+ param: {
1058
+ id: string;
1059
+ };
1060
+ } & {
1061
+ json: {
1062
+ invoiceNumber?: string | undefined;
1063
+ bookingId?: string | undefined;
1064
+ personId?: string | null | undefined;
1065
+ organizationId?: string | null | undefined;
1066
+ status?: "draft" | "pending_external_allocation" | "issued" | "partially_paid" | "paid" | "overdue" | "void" | undefined;
1067
+ currency?: string | undefined;
1068
+ baseCurrency?: string | null | undefined;
1069
+ fxRateSetId?: string | null | undefined;
1070
+ subtotalCents?: number | undefined;
1071
+ baseSubtotalCents?: number | null | undefined;
1072
+ taxCents?: number | undefined;
1073
+ baseTaxCents?: number | null | undefined;
1074
+ totalCents?: number | undefined;
1075
+ baseTotalCents?: number | null | undefined;
1076
+ paidCents?: number | undefined;
1077
+ basePaidCents?: number | null | undefined;
1078
+ balanceDueCents?: number | undefined;
1079
+ baseBalanceDueCents?: number | null | undefined;
1080
+ commissionPercent?: number | null | undefined;
1081
+ commissionAmountCents?: number | null | undefined;
1082
+ issueDate?: string | undefined;
1083
+ dueDate?: string | undefined;
1084
+ notes?: string | null | undefined;
1085
+ };
1086
+ };
1087
+ output: {
1088
+ error: string;
1089
+ };
1090
+ outputFormat: "json";
1091
+ status: 409;
1008
1092
  };
1009
1093
  };
1010
1094
  } & {
@@ -1068,6 +1152,17 @@ export declare const financeInvoiceCoreRoutes: OpenAPIHono<Env, import("hono/typ
1068
1152
  };
1069
1153
  outputFormat: "json";
1070
1154
  status: 400;
1155
+ } | {
1156
+ input: {
1157
+ param: {
1158
+ id: string;
1159
+ };
1160
+ };
1161
+ output: {
1162
+ error: string;
1163
+ };
1164
+ outputFormat: "json";
1165
+ status: 409;
1071
1166
  } | {
1072
1167
  input: {
1073
1168
  param: {
@@ -1115,17 +1210,6 @@ export declare const financeInvoiceCoreRoutes: OpenAPIHono<Env, import("hono/typ
1115
1210
  };
1116
1211
  outputFormat: "json";
1117
1212
  status: 200;
1118
- } | {
1119
- input: {
1120
- param: {
1121
- id: string;
1122
- };
1123
- };
1124
- output: {
1125
- error: string;
1126
- };
1127
- outputFormat: "json";
1128
- status: 409;
1129
1213
  };
1130
1214
  };
1131
1215
  } & {
@@ -1 +1 @@
1
- {"version":3,"file":"routes-invoice-core.d.ts","sourceRoot":"","sources":["../src/routes-invoice-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAe/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AAgqB7C,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAQZ,CAAA"}
1
+ {"version":3,"file":"routes-invoice-core.d.ts","sourceRoot":"","sources":["../src/routes-invoice-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAe/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AAgwB7C,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAQZ,CAAA"}
@@ -25,7 +25,7 @@ import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
25
25
  import { openApiValidationHook, parseOptionalJsonBody, requireUserId } from "@voyant-travel/hono";
26
26
  import { creditNoteLineItemSchema, creditNoteSchema, errorResponseSchema, financeNoteSchema, invoiceDetailSchema, invoiceLineItemSchema, invoiceSchema, paymentSchema, paymentSessionSchema, successResponseSchema, } from "./routes-invoice-schemas.js";
27
27
  import { getActionLedgerRequestContext, getFinanceRouteRuntime } from "./routes-runtime.js";
28
- import { financeService, PaymentValidationError } from "./service.js";
28
+ import { financeService, InvoiceNumberConflictError, InvoiceValidationError, PaymentValidationError, } from "./service.js";
29
29
  import { createPaymentSessionFromInvoiceSchema, insertCreditNoteLineItemSchema, insertCreditNoteSchema, insertFinanceNoteSchema, insertInvoiceLineItemSchema, insertPaymentSchema, updateCreditNoteSchema, updateInvoiceLineItemSchema, updateInvoiceSchema, voidInvoiceSchema, } from "./validation.js";
30
30
  const idParamSchema = z.object({ id: z.string() });
31
31
  const lineParamSchema = z.object({ id: z.string(), lineId: z.string() });
@@ -69,6 +69,10 @@ const updateInvoiceRoute = createRoute({
69
69
  description: "Invoice not found",
70
70
  content: { "application/json": { schema: errorResponseSchema } },
71
71
  },
72
+ 409: {
73
+ description: "Invoice number already exists",
74
+ content: { "application/json": { schema: errorResponseSchema } },
75
+ },
72
76
  },
73
77
  });
74
78
  const deleteInvoiceRoute = createRoute({
@@ -154,13 +158,28 @@ const invoiceActionRoutes = new OpenAPIHono({ defaultHook: openApiValidationHook
154
158
  return row ? c.json({ data: row }, 200) : c.json({ error: "Invoice not found" }, 404);
155
159
  })
156
160
  .openapi(updateInvoiceRoute, async (c) => {
157
- const runtime = getFinanceRouteRuntime(c);
158
- const row = await financeService.updateInvoice(c.get("db"), c.req.valid("param").id, c.req.valid("json"), {
159
- eventBus: runtime?.eventBus,
160
- actionLedgerContext: getActionLedgerRequestContext(c),
161
- actionLedgerAuthorizationSource: "finance.invoice.route",
162
- });
163
- return row ? c.json({ data: row }, 200) : c.json({ error: "Invoice not found" }, 404);
161
+ try {
162
+ const runtime = getFinanceRouteRuntime(c);
163
+ const row = await financeService.updateInvoice(c.get("db"), c.req.valid("param").id, c.req.valid("json"), {
164
+ eventBus: runtime?.eventBus,
165
+ actionLedgerContext: getActionLedgerRequestContext(c),
166
+ actionLedgerAuthorizationSource: "finance.invoice.route",
167
+ });
168
+ return row ? c.json({ data: row }, 200) : c.json({ error: "Invoice not found" }, 404);
169
+ }
170
+ catch (error) {
171
+ if (error instanceof InvoiceNumberConflictError) {
172
+ return c.json({
173
+ error: "Invoice number already exists",
174
+ code: error.code,
175
+ invoiceNumber: error.invoiceNumber,
176
+ }, 409);
177
+ }
178
+ if (error instanceof InvoiceValidationError) {
179
+ return c.json({ error: error.message, code: error.code, details: error.details }, error.status);
180
+ }
181
+ throw error;
182
+ }
164
183
  })
165
184
  .openapi(deleteInvoiceRoute, async (c) => {
166
185
  const runtime = getFinanceRouteRuntime(c);
@@ -304,22 +323,48 @@ const deleteInvoiceLineItemRoute = createRoute({
304
323
  const invoiceLineItemRoutes = new OpenAPIHono({ defaultHook: openApiValidationHook })
305
324
  .openapi(listInvoiceLineItemsRoute, async (c) => c.json({ data: await financeService.listInvoiceLineItems(c.get("db"), c.req.valid("param").id) }, 200))
306
325
  .openapi(createInvoiceLineItemRoute, async (c) => {
307
- const runtime = getFinanceRouteRuntime(c);
308
- const row = await financeService.createInvoiceLineItem(c.get("db"), c.req.valid("param").id, c.req.valid("json"), {
309
- eventBus: runtime?.eventBus,
310
- actionLedgerContext: getActionLedgerRequestContext(c),
311
- actionLedgerAuthorizationSource: "finance.invoice_line_item.route",
312
- });
313
- return row ? c.json({ data: row }, 201) : c.json({ error: "Invoice not found" }, 404);
326
+ try {
327
+ const runtime = getFinanceRouteRuntime(c);
328
+ const row = await financeService.createInvoiceLineItem(c.get("db"), c.req.valid("param").id, c.req.valid("json"), {
329
+ eventBus: runtime?.eventBus,
330
+ actionLedgerContext: getActionLedgerRequestContext(c),
331
+ actionLedgerAuthorizationSource: "finance.invoice_line_item.route",
332
+ });
333
+ return row ? c.json({ data: row }, 201) : c.json({ error: "Invoice not found" }, 404);
334
+ }
335
+ catch (error) {
336
+ if (error instanceof InvoiceValidationError) {
337
+ if (error.status === 404) {
338
+ return c.json({ error: error.message, code: error.code, details: error.details }, 404);
339
+ }
340
+ if (error.status === 409)
341
+ throw error;
342
+ return c.json({ error: error.message, code: error.code, details: error.details }, 400);
343
+ }
344
+ throw error;
345
+ }
314
346
  })
315
347
  .openapi(updateInvoiceLineItemRoute, async (c) => {
316
- const runtime = getFinanceRouteRuntime(c);
317
- const row = await financeService.updateInvoiceLineItem(c.get("db"), c.req.valid("param").lineId, c.req.valid("json"), {
318
- eventBus: runtime?.eventBus,
319
- actionLedgerContext: getActionLedgerRequestContext(c),
320
- actionLedgerAuthorizationSource: "finance.invoice_line_item.route",
321
- });
322
- return row ? c.json({ data: row }, 200) : c.json({ error: "Line item not found" }, 404);
348
+ try {
349
+ const runtime = getFinanceRouteRuntime(c);
350
+ const row = await financeService.updateInvoiceLineItem(c.get("db"), c.req.valid("param").lineId, c.req.valid("json"), {
351
+ eventBus: runtime?.eventBus,
352
+ actionLedgerContext: getActionLedgerRequestContext(c),
353
+ actionLedgerAuthorizationSource: "finance.invoice_line_item.route",
354
+ });
355
+ return row ? c.json({ data: row }, 200) : c.json({ error: "Line item not found" }, 404);
356
+ }
357
+ catch (error) {
358
+ if (error instanceof InvoiceValidationError) {
359
+ if (error.status === 404) {
360
+ return c.json({ error: error.message, code: error.code, details: error.details }, 404);
361
+ }
362
+ if (error.status === 409)
363
+ throw error;
364
+ return c.json({ error: error.message, code: error.code, details: error.details }, 400);
365
+ }
366
+ throw error;
367
+ }
323
368
  })
324
369
  .openapi(deleteInvoiceLineItemRoute, async (c) => {
325
370
  const runtime = getFinanceRouteRuntime(c);
@@ -428,6 +473,10 @@ const createCreditNoteRoute = createRoute({
428
473
  description: "Invoice not found",
429
474
  content: { "application/json": { schema: errorResponseSchema } },
430
475
  },
476
+ 409: {
477
+ description: "Credit note would exceed the invoice balance due",
478
+ content: { "application/json": { schema: errorResponseSchema } },
479
+ },
431
480
  },
432
481
  });
433
482
  const updateCreditNoteRoute = createRoute({
@@ -453,27 +502,59 @@ const updateCreditNoteRoute = createRoute({
453
502
  description: "Credit note not found",
454
503
  content: { "application/json": { schema: errorResponseSchema } },
455
504
  },
505
+ 409: {
506
+ description: "Credit note would exceed the invoice balance due",
507
+ content: { "application/json": { schema: errorResponseSchema } },
508
+ },
456
509
  },
457
510
  });
458
511
  const creditNoteRoutes = new OpenAPIHono({ defaultHook: openApiValidationHook })
459
512
  .openapi(listCreditNotesRoute, async (c) => c.json({ data: await financeService.listCreditNotes(c.get("db"), c.req.valid("param").id) }, 200))
460
513
  .openapi(createCreditNoteRoute, async (c) => {
461
- const runtime = getFinanceRouteRuntime(c);
462
- const row = await financeService.createCreditNote(c.get("db"), c.req.valid("param").id, c.req.valid("json"), {
463
- ...(runtime ?? {}),
464
- actionLedgerContext: getActionLedgerRequestContext(c),
465
- actionLedgerAuthorizationSource: "finance.credit_note.route",
466
- });
467
- return row ? c.json({ data: row }, 201) : c.json({ error: "Invoice not found" }, 404);
514
+ try {
515
+ const runtime = getFinanceRouteRuntime(c);
516
+ const row = await financeService.createCreditNote(c.get("db"), c.req.valid("param").id, c.req.valid("json"), {
517
+ ...(runtime ?? {}),
518
+ actionLedgerContext: getActionLedgerRequestContext(c),
519
+ actionLedgerAuthorizationSource: "finance.credit_note.route",
520
+ });
521
+ return row ? c.json({ data: row }, 201) : c.json({ error: "Invoice not found" }, 404);
522
+ }
523
+ catch (error) {
524
+ if (error instanceof InvoiceValidationError) {
525
+ if (error.status === 404) {
526
+ return c.json({ error: error.message, code: error.code, details: error.details }, 404);
527
+ }
528
+ if (error.status === 409) {
529
+ return c.json({ error: error.message, code: error.code, details: error.details }, 409);
530
+ }
531
+ return c.json({ error: error.message, code: error.code, details: error.details }, 400);
532
+ }
533
+ throw error;
534
+ }
468
535
  })
469
536
  .openapi(updateCreditNoteRoute, async (c) => {
470
- const runtime = getFinanceRouteRuntime(c);
471
- const row = await financeService.updateCreditNote(c.get("db"), c.req.valid("param").creditNoteId, c.req.valid("json"), {
472
- ...(runtime ?? {}),
473
- actionLedgerContext: getActionLedgerRequestContext(c),
474
- actionLedgerAuthorizationSource: "finance.credit_note.route",
475
- });
476
- return row ? c.json({ data: row }, 200) : c.json({ error: "Credit note not found" }, 404);
537
+ try {
538
+ const runtime = getFinanceRouteRuntime(c);
539
+ const row = await financeService.updateCreditNote(c.get("db"), c.req.valid("param").creditNoteId, c.req.valid("json"), {
540
+ ...(runtime ?? {}),
541
+ actionLedgerContext: getActionLedgerRequestContext(c),
542
+ actionLedgerAuthorizationSource: "finance.credit_note.route",
543
+ });
544
+ return row ? c.json({ data: row }, 200) : c.json({ error: "Credit note not found" }, 404);
545
+ }
546
+ catch (error) {
547
+ if (error instanceof InvoiceValidationError) {
548
+ if (error.status === 404) {
549
+ return c.json({ error: error.message, code: error.code, details: error.details }, 404);
550
+ }
551
+ if (error.status === 409) {
552
+ return c.json({ error: error.message, code: error.code, details: error.details }, 409);
553
+ }
554
+ return c.json({ error: error.message, code: error.code, details: error.details }, 400);
555
+ }
556
+ throw error;
557
+ }
477
558
  });
478
559
  // --- credit note line items ------------------------------------------------
479
560
  const listCreditNoteLineItemsRoute = createRoute({
@@ -519,13 +600,26 @@ const creditNoteLineItemRoutes = new OpenAPIHono({ defaultHook: openApiValidatio
519
600
  data: await financeService.listCreditNoteLineItems(c.get("db"), c.req.valid("param").creditNoteId),
520
601
  }, 200))
521
602
  .openapi(createCreditNoteLineItemRoute, async (c) => {
522
- const runtime = getFinanceRouteRuntime(c);
523
- const row = await financeService.createCreditNoteLineItem(c.get("db"), c.req.valid("param").creditNoteId, c.req.valid("json"), {
524
- eventBus: runtime?.eventBus,
525
- actionLedgerContext: getActionLedgerRequestContext(c),
526
- actionLedgerAuthorizationSource: "finance.credit_note_line_item.route",
527
- });
528
- return row ? c.json({ data: row }, 201) : c.json({ error: "Credit note not found" }, 404);
603
+ try {
604
+ const runtime = getFinanceRouteRuntime(c);
605
+ const row = await financeService.createCreditNoteLineItem(c.get("db"), c.req.valid("param").creditNoteId, c.req.valid("json"), {
606
+ eventBus: runtime?.eventBus,
607
+ actionLedgerContext: getActionLedgerRequestContext(c),
608
+ actionLedgerAuthorizationSource: "finance.credit_note_line_item.route",
609
+ });
610
+ return row ? c.json({ data: row }, 201) : c.json({ error: "Credit note not found" }, 404);
611
+ }
612
+ catch (error) {
613
+ if (error instanceof InvoiceValidationError) {
614
+ if (error.status === 404) {
615
+ return c.json({ error: error.message, code: error.code, details: error.details }, 404);
616
+ }
617
+ if (error.status === 409)
618
+ throw error;
619
+ return c.json({ error: error.message, code: error.code, details: error.details }, 400);
620
+ }
621
+ throw error;
622
+ }
529
623
  });
530
624
  // --- finance notes ---------------------------------------------------------
531
625
  const listNotesRoute = createRoute({
@@ -1 +1 @@
1
- {"version":3,"file":"routes-invoice-issue.d.ts","sourceRoot":"","sources":["../src/routes-invoice-issue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAc/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AA6G7C,eAAO,MAAM,yBAAyB,2BAEpC,CAAA"}
1
+ {"version":3,"file":"routes-invoice-issue.d.ts","sourceRoot":"","sources":["../src/routes-invoice-issue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAc/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AAsH7C,eAAO,MAAM,yBAAyB,2BAEpC,CAAA"}
@@ -18,7 +18,7 @@ import { openApiValidationHook, parseJsonBody } from "@voyant-travel/hono";
18
18
  import { listResponseSchema } from "@voyant-travel/types";
19
19
  import { errorResponseSchema, invoiceListItemSchema, invoiceSchema, } from "./routes-invoice-schemas.js";
20
20
  import { getActionLedgerRequestContext, getFinanceRouteRuntime, routeIdempotencyKey, } from "./routes-runtime.js";
21
- import { financeService, InvoiceFromBookingValidationError, InvoiceNumberAllocationError, InvoiceNumberConflictError, } from "./service.js";
21
+ import { financeService, InvoiceFromBookingValidationError, InvoiceNumberAllocationError, InvoiceNumberConflictError, InvoiceValidationError, } from "./service.js";
22
22
  import { insertInvoiceSchema, invoiceFromBookingSchema, invoiceListQuerySchema, } from "./validation.js";
23
23
  const idParamSchema = z.object({ id: z.string() });
24
24
  const listInvoicesRoute = createRoute({
@@ -50,6 +50,14 @@ const createInvoiceRoute = createRoute({
50
50
  description: "invalid_request: request body failed validation",
51
51
  content: { "application/json": { schema: errorResponseSchema } },
52
52
  },
53
+ 404: {
54
+ description: "Booking, person, or organization reference not found",
55
+ content: { "application/json": { schema: errorResponseSchema } },
56
+ },
57
+ 409: {
58
+ description: "Invoice number already exists",
59
+ content: { "application/json": { schema: errorResponseSchema } },
60
+ },
53
61
  },
54
62
  });
55
63
  const issueInvoiceFromBookingRoute = createRoute({
@@ -126,7 +134,24 @@ financeInvoiceIssueRoutes.use("/invoices/from-booking", postOnly(routeIdempotenc
126
134
  })));
127
135
  financeInvoiceIssueRoutes
128
136
  .openapi(listInvoicesRoute, async (c) => c.json(await financeService.listInvoices(c.get("db"), c.req.valid("query")), 200))
129
- .openapi(createInvoiceRoute, async (c) => c.json({ data: (await financeService.createInvoice(c.get("db"), c.req.valid("json"))) ?? null }, 201))
137
+ .openapi(createInvoiceRoute, async (c) => {
138
+ try {
139
+ return c.json({ data: (await financeService.createInvoice(c.get("db"), c.req.valid("json"))) ?? null }, 201);
140
+ }
141
+ catch (error) {
142
+ if (error instanceof InvoiceNumberConflictError) {
143
+ return c.json({
144
+ error: "Invoice number already exists",
145
+ code: error.code,
146
+ invoiceNumber: error.invoiceNumber,
147
+ }, 409);
148
+ }
149
+ if (error instanceof InvoiceValidationError) {
150
+ return c.json({ error: error.message, code: error.code, details: error.details }, error.status);
151
+ }
152
+ throw error;
153
+ }
154
+ })
130
155
  .openapi(issueInvoiceFromBookingRoute, async (c) => {
131
156
  const input = c.req.valid("json");
132
157
  const db = c.get("db");
@@ -134,6 +134,32 @@ export declare const financePaymentRoutes: OpenAPIHono<Env, import("hono/types")
134
134
  };
135
135
  outputFormat: "json";
136
136
  status: 201;
137
+ } | {
138
+ input: {
139
+ json: {
140
+ amountCents: number;
141
+ currency: string;
142
+ paymentMethod: "bank_transfer" | "credit_card" | "debit_card" | "cash" | "cheque" | "wallet" | "direct_bill" | "voucher" | "other";
143
+ paymentDate: string;
144
+ bookingId?: string | null | undefined;
145
+ supplierInvoiceId?: string | null | undefined;
146
+ supplierId?: string | null | undefined;
147
+ bookingSupplierStatusId?: string | null | undefined;
148
+ baseCurrency?: string | null | undefined;
149
+ baseAmountCents?: number | null | undefined;
150
+ fxRateSetId?: string | null | undefined;
151
+ paymentInstrumentId?: string | null | undefined;
152
+ status?: "pending" | "completed" | "failed" | "refunded" | undefined;
153
+ referenceNumber?: string | null | undefined;
154
+ notes?: string | null | undefined;
155
+ };
156
+ };
157
+ output: {
158
+ error: string;
159
+ code: string;
160
+ };
161
+ outputFormat: "json";
162
+ status: 422;
137
163
  };
138
164
  };
139
165
  } & {
@@ -196,6 +222,36 @@ export declare const financePaymentRoutes: OpenAPIHono<Env, import("hono/types")
196
222
  };
197
223
  outputFormat: "json";
198
224
  status: 400;
225
+ } | {
226
+ input: {
227
+ param: {
228
+ id: string;
229
+ };
230
+ } & {
231
+ json: {
232
+ bookingId?: string | null | undefined;
233
+ supplierInvoiceId?: string | null | undefined;
234
+ supplierId?: string | null | undefined;
235
+ bookingSupplierStatusId?: string | null | undefined;
236
+ amountCents?: number | undefined;
237
+ currency?: string | undefined;
238
+ baseCurrency?: string | null | undefined;
239
+ baseAmountCents?: number | null | undefined;
240
+ fxRateSetId?: string | null | undefined;
241
+ paymentMethod?: "bank_transfer" | "credit_card" | "debit_card" | "cash" | "cheque" | "wallet" | "direct_bill" | "voucher" | "other" | undefined;
242
+ paymentInstrumentId?: string | null | undefined;
243
+ status?: "pending" | "completed" | "failed" | "refunded" | undefined;
244
+ referenceNumber?: string | null | undefined;
245
+ paymentDate?: string | undefined;
246
+ notes?: string | null | undefined;
247
+ };
248
+ };
249
+ output: {
250
+ error: string;
251
+ code: string;
252
+ };
253
+ outputFormat: "json";
254
+ status: 422;
199
255
  } | {
200
256
  input: {
201
257
  param: {
@@ -407,6 +463,33 @@ export declare const financePaymentRoutes: OpenAPIHono<Env, import("hono/types")
407
463
  };
408
464
  outputFormat: "json";
409
465
  status: 400;
466
+ } | {
467
+ input: {
468
+ param: {
469
+ id: string;
470
+ };
471
+ } & {
472
+ json: {
473
+ amountCents?: number | undefined;
474
+ currency?: string | undefined;
475
+ baseCurrency?: string | null | undefined;
476
+ baseAmountCents?: number | null | undefined;
477
+ fxRateSetId?: string | null | undefined;
478
+ paymentMethod?: "bank_transfer" | "credit_card" | "debit_card" | "cash" | "cheque" | "wallet" | "direct_bill" | "voucher" | "other" | undefined;
479
+ paymentInstrumentId?: string | null | undefined;
480
+ paymentAuthorizationId?: string | null | undefined;
481
+ paymentCaptureId?: string | null | undefined;
482
+ status?: "pending" | "completed" | "failed" | "refunded" | undefined;
483
+ referenceNumber?: string | null | undefined;
484
+ paymentDate?: string | undefined;
485
+ notes?: string | null | undefined;
486
+ };
487
+ };
488
+ output: {
489
+ error: string;
490
+ };
491
+ outputFormat: "json";
492
+ status: 409;
410
493
  } | {
411
494
  input: {
412
495
  param: {
@@ -1 +1 @@
1
- {"version":3,"file":"routes-payments.d.ts","sourceRoot":"","sources":["../src/routes-payments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAM/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AAkO7C,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEG,CAAA"}
1
+ {"version":3,"file":"routes-payments.d.ts","sourceRoot":"","sources":["../src/routes-payments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAe,WAAW,EAAK,MAAM,mBAAmB,CAAA;AAM/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AA2Q7C,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAEG,CAAA"}