187 lines
6.1 KiB
JavaScript

/**
* 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);
}
}