104 lines
4.4 KiB
TypeScript
104 lines
4.4 KiB
TypeScript
/**
|
|
* Inspecciona un CFDI específico para entender por qué el filtro de
|
|
* "Considerar activos" no lo captura. Imprime los campos relevantes y
|
|
* cualquier CFDI relacionado.
|
|
*/
|
|
import { prisma, tenantDb } from '../src/config/database.js';
|
|
|
|
async function main() {
|
|
const uuid = process.argv[2] || '8ec2eaf3-7879-11f0-81a8-8daae9822b10';
|
|
|
|
// Buscar en TODOS los tenants
|
|
const tenants = await prisma.tenant.findMany({
|
|
where: { active: true },
|
|
select: { id: true, rfc: true, nombre: true, databaseName: true },
|
|
});
|
|
|
|
for (const t of tenants) {
|
|
const pool = await tenantDb.getPool(t.id, t.databaseName);
|
|
const { rows } = await pool.query(`
|
|
SELECT
|
|
uuid, type, tipo_comprobante, metodo_pago, forma_pago,
|
|
uso_cfdi, cfdi_tipo_relacion,
|
|
rfc_emisor, nombre_emisor, regimen_fiscal_emisor,
|
|
rfc_receptor, nombre_receptor, regimen_fiscal_receptor,
|
|
total_mxn, monto_pago_mxn,
|
|
fecha_emision, fecha_pago_p, status,
|
|
uuid_relacionado, cfdis_relacionados
|
|
FROM cfdis
|
|
WHERE uuid = $1
|
|
`, [uuid]);
|
|
|
|
if (rows.length === 0) continue;
|
|
|
|
console.log(`\n═══ Tenant: ${t.rfc} (${t.nombre}) ═══`);
|
|
const r = rows[0];
|
|
for (const [k, v] of Object.entries(r)) {
|
|
console.log(` ${k.padEnd(28)} ${v}`);
|
|
}
|
|
|
|
// Si hay uuid_relacionado o cfdis_relacionados, traer esos también
|
|
if (r.uuid_relacionado) {
|
|
const { rows: rel } = await pool.query(
|
|
`SELECT uuid, tipo_comprobante, uso_cfdi, total_mxn FROM cfdis WHERE LOWER(uuid) = LOWER($1)`,
|
|
[r.uuid_relacionado],
|
|
);
|
|
console.log(`\n Relacionado vía uuid_relacionado (${r.uuid_relacionado}):`);
|
|
console.log(rel[0] || '(no encontrado)');
|
|
}
|
|
|
|
if (r.cfdis_relacionados) {
|
|
const uuids = String(r.cfdis_relacionados).split('|').map(s => s.trim()).filter(Boolean);
|
|
console.log(`\n Relacionados vía cfdis_relacionados (${uuids.length}):`);
|
|
for (const u of uuids) {
|
|
const { rows: rel } = await pool.query(
|
|
`SELECT uuid, tipo_comprobante, uso_cfdi, total_mxn FROM cfdis WHERE LOWER(uuid) = LOWER($1)`,
|
|
[u],
|
|
);
|
|
console.log(` ${u} →`, rel[0] || '(no encontrado)');
|
|
}
|
|
}
|
|
|
|
// Test del filtro: aplica activosExclusionNoAlias y verifica
|
|
const ACTIVOS_USOS = "('I01','I02','I03','I04','I05','I06','I07','I08')";
|
|
const test = await pool.query(`
|
|
SELECT
|
|
(tipo_comprobante = 'I' AND uso_cfdi IN ${ACTIVOS_USOS}) AS regla1_directo,
|
|
(tipo_comprobante = 'P' AND EXISTS (
|
|
SELECT 1 FROM cfdis i_act
|
|
WHERE LOWER(i_act.uuid) = LOWER(cfdis.uuid_relacionado)
|
|
AND i_act.tipo_comprobante = 'I'
|
|
AND i_act.uso_cfdi IN ${ACTIVOS_USOS}
|
|
)) AS regla2_p_paga_activo,
|
|
(tipo_comprobante = 'E' AND cfdis.cfdis_relacionados IS NOT NULL AND EXISTS (
|
|
SELECT 1 FROM cfdis r_act
|
|
WHERE LOWER(r_act.uuid) = ANY(string_to_array(LOWER(cfdis.cfdis_relacionados), '|'))
|
|
AND (r_act.tipo_comprobante = 'I' AND r_act.uso_cfdi IN ${ACTIVOS_USOS})
|
|
)) AS regla3_e_referencia_activo,
|
|
(tipo_comprobante = 'I' AND EXISTS (
|
|
SELECT 1 FROM cfdis i07_act
|
|
WHERE i07_act.tipo_comprobante = 'I'
|
|
AND i07_act.metodo_pago = 'PPD'
|
|
AND COALESCE(i07_act.cfdi_tipo_relacion, '') = '07'
|
|
AND i07_act.uso_cfdi IN ${ACTIVOS_USOS}
|
|
AND i07_act.status NOT IN ('Cancelado', '0')
|
|
AND i07_act.cfdis_relacionados IS NOT NULL
|
|
AND LOWER(cfdis.uuid) = ANY(string_to_array(LOWER(i07_act.cfdis_relacionados), '|'))
|
|
)) AS regla4_anticipo_activo
|
|
FROM cfdis
|
|
WHERE uuid = $1
|
|
`, [uuid]);
|
|
console.log(`\n Filtro activos:`);
|
|
console.log(` regla1 (I directo activo): ${test.rows[0].regla1_directo}`);
|
|
console.log(` regla2 (P paga I activo): ${test.rows[0].regla2_p_paga_activo}`);
|
|
console.log(` regla3 (E ref. I/P activo): ${test.rows[0].regla3_e_referencia_activo}`);
|
|
console.log(` regla4 (anticipo de I/07 act): ${test.rows[0].regla4_anticipo_activo}`);
|
|
const filtrado = test.rows[0].regla1_directo || test.rows[0].regla2_p_paga_activo || test.rows[0].regla3_e_referencia_activo || test.rows[0].regla4_anticipo_activo;
|
|
console.log(` → ${filtrado ? '🔴 FILTRADO (excluido del cálculo)' : '🟢 PASA (incluido en cálculo)'}`);
|
|
}
|
|
|
|
await prisma.$disconnect();
|
|
}
|
|
|
|
main().catch(e => { console.error(e); process.exit(1); });
|