Files
HoruxDespachosNuevo/apps/api/scripts/inspect-cfdi.ts

91 lines
3.1 KiB
TypeScript

/**
* Inspecciona el estado de un CFDI y sus relacionados (pagos + E/07) en todos
* los tenants. Útil para debug de saldos pendientes.
*
* Uso:
* pnpm --filter @horux/api exec tsx scripts/inspect-cfdi.ts <uuid>
*/
import { prisma, tenantDb } from '../src/config/database.js';
const rawUuid = process.argv[2];
if (!rawUuid) {
console.error('Usage: tsx scripts/inspect-cfdi.ts <uuid>');
process.exit(1);
}
const uuid = rawUuid.toLowerCase();
async function main() {
const tenants = await prisma.tenant.findMany({
where: { active: true },
select: { id: true, rfc: true, databaseName: true },
orderBy: { rfc: 'asc' },
});
for (const t of tenants) {
const pool = await tenantDb.getPool(t.id, t.databaseName);
const { rows: base } = await pool.query(
`SELECT id, uuid, type, tipo_comprobante, metodo_pago, status, fecha_emision,
total, total_mxn, monto_pago, monto_pago_mxn,
saldo_insoluto, saldo_pendiente, saldo_pendiente_mxn,
uuid_relacionado, cfdi_tipo_relacion, cfdis_relacionados,
rfc_emisor, rfc_receptor, conciliado, id_conciliacion,
source, facturapi_id
FROM cfdis WHERE LOWER(uuid) = $1`,
[uuid],
);
if (base.length === 0) continue;
console.log(`\n=== Tenant ${t.rfc} (${t.databaseName}) ===`);
console.log('CFDI base:');
console.log(base[0]);
// P complements que apuntan a este UUID via uuid_relacionado (DoctoRelacionado)
const { rows: pagosP } = await pool.query(
`SELECT id, uuid, type, tipo_comprobante, fecha_emision, fecha_pago_p,
monto_pago, monto_pago_mxn, num_parcialidad,
uuid_relacionado, status
FROM cfdis
WHERE tipo_comprobante = 'P' AND LOWER(uuid_relacionado) = $1
ORDER BY fecha_pago_p NULLS LAST, id`,
[uuid],
);
console.log(`\nComplementos P que referencian este UUID (DoctoRelacionado): ${pagosP.length}`);
for (const r of pagosP) console.log(' ', r);
// E CFDIs con cfdis_relacionados que contengan este UUID (TipoRelacion=07 típicamente)
const { rows: ecfdis } = await pool.query(
`SELECT id, uuid, type, tipo_comprobante, metodo_pago, fecha_emision,
total, total_mxn, cfdi_tipo_relacion, cfdis_relacionados,
status
FROM cfdis
WHERE tipo_comprobante = 'E'
AND cfdis_relacionados IS NOT NULL
AND LOWER(cfdis_relacionados) LIKE $1
ORDER BY fecha_emision, id`,
[`%${uuid}%`],
);
console.log(`\nCFDIs tipo E con este UUID en cfdis_relacionados: ${ecfdis.length}`);
for (const r of ecfdis) console.log(' ', r);
// Si el base está conciliado, traer la fila
if (base[0].id_conciliacion) {
const { rows: conc } = await pool.query(
`SELECT * FROM conciliaciones WHERE id = $1`,
[base[0].id_conciliacion],
);
console.log(`\nConciliación vinculada:`);
for (const r of conc) console.log(' ', r);
}
}
await prisma.$disconnect();
}
main().catch(async (err) => {
console.error('Fatal:', err);
await prisma.$disconnect().catch(() => {});
process.exit(1);
});