jws-backend/importData.ts
2026-01-12 14:47:19 +07:00

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 ✅");
});