import { METABASE_QUERIES } from '../../config/metabase-queries' /** * Execute all informe empleados queries in parallel * Returns data for the Informe de Empleados page */ export default defineEventHandler(async (event) => { const body = await readBody(event) const { fecha_desde = null, fecha_hasta = null, empleado_ids = [], titulos_tareas = [], titulos_planillas = [] } = body try { // First, get all cards to find our informe empleados queries const allCards = await getMetabaseCards('all') // Find our informe empleados queries by name using centralized config const queryNames = METABASE_QUERIES.informe_empleados const cards: Record = {} for (const [key, name] of Object.entries(queryNames)) { const card = allCards.find((c: any) => c.name === name) if (!card) { console.warn(`[Informe Empleados] Query not found: ${name}`) } else { cards[key] = card } } // Build parameters array for Metabase queries const buildParameters = () => { const params = [ { type: 'text', target: ['variable', ['template-tag', 'fecha_desde']], value: fecha_desde || '' }, { type: 'text', target: ['variable', ['template-tag', 'fecha_hasta']], value: fecha_hasta || '' } ] // Solo agregar filtros opcionales si tienen valores (no vacíos) if (empleado_ids && Array.isArray(empleado_ids) && empleado_ids.length > 0) { params.push({ type: 'number', target: ['variable', ['template-tag', 'empleado_ids']], value: empleado_ids }) } if (titulos_tareas && Array.isArray(titulos_tareas) && titulos_tareas.length > 0) { params.push({ type: 'text', target: ['variable', ['template-tag', 'titulos_tareas']], value: titulos_tareas }) } if (titulos_planillas && Array.isArray(titulos_planillas) && titulos_planillas.length > 0) { params.push({ type: 'text', target: ['variable', ['template-tag', 'titulos_planillas']], value: titulos_planillas }) } return params } const standardParams = buildParameters() const emptyParams: any[] = [] // Para opciones_filtros que no requiere parámetros // Execute all queries in parallel with error handling const executeWithErrorHandling = async (name: string, cardId: number | undefined, parameters: any[], defaultValue: any) => { if (!cardId) { console.warn(`[Informe Empleados] No card ID for ${name}`) return defaultValue } try { console.log(`[Informe Empleados] Executing query: ${name} (ID: ${cardId})`) const result = await executeCardQuery(cardId, parameters) console.log(`[Informe Empleados] Query ${name} returned ${result.data?.rows?.length || 0} rows`) return result } catch (error: any) { console.error(`[Informe Empleados] Error executing ${name}:`, error.message) return defaultValue } } const [ contadores, listaEmpleados, detalleTareas, detalleAsistencias, detallePlanillas, opcionesFiltros ] = await Promise.all([ executeWithErrorHandling('contadores', cards.contadores?.id, standardParams, { data: { rows: [[]], cols: [] } }), executeWithErrorHandling('lista_empleados', cards.lista_empleados?.id, standardParams, { data: { rows: [], cols: [] } }), executeWithErrorHandling('detalle_tareas', cards.detalle_tareas?.id, standardParams, { data: { rows: [], cols: [] } }), executeWithErrorHandling('detalle_asistencias', cards.detalle_asistencias?.id, standardParams, { data: { rows: [], cols: [] } }), executeWithErrorHandling('detalle_planillas', cards.detalle_planillas?.id, standardParams, { data: { rows: [], cols: [] } }), executeWithErrorHandling('opciones_filtros', cards.opciones_filtros?.id, emptyParams, { data: { rows: [], cols: [] } }) ]) // Transform Metabase responses to objects for easier frontend consumption const transformSingleRow = (result: any) => { if (!result.data?.rows?.[0] || !result.data?.cols) return {} const row = result.data.rows[0] const cols = result.data.cols const obj: any = {} cols.forEach((col: any, index: number) => { obj[col.name] = row[index] }) return obj } const transformMultipleRows = (result: any) => { if (!result.data?.rows || !result.data?.cols) return [] const cols = result.data.cols return result.data.rows.map((row: any[]) => { const obj: any = {} cols.forEach((col: any, index: number) => { obj[col.name] = row[index] }) return obj }) } // Transform opciones_filtros to a more usable format const transformOpcionesFiltros = (result: any) => { if (!result.data?.rows || !result.data?.cols) { return { titulos_tareas: [], titulos_planillas: [] } } const rows = transformMultipleRows(result) const opciones: any = { titulos_tareas: [], titulos_planillas: [] } rows.forEach((row: any) => { if (row.tipo_opcion === 'titulos_tareas') { opciones.titulos_tareas.push(row.valor) } else if (row.tipo_opcion === 'titulos_planillas') { opciones.titulos_planillas.push(row.valor) } }) return opciones } // Return all data in a structured format return { contadores: transformSingleRow(contadores), listaEmpleados: transformMultipleRows(listaEmpleados), detalleTareas: transformMultipleRows(detalleTareas), detalleAsistencias: transformMultipleRows(detalleAsistencias), detallePlanillas: transformMultipleRows(detallePlanillas), opcionesFiltros: transformOpcionesFiltros(opcionesFiltros) } } catch (error: any) { console.error('[API] Failed to execute informe empleados queries:', error) throw createError({ statusCode: error.statusCode || 500, statusMessage: error.statusMessage || 'Failed to execute informe empleados queries' }) } })