@voyant-travel/finance 0.166.0 → 0.167.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/dist/booking-tax.d.ts
CHANGED
|
@@ -23,9 +23,11 @@ export type BookingTaxSettings = {
|
|
|
23
23
|
taxPriceMode?: "inclusive" | "exclusive" | null;
|
|
24
24
|
taxPolicyProfileId?: string | null;
|
|
25
25
|
/**
|
|
26
|
-
* Operator invoicing mode
|
|
27
|
-
*
|
|
28
|
-
* to a fiscal invoice on full settlement
|
|
26
|
+
* Operator invoicing mode for the deferred bank-transfer path.
|
|
27
|
+
* `proforma-first` issues a proforma at order placement and converts it
|
|
28
|
+
* to a fiscal invoice on full settlement; `direct` issues the fiscal
|
|
29
|
+
* invoice at order placement. Card payments always invoice directly and
|
|
30
|
+
* never consult this. Absent/null → `proforma-first`.
|
|
29
31
|
*/
|
|
30
32
|
invoicingMode?: InvoicingMode | null;
|
|
31
33
|
/**
|
|
@@ -57,12 +59,6 @@ export declare function resolveBookingSellTaxRate(db: PostgresJsDatabase, args:
|
|
|
57
59
|
productId?: string | null;
|
|
58
60
|
facts?: Partial<ProductTaxFacts>;
|
|
59
61
|
}, options?: ResolveBookingSellTaxRateOptions): Promise<ResolvedBookingSellTaxRate | null>;
|
|
60
|
-
/**
|
|
61
|
-
* Resolve just the operator invoicing mode, defaulting to `direct`
|
|
62
|
-
* when no settings row exists. Shared by the proforma-conversion
|
|
63
|
-
* subscriber so it never converts unless the operator opted in.
|
|
64
|
-
*/
|
|
65
|
-
export declare function resolveInvoicingModeOrDefault(db: PostgresJsDatabase, options?: ResolveBookingSellTaxRateOptions): Promise<InvoicingMode>;
|
|
66
62
|
export declare function computeBookingItemTaxLine(taxRate: ResolvedBookingSellTaxRate | null, amountCents: number, currency: string, sortOrder?: number): {
|
|
67
63
|
code: string;
|
|
68
64
|
name: string;
|
package/dist/booking-tax.js
CHANGED
|
@@ -117,19 +117,10 @@ async function resolveBookingTaxSettingsOrDefault(db, options = {}) {
|
|
|
117
117
|
return {
|
|
118
118
|
taxPriceMode: settings?.taxPriceMode === "exclusive" ? "exclusive" : "inclusive",
|
|
119
119
|
taxPolicyProfileId: settings?.taxPolicyProfileId ?? null,
|
|
120
|
-
invoicingMode: settings?.invoicingMode === "
|
|
120
|
+
invoicingMode: settings?.invoicingMode === "direct" ? "direct" : "proforma-first",
|
|
121
121
|
fxReferenceSource: settings?.fxReferenceSource === "bnr" ? "bnr" : "ecb",
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
|
-
/**
|
|
125
|
-
* Resolve just the operator invoicing mode, defaulting to `direct`
|
|
126
|
-
* when no settings row exists. Shared by the proforma-conversion
|
|
127
|
-
* subscriber so it never converts unless the operator opted in.
|
|
128
|
-
*/
|
|
129
|
-
export async function resolveInvoicingModeOrDefault(db, options = {}) {
|
|
130
|
-
const settings = await resolveBookingTaxSettingsOrDefault(db, options);
|
|
131
|
-
return settings.invoicingMode;
|
|
132
|
-
}
|
|
133
124
|
export function computeBookingItemTaxLine(taxRate, amountCents, currency, sortOrder = 0) {
|
|
134
125
|
if (!taxRate || taxRate.rate <= 0 || amountCents <= 0)
|
|
135
126
|
return null;
|
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare const createFinanceVoyantRuntime: import("@voyant-travel/core/pro
|
|
|
26
26
|
export type { PaymentAdapter, PaymentAdapterCapabilities, PaymentAdapterConformanceHarness, PaymentAdapterConformanceResult, PaymentAdapterDiagnostics, PaymentAdapterRuntimeContext, PaymentCallbackEvent, PaymentCallbackRequest, PaymentCallbackVerificationResult, PaymentInitiationInput, PaymentInitiationResult, PaymentMoney, PaymentOperationInput, PaymentOperationResult, PaymentStatusInput, PaymentStatusResult, } from "@voyant-travel/payments";
|
|
27
27
|
export { PAYMENT_ADAPTER_CONTRACT_VERSION, PAYMENT_ADAPTER_RUNTIME_PORT_ID, paymentAdapterRuntimePort, runPaymentAdapterConformance, } from "@voyant-travel/payments";
|
|
28
28
|
export { type BookingCancellationSettlementInput, buildPaidBookingCancellationSettlementNote, closeTerminalBookingPaymentSchedules, financeBookingLifecycle, recordPaidBookingCancellationSettlement, } from "./booking-lifecycle.js";
|
|
29
|
-
export { type BookingTaxRouteOptions, type BookingTaxSettings, computeBookingItemTaxLine, createBookingTaxApiExtension, createBookingTaxRoutes, createBookingTaxVoyantRuntime,
|
|
29
|
+
export { type BookingTaxRouteOptions, type BookingTaxSettings, computeBookingItemTaxLine, createBookingTaxApiExtension, createBookingTaxRoutes, createBookingTaxVoyantRuntime, loadProductTaxFacts, matchesTaxPolicyCondition, mountBookingTaxRoutes, type ProductTaxFacts, type ResolveBookingSellTaxRateOptions, type ResolveBookingTaxSettings, type ResolvedBookingSellTaxRate, resolveBookingSellTaxRate, type TaxPolicyCondition, type UpdateBookingTaxSettings, } from "./booking-tax.js";
|
|
30
30
|
export type { CardPaymentBilling, CardPaymentStartArgs, CardPaymentStarter, CardPaymentStartResult, PaymentAdapterCardPaymentStarterOptions, } from "./card-payment.js";
|
|
31
31
|
export { createPaymentAdapterCardPaymentStarter } from "./card-payment.js";
|
|
32
32
|
export { type DocumentDownloadEnvelope, type DocumentDownloadResolution, type DocumentDownloadResolver, resolveStoredDocumentDownload, type StoredDocumentReference, } from "./document-download.js";
|
|
@@ -385,11 +385,9 @@ export const createBookingScheduleVoyantRuntime = defineGraphRuntimeFactory(asyn
|
|
|
385
385
|
resolveRoutesOptions: () => provider.options,
|
|
386
386
|
withDb: provider.withDb,
|
|
387
387
|
});
|
|
388
|
-
// Same host
|
|
389
|
-
//
|
|
390
|
-
// proforma-first mode, mints the fiscal invoice on settlement.
|
|
388
|
+
// Same host wiring powers the proforma-conversion subscriber:
|
|
389
|
+
// when a fully-paid proforma settles it mints the fiscal invoice.
|
|
391
390
|
container.register(PROFORMA_CONVERSION_SUBSCRIBER_RUNTIME_KEY, {
|
|
392
|
-
resolveInvoicingMode: operatorSettings.resolveInvoicingMode,
|
|
393
391
|
withDb: provider.withDb,
|
|
394
392
|
eventBus,
|
|
395
393
|
});
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
import type { EventBus, SubscriberRuntimeDescriptor } from "@voyant-travel/core";
|
|
2
2
|
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
|
-
import type { InvoicingMode } from "./booking-tax.js";
|
|
4
3
|
/**
|
|
5
4
|
* Standard proforma → fiscal invoice conversion.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* (`invoice.settled` from the settlement poller and
|
|
11
|
-
* `invoice.payment.recorded` from manual/processed payments) and
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
6
|
+
* A proforma is issued for deferred (bank-transfer) checkouts when the
|
|
7
|
+
* operator runs the `proforma-first` invoicing mode, or by the manual
|
|
8
|
+
* `POST /invoices/{id}/convert-to-invoice` flow. This subscriber watches
|
|
9
|
+
* settlement signals (`invoice.settled` from the settlement poller and
|
|
10
|
+
* `invoice.payment.recorded` from manual/processed payments) and converts
|
|
11
|
+
* a fully-paid proforma to its fiscal invoice via
|
|
12
|
+
* {@link convertProformaToInvoice} (which copies lines, assigns the fiscal
|
|
13
|
+
* number, links both documents, and voids the proforma).
|
|
14
|
+
*
|
|
15
|
+
* The conversion is not gated on the invoicing mode: any fully-paid
|
|
16
|
+
* proforma should mint its fiscal invoice, and the `invoiceType ===
|
|
17
|
+
* "proforma"` guard already scopes it to proformas. Gating on the current
|
|
18
|
+
* mode would strand a proforma that is still outstanding when an operator
|
|
19
|
+
* switches from `proforma-first` to `direct`. When no proforma exists
|
|
20
|
+
* (card checkouts, or bank transfer in `direct` mode) the subscriber
|
|
21
|
+
* simply never fires. The conversion is idempotent (the service guards
|
|
22
|
+
* against double-conversion under an advisory lock).
|
|
18
23
|
*/
|
|
19
24
|
export declare const FINANCE_PROFORMA_CONVERSION_SUBSCRIBER_ID = "@voyant-travel/finance#subscriber.proforma-conversion";
|
|
20
25
|
export declare const PROFORMA_CONVERSION_SUBSCRIBER_RUNTIME_KEY = "finance.proformaConversionSubscriberRuntime";
|
|
21
26
|
export interface ProformaConversionSubscriberRuntime {
|
|
22
|
-
/** Operator invoicing mode; defaults to `direct` when unconfigured. */
|
|
23
|
-
resolveInvoicingMode(db: PostgresJsDatabase): Promise<InvoicingMode>;
|
|
24
27
|
/** Resolve the deployment database and retain ownership of its lifecycle. */
|
|
25
28
|
withDb<T>(bindings: unknown, operation: (db: PostgresJsDatabase) => Promise<T>): Promise<T>;
|
|
26
29
|
/** Event bus used to re-emit conversion events for downstream plugins. */
|
|
@@ -3,17 +3,23 @@ import { convertProformaToInvoice } from "./service-issue.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Standard proforma → fiscal invoice conversion.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* (`invoice.settled` from the settlement poller and
|
|
10
|
-
* `invoice.payment.recorded` from manual/processed payments) and
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
6
|
+
* A proforma is issued for deferred (bank-transfer) checkouts when the
|
|
7
|
+
* operator runs the `proforma-first` invoicing mode, or by the manual
|
|
8
|
+
* `POST /invoices/{id}/convert-to-invoice` flow. This subscriber watches
|
|
9
|
+
* settlement signals (`invoice.settled` from the settlement poller and
|
|
10
|
+
* `invoice.payment.recorded` from manual/processed payments) and converts
|
|
11
|
+
* a fully-paid proforma to its fiscal invoice via
|
|
12
|
+
* {@link convertProformaToInvoice} (which copies lines, assigns the fiscal
|
|
13
|
+
* number, links both documents, and voids the proforma).
|
|
14
|
+
*
|
|
15
|
+
* The conversion is not gated on the invoicing mode: any fully-paid
|
|
16
|
+
* proforma should mint its fiscal invoice, and the `invoiceType ===
|
|
17
|
+
* "proforma"` guard already scopes it to proformas. Gating on the current
|
|
18
|
+
* mode would strand a proforma that is still outstanding when an operator
|
|
19
|
+
* switches from `proforma-first` to `direct`. When no proforma exists
|
|
20
|
+
* (card checkouts, or bank transfer in `direct` mode) the subscriber
|
|
21
|
+
* simply never fires. The conversion is idempotent (the service guards
|
|
22
|
+
* against double-conversion under an advisory lock).
|
|
17
23
|
*/
|
|
18
24
|
export const FINANCE_PROFORMA_CONVERSION_SUBSCRIBER_ID = "@voyant-travel/finance#subscriber.proforma-conversion";
|
|
19
25
|
export const PROFORMA_CONVERSION_SUBSCRIBER_RUNTIME_KEY = "finance.proformaConversionSubscriberRuntime";
|
|
@@ -26,15 +32,13 @@ export function createProformaConversionSubscriberRuntime(dependencies = {}) {
|
|
|
26
32
|
eventType: "invoice.settled",
|
|
27
33
|
register: ({ bindings, container, eventBus }) => {
|
|
28
34
|
const handler = async ({ data }) => {
|
|
29
|
-
// Runtime is
|
|
30
|
-
//
|
|
35
|
+
// Runtime is registered by the finance booking-schedule host wiring.
|
|
36
|
+
// Absent → the deployment did not mount finance settlement → no-op.
|
|
31
37
|
if (!container.has(PROFORMA_CONVERSION_SUBSCRIBER_RUNTIME_KEY))
|
|
32
38
|
return;
|
|
33
39
|
const runtime = resolveProformaConversionSubscriberRuntime(container);
|
|
34
40
|
try {
|
|
35
41
|
await runtime.withDb(bindings, async (db) => {
|
|
36
|
-
if ((await runtime.resolveInvoicingMode(db)) !== "proforma-first")
|
|
37
|
-
return;
|
|
38
42
|
const invoice = await financeService.getInvoiceById(db, data.invoiceId);
|
|
39
43
|
if (!invoice)
|
|
40
44
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyant-travel/finance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.167.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -151,17 +151,17 @@
|
|
|
151
151
|
"hono": "^4.12.27",
|
|
152
152
|
"zod": "^4.4.3",
|
|
153
153
|
"@voyant-travel/action-ledger": "^0.111.1",
|
|
154
|
+
"@voyant-travel/bookings": "^0.167.0",
|
|
155
|
+
"@voyant-travel/core": "^0.125.0",
|
|
154
156
|
"@voyant-travel/db": "^0.114.10",
|
|
155
157
|
"@voyant-travel/types": "^0.109.3",
|
|
156
|
-
"@voyant-travel/
|
|
158
|
+
"@voyant-travel/finance-contracts": "^0.106.2",
|
|
157
159
|
"@voyant-travel/hono": "^0.128.1",
|
|
158
|
-
"@voyant-travel/
|
|
159
|
-
"@voyant-travel/storage": "^0.111.1",
|
|
160
|
-
"@voyant-travel/payments": "^0.2.0",
|
|
161
|
-
"@voyant-travel/tools": "^0.3.0",
|
|
160
|
+
"@voyant-travel/payments": "^0.2.1",
|
|
162
161
|
"@voyant-travel/public-document-delivery": "^0.4.1",
|
|
163
|
-
"@voyant-travel/
|
|
164
|
-
"@voyant-travel/utils": "^0.107.1"
|
|
162
|
+
"@voyant-travel/storage": "^0.111.1",
|
|
163
|
+
"@voyant-travel/utils": "^0.107.1",
|
|
164
|
+
"@voyant-travel/tools": "^0.3.0"
|
|
165
165
|
},
|
|
166
166
|
"devDependencies": {
|
|
167
167
|
"drizzle-kit": "^0.31.10",
|