diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 59bae3b..c358c91 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,9 +7,9 @@ on: workflow_dispatch: env: REGISTRY: docker.frappet.com - IMAGE_NAME: ehr/bma-ehr-org-service - DEPLOY_HOST: 192.168.1.80 - COMPOSE_PATH: /home/frappet/docker/bma-ehr + IMAGE_NAME: ehr/bma-ehr-development-service + DEPLOY_HOST: 49.0.91.80 + COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-development jobs: # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=test-v1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd release-test: @@ -59,11 +59,11 @@ jobs: host: ${{env.DEPLOY_HOST}} username: frappet password: ${{ secrets.SSH_PASSWORD }} - port: 22 + port: 10102 script: | cd "${{env.COMPOSE_PATH}}" - docker-compose pull - docker-compose up -d + docker compose pull + docker compose up -d echo "${{ steps.gen_ver.outputs.image_ver }}"> success - uses: snow-actions/line-notify@v1.1.0 if: success() @@ -73,7 +73,7 @@ jobs: -Success✅✅✅ Image: ${{env.IMAGE_NAME}} Version: ${{ steps.gen_ver.outputs.IMAGE_VER }} - By: ${{secrets.DOCKER_USER}} + By: ${{github.actor}} - uses: snow-actions/line-notify@v1.1.0 if: failure() with: @@ -82,4 +82,5 @@ jobs: -Failure❌❌❌ Image: ${{env.IMAGE_NAME}} Version: ${{ steps.gen_ver.outputs.IMAGE_VER }} - By: ${{secrets.DOCKER_USER}} + By: ${{github.actor}} + diff --git a/package-lock.json b/package-lock.json index 303f4cb..3fd41e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@tsoa/runtime": "^6.0.0", + "axios": "^1.6.8", "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", @@ -520,6 +521,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -531,6 +537,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -967,6 +983,17 @@ "resolved": "https://registry.npmjs.org/colors-console/-/colors-console-1.0.3.tgz", "integrity": "sha512-Q31K32UwadWqAxs+Iu46gNm4HJqUwrTJT2zen5NnhkKE5w7uqeZQZiuODUOxM/zOtHfiUTkia0io6zbN/VcCUQ==" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -1112,6 +1139,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -1497,6 +1532,25 @@ "node": ">= 0.8" } }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1520,6 +1574,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3067,6 +3134,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", diff --git a/package.json b/package.json index f5a8240..b530886 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "dependencies": { "@tsoa/runtime": "^6.0.0", + "axios": "^1.6.8", "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", diff --git a/src/controllers/DevelopmentController.ts b/src/controllers/DevelopmentController.ts index baaada6..451a952 100644 --- a/src/controllers/DevelopmentController.ts +++ b/src/controllers/DevelopmentController.ts @@ -11,20 +11,34 @@ import { Path, Request, Query, - Example + Example, } from "tsoa"; import { AppDataSource } from "../database/data-source"; -import { In, Not, MoreThan, Brackets, Like, MoreThanOrEqual, } from "typeorm"; +import { Not } from "typeorm"; import HttpSuccess from "../interfaces/http-success"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; import { Development, CreateDevelopment, UpdateDevelopment } from "../entities/Development"; +import { ActualPeople } from "../entities/ActualPeople"; +import { PlannedPeople } from "../entities/PlannedPeople"; +import { ActualGoal } from "../entities/ActualGoal"; +import { PlannedGoal } from "../entities/PlannedGoal"; +import { Province } from "../entities/Province"; +import { PosType } from "../entities/PosType"; +import { PosLevel } from "../entities/PosLevel"; @Route("api/v1/development/main") @Tags("Development") @Security("bearerAuth") export class DevelopmentController extends Controller { private developmentRepository = AppDataSource.getRepository(Development); + private actualPeopleRepository = AppDataSource.getRepository(ActualPeople); + private plannedPeopleRepository = AppDataSource.getRepository(PlannedPeople); + private actualGoalRepository = AppDataSource.getRepository(ActualGoal); + private plannedGoalRepository = AppDataSource.getRepository(PlannedGoal); + private provinceRepository = AppDataSource.getRepository(Province); + private posTypeRepository = AppDataSource.getRepository(PosType); + private posLevelRepository = AppDataSource.getRepository(PosLevel); /** * API เพิ่มโครงการ/หลักสูตรการฝึกอบรม @@ -33,35 +47,127 @@ export class DevelopmentController extends Controller { * */ @Post() - @Example({ - name: "", - year: 2024, - }) async CreateDevelopment( @Body() requestBody: CreateDevelopment, @Request() request: { user: Record }, ) { - const development = Object.assign(new Development(), requestBody); - if (!development) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); - } const chk_name = await this.developmentRepository.find({ - where: { - name: requestBody.name, - year: requestBody.year + where: { + projectName: requestBody.projectName, + year: requestBody.year, }, }); if (chk_name.length > 0) { throw new HttpError( - HttpStatusCode.NOT_FOUND, - "โครงการ/หลักสูตรการฝึกอบรม: " + requestBody.name + " ปีงบประมาณ: " + requestBody.year + " มีอยู่ในระบบแล้ว", + HttpStatusCode.NOT_FOUND, + "โครงการ/หลักสูตรการฝึกอบรม: " + + requestBody.projectName + + " ปีงบประมาณ: " + + requestBody.year + + " มีอยู่ในระบบแล้ว", ); } + + if (requestBody.provinceId != null) { + const checkId = await this.provinceRepository.findOne({ + where: { id: requestBody.provinceId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลจังหวัดสถานที่ดำเนินการ"); + } + } + if (requestBody.provinceActualId != null) { + const checkId = await this.provinceRepository.findOne({ + where: { id: requestBody.provinceActualId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลจังหวัดข้อมูลด้านวิชาการ"); + } + } + + const development = Object.assign(new Development(), requestBody); + development.createdUserId = request.user.sub; development.createdFullName = request.user.name; development.lastUpdateUserId = request.user.sub; development.lastUpdateFullName = request.user.name; await this.developmentRepository.save(development); + await Promise.all( + requestBody.actualPeoples.map(async (x) => { + const data = Object.assign(new ActualPeople(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentActualPeopleId = development.id; + await this.actualPeopleRepository.save(data); + }), + ); + await Promise.all( + requestBody.plannedPeoples.map(async (x) => { + const data = Object.assign(new PlannedPeople(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentPlannedPeopleId = development.id; + await this.plannedPeopleRepository.save(data); + }), + ); + await Promise.all( + requestBody.actualGoals.map(async (x) => { + if (x.posTypeActualId != null) { + const checkId = await this.posTypeRepository.findOne({ + where: { id: x.posTypeActualId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่ง"); + } + } + if (x.posLevelActualId != null) { + const checkId = await this.posLevelRepository.findOne({ + where: { id: x.posLevelActualId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่ง"); + } + } + const data = Object.assign(new ActualGoal(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentActualGoalId = development.id; + await this.actualGoalRepository.save(data); + }), + ); + await Promise.all( + requestBody.plannedGoals.map(async (x) => { + if (x.posTypePlannedId != null) { + const checkId = await this.posTypeRepository.findOne({ + where: { id: x.posTypePlannedId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่ง"); + } + } + if (x.posLevelPlannedId != null) { + const checkId = await this.posLevelRepository.findOne({ + where: { id: x.posLevelPlannedId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่ง"); + } + } + const data = Object.assign(new PlannedGoal(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentPlannedGoalId = development.id; + await this.plannedGoalRepository.save(data); + }), + ); return new HttpSuccess(development.id); } @@ -78,27 +184,135 @@ export class DevelopmentController extends Controller { @Body() requestBody: UpdateDevelopment, @Request() request: { user: Record }, ) { - const development = await this.developmentRepository.findOne({ where: { id } }); + const development = await this.developmentRepository.findOne({ + where: { id }, + relations: { + developmentActualPeoples: true, + developmentPlannedPeoples: true, + developmentActualGoals: true, + developmentPlannedGoals: true, + }, + }); if (!development) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงการ/หลักสูตรการฝึกอบรมนี้"); } + if (requestBody.provinceId != null) { + const checkId = await this.provinceRepository.findOne({ + where: { id: requestBody.provinceId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลจังหวัดสถานที่ดำเนินการ"); + } + } + if (requestBody.provinceActualId != null) { + const checkId = await this.provinceRepository.findOne({ + where: { id: requestBody.provinceActualId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลจังหวัดข้อมูลด้านวิชาการ"); + } + } const chk_name = await this.developmentRepository.find({ - where: { - name: requestBody.name, + where: { + projectName: requestBody.projectName, year: requestBody.year, - id: Not(id) + id: Not(id), }, }); if (chk_name.length > 0) { throw new HttpError( - HttpStatusCode.NOT_FOUND, - "โครงการ/หลักสูตรการฝึกอบรม: " + requestBody.name + " ปีงบประมาณ: " + requestBody.year + " มีอยู่ในระบบแล้ว", + HttpStatusCode.NOT_FOUND, + "โครงการ/หลักสูตรการฝึกอบรม: " + + requestBody.projectName + + " ปีงบประมาณ: " + + requestBody.year + + " มีอยู่ในระบบแล้ว", ); } + Object.assign(development, requestBody); development.lastUpdateUserId = request.user.sub; development.lastUpdateFullName = request.user.name; - this.developmentRepository.merge(development, requestBody); await this.developmentRepository.save(development); + await this.actualPeopleRepository.remove(development.developmentActualPeoples); + await this.plannedPeopleRepository.remove(development.developmentPlannedPeoples); + await this.actualGoalRepository.remove(development.developmentActualGoals); + await this.plannedGoalRepository.remove(development.developmentPlannedGoals); + await Promise.all( + requestBody.actualPeoples.map(async (x) => { + const data = Object.assign(new ActualPeople(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentActualPeopleId = development.id; + await this.actualPeopleRepository.save(data); + }), + ); + await Promise.all( + requestBody.plannedPeoples.map(async (x) => { + const data = Object.assign(new PlannedPeople(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentPlannedPeopleId = development.id; + await this.plannedPeopleRepository.save(data); + }), + ); + await Promise.all( + requestBody.actualGoals.map(async (x) => { + if (x.posTypeActualId != null) { + const checkId = await this.posTypeRepository.findOne({ + where: { id: x.posTypeActualId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่ง"); + } + } + if (x.posLevelActualId != null) { + const checkId = await this.posLevelRepository.findOne({ + where: { id: x.posLevelActualId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่ง"); + } + } + const data = Object.assign(new ActualGoal(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentActualGoalId = development.id; + await this.actualGoalRepository.save(data); + }), + ); + await Promise.all( + requestBody.plannedGoals.map(async (x) => { + if (x.posTypePlannedId != null) { + const checkId = await this.posTypeRepository.findOne({ + where: { id: x.posTypePlannedId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่ง"); + } + } + if (x.posLevelPlannedId != null) { + const checkId = await this.posLevelRepository.findOne({ + where: { id: x.posLevelPlannedId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่ง"); + } + } + const data = Object.assign(new PlannedGoal(), x); + data.createdUserId = request.user.sub; + data.createdFullName = request.user.name; + data.lastUpdateUserId = request.user.sub; + data.lastUpdateFullName = request.user.name; + data.developmentPlannedGoalId = development.id; + await this.plannedGoalRepository.save(data); + }), + ); return new HttpSuccess(development.id); } @@ -111,11 +325,24 @@ export class DevelopmentController extends Controller { */ @Delete("{id}") async DeleteDevelopment(@Path() id: string) { - const delDevelopment = await this.developmentRepository.findOne({ where: { id } }); - if (!delDevelopment) { + const development = await this.developmentRepository.findOne({ + where: { id }, + relations: { + developmentActualPeoples: true, + developmentPlannedPeoples: true, + developmentActualGoals: true, + developmentPlannedGoals: true, + }, + }); + if (!development) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงการ/หลักสูตรการฝึกอบรมนี้"); } - await this.developmentRepository.remove(delDevelopment); + + await this.actualPeopleRepository.remove(development.developmentActualPeoples); + await this.plannedPeopleRepository.remove(development.developmentPlannedPeoples); + await this.actualGoalRepository.remove(development.developmentActualGoals); + await this.plannedGoalRepository.remove(development.developmentPlannedGoals); + await this.developmentRepository.remove(development); return new HttpSuccess(); } @@ -130,18 +357,15 @@ export class DevelopmentController extends Controller { @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, @Query("keyword") keyword?: string, - @Query("year") year: number = 2024, + @Query("year") year?: number, ) { const [development, total] = await AppDataSource.getRepository(Development) .createQueryBuilder("development") - .andWhere(year != 0 ? "development.year LIKE :year" : "1=1", { year: `${year}` }) - .orWhere("development.name LIKE :keyword", { keyword: `${keyword}` }) - .select([ - "development.id", - "development.name", - "development.year", - ]) + .andWhere(year == null ? "development.year LIKE :year" : "1=1", { year: `${year}` }) + .orWhere("development.projectName LIKE :keyword", { keyword: `${keyword}` }) + .select(["development.id", "development.projectName", "development.year"]) .orderBy("development.year", "DESC") + .orderBy("development.createdAt", "DESC") .skip((page - 1) * pageSize) .take(pageSize) .getManyAndCount(); @@ -159,13 +383,17 @@ export class DevelopmentController extends Controller { @Get("{id}") async GetDevelopemtById(@Path() id: string) { const getDevelopment = await this.developmentRepository.findOne({ - select: ["id", "name", "year"], where: { id: id }, + relations: { + developmentActualPeoples: true, + developmentPlannedPeoples: true, + developmentActualGoals: true, + developmentPlannedGoals: true, + }, }); if (!getDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงการ/หลักสูตรการฝึกอบรมนี้"); } return new HttpSuccess(getDevelopment); } - } diff --git a/src/controllers/DevelopmentHistoryController.ts b/src/controllers/DevelopmentHistoryController.ts new file mode 100644 index 0000000..283ac8d --- /dev/null +++ b/src/controllers/DevelopmentHistoryController.ts @@ -0,0 +1,178 @@ +import { + Controller, + Get, + Post, + Put, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + Query, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { Not } from "typeorm"; +import HttpSuccess from "../interfaces/http-success"; +import HttpError from "../interfaces/http-error"; +import HttpStatusCode from "../interfaces/http-status"; +import { Development } from "../entities/Development"; +import { + CreateDevelopmentHistory, + DevelopmentHistory, + UpdateDevelopmentHistory, +} from "../entities/DevelopmentHistory"; + +@Route("api/v1/development/history") +@Tags("DevelopmentHistory") +@Security("bearerAuth") +export class DevelopmentHistoryController extends Controller { + private developmentHistoryRepository = AppDataSource.getRepository(DevelopmentHistory); + private developmentRepository = AppDataSource.getRepository(Development); + + /** + * API เพิ่มประวัติการฝึกอบรม/ดูงาน + * + * @summary DEV_006 - เพิ่มประวัติการฝึกอบรม/ดูงาน#6 + * + */ + @Post() + async CreateDevelopmentHistory( + @Body() requestBody: CreateDevelopmentHistory, + @Request() request: { user: Record }, + ) { + const chk_name = await this.developmentHistoryRepository.find({ + where: { + citizenId: requestBody.citizenId, + developmentId: requestBody.developmentId, + }, + }); + if (chk_name.length > 0) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ประวัติการฝึกอบรม/ดูงาน มีอยู่ในระบบแล้ว"); + } + + const checkId = await this.developmentRepository.findOne({ + where: { id: requestBody.developmentId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงการ/หลักสูตรการฝึกอบรม"); + } + + const development = Object.assign(new DevelopmentHistory(), requestBody); + + development.createdUserId = request.user.sub; + development.createdFullName = request.user.name; + development.lastUpdateUserId = request.user.sub; + development.lastUpdateFullName = request.user.name; + await this.developmentHistoryRepository.save(development); + return new HttpSuccess(development.id); + } + + /** + * API แก้ไขประวัติการฝึกอบรม/ดูงาน + * + * @summary DEV_007 - แก้ไขประวัติการฝึกอบรม/ดูงาน #7 + * + * @param {string} id Id โครงการ + */ + @Put("{id}") + async UpdateDevelopmentHistory( + @Path() id: string, + @Body() requestBody: UpdateDevelopmentHistory, + @Request() request: { user: Record }, + ) { + const development = await this.developmentHistoryRepository.findOne({ + where: { id }, + }); + if (!development) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประวัติการฝึกอบรม/ดูงานนี้"); + } + const chk_name = await this.developmentHistoryRepository.find({ + where: { + citizenId: requestBody.citizenId, + developmentId: requestBody.developmentId, + id: Not(id), + }, + }); + if (chk_name.length > 0) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ประวัติการฝึกอบรม/ดูงาน มีอยู่ในระบบแล้ว"); + } + const checkId = await this.developmentRepository.findOne({ + where: { id: requestBody.developmentId }, + }); + if (!checkId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงการ/หลักสูตรการฝึกอบรม"); + } + Object.assign(development, requestBody); + development.lastUpdateUserId = request.user.sub; + development.lastUpdateFullName = request.user.name; + await this.developmentHistoryRepository.save(development); + return new HttpSuccess(development.id); + } + + /** + * API ลบประวัติการฝึกอบรม/ดูงาน + * + * @summary DEV_008 - ลบประวัติการฝึกอบรม/ดูงาน #8 + * + * @param {string} id Id โครงการ + */ + @Delete("{id}") + async DeleteDevelopmentHistory(@Path() id: string) { + const development = await this.developmentHistoryRepository.findOne({ + where: { id }, + }); + if (!development) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประวัติการฝึกอบรม/ดูงานนี้"); + } + + await this.developmentHistoryRepository.remove(development); + return new HttpSuccess(); + } + + /** + * API รายการประวัติการฝึกอบรม/ดูงาน + * + * @summary DEV_009 - รายการประวัติการฝึกอบรม/ดูงาน #9 + * + */ + @Get() + async GetDevelopmentHistoryLists( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, + @Query("keyword") keyword?: string, + @Query("year") year?: number, + ) { + const [development, total] = await AppDataSource.getRepository(DevelopmentHistory) + .createQueryBuilder("developmentHistory") + // .andWhere(year == null ? "developmentHistory.year LIKE :year" : "1=1", { year: `${year}` }) + // .orWhere("developmentHistory.projectName LIKE :keyword", { keyword: `${keyword}` }) + // .select(["development.id", "development.projectName", "development.year"]) + // .orderBy("developmentHistory.year", "DESC") + .orderBy("developmentHistory.createdAt", "DESC") + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); + + return new HttpSuccess({ data: development, total }); + } + + /** + * API รายละเอียดประวัติการฝึกอบรม/ดูงาน + * + * @summary DEV_010 - รายละเอียดประวัติการฝึกอบรม/ดูงาน #10 + * + * @param {string} id Id โครงการ + */ + @Get("{id}") + async GetDevelopemtHistoryById(@Path() id: string) { + const getDevelopment = await this.developmentHistoryRepository.findOne({ + where: { id: id }, + }); + if (!getDevelopment) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประวัติการฝึกอบรม/ดูงานนี้"); + } + return new HttpSuccess(getDevelopment); + } +} diff --git a/src/entities/ActualGoal.ts b/src/entities/ActualGoal.ts new file mode 100644 index 0000000..cbe85aa --- /dev/null +++ b/src/entities/ActualGoal.ts @@ -0,0 +1,95 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Development } from "./Development"; +import { PosLevel } from "./PosLevel"; +import { PosType } from "./PosType"; + +@Entity("actualGoal") +export class ActualGoal extends EntityBase { + @Column({ + nullable: true, + comment: "กลุ่มเป้าหมาย", + default: null, + }) + groupTarget: string; + + @Column({ + nullable: true, + comment: "กลุ่มเป้าหมายย่อย", + default: null, + }) + groupTargetSub: string; + + @Column({ + nullable: true, + comment: "ตำแหน่ง", + default: null, + }) + position: string; + + @Column({ + nullable: true, + comment: "ประเภทตำแหน่ง", + default: null, + }) + posTypeActualId: string; + + @ManyToOne(() => PosType, (posType: PosType) => posType.actualGoals) + @JoinColumn({ name: "posTypeActualId" }) + posTypeActual: PosType; + + @Column({ + nullable: true, + comment: "ระดับตำแหน่ง", + default: null, + }) + posLevelActualId: string; + + @ManyToOne(() => PosLevel, (posLevel: PosLevel) => posLevel.actualGoals) + @JoinColumn({ name: "posLevelActualId" }) + posLevelActual: PosLevel; + + @Column({ + nullable: true, + comment: "ประเภท(กลุ่มอาชีพ คุณสมบัติ)", + default: null, + }) + type: string; + + @Column({ + nullable: true, + comment: "จำนวน(คน)", + default: null, + }) + amount: number; + + @Column({ + nullable: true, + comment: "id โครงการ", + default: null, + }) + developmentActualGoalId: string; + + @ManyToOne(() => Development, (development: Development) => development.developmentActualGoals) + @JoinColumn({ name: "developmentActualGoalId" }) + developmentActualGoal: Development; +} + +export class CreateActualGoal { + @Column() + groupTarget: string | null; + @Column() + groupTargetSub: string | null; + @Column() + position: string | null; + @Column() + posTypeActualId: string | null; + @Column() + posLevelActualId: string | null; + @Column() + type: string | null; + @Column() + amount: number | null; +} + +export type UpdateActualGoal = Partial; diff --git a/src/entities/ActualPeople.ts b/src/entities/ActualPeople.ts new file mode 100644 index 0000000..8050810 --- /dev/null +++ b/src/entities/ActualPeople.ts @@ -0,0 +1,40 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Development } from "./Development"; + +@Entity("actualPeople") +export class ActualPeople extends EntityBase { + @Column({ + nullable: true, + comment: "ผู้เกี่ยวข้อง", + default: null, + }) + groupTarget: string; + + @Column({ + nullable: true, + comment: "จำนวน(คน)", + default: null, + }) + amount: number; + + @Column({ + nullable: true, + comment: "id โครงการ", + default: null, + }) + developmentActualPeopleId: string; + + @ManyToOne(() => Development, (development: Development) => development.developmentActualPeoples) + @JoinColumn({ name: "developmentActualPeopleId" }) + developmentActualPeople: Development; +} + +export class CreateActualPeople { + @Column() + groupTarget: string | null; + @Column() + amount: number | null; +} + +export type UpdateActualPeople = Partial; diff --git a/src/entities/Development.ts b/src/entities/Development.ts index ca5c2b9..a3d5368 100644 --- a/src/entities/Development.ts +++ b/src/entities/Development.ts @@ -1,34 +1,471 @@ -import { Entity, Column, ManyToOne, JoinColumn, OneToOne, OneToMany } from "typeorm"; +import { Entity, Column, ManyToOne, JoinColumn, OneToOne, OneToMany, Double } from "typeorm"; import { EntityBase } from "./base/Base"; +import { Province } from "./Province"; +import { ActualPeople, CreateActualPeople } from "./ActualPeople"; +import { CreatePlannedPeople, PlannedPeople } from "./PlannedPeople"; +import { ActualGoal, CreateActualGoal } from "./ActualGoal"; +import { CreatePlannedGoal, PlannedGoal } from "./PlannedGoal"; +import { DevelopmentHistory } from "./DevelopmentHistory"; @Entity("development") export class Development extends EntityBase { - @Column({ - comment: "ชื่อโครงการ/กิจกรรม/หลักสูตร", - length: 255, - }) - name: string; - @Column({ nullable: true, comment: "ปีงบประมาณ", }) year: number; -} + @Column({ + comment: "ชื่อโครงการ/กิจกรรม/หลักสูตร", + length: 255, + }) + projectName: string; + @Column({ + nullable: true, + comment: "หลักการและเหตุผล", + default: null, + }) + reason: string; + + @Column({ + nullable: true, + comment: "วัตถุประสงค์", + default: null, + }) + objective: string; + + @Column({ + nullable: true, + comment: "ประเภทตัวชี้วัด", + default: null, + }) + metricType: string; + + @Column({ + nullable: true, + comment: "ตัวชี้วัด", + default: null, + }) + indicators: string; + + @Column({ + nullable: true, + comment: "เป้าหมาย", + default: null, + }) + target: string; + + @Column({ + nullable: true, + comment: "วิธีการคำนวณ/เครื่องมือ", + default: null, + }) + calculation: string; + + @Column({ + nullable: true, + comment: "ระยะเวลาวัดผล", + default: null, + }) + measuRement: string; + + @Column({ + nullable: true, + comment: "ผลการดำเนิน", + default: null, + }) + results: string; + + @Column({ + nullable: true, + comment: "ปัญหาอุปสรรค", + default: null, + }) + obstacles: string; + + @Column({ + nullable: true, + comment: "ข้อเสนอเเนะ", + default: null, + }) + suggestions: string; + + @Column({ + nullable: true, + comment: "ประเภทโครงการ", + default: null, + }) + project: string; + + @Column({ + comment: "ผ่านการพิจาณา ได้รับการจัดสรรงบประมาณตามข้อบัญญัติ", + default: false, + }) + isPassAllocate: boolean; + + @Column({ + comment: + "ผ่านการพิจารณา ไม่ได้รับการจัดสรรงบประมาณตามข้อบัญญัติ แต่ได้รับการจัดสรรเงินนอกงบประมาณ", + default: false, + }) + isPassNoAllocate: boolean; + + @Column({ + comment: "ไม่ผ่านการพิจารณา แต่ได้รับการจัดสรรเงินนอกงบประมาณ", + default: false, + }) + isNoPass: boolean; + + @Column({ + comment: "แต่ได้รับการจัดสรรงบประมาณตามข้อบัญญัติ", + default: false, + }) + isBudget: boolean; + + @Column({ + comment: "แต่ได้รับการจัดสรรเงินนอกงบประมาณ", + default: false, + }) + isOutBudget: boolean; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันที่เริ่มต้น", + default: null, + }) + dateStart: Date; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันที่สิ้นสุด", + default: null, + }) + dateEnd: Date; + + @Column({ + nullable: true, + comment: "รวมระยะเวลา (วัน)", + default: null, + }) + totalDate: number; + + @Column({ + nullable: true, + comment: "ที่อยู่", + default: null, + }) + address: string; + + @Column({ + nullable: true, + comment: "จังหวัด", + default: null, + }) + provinceId: string; + + @ManyToOne(() => Province, (province: Province) => province.developments) + @JoinColumn({ name: "provinceId" }) + province: Province; + + @Column({ + nullable: true, + comment: "ประเภทงบประมาณ", + default: null, + }) + budget: string; + + @Column({ + nullable: true, + comment: "จํานวนงบประมาณที่ขอรับการจัดสรรฯ", + default: 0, + type: "double", + }) + accept: Double; + + @Column({ + nullable: true, + comment: "จํานวนงบประมาณที่ได้รับการจัดสรรฯ", + default: 0, + type: "double", + }) + receive: Double; + + @Column({ + nullable: true, + comment: "จํานวนงบประมาณที่ได้รับอนุมัติ", + default: 0, + type: "double", + }) + approved: Double; + + @Column({ + nullable: true, + comment: "จํานวนงบประมาณที่จ่ายจริง", + default: 0, + type: "double", + }) + budgetPay: Double; + + @Column({ + nullable: true, + comment: "ประเด็นความเสี่ยง", + default: null, + }) + issues: string; + + @Column({ + nullable: true, + comment: "โอกาสที่จะเกิด", + default: null, + }) + chance: string; + + @Column({ + nullable: true, + comment: "ผลกระทบจากการเกิด", + default: null, + }) + effects: string; + + @Column({ + nullable: true, + comment: "ระดับความเสี่ยง", + default: null, + }) + riskLevel: string; + + @Column({ + nullable: true, + comment: "เเนวทางการบริหารความเสี่ยง", + default: null, + }) + riskManagement: string; + + @Column({ + nullable: true, + comment: "ประโยชน์ที่คาดว่าจะได้รับ", + default: null, + }) + expect: string; + + @Column({ + nullable: true, + comment: "หัวข้อ/ประเด็นการฝึกอบรม ศึกษาดูงาน", + default: null, + }) + topicAcademic: string; + + @Column({ + nullable: true, + comment: "สถานที่ฝึกอบรม ศึกษาดูงาน", + default: null, + }) + addressAcademic: string; + + @Column({ + nullable: true, + comment: "จังหวัด(ข้อมูลวิชาการ)", + default: null, + }) + provinceActualId: string; + + @ManyToOne(() => Province, (province: Province) => province.developmentActuals) + @JoinColumn({ name: "provinceActualId" }) + provinceActual: Province; + + @OneToMany( + () => ActualPeople, + (actualPeople: ActualPeople) => actualPeople.developmentActualPeople, + ) + developmentActualPeoples: ActualPeople[]; + + @OneToMany( + () => PlannedPeople, + (plannedPeople: PlannedPeople) => plannedPeople.developmentPlannedPeople, + ) + developmentPlannedPeoples: PlannedPeople[]; + + @OneToMany(() => ActualGoal, (actualGoal: ActualGoal) => actualGoal.developmentActualGoal) + developmentActualGoals: ActualGoal[]; + + @OneToMany(() => PlannedGoal, (plannedGoal: PlannedGoal) => plannedGoal.developmentPlannedGoal) + developmentPlannedGoals: PlannedGoal[]; + + @OneToMany( + () => DevelopmentHistory, + (developmentHistory: DevelopmentHistory) => developmentHistory.development, + ) + developmentHistorys: DevelopmentHistory[]; +} export class CreateDevelopment { - @Column() - name: string; - @Column() year: number; + @Column() + projectName: string; + @Column() + reason: string | null; + @Column() + objective: string | null; + @Column() + metricType: string | null; + @Column() + indicators: string | null; + @Column() + target: string | null; + @Column() + calculation: string | null; + @Column() + measuRement: string | null; + @Column() + results: string | null; + @Column() + obstacles: string | null; + @Column() + suggestions: string | null; + @Column() + project: string | null; + @Column() + isPassAllocate: boolean; + @Column() + isPassNoAllocate: boolean; + @Column() + isNoPass: boolean; + @Column() + isBudget: boolean; + @Column() + isOutBudget: boolean; + @Column() + dateStart: Date | null; + @Column() + dateEnd: Date | null; + @Column() + totalDate: number | null; + @Column() + address: string | null; + @Column() + provinceId: string | null; + @Column() + budget: string | null; + @Column() + accept: Double | null; + @Column() + receive: Double | null; + @Column() + approved: Double | null; + @Column() + budgetPay: Double | null; + @Column() + issues: string | null; + @Column() + chance: string | null; + @Column() + effects: string | null; + @Column() + riskLevel: string | null; + @Column() + riskManagement: string | null; + @Column() + expect: string | null; + @Column() + topicAcademic: string | null; + @Column() + addressAcademic: string | null; + @Column() + provinceActualId: string | null; + @Column() + actualPeoples: CreateActualPeople[]; + @Column() + plannedPeoples: CreatePlannedPeople[]; + @Column() + actualGoals: CreateActualGoal[]; + @Column() + plannedGoals: CreatePlannedGoal[]; } export class UpdateDevelopment { - @Column() - name: string; - @Column() year: number; + @Column() + projectName: string; + @Column() + reason: string | null; + @Column() + objective: string | null; + @Column() + metricType: string | null; + @Column() + indicators: string | null; + @Column() + target: string | null; + @Column() + calculation: string | null; + @Column() + measuRement: string | null; + @Column() + results: string | null; + @Column() + obstacles: string | null; + @Column() + suggestions: string | null; + @Column() + project: string | null; + @Column() + isPassAllocate: boolean; + @Column() + isPassNoAllocate: boolean; + @Column() + isNoPass: boolean; + @Column() + isBudget: boolean; + @Column() + isOutBudget: boolean; + @Column() + dateStart: Date | null; + @Column() + dateEnd: Date | null; + @Column() + totalDate: number | null; + @Column() + address: string | null; + @Column() + provinceId: string | null; + @Column() + budget: string | null; + @Column() + accept: Double | null; + @Column() + receive: Double | null; + @Column() + approved: Double | null; + @Column() + budgetPay: Double | null; + @Column() + issues: string | null; + @Column() + chance: string | null; + @Column() + effects: string | null; + @Column() + riskLevel: string | null; + @Column() + riskManagement: string | null; + @Column() + expect: string | null; + @Column() + topicAcademic: string | null; + @Column() + addressAcademic: string | null; + @Column() + provinceActualId: string | null; + @Column() + actualPeoples: CreateActualPeople[]; + @Column() + plannedPeoples: CreatePlannedPeople[]; + @Column() + actualGoals: CreateActualGoal[]; + @Column() + plannedGoals: CreatePlannedGoal[]; } diff --git a/src/entities/DevelopmentHistory.ts b/src/entities/DevelopmentHistory.ts new file mode 100644 index 0000000..ca34e4f --- /dev/null +++ b/src/entities/DevelopmentHistory.ts @@ -0,0 +1,154 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { PosLevel } from "./PosLevel"; +import { PosType } from "./PosType"; +import { Development } from "./Development"; + +@Entity("developmentHistory") +export class DevelopmentHistory extends EntityBase { + @Column({ + nullable: true, + comment: "ยศ", + length: 40, + default: null, + }) + rank: string; + + @Column({ + nullable: true, + comment: "คำนำหน้าชื่อ", + length: 40, + default: null, + }) + prefix: string; + + @Column({ + nullable: true, + comment: "ชื่อ", + length: 255, + default: null, + }) + firstName: string; + + @Column({ + nullable: true, + comment: "นามสกุล", + length: 255, + default: null, + }) + lastName: string; + + @Column({ + nullable: true, + comment: "เลขประจำตัวประชาชน", + default: null, + length: 13, + }) + citizenId: string; + + @Column({ + nullable: true, + comment: "ตำแหน่ง", + default: null, + length: 255, + }) + position: string; + + @Column({ + nullable: true, + length: 40, + comment: "ไอดีระดับตำแหน่ง", + }) + posLevelId: string | null; + + @ManyToOne(() => PosLevel, (posLevel) => posLevel.developmentHistorys) + @JoinColumn({ name: "posLevelId" }) + posLevel: PosLevel; + + @Column({ + nullable: true, + length: 40, + comment: "ไอดีประเภทตำแหน่ง", + }) + posTypeId: string | null; + + @ManyToOne(() => PosType, (posType) => posType.developmentHistorys) + @JoinColumn({ name: "posTypeId" }) + posType: PosType; + + @Column({ + nullable: true, + comment: "โครงการ/หลักสูตรการฝึกอบรม", + default: null, + }) + developmentId: string; + + @ManyToOne(() => Development, (development: Development) => development.developmentHistorys) + @JoinColumn({ name: "developmentId" }) + development: Development; + + @Column({ + nullable: true, + comment: "เลขที่คำสั่ง/เลขที่หนังสืออนุมัติ", + default: null, + length: 255, + }) + order: string; + + @Column({ + nullable: true, + comment: "คำสั่งลงวันที่/หนังสืออนุมัติลงวันที่", + default: null, + length: 255, + }) + dateOrder: string; +} +export class CreateDevelopmentHistory { + @Column() + rank: string | null; + @Column() + prefix: string | null; + @Column() + firstName: string | null; + @Column() + lastName: string | null; + @Column() + citizenId: string; + @Column() + position: string | null; + @Column() + posLevelId: string | null; + @Column() + posTypeId: string | null; + @Column() + developmentId: string; + @Column() + order: string | null; + @Column() + dateOrder: string | null; +} + +export class UpdateDevelopmentHistory { + @Column() + rank: string | null; + @Column() + prefix: string | null; + @Column() + firstName: string | null; + @Column() + lastName: string | null; + @Column() + citizenId: string; + @Column() + position: string | null; + @Column() + posLevelId: string | null; + @Column() + posTypeId: string | null; + @Column() + developmentId: string; + @Column() + order: string | null; + @Column() + dateOrder: string | null; +} diff --git a/src/entities/EmployeePosLevel.ts b/src/entities/EmployeePosLevel.ts new file mode 100644 index 0000000..c84e309 --- /dev/null +++ b/src/entities/EmployeePosLevel.ts @@ -0,0 +1,61 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { EmployeePosType } from "./EmployeePosType"; + +enum EmployeePosLevelAuthoritys { + HEAD = "HEAD", + DEPUTY = "DEPUTY", + GOVERNOR = "GOVERNOR", +} +@Entity("employeePosLevel") +export class EmployeePosLevel extends EntityBase { + @Column({ + comment: "ชื่อระดับชั้นงาน", + type: "int", + }) + posLevelName: number; + + @Column({ + comment: "ระดับของระดับชั้นงาน", + type: "int", + }) + posLevelRank: number; + + @Column({ + nullable: true, + comment: + "ผู้มีอำนาจสั่งบรรจุของระดับนี้ head = หัวหน้าหน่วยงาน , deputy = ปลัด , governor = ผู้ว่าฯ", + type: "enum", + enum: EmployeePosLevelAuthoritys, + default: null, + }) + posLevelAuthority: EmployeePosLevelAuthoritys; + + @Column({ + length: 40, + comment: "คีย์นอก(FK)ของตาราง employeePosType", + }) + posTypeId: string; + + @ManyToOne(() => EmployeePosType, (posType: EmployeePosType) => posType.posLevels) + @JoinColumn({ name: "posTypeId" }) + posType: EmployeePosType; +} + +export class CreateEmployeePosLevel { + @Column() + posLevelName: number; + + @Column() + posLevelRank: number; + + @Column() + posLevelAuthority: string; + + @Column("uuid") + posTypeId: string; +} + +export type UpdateEmployeePosLevel = Partial & { + posLevelAuthority: EmployeePosLevelAuthoritys; +}; diff --git a/src/entities/EmployeePosType.ts b/src/entities/EmployeePosType.ts new file mode 100644 index 0000000..99b1cdb --- /dev/null +++ b/src/entities/EmployeePosType.ts @@ -0,0 +1,43 @@ +import { Entity, Column, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { EmployeePosLevel } from "./EmployeePosLevel"; + +@Entity("employeePosType") +export class EmployeePosType extends EntityBase { + @Column({ + nullable: true, + comment: "ชื่อกลุ่มงาน", + length: 255, + default: null, + }) + posTypeName: string; + + @Column({ + comment: "ระดับของกลุ่มงาน", + }) + posTypeRank: number; + + @Column({ + nullable: true, + comment: "ชื่อย่อกลุ่มงาน", + length: 255, + default: null, + }) + posTypeShortName: string; + + @OneToMany(() => EmployeePosLevel, (posLevel: EmployeePosLevel) => posLevel.posType) + posLevels: EmployeePosLevel[]; +} + +export class CreateEmployeePosType { + @Column() + posTypeName: string; + + @Column() + posTypeRank: number; + + @Column() + posTypeShortName: string; +} + +export type UpdateEmployeePosType = Partial; diff --git a/src/entities/PlannedGoal.ts b/src/entities/PlannedGoal.ts new file mode 100644 index 0000000..5758ed8 --- /dev/null +++ b/src/entities/PlannedGoal.ts @@ -0,0 +1,95 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Development } from "./Development"; +import { PosType } from "./PosType"; +import { PosLevel } from "./PosLevel"; + +@Entity("plannedGoal") +export class PlannedGoal extends EntityBase { + @Column({ + nullable: true, + comment: "กลุ่มเป้าหมาย", + default: null, + }) + groupTarget: string; + + @Column({ + nullable: true, + comment: "กลุ่มเป้าหมายย่อย", + default: null, + }) + groupTargetSub: string; + + @Column({ + nullable: true, + comment: "ตำแหน่ง", + default: null, + }) + position: string; + + @Column({ + nullable: true, + comment: "ประเภทตำแหน่ง", + default: null, + }) + posTypePlannedId: string; + + @ManyToOne(() => PosType, (posType: PosType) => posType.plannedGoals) + @JoinColumn({ name: "posTypePlannedId" }) + posTypePlanned: PosType; + + @Column({ + nullable: true, + comment: "ระดับตำแหน่ง", + default: null, + }) + posLevelPlannedId: string; + + @ManyToOne(() => PosLevel, (posLevel: PosLevel) => posLevel.plannedGoals) + @JoinColumn({ name: "posLevelPlannedId" }) + posLevelPlanned: PosLevel; + + @Column({ + nullable: true, + comment: "ประเภท(กลุ่มอาชีพ คุณสมบัติ)", + default: null, + }) + type: string; + + @Column({ + nullable: true, + comment: "จำนวน(คน)", + default: null, + }) + amount: number; + + @Column({ + nullable: true, + comment: "id โครงการ", + default: null, + }) + developmentPlannedGoalId: string; + + @ManyToOne(() => Development, (development: Development) => development.developmentPlannedGoals) + @JoinColumn({ name: "developmentPlannedGoalId" }) + developmentPlannedGoal: Development; +} + +export class CreatePlannedGoal { + @Column() + groupTarget: string | null; + @Column() + groupTargetSub: string | null; + @Column() + position: string | null; + @Column() + posTypePlannedId: string | null; + @Column() + posLevelPlannedId: string | null; + @Column() + type: string | null; + @Column() + amount: number | null; +} + +export type UpdatePlannedGoal = Partial; diff --git a/src/entities/PlannedPeople.ts b/src/entities/PlannedPeople.ts new file mode 100644 index 0000000..8743fd1 --- /dev/null +++ b/src/entities/PlannedPeople.ts @@ -0,0 +1,40 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Development } from "./Development"; + +@Entity("plannedPeople") +export class PlannedPeople extends EntityBase { + @Column({ + nullable: true, + comment: "ผู้เกี่ยวข้อง", + default: null, + }) + groupTarget: string; + + @Column({ + nullable: true, + comment: "จำนวน(คน)", + default: null, + }) + amount: number; + + @Column({ + nullable: true, + comment: "id โครงการ", + default: null, + }) + developmentPlannedPeopleId: string; + + @ManyToOne(() => Development, (development: Development) => development.developmentPlannedPeoples) + @JoinColumn({ name: "developmentPlannedPeopleId" }) + developmentPlannedPeople: Development; +} + +export class CreatePlannedPeople { + @Column() + groupTarget: string | null; + @Column() + amount: number | null; +} + +export type UpdatePlannedPeople = Partial; diff --git a/src/entities/PosLevel.ts b/src/entities/PosLevel.ts new file mode 100644 index 0000000..cecb35f --- /dev/null +++ b/src/entities/PosLevel.ts @@ -0,0 +1,74 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { PosType } from "./PosType"; +import { ActualGoal } from "./ActualGoal"; +import { PlannedGoal } from "./PlannedGoal"; +import { DevelopmentHistory } from "./DevelopmentHistory"; + +enum PosLevelAuthority { + HEAD = "HEAD", + DEPUTY = "DEPUTY", + GOVERNOR = "GOVERNOR", +} +@Entity("posLevel") +export class PosLevel extends EntityBase { + @Column({ + nullable: true, + comment: "ชื่อระดับตำแหน่ง", + length: 255, + default: null, + }) + posLevelName: string; + + @Column({ + nullable: true, + comment: "ระดับของระดับตำแหน่ง", + default: null, + }) + posLevelRank: number; + + @Column({ + nullable: true, + comment: + "ผู้มีอำนาจสั่งบรรจุของระดับนี้ head = หัวหน้าหน่วยงาน , deputy = ปลัด , governor = ผู้ว่าฯ", + type: "enum", + enum: PosLevelAuthority, + default: null, + }) + posLevelAuthority: PosLevelAuthority; + + @Column({ + length: 40, + comment: "เป็นระดับของประเภทตำแหน่งใด", + }) + posTypeId: string; + + @ManyToOne(() => PosType, (posType: PosType) => posType.posLevels) + @JoinColumn({ name: "posTypeId" }) + posType: PosType; + + @OneToMany(() => ActualGoal, (actualGoal: ActualGoal) => actualGoal.posLevelActual) + actualGoals: ActualGoal[]; + + @OneToMany(() => PlannedGoal, (plannedGoal: PlannedGoal) => plannedGoal.posLevelPlanned) + plannedGoals: PlannedGoal[]; + + @OneToMany(() => DevelopmentHistory, (developmentHistory) => developmentHistory.posLevel) + developmentHistorys: DevelopmentHistory[]; +} + +export class CreatePosLevel { + @Column() + posLevelName: string; + + @Column() + posLevelRank: number; + + @Column() + posLevelAuthority: string; + + @Column("uuid") + posTypeId: string; +} + +export type UpdatePosLevel = Partial & { posLevelAuthority?: PosLevelAuthority }; diff --git a/src/entities/PosType.ts b/src/entities/PosType.ts new file mode 100644 index 0000000..f6a89f6 --- /dev/null +++ b/src/entities/PosType.ts @@ -0,0 +1,47 @@ +import { Entity, Column, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { PosLevel } from "./PosLevel"; +import { ActualGoal } from "./ActualGoal"; +import { PlannedGoal } from "./PlannedGoal"; +import { DevelopmentHistory } from "./DevelopmentHistory"; + +@Entity("posType") +export class PosType extends EntityBase { + @Column({ + nullable: true, + comment: "ชื่อประเภทตำแหน่ง (ทั่วไป วิชาการ อำนวยการ บริหาร)", + length: 255, + default: null, + }) + posTypeName: string; + + @Column({ + nullable: true, + comment: + "ระดับของประเภทตำแหน่ง ไว้ใช้ระบุว่าประเภทตำแหน่งนี้อยู่ระดับสูงหรือต่ำกว่ากัน โดย 1 = ต่ำกว่า , มากกว่า 1 = สูงกว่า ทั่วไป = 1 วิชาการ = 2 อำนวยการ = 3 บริหาร = 4", + default: null, + }) + posTypeRank: number; + + @OneToMany(() => PosLevel, (posLevel: PosLevel) => posLevel.posType) + posLevels: PosLevel[]; + + @OneToMany(() => ActualGoal, (actualGoal: ActualGoal) => actualGoal.posTypeActual) + actualGoals: ActualGoal[]; + + @OneToMany(() => PlannedGoal, (plannedGoal: PlannedGoal) => plannedGoal.posTypePlanned) + plannedGoals: PlannedGoal[]; + + @OneToMany(() => DevelopmentHistory, (developmentHistory) => developmentHistory.posType) + developmentHistorys: DevelopmentHistory[]; +} + +export class CreatePosType { + @Column() + posTypeName: string; + + @Column() + posTypeRank: number; +} + +export type UpdatePosType = Partial; diff --git a/src/entities/Province.ts b/src/entities/Province.ts new file mode 100644 index 0000000..0ab83ff --- /dev/null +++ b/src/entities/Province.ts @@ -0,0 +1,27 @@ +import { Entity, Column, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Development } from "./Development"; + +@Entity("province") +export class Province extends EntityBase { + @Column({ + nullable: true, + comment: "จังหวัด", + length: 255, + default: null, + }) + name: string; + + @OneToMany(() => Development, (development: Development) => development.province) + developments: Development[]; + + @OneToMany(() => Development, (development: Development) => development.provinceActual) + developmentActuals: Development[]; +} + +export class CreateProvince { + @Column() + name: string; +} + +export type UpdateProvince = Partial; diff --git a/src/migration/1712060108057-add_table_development.ts b/src/migration/1712060108057-add_table_development.ts new file mode 100644 index 0000000..cdca497 --- /dev/null +++ b/src/migration/1712060108057-add_table_development.ts @@ -0,0 +1,128 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddTableDevelopment1712060108057 implements MigrationInterface { + name = 'AddTableDevelopment1712060108057' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`actualPeople\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`groupTarget\` varchar(255) NULL COMMENT 'ผู้เกี่ยวข้อง', \`amount\` int NULL COMMENT 'จำนวน(คน)', \`developmentActualPeopleId\` varchar(255) NULL COMMENT 'id โครงการ', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`plannedPeople\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`groupTarget\` varchar(255) NULL COMMENT 'ผู้เกี่ยวข้อง', \`amount\` int NULL COMMENT 'จำนวน(คน)', \`developmentPlannedPeopleId\` varchar(255) NULL COMMENT 'id โครงการ', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`plannedGoal\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`groupTarget\` varchar(255) NULL COMMENT 'กลุ่มเป้าหมาย', \`groupTargetSub\` varchar(255) NULL COMMENT 'กลุ่มเป้าหมายย่อย', \`position\` varchar(255) NULL COMMENT 'ตำแหน่ง', \`posTypePlannedId\` varchar(255) NULL COMMENT 'ประเภทตำแหน่ง', \`posLevelPlannedId\` varchar(255) NULL COMMENT 'ระดับตำแหน่ง', \`type\` varchar(255) NULL COMMENT 'ประเภท(กลุ่มอาชีพ คุณสมบัติ)', \`amount\` int NULL COMMENT 'จำนวน(คน)', \`developmentPlannedGoalId\` varchar(255) NULL COMMENT 'id โครงการ', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`posType\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`posTypeName\` varchar(255) NULL COMMENT 'ชื่อประเภทตำแหน่ง (ทั่วไป วิชาการ อำนวยการ บริหาร)', \`posTypeRank\` int NULL COMMENT 'ระดับของประเภทตำแหน่ง ไว้ใช้ระบุว่าประเภทตำแหน่งนี้อยู่ระดับสูงหรือต่ำกว่ากัน โดย 1 = ต่ำกว่า , มากกว่า 1 = สูงกว่า ทั่วไป = 1 วิชาการ = 2 อำนวยการ = 3 บริหาร = 4', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`posLevel\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`posLevelName\` varchar(255) NULL COMMENT 'ชื่อระดับตำแหน่ง', \`posLevelRank\` int NULL COMMENT 'ระดับของระดับตำแหน่ง', \`posLevelAuthority\` enum ('HEAD', 'DEPUTY', 'GOVERNOR') NULL COMMENT 'ผู้มีอำนาจสั่งบรรจุของระดับนี้ head = หัวหน้าหน่วยงาน , deputy = ปลัด , governor = ผู้ว่าฯ', \`posTypeId\` varchar(40) NOT NULL COMMENT 'เป็นระดับของประเภทตำแหน่งใด', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`actualGoal\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`groupTarget\` varchar(255) NULL COMMENT 'กลุ่มเป้าหมาย', \`groupTargetSub\` varchar(255) NULL COMMENT 'กลุ่มเป้าหมายย่อย', \`position\` varchar(255) NULL COMMENT 'ตำแหน่ง', \`posTypeActualId\` varchar(255) NULL COMMENT 'ประเภทตำแหน่ง', \`posLevelActualId\` varchar(255) NULL COMMENT 'ระดับตำแหน่ง', \`type\` varchar(255) NULL COMMENT 'ประเภท(กลุ่มอาชีพ คุณสมบัติ)', \`amount\` int NULL COMMENT 'จำนวน(คน)', \`developmentActualGoalId\` varchar(255) NULL COMMENT 'id โครงการ', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`province\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`name\` varchar(255) NULL COMMENT 'จังหวัด', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`employeePosType\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`posTypeName\` varchar(255) NULL COMMENT 'ชื่อกลุ่มงาน', \`posTypeRank\` int NOT NULL COMMENT 'ระดับของกลุ่มงาน', \`posTypeShortName\` varchar(255) NULL COMMENT 'ชื่อย่อกลุ่มงาน', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`employeePosLevel\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`posLevelName\` int NOT NULL COMMENT 'ชื่อระดับชั้นงาน', \`posLevelRank\` int NOT NULL COMMENT 'ระดับของระดับชั้นงาน', \`posLevelAuthority\` enum ('HEAD', 'DEPUTY', 'GOVERNOR') NULL COMMENT 'ผู้มีอำนาจสั่งบรรจุของระดับนี้ head = หัวหน้าหน่วยงาน , deputy = ปลัด , governor = ผู้ว่าฯ', \`posTypeId\` varchar(40) NOT NULL COMMENT 'คีย์นอก(FK)ของตาราง employeePosType', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`name\``); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`projectName\` varchar(255) NOT NULL COMMENT 'ชื่อโครงการ/กิจกรรม/หลักสูตร'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`reason\` varchar(255) NULL COMMENT 'หลักการและเหตุผล'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`objective\` varchar(255) NULL COMMENT 'วัตถุประสงค์'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`metricType\` varchar(255) NULL COMMENT 'ประเภทตัวชี้วัด'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`indicators\` varchar(255) NULL COMMENT 'ตัวชี้วัด'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`target\` varchar(255) NULL COMMENT 'เป้าหมาย'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`calculation\` varchar(255) NULL COMMENT 'วิธีการคำนวณ/เครื่องมือ'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`measuRement\` varchar(255) NULL COMMENT 'ระยะเวลาวัดผล'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`results\` varchar(255) NULL COMMENT 'ผลการดำเนิน'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`obstacles\` varchar(255) NULL COMMENT 'ปัญหาอุปสรรค'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`suggestions\` varchar(255) NULL COMMENT 'ข้อเสนอเเนะ'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`project\` varchar(255) NULL COMMENT 'ประเภทโครงการ'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`isPassAllocate\` tinyint NOT NULL COMMENT 'ผ่านการพิจาณา ได้รับการจัดสรรงบประมาณตามข้อบัญญัติ' DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`isPassNoAllocate\` tinyint NOT NULL COMMENT 'ผ่านการพิจารณา ไม่ได้รับการจัดสรรงบประมาณตามข้อบัญญัติ แต่ได้รับการจัดสรรเงินนอกงบประมาณ' DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`isNoPass\` tinyint NOT NULL COMMENT 'ไม่ผ่านการพิจารณา แต่ได้รับการจัดสรรเงินนอกงบประมาณ' DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`isBudget\` tinyint NOT NULL COMMENT 'แต่ได้รับการจัดสรรงบประมาณตามข้อบัญญัติ' DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`isOutBudget\` tinyint NOT NULL COMMENT 'แต่ได้รับการจัดสรรเงินนอกงบประมาณ' DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`dateStart\` datetime NULL COMMENT 'วันที่เริ่มต้น'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`dateEnd\` datetime NULL COMMENT 'วันที่สิ้นสุด'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`totalDate\` int NULL COMMENT 'รวมระยะเวลา (วัน)'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`address\` varchar(255) NULL COMMENT 'ที่อยู่'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`provinceId\` varchar(255) NULL COMMENT 'จังหวัด'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`budget\` varchar(255) NULL COMMENT 'ประเภทงบประมาณ'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`accept\` double NULL COMMENT 'จํานวนงบประมาณที่ขอรับการจัดสรรฯ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`receive\` double NULL COMMENT 'จํานวนงบประมาณที่ได้รับการจัดสรรฯ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`approved\` double NULL COMMENT 'จํานวนงบประมาณที่ได้รับอนุมัติ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`budgetPay\` double NULL COMMENT 'จํานวนงบประมาณที่จ่ายจริง' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`issues\` varchar(255) NULL COMMENT 'ประเด็นความเสี่ยง'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`chance\` varchar(255) NULL COMMENT 'โอกาศที่จะเกิด'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`effects\` varchar(255) NULL COMMENT 'ผลกระทบจากการเกิด'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`riskLevel\` varchar(255) NULL COMMENT 'ระดับความเสี่ยง'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`riskManagement\` varchar(255) NULL COMMENT 'เเนวทางการบริหารความเสี่ยง'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`expect\` varchar(255) NULL COMMENT 'ประโยชน์ที่คาดว่าจะได้รับ'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`topicAcademic\` varchar(255) NULL COMMENT 'หัวข้อ/ประเด็นการฝึกอบรม ศึกษาดูงาน'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`addressAcademic\` varchar(255) NULL COMMENT 'สถานที่ฝึกอบรม ศึกษาดูงาน'`); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`provinceActualId\` varchar(255) NULL COMMENT 'จังหวัด(ข้อมูลวิชาการ)'`); + await queryRunner.query(`ALTER TABLE \`actualPeople\` ADD CONSTRAINT \`FK_f829036b60eabcca870d5e9242e\` FOREIGN KEY (\`developmentActualPeopleId\`) REFERENCES \`development\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`plannedPeople\` ADD CONSTRAINT \`FK_b508fdcde0693754799a9a75603\` FOREIGN KEY (\`developmentPlannedPeopleId\`) REFERENCES \`development\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`plannedGoal\` ADD CONSTRAINT \`FK_308d02f616b878261a3890b4d40\` FOREIGN KEY (\`posTypePlannedId\`) REFERENCES \`posType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`plannedGoal\` ADD CONSTRAINT \`FK_0e6aba627301f35aa3570b44bf5\` FOREIGN KEY (\`posLevelPlannedId\`) REFERENCES \`posLevel\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`plannedGoal\` ADD CONSTRAINT \`FK_14f48058eff5d24c8be711ae92b\` FOREIGN KEY (\`developmentPlannedGoalId\`) REFERENCES \`development\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`posLevel\` ADD CONSTRAINT \`FK_66caa3d974b67a8a8b343d029b2\` FOREIGN KEY (\`posTypeId\`) REFERENCES \`posType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`actualGoal\` ADD CONSTRAINT \`FK_e08e337e5ddeb4942c72393ff58\` FOREIGN KEY (\`posTypeActualId\`) REFERENCES \`posType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`actualGoal\` ADD CONSTRAINT \`FK_a9a864dd06eaa25edba8be8f24c\` FOREIGN KEY (\`posLevelActualId\`) REFERENCES \`posLevel\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`actualGoal\` ADD CONSTRAINT \`FK_5fc0017c134049b436d20ee81b4\` FOREIGN KEY (\`developmentActualGoalId\`) REFERENCES \`development\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`development\` ADD CONSTRAINT \`FK_c7552b4624cc7347144be758e6e\` FOREIGN KEY (\`provinceId\`) REFERENCES \`province\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`development\` ADD CONSTRAINT \`FK_bdafbb824b88c3bdb73adf7f220\` FOREIGN KEY (\`provinceActualId\`) REFERENCES \`province\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeePosLevel\` ADD CONSTRAINT \`FK_7fb9ab868f3f46b44f460c984f1\` FOREIGN KEY (\`posTypeId\`) REFERENCES \`employeePosType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`employeePosLevel\` DROP FOREIGN KEY \`FK_7fb9ab868f3f46b44f460c984f1\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP FOREIGN KEY \`FK_bdafbb824b88c3bdb73adf7f220\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP FOREIGN KEY \`FK_c7552b4624cc7347144be758e6e\``); + await queryRunner.query(`ALTER TABLE \`actualGoal\` DROP FOREIGN KEY \`FK_5fc0017c134049b436d20ee81b4\``); + await queryRunner.query(`ALTER TABLE \`actualGoal\` DROP FOREIGN KEY \`FK_a9a864dd06eaa25edba8be8f24c\``); + await queryRunner.query(`ALTER TABLE \`actualGoal\` DROP FOREIGN KEY \`FK_e08e337e5ddeb4942c72393ff58\``); + await queryRunner.query(`ALTER TABLE \`posLevel\` DROP FOREIGN KEY \`FK_66caa3d974b67a8a8b343d029b2\``); + await queryRunner.query(`ALTER TABLE \`plannedGoal\` DROP FOREIGN KEY \`FK_14f48058eff5d24c8be711ae92b\``); + await queryRunner.query(`ALTER TABLE \`plannedGoal\` DROP FOREIGN KEY \`FK_0e6aba627301f35aa3570b44bf5\``); + await queryRunner.query(`ALTER TABLE \`plannedGoal\` DROP FOREIGN KEY \`FK_308d02f616b878261a3890b4d40\``); + await queryRunner.query(`ALTER TABLE \`plannedPeople\` DROP FOREIGN KEY \`FK_b508fdcde0693754799a9a75603\``); + await queryRunner.query(`ALTER TABLE \`actualPeople\` DROP FOREIGN KEY \`FK_f829036b60eabcca870d5e9242e\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`provinceActualId\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`addressAcademic\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`topicAcademic\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`expect\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`riskManagement\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`riskLevel\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`effects\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`chance\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`issues\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`budgetPay\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`approved\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`receive\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`accept\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`budget\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`provinceId\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`address\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`totalDate\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`dateEnd\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`dateStart\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`isOutBudget\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`isBudget\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`isNoPass\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`isPassNoAllocate\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`isPassAllocate\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`project\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`suggestions\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`obstacles\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`results\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`measuRement\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`calculation\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`target\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`indicators\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`metricType\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`objective\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`reason\``); + await queryRunner.query(`ALTER TABLE \`development\` DROP COLUMN \`projectName\``); + await queryRunner.query(`ALTER TABLE \`development\` ADD \`name\` varchar(255) NOT NULL COMMENT 'ชื่อโครงการ/กิจกรรม/หลักสูตร'`); + await queryRunner.query(`DROP TABLE \`employeePosLevel\``); + await queryRunner.query(`DROP TABLE \`employeePosType\``); + await queryRunner.query(`DROP TABLE \`province\``); + await queryRunner.query(`DROP TABLE \`actualGoal\``); + await queryRunner.query(`DROP TABLE \`posLevel\``); + await queryRunner.query(`DROP TABLE \`posType\``); + await queryRunner.query(`DROP TABLE \`plannedGoal\``); + await queryRunner.query(`DROP TABLE \`plannedPeople\``); + await queryRunner.query(`DROP TABLE \`actualPeople\``); + } + +} diff --git a/src/migration/1712076616416-add_table_developmentHistory.ts b/src/migration/1712076616416-add_table_developmentHistory.ts new file mode 100644 index 0000000..1a5e76e --- /dev/null +++ b/src/migration/1712076616416-add_table_developmentHistory.ts @@ -0,0 +1,22 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddTableDevelopmentHistory1712076616416 implements MigrationInterface { + name = 'AddTableDevelopmentHistory1712076616416' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`developmentHistory\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`rank\` varchar(40) NULL COMMENT 'ยศ', \`prefix\` varchar(40) NULL COMMENT 'คำนำหน้าชื่อ', \`firstName\` varchar(255) NULL COMMENT 'ชื่อ', \`lastName\` varchar(255) NULL COMMENT 'นามสกุล', \`citizenId\` varchar(13) NULL COMMENT 'เลขประจำตัวประชาชน', \`position\` varchar(255) NULL COMMENT 'ตำแหน่ง', \`posLevelId\` varchar(40) NULL COMMENT 'ไอดีระดับตำแหน่ง', \`posTypeId\` varchar(40) NULL COMMENT 'ไอดีประเภทตำแหน่ง', \`developmentId\` varchar(255) NULL COMMENT 'โครงการ/หลักสูตรการฝึกอบรม', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`development\` CHANGE \`chance\` \`chance\` varchar(255) NULL COMMENT 'โอกาสที่จะเกิด'`); + await queryRunner.query(`ALTER TABLE \`developmentHistory\` ADD CONSTRAINT \`FK_d786f60dffba2d9a24c3bd3921b\` FOREIGN KEY (\`posLevelId\`) REFERENCES \`posLevel\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`developmentHistory\` ADD CONSTRAINT \`FK_d4e7a95f885bd0bd26c9ec1dba2\` FOREIGN KEY (\`posTypeId\`) REFERENCES \`posType\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`developmentHistory\` ADD CONSTRAINT \`FK_405574443eb92d4cdd8a88a22e6\` FOREIGN KEY (\`developmentId\`) REFERENCES \`development\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`developmentHistory\` DROP FOREIGN KEY \`FK_405574443eb92d4cdd8a88a22e6\``); + await queryRunner.query(`ALTER TABLE \`developmentHistory\` DROP FOREIGN KEY \`FK_d4e7a95f885bd0bd26c9ec1dba2\``); + await queryRunner.query(`ALTER TABLE \`developmentHistory\` DROP FOREIGN KEY \`FK_d786f60dffba2d9a24c3bd3921b\``); + await queryRunner.query(`ALTER TABLE \`development\` CHANGE \`chance\` \`chance\` varchar(255) NULL COMMENT 'โอกาศที่จะเกิด'`); + await queryRunner.query(`DROP TABLE \`developmentHistory\``); + } + +} diff --git a/src/migration/1712078526676-add_table_developmentHistory1.ts b/src/migration/1712078526676-add_table_developmentHistory1.ts new file mode 100644 index 0000000..0f832c9 --- /dev/null +++ b/src/migration/1712078526676-add_table_developmentHistory1.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddTableDevelopmentHistory11712078526676 implements MigrationInterface { + name = 'AddTableDevelopmentHistory11712078526676' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`developmentHistory\` ADD \`order\` varchar(255) NULL COMMENT 'เลขที่คำสั่ง/เลขที่หนังสืออนุมัติ'`); + await queryRunner.query(`ALTER TABLE \`developmentHistory\` ADD \`dateOrder\` varchar(255) NULL COMMENT 'คำสั่งลงวันที่/หนังสืออนุมัติลงวันที่'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`developmentHistory\` DROP COLUMN \`dateOrder\``); + await queryRunner.query(`ALTER TABLE \`developmentHistory\` DROP COLUMN \`order\``); + } + +} diff --git a/tsoa.json b/tsoa.json index ff48c69..c0d60df 100644 --- a/tsoa.json +++ b/tsoa.json @@ -31,6 +31,9 @@ }, { "name": "Development", "description": "ชื่อโครงการ/กิจกรรม/หลักสูตร" + }, + { + "name": "DevelopmentHistory", "description": "ประวัติการฝึกอบรม/ดูงาน" } ] },