import {z} from 'zod' export type GetApiCrbsCrbIdSalesArgs = {crb_id: string, start_date: string, end_date: string, limit?: number | undefined, offset?: number | undefined, customer_id?: string | undefined, pos_customer_id?: string | undefined, last_updated_from?: string | undefined, last_updated_to?: string | undefined}; export type GetApiCrbsCrbIdSalesOptions = {baseUrl?: string | undefined, accessAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const positiveInteger = z.number().int().gte(0); export const uUID = z.string(); export const utcDateTime = z.string(); export const localDateTime = z.string(); export const transactionType = z.enum(["sale", "return", "adjustment"]); export const friendlyPosName = z.enum(["Alleaves", "Apex Trading Wholesale", "Dutchie", "Dutchie Wholesale", "Cova", "Meadow", "MJ Freeway", "MJ Freeway Wholesale", "Greenbits", "GrowFlow", "GrowFlow Wholesale", "Portal42", "Metrc S2S", "Metrc S2S Wholesale", "Flourish", "Flourish Wholesale", "Flowhub", "BioTrack", "BioTrack Wholesale", "Treez", "Blaze", "Quickbooks", "Sage Intacct", "Canix", "Brytemap", "POSaBIT", "Proteus420", "IndicaOnline", "Sweed", "Weave", "Jane", "Manual Upload Wholesale", "Cova Test Account", "Leaf Logix Test Account", "BioTrack Test Account", "Mj Freeway Test Account", "Treez IO Test Account", "Green Bits Test Account", "Manual Upload Retail", "SFTP Sales Retail", "SFTP Sales Wholesale", "Not Configured", "Unsupported", "CRBMonitor", "Plaid"]); export const saleTypeRetail = z.literal("retail"); export const productCategoryType = z.enum(["flower", "oil/concentrate", "edible", "other", "seedling", "seed", "liquid", "solid", "extract", "plant", "accessory", "marijuana_product", "topical", "edible_liquid"]).nullable(); export const saleDiscount = z.object({flat_amount: z.number().nullable(), pct_amount: z.number().nullable(), name: z.string().nullable()}); export const saleTax = z.object({flat_amount: z.number().nullable(), pct_amount: z.number().nullable(), name: z.string().nullable()}); export const saleFee = z.object({fee_name: z.string().nullable(), percent_amount: z.number().nullable(), flat_amount: z.number().nullable(), included_in_subtotal: z.boolean().nullable()}); export const saleLineItem = z.object({product_id: uUID.nullable(), pos_product_id: z.string().nullable(), product_name: z.string().nullable(), num_units: z.number().nullable(), price_per_unit: z.number().nullable(), grams: z.number().nullable(), product_type: productCategoryType.nullable(), cannabis_product: z.boolean().nullable(), line_item_discounts: z.array(saleDiscount), line_item_taxes: z.array(saleTax), line_item_fees: z.array(saleFee)}); export const paymentType = z.enum(["cash", "check", "debit", "credit", "multiple", "ach", "wire", "other", "unknown"]); export const salePayment = z.object({type: paymentType, amount_paid: z.number()}); export const medicalOrRec = z.enum(["medical", "rec"]); export const iDType = z.enum(["drivers", "medical", "ssn", "passport", "medical_with_rec", "medical_with_state_card", "caregiver", "minor_medical", "temporary_minor_medical", "temporary_adult"]); export const saleCustomer = z.object({customer_id: uUID.nullable(), pos_customer_id: z.string().nullable(), type: medicalOrRec.nullable(), dob: z.string().nullable(), id_type: iDType.nullable(), id_expiration_date: z.string().nullable()}); export const complianceStatus = z.enum(["unchecked", "red_flag", "green_checked", "warning"]); export const retailSale = z.object({id: uUID, pos_sale_id: z.string().nullable(), crb_id: uUID, subtotal: z.number().nullable(), total_discounts: z.number().nullable(), tax_paid: z.number().nullable(), total_paid: z.number().nullable(), date: utcDateTime, local_date: localDateTime, gc_created_date: utcDateTime, gc_updated_date: utcDateTime, transaction_type: transactionType.nullable(), pos_name: friendlyPosName, type: saleTypeRetail, employee_id: z.string().nullable().optional(), line_items: z.array(saleLineItem), discounts: z.array(saleDiscount), taxes: z.array(saleTax), payments: z.array(salePayment), customer: saleCustomer, fees: z.array(saleFee), compliance_status: complianceStatus.nullable(), compliance_exceptions: z.array(z.string()).nullable(), compliance_warnings: z.array(z.string()).nullable()}); export const saleTypeWholesale = z.literal("wholesale"); export const wholesaleSale = z.object({id: uUID, pos_sale_id: z.string().nullable(), crb_id: uUID, subtotal: z.number().nullable(), total_discounts: z.number().nullable(), tax_paid: z.number().nullable(), total_paid: z.number().nullable(), date: utcDateTime, local_date: localDateTime, gc_created_date: utcDateTime, gc_updated_date: utcDateTime, transaction_type: transactionType.nullable(), pos_name: friendlyPosName, type: saleTypeWholesale, employee_id: z.string().nullable().optional(), line_items: z.array(saleLineItem), discounts: z.array(saleDiscount), taxes: z.array(saleTax), payments: z.array(salePayment), customer: saleCustomer.nullable(), fees: z.array(saleFee), invoice: z.object({pos_customer_id: z.string().nullable(), memo: z.string().nullable(), open_balance: z.number().nullable(), total: z.number().nullable(), id: z.string().nullable()})}); export const pagedSales = z.object({metadata: z.object({total: positiveInteger, count: z.string()}), data: z.array(z.union([retailSale, wholesaleSale]))}); 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 CRB sales * * GET /crbs/{crb_id}/sales */ export const getApiCrbsCrbIdSales = async (args: GetApiCrbsCrbIdSalesArgs, options?: GetApiCrbsCrbIdSalesOptions) => { const {baseUrl = "https://sandbox-api.greencheckverified.com", fetch: fetchFn = fetch, accessAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.start_date != null) query.append("start_date", String(args.start_date)) if (args.end_date != null) query.append("end_date", String(args.end_date)) if (args.limit != null) query.append("limit", String(args.limit)) if (args.offset != null) query.append("offset", String(args.offset)) if (args.customer_id != null) query.append("customer_id", String(args.customer_id)) if (args.pos_customer_id != null) query.append("pos_customer_id", String(args.pos_customer_id)) if (args.last_updated_from != null) query.append("last_updated_from", String(args.last_updated_from)) if (args.last_updated_to != null) query.append("last_updated_to", String(args.last_updated_to)) if (accessAuth !== undefined) headers.set("Authorization", accessAuth) const url = `${baseUrl.replace(/\/+$/, '')}/crbs/${encodeURIComponent(String(args.crb_id))}/sales${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(pagedSales, await res.json()) };