fix(sat, payments, admin): multiple production fixes
- sat sweep-stale-jobs: increase initial/custom sync threshold 8h→24h to prevent watchdog killing long historical syncs - sat-client: fix formatDateForSat same-day rejection by auto-adjusting fechaFin - sat-sync job: check fiel_contribuyente in addition to fiel_credentials for cron eligibility - database: extend pool idle cleanup from 5min to 12h to prevent pool closure during long syncs - webhook controller: auto-extend currentPeriodEnd on recurring MercadoPago payments - invoicing service: auto-send FacturAPI invoice by email after creation - admin-clientes: fix no-renovaciones detection to include expired trials and deleted subscriptions
This commit is contained in:
@@ -21,19 +21,50 @@ const EXPIRY_REMINDERS_CRON = '0 9 * * *'; // 9:00 AM diario — avisos p
|
||||
let isRunning = false;
|
||||
let isIncrementalRunning = false;
|
||||
|
||||
/**
|
||||
* Verifica si un tenant tiene FIEL a nivel tenant (legacy Horux 360)
|
||||
* o a nivel contribuyente (modelo despacho).
|
||||
*/
|
||||
async function hasAnyFielConfigured(tenantId: string, databaseName?: string | null): Promise<boolean> {
|
||||
// 1) FIEL legacy a nivel tenant
|
||||
const hasLegacy = await hasFielConfigured(tenantId);
|
||||
if (hasLegacy) return true;
|
||||
|
||||
// 2) FIEL por contribuyente (modelo despacho)
|
||||
if (!databaseName) {
|
||||
const tenant = await prisma.tenant.findUnique({
|
||||
where: { id: tenantId },
|
||||
select: { databaseName: true },
|
||||
});
|
||||
databaseName = tenant?.databaseName;
|
||||
}
|
||||
if (!databaseName) return false;
|
||||
|
||||
try {
|
||||
const pool = await tenantDb.getPool(tenantId, databaseName);
|
||||
const { rows } = await pool.query(
|
||||
`SELECT 1 FROM fiel_contribuyente WHERE is_active = true LIMIT 1`
|
||||
);
|
||||
return rows.length > 0;
|
||||
} catch (err: any) {
|
||||
console.error(`[SAT Cron] Error verificando FIEL contribuyente para tenant ${tenantId}:`, err.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los tenants que tienen FIEL configurada y activa
|
||||
*/
|
||||
async function getTenantsWithFiel(): Promise<string[]> {
|
||||
const tenants = await prisma.tenant.findMany({
|
||||
where: { active: true },
|
||||
select: { id: true },
|
||||
select: { id: true, databaseName: true },
|
||||
});
|
||||
|
||||
const tenantsWithFiel: string[] = [];
|
||||
|
||||
for (const tenant of tenants) {
|
||||
const hasFiel = await hasFielConfigured(tenant.id);
|
||||
const hasFiel = await hasAnyFielConfigured(tenant.id, tenant.databaseName);
|
||||
if (hasFiel) {
|
||||
tenantsWithFiel.push(tenant.id);
|
||||
}
|
||||
@@ -172,12 +203,12 @@ async function getTenantsConSatIncremental(): Promise<string[]> {
|
||||
|
||||
const tenants = await prisma.tenant.findMany({
|
||||
where: { active: true, plan: { in: planNames as any } },
|
||||
select: { id: true },
|
||||
select: { id: true, databaseName: true },
|
||||
});
|
||||
|
||||
const result: string[] = [];
|
||||
for (const tenant of tenants) {
|
||||
if (await hasFielConfigured(tenant.id)) {
|
||||
if (await hasAnyFielConfigured(tenant.id, tenant.databaseName)) {
|
||||
result.push(tenant.id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user