ifixkart-admin/services/api/catalogService.ts

566 lines
17 KiB
TypeScript

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<BrandResponse[]> {
return apiFetch<BrandResponse[]>(API_ENDPOINTS.CATALOG_BRANDS_ALL, { skipAuth: true });
},
async createBrand(data: { name: string; logo_url?: string; device_types?: string[] }): Promise<BrandResponse> {
return apiFetch<BrandResponse>(API_ENDPOINTS.CATALOG_BRANDS_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Categories
async getCategories(): Promise<CategoryResponse[]> {
return apiFetch<CategoryResponse[]>(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<CategoryResponse> {
return apiFetch<CategoryResponse>(API_ENDPOINTS.CATALOG_CATEGORIES_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Parts (Inventory Items)
async getParts(): Promise<PartResponse[]> {
return apiFetch<PartResponse[]>(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<PartResponse> {
return apiFetch<PartResponse>(API_ENDPOINTS.CATALOG_PARTS_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Device Series
async getDeviceSeries(): Promise<DeviceSeriesResponse[]> {
return apiFetch<DeviceSeriesResponse[]>(API_ENDPOINTS.CATALOG_DEVICE_SERIES_ALL, { skipAuth: true });
},
async createDeviceSeries(data: { brand_id: string; name: string; device_type?: string | null; sort_order?: number }): Promise<DeviceSeriesResponse> {
return apiFetch<DeviceSeriesResponse>(API_ENDPOINTS.CATALOG_DEVICE_SERIES_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Device Models
async getDeviceModels(): Promise<DeviceModelResponse[]> {
return apiFetch<DeviceModelResponse[]>(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<DeviceModelResponse> {
return apiFetch<DeviceModelResponse>(API_ENDPOINTS.CATALOG_DEVICE_MODELS_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Service Types
async getServiceTypes(): Promise<ServiceTypeResponse[]> {
return apiFetch<ServiceTypeResponse[]>(API_ENDPOINTS.CATALOG_SERVICE_TYPES_ALL, { skipAuth: true });
},
async createServiceType(data: { name: string; icon_url?: string; description?: string }): Promise<ServiceTypeResponse> {
return apiFetch<ServiceTypeResponse>(API_ENDPOINTS.CATALOG_SERVICE_TYPES_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Repair Services
async getRepairServices(): Promise<RepairServiceResponse[]> {
return apiFetch<RepairServiceResponse[]>(API_ENDPOINTS.CATALOG_REPAIR_SERVICES_ALL, { skipAuth: true });
},
async createRepairService(data: { model_id: string; service_type_id: string; description?: string }): Promise<RepairServiceResponse> {
return apiFetch<RepairServiceResponse>(API_ENDPOINTS.CATALOG_REPAIR_SERVICES_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Repair Variants
async getRepairVariants(): Promise<RepairVariantResponse[]> {
return apiFetch<RepairVariantResponse[]>(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<RepairVariantResponse> {
return apiFetch<RepairVariantResponse>(API_ENDPOINTS.CATALOG_REPAIR_VARIANTS_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Stock Ledger
async getStockHistory(): Promise<StockMovementResponse[]> {
return apiFetch<StockMovementResponse[]>(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<StockMovementResponse> {
return apiFetch<StockMovementResponse>(API_ENDPOINTS.CATALOG_STOCK_ADJUST, {
method: 'POST',
body: JSON.stringify(data),
});
},
// Purchase Orders
async getPurchaseOrders(): Promise<PurchaseOrderResponse[]> {
return apiFetch<PurchaseOrderResponse[]>(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<PurchaseOrderResponse> {
return apiFetch<PurchaseOrderResponse>(API_ENDPOINTS.CATALOG_PO_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
async receivePurchaseOrder(
poId: string,
itemsReceived: Array<{ id: string; quantity_received: number }>
): Promise<PurchaseOrderResponse> {
return apiFetch<PurchaseOrderResponse>(API_ENDPOINTS.CATALOG_PO_RECEIVE(poId), {
method: 'POST',
body: JSON.stringify({ items_received: itemsReceived }),
});
},
// Attributes
async getAttributes(): Promise<AttributeTypeResponse[]> {
return apiFetch<AttributeTypeResponse[]>(API_ENDPOINTS.CATALOG_ATTRIBUTES_ALL, { skipAuth: true });
},
async createAttribute(data: { name: string; code: string; preset_values?: string[] }): Promise<AttributeTypeResponse> {
return apiFetch<AttributeTypeResponse>(API_ENDPOINTS.CATALOG_ATTRIBUTES_CREATE, {
method: 'POST',
body: JSON.stringify(data),
});
},
async updateAttribute(attributeId: string, data: { name?: string; code?: string; preset_values?: string[] }): Promise<AttributeTypeResponse> {
return apiFetch<AttributeTypeResponse>(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<ProductResponse> {
return apiFetch<ProductResponse>(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<BrandResponse> {
return apiFetch<BrandResponse>(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<CategoryResponse> {
return apiFetch<CategoryResponse>(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<DeviceSeriesResponse> {
return apiFetch<DeviceSeriesResponse>(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<DeviceModelResponse> {
return apiFetch<DeviceModelResponse>(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<ServiceTypeResponse> {
return apiFetch<ServiceTypeResponse>(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<RepairServiceResponse> {
return apiFetch<RepairServiceResponse>(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<RepairVariantResponse> {
return apiFetch<RepairVariantResponse>(API_ENDPOINTS.CATALOG_REPAIR_VARIANTS_UPDATE(variantId), {
method: 'PUT',
body: JSON.stringify(data),
});
},
async updateProduct(productId: string, data: any): Promise<ProductResponse> {
return apiFetch<ProductResponse>(API_ENDPOINTS.CATALOG_PRODUCTS_UPDATE(productId), {
method: 'PUT',
body: JSON.stringify(data),
});
},
async deleteProduct(id: string): Promise<any> {
return apiFetch<any>(API_ENDPOINTS.CATALOG_PRODUCTS_DELETE(id), { method: 'DELETE' });
},
async deleteCategory(id: string): Promise<any> {
return apiFetch<any>(API_ENDPOINTS.CATALOG_CATEGORIES_DELETE(id), { method: 'DELETE' });
},
async deleteBrand(id: string): Promise<any> {
return apiFetch<any>(API_ENDPOINTS.CATALOG_BRANDS_DELETE(id), { method: 'DELETE' });
},
async deleteDeviceSeries(id: string): Promise<any> {
return apiFetch<any>(API_ENDPOINTS.CATALOG_DEVICE_SERIES_DELETE(id), { method: 'DELETE' });
},
async deleteDeviceModel(id: string): Promise<any> {
return apiFetch<any>(API_ENDPOINTS.CATALOG_DEVICE_MODELS_DELETE(id), { method: 'DELETE' });
},
async deleteAttribute(id: string): Promise<any> {
return apiFetch<any>(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[];
}