151 lines
5.3 KiB
TypeScript
151 lines
5.3 KiB
TypeScript
/**
|
|
* 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<string, any> = {}
|
|
|
|
console.log('[Panorama] Total cards found:', allCards.length)
|
|
console.log('[Panorama] Looking for queries:', queryNames)
|
|
|
|
for (const name of queryNames) {
|
|
const card = allCards.find((c: any) => c.name === name)
|
|
if (!card) {
|
|
console.warn(`[Panorama] Query not found: ${name}`)
|
|
} else {
|
|
console.log(`[Panorama] Found query: ${name} with ID ${card.id}`)
|
|
cards[name] = card
|
|
}
|
|
}
|
|
|
|
console.log('[Panorama] Total cards matched:', Object.keys(cards).length)
|
|
|
|
// 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 with error handling
|
|
const executeWithErrorHandling = async (name: string, cardId: number | undefined, defaultValue: any) => {
|
|
if (!cardId) {
|
|
console.warn(`[Panorama] No card ID for ${name}`)
|
|
return defaultValue
|
|
}
|
|
|
|
try {
|
|
console.log(`[Panorama] Executing query: ${name} (ID: ${cardId})`)
|
|
const result = await executeCardQuery(cardId, parameters)
|
|
console.log(`[Panorama] Query ${name} returned ${result.data?.rows?.length || 0} rows`)
|
|
return result
|
|
} catch (error: any) {
|
|
console.error(`[Panorama] Error executing ${name}:`, error.message)
|
|
return defaultValue
|
|
}
|
|
}
|
|
|
|
const [
|
|
financieros,
|
|
ingresoCompra,
|
|
monetarios,
|
|
verde,
|
|
secosVendidos,
|
|
rechazos,
|
|
serieTemporal,
|
|
topClientes,
|
|
conteos
|
|
] = await Promise.all([
|
|
executeWithErrorHandling('financieros', cards['panorama_totales_financieros_principales']?.id, { data: { rows: [[0, 0, 0]], cols: [] } }),
|
|
executeWithErrorHandling('ingresoCompra', cards['panorama_totales_ingreso_compra']?.id, { data: { rows: [[]], cols: [] } }),
|
|
executeWithErrorHandling('monetarios', cards['panorama_totales_monetarios']?.id, { data: { rows: [[]], cols: [] } }),
|
|
executeWithErrorHandling('verde', cards['panorama_totales_verde']?.id, { data: { rows: [[]], cols: [] } }),
|
|
executeWithErrorHandling('secosVendidos', cards['panorama_secos_vendidos']?.id, { data: { rows: [[]], cols: [] } }),
|
|
executeWithErrorHandling('rechazos', cards['panorama_rechazos_subproductos']?.id, { data: { rows: [], cols: [] } }),
|
|
executeWithErrorHandling('serieTemporal', cards['panorama_serie_temporal_diaria']?.id, { data: { rows: [], cols: [] } }),
|
|
executeWithErrorHandling('topClientes', cards['panorama_top_clientes']?.id, { data: { rows: [], cols: [] } }),
|
|
executeWithErrorHandling('conteos', cards['panorama_conteo_registros']?.id, { data: { rows: [[0, 0, 0, 0]], 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 {
|
|
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'
|
|
})
|
|
}
|
|
})
|