// types/task.ts // Estado de la tarea en Dolibarr export type TaskStatus = '0' | '1' | '2'; // 0: borrador, 1: validada, 2: cerrada/completada // Prioridad de la tarea export type TaskPriority = '0' | '1' | '2' | '3'; // 0: ninguna, 1: baja, 2: media, 3: alta // Interface para los datos crudos que vienen de Dolibarr export interface DolibarrTask { id: string | number; ref: string; label: string; description: string; fk_project: string | number; fk_task_parent: string | number; date_start: number | null; date_end: number | null; dateo: number | null; // fecha planificada inicio datee: number | null; // fecha planificada fin date_c: number | null; date_m: number | null; duration_effective: number; // segundos trabajados planned_workload: number; // segundos planificados progress: number | string; priority: string | number; budget_amount: string | number; rang: number; status: string; note_public: string; note_private: string; fk_user_creat: string | number; fk_user_valid: string | number; // Campos adicionales que puede devolver la API timespent?: number; array_options?: Record; } // Interface normalizada para la UI export interface Task { id: number; ref: string; title: string; description: string; projectId: number; parentTaskId: number | null; status: TaskStatus; priority: TaskPriority; progress: number; plannedHours: number; workedHours: number; budget: number; startDate: string | null; endDate: string | null; plannedStartDate: string | null; plannedEndDate: string | null; createdAt: string; updatedAt: string; createdBy: number; order: number; } // Configuración de estados de tarea export const TASK_STATUS_CONFIG: Record = { '0': { label: 'Borrador', color: 'gray', bgClass: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300' }, '1': { label: 'Validada', color: 'blue', bgClass: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400' }, '2': { label: 'Completada', color: 'green', bgClass: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' }, }; // Configuración de prioridades export const TASK_PRIORITY_CONFIG: Record = { '0': { label: 'Sin prioridad', color: 'gray', bgClass: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400' }, '1': { label: 'Baja', color: 'blue', bgClass: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400' }, '2': { label: 'Media', color: 'yellow', bgClass: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400' }, '3': { label: 'Alta', color: 'red', bgClass: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400' }, }; // Helper para convertir timestamp a fecha ISO function timestampToDateString(timestamp: number | null | undefined): string | null { if (!timestamp || timestamp === 0) { return null; } return new Date(timestamp * 1000).toISOString().split('T')[0]; } // Helper para convertir segundos a horas function secondsToHours(seconds: number | null | undefined): number { if (!seconds) return 0; return Math.round((seconds / 3600) * 10) / 10; // Redondear a 1 decimal } // Función para mapear tarea de Dolibarr al formato UI export function mapDolibarrTask(dolibarr: DolibarrTask): Task { const progress = typeof dolibarr.progress === 'string' ? parseFloat(dolibarr.progress) : (dolibarr.progress || 0); const priority = String(dolibarr.priority || '0') as TaskPriority; const validPriorities: TaskPriority[] = ['0', '1', '2', '3']; const safePriority: TaskPriority = validPriorities.includes(priority) ? priority : '0'; const status = String(dolibarr.status || '0') as TaskStatus; const validStatuses: TaskStatus[] = ['0', '1', '2']; const safeStatus: TaskStatus = validStatuses.includes(status) ? status : '0'; return { id: typeof dolibarr.id === 'string' ? parseInt(dolibarr.id) : dolibarr.id, ref: dolibarr.ref || '', title: dolibarr.label || 'Sin título', description: dolibarr.description || '', projectId: typeof dolibarr.fk_project === 'string' ? parseInt(dolibarr.fk_project) : dolibarr.fk_project, parentTaskId: dolibarr.fk_task_parent ? (typeof dolibarr.fk_task_parent === 'string' ? parseInt(dolibarr.fk_task_parent) : dolibarr.fk_task_parent) : null, status: safeStatus, priority: safePriority, progress: Math.min(Math.max(progress, 0), 100), // Asegurar entre 0-100 plannedHours: secondsToHours(dolibarr.planned_workload), workedHours: secondsToHours(dolibarr.duration_effective || dolibarr.timespent), budget: typeof dolibarr.budget_amount === 'string' ? parseFloat(dolibarr.budget_amount) || 0 : (dolibarr.budget_amount || 0), startDate: timestampToDateString(dolibarr.date_start), endDate: timestampToDateString(dolibarr.date_end), plannedStartDate: timestampToDateString(dolibarr.dateo), plannedEndDate: timestampToDateString(dolibarr.datee), createdAt: timestampToDateString(dolibarr.date_c) || new Date().toISOString().split('T')[0], updatedAt: timestampToDateString(dolibarr.date_m) || new Date().toISOString().split('T')[0], createdBy: typeof dolibarr.fk_user_creat === 'string' ? parseInt(dolibarr.fk_user_creat) : (dolibarr.fk_user_creat || 0), order: dolibarr.rang || 0, }; } // Helper para obtener label de estado export function getTaskStatusLabel(status: TaskStatus): string { return TASK_STATUS_CONFIG[status]?.label || 'Desconocido'; } // Helper para obtener label de prioridad export function getTaskPriorityLabel(priority: TaskPriority): string { return TASK_PRIORITY_CONFIG[priority]?.label || 'Sin prioridad'; }