diff --git a/api-gateway/scripts/importar-cobranza-preventa.js b/api-gateway/scripts/importar-cobranza-preventa.js new file mode 100755 index 0000000..2174d2e --- /dev/null +++ b/api-gateway/scripts/importar-cobranza-preventa.js @@ -0,0 +1,128 @@ +#!/usr/bin/env node +/** + * Importa el archivo COBRANZA PREVENTA a PlanPago + Pago. + * Lee cada hoja de desarrollo, extrae clientes y sus pagos mensuales. + */ +import { PrismaClient } from '@prisma/client' +import XLSX from 'xlsx' + +const prisma = new PrismaClient() +const toStr = (v) => v == null ? null : String(v).trim() || null +const toFloat = (v) => { + if (v == null) return null + if (typeof v === 'number') return v + const n = parseFloat(String(v).replace(/[$,\s]/g, '')) + return Number.isFinite(n) ? n : null +} +const toDate = (v) => { + if (v == null) return null + if (v instanceof Date) return v + const n = Date.parse(String(v).trim()) + return isNaN(n) ? null : new Date(n) +} + +const DESARROLLOS = ['ZAFIRO', 'MUTUO', 'SOLE', 'ATELIER', 'ESTANZA', 'SOLANA I', 'SOLANA II', 'UMBRAL', 'DIAGONAL 40', 'SENDA'] + +const ruta = '/root/COBRANZA PREVENTA 060926.xlsx' +console.log(`Leyendo: ${ruta}`) +const wb = XLSX.readFile(ruta) + +let totalPlanes = 0, totalPagos = 0, errores = 0 + +for (const nombreHoja of DESARROLLOS) { + const sheet = wb.Sheets[nombreHoja] + if (!sheet) { console.log(` Hoja "${nombreHoja}" no encontrada, saltando`); continue } + + const rows = XLSX.utils.sheet_to_json(sheet, { header: 1, defval: null }) + console.log(`\n ${nombreHoja}: ${rows.length} filas`) + + // Header row is typically row 2 (index 2), data starts at row 3 (index 3) + // Find the header row with 'NOMBRE' or 'CTE' + let headerIdx = -1 + for (let i = 0; i < Math.min(rows.length, 5); i++) { + if (rows[i]?.[2] && String(rows[i][2]).includes('NOMBRE')) { + headerIdx = i + break + } + } + if (headerIdx === -1) { + console.log(` No se encontrĂ³ header en ${nombreHoja}, saltando`) + continue + } + + const dataRows = rows.slice(headerIdx + 1) + let hojaPlanes = 0, hojaPagos = 0 + + for (const row of dataRows) { + const unidadCodigo = toStr(row[0]) + const clienteId = toStr(row[1]) + const clienteNombre = toStr(row[2]) + if (!clienteNombre || clienteNombre.length < 3) continue + + const precioVenta = toFloat(row[3]) || 0 + const fechaVenta = toDate(row[4]) + const tipoVenta = toStr(row[5]) || '' + const asesor = toStr(row[6]) || '' + const apartadoPagado = toFloat(row[10]) || 0 + const enganchePagado = toFloat(row[11]) || 0 + const meses = parseInt(String(row[13] || '0')) || 0 + const mesInicio = toDate(row[14]) + const mensualidad = toFloat(row[16]) || 0 + const totalPagado = toFloat(row[58]) || 0 + + // Create PlanPago + try { + const plan = await prisma.planPago.create({ + data: { + ventaRef: clienteId || null, + clienteNombre, + clienteTelefono: null, + unidadCodigo: unidadCodigo || '', + proyecto: nombreHoja, + fechaInicio: mesInicio || fechaVenta || new Date(), + engancheTotal: apartadoPagado + enganchePagado, + numPagos: meses || 1, + mensualidad, + tasaMoraMensual: 0, + status: 'ACTIVO', + vendedorId: null, + }, + }) + hojaPlanes++ + + // Create Pago records for each month with a value + let numPago = 1 + for (let col = 20; col <= 43; col++) { + const montoMes = toFloat(row[col]) + if (montoMes && montoMes > 0) { + // Calculate date for this payment month + const fechaMes = new Date(2025, 7 + (col - 20), 1) // Starting from Aug 2025 + await prisma.pago.create({ + data: { + planId: plan.id, + numPago, + fechaVencimiento: fechaMes, + monto: montoMes, + montoPagado: 0, // Will be updated if we have payment data + }, + }) + hojaPagos++ + numPago++ + } + } + } catch (err) { + errores++ + if (errores <= 3) console.log(` Error: ${clienteNombre} - ${err.message?.slice(0, 100)}`) + } + } + totalPlanes += hojaPlanes + totalPagos += hojaPagos + console.log(` ${hojaPlanes} planes, ${hojaPagos} pagos`) +} + +console.log(`\n=== Resumen ===`) +console.log(`Planes creados: ${totalPlanes}`) +console.log(`Pagos creados: ${totalPagos}`) +console.log(`Errores: ${errores}`) + +await prisma.$disconnect()