Agregar endpoint de Informe de Ingresos y centralizar config de queries de Metabase
Some checks failed
build-and-deploy / build-and-deploy (push) Failing after 35s
Some checks failed
build-and-deploy / build-and-deploy (push) Failing after 35s
This commit is contained in:
183
nuxt4-app/server/api/metabase/informe.post.ts
Normal file
183
nuxt4-app/server/api/metabase/informe.post.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
import { METABASE_QUERIES } from '~/server/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<string, any> = {}
|
||||
|
||||
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
|
||||
const buildParameters = (includeGranularidad: boolean = false) => {
|
||||
const params = [
|
||||
{
|
||||
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
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
target: ['variable', ['template-tag', 'cliente_ids']],
|
||||
value: cliente_ids
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
target: ['variable', ['template-tag', 'tipos']],
|
||||
value: tipos
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
target: ['variable', ['template-tag', 'estados']],
|
||||
value: estados
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
target: ['variable', ['template-tag', 'ubicaciones']],
|
||||
value: ubicaciones
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
target: ['variable', ['template-tag', 'calidades']],
|
||||
value: calidades
|
||||
}
|
||||
]
|
||||
|
||||
if (includeGranularidad) {
|
||||
params.push({
|
||||
type: 'category',
|
||||
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'
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,3 +1,5 @@
|
||||
import { METABASE_QUERIES } from '~/server/config/metabase-queries'
|
||||
|
||||
/**
|
||||
* Execute all panorama queries in parallel
|
||||
* Returns data for the Panorama Facturador page
|
||||
@@ -11,27 +13,17 @@ export default defineEventHandler(async (event) => {
|
||||
// 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'
|
||||
]
|
||||
// Find our panorama queries by name using centralized config
|
||||
const queryNames = METABASE_QUERIES.panorama
|
||||
|
||||
const cards: Record<string, any> = {}
|
||||
|
||||
for (const name of queryNames) {
|
||||
for (const [key, name] of Object.entries(queryNames)) {
|
||||
const card = allCards.find((c: any) => c.name === name)
|
||||
if (!card) {
|
||||
console.warn(`[Panorama] Query not found: ${name}`)
|
||||
} else {
|
||||
cards[name] = card
|
||||
cards[key] = card
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,15 +76,15 @@ export default defineEventHandler(async (event) => {
|
||||
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: [] } })
|
||||
executeWithErrorHandling('financieros', cards.totales_financieros_principales?.id, { data: { rows: [[0, 0, 0]], cols: [] } }),
|
||||
executeWithErrorHandling('ingresoCompra', cards.totales_ingreso_compra?.id, { data: { rows: [[]], cols: [] } }),
|
||||
executeWithErrorHandling('monetarios', cards.totales_monetarios?.id, { data: { rows: [[]], cols: [] } }),
|
||||
executeWithErrorHandling('verde', cards.totales_verde?.id, { data: { rows: [[]], cols: [] } }),
|
||||
executeWithErrorHandling('secosVendidos', cards.secos_vendidos?.id, { data: { rows: [[]], cols: [] } }),
|
||||
executeWithErrorHandling('rechazos', cards.rechazos_subproductos?.id, { data: { rows: [], cols: [] } }),
|
||||
executeWithErrorHandling('serieTemporal', cards.serie_temporal_diaria?.id, { data: { rows: [], cols: [] } }),
|
||||
executeWithErrorHandling('topClientes', cards.top_clientes?.id, { data: { rows: [], cols: [] } }),
|
||||
executeWithErrorHandling('conteos', cards.conteo_registros?.id, { data: { rows: [[0, 0, 0, 0]], cols: [] } })
|
||||
])
|
||||
|
||||
// Transform Metabase responses to objects for easier frontend consumption
|
||||
|
||||
Reference in New Issue
Block a user