import { METABASE_QUERIES } from '../../config/metabase-queries' /** * Execute all informe queries in parallel * Returns data for the Informe de Ingresos page */ export default defineEventHandler(async (event) => { const body = await readBody(event) const { fecha_desde = null, fecha_hasta = null, incluir_anulados = false, cliente_ids = [], tipos = [], estados = [], ubicaciones = [], calidades = [], granularidad = 'dia' } = body try { // First, get all cards to find our informe queries const allCards = await getMetabaseCards('all') // Find our informe queries by name using centralized config const queryNames = METABASE_QUERIES.informe 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] Query not found: ${name}`) } else { cards[key] = card } } // Build parameters array for Metabase queries // Las queries SQL nativas usan template-tags de tipo 'text' para fechas, no 'date/single' const buildParameters = (includeGranularidad: boolean = false) => { const params = [ { type: 'text', target: ['variable', ['template-tag', 'fecha_desde']], value: fecha_desde || '' }, { type: 'text', target: ['variable', ['template-tag', 'fecha_hasta']], value: fecha_hasta || '' }, { type: 'boolean', target: ['variable', ['template-tag', 'incluir_anulados']], value: incluir_anulados }, { type: 'number', target: ['variable', ['template-tag', 'cliente_ids']], value: cliente_ids }, { type: 'text', target: ['variable', ['template-tag', 'tipos']], value: tipos }, { type: 'text', target: ['variable', ['template-tag', 'estados']], value: estados }, { type: 'text', target: ['variable', ['template-tag', 'ubicaciones']], value: ubicaciones }, { type: 'text', target: ['variable', ['template-tag', 'calidades']], value: calidades } ] if (includeGranularidad) { params.push({ type: 'text', target: ['variable', ['template-tag', 'granularidad']], value: granularidad }) } return params } const standardParams = buildParameters(false) const serieTemporalParams = buildParameters(true) // 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] No card ID for ${name}`) return defaultValue } try { console.log(`[Informe] Executing query: ${name} (ID: ${cardId})`) const result = await executeCardQuery(cardId, parameters) console.log(`[Informe] Query ${name} returned ${result.data?.rows?.length || 0} rows`) return result } catch (error: any) { console.error(`[Informe] Error executing ${name}:`, error.message) return defaultValue } } const [ totalesIngresoCompra, totalesMonetarios, totalesVerde, listaIngresos, listaClientes, serieTemporal, opcionesFiltros, contadores ] = await Promise.all([ executeWithErrorHandling('totales_ingreso_compra', cards.totales_ingreso_compra?.id, standardParams, { data: { rows: [[]], cols: [] } }), executeWithErrorHandling('totales_monetarios', cards.totales_monetarios?.id, standardParams, { data: { rows: [[]], cols: [] } }), executeWithErrorHandling('totales_verde', cards.totales_verde?.id, standardParams, { data: { rows: [[]], cols: [] } }), executeWithErrorHandling('lista_ingresos', cards.lista_ingresos?.id, standardParams, { data: { rows: [], cols: [] } }), executeWithErrorHandling('lista_clientes', cards.lista_clientes?.id, standardParams, { data: { rows: [], cols: [] } }), executeWithErrorHandling('serie_temporal', cards.serie_temporal?.id, serieTemporalParams, { data: { rows: [], cols: [] } }), executeWithErrorHandling('opciones_filtros', cards.opciones_filtros?.id, [], { data: { rows: [[]], cols: [] } }), executeWithErrorHandling('contadores', cards.contadores?.id, standardParams, { 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 }) } // Return all data in a structured format return { totalesIngresoCompra: transformSingleRow(totalesIngresoCompra), totalesMonetarios: transformSingleRow(totalesMonetarios), totalesVerde: transformSingleRow(totalesVerde), listaIngresos: transformMultipleRows(listaIngresos), listaClientes: transformMultipleRows(listaClientes), serieTemporal: transformMultipleRows(serieTemporal), opcionesFiltros: transformSingleRow(opcionesFiltros), contadores: transformSingleRow(contadores) } } catch (error: any) { console.error('[API] Failed to execute informe queries:', error) throw createError({ statusCode: error.statusCode || 500, statusMessage: error.statusMessage || 'Failed to execute informe queries' }) } })