import {z} from 'zod' export type GetApiQuickbooksDesktopReportsAgingArgs = {'Conductor-End-User-Id': string, reportType: 'ap_aging_detail' | 'ap_aging_summary' | 'ar_aging_detail' | 'ar_aging_summary' | 'collections_report', reportDateFrom?: string | undefined, reportDateTo?: string | undefined, reportDateMacro?: ('all' | 'today' | 'this_week' | 'this_week_to_date' | 'this_month' | 'this_month_to_date' | 'this_quarter' | 'this_quarter_to_date' | 'this_year' | 'this_year_to_date' | 'yesterday' | 'last_week' | 'last_week_to_date' | 'last_month' | 'last_month_to_date' | 'last_quarter' | 'last_quarter_to_date' | 'last_year' | 'last_year_to_date' | 'next_week' | 'next_four_weeks' | 'next_month' | 'next_quarter' | 'next_year') | undefined, accountType?: ('accounts_payable' | 'accounts_receivable' | 'allowed_for_1099' | 'ap_and_sales_tax' | 'ap_or_credit_card' | 'ar_and_ap' | 'asset' | 'balance_sheet' | 'bank' | 'bank_and_ar_and_ap_and_uf' | 'bank_and_uf' | 'cost_of_sales' | 'credit_card' | 'current_asset' | 'current_asset_and_expense' | 'current_liability' | 'equity' | 'equity_and_income_and_expense' | 'expense_and_other_expense' | 'fixed_asset' | 'income_and_expense' | 'income_and_other_income' | 'liability' | 'liability_and_equity' | 'long_term_liability' | 'non_posting' | 'ordinary_expense' | 'ordinary_income' | 'ordinary_income_and_cogs' | 'ordinary_income_and_expense' | 'other_asset' | 'other_current_asset' | 'other_current_liability' | 'other_expense' | 'other_income' | 'other_income_or_expense') | undefined, accountIds?: Array | undefined, accountFullNames?: Array | undefined, entityType?: ('customer' | 'employee' | 'other_name' | 'vendor') | undefined, entityIds?: Array | undefined, entityFullNames?: Array | undefined, itemType?: ('all_except_fixed_asset' | 'assembly' | 'discount' | 'fixed_asset' | 'inventory' | 'inventory_and_assembly' | 'non_inventory' | 'other_charge' | 'payment' | 'sales' | 'sales_tax' | 'service') | undefined, itemIds?: Array | undefined, itemFullNames?: Array | undefined, classIds?: Array | undefined, classFullNames?: Array | undefined, transactionTypes?: (Array<'all' | 'ar_refund_credit_card' | 'bill' | 'bill_payment_check' | 'bill_payment_credit_card' | 'build_assembly' | 'charge' | 'check' | 'credit_card_charge' | 'credit_card_credit' | 'credit_memo' | 'deposit' | 'estimate' | 'inventory_adjustment' | 'invoice' | 'item_receipt' | 'journal_entry' | 'liability_adjustment' | 'paycheck' | 'payroll_liability_check' | 'purchase_order' | 'receive_payment' | 'sales_order' | 'sales_receipt' | 'sales_tax_payment_check' | 'transfer' | 'vendor_credit' | 'ytd_adjustment'>) | undefined, detailLevel?: ('all' | 'all_except_summary' | 'summary_only') | undefined, postingStatus?: ('either' | 'non_posting' | 'posting') | undefined, updatedAfter?: string | undefined, updatedBefore?: string | undefined, updatedDateMacro?: ('all' | 'today' | 'this_week' | 'this_week_to_date' | 'this_month' | 'this_month_to_date' | 'this_quarter' | 'this_quarter_to_date' | 'this_year' | 'this_year_to_date' | 'yesterday' | 'last_week' | 'last_week_to_date' | 'last_month' | 'last_month_to_date' | 'last_quarter' | 'last_quarter_to_date' | 'last_year' | 'last_year_to_date' | 'next_week' | 'next_four_weeks' | 'next_month' | 'next_quarter' | 'next_year') | undefined, includeColumns?: (Array<'account' | 'aging' | 'amount' | 'amount_difference' | 'average_cost' | 'billed_date' | 'billing_status' | 'calculated_amount' | 'class' | 'cleared_status' | 'cost_price' | 'credit' | 'currency' | 'date' | 'debit' | 'delivery_date' | 'due_date' | 'estimate_active' | 'exchange_rate' | 'shipment_origin' | 'income_subject_to_tax' | 'invoiced' | 'item' | 'description' | 'last_modified_by' | 'latest_or_prior_state' | 'memo' | 'updated_at' | 'name' | 'name_account_number' | 'name_address' | 'name_city' | 'name_contact' | 'name_email' | 'name_fax' | 'name_phone' | 'name_state' | 'name_postal_code' | 'open_balance' | 'original_amount' | 'paid_amount' | 'paid_status' | 'paid_through_date' | 'payment_method' | 'payroll_item' | 'purchase_order_number' | 'print_status' | 'progress_amount' | 'progress_percent' | 'quantity' | 'quantity_available' | 'quantity_on_hand' | 'quantity_on_sales_order' | 'received_quantity' | 'ref_number' | 'running_balance' | 'sales_representative' | 'sales_tax_code' | 'serial_or_lot_number' | 'shipping_date' | 'shipping_method' | 'source_name' | 'split_account' | 'ssn_or_tax_identification_number' | 'tax_line' | 'tax_table_version' | 'terms' | 'transaction_id' | 'transaction_number' | 'transaction_type' | 'unit_price' | 'user_edit' | 'value_on_hand' | 'wage_base' | 'wage_base_tips'>) | undefined, accountsToInclude?: ('all' | 'in_use') | undefined, agingAsOf?: ('report_end_date' | 'today') | undefined}; export type GetApiQuickbooksDesktopReportsAgingOptions = {baseUrl?: string | undefined, BearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const qbdReport = z.object({objectType: z.literal("qbd_report"), category: z.enum(["general_summary", "general_detail", "aging", "budget_summary", "job", "time", "custom_detail", "custom_summary", "payroll_detail", "payroll_summary"]), reportType: z.enum(["balance_sheet_by_class", "balance_sheet_previous_year_comparison", "balance_sheet_standard", "balance_sheet_summary", "customer_balance_summary", "expense_by_vendor_summary", "income_by_customer_summary", "inventory_stock_status_by_item", "inventory_stock_status_by_vendor", "income_tax_summary", "inventory_valuation_summary", "inventory_valuation_summary_by_site", "lot_number_in_stock_by_site", "physical_inventory_worksheet", "profit_and_loss_by_class", "profit_and_loss_by_job", "profit_and_loss_previous_year_comparison", "profit_and_loss_standard", "profit_and_loss_ytd_comparison", "purchase_by_item_summary", "purchase_by_vendor_summary", "sales_by_customer_summary", "sales_by_item_summary", "sales_by_sales_representative_summary", "sales_tax_liability", "sales_tax_revenue_summary", "serial_number_in_stock_by_site", "trial_balance", "vendor_balance_summary", "1099_detail", "audit_trail", "balance_sheet_detail", "check_detail", "customer_balance_detail", "deposit_detail", "estimates_by_job", "expense_by_vendor_detail", "general_ledger", "income_by_customer_detail", "income_tax_detail", "inventory_valuation_detail", "job_progress_invoices_vs_estimates", "journal", "missing_checks", "open_invoices", "open_purchase_orders", "open_purchase_orders_by_job", "open_sales_order_by_customer", "open_sales_order_by_item", "pending_sales", "profit_and_loss_detail", "purchase_by_item_detail", "purchase_by_vendor_detail", "sales_by_customer_detail", "sales_by_item_detail", "sales_by_sales_representative_detail", "transaction_detail_by_account", "transaction_list_by_customer", "transaction_list_by_date", "transaction_list_by_vendor", "unpaid_bills_detail", "unbilled_costs_by_job", "vendor_balance_detail", "ap_aging_detail", "ap_aging_summary", "ar_aging_detail", "ar_aging_summary", "collections_report", "balance_sheet_budget_overview", "balance_sheet_budget_vs_actual", "profit_and_loss_budget_overview", "profit_and_loss_budget_performance", "profit_and_loss_budget_vs_actual", "item_estimates_vs_actuals", "item_profitability", "job_estimates_vs_actuals_detail", "job_estimates_vs_actuals_summary", "job_profitability_detail", "job_profitability_summary", "time_by_item", "time_by_job_detail", "time_by_job_summary", "time_by_name", "custom_transaction_detail", "custom_summary", "employee_state_taxes_detail", "payroll_item_detail", "payroll_review_detail", "payroll_transaction_detail", "payroll_transactions_by_payee", "employee_earnings_summary", "payroll_liability_balances", "payroll_summary"]), title: z.string().nullable(), subtitle: z.string().nullable(), basis: z.enum(["accrual", "cash", "none"]).nullable(), rowCount: z.number().nullable(), columnCount: z.number().nullable(), columnTitleRowCount: z.number().nullable(), columns: z.array(z.object({columnId: z.string(), columnType: z.string(), dataType: z.string().nullable(), titles: z.array(z.object({rowNumber: z.number(), value: z.string().nullable()}))})), rows: z.array(z.discriminatedUnion("kind", [z.object({kind: z.literal("text"), rowNumber: z.number(), text: z.string().nullable()}), z.object({kind: z.literal("data"), rowNumber: z.number(), rowDescriptor: z.object({type: z.string().nullable(), value: z.string().nullable()}).nullable(), cells: z.array(z.object({columnId: z.string(), value: z.string().nullable(), dataType: z.string().nullable()}))}), z.object({kind: z.literal("subtotal"), rowNumber: z.number(), rowDescriptor: z.object({type: z.string().nullable(), value: z.string().nullable()}).nullable(), cells: z.array(z.object({columnId: z.string(), value: z.string().nullable(), dataType: z.string().nullable()}))}), z.object({kind: z.literal("total"), rowNumber: z.number(), rowDescriptor: z.object({type: z.string().nullable(), value: z.string().nullable()}).nullable(), cells: z.array(z.object({columnId: z.string(), value: z.string().nullable(), dataType: z.string().nullable()}))})]))}); 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 }; /** * Retrieve an aging report * * GET /quickbooks-desktop/reports/aging */ export const getApiQuickbooksDesktopReportsAging = async (args: GetApiQuickbooksDesktopReportsAgingArgs, options?: GetApiQuickbooksDesktopReportsAgingOptions) => { const {baseUrl = "https://api.conductor.is/v1", fetch: fetchFn = fetch, BearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args['Conductor-End-User-Id'] != null) headers.set("Conductor-End-User-Id", String(args['Conductor-End-User-Id'])) if (args.reportType != null) query.append("reportType", String(args.reportType)) if (args.reportDateFrom != null) query.append("reportDateFrom", String(args.reportDateFrom)) if (args.reportDateTo != null) query.append("reportDateTo", String(args.reportDateTo)) if (args.reportDateMacro != null) query.append("reportDateMacro", String(args.reportDateMacro)) if (args.accountType != null) query.append("accountType", String(args.accountType)) for (const item of args.accountIds ?? []) query.append("accountIds", String(item)) for (const item of args.accountFullNames ?? []) query.append("accountFullNames", String(item)) if (args.entityType != null) query.append("entityType", String(args.entityType)) for (const item of args.entityIds ?? []) query.append("entityIds", String(item)) for (const item of args.entityFullNames ?? []) query.append("entityFullNames", String(item)) if (args.itemType != null) query.append("itemType", String(args.itemType)) for (const item of args.itemIds ?? []) query.append("itemIds", String(item)) for (const item of args.itemFullNames ?? []) query.append("itemFullNames", String(item)) for (const item of args.classIds ?? []) query.append("classIds", String(item)) for (const item of args.classFullNames ?? []) query.append("classFullNames", String(item)) for (const item of args.transactionTypes ?? []) query.append("transactionTypes", String(item)) if (args.detailLevel != null) query.append("detailLevel", String(args.detailLevel)) if (args.postingStatus != null) query.append("postingStatus", String(args.postingStatus)) if (args.updatedAfter != null) query.append("updatedAfter", String(args.updatedAfter)) if (args.updatedBefore != null) query.append("updatedBefore", String(args.updatedBefore)) if (args.updatedDateMacro != null) query.append("updatedDateMacro", String(args.updatedDateMacro)) for (const item of args.includeColumns ?? []) query.append("includeColumns", String(item)) if (args.accountsToInclude != null) query.append("accountsToInclude", String(args.accountsToInclude)) if (args.agingAsOf != null) query.append("agingAsOf", String(args.agingAsOf)) if (BearerAuth !== undefined) headers.set('authorization', `Bearer ${BearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/quickbooks-desktop/reports/aging${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(qbdReport, await res.json()) };