/** * Execute all panorama queries in parallel * Returns data for the Panorama Facturador page */ export default defineEventHandler(async (event) => { const body = await readBody(event) const { fecha_desde = null, fecha_hasta = null, incluir_anulados = false } = body try { // First, get all cards to find our panorama queries const allCards = await getMetabaseCards('all') // Find our panorama queries by name const queryNames = [ 'panorama_totales_financieros_principales', 'panorama_totales_ingreso_compra', 'panorama_totales_monetarios', 'panorama_totales_verde', 'panorama_secos_vendidos', 'panorama_rechazos_subproductos', 'panorama_serie_temporal_diaria', 'panorama_top_clientes', 'panorama_conteo_registros' ] const cards: Record = {} for (const name of queryNames) { const card = allCards.find((c: any) => c.name === name) if (!card) { console.warn(`[Panorama] Query not found: ${name}`) } else { cards[name] = card } } // Build parameters array for Metabase queries const parameters = [ { type: 'date/single', target: ['variable', ['template-tag', 'fecha_desde']], value: fecha_desde }, { type: 'date/single', target: ['variable', ['template-tag', 'fecha_hasta']], value: fecha_hasta }, { type: 'category', target: ['variable', ['template-tag', 'incluir_anulados']], value: incluir_anulados } ] // Execute all queries in parallel const [ financieros, ingresoCompra, monetarios, verde, secosVendidos, rechazos, serieTemporal, topClientes, conteos ] = await Promise.all([ cards['panorama_totales_financieros_principales'] ? executeCardQuery(cards['panorama_totales_financieros_principales'].id, parameters) : { data: { rows: [[0, 0, 0]] } }, cards['panorama_totales_ingreso_compra'] ? executeCardQuery(cards['panorama_totales_ingreso_compra'].id, parameters) : { data: { rows: [[]] } }, cards['panorama_totales_monetarios'] ? executeCardQuery(cards['panorama_totales_monetarios'].id, parameters) : { data: { rows: [[]] } }, cards['panorama_totales_verde'] ? executeCardQuery(cards['panorama_totales_verde'].id, parameters) : { data: { rows: [[]] } }, cards['panorama_secos_vendidos'] ? executeCardQuery(cards['panorama_secos_vendidos'].id, parameters) : { data: { rows: [[]] } }, cards['panorama_rechazos_subproductos'] ? executeCardQuery(cards['panorama_rechazos_subproductos'].id, parameters) : { data: { rows: [] } }, cards['panorama_serie_temporal_diaria'] ? executeCardQuery(cards['panorama_serie_temporal_diaria'].id, parameters) : { data: { rows: [] } }, cards['panorama_top_clientes'] ? executeCardQuery(cards['panorama_top_clientes'].id, parameters) : { data: { rows: [] } }, cards['panorama_conteo_registros'] ? executeCardQuery(cards['panorama_conteo_registros'].id, parameters) : { data: { rows: [[0, 0, 0, 0]] } } ]) // 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 { financieros: transformSingleRow(financieros), ingresoCompra: transformSingleRow(ingresoCompra), monetarios: transformSingleRow(monetarios), verde: transformSingleRow(verde), secosVendidos: transformSingleRow(secosVendidos), rechazos: transformMultipleRows(rechazos), serieTemporal: transformMultipleRows(serieTemporal), topClientes: transformMultipleRows(topClientes), conteos: transformSingleRow(conteos) } } catch (error: any) { console.error('[API] Failed to execute panorama queries:', error) throw createError({ statusCode: error.statusCode || 500, statusMessage: error.statusMessage || 'Failed to execute panorama queries' }) } })