import { queryOptions } from '@tanstack/react-query' import { api } from '@/lib/api-client' // --- Types --- export interface Transaction { id: string locationId: string | null transactionNumber: string accountId: string | null repairTicketId: string | null repairBatchId: string | null transactionType: string status: string subtotal: string discountTotal: string taxTotal: string total: string paymentMethod: string | null amountTendered: string | null changeGiven: string | null checkNumber: string | null roundingAdjustment: string taxExempt: boolean taxExemptReason: string | null processedBy: string drawerSessionId: string | null notes: string | null completedAt: string | null createdAt: string updatedAt: string lineItems?: TransactionLineItem[] } export interface TransactionLineItem { id: string transactionId: string productId: string | null inventoryUnitId: string | null description: string qty: number unitPrice: string discountAmount: string discountReason: string | null taxRate: string taxAmount: string lineTotal: string createdAt: string } export interface DrawerSession { id: string locationId: string | null openedBy: string closedBy: string | null openingBalance: string closingBalance: string | null expectedBalance: string | null overShort: string | null denominations: Record | null status: string notes: string | null openedAt: string closedAt: string | null } export interface Discount { id: string name: string discountType: string discountValue: string appliesTo: string requiresApprovalAbove: string | null isActive: boolean } export interface Product { id: string name: string sku: string | null upc: string | null description: string | null price: string | null costPrice: string | null qtyOnHand: number | null taxCategory: string isSerialized: boolean isActive: boolean } // --- Query Keys --- export const posKeys = { transaction: (id: string) => ['pos', 'transaction', id] as const, drawer: (locationId: string) => ['pos', 'drawer', locationId] as const, products: (search: string) => ['pos', 'products', search] as const, discounts: ['pos', 'discounts'] as const, } // --- Query Options --- export function transactionOptions(id: string | null) { return queryOptions({ queryKey: posKeys.transaction(id ?? ''), queryFn: () => api.get(`/v1/transactions/${id}`), enabled: !!id, }) } export function currentDrawerOptions(locationId: string | null) { return queryOptions({ queryKey: posKeys.drawer(locationId ?? ''), queryFn: () => api.get('/v1/drawer/current', { locationId }), enabled: !!locationId, retry: false, }) } export function productSearchOptions(search: string) { return queryOptions({ queryKey: posKeys.products(search), queryFn: () => api.get<{ data: Product[]; pagination: { page: number; limit: number; total: number; totalPages: number } }>('/v1/products', { q: search, limit: 24, isActive: true }), enabled: search.length >= 1, }) } export function discountListOptions() { return queryOptions({ queryKey: posKeys.discounts, queryFn: () => api.get('/v1/discounts/all'), }) } // --- Mutations --- export const posMutations = { createTransaction: (data: { transactionType: string; locationId?: string }) => api.post('/v1/transactions', data), addLineItem: (txnId: string, data: { productId?: string; inventoryUnitId?: string; description: string; qty: number; unitPrice: number }) => api.post(`/v1/transactions/${txnId}/line-items`, data), removeLineItem: (txnId: string, lineItemId: string) => api.del(`/v1/transactions/${txnId}/line-items/${lineItemId}`), applyDiscount: (txnId: string, data: { discountId?: string; amount: number; reason: string; lineItemId?: string }) => api.post(`/v1/transactions/${txnId}/discounts`, data), complete: (txnId: string, data: { paymentMethod: string; amountTendered?: number; checkNumber?: string }) => api.post(`/v1/transactions/${txnId}/complete`, data), void: (txnId: string) => api.post(`/v1/transactions/${txnId}/void`, {}), openDrawer: (data: { locationId?: string; openingBalance: number }) => api.post('/v1/drawer/open', data), closeDrawer: (id: string, data: { closingBalance: number; denominations?: Record; notes?: string }) => api.post(`/v1/drawer/${id}/close`, data), lookupUpc: (upc: string) => api.get(`/v1/products/lookup/upc/${upc}`), }