Files
HoruxDespachosNuevo/apps/api/scripts/debug-ingresos-horux-may.ts

112 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Debug ingresos Horux 360 mayo-2025 post-Método A:
* - Llama al KPI (calcularIngresosPorRegimen)
* - Lista los CFDIs que entran al drill-down (mismos filtros del controller)
* - Suma manualmente para ver dónde está la discrepancia
*/
process.env.METRICAS_BYPASS_CACHE = '1';
import { prisma, tenantDb } from '../src/config/database.js';
import { calcularIngresosPorRegimen, GRUPO_PF_EMPRESARIAL, GRUPO_PM_OTROS } from '../src/services/dashboard.service.js';
import { resolveContribuyenteContext } from '../src/utils/contribuyente-context.js';
const TENANT_RFC = 'DESPACHO_MO3NI6U8_B9VGG';
const CONTRIB_ID = 'b3761db6-0b8d-4251-8078-4ddc31e9c75b'; // Horux 360
const FI = '2025-05-01';
const FF = '2025-05-31';
async function main() {
const tenant = await prisma.tenant.findFirst({
where: { rfc: TENANT_RFC },
select: { id: true, databaseName: true },
});
if (!tenant) return;
const pool = await tenantDb.getPool(tenant.id, tenant.databaseName);
const ctx = await resolveContribuyenteContext(pool, tenant.id, CONTRIB_ID);
console.log(`\n=== KPI calcularIngresosPorRegimen ===`);
const kpi = await calcularIngresosPorRegimen(
pool, tenant.id, FI, FF, undefined, undefined, false, CONTRIB_ID,
);
console.log(`Total KPI: ${kpi.total.toFixed(2)}`);
for (const r of kpi.porRegimen) {
console.log(` ${r.regimenClave} ${r.regimenDescripcion.substring(0, 40).padEnd(40)} ${r.monto.toFixed(2)}`);
}
// Replica de los filtros del drill-down bucket 'ingresos' (cfdi.controller.ts:163-187)
const IMP_TRAS = `COALESCE(iva_traslado_mxn,0) + COALESCE(ieps_traslado_mxn,0) + COALESCE(impuestos_locales_trasladado_mxn,0)`;
const IMP_TRAS_PAGO = `COALESCE(iva_traslado_pago_mxn,0) + COALESCE(ieps_traslado_pago_mxn,0)`;
const VIGENTE = `status NOT IN ('Cancelado', '0')`;
const CLAVES = `('84121603','93161608','85101501','85121800')`;
const EXCL_MONTO = `COALESCE((SELECT SUM(COALESCE(cc.importe_mxn,0)-COALESCE(cc.descuento_mxn,0)) FROM cfdi_conceptos cc WHERE cc.cfdi_id = cfdis.id AND cc.clave_prod_serv IN ${CLAVES}),0)`;
const g1 = GRUPO_PF_EMPRESARIAL.map(r => `'${r}'`).join(',');
const g3 = GRUPO_PM_OTROS.map(r => `'${r}'`).join(',');
const drillSql = `
SELECT id, uuid, type, tipo_comprobante, metodo_pago, regimen_fiscal_emisor,
regimen_fiscal_receptor, rfc_emisor, rfc_receptor, nombre_receptor,
total_mxn, iva_traslado_mxn, ieps_traslado_mxn, impuestos_locales_trasladado_mxn,
monto_pago_mxn, iva_traslado_pago_mxn, ieps_traslado_pago_mxn,
cfdi_tipo_relacion, fecha_emision, fecha_pago_p, source,
-- neto (lo que "contribuye" a ingresos según grupo)
CASE
WHEN tipo_comprobante='I' THEN (COALESCE(total_mxn,0) - (${IMP_TRAS}) - (${EXCL_MONTO}))
WHEN tipo_comprobante='E' THEN -(COALESCE(total_mxn,0) - (${IMP_TRAS}) - (${EXCL_MONTO}))
WHEN tipo_comprobante='P' THEN (COALESCE(monto_pago_mxn,0) - (${IMP_TRAS_PAGO}))
WHEN tipo_comprobante='N' THEN COALESCE(total_mxn,0)
ELSE 0
END AS aporte
FROM cfdis
WHERE ${VIGENTE}
AND fecha_emision >= $1::date AND fecha_emision < ($2::date + interval '1 day')
AND (
(${ctx.esEmisor} AND regimen_fiscal_emisor IN (${g1}) AND (
(tipo_comprobante='I' AND metodo_pago='PUE')
OR (tipo_comprobante='P')
OR (tipo_comprobante='E' AND metodo_pago='PUE')
))
OR (${ctx.esReceptor} AND tipo_comprobante='N' AND metodo_pago='PUE' AND regimen_fiscal_receptor='605')
OR (${ctx.esEmisor} AND regimen_fiscal_emisor IN (${g3}) AND (
(tipo_comprobante='I' AND metodo_pago IN ('PUE','PPD'))
OR (tipo_comprobante='E' AND metodo_pago='PUE')
))
)
ORDER BY fecha_emision, tipo_comprobante, total_mxn DESC
`;
const { rows } = await pool.query(drillSql, [FI, FF]);
console.log(`\n=== Drill-down (${rows.length} CFDIs) ===`);
let sumDrill = 0;
const perRegimen: Record<string, number> = {};
for (const r of rows) {
const aporte = Number(r.aporte || 0);
sumDrill += aporte;
const reg = r.regimen_fiscal_emisor || r.regimen_fiscal_receptor || '?';
perRegimen[reg] = (perRegimen[reg] || 0) + aporte;
const fe = r.fecha_emision?.toISOString?.()?.slice(0, 10) || r.fecha_emision;
const rel07 = r.cfdi_tipo_relacion === '07' ? ' [07]' : '';
const src = r.source === 'facturapi' ? ' [facturapi]' : '';
console.log(
` ${fe} ${r.tipo_comprobante}/${r.metodo_pago}${rel07}${src} ` +
`reg=${reg} ${String(r.rfc_emisor).padEnd(14)}${String(r.rfc_receptor).padEnd(14)} ` +
`total=${Number(r.total_mxn || 0).toFixed(2).padStart(10)} ` +
`aporte=${aporte.toFixed(2).padStart(10)} ${r.uuid.substring(0,8)}`
);
}
console.log(`\n=== Suma de aportes del drill-down: ${sumDrill.toFixed(2)} ===`);
console.log(`Por régimen (drill-down):`);
for (const [reg, monto] of Object.entries(perRegimen).sort()) {
console.log(` ${reg}: ${monto.toFixed(2)}`);
}
console.log(`\n=== Diferencia KPI drill: ${(kpi.total - sumDrill).toFixed(2)} ===`);
await prisma.$disconnect();
}
main().catch(async e => { console.error(e); await prisma.$disconnect().catch(() => {}); process.exit(1); });