218 lines
5.9 KiB
TypeScript
218 lines
5.9 KiB
TypeScript
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<string, string>();
|
|
|
|
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 ✅");
|
|
});
|