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
This commit is contained in:
66
api-gateway/scripts/importar-clientes-maestro.js
Executable file
66
api-gateway/scripts/importar-clientes-maestro.js
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user