erp-core-frontend-v2/src/features/warehouses/api/warehouses.api.ts
Adrian Flores Cortes 158ebcb57b [TASK-MASTER] feat: FE-001 products + FE-002 warehouses features
FE-001: Products Feature (16 archivos)
- types/index.ts - Interfaces TypeScript
- api/products.api.ts, categories.api.ts - Clientes Axios
- hooks/useProducts, useCategories, useProductPricing
- components/ProductForm, ProductCard, CategoryTree, VariantSelector, PricingTable
- pages/ProductsPage, ProductDetailPage, CategoriesPage

FE-002: Warehouses Feature (15 archivos)
- types/index.ts - Interfaces TypeScript
- api/warehouses.api.ts - Cliente Axios
- hooks/useWarehouses, useLocations
- components/WarehouseCard, LocationGrid, WarehouseLayout, ZoneCard, badges
- pages/WarehousesPage, WarehouseDetailPage, LocationsPage, ZonesPage

Ambos siguen patrones de inventory y React Query + react-hook-form + zod

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:16:34 -06:00

162 lines
5.6 KiB
TypeScript

import api from '@services/api/axios-instance';
import type { ApiResponse } from '@shared/types/api.types';
import type {
Warehouse,
WarehouseLocation,
CreateWarehouseDto,
UpdateWarehouseDto,
CreateLocationDto,
UpdateLocationDto,
WarehouseFilters,
LocationFilters,
WarehousesResponse,
LocationsResponse,
} from '../types';
const BASE_URL = '/api/v1/warehouses';
// ==================== Warehouses API ====================
export const warehousesApi = {
// List all warehouses with filters
list: async (filters?: WarehouseFilters): Promise<WarehousesResponse> => {
const response = await api.get<ApiResponse<Warehouse[]> & { total?: number }>(BASE_URL, {
params: filters,
});
if (!response.data.success) {
throw new Error(response.data.error || 'Error al obtener almacenes');
}
return {
data: response.data.data || [],
total: response.data.total || response.data.data?.length || 0,
};
},
// Get warehouse by ID
getById: async (id: string): Promise<Warehouse> => {
const response = await api.get<ApiResponse<Warehouse>>(`${BASE_URL}/${id}`);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'Almacen no encontrado');
}
return response.data.data;
},
// Get warehouse by code
getByCode: async (code: string): Promise<Warehouse> => {
const response = await api.get<ApiResponse<Warehouse>>(`${BASE_URL}/code/${code}`);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'Almacen no encontrado');
}
return response.data.data;
},
// Get default warehouse
getDefault: async (): Promise<Warehouse> => {
const response = await api.get<ApiResponse<Warehouse>>(`${BASE_URL}/default`);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'No hay almacen por defecto');
}
return response.data.data;
},
// Get active warehouses
getActive: async (): Promise<Warehouse[]> => {
const response = await api.get<ApiResponse<Warehouse[]> & { total?: number }>(`${BASE_URL}/active`);
if (!response.data.success) {
throw new Error(response.data.error || 'Error al obtener almacenes activos');
}
return response.data.data || [];
},
// Create warehouse
create: async (data: CreateWarehouseDto): Promise<Warehouse> => {
const response = await api.post<ApiResponse<Warehouse>>(BASE_URL, data);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'Error al crear almacen');
}
return response.data.data;
},
// Update warehouse
update: async (id: string, data: UpdateWarehouseDto): Promise<Warehouse> => {
const response = await api.patch<ApiResponse<Warehouse>>(`${BASE_URL}/${id}`, data);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'Error al actualizar almacen');
}
return response.data.data;
},
// Delete warehouse
delete: async (id: string): Promise<void> => {
const response = await api.delete<ApiResponse>(`${BASE_URL}/${id}`);
if (!response.data.success) {
throw new Error(response.data.error || 'Error al eliminar almacen');
}
},
};
// ==================== Locations API ====================
export const locationsApi = {
// List all locations with filters
list: async (filters?: LocationFilters): Promise<LocationsResponse> => {
const response = await api.get<ApiResponse<WarehouseLocation[]> & { total?: number }>(
`${BASE_URL}/locations`,
{ params: filters }
);
if (!response.data.success) {
throw new Error(response.data.error || 'Error al obtener ubicaciones');
}
return {
data: response.data.data || [],
total: response.data.total || response.data.data?.length || 0,
};
},
// Get location by ID
getById: async (id: string): Promise<WarehouseLocation> => {
const response = await api.get<ApiResponse<WarehouseLocation>>(`${BASE_URL}/locations/${id}`);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'Ubicacion no encontrada');
}
return response.data.data;
},
// Get locations by warehouse
getByWarehouse: async (warehouseId: string): Promise<WarehouseLocation[]> => {
const response = await api.get<ApiResponse<WarehouseLocation[]> & { total?: number }>(
`${BASE_URL}/${warehouseId}/locations`
);
if (!response.data.success) {
throw new Error(response.data.error || 'Error al obtener ubicaciones del almacen');
}
return response.data.data || [];
},
// Create location
create: async (data: CreateLocationDto): Promise<WarehouseLocation> => {
const response = await api.post<ApiResponse<WarehouseLocation>>(`${BASE_URL}/locations`, data);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'Error al crear ubicacion');
}
return response.data.data;
},
// Update location
update: async (id: string, data: UpdateLocationDto): Promise<WarehouseLocation> => {
const response = await api.patch<ApiResponse<WarehouseLocation>>(`${BASE_URL}/locations/${id}`, data);
if (!response.data.success || !response.data.data) {
throw new Error(response.data.error || 'Error al actualizar ubicacion');
}
return response.data.data;
},
// Delete location
delete: async (id: string): Promise<void> => {
const response = await api.delete<ApiResponse>(`${BASE_URL}/locations/${id}`);
if (!response.data.success) {
throw new Error(response.data.error || 'Error al eliminar ubicacion');
}
},
};