Files
HoruxDespachosNuevo/apps/api/scripts/backfill-pago-fields.ts

79 lines
2.8 KiB
TypeScript

/**
* Backfill: re-parsea CFDIs tipo P emitidos vía Facturapi (source='facturapi')
* que tienen `monto_pago_mxn` o `fecha_pago_p` NULL, y popula esos campos
* desde el XML original. Bug histórico — el INSERT de facturapi.controller.ts
* no incluía los campos del complemento Pagos hasta el fix de hoy.
*
* Idempotente — solo actualiza si el XML tiene datos y el row tiene NULL.
*/
import { prisma, tenantDb } from '../src/config/database.js';
import { parseXml } from '../src/services/sat/sat-parser.service.js';
async function main() {
const tenants = await prisma.tenant.findMany({
where: { active: true },
select: { id: true, rfc: true, nombre: true, databaseName: true },
});
let totalUpdated = 0;
let totalChecked = 0;
for (const t of tenants) {
const pool = await tenantDb.getPool(t.id, t.databaseName);
const { rows } = await pool.query(`
SELECT uuid, xml_original
FROM cfdis
WHERE source = 'facturapi'
AND tipo_comprobante = 'P'
AND xml_original IS NOT NULL
AND (monto_pago_mxn IS NULL OR fecha_pago_p IS NULL)
`);
if (rows.length === 0) continue;
console.log(`\n>>> ${t.rfc} (${t.nombre}): ${rows.length} P por backfill`);
for (const r of rows) {
totalChecked++;
const parsed = parseXml(r.xml_original, 'emitidos');
if (!parsed || parsed.tipoComprobante !== 'P') continue;
const fechaPagoP = parsed.fechaPagoP
? new Date(String(parsed.fechaPagoP).split('|')[0])
: null;
if (!parsed.montoPago && !fechaPagoP) {
console.log(` ${r.uuid}: XML sin datos de Pago — skip`);
continue;
}
await pool.query(`
UPDATE cfdis SET
monto_pago = COALESCE(monto_pago, $1),
monto_pago_mxn = COALESCE(monto_pago_mxn, $1),
fecha_pago_p = COALESCE(fecha_pago_p, $2),
iva_traslado_pago = COALESCE(iva_traslado_pago, $3),
iva_traslado_pago_mxn = COALESCE(iva_traslado_pago_mxn, $3),
iva_retencion_pago = COALESCE(iva_retencion_pago, $4),
iva_retencion_pago_mxn = COALESCE(iva_retencion_pago_mxn, $4),
ieps_traslado_pago = COALESCE(ieps_traslado_pago, $5),
ieps_traslado_pago_mxn = COALESCE(ieps_traslado_pago_mxn, $5)
WHERE uuid = $6
`, [
parsed.montoPago || 0,
fechaPagoP,
parsed.ivaTrasladoPago || 0,
parsed.ivaRetencionPago || 0,
parsed.iepsTrasladoPago || 0,
r.uuid,
]);
totalUpdated++;
console.log(` ${r.uuid}: ✓ monto=$${parsed.montoPago} fecha_pago=${fechaPagoP?.toISOString().slice(0, 10)} iva=$${parsed.ivaTrasladoPago}`);
}
}
console.log(`\n[Backfill] Completado: ${totalUpdated}/${totalChecked} actualizadas`);
await prisma.$disconnect();
}
main().catch(e => { console.error(e); process.exit(1); });