/** Breakdown: qué CFDIs contribuyen al IVA acreditable vs al gasto. */ import { prisma, tenantDb } from '../src/config/database.js'; import { resolveContribuyenteContext } from '../src/utils/contribuyente-context.js'; const tenantRfc = process.argv[2] || 'DESPACHO_MO3NI6U8_B9VGG'; const contribuyenteId = process.argv[3] || 'd745a915-6a23-4818-944b-a7e1e18e536a'; const yearMonth = process.argv[4] || '2025-12'; async function main() { const tenant = await prisma.tenant.findFirst({ where: { rfc: tenantRfc }, select: { id: true, databaseName: true } }); if (!tenant) return; const pool = await tenantDb.getPool(tenant.id, tenant.databaseName); const ctx = await resolveContribuyenteContext(pool, tenant.id, contribuyenteId); const [anio, mes] = yearMonth.split('-').map(Number); const lastDay = new Date(anio, mes, 0).getDate(); const fi = `${yearMonth}-01`; const ff = `${yearMonth}-${String(lastDay).padStart(2, '0')}`; const IMP_TRAS = `COALESCE(iva_traslado_mxn,0) + COALESCE(ieps_traslado_mxn,0) + COALESCE(impuestos_locales_trasladado_mxn,0)`; // I PUE recibidas const { rows: facturas } = await pool.query( `SELECT uuid, total_mxn, iva_traslado_mxn, cfdi_tipo_relacion, cfdis_relacionados, (COALESCE(total_mxn,0) - (${IMP_TRAS})) AS neto_normal FROM cfdis WHERE ${ctx.esReceptor} AND tipo_comprobante='I' AND metodo_pago='PUE' AND status NOT IN ('Cancelado','0') AND fecha_emision >= $1::date AND fecha_emision < ($2::date + interval '1 day') ORDER BY total_mxn DESC`, [fi, ff], ); console.log(`\n=== I PUE recibidas ${yearMonth} ===`); console.log(`# | UUID | total | IVA | neto_normal | rel | cfdis_relacionados`); for (const r of facturas) { const rel = r.cfdi_tipo_relacion || '-'; const cr = r.cfdis_relacionados ? ` → ${r.cfdis_relacionados.substring(0,36)}` : ''; console.log(` ${r.uuid.substring(0,8)} total=${Number(r.total_mxn).toFixed(2).padStart(12)} IVA=${Number(r.iva_traslado_mxn).toFixed(2).padStart(10)} neto=${Number(r.neto_normal).toFixed(2).padStart(12)} rel=${rel.padEnd(3)}${cr}`); } // I PUE recibidas con relación 07 — verificar si el anticipo está en otro mes const i07 = facturas.filter((r: any) => r.cfdi_tipo_relacion === '07'); if (i07.length > 0) { console.log(`\nI/07 recibidas en ${yearMonth}: ${i07.length}`); for (const r of i07) { const relsUuids = (r.cfdis_relacionados || '').split('|').filter(Boolean).map((u: string) => u.toLowerCase()); if (relsUuids.length > 0) { const { rows: rels } = await pool.query( `SELECT uuid, fecha_emision, total_mxn, iva_traslado_mxn FROM cfdis a WHERE LOWER(a.uuid) = ANY($1::text[]) AND a.status NOT IN ('Cancelado','0')`, [relsUuids], ); console.log(`\n I/07 ${r.uuid.substring(0,8)} total=${Number(r.total_mxn).toFixed(2)} IVA=${Number(r.iva_traslado_mxn).toFixed(2)}`); for (const a of rels) { const fecha = a.fecha_emision.toISOString().slice(0,10); const fuera = fecha.substring(0,7) !== yearMonth ? ' ← FUERA DEL MES' : ''; console.log(` anticipo ${a.uuid.substring(0,8)} fecha=${fecha} total=${Number(a.total_mxn).toFixed(2)} IVA=${Number(a.iva_traslado_mxn).toFixed(2)}${fuera}`); } } } } await prisma.$disconnect(); } main().catch(async e => { console.error(e); await prisma.$disconnect().catch(() => {}); process.exit(1); });