import { apiFetch } from './client'; import { API_ENDPOINTS } from './config'; export interface BrandResponse { brand_id: string; name: string; slug: string; logo_url: string | null; is_active: boolean; device_types?: string[]; created_at: string; } export interface CategoryResponse { category_id: string; parent_category_id: string | null; name: string; slug: string; description: string | null; image_url: string | null; sort_order: string; is_parent_feature?: boolean; is_active: boolean; created_at: string; } export interface PartResponse { part_id: string; sku: string; name: string; cost_price: number; low_stock_alert: number; supplier: string | null; barcode: string | null; is_active: boolean; stock: number; } export interface DeviceSeriesResponse { series_id: string; brand_id: string; name: string; slug: string; device_type?: string | null; sort_order: number; is_active: boolean; } export interface DeviceModelResponse { model_id: string; series_id: string; brand_id: string; name: string; slug: string; device_type?: string | null; full_path: string; release_year: number | null; image_url: string | null; is_active: boolean; } export interface ServiceTypeResponse { service_type_id: string; name: string; slug: string; icon_url: string | null; description: string | null; is_active: boolean; } export interface RepairServiceResponse { repair_service_id: string; model_id: string; service_type_id: string; slug: string; full_path: string; description: string | null; } export interface RepairVariantPartResponse { id: string; variant_id: string; part_id: string; quantity: number; } export interface RepairVariantResponse { variant_id: string; repair_service_id: string; name: string; price: number; cost: number; duration_minutes: number; warranty_days: number; status: string; created_at: string; bom_parts?: RepairVariantPartResponse[]; } export interface StockMovementResponse { movement_id: string; entity_type: string; entity_id: string; movement_type: string; quantity: number; reference_type: string; reference_id: string; created_at: string; } export interface PurchaseOrderItemResponse { id: string; part_id: string; quantity_ordered: number; quantity_received: number; unit_price: number; } export interface PurchaseOrderResponse { purchase_order_id: string; po_number: string; supplier_name: string; status: string; total_amount: number; created_at: string; items: PurchaseOrderItemResponse[]; } export interface AttributeTypeResponse { attribute_id: string; name: string; code: string; status: string; preset_values?: string[]; created_at?: string; } export const catalogService = { // Brands async getBrands(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_BRANDS_ALL, { skipAuth: true }); }, async createBrand(data: { name: string; logo_url?: string; device_types?: string[] }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_BRANDS_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Categories async getCategories(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_CATEGORIES_ALL, { skipAuth: true }); }, async createCategory(data: { name: string; parent_category_id?: string | null; description?: string; image_url?: string; sort_order?: string; is_parent_feature?: boolean; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_CATEGORIES_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Parts (Inventory Items) async getParts(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PARTS_ALL, { skipAuth: true }); }, async createPart(data: { sku: string; name: string; cost_price: number; low_stock_alert?: number; supplier?: string; barcode?: string; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PARTS_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Device Series async getDeviceSeries(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_SERIES_ALL, { skipAuth: true }); }, async createDeviceSeries(data: { brand_id: string; name: string; device_type?: string | null; sort_order?: number }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_SERIES_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Device Models async getDeviceModels(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_MODELS_ALL, { skipAuth: true }); }, async createDeviceModel(data: { series_id?: string; brand_id: string; name: string; device_type?: string | null; release_year?: number; image_url?: string; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_MODELS_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Service Types async getServiceTypes(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_SERVICE_TYPES_ALL, { skipAuth: true }); }, async createServiceType(data: { name: string; icon_url?: string; description?: string }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_SERVICE_TYPES_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Repair Services async getRepairServices(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_REPAIR_SERVICES_ALL, { skipAuth: true }); }, async createRepairService(data: { model_id: string; service_type_id: string; description?: string }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_REPAIR_SERVICES_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Repair Variants async getRepairVariants(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_REPAIR_VARIANTS_ALL, { skipAuth: true }); }, async createRepairVariant(data: { repair_service_id: string; name: string; price: number; cost: number; duration_minutes?: number; warranty_days?: number; parts: Array<{ part_id: string; quantity?: number }>; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_REPAIR_VARIANTS_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, // Stock Ledger async getStockHistory(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_STOCK_HISTORY, { skipAuth: true }); }, async adjustStock(data: { entity_type: 'variant' | 'part'; entity_id: string; movement_type: 'Adjustment' | 'Damage'; quantity: number; reference_type: 'ManualAdjustment'; reference_id: string; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_STOCK_ADJUST, { method: 'POST', body: JSON.stringify(data), }); }, // Purchase Orders async getPurchaseOrders(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PO_ALL, { skipAuth: true }); }, async createPurchaseOrder(data: { supplier_name: string; items: Array<{ part_id: string; quantity_ordered: number; unit_price: number }>; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PO_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, async receivePurchaseOrder( poId: string, itemsReceived: Array<{ id: string; quantity_received: number }> ): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PO_RECEIVE(poId), { method: 'POST', body: JSON.stringify({ items_received: itemsReceived }), }); }, // Attributes async getAttributes(): Promise { return apiFetch(API_ENDPOINTS.CATALOG_ATTRIBUTES_ALL, { skipAuth: true }); }, async createAttribute(data: { name: string; code: string; preset_values?: string[] }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_ATTRIBUTES_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, async updateAttribute(attributeId: string, data: { name?: string; code?: string; preset_values?: string[] }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_ATTRIBUTES_UPDATE(attributeId), { method: 'PUT', body: JSON.stringify(data), }); }, // Products async getProducts(params: { page?: number; limit?: number; search?: string } = {}): Promise<{ total: number; page: number; limit: number; products: ProductResponse[]; }> { const query = new URLSearchParams(); query.set('page', String(params.page || 1)); query.set('limit', String(params.limit || 50)); if (params.search) query.set('search', params.search); return apiFetch(`${API_ENDPOINTS.CATALOG_PRODUCTS_ALL}?${query.toString()}`, { skipAuth: true }); }, async getSellableSkus(params: { page?: number; limit?: number; q?: string } = {}): Promise<{ total: number; page: number; limit: number; items: SellableSkuRow[]; }> { const query = new URLSearchParams(); query.set('page', String(params.page || 1)); query.set('limit', String(params.limit || 50)); if (params.q) query.set('q', params.q); return apiFetch(`${API_ENDPOINTS.INVENTORY_SKUS}?${query.toString()}`); }, async adjustSellableStock(data: { variant_id: string; event_type: string; qty: number; notes?: string; }): Promise<{ message: string; ledger_id: string }> { return apiFetch(API_ENDPOINTS.INVENTORY_ADJUST, { method: 'POST', body: JSON.stringify(data), }); }, async createProduct(data: { category_id: string; brand_id?: string | null; device_series_id?: string | null; device_model_id?: string | null; name: string; description?: string; warranty_type?: string; warranty_summary?: string; seo_title?: string; seo_description?: string; meta_keywords?: string; images?: Array<{ image_url: string; alt_text?: string; sort_order?: number; is_banner?: boolean }>; variants: Array<{ sku: string; barcode?: string; price: number; compare_price?: number; cost_price: number; low_stock_threshold?: number; initial_stock?: number; attributes: Array<{ attribute_id: string; attribute_value: string }>; images?: Array<{ image_url: string; sort_order?: number; is_primary?: boolean }>; }>; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PRODUCTS_CREATE, { method: 'POST', body: JSON.stringify(data), }); }, async bulkDeleteProducts(productIds: string[]): Promise<{ status: string; deleted_products_count: number; deleted_images_count: number; message: string }> { return apiFetch('/api/v1/catalog/products/bulk-delete', { method: 'POST', body: JSON.stringify({ product_ids: productIds }), }); }, async updateBrand(brandId: string, data: { name: string; logo_url?: string; is_active?: boolean; device_types?: string[] }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_BRANDS_UPDATE(brandId), { method: 'PUT', body: JSON.stringify(data), }); }, async updateCategory(categoryId: string, data: { name?: string; parent_category_id?: string | null; description?: string; image_url?: string; sort_order?: string; is_active?: boolean; is_parent_feature?: boolean; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_CATEGORIES_UPDATE(categoryId), { method: 'PUT', body: JSON.stringify(data), }); }, async updateDeviceSeries(seriesId: string, data: { brand_id?: string; name?: string; device_type?: string | null; sort_order?: number; is_active?: boolean }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_SERIES_UPDATE(seriesId), { method: 'PUT', body: JSON.stringify(data), }); }, async updateDeviceModel(modelId: string, data: { series_id?: string; brand_id?: string; name?: string; device_type?: string | null; release_year?: number; image_url?: string; is_active?: boolean; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_MODELS_UPDATE(modelId), { method: 'PUT', body: JSON.stringify(data), }); }, async updateServiceType(serviceTypeId: string, data: { name?: string; icon_url?: string; description?: string; is_active?: boolean }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_SERVICE_TYPES_UPDATE(serviceTypeId), { method: 'PUT', body: JSON.stringify(data), }); }, async updateRepairService(repairServiceId: string, data: { model_id?: string; service_type_id?: string; description?: string }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_REPAIR_SERVICES_UPDATE(repairServiceId), { method: 'PUT', body: JSON.stringify(data), }); }, async updateRepairVariant(variantId: string, data: { repair_service_id?: string; name?: string; price?: number; cost?: number; duration_minutes?: number; warranty_days?: number; parts?: Array<{ part_id: string; quantity?: number }>; status?: string; }): Promise { return apiFetch(API_ENDPOINTS.CATALOG_REPAIR_VARIANTS_UPDATE(variantId), { method: 'PUT', body: JSON.stringify(data), }); }, async updateProduct(productId: string, data: any): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PRODUCTS_UPDATE(productId), { method: 'PUT', body: JSON.stringify(data), }); }, async deleteProduct(id: string): Promise { return apiFetch(API_ENDPOINTS.CATALOG_PRODUCTS_DELETE(id), { method: 'DELETE' }); }, async deleteCategory(id: string): Promise { return apiFetch(API_ENDPOINTS.CATALOG_CATEGORIES_DELETE(id), { method: 'DELETE' }); }, async deleteBrand(id: string): Promise { return apiFetch(API_ENDPOINTS.CATALOG_BRANDS_DELETE(id), { method: 'DELETE' }); }, async deleteDeviceSeries(id: string): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_SERIES_DELETE(id), { method: 'DELETE' }); }, async deleteDeviceModel(id: string): Promise { return apiFetch(API_ENDPOINTS.CATALOG_DEVICE_MODELS_DELETE(id), { method: 'DELETE' }); }, async deleteAttribute(id: string): Promise { return apiFetch(API_ENDPOINTS.CATALOG_ATTRIBUTES_DELETE(id), { method: 'DELETE' }); }, }; export interface AttributeTypeResponse { attribute_id: string; name: string; code: string; status: string; preset_values?: string[]; created_at?: string; } export interface VariantAttributeResponse { id: string; variant_id: string; attribute_id: string; attribute_value: string; } export interface ProductImageResponse { image_id: string; product_id: string; image_url: string; alt_text: string | null; sort_order: number; is_banner: boolean; } export interface VariantImageResponse { image_id: string; variant_id: string; image_url: string; sort_order: number; is_primary: boolean; } export interface ProductVariantResponse { variant_id: string; product_id: string; sku: string; barcode: string | null; price: number; compare_price: number | null; cost_price: number; low_stock_threshold: number; status: string; available_stock?: number; attributes?: VariantAttributeResponse[]; images?: VariantImageResponse[]; } export interface SellableSkuRow { variant_id: string; product_id: string; product_name: string; sku: string; barcode: string | null; price: number; cost_price: number; available_stock: number; pending_confirmation_units?: number; confirmed_units?: number; low_stock_threshold: number; status: string; is_low: boolean; } export interface ProductResponse { product_id: string; category_id: string; brand_id: string | null; device_series_id: string | null; device_model_id: string | null; device_type?: string | null; name: string; slug: string; full_path: string; description: string | null; warranty_type?: string | null; warranty_summary?: string | null; seo_title?: string | null; seo_description?: string | null; meta_keywords?: string | null; show_specifications?: boolean; status: string; created_at: string; images: ProductImageResponse[]; variants: ProductVariantResponse[]; }