@voyantjs/finance 0.19.0 → 0.21.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 (38) hide show
  1. package/dist/index.d.ts +8 -4
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +14 -4
  4. package/dist/payment-policy.d.ts +113 -0
  5. package/dist/payment-policy.d.ts.map +1 -0
  6. package/dist/payment-policy.js +193 -0
  7. package/dist/routes-documents.d.ts +2 -2
  8. package/dist/routes-public.d.ts +28 -20
  9. package/dist/routes-public.d.ts.map +1 -1
  10. package/dist/routes.d.ts +542 -43
  11. package/dist/routes.d.ts.map +1 -1
  12. package/dist/routes.js +120 -5
  13. package/dist/schema.d.ts +541 -9
  14. package/dist/schema.d.ts.map +1 -1
  15. package/dist/schema.js +85 -0
  16. package/dist/service-documents.d.ts +1 -1
  17. package/dist/service-documents.d.ts.map +1 -1
  18. package/dist/service-issue.d.ts +108 -0
  19. package/dist/service-issue.d.ts.map +1 -0
  20. package/dist/service-issue.js +57 -0
  21. package/dist/service-public.d.ts +13 -9
  22. package/dist/service-public.d.ts.map +1 -1
  23. package/dist/service-public.js +1 -0
  24. package/dist/service.d.ts +269 -49
  25. package/dist/service.d.ts.map +1 -1
  26. package/dist/service.js +278 -20
  27. package/dist/validation-billing.d.ts +109 -0
  28. package/dist/validation-billing.d.ts.map +1 -1
  29. package/dist/validation-billing.js +58 -0
  30. package/dist/validation-payments.d.ts +19 -16
  31. package/dist/validation-payments.d.ts.map +1 -1
  32. package/dist/validation-public.d.ts +5 -3
  33. package/dist/validation-public.d.ts.map +1 -1
  34. package/dist/validation-public.js +7 -0
  35. package/dist/validation-shared.d.ts +6 -5
  36. package/dist/validation-shared.d.ts.map +1 -1
  37. package/dist/validation-shared.js +1 -0
  38. package/package.json +7 -7
package/dist/schema.js CHANGED
@@ -43,6 +43,7 @@ export const paymentSessionTargetTypeEnum = pgEnum("payment_session_target_type"
43
43
  "invoice",
44
44
  "booking_payment_schedule",
45
45
  "booking_guarantee",
46
+ "flight_order",
46
47
  "other",
47
48
  ]);
48
49
  export const paymentInstrumentTypeEnum = pgEnum("payment_instrument_type", [
@@ -527,6 +528,15 @@ export const invoices = pgTable("invoices", {
527
528
  id: typeId("invoices"),
528
529
  invoiceNumber: text("invoice_number").notNull().unique(),
529
530
  invoiceType: invoiceTypeEnum("invoice_type").notNull().default("invoice"),
531
+ /**
532
+ * Source proforma when this row is the final invoice that
533
+ * superseded one. Lets the bank-transfer flow link the proforma
534
+ * issued at checkout to the invoice issued after payment lands —
535
+ * SmartBill's "convert proforma" call returns the same number
536
+ * series, but the local rows stay distinct so the audit trail
537
+ * shows both documents.
538
+ */
539
+ convertedFromInvoiceId: text("converted_from_invoice_id"),
530
540
  seriesId: typeIdRef("series_id"),
531
541
  sequence: integer("sequence"),
532
542
  templateId: typeIdRef("template_id"),
@@ -566,6 +576,7 @@ export const invoices = pgTable("invoices", {
566
576
  index("idx_invoices_fx_rate_set").on(table.fxRateSetId),
567
577
  index("idx_invoices_number").on(table.invoiceNumber),
568
578
  index("idx_invoices_due_date").on(table.dueDate),
579
+ index("idx_invoices_converted_from").on(table.convertedFromInvoiceId),
569
580
  // base_currency covers every base_*_cents column. If any base amount is
570
581
  // present, base_currency must be set so reporting can interpret it.
571
582
  check("ck_invoices_base_currency_amounts", sql `(
@@ -809,6 +820,80 @@ export const taxRegimes = pgTable("tax_regimes", {
809
820
  index("idx_tax_regimes_active").on(table.active),
810
821
  index("idx_tax_regimes_active_updated").on(table.active, table.updatedAt),
811
822
  ]);
823
+ // ---------- tax_classes ----------
824
+ //
825
+ // Per-product tax-treatment decision. Stacks on top of `tax_regimes`
826
+ // (the jurisdictional rate catalog) — a class points at a default
827
+ // regime, plus optional regime-per-applies_to overrides for products
828
+ // that mix base / addon / accommodation treatments.
829
+ //
830
+ // Per booking-journey-architecture §9.
831
+ export const taxClassAppliesToEnum = pgEnum("tax_class_applies_to", [
832
+ "base",
833
+ "addon",
834
+ "accommodation",
835
+ "all",
836
+ ]);
837
+ export const taxPolicySideEnum = pgEnum("tax_policy_side", ["sell", "buy"]);
838
+ export const taxClasses = pgTable("tax_classes", {
839
+ id: typeId("tax_classes"),
840
+ /** Stable code for idempotent seeding (e.g. "vat-standard-ro",
841
+ * "exempt-art311", "reduced-de"). */
842
+ code: text("code").notNull(),
843
+ label: text("label").notNull(),
844
+ description: text("description"),
845
+ /** Default regime resolved at quote time when no per-line rule
846
+ * matches. Plain text — cross-domain refs go through link service
847
+ * per schema-discipline. */
848
+ defaultRegimeId: text("default_regime_id"),
849
+ /**
850
+ * Regime-per-applies_to overrides. Empty / null falls through to
851
+ * `default_regime_id`. Parsed at quote time by the engine.
852
+ */
853
+ lines: jsonb("lines").$type(),
854
+ active: boolean("active").notNull().default(true),
855
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
856
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
857
+ }, (table) => [
858
+ index("idx_tax_classes_code").on(table.code),
859
+ index("idx_tax_classes_active").on(table.active),
860
+ ]);
861
+ // ---------- tax_policy_profiles ----------
862
+ //
863
+ // Operator/jurisdiction-specific tax decision profiles. Profiles are
864
+ // implementation presets such as "Romanian travel operator"; rules under
865
+ // the profile map product/order facts to tax regimes for sell-side and
866
+ // buy-side tax decisions.
867
+ export const taxPolicyProfiles = pgTable("tax_policy_profiles", {
868
+ id: typeId("tax_policy_profiles"),
869
+ code: text("code").notNull(),
870
+ name: text("name").notNull(),
871
+ jurisdiction: text("jurisdiction"),
872
+ description: text("description"),
873
+ active: boolean("active").notNull().default(true),
874
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
875
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
876
+ }, (table) => [
877
+ index("idx_tax_policy_profiles_code").on(table.code),
878
+ index("idx_tax_policy_profiles_active").on(table.active),
879
+ ]);
880
+ export const taxPolicyRules = pgTable("tax_policy_rules", {
881
+ id: typeId("tax_policy_rules"),
882
+ profileId: text("profile_id").notNull(),
883
+ side: taxPolicySideEnum("side").notNull().default("sell"),
884
+ priority: integer("priority").notNull().default(100),
885
+ name: text("name").notNull(),
886
+ appliesTo: taxClassAppliesToEnum("applies_to").notNull().default("all"),
887
+ condition: jsonb("condition").$type(),
888
+ taxRegimeId: text("tax_regime_id").notNull(),
889
+ active: boolean("active").notNull().default(true),
890
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
891
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
892
+ }, (table) => [
893
+ index("idx_tax_policy_rules_profile").on(table.profileId),
894
+ index("idx_tax_policy_rules_profile_side_priority").on(table.profileId, table.side, table.priority),
895
+ index("idx_tax_policy_rules_active").on(table.active),
896
+ ]);
812
897
  // ---------- invoice_external_refs ----------
813
898
  export const invoiceExternalRefs = pgTable("invoice_external_refs", {
814
899
  id: typeId("invoice_external_refs"),
@@ -1,5 +1,5 @@
1
1
  import type { EventBus } from "@voyantjs/core";
2
- import type { StorageProvider, StorageUploadBody } from "@voyantjs/voyant-storage";
2
+ import type { StorageProvider, StorageUploadBody } from "@voyantjs/storage";
3
3
  import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
4
4
  import { type invoiceLineItems, type invoiceRenditions, type invoices, invoiceTemplates, type payments } from "./schema.js";
5
5
  import type { GenerateInvoiceDocumentInput } from "./validation.js";
@@ -1 +1 @@
1
- {"version":3,"file":"service-documents.d.ts","sourceRoot":"","sources":["../src/service-documents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service-documents.d.ts","sourceRoot":"","sources":["../src/service-documents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ import type { EventBus } from "@voyantjs/core";
2
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
3
+ import { type CreateInvoiceFromBookingInput, type InvoiceFromBookingData } from "./service.js";
4
+ /**
5
+ * Issue / proforma orchestration helpers that wrap the bare invoice
6
+ * creators with EventBus emissions so subscribers (SmartBill plugin,
7
+ * checkout-finalize workflow) can react.
8
+ *
9
+ * `createInvoice*` services in `service.ts` stay pure DB writers —
10
+ * the workflow / route layer chooses when to mark them as "issued"
11
+ * (a status change that's also a system signal).
12
+ */
13
+ export interface InvoiceIssueRuntime {
14
+ eventBus?: EventBus;
15
+ }
16
+ export interface InvoiceIssuedEvent {
17
+ invoiceId: string;
18
+ invoiceNumber: string;
19
+ invoiceType: "invoice" | "proforma" | "credit_note";
20
+ bookingId: string | null;
21
+ totalCents: number;
22
+ currency: string;
23
+ /** Linkage when this invoice replaced a proforma. */
24
+ convertedFromInvoiceId?: string | null;
25
+ }
26
+ /**
27
+ * Create + emit an invoice from a booking. Returns the persisted row
28
+ * after flipping the status from `draft` → `sent`. The status flip is
29
+ * what consumers treat as "issued" — drafts shouldn't trigger
30
+ * SmartBill sync.
31
+ */
32
+ export declare function issueInvoiceFromBooking(db: PostgresJsDatabase, input: CreateInvoiceFromBookingInput, bookingData: InvoiceFromBookingData, runtime?: InvoiceIssueRuntime): Promise<{
33
+ id: string;
34
+ createdAt: Date;
35
+ updatedAt: Date;
36
+ organizationId: string | null;
37
+ status: "void" | "draft" | "sent" | "partially_paid" | "paid" | "overdue";
38
+ issueDate: string;
39
+ currency: string;
40
+ notes: string | null;
41
+ bookingId: string;
42
+ personId: string | null;
43
+ baseCurrency: string | null;
44
+ fxRateSetId: string | null;
45
+ invoiceNumber: string;
46
+ invoiceType: "invoice" | "proforma" | "credit_note";
47
+ convertedFromInvoiceId: string | null;
48
+ seriesId: string | null;
49
+ sequence: number | null;
50
+ templateId: string | null;
51
+ taxRegimeId: string | null;
52
+ language: string | null;
53
+ subtotalCents: number;
54
+ baseSubtotalCents: number | null;
55
+ taxCents: number;
56
+ baseTaxCents: number | null;
57
+ totalCents: number;
58
+ baseTotalCents: number | null;
59
+ paidCents: number;
60
+ basePaidCents: number | null;
61
+ balanceDueCents: number;
62
+ baseBalanceDueCents: number | null;
63
+ commissionPercent: number | null;
64
+ commissionAmountCents: number | null;
65
+ dueDate: string;
66
+ } | null>;
67
+ /**
68
+ * Create + emit a proforma from a booking. Same shape as
69
+ * `issueInvoiceFromBooking` but marks the row as `invoiceType:
70
+ * 'proforma'` and emits the proforma-specific event so the
71
+ * SmartBill plugin can route to its proforma endpoint.
72
+ */
73
+ export declare function issueProformaFromBooking(db: PostgresJsDatabase, input: CreateInvoiceFromBookingInput, bookingData: InvoiceFromBookingData, runtime?: InvoiceIssueRuntime): Promise<{
74
+ id: string;
75
+ createdAt: Date;
76
+ updatedAt: Date;
77
+ organizationId: string | null;
78
+ status: "void" | "draft" | "sent" | "partially_paid" | "paid" | "overdue";
79
+ issueDate: string;
80
+ currency: string;
81
+ notes: string | null;
82
+ bookingId: string;
83
+ personId: string | null;
84
+ baseCurrency: string | null;
85
+ fxRateSetId: string | null;
86
+ invoiceNumber: string;
87
+ invoiceType: "invoice" | "proforma" | "credit_note";
88
+ convertedFromInvoiceId: string | null;
89
+ seriesId: string | null;
90
+ sequence: number | null;
91
+ templateId: string | null;
92
+ taxRegimeId: string | null;
93
+ language: string | null;
94
+ subtotalCents: number;
95
+ baseSubtotalCents: number | null;
96
+ taxCents: number;
97
+ baseTaxCents: number | null;
98
+ totalCents: number;
99
+ baseTotalCents: number | null;
100
+ paidCents: number;
101
+ basePaidCents: number | null;
102
+ balanceDueCents: number;
103
+ baseBalanceDueCents: number | null;
104
+ commissionPercent: number | null;
105
+ commissionAmountCents: number | null;
106
+ dueDate: string;
107
+ } | null>;
108
+ //# sourceMappingURL=service-issue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-issue.d.ts","sourceRoot":"","sources":["../src/service-issue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,EACL,KAAK,6BAA6B,EAElC,KAAK,sBAAsB,EAC5B,MAAM,cAAc,CAAA;AAErB;;;;;;;;GAQG;AAEH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;IACnD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACvC;AAKD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,6BAA6B,EACpC,WAAW,EAAE,sBAAsB,EACnC,OAAO,GAAE,mBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAclC;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,6BAA6B,EACpC,WAAW,EAAE,sBAAsB,EACnC,OAAO,GAAE,mBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAclC"}
@@ -0,0 +1,57 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { invoices } from "./schema.js";
3
+ import { financeService, } from "./service.js";
4
+ const ISSUED_EVENT = "invoice.issued";
5
+ const PROFORMA_ISSUED_EVENT = "invoice.proforma.issued";
6
+ /**
7
+ * Create + emit an invoice from a booking. Returns the persisted row
8
+ * after flipping the status from `draft` → `sent`. The status flip is
9
+ * what consumers treat as "issued" — drafts shouldn't trigger
10
+ * SmartBill sync.
11
+ */
12
+ export async function issueInvoiceFromBooking(db, input, bookingData, runtime = {}) {
13
+ const draft = await financeService.createInvoiceFromBooking(db, input, bookingData);
14
+ if (!draft)
15
+ return null;
16
+ const [issued] = await db
17
+ .update(invoices)
18
+ .set({ status: "sent", updatedAt: new Date() })
19
+ .where(eq(invoices.id, draft.id))
20
+ .returning();
21
+ const row = issued ?? draft;
22
+ await emitIssued(runtime, ISSUED_EVENT, row);
23
+ return row;
24
+ }
25
+ /**
26
+ * Create + emit a proforma from a booking. Same shape as
27
+ * `issueInvoiceFromBooking` but marks the row as `invoiceType:
28
+ * 'proforma'` and emits the proforma-specific event so the
29
+ * SmartBill plugin can route to its proforma endpoint.
30
+ */
31
+ export async function issueProformaFromBooking(db, input, bookingData, runtime = {}) {
32
+ const draft = await financeService.createInvoiceFromBooking(db, input, bookingData);
33
+ if (!draft)
34
+ return null;
35
+ const [issued] = await db
36
+ .update(invoices)
37
+ .set({ invoiceType: "proforma", status: "sent", updatedAt: new Date() })
38
+ .where(eq(invoices.id, draft.id))
39
+ .returning();
40
+ const row = issued ?? draft;
41
+ await emitIssued(runtime, PROFORMA_ISSUED_EVENT, row);
42
+ return row;
43
+ }
44
+ async function emitIssued(runtime, eventName, invoice) {
45
+ if (!runtime.eventBus)
46
+ return;
47
+ const payload = {
48
+ invoiceId: invoice.id,
49
+ invoiceNumber: invoice.invoiceNumber,
50
+ invoiceType: invoice.invoiceType,
51
+ bookingId: invoice.bookingId,
52
+ totalCents: invoice.totalCents,
53
+ currency: invoice.currency,
54
+ convertedFromInvoiceId: invoice.convertedFromInvoiceId,
55
+ };
56
+ await runtime.eventBus.emit(eventName, payload);
57
+ }
@@ -33,7 +33,7 @@ export declare const publicFinanceService: {
33
33
  id: string;
34
34
  bookingPaymentScheduleId: string | null;
35
35
  guaranteeType: "other" | "voucher" | "bank_transfer" | "credit_card" | "deposit" | "preauth" | "card_on_file" | "agency_letter";
36
- status: "pending" | "active" | "expired" | "cancelled" | "released" | "failed";
36
+ status: "pending" | "active" | "failed" | "expired" | "cancelled" | "released";
37
37
  currency: string | null;
38
38
  amountCents: number | null;
39
39
  provider: string | null;
@@ -49,13 +49,13 @@ export declare const publicFinanceService: {
49
49
  getBookingPayments(db: PostgresJsDatabase, bookingId: string): Promise<PublicBookingFinancePayments | null>;
50
50
  getPaymentSession(db: PostgresJsDatabase, sessionId: string): Promise<{
51
51
  id: string;
52
- targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee";
52
+ targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
53
53
  targetId: string | null;
54
54
  bookingId: string | null;
55
55
  invoiceId: string | null;
56
56
  bookingPaymentScheduleId: string | null;
57
57
  bookingGuaranteeId: string | null;
58
- status: "pending" | "expired" | "cancelled" | "failed" | "paid" | "requires_redirect" | "processing" | "authorized";
58
+ status: "pending" | "failed" | "expired" | "cancelled" | "paid" | "requires_redirect" | "processing" | "authorized";
59
59
  provider: string | null;
60
60
  providerSessionId: string | null;
61
61
  providerPaymentId: string | null;
@@ -73,16 +73,17 @@ export declare const publicFinanceService: {
73
73
  completedAt: string | null;
74
74
  failureCode: string | null;
75
75
  failureMessage: string | null;
76
+ notes: string | null;
76
77
  } | null>;
77
78
  startBookingSchedulePaymentSession(db: PostgresJsDatabase, bookingId: string, scheduleId: string, input: PublicStartPaymentSessionInput): Promise<{
78
79
  id: string;
79
- targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee";
80
+ targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
80
81
  targetId: string | null;
81
82
  bookingId: string | null;
82
83
  invoiceId: string | null;
83
84
  bookingPaymentScheduleId: string | null;
84
85
  bookingGuaranteeId: string | null;
85
- status: "pending" | "expired" | "cancelled" | "failed" | "paid" | "requires_redirect" | "processing" | "authorized";
86
+ status: "pending" | "failed" | "expired" | "cancelled" | "paid" | "requires_redirect" | "processing" | "authorized";
86
87
  provider: string | null;
87
88
  providerSessionId: string | null;
88
89
  providerPaymentId: string | null;
@@ -100,16 +101,17 @@ export declare const publicFinanceService: {
100
101
  completedAt: string | null;
101
102
  failureCode: string | null;
102
103
  failureMessage: string | null;
104
+ notes: string | null;
103
105
  } | null>;
104
106
  startBookingGuaranteePaymentSession(db: PostgresJsDatabase, bookingId: string, guaranteeId: string, input: PublicStartPaymentSessionInput): Promise<{
105
107
  id: string;
106
- targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee";
108
+ targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
107
109
  targetId: string | null;
108
110
  bookingId: string | null;
109
111
  invoiceId: string | null;
110
112
  bookingPaymentScheduleId: string | null;
111
113
  bookingGuaranteeId: string | null;
112
- status: "pending" | "expired" | "cancelled" | "failed" | "paid" | "requires_redirect" | "processing" | "authorized";
114
+ status: "pending" | "failed" | "expired" | "cancelled" | "paid" | "requires_redirect" | "processing" | "authorized";
113
115
  provider: string | null;
114
116
  providerSessionId: string | null;
115
117
  providerPaymentId: string | null;
@@ -127,16 +129,17 @@ export declare const publicFinanceService: {
127
129
  completedAt: string | null;
128
130
  failureCode: string | null;
129
131
  failureMessage: string | null;
132
+ notes: string | null;
130
133
  } | null>;
131
134
  startInvoicePaymentSession(db: PostgresJsDatabase, invoiceId: string, input: PublicStartPaymentSessionInput): Promise<{
132
135
  id: string;
133
- targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee";
136
+ targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
134
137
  targetId: string | null;
135
138
  bookingId: string | null;
136
139
  invoiceId: string | null;
137
140
  bookingPaymentScheduleId: string | null;
138
141
  bookingGuaranteeId: string | null;
139
- status: "pending" | "expired" | "cancelled" | "failed" | "paid" | "requires_redirect" | "processing" | "authorized";
142
+ status: "pending" | "failed" | "expired" | "cancelled" | "paid" | "requires_redirect" | "processing" | "authorized";
140
143
  provider: string | null;
141
144
  providerSessionId: string | null;
142
145
  providerPaymentId: string | null;
@@ -154,6 +157,7 @@ export declare const publicFinanceService: {
154
157
  completedAt: string | null;
155
158
  failureCode: string | null;
156
159
  failureMessage: string | null;
160
+ notes: string | null;
157
161
  } | null>;
158
162
  validateVoucher(db: PostgresJsDatabase, input: PublicValidateVoucherInput): Promise<{
159
163
  valid: false;
@@ -1 +1 @@
1
- {"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAYjE,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAE5B,2BAA2B,EAC3B,yBAAyB,EACzB,8BAA8B,EAC9B,0BAA0B,EAC3B,MAAM,wBAAwB,CAAA;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;CAC5F;AA8HD,eAAO,MAAM,oBAAoB;4BAEzB,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,6BAA6B,GAAG,IAAI,CAAC;+BA6C1C,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC;iCA0CxC,kBAAkB,aACX,MAAM,SACV,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAoH5B,kBAAkB,aACX,MAAM,GAChB,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC;0BA2DnB,kBAAkB,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;2CAM3D,kBAAkB,aACX,MAAM,cACL,MAAM,SACX,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;4CA4BjC,kBAAkB,aACX,MAAM,eACJ,MAAM,SACZ,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAuBjC,kBAAkB,aACX,MAAM,SACV,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAMb,kBAAkB,SAAS,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEhF,CAAA"}
1
+ {"version":3,"file":"service-public.d.ts","sourceRoot":"","sources":["../src/service-public.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAYjE,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAE5B,2BAA2B,EAC3B,yBAAyB,EACzB,8BAA8B,EAC9B,0BAA0B,EAC3B,MAAM,wBAAwB,CAAA;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAA;CAC5F;AA+HD,eAAO,MAAM,oBAAoB;4BAEzB,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,6BAA6B,GAAG,IAAI,CAAC;+BA6C1C,kBAAkB,aACX,MAAM,YACR,2BAA2B,GACnC,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC;iCA0CxC,kBAAkB,aACX,MAAM,SACV,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAoH5B,kBAAkB,aACX,MAAM,GAChB,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC;0BA2DnB,kBAAkB,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CAM3D,kBAAkB,aACX,MAAM,cACL,MAAM,SACX,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CA4BjC,kBAAkB,aACX,MAAM,eACJ,MAAM,SACZ,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAuBjC,kBAAkB,aACX,MAAM,SACV,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAMb,kBAAkB,SAAS,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEhF,CAAA"}
@@ -72,6 +72,7 @@ function toPublicPaymentSession(session) {
72
72
  completedAt: normalizeDateTime(session.completedAt),
73
73
  failureCode: session.failureCode ?? null,
74
74
  failureMessage: session.failureMessage ?? null,
75
+ notes: session.notes ?? null,
75
76
  };
76
77
  }
77
78
  async function mapInvoiceDocument(invoice, renditions, runtime = {}) {