Files
FRASA-CAS/api-gateway/scripts/importar-clientes-maestro.js
Consult AS Technology 9021733455 feat(clientes-maestro): importar y exportar clientes del archivo maestro
- Tabla ClienteMaestro (27 campos, unique numCliente)
- Importador Excel: 1535 clientes del Reporte maestro
- API: listar/filtros/exportar/detalle/importar
- Frontend: tabla paginada, filtros, exportar Excel
- Dark mode completo, 52 tests verdes
2026-09-07 09:11:09 +00:00

67 lines
1.9 KiB
JavaScript
Executable File

#!/usr/bin/env node
import { PrismaClient } from '@prisma/client'
import XLSX from 'xlsx'
const prisma = new PrismaClient()
const toStr = (v) => v == null ? null : String(v).trim() || null
const toNum = (v) => {
if (v == null) return null
const n = Number(String(v).replace(/[$,\s]/g, ''))
return Number.isFinite(n) ? n : null
}
const wb = XLSX.readFile('/root/Reporte maestro de clientesAGO26.xlsx')
const rows = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1, defval: null })
console.log(`Filas: ${rows.length}`)
const map = new Map()
for (let i = 1; i < rows.length; i++) {
const nc = toStr(rows[i][0])
if (nc) map.set(nc, rows[i])
}
console.log(`Clientes: ${map.size}`)
let ok = 0, fail = 0
let idx = 0
for (const [nc, r] of map) {
idx++
const d = {
numCliente: nc,
nombre: toStr(r[1]) || 'SIN NOMBRE',
apellidoPaterno: toStr(r[2]) || '',
apellidoMaterno: toStr(r[3]),
sexo: toStr(r[4]),
telefono: toStr(r[5]),
email: toStr(r[6]),
estadoCivil: toStr(r[7]),
rangoEdad: toStr(r[8]),
ocupacion: toStr(r[16]),
rangoIngresos: toStr(r[15]),
credito: toStr(r[10]),
institucion: toStr(r[11]),
medioContacto: toStr(r[13]),
canal: toStr(r[14]),
desarrollo: toStr(r[19]),
manzana: toStr(r[20]),
lote: toStr(r[21]),
interior: toStr(r[22]),
tipoCasa: toStr(r[24]),
etapa: toStr(r[27]),
valorTotal: toNum(r[26]),
estatus: toStr(r[27]),
fechaLiberacion: r[28] instanceof Date ? r[28] : null,
vendedor: toStr(r[29]),
vendedorId: toStr(r[30]),
}
try {
await prisma.clienteMaestro.upsert({ where: { numCliente: nc }, update: d, create: d })
ok++
} catch (e) {
fail++
if (fail <= 5) console.log(`ERR ${nc}: ${e.message.slice(0, 120)}`)
}
if (idx % 500 === 0) console.log(` ${idx}/${map.size} ok=${ok} fail=${fail}`)
}
console.log(`\nListo: ${ok} ok, ${fail} fail / ${map.size}`)
await prisma.$disconnect()