feat: employment office (#5)
* feat: add table employment office * feat: add tag * feat: add employment office * chore: migrations * feat: order employment office * feat: delete old employment office when special got added
This commit is contained in:
parent
22b3981aa7
commit
401d376a63
6 changed files with 171 additions and 1 deletions
|
|
@ -0,0 +1,26 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "EmploymentOffice" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"nameEN" TEXT NOT NULL,
|
||||
"provinceId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "EmploymentOffice_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "EmploymentOfficeDistrict" (
|
||||
"areaId" TEXT NOT NULL,
|
||||
"districtId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "EmploymentOfficeDistrict_pkey" PRIMARY KEY ("areaId","districtId")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EmploymentOffice" ADD CONSTRAINT "EmploymentOffice_provinceId_fkey" FOREIGN KEY ("provinceId") REFERENCES "Province"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EmploymentOfficeDistrict" ADD CONSTRAINT "EmploymentOfficeDistrict_areaId_fkey" FOREIGN KEY ("areaId") REFERENCES "EmploymentOffice"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EmploymentOfficeDistrict" ADD CONSTRAINT "EmploymentOfficeDistrict_districtId_fkey" FOREIGN KEY ("districtId") REFERENCES "District"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
|
@ -164,6 +164,7 @@ model Province {
|
|||
customerBranchCitizen CustomerBranchCitizen[]
|
||||
customerBranchHouseRegis CustomerBranchHouseRegis[]
|
||||
institution Institution[]
|
||||
employmentOffice EmploymentOffice[]
|
||||
}
|
||||
|
||||
model District {
|
||||
|
|
@ -187,6 +188,7 @@ model District {
|
|||
customerBranchCitizen CustomerBranchCitizen[]
|
||||
customerBranchHouseRegis CustomerBranchHouseRegis[]
|
||||
institution Institution[]
|
||||
employmentOffice EmploymentOfficeDistrict[]
|
||||
}
|
||||
|
||||
model SubDistrict {
|
||||
|
|
@ -212,6 +214,28 @@ model SubDistrict {
|
|||
institution Institution[]
|
||||
}
|
||||
|
||||
model EmploymentOffice {
|
||||
id String @id @default(cuid())
|
||||
|
||||
name String
|
||||
nameEN String
|
||||
|
||||
provinceId String
|
||||
province Province @relation(fields: [provinceId], references: [id])
|
||||
|
||||
district EmploymentOfficeDistrict[]
|
||||
}
|
||||
|
||||
model EmploymentOfficeDistrict {
|
||||
areaId String
|
||||
area EmploymentOffice @relation(fields: [areaId], references: [id])
|
||||
|
||||
districtId String
|
||||
district District @relation(fields: [districtId], references: [id])
|
||||
|
||||
@@id([areaId, districtId])
|
||||
}
|
||||
|
||||
enum Status {
|
||||
CREATED
|
||||
ACTIVE
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import express, { json, urlencoded } from "express";
|
|||
import error from "./middlewares/error";
|
||||
import morgan from "./middlewares/morgan";
|
||||
import { RegisterRoutes } from "./routes";
|
||||
import { initThailandAreaDatabase } from "./utils/thailand-area";
|
||||
import { initEmploymentOffice, initThailandAreaDatabase } from "./utils/thailand-area";
|
||||
import { initFirstAdmin } from "./utils/database";
|
||||
import { apiReference } from "@scalar/express-api-reference";
|
||||
import { initSchedule } from "./services/schedule";
|
||||
|
|
@ -17,6 +17,7 @@ const APP_PORT = +(process.env.APP_PORT || 3000);
|
|||
|
||||
await initThailandAreaDatabase();
|
||||
await initFirstAdmin();
|
||||
await initEmploymentOffice();
|
||||
|
||||
initSchedule();
|
||||
|
||||
|
|
|
|||
28
src/controllers/00-employment-office-controller.ts
Normal file
28
src/controllers/00-employment-office-controller.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { Controller, Get, Query, Route, Tags } from "tsoa";
|
||||
import prisma from "../db";
|
||||
|
||||
@Route("/api/v1/employment-office")
|
||||
@Tags("Employment Office")
|
||||
export class EmploymentOfficeController extends Controller {
|
||||
@Get()
|
||||
async getEmploymentOfficeList(@Query() districtId?: string) {
|
||||
return await prisma.employmentOffice.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
{
|
||||
province: {
|
||||
district: { some: { id: districtId } },
|
||||
},
|
||||
district: { none: {} },
|
||||
},
|
||||
{
|
||||
district: {
|
||||
some: { districtId },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
orderBy: [{ provinceId: "asc" }, { id: "asc" }],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -141,4 +141,94 @@ export async function initThailandAreaDatabase() {
|
|||
}),
|
||||
);
|
||||
});
|
||||
|
||||
console.log("[INFO]: Sync thailand province, district and subdistrict, OK.");
|
||||
}
|
||||
|
||||
export async function initEmploymentOffice() {
|
||||
const name = (provinceName: string) => `สำนักงานจัดหางานจังหวัด${provinceName}`;
|
||||
const nameEN = (provinceNameEN: string) => `${provinceNameEN} Employment Office`;
|
||||
const nameSpecial = (provinceName: string, areaNo: number) =>
|
||||
`สำนักงานจัดหางาน${provinceName} พื้นที่ ${areaNo}`;
|
||||
const nameSpecialEN = (provinceNameEN: string, areaNo: number) =>
|
||||
`${provinceNameEN} Employment Office Area ${areaNo}`;
|
||||
|
||||
const special: Record<string, { [key: string]: string[] }> = {
|
||||
"10": {
|
||||
"1": ["1004", "1007", "1012", "1028", "1031"],
|
||||
"2": ["1021", "1024", "1035", "1049", "1050"],
|
||||
"3": ["1009", "1032", "1033", "1034", "1039", "1047"],
|
||||
"4": ["1006", "1038", "1043", "1027", "1045"],
|
||||
"5": ["1003", "1010", "1011", "1042", "1044", "1046"],
|
||||
"6": ["1015", "1016", "1018", "1020", "1025"],
|
||||
"7": ["1019", "1022", "1023", "1040", "1048"],
|
||||
"8": ["1001", "1002", "1008", "1013"],
|
||||
"9": ["1005", "1029", "1030", "1041"],
|
||||
"10": ["1014", "1017", "1026", "1036", "1037"],
|
||||
},
|
||||
};
|
||||
|
||||
const list = await prisma.province.findMany();
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await Promise.all(
|
||||
list
|
||||
.map(async (province) => {
|
||||
if (special[province.id]) {
|
||||
await tx.employmentOffice.deleteMany({
|
||||
where: { provinceId: province.id, district: { none: {} } },
|
||||
});
|
||||
return Object.entries(special[province.id]).map(([key, val]) => {
|
||||
const id = province.id + "-" + key.padStart(2, "0");
|
||||
return tx.employmentOffice.upsert({
|
||||
where: { id },
|
||||
create: {
|
||||
id,
|
||||
name: nameSpecial(province.name, +key),
|
||||
nameEN: nameSpecialEN(province.nameEN, +key),
|
||||
provinceId: province.id,
|
||||
district: {
|
||||
createMany: {
|
||||
data: val.map((districtId) => ({ districtId })),
|
||||
skipDuplicates: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
update: {
|
||||
id,
|
||||
name: nameSpecial(province.name, +key),
|
||||
nameEN: nameSpecialEN(province.nameEN, +key),
|
||||
provinceId: province.id,
|
||||
district: {
|
||||
deleteMany: { districtId: { notIn: val } },
|
||||
createMany: {
|
||||
data: val.map((districtId) => ({ districtId })),
|
||||
skipDuplicates: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return tx.employmentOffice.upsert({
|
||||
where: { id: province.id },
|
||||
create: {
|
||||
id: province.id,
|
||||
name: name(province.name),
|
||||
nameEN: nameEN(province.nameEN),
|
||||
provinceId: province.id,
|
||||
},
|
||||
update: {
|
||||
name: name(province.name),
|
||||
nameEN: nameEN(province.nameEN),
|
||||
provinceId: province.id,
|
||||
},
|
||||
});
|
||||
})
|
||||
.flat(),
|
||||
);
|
||||
});
|
||||
|
||||
console.log("[INFO]: Sync employment office, OK.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
{ "name": "Notification" },
|
||||
{ "name": "Permission" },
|
||||
{ "name": "Address" },
|
||||
{ "name": "Employment Office" },
|
||||
{ "name": "Branch" },
|
||||
{ "name": "User" },
|
||||
{ "name": "Branch User" },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue