@voyantjs/finance 0.53.2 → 0.55.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 CHANGED
@@ -73,6 +73,58 @@ The by-reference variant resolves invoice numbers and payment reference numbers
73
73
  only inside that booking, so a valid capability for one booking cannot retrieve
74
74
  documents from another booking.
75
75
 
76
+ ## Booking Tax Preview
77
+
78
+ Booking creation UIs can show the same tax line that booking finalization will
79
+ persist by mounting the booking-tax extension:
80
+
81
+ ```typescript
82
+ import { createBookingTaxHonoExtension } from "@voyantjs/finance/booking-tax"
83
+
84
+ createApp({
85
+ extensions: [
86
+ createBookingTaxHonoExtension({
87
+ resolveBookingTaxSettings: async (db) => {
88
+ const settings = await getTaxSettings(db)
89
+ return {
90
+ taxPriceMode: settings?.taxPriceMode ?? "inclusive",
91
+ taxPolicyProfileId: settings?.taxPolicyProfileId ?? null,
92
+ }
93
+ },
94
+ }),
95
+ ],
96
+ })
97
+ ```
98
+
99
+ The settings callback is the storage seam. A template can read a singleton
100
+ settings table, KV, environment configuration, or any other deployment-owned
101
+ store, while `@voyantjs/finance` owns the tax policy rule walker, tax-regime
102
+ lookup, product tax-class fallback, and inclusive/exclusive math.
103
+
104
+ Templates that already mount custom routes can call `mountBookingTaxRoutes(...)`
105
+ from the same entrypoint instead of using the Hono extension.
106
+
107
+ Mounting this route registers:
108
+
109
+ - `GET /v1/admin/bookings/tax-settings`
110
+ - `PATCH /v1/admin/bookings/tax-settings` when `updateBookingTaxSettings` is supplied
111
+ - `POST /v1/admin/bookings/tax-preview`
112
+
113
+ The preview endpoint is consumed by `@voyantjs/bookings-react` tax-preview
114
+ hooks. Consumers that use the booking-create dialog without mounting the route
115
+ will silently lose tax rows in the dialog summary because the client treats a
116
+ missing preview as "no tax to show".
117
+
118
+ Server-side booking-finalize code can use the same helpers directly:
119
+
120
+ ```typescript
121
+ import {
122
+ computeBookingItemTaxLine,
123
+ loadProductTaxFacts,
124
+ resolveBookingSellTaxRate,
125
+ } from "@voyantjs/finance/booking-tax"
126
+ ```
127
+
76
128
  ## Exports
77
129
 
78
130
  | Entry | Description |
@@ -80,6 +132,7 @@ documents from another booking.
80
132
  | `.` | Module export |
81
133
  | `./schema` | Drizzle tables |
82
134
  | `./validation` | Zod schemas |
135
+ | `./booking-tax` | Booking sell-side tax policy helpers and route mounting |
83
136
  | `./routes` | Hono routes |
84
137
 
85
138
  ## License
@@ -0,0 +1,124 @@
1
+ import type { HonoExtension } from "@voyantjs/hono/module";
2
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
3
+ import type { Hono } from "hono";
4
+ export type ProductTaxFacts = {
5
+ hasAccommodation: boolean;
6
+ accommodationCountries: string[];
7
+ };
8
+ export type ResolvedBookingSellTaxRate = {
9
+ code: string;
10
+ label: string;
11
+ rate: number;
12
+ priceMode: "inclusive" | "exclusive";
13
+ };
14
+ export type BookingTaxSettings = {
15
+ taxPriceMode?: "inclusive" | "exclusive" | null;
16
+ taxPolicyProfileId?: string | null;
17
+ };
18
+ export type ResolveBookingTaxSettings = (db: PostgresJsDatabase) => BookingTaxSettings | null | undefined | Promise<BookingTaxSettings | null | undefined>;
19
+ export type UpdateBookingTaxSettings = (db: PostgresJsDatabase, settings: BookingTaxSettings) => BookingTaxSettings | null | undefined | Promise<BookingTaxSettings | null | undefined>;
20
+ export type TaxPolicyCondition = {
21
+ always: true;
22
+ } | {
23
+ all: TaxPolicyCondition[];
24
+ } | {
25
+ any: TaxPolicyCondition[];
26
+ } | {
27
+ fact: keyof ProductTaxFacts;
28
+ eq?: unknown;
29
+ contains?: unknown;
30
+ };
31
+ export interface ResolveBookingSellTaxRateOptions {
32
+ settings?: BookingTaxSettings | null;
33
+ resolveBookingTaxSettings?: ResolveBookingTaxSettings;
34
+ }
35
+ export interface BookingTaxRouteOptions extends ResolveBookingSellTaxRateOptions {
36
+ updateBookingTaxSettings?: UpdateBookingTaxSettings;
37
+ }
38
+ export declare function resolveBookingSellTaxRate(db: PostgresJsDatabase, args: {
39
+ productId?: string | null;
40
+ facts?: Partial<ProductTaxFacts>;
41
+ }, options?: ResolveBookingSellTaxRateOptions): Promise<ResolvedBookingSellTaxRate | null>;
42
+ export declare function computeBookingItemTaxLine(taxRate: ResolvedBookingSellTaxRate | null, amountCents: number, currency: string, sortOrder?: number): {
43
+ code: string;
44
+ name: string;
45
+ scope: "included" | "excluded";
46
+ currency: string;
47
+ amountCents: number;
48
+ rateBasisPoints: number;
49
+ includedInPrice: boolean;
50
+ sortOrder: number;
51
+ } | null;
52
+ export declare function loadProductTaxFacts(db: PostgresJsDatabase, productId: string): Promise<ProductTaxFacts>;
53
+ export declare function matchesTaxPolicyCondition(condition: TaxPolicyCondition | null | undefined, facts: ProductTaxFacts): boolean;
54
+ export declare function createBookingTaxRoutes(options?: BookingTaxRouteOptions): import("hono/hono-base").HonoBase<{
55
+ Variables: {
56
+ db: PostgresJsDatabase;
57
+ };
58
+ }, {
59
+ "/tax-settings": {
60
+ $get: {
61
+ input: {};
62
+ output: {
63
+ data: {
64
+ taxPriceMode?: "inclusive" | "exclusive" | null | undefined;
65
+ taxPolicyProfileId?: string | null | undefined;
66
+ };
67
+ };
68
+ outputFormat: "json";
69
+ status: import("hono/utils/http-status").ContentfulStatusCode;
70
+ };
71
+ };
72
+ } & {
73
+ "/tax-settings": {
74
+ $patch: {
75
+ input: {};
76
+ output: {
77
+ data: {
78
+ taxPriceMode?: "inclusive" | "exclusive" | null | undefined;
79
+ taxPolicyProfileId?: string | null | undefined;
80
+ };
81
+ };
82
+ outputFormat: "json";
83
+ status: import("hono/utils/http-status").ContentfulStatusCode;
84
+ };
85
+ };
86
+ } & {
87
+ "/tax-preview": {
88
+ $post: {
89
+ input: {};
90
+ output: {
91
+ data: {
92
+ subtotalCents: number;
93
+ taxCents: number;
94
+ totalCents: number;
95
+ currency: string;
96
+ taxRate: null;
97
+ };
98
+ };
99
+ outputFormat: "json";
100
+ status: import("hono/utils/http-status").ContentfulStatusCode;
101
+ } | {
102
+ input: {};
103
+ output: {
104
+ data: {
105
+ subtotalCents: number;
106
+ taxCents: number;
107
+ totalCents: number;
108
+ currency: string;
109
+ taxRate: {
110
+ code: string;
111
+ label: string;
112
+ rateBasisPoints: number;
113
+ priceMode: "inclusive" | "exclusive";
114
+ };
115
+ };
116
+ };
117
+ outputFormat: "json";
118
+ status: import("hono/utils/http-status").ContentfulStatusCode;
119
+ };
120
+ };
121
+ }, "/", "/tax-preview">;
122
+ export declare function mountBookingTaxRoutes(hono: Hono, options?: BookingTaxRouteOptions): void;
123
+ export declare function createBookingTaxHonoExtension(options?: BookingTaxRouteOptions): HonoExtension;
124
+ //# sourceMappingURL=booking-tax.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"booking-tax.d.ts","sourceRoot":"","sources":["../src/booking-tax.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,254 @@
1
+ import { ApiHttpError, parseJsonBody } from "@voyantjs/hono";
2
+ import { productDayServices, productDays, productItineraries, productLocations, products as productsTable, } from "@voyantjs/products/schema";
3
+ import { and, asc, eq } from "drizzle-orm";
4
+ import { Hono as HonoApp } from "hono";
5
+ import { z } from "zod";
6
+ import { taxClasses, taxPolicyProfiles, taxPolicyRules, taxRegimes } from "./schema.js";
7
+ const taxPreviewBodySchema = z.object({
8
+ productId: z.string().min(1),
9
+ subtotalCents: z.number().int().min(0),
10
+ currency: z.string().min(3).max(8),
11
+ });
12
+ const bookingTaxSettingsPatchSchema = z.object({
13
+ taxPriceMode: z.enum(["inclusive", "exclusive"]).optional(),
14
+ taxPolicyProfileId: z.string().min(1).nullable().optional(),
15
+ });
16
+ export async function resolveBookingSellTaxRate(db, args, options = {}) {
17
+ const resolvedSettings = options.settings !== undefined
18
+ ? options.settings
19
+ : ((await options.resolveBookingTaxSettings?.(db)) ?? null);
20
+ const priceMode = resolvedSettings?.taxPriceMode === "exclusive" ? "exclusive" : "inclusive";
21
+ const policyProfile = await resolveTaxPolicyProfile(db, resolvedSettings?.taxPolicyProfileId);
22
+ if (policyProfile) {
23
+ const facts = normalizeTaxFacts(args.facts ?? (args.productId ? await loadProductTaxFacts(db, args.productId) : undefined));
24
+ const rules = await db
25
+ .select({
26
+ condition: taxPolicyRules.condition,
27
+ taxRegimeId: taxPolicyRules.taxRegimeId,
28
+ })
29
+ .from(taxPolicyRules)
30
+ .where(and(eq(taxPolicyRules.profileId, policyProfile.id), eq(taxPolicyRules.side, "sell"), eq(taxPolicyRules.active, true)))
31
+ .orderBy(asc(taxPolicyRules.priority), asc(taxPolicyRules.createdAt));
32
+ for (const rule of rules) {
33
+ if (!matchesTaxPolicyCondition(rule.condition, facts))
34
+ continue;
35
+ const resolved = await loadResolvedTaxRegime(db, rule.taxRegimeId, policyProfile.code);
36
+ if (resolved)
37
+ return { ...resolved, priceMode };
38
+ }
39
+ }
40
+ return args.productId ? resolveProductTaxClassRate(db, args.productId, priceMode) : null;
41
+ }
42
+ async function resolveBookingTaxSettingsOrDefault(db, options = {}) {
43
+ const settings = options.settings !== undefined
44
+ ? options.settings
45
+ : ((await options.resolveBookingTaxSettings?.(db)) ?? null);
46
+ return {
47
+ taxPriceMode: settings?.taxPriceMode === "exclusive" ? "exclusive" : "inclusive",
48
+ taxPolicyProfileId: settings?.taxPolicyProfileId ?? null,
49
+ };
50
+ }
51
+ export function computeBookingItemTaxLine(taxRate, amountCents, currency, sortOrder = 0) {
52
+ if (!taxRate || taxRate.rate <= 0 || amountCents <= 0)
53
+ return null;
54
+ const includedInPrice = taxRate.priceMode === "inclusive";
55
+ const taxCents = includedInPrice
56
+ ? Math.round(amountCents - amountCents / (1 + taxRate.rate))
57
+ : Math.round(amountCents * taxRate.rate);
58
+ if (taxCents <= 0)
59
+ return null;
60
+ return {
61
+ code: taxRate.code,
62
+ name: taxRate.label,
63
+ scope: includedInPrice ? "included" : "excluded",
64
+ currency,
65
+ amountCents: taxCents,
66
+ rateBasisPoints: Math.round(taxRate.rate * 10_000),
67
+ includedInPrice,
68
+ sortOrder,
69
+ };
70
+ }
71
+ export async function loadProductTaxFacts(db, productId) {
72
+ const [accommodationLocations, accommodationServices] = await Promise.all([
73
+ db
74
+ .select({ countryCode: productLocations.countryCode })
75
+ .from(productLocations)
76
+ .where(eq(productLocations.productId, productId)),
77
+ db
78
+ .select({ id: productDayServices.id, countryCode: productDayServices.countryCode })
79
+ .from(productDayServices)
80
+ .innerJoin(productDays, eq(productDayServices.dayId, productDays.id))
81
+ .innerJoin(productItineraries, eq(productDays.itineraryId, productItineraries.id))
82
+ .where(and(eq(productItineraries.productId, productId), eq(productDayServices.serviceType, "accommodation"))),
83
+ ]);
84
+ const accommodationCountries = [...accommodationServices, ...accommodationLocations]
85
+ .map((entry) => entry.countryCode?.trim().toUpperCase())
86
+ .filter((countryCode) => Boolean(countryCode));
87
+ return {
88
+ hasAccommodation: accommodationLocations.length > 0 || accommodationServices.length > 0,
89
+ accommodationCountries: [...new Set(accommodationCountries)],
90
+ };
91
+ }
92
+ export function matchesTaxPolicyCondition(condition, facts) {
93
+ if (!condition)
94
+ return true;
95
+ if ("always" in condition)
96
+ return condition.always === true;
97
+ if ("all" in condition)
98
+ return condition.all.every((entry) => matchesTaxPolicyCondition(entry, facts));
99
+ if ("any" in condition)
100
+ return condition.any.some((entry) => matchesTaxPolicyCondition(entry, facts));
101
+ if (!("fact" in condition))
102
+ return false;
103
+ const value = facts[condition.fact];
104
+ if ("eq" in condition)
105
+ return value === condition.eq;
106
+ if ("contains" in condition) {
107
+ return Array.isArray(value) && value.includes(String(condition.contains).toUpperCase());
108
+ }
109
+ return false;
110
+ }
111
+ function normalizeTaxFacts(facts) {
112
+ return {
113
+ hasAccommodation: facts?.hasAccommodation === true,
114
+ accommodationCountries: [
115
+ ...new Set((facts?.accommodationCountries ?? [])
116
+ .map((countryCode) => countryCode.trim().toUpperCase())
117
+ .filter(Boolean)),
118
+ ],
119
+ };
120
+ }
121
+ async function resolveTaxPolicyProfile(db, configuredProfileId) {
122
+ if (configuredProfileId) {
123
+ const [configured] = await db
124
+ .select()
125
+ .from(taxPolicyProfiles)
126
+ .where(eq(taxPolicyProfiles.id, configuredProfileId))
127
+ .limit(1);
128
+ if (configured?.active)
129
+ return configured;
130
+ }
131
+ const [active] = await db
132
+ .select()
133
+ .from(taxPolicyProfiles)
134
+ .where(eq(taxPolicyProfiles.active, true))
135
+ .orderBy(asc(taxPolicyProfiles.createdAt))
136
+ .limit(1);
137
+ return active ?? null;
138
+ }
139
+ async function loadResolvedTaxRegime(db, taxRegimeId, codePrefix) {
140
+ const [regime] = await db
141
+ .select({
142
+ ratePercent: taxRegimes.ratePercent,
143
+ code: taxRegimes.code,
144
+ name: taxRegimes.name,
145
+ })
146
+ .from(taxRegimes)
147
+ .where(eq(taxRegimes.id, taxRegimeId))
148
+ .limit(1);
149
+ if (!regime || regime.ratePercent == null)
150
+ return null;
151
+ return {
152
+ code: `${codePrefix}/${regime.code}`,
153
+ label: regime.name,
154
+ rate: regime.ratePercent / 100,
155
+ };
156
+ }
157
+ async function resolveProductTaxClassRate(db, productId, priceMode) {
158
+ const productRows = await db
159
+ .select({ taxClassId: productsTable.taxClassId })
160
+ .from(productsTable)
161
+ .where(eq(productsTable.id, productId))
162
+ .limit(1);
163
+ const taxClassId = productRows[0]?.taxClassId;
164
+ if (!taxClassId)
165
+ return null;
166
+ const classRows = await db
167
+ .select({
168
+ defaultRegimeId: taxClasses.defaultRegimeId,
169
+ code: taxClasses.code,
170
+ })
171
+ .from(taxClasses)
172
+ .where(eq(taxClasses.id, taxClassId))
173
+ .limit(1);
174
+ const klass = classRows[0];
175
+ if (!klass?.defaultRegimeId)
176
+ return null;
177
+ const resolved = await loadResolvedTaxRegime(db, klass.defaultRegimeId, klass.code);
178
+ return resolved ? { ...resolved, priceMode } : null;
179
+ }
180
+ export function createBookingTaxRoutes(options = {}) {
181
+ return new HonoApp()
182
+ .get("/tax-settings", async (c) => {
183
+ return c.json({
184
+ data: await resolveBookingTaxSettingsOrDefault(c.get("db"), options),
185
+ });
186
+ })
187
+ .patch("/tax-settings", async (c) => {
188
+ if (!options.updateBookingTaxSettings) {
189
+ throw new ApiHttpError("Booking tax settings updates are not configured", {
190
+ status: 409,
191
+ code: "booking_tax_settings_update_not_configured",
192
+ });
193
+ }
194
+ const current = await resolveBookingTaxSettingsOrDefault(c.get("db"), options);
195
+ const patch = await parseJsonBody(c, bookingTaxSettingsPatchSchema);
196
+ const next = await options.updateBookingTaxSettings(c.get("db"), {
197
+ taxPriceMode: patch.taxPriceMode ?? current.taxPriceMode,
198
+ taxPolicyProfileId: patch.taxPolicyProfileId === undefined
199
+ ? current.taxPolicyProfileId
200
+ : patch.taxPolicyProfileId,
201
+ });
202
+ return c.json({
203
+ data: await resolveBookingTaxSettingsOrDefault(c.get("db"), { settings: next }),
204
+ });
205
+ })
206
+ .post("/tax-preview", async (c) => {
207
+ const body = await parseJsonBody(c, taxPreviewBodySchema);
208
+ const taxRate = await resolveBookingSellTaxRate(c.get("db"), { productId: body.productId }, options);
209
+ const taxLine = computeBookingItemTaxLine(taxRate, body.subtotalCents, body.currency);
210
+ if (!taxRate || !taxLine) {
211
+ return c.json({
212
+ data: {
213
+ subtotalCents: body.subtotalCents,
214
+ taxCents: 0,
215
+ totalCents: body.subtotalCents,
216
+ currency: body.currency,
217
+ taxRate: null,
218
+ },
219
+ });
220
+ }
221
+ const inclusive = taxLine.includedInPrice;
222
+ const displaySubtotal = inclusive
223
+ ? Math.max(0, body.subtotalCents - taxLine.amountCents)
224
+ : body.subtotalCents;
225
+ const total = inclusive ? body.subtotalCents : body.subtotalCents + taxLine.amountCents;
226
+ return c.json({
227
+ data: {
228
+ subtotalCents: displaySubtotal,
229
+ taxCents: taxLine.amountCents,
230
+ totalCents: total,
231
+ currency: body.currency,
232
+ taxRate: {
233
+ code: taxRate.code,
234
+ label: taxRate.label,
235
+ rateBasisPoints: Math.round(taxRate.rate * 10_000),
236
+ priceMode: taxRate.priceMode,
237
+ },
238
+ },
239
+ });
240
+ });
241
+ }
242
+ export function mountBookingTaxRoutes(hono, options = {}) {
243
+ hono.route("/v1/admin/bookings", createBookingTaxRoutes(options));
244
+ }
245
+ export function createBookingTaxHonoExtension(options = {}) {
246
+ const extension = {
247
+ name: "booking-tax",
248
+ module: "bookings",
249
+ };
250
+ return {
251
+ extension,
252
+ adminRoutes: createBookingTaxRoutes(options),
253
+ };
254
+ }
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ export interface FinanceHonoModuleOptions extends FinanceRuntimeOptions, PublicF
19
19
  }
20
20
  export declare function createFinanceHonoModule(options?: FinanceHonoModuleOptions): HonoModule;
21
21
  export declare const financeHonoModule: HonoModule;
22
+ export { type BookingTaxRouteOptions, type BookingTaxSettings, computeBookingItemTaxLine, createBookingTaxHonoExtension, createBookingTaxRoutes, loadProductTaxFacts, matchesTaxPolicyCondition, mountBookingTaxRoutes, type ProductTaxFacts, type ResolveBookingSellTaxRateOptions, type ResolveBookingTaxSettings, type ResolvedBookingSellTaxRate, resolveBookingSellTaxRate, type TaxPolicyCondition, type UpdateBookingTaxSettings, } from "./booking-tax.js";
22
23
  export type { ComputedScheduleEntry, ComputeScheduleInput, DepositKind, DepositRule, PaymentPolicy, PaymentPolicyCascadeLayers, PaymentPolicySource, PaymentScheduleEntryType, ResolvedPaymentPolicy, } from "./payment-policy.js";
23
24
  export { computePaymentSchedule, isPaymentPolicyEmpty, noDepositPolicy, policyShouldRequireFullPayment, resolveEffectivePaymentPolicy, } from "./payment-policy.js";
24
25
  export { buildFinanceRouteRuntime, FINANCE_ROUTE_RUNTIME_CONTAINER_KEY, type FinanceRouteRuntime, type FinanceRuntimeOptions, } from "./route-runtime.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,oBAAoB,CAAA;AAI3B,OAAO,EAA6B,KAAK,yBAAyB,EAAE,MAAM,oBAAoB,CAAA;AAG9F,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EACL,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,mBAAmB,GACpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE5F,eAAO,MAAM,eAAe,EAAE,kBAK7B,CAAA;AAED,eAAO,MAAM,uBAAuB,EAAE,kBAKrC,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,kBAKhC,CAAA;AAED,eAAO,MAAM,eAAe;;;;CAI3B,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAG3B,CAAA;AAED,MAAM,WAAW,wBACf,SAAQ,qBAAqB,EAC3B,yBAAyB;CAAG;AAEhC,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,wBAA6B,GAAG,UAAU,CA2B1F;AAED,eAAO,MAAM,iBAAiB,EAAE,UAAsC,CAAA;AAEtE,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,gCAAgC,EACrC,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,GAC9B,MAAM,kBAAkB,CAAA;AACzB,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,aAAa,EACb,0BAA0B,EAC1B,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,wBAAwB,EACxB,mCAAmC,EACnC,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,EACL,gCAAgC,EAChC,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,GAC9B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,kCAAkC,EAClC,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,GAC7B,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,SAAS,EACT,OAAO,EACP,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,QAAQ,GACT,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,yBAAyB,EACzB,+BAA+B,EAC/B,6BAA6B,EAC7B,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChE,YAAY,EACV,kCAAkC,EAClC,iBAAiB,GAClB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,mBAAmB,EACnB,aAAa,GACd,MAAM,6BAA6B,CAAA;AACpC,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,mCAAmC,CAAA;AAC1C,YAAY,EACV,8BAA8B,EAC9B,iCAAiC,EACjC,6BAA6B,EAC7B,+BAA+B,EAC/B,6BAA6B,EAC7B,4CAA4C,EAC5C,sCAAsC,EACtC,kCAAkC,GACnC,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,iCAAiC,EACjC,2CAA2C,EAC3C,mCAAmC,EACnC,6CAA6C,EAC7C,uBAAuB,GACxB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACjF,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AACtF,YAAY,EACV,+BAA+B,EAC/B,mBAAmB,EACnB,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC5E,OAAO,EACL,qCAAqC,EACrC,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,GAC1B,MAAM,iCAAiC,CAAA;AACxC,YAAY,EACV,8BAA8B,EAC9B,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,sBAAsB,EACtB,gCAAgC,EAChC,oCAAoC,EACpC,0BAA0B,EAC1B,4BAA4B,EAC5B,uCAAuC,EACvC,qCAAqC,EACrC,sCAAsC,EACtC,0BAA0B,EAC1B,wBAAwB,EACxB,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EAClC,4BAA4B,EAC5B,iCAAiC,EACjC,8BAA8B,EAC9B,kCAAkC,EAClC,8BAA8B,EAC9B,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EAC9B,2BAA2B,EAC3B,+BAA+B,EAC/B,4BAA4B,EAC5B,mBAAmB,EACnB,2BAA2B,EAC3B,gCAAgC,EAChC,0BAA0B,EAC1B,6BAA6B,EAC7B,mBAAmB,EACnB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,kCAAkC,EAClC,8BAA8B,EAC9B,wCAAwC,EACxC,mCAAmC,EACnC,6BAA6B,EAC7B,gCAAgC,EAChC,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,6BAA6B,EAC7B,2CAA2C,EAC3C,mCAAmC,EACnC,gCAAgC,EAChC,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,8BAA8B,EAC9B,uBAAuB,EACvB,+BAA+B,EAC/B,4BAA4B,EAC5B,wBAAwB,EACxB,4BAA4B,EAC5B,iCAAiC,EACjC,8BAA8B,EAC9B,kCAAkC,EAClC,8BAA8B,EAC9B,sBAAsB,EACtB,8BAA8B,EAC9B,2BAA2B,EAC3B,+BAA+B,EAC/B,4BAA4B,EAC5B,mBAAmB,EACnB,2BAA2B,EAC3B,gCAAgC,EAChC,0BAA0B,EAC1B,6BAA6B,EAC7B,mBAAmB,EACnB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,8BAA8B,EAC9B,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,mCAAmC,EACnC,kCAAkC,EAClC,iCAAiC,EACjC,kCAAkC,EAClC,iCAAiC,EACjC,uCAAuC,EACvC,iCAAiC,EACjC,sCAAsC,EACtC,iCAAiC,EACjC,8BAA8B,EAC9B,+BAA+B,EAC/B,0BAA0B,EAC1B,+BAA+B,EAC/B,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,wBAAwB,CAAA"}
package/dist/index.js CHANGED
@@ -62,6 +62,7 @@ export function createFinanceHonoModule(options = {}) {
62
62
  };
63
63
  }
64
64
  export const financeHonoModule = createFinanceHonoModule();
65
+ export { computeBookingItemTaxLine, createBookingTaxHonoExtension, createBookingTaxRoutes, loadProductTaxFacts, matchesTaxPolicyCondition, mountBookingTaxRoutes, resolveBookingSellTaxRate, } from "./booking-tax.js";
65
66
  export { computePaymentSchedule, isPaymentPolicyEmpty, noDepositPolicy, policyShouldRequireFullPayment, resolveEffectivePaymentPolicy, } from "./payment-policy.js";
66
67
  export { buildFinanceRouteRuntime, FINANCE_ROUTE_RUNTIME_CONTAINER_KEY, } from "./route-runtime.js";
67
68
  export { bookingsCreateExtension } from "./routes-booking-create.js";
@@ -143,6 +143,8 @@ export declare const bookingCreateSchema: z.ZodObject<{
143
143
  export declare const bookingCreateSubSchema: z.ZodObject<{
144
144
  organizationId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
145
145
  personId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
146
+ productId: z.ZodString;
147
+ optionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
146
148
  bookingNumber: z.ZodString;
147
149
  contactFirstName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
148
150
  contactLastName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -155,8 +157,6 @@ export declare const bookingCreateSubSchema: z.ZodObject<{
155
157
  contactAddressLine1: z.ZodNullable<z.ZodOptional<z.ZodString>>;
156
158
  contactPostalCode: z.ZodNullable<z.ZodOptional<z.ZodString>>;
157
159
  internalNotes: z.ZodNullable<z.ZodOptional<z.ZodString>>;
158
- productId: z.ZodString;
159
- optionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
160
160
  travelers: z.ZodOptional<z.ZodArray<z.ZodObject<{
161
161
  firstName: z.ZodString;
162
162
  lastName: z.ZodString;
@@ -7,6 +7,8 @@ export declare const dualCreateBookingSchema: z.ZodObject<{
7
7
  primary: z.ZodObject<{
8
8
  organizationId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
9
9
  personId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
10
+ productId: z.ZodString;
11
+ optionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
10
12
  bookingNumber: z.ZodString;
11
13
  contactFirstName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
12
14
  contactLastName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -19,8 +21,6 @@ export declare const dualCreateBookingSchema: z.ZodObject<{
19
21
  contactAddressLine1: z.ZodNullable<z.ZodOptional<z.ZodString>>;
20
22
  contactPostalCode: z.ZodNullable<z.ZodOptional<z.ZodString>>;
21
23
  internalNotes: z.ZodNullable<z.ZodOptional<z.ZodString>>;
22
- productId: z.ZodString;
23
- optionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
24
24
  travelers: z.ZodOptional<z.ZodArray<z.ZodObject<{
25
25
  firstName: z.ZodString;
26
26
  lastName: z.ZodString;
@@ -102,6 +102,8 @@ export declare const dualCreateBookingSchema: z.ZodObject<{
102
102
  secondary: z.ZodObject<{
103
103
  organizationId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
104
104
  personId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
105
+ productId: z.ZodString;
106
+ optionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
105
107
  bookingNumber: z.ZodString;
106
108
  contactFirstName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
107
109
  contactLastName: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -114,8 +116,6 @@ export declare const dualCreateBookingSchema: z.ZodObject<{
114
116
  contactAddressLine1: z.ZodNullable<z.ZodOptional<z.ZodString>>;
115
117
  contactPostalCode: z.ZodNullable<z.ZodOptional<z.ZodString>>;
116
118
  internalNotes: z.ZodNullable<z.ZodOptional<z.ZodString>>;
117
- productId: z.ZodString;
118
- optionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
119
119
  travelers: z.ZodOptional<z.ZodArray<z.ZodObject<{
120
120
  firstName: z.ZodString;
121
121
  lastName: z.ZodString;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/finance",
3
- "version": "0.53.2",
3
+ "version": "0.55.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -24,6 +24,11 @@
24
24
  "import": "./dist/validation.js",
25
25
  "default": "./dist/validation.js"
26
26
  },
27
+ "./booking-tax": {
28
+ "types": "./dist/booking-tax.d.ts",
29
+ "import": "./dist/booking-tax.js",
30
+ "default": "./dist/booking-tax.js"
31
+ },
27
32
  "./routes": {
28
33
  "types": "./dist/routes.d.ts",
29
34
  "import": "./dist/routes.js",
@@ -44,13 +49,14 @@
44
49
  "drizzle-orm": "^0.45.2",
45
50
  "hono": "^4.12.10",
46
51
  "zod": "^4.3.6",
47
- "@voyantjs/action-ledger": "0.53.2",
48
- "@voyantjs/bookings": "0.53.2",
49
- "@voyantjs/core": "0.53.2",
50
- "@voyantjs/db": "0.53.2",
51
- "@voyantjs/hono": "0.53.2",
52
- "@voyantjs/utils": "0.53.2",
53
- "@voyantjs/storage": "0.53.2"
52
+ "@voyantjs/action-ledger": "0.55.0",
53
+ "@voyantjs/bookings": "0.55.0",
54
+ "@voyantjs/core": "0.55.0",
55
+ "@voyantjs/db": "0.55.0",
56
+ "@voyantjs/hono": "0.55.0",
57
+ "@voyantjs/products": "0.55.0",
58
+ "@voyantjs/utils": "0.55.0",
59
+ "@voyantjs/storage": "0.55.0"
54
60
  },
55
61
  "devDependencies": {
56
62
  "typescript": "^6.0.2",