feat: add bulk import endpoint
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
import { CreatePermitInput, UpdatePermitInput } from "./permit.schema";
|
||||
import {
|
||||
bulkImport,
|
||||
createPermit,
|
||||
deletePermit,
|
||||
getPermit,
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
updatePermit,
|
||||
} from "./permit.service";
|
||||
import { PageQueryParams } from "../pagination";
|
||||
import { csv2json } from "json-2-csv";
|
||||
|
||||
export async function createPermitHandler(
|
||||
req: FastifyRequest,
|
||||
@@ -117,3 +119,20 @@ export async function searchPermitByAddressHandler(
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function bulkImportHandler(
|
||||
req: FastifyRequest,
|
||||
res: FastifyReply
|
||||
) {
|
||||
try {
|
||||
const data = await req.file();
|
||||
const csvString = (await data.toBuffer()).toString("utf-8");
|
||||
|
||||
const parsedCSV = csv2json(csvString, { delimiter: { eol: "\r\n" } });
|
||||
const result = await bulkImport(parsedCSV, req.user);
|
||||
|
||||
return res.code(200).send(result);
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import {
|
||||
bulkImportHandler,
|
||||
createPermitHandler,
|
||||
deletePermitHandler,
|
||||
getPermitHandler,
|
||||
@@ -138,6 +139,15 @@ export async function permitRoutes(fastify: FastifyInstance) {
|
||||
}
|
||||
);
|
||||
|
||||
fastify.post(
|
||||
"/bulkImport",
|
||||
{
|
||||
config: { requiredClaims: ["permit:write"] },
|
||||
preHandler: [fastify.authorize],
|
||||
},
|
||||
bulkImportHandler
|
||||
);
|
||||
|
||||
await noteRoutes(fastify);
|
||||
|
||||
fastify.addHook("onSend", hideFields("permits"));
|
||||
|
||||
@@ -110,6 +110,7 @@ const permitSchema = new mongoose.Schema({
|
||||
relationship: String,
|
||||
type_text: String,
|
||||
},
|
||||
importFlag: Boolean,
|
||||
});
|
||||
|
||||
permitSchema.index({ tenantId: 1, permitNumber: 1 }, { unique: true });
|
||||
|
||||
@@ -518,3 +518,96 @@ export async function searchPermitByAddress(address: string) {
|
||||
.sort({ score: { $meta: "textScore" } })
|
||||
.limit(1);
|
||||
}
|
||||
|
||||
export async function bulkImport(csvData: Object[], user: AuthenticatedUser) {
|
||||
const allowedFields = [
|
||||
"Permit Number",
|
||||
"County",
|
||||
"Client",
|
||||
"Address",
|
||||
"Open Date",
|
||||
"County Status",
|
||||
"Record Type",
|
||||
"Lot",
|
||||
"Block",
|
||||
"Job Number",
|
||||
"Community Name",
|
||||
];
|
||||
|
||||
const failed = [];
|
||||
const created = [];
|
||||
|
||||
for (const [index, record] of csvData.entries()) {
|
||||
try {
|
||||
if (!record["Permit Number"]) {
|
||||
failed.push(index);
|
||||
continue;
|
||||
}
|
||||
|
||||
const permitInDb = await permitModel.findOne({
|
||||
permitNumber: record["Permit Number"],
|
||||
});
|
||||
|
||||
if (!permitInDb) {
|
||||
let clientData = null;
|
||||
let countyData = null;
|
||||
|
||||
if (record["Client"]) {
|
||||
const clientInDb = await orgModel.findOne({ name: record["Client"] });
|
||||
if (clientInDb) {
|
||||
clientData = {
|
||||
id: clientInDb._id,
|
||||
pid: clientInDb.pid,
|
||||
licenseNumber: clientInDb.licenseNumber,
|
||||
name: clientInDb.name,
|
||||
avatar: clientInDb.avatar,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (record["County"]) {
|
||||
const countyInDb = await orgModel.findOne({ name: record["County"] });
|
||||
if (countyInDb) {
|
||||
countyData = {
|
||||
id: countyInDb._id,
|
||||
pid: countyInDb.pid,
|
||||
name: countyInDb.name,
|
||||
avatar: countyInDb.avatar,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const newPermit = await permitModel.create({
|
||||
tenantId: user.tenantId,
|
||||
pid: generateId(),
|
||||
permitNumber: record["Permit Number"],
|
||||
county: countyData,
|
||||
client: clientData?.id,
|
||||
clientData: clientData,
|
||||
cleanStatus: record["County Status"],
|
||||
address: record["Address"],
|
||||
recordType: record["Record Type"],
|
||||
lot: record["Lot"],
|
||||
block: record["Block"],
|
||||
jobNumber: record["Job Number"],
|
||||
communityName: record["Community Name"],
|
||||
createdAt: new Date(),
|
||||
createdBy: user.userId,
|
||||
importFlag: true,
|
||||
});
|
||||
|
||||
const populatedPermit = await newPermit.populate({
|
||||
path: "assignedTo createdBy",
|
||||
select: "pid name avatar",
|
||||
});
|
||||
|
||||
created.push(populatedPermit);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
failed.push(index + 2);
|
||||
}
|
||||
}
|
||||
|
||||
return { created, failed, allowedFields };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user