Feat: Agregar página Comparativa UVA vs Carretas
Some checks failed
build-and-deploy / build-and-deploy (push) Failing after 4m22s
Some checks failed
build-and-deploy / build-and-deploy (push) Failing after 4m22s
- Nuevo endpoint API para ejecutar Card 94 de Metabase - Página con filtros de fecha, cards de totales y tabla completa - Colores de rendimiento: verde (95-105%), amarillo, rojo - Enlace agregado al sidebar
This commit is contained in:
107
nuxt4-app/server/api/metabase/comparativa-uva-carretas.post.ts
Normal file
107
nuxt4-app/server/api/metabase/comparativa-uva-carretas.post.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* API endpoint for Comparativa Ingreso UVA vs Salida Carretas
|
||||
* Executes Card 94 from Metabase and returns processed data
|
||||
*/
|
||||
|
||||
const CARD_ID = 94 // Comparativa Ingreso UVA vs Salida (Nov-Dic 2025)
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event)
|
||||
|
||||
const {
|
||||
fecha_desde = null,
|
||||
fecha_hasta = null
|
||||
} = body
|
||||
|
||||
try {
|
||||
console.log(`[Comparativa UVA] Executing card ${CARD_ID}`)
|
||||
|
||||
// Execute the card without parameters (dates are hardcoded in the card)
|
||||
const result = await executeCardQuery(CARD_ID, [])
|
||||
|
||||
if (!result.data?.rows || !result.data?.cols) {
|
||||
console.warn('[Comparativa UVA] No data returned from Metabase')
|
||||
return {
|
||||
datos: [],
|
||||
totales: {
|
||||
ingreso_qq: 0,
|
||||
ingreso_lb: 0,
|
||||
salida_lb: 0,
|
||||
diferencia_lb: 0,
|
||||
rendimiento_promedio: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform rows to objects
|
||||
const cols = result.data.cols
|
||||
let datos = result.data.rows.map((row: any[]) => {
|
||||
const obj: Record<string, any> = {}
|
||||
cols.forEach((col: any, index: number) => {
|
||||
obj[col.name] = row[index]
|
||||
})
|
||||
return obj
|
||||
})
|
||||
|
||||
console.log(`[Comparativa UVA] Retrieved ${datos.length} rows`)
|
||||
|
||||
// Filter by dates if provided
|
||||
if (fecha_desde || fecha_hasta) {
|
||||
datos = datos.filter((row: any) => {
|
||||
if (!row.fecha) return false
|
||||
|
||||
const rowDate = new Date(row.fecha)
|
||||
|
||||
if (fecha_desde) {
|
||||
const desde = new Date(fecha_desde)
|
||||
if (rowDate < desde) return false
|
||||
}
|
||||
|
||||
if (fecha_hasta) {
|
||||
const hasta = new Date(fecha_hasta)
|
||||
if (rowDate > hasta) return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
console.log(`[Comparativa UVA] After date filter: ${datos.length} rows`)
|
||||
}
|
||||
|
||||
// Calculate totals
|
||||
const totales = datos.reduce((acc: any, row: any) => {
|
||||
acc.ingreso_qq += Number(row.ingreso_uva_qq) || 0
|
||||
acc.ingreso_lb += Number(row.ingreso_uva_lb) || 0
|
||||
acc.salida_lb += Number(row.salida_total_lb) || 0
|
||||
acc.diferencia_lb += Number(row.diferencia_lb) || 0
|
||||
return acc
|
||||
}, {
|
||||
ingreso_qq: 0,
|
||||
ingreso_lb: 0,
|
||||
salida_lb: 0,
|
||||
diferencia_lb: 0
|
||||
})
|
||||
|
||||
// Calculate weighted average rendimiento
|
||||
totales.rendimiento_promedio = totales.ingreso_lb > 0
|
||||
? Math.round((totales.salida_lb / totales.ingreso_lb) * 1000) / 10
|
||||
: 0
|
||||
|
||||
// Round totals
|
||||
totales.ingreso_qq = Math.round(totales.ingreso_qq * 100) / 100
|
||||
totales.ingreso_lb = Math.round(totales.ingreso_lb)
|
||||
totales.salida_lb = Math.round(totales.salida_lb)
|
||||
totales.diferencia_lb = Math.round(totales.diferencia_lb)
|
||||
|
||||
return {
|
||||
datos,
|
||||
totales
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('[Comparativa UVA] Failed to execute query:', error)
|
||||
throw createError({
|
||||
statusCode: error.statusCode || 500,
|
||||
statusMessage: error.statusMessage || 'Failed to execute comparativa UVA query'
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user