import { parse } from "csv-parse"; import fs from "fs"; import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient({ datasourceUrl: process.env.TEST_DATABASE_URL || process.env.DATABASE_URL, }); type CsvRow = { customerType: string; status: string; statusOrder: string; branchCode: string; branchTaxNo: string; branchName: string; branchNameEN: string; code: string; legalPersonNo: string; registerName: string; registerNameEN: string; registerDate: string; authorizedCapital: string; authorizedName: string; authorizedNameEN: string; email: string; telephoneNo: string; employmentOffice: string; employmentOfficeEN: string; officeTel: string; jobPosition: string; jobDescription: string; payDate: string; payDateEN: string; wageRate: string; wageRateText: string; namePrefix: string; firstName: string; firstNameEN: string; lastName: string; lastNameEN: string; contactName: string; contactTel: string; gender: string; birthDate: string; address: string; addressEN: string; moo: string; mooEN: string; soi: string; soiEN: string; street: string; streetEN: string; subDistrict: string; district: string; province: string; zipcode: string; homeCode: string; lineId: string; }; async function importCsv(filePath: string) { const parser = fs.createReadStream(filePath).pipe(parse({ columns: true, trim: true })); const rows: CsvRow[] = []; for await (const row of parser) { rows.push(row as CsvRow); } // ✅ 1. ดึง subDistrict ล่วงหน้า const subDistricts = [...new Set(rows.map((r) => r.subDistrict).filter(Boolean))]; const searchAddr = await prisma.subDistrict.findMany({ where: { name: { in: subDistricts }, }, include: { district: { include: { province: true, }, }, }, }); const sdtDtPv = new Map< string, { subDistrictId: string; districtId: string; provinceId: string } >(); for (const s of searchAddr) { if (!s.zipCode) continue; sdtDtPv.set(s.zipCode, { subDistrictId: s.id, districtId: s.districtId, provinceId: s.district.provinceId, }); } // ✅ cache branch ที่สร้างแล้วเพื่อลด query const branchCache = new Map(); for (const row of rows) { // หา province/district/subdistrict จาก zipcode const addr = sdtDtPv.get(row.zipcode); let branchId = branchCache.get(row.branchCode); if (!branchId) { let registeredBranch = await prisma.branch.findFirst({ where: { code: row.branchCode, name: row.branchName, }, }); if (!registeredBranch) { registeredBranch = await prisma.branch.create({ data: { code: row.branchCode, taxNo: row.branchTaxNo || "-", name: row.branchName, nameEN: row.branchNameEN || row.branchName, telephoneNo: row.telephoneNo || "-", permitNo: "-", address: row.address || "-", addressEN: row.addressEN || row.address || "-", email: row.email || "-", latitude: "0", longitude: "0", headOfficeId: "DEFAULT_HEAD_OFFICE_ID", status: "CREATED", statusOrder: 0, }, }); } branchId = registeredBranch.id; branchCache.set(row.branchCode, branchId); } // ✅ Create customer const customer = await prisma.customer.create({ data: { customerType: row.customerType as any, status: row.status as any, statusOrder: Number(row.statusOrder) || 0, registeredBranch: { connect: { id: branchId }, }, }, }); // ✅ Create CustomerBranch await prisma.customerBranch.create({ data: { customerId: customer.id, code: row.code || "-", codeCustomer: row.legalPersonNo || "-", telephoneNo: row.telephoneNo || "-", namePrefix: row.namePrefix || null, firstName: row.firstName || null, firstNameEN: row.firstNameEN || null, lastName: row.lastName || null, lastNameEN: row.lastNameEN || null, gender: row.gender || null, birthDate: row.birthDate ? new Date(row.birthDate) : null, citizenId: row.legalPersonNo || null, legalPersonNo: row.legalPersonNo || null, registerName: row.registerName || null, registerNameEN: row.registerNameEN || null, registerDate: row.registerDate ? new Date(row.registerDate) : null, authorizedCapital: row.authorizedCapital || null, authorizedName: row.authorizedName || null, authorizedNameEN: row.authorizedNameEN || null, homeCode: row.homeCode || "-", employmentOffice: row.employmentOffice || "-", employmentOfficeEN: row.employmentOfficeEN || "-", // Address address: row.address || "-", addressEN: row.addressEN || "-", soi: row.soi || null, soiEN: row.soiEN || null, moo: row.moo || null, mooEN: row.mooEN || null, street: row.street || null, streetEN: row.streetEN || null, provinceId: addr?.provinceId, districtId: addr?.districtId, subDistrictId: addr?.subDistrictId, // Contact email: row.email || "-", contactTel: row.contactTel || "-", officeTel: row.officeTel || "-", contactName: row.contactName || "-", jobPosition: row.jobPosition || "-", jobDescription: row.jobDescription || "-", payDate: row.payDate || "-", payDateEN: row.payDateEN || "-", wageRate: parseInt(row.wageRate || "0", 10), wageRateText: row.wageRateText || "-", }, }); console.log(`✅ Inserted customer ${customer.id} with branch ${branchId}`); } } importCsv("/home/hamu/Documents/JWS import.csv").then(() => { console.log("Import finished ✅"); });