/** * Servicio para Warehouse Classifications * * @author Sistema * @version 1.0.0 */ import { api, apiURL } from '@Services/Api'; export default class WarehouseClassificationService { /** * Obtener todas las clasificaciones de almacén * @param {Object} params - Parámetros de la consulta * @returns {Promise} Promesa con la respuesta */ async getAll(params = {}) { return new Promise((resolve, reject) => { api.get(apiURL('catalogs/warehouse-classifications'), { params, onSuccess: (response) => resolve(response), onError: (error) => reject(error) }); }); } /** * Obtener una clasificación de almacén por ID * @param {number} id - ID de la clasificación * @returns {Promise} Promesa con la respuesta */ async getById(id) { return new Promise((resolve, reject) => { api.get(apiURL(`catalogs/warehouse-classifications/${id}`), { onSuccess: (response) => resolve(response), onError: (error) => reject(error) }); }); } /** * Crear una nueva clasificación de almacén * @param {Object} data - Datos de la clasificación * @param {string} data.code - Código de la clasificación * @param {string} data.name - Nombre de la clasificación * @param {string|null} data.description - Descripción de la clasificación * @param {boolean} data.is_active - Estado activo/inactivo * @param {number|null} data.parent_id - ID del padre * @returns {Promise} Promesa con la respuesta */ async create(data) { return new Promise((resolve, reject) => { api.post(apiURL('catalogs/warehouse-classifications'), { data, onSuccess: (response) => { resolve(response); }, onError: (error) => { reject(error); } }); }); } /** * Actualizar una clasificación de almacén * @param {number} id - ID de la clasificación * @param {Object} data - Datos a actualizar * @param {string} [data.code] - Código de la clasificación * @param {string} [data.name] - Nombre de la clasificación * @param {string|null} [data.description] - Descripción de la clasificación * @param {boolean} [data.is_active] - Estado activo/inactivo * @param {number|null} [data.parent_id] - ID del padre * @returns {Promise} Promesa con la respuesta */ async update(id, data) { return new Promise((resolve, reject) => { api.put(apiURL(`catalogs/warehouse-classifications/${id}`), { data, onSuccess: (response) => resolve(response), onError: (error) => reject(error) }); }); } /** * Actualizar solo el estado de una clasificación de almacén * @param {number} id - ID de la clasificación * @param {boolean} is_active - Nuevo estado * @returns {Promise} Promesa con la respuesta */ async updateStatus(id, is_active) { return new Promise((resolve, reject) => { api.put(apiURL(`catalogs/warehouse-classifications/${id}`), { data: { is_active }, onSuccess: (response) => { resolve(response); }, onError: (error) => { // Mejorar el manejo de errores const enhancedError = { ...error, timestamp: new Date().toISOString(), action: 'updateStatus', id: id, is_active: is_active }; reject(enhancedError); } }); }); } /** * Eliminar una clasificación de almacén * @param {number} id - ID de la clasificación * @returns {Promise} Promesa con la respuesta */ async delete(id) { return new Promise((resolve, reject) => { api.delete(apiURL(`catalogs/warehouse-classifications/${id}`), { onSuccess: (response) => resolve(response), onError: (error) => reject(error) }); }); } /** * Obtener clasificaciones padre disponibles (para selects) * @param {number|null} excludeId - ID a excluir de la lista (para evitar loops) * @returns {Promise} Promesa con la respuesta */ async getParentOptions(excludeId = null) { return new Promise((resolve, reject) => { api.get(apiURL('catalogs/warehouse-classifications'), { params: { exclude_children_of: excludeId }, onSuccess: (response) => { // Aplanar la estructura jerárquica para el selector const flattenOptions = (items, level = 0) => { let options = []; items.forEach(item => { if (excludeId && (item.id === excludeId || this.hasDescendant(item, excludeId))) { return; // Excluir item actual y sus descendientes } options.push({ ...item, name: ' '.repeat(level) + item.name, // Indentación visual level }); if (item.children && item.children.length > 0) { options = options.concat(flattenOptions(item.children, level + 1)); } }); return options; }; const flatOptions = flattenOptions(response.warehouse_classifications?.data || response.data || []); resolve(flatOptions); }, onError: (error) => reject(error) }); }); } /** * Función auxiliar para verificar si un item tiene como descendiente un ID específico * @param {Object} item - Item a verificar * @param {number} targetId - ID objetivo * @returns {boolean} True si es descendiente */ hasDescendant(item, targetId) { if (!item.children) return false; return item.children.some(child => child.id === targetId || this.hasDescendant(child, targetId) ); } /** * Alternar el estado de una clasificación * @param {Object} item - Objeto con la clasificación * @returns {Promise} Promesa con la respuesta */ async toggleStatus(item) { const newStatus = !item.is_active; return this.updateStatus(item.id, newStatus); } }