export interface Supplier { id: string; suppliername: string; email: string; suppliernumber: string; supplieraddress: string; supply_tags: string; coordinates: string; // Raw coordinates text (e.g. "-33.9249, 18.4241") closingtime: string; } export interface Order { id: string; order_number: string; status: string; notes: string; } export interface PurchaseOrder { id: string; po_number: string; status: string; } export interface OrderItem { id: string; order: string; // Customer-facing line. Use this for label / list / customer view. description: string; // Supplier-facing line. Use this on the PO pickup screen — supplier // paperwork references this exact wording. Falls back to description. po_description?: string; // Customer-side quantity. Nullable on legacy rows. quantity: number; // Supplier-side quantity. Per the brief, falls back to quantity when // blank (zero is treated as blank in getItemDisplayQty). order_qty?: number; // Pricing — operator-side (cost), customer-side (selling), and audit // source ('quote' | 'catalogue' | 'manual'). cost_price?: number; selling_price?: number | null; pricing_source?: 'quote' | 'catalogue' | 'manual' | string; matched_quote_item?: string; // Supplier part number. Use this on PO paperwork over description. sku?: string; // Workflow states. item_status is the operator-side state, drv_status // is the driver-side state. They're independent enums — an item can // be item_status='collected' (operator marked it received) while // drv_status is still 'en_route' (driver hasn't checked in), etc. item_status: | 'pending' | 'processed' | 'po_generated' | 'collection_pool' | 'assigned' | 'collected' | 'stock_verified' | 'picking' | 'ready_delivery' | 'delivered' | 'cancelled'; drv_status?: 'unassigned' | 'assigned' | 'en_route' | 'collected' | 'failed' | string; driver_status?: string; delivery_status?: 'pending' | 'ready' | 'in_transit' | 'delivered' | 'failed'; invoice_status?: 'pending' | 'invoiced' | 'paid' | 'cancelled'; // Driver assignment. The canonical driver field per the brief is // `drv_id` (relation -> users); the older `driver` field is a legacy // shadow that only a handful of rows set. Use drv_id in every filter. drv_id?: string; driver?: string; // Server-side ISO timestamp of when drv_id was set. Surface in detail. assigned_at?: string; // Audit trail of failed-collection attempts. The driver writes here. // Distinct from notes (operator-side). notes?: string; problem_notes?: string; problem_flag?: boolean; problem_type?: 'stock' | 'supplier' | 'driver' | 'delivery' | 'pricing' | 'other' | string; // Per-row quantities used for proving/dashboard math. qty_processed?: number; qty_assigned?: number; qty_collected?: number; qty_delivered?: number; drv_assigned_at?: string; drv_collected_at?: string; delivered_at?: string; markup?: number; markup_percent?: number; legacy_order_item_id?: string; // Backwards-compat shim the app uses in some spots is_stock_item?: boolean; collected_date?: string; collection_date?: string; // Expanded fields expand?: { supplier?: Supplier; // PB expand key matches relation field name order?: Order; purchase_order?: PurchaseOrder; }; } export interface DriverLocation { id: string; driver: string; latitude: number; longitude: number; accuracy?: number; altitude?: number; speed?: number; heading?: number; timestamp: string; } export interface AppSettings { locationInterval: number; minimumAccuracy: number; enableHighAccuracy: boolean; darkMode: boolean; fontSize: 'small' | 'normal' | 'large'; offlineMode: boolean; } export const DEFAULT_SETTINGS: AppSettings = { locationInterval: 60, minimumAccuracy: 50, enableHighAccuracy: true, darkMode: false, fontSize: 'normal', offlineMode: false, }; export const PROBLEM_TYPES = [ { value: 'out_of_stock', label: 'Out of Stock' }, { value: 'partial_stock', label: 'Partial Stock' }, { value: 'quality_issue', label: 'Quality Issue' }, { value: 'wrong_item', label: 'Wrong Item' }, { value: 'other', label: 'Other' }, ] as const;