feat(sat): factura global + fecha_efectiva, fallback tenant-contribuyente, fix anio_global typo
Factura Global & fecha_efectiva: - Migracion 045_factura_global.sql: periodicidad, meses_global, año_global, fecha_efectiva - sat-parser.service.ts: extrae InformacionGlobal del XML - sat.service.ts: calcFechaEfectiva con soporte bimestral (periodicidad 05) - metricas-compute, dashboard, impuestos, cfdi, export, conciliacion, alertas: reemplaza fecha_emision-1h por COALESCE(fecha_efectiva, fecha_emision-1h) - Script recalc-metricas.ts para recalculo manual Fallback datos fiscales tenant → contribuyente: - contribuyente.service.ts: fetchTenantFiscalData + mergeContribuyenteWithTenant rellena regimenFiscal, codigoPostal y domicilio cuando el contribuyente tiene el mismo RFC que el tenant y sus campos estan vacios - contribuyente.controller.ts y contribuyente-config.controller.ts: pasan req.user!.tenantId al servicio Fix critico SAT sync: - sat.service.ts: anio_global → año_global en INSERT/UPDATE de CFDIs (la migracion creo 'año_global' con tilde; el codigo usaba 'anio_global', causando fallo en 100% de inserciones de CFDI) - determineChunkMonths: salta sondeo si existe job previo con requestIds - MAX_POLL_ATTEMPTS: 45 → 500 (~8h) para syncs iniciales grandes Docs: - docs/sessions/2026-05-22-factura-global-contribuyente-fallback.md
This commit is contained in:
@@ -109,13 +109,13 @@ export const GRUPO_PM_OTROS = ['601', '603', '607', '608', '610', '611', '614',
|
||||
const TODOS_REGIMENES = [...GRUPO_PF_EMPRESARIAL, ...GRUPO_SUELDOS, ...GRUPO_PM_OTROS];
|
||||
|
||||
// Filtro de fecha por rango — normal o conciliación
|
||||
const FECHA_RANGO = `fecha_emision >= $1::date AND fecha_emision < ($2::date + interval '1 day')`;
|
||||
const FECHA_RANGO = `COALESCE(fecha_efectiva, fecha_emision - interval '1 hour') >= $1::date AND COALESCE(fecha_efectiva, fecha_emision - interval '1 hour') < ($2::date + interval '1 day')`;
|
||||
// Para CFDIs tipo P (complementos de pago): el ingreso/gasto se reconoce en la
|
||||
// fecha_pago_p (cuándo el cliente realmente pagó), no cuando se emitió el
|
||||
// complemento — el CFDI P puede emitirse hasta el día 5 del mes siguiente al
|
||||
// pago, o incluso después, y cruzar meses (ej. pago de noviembre 2024 con
|
||||
// complemento emitido en mayo 2025).
|
||||
const FECHA_PAGO_RANGO = `fecha_pago_p >= $1::date AND fecha_pago_p < ($2::date + interval '1 day')`;
|
||||
const FECHA_PAGO_RANGO = `(fecha_pago_p - interval '1 hour') >= $1::date AND (fecha_pago_p - interval '1 hour') < ($2::date + interval '1 day')`;
|
||||
const FECHA_RANGO_CONCILIACION = `id_conciliacion IS NOT NULL AND id_conciliacion IN (
|
||||
SELECT id FROM conciliaciones WHERE fecha_de_pago >= $1::date AND fecha_de_pago < ($2::date + interval '1 day')
|
||||
)`;
|
||||
@@ -989,14 +989,14 @@ export async function calcularIvaBalancePorRegimen(
|
||||
AND e.status NOT IN ('Cancelado', '0')
|
||||
AND ${esEmisor.replace(/\brfc_emisor\b/g, 'e.rfc_emisor')}
|
||||
AND LOWER(i.uuid) = ANY(string_to_array(LOWER(e.cfdis_relacionados), '|'))
|
||||
AND date_trunc('month', e.fecha_emision) = date_trunc('month', i.fecha_emision)
|
||||
AND date_trunc('month', COALESCE(e.fecha_efectiva, e.fecha_emision - interval '1 hour')) = date_trunc('month', COALESCE(i.fecha_efectiva, i.fecha_emision - interval '1 hour'))
|
||||
)), 0) as monto
|
||||
FROM cfdis i
|
||||
WHERE ${esEmisor.replace(/\brfc_emisor\b/g, 'i.rfc_emisor')}
|
||||
AND i.tipo_comprobante = 'I' AND i.metodo_pago = 'PPD'
|
||||
AND COALESCE(i.cfdi_tipo_relacion, '') = '07'
|
||||
AND i.status NOT IN ('Cancelado','0')
|
||||
AND ${FR.replace(/\bfecha_emision\b/g, 'i.fecha_emision')}
|
||||
AND ${FR.replace(/\bfecha_efectiva\b/g, 'i.fecha_efectiva').replace(/\bfecha_emision\b/g, 'i.fecha_emision')}
|
||||
AND i.regimen_fiscal_emisor = ANY($3)
|
||||
GROUP BY i.regimen_fiscal_emisor
|
||||
`, [fechaInicio, fechaFin, TODOS_REGIMENES]);
|
||||
@@ -1012,14 +1012,14 @@ export async function calcularIvaBalancePorRegimen(
|
||||
AND e.status NOT IN ('Cancelado', '0')
|
||||
AND ${esReceptor.replace(/\brfc_receptor\b/g, 'e.rfc_receptor')}
|
||||
AND LOWER(i.uuid) = ANY(string_to_array(LOWER(e.cfdis_relacionados), '|'))
|
||||
AND date_trunc('month', e.fecha_emision) = date_trunc('month', i.fecha_emision)
|
||||
AND date_trunc('month', COALESCE(e.fecha_efectiva, e.fecha_emision - interval '1 hour')) = date_trunc('month', COALESCE(i.fecha_efectiva, i.fecha_emision - interval '1 hour'))
|
||||
)), 0) as monto
|
||||
FROM cfdis i
|
||||
WHERE ${esReceptor.replace(/\brfc_receptor\b/g, 'i.rfc_receptor')}
|
||||
AND i.tipo_comprobante = 'I' AND i.metodo_pago = 'PPD'
|
||||
AND COALESCE(i.cfdi_tipo_relacion, '') = '07'
|
||||
AND i.status NOT IN ('Cancelado','0')
|
||||
AND ${FR.replace(/\bfecha_emision\b/g, 'i.fecha_emision')}
|
||||
AND ${FR.replace(/\bfecha_efectiva\b/g, 'i.fecha_efectiva').replace(/\bfecha_emision\b/g, 'i.fecha_emision')}
|
||||
AND i.regimen_fiscal_receptor = ANY($3)
|
||||
GROUP BY i.regimen_fiscal_receptor
|
||||
`, [fechaInicio, fechaFin, TODOS_REGIMENES]);
|
||||
|
||||
Reference in New Issue
Block a user