import {z} from 'zod' export type InstallmentPreferences = {cadence?: ('none' | 'fullPay' | 'weekly' | 'everyOtherWeek' | 'monthly' | 'quarterly' | 'semiannually' | 'annually' | 'thirtyDays' | 'everyNDays') | undefined, anchorMode?: ('generateDay' | 'termStartDay' | 'dueDay') | undefined, generateLeadDays?: number | undefined, dueLeadDays?: number | undefined, installmentWeights: Array, maxInstallmentsPerTerm?: number | undefined, installmentPlanName?: string | undefined, anchorType?: ('none' | 'dayOfMonth' | 'anchorTime' | 'dayOfWeek' | 'weekOfMonth') | undefined, dayOfMonth?: number | undefined, dayOfWeek?: ('monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday') | undefined, weekOfMonth?: ('none' | 'first' | 'second' | 'third' | 'fourth' | 'fifth') | undefined, anchorTime?: string | undefined, autopayLeadDays?: number | undefined}; export type PreviewChargeRequest = {amount: number, chargeType: string, elementLocator?: unknown | undefined, elementStaticLocator?: unknown | undefined}; export type QuoteBillingPreviewRequest = {accountLocator: unknown, productName: string, termStartTime: string, termEndTime: string, timezone?: string | undefined, durationBasis?: ('years' | 'months' | 'weeks' | 'days' | 'hours') | undefined, currency?: string | undefined, invoiceFeeAmount?: number | undefined, installmentPreferences?: InstallmentPreferences | undefined, charges: Array}; export type GetApiBillingTenantLocatorInstallmentsQuotesStatelessPreviewArgs = {tenantLocator: string, quotePreviewRequest: QuoteBillingPreviewRequest}; export type GetApiBillingTenantLocatorInstallmentsQuotesStatelessPreviewOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const installmentItem = z.object({locator: z.string(), installmentLocator: z.string(), chargeLocator: z.string(), elementLocator: z.string(), elementStaticLocator: z.string(), chargeType: z.string(), chargeCategory: z.string(), amount: z.number(), invoiceItemLocator: z.string().optional(), createdAt: z.string(), createdBy: z.string(), reversalOfInstallmentItemLocator: z.string().optional()}); export const installment = z.object({locator: z.string(), installmentLatticeLocator: z.string(), accountLocator: z.string(), currency: z.string(), timezone: z.string(), installmentFrameIndex: z.number().int(), quoteLocator: z.string().optional(), policyLocator: z.string().optional(), transactionLocator: z.string().optional(), installmentStartTime: z.string(), installmentEndTime: z.string(), coverageStartTime: z.string(), coverageEndTime: z.string(), installmentDuration: z.number(), coverageDuration: z.number(), generateTime: z.string(), dueTime: z.string(), invoiceLocator: z.string().optional(), createdAt: z.string(), createdBy: z.string(), updatedAt: z.string(), updatedBy: z.string(), installmentItems: z.array(installmentItem), reversalOfInstallmentLocator: z.string().optional(), termLocator: z.string().optional(), migratedFromInstallmentLocator: z.string().optional(), autopayTime: z.string().optional(), enhancedByPlugin: z.boolean().optional()}); export const chargeMetadata = z.object({policyLocator: z.string().optional(), transactionLocator: z.string().optional(), elementStaticLocator: z.string().optional(), timezone: z.string().optional(), invoicing: z.enum(["scheduled", "next", "immediate"]).optional()}); export const chargeQueueItem = z.object({chargeLocator: z.string(), accountLocator: z.string(), invoiceItemLocator: z.string().optional(), chargeSource: z.enum(["billing", "policy"]), currency: z.string(), amount: z.number(), chargeType: z.string(), chargeMetadata: chargeMetadata}); export const installmentSettings = z.object({cadence: z.enum(["none", "fullPay", "weekly", "everyOtherWeek", "monthly", "quarterly", "semiannually", "annually", "thirtyDays", "everyNDays"]), anchorMode: z.enum(["generateDay", "termStartDay", "dueDay"]), generateLeadDays: z.number().int(), dueLeadDays: z.number().int(), installmentWeights: z.array(z.number()), maxInstallmentsPerTerm: z.number().int().optional(), anchorType: z.enum(["none", "dayOfMonth", "anchorTime", "dayOfWeek", "weekOfMonth"]).optional(), dayOfMonth: z.number().int().optional(), dayOfWeek: z.enum(["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]).optional(), weekOfMonth: z.enum(["none", "first", "second", "third", "fourth", "fifth"]).optional(), anchorTime: z.string().optional(), autopayLeadDays: z.number().optional()}); export const settings = z.object({locator: z.string(), installmentSettings: installmentSettings, createdAt: z.string(), createdBy: z.string()}); export const installmentsPreview = z.object({installments: z.array(installment), accountLocator: z.string(), quoteLocator: z.string().optional(), policyLocator: z.string().optional(), transactionLocator: z.string().optional(), queuedPolicyCharges: z.array(chargeQueueItem), durationBasis: z.enum(["years", "months", "weeks", "days", "hours"]), settings: settings, persistedInstallmentLocators: z.array(z.string())}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * GET /billing/{tenantLocator}/installments/quotes/statelessPreview */ export const getApiBillingTenantLocatorInstallmentsQuotesStatelessPreview = async (args: GetApiBillingTenantLocatorInstallmentsQuotesStatelessPreviewArgs, options: GetApiBillingTenantLocatorInstallmentsQuotesStatelessPreviewOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.quotePreviewRequest != null) query.append("quotePreviewRequest", JSON.stringify(args.quotePreviewRequest)) const url = `${baseUrl.replace(/\/+$/, '')}/billing/${encodeURIComponent(String(args.tenantLocator))}/installments/quotes/statelessPreview${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(installmentsPreview, await res.json()) };