From 6e8b8d58b91d7ad646c86e64fd141becab58b192 Mon Sep 17 00:00:00 2001 From: Kittapath Date: Tue, 26 Mar 2024 09:47:17 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B8=84=E0=B9=89=E0=B8=99=E0=B8=AB=E0=B8=B2?= =?UTF-8?q?=E0=B8=97=E0=B8=B0=E0=B9=80=E0=B8=9A=E0=B8=B5=E0=B8=A2=E0=B8=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/MainController.ts | 1279 +++++++++++++++++ src/controllers/ProfileController.ts | 114 +- src/entities/Profile.ts | 11 + src/interfaces/utils.ts | 24 +- ...767283-update_table_profile_add_isLeave.ts | 16 + 5 files changed, 1412 insertions(+), 32 deletions(-) create mode 100644 src/controllers/MainController.ts create mode 100644 src/migration/1711357767283-update_table_profile_add_isLeave.ts diff --git a/src/controllers/MainController.ts b/src/controllers/MainController.ts new file mode 100644 index 00000000..76930bcc --- /dev/null +++ b/src/controllers/MainController.ts @@ -0,0 +1,1279 @@ +import { + Controller, + Post, + Put, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + SuccessResponse, + Response, + Get, + Query, + Example, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { Profile, CreateProfile, UpdateProfile, ProfileHistory } from "../entities/Profile"; +import { Brackets, IsNull, Like, Not } from "typeorm"; +import { OrgRevision } from "../entities/OrgRevision"; +import { PosMaster } from "../entities/PosMaster"; +import { PosLevel } from "../entities/PosLevel"; +import { PosType } from "../entities/PosType"; +import { calculateRetireDate, calculateRetireYear } from "../interfaces/utils"; +import { RequestWithUser } from "../middlewares/user"; + +@Route("api/v1/org/profile") +@Tags("Profile") +@Security("bearerAuth") +@Response( + HttpStatus.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) +@SuccessResponse(HttpStatus.OK, "สำเร็จ") +export class MainController extends Controller { + private orgRevisionRepo = AppDataSource.getRepository(OrgRevision); + private posMasterRepo = AppDataSource.getRepository(PosMaster); + private profileRepo = AppDataSource.getRepository(Profile); + private profileHistoryRepo = AppDataSource.getRepository(ProfileHistory); + private posLevelRepo = AppDataSource.getRepository(PosLevel); + private posTypeRepo = AppDataSource.getRepository(PosType); + + /** + * API สร้างทะเบียนประวัติ + * + * @summary ORG_065 - สร้างทะเบียนประวัติ (ADMIN) #70 + * + */ + @Post() + async createProfile(@Request() request: RequestWithUser, @Body() body: CreateProfile) { + if (await this.profileRepo.findOneBy({ citizenId: body.citizenId })) { + throw new HttpError( + HttpStatus.INTERNAL_SERVER_ERROR, + "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", + ); + } + + if (body.posLevelId === "") body.posLevelId = null; + if (body.posTypeId === "") body.posTypeId = null; + + if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); + } + + if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); + } + + const profile = Object.assign(new Profile(), body); + profile.createdUserId = request.user.sub; + profile.createdFullName = request.user.name; + profile.lastUpdateUserId = request.user.sub; + profile.lastUpdateFullName = request.user.name; + await this.profileRepo.save(profile); + + return new HttpSuccess(); + } + + /** + * API แก้ไขทะเบียนประวัติ + * + * @summary ORG_065 - แก้ไขทะเบียนประวัติ (ADMIN) #70 + * + * @param {string} id Id ทะเบียนประวัติ + */ + @Put("{id}") + async updateProfile( + @Request() request: RequestWithUser, + @Path() id: string, + @Body() body: UpdateProfile, + ) { + const exists = + !!body.citizenId && + (await this.profileRepo.findOne({ + where: { id: Not(id), citizenId: body.citizenId }, + })); + + if (exists) { + throw new HttpError(HttpStatus.CONFLICT, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); + } + + if (body.posLevelId === "") body.posLevelId = null; + if (body.posTypeId === "") body.posTypeId = null; + + if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); + } + + if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); + } + + const record = await this.profileRepo.findOneBy({ id }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); + + await this.profileHistoryRepo.save( + Object.assign(new ProfileHistory(), { + ...record, + profileId: id, + id: undefined, + }), + ); + + Object.assign(record, body); + record.lastUpdateUserId = request.user.sub; + record.lastUpdateFullName = request.user.name; + + await this.profileRepo.save(record); + + return new HttpSuccess(); + } + + /** + * API ลบทะเบียนประวัติ + * + * @summary ORG_065 - ลบทะเบียนประวัติ (ADMIN) #70 + * + * @param {string} id Id ทะเบียนประวัติ + */ + @Delete("{id}") + async deleteProfile(@Path() id: string) { + const result = await this.profileRepo.delete({ id }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } + + /** + * API รายละเอียดรายการทะเบียนประวัติ + * + * @summary ORG_065 - รายละเอียดรายการทะเบียนประวัติ (ADMIN) #70 + * + * @param {string} id Id ทะเบียนประวัติ + */ + @Get("{id}") + async getProfile(@Path() id: string) { + const profile = await this.profileRepo.findOne({ + relations: { + posLevel: true, + posType: true, + gender: true, + relationship: true, + bloodGroup: true, + }, + where: { id }, + }); + + if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + return new HttpSuccess(profile); + } + + @Get("history/{id}") + async getProfileHistory(@Path() id: string) { + const profile = await this.profileHistoryRepo.find({ + relations: { + posLevel: true, + posType: true, + gender: true, + relationship: true, + bloodGroup: true, + }, + where: { profileId: id }, + }); + + if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + return new HttpSuccess(profile); + } + + /** + * API รายการทะเบียนประวัติ + * + * @summary ORG_065 - รายการทะเบียนประวัติ (ADMIN) #70 + * + */ + @Get() + @Example({ + status: 200, + message: "สำเร็จ", + result: { + data: [ + { + id: "ecb0b34c-037e-41f2-b95e-7e19f88b42ae", + createdAt: "2024-03-24T12:39:12.105Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-24T12:41:43.164Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "string", + prefix: null, + firstName: "Methapon", + lastName: "Metanipat", + citizenId: null, + position: null, + posLevelId: null, + posTypeId: null, + email: null, + phone: null, + keycloak: null, + isProbation: false, + dateRetire: null, + birthDate: null, + ethnicity: null, + telephoneNumber: null, + genderId: "22041841-3149-4b40-ab0e-0d4e98ffd2e1", + gender: { + id: "22041841-3149-4b40-ab0e-0d4e98ffd2e1", + createdAt: "2024-03-24T12:35:45.693Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-24T12:35:45.693Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "string", + name: "Male", + }, + relationshipId: null, + relationship: null, + religionId: null, + bloodGroupId: null, + bloodGroup: null, + posLevel: null, + posType: null, + }, + ], + total: 1, + }, + }) + async listProfile( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, + @Query() searchField?: "firstName" | "lastName" | "fullName" | "citizenId" | "position", + @Query() searchKeyword: string = "", + @Query() posType?: string, + @Query() posLevel?: string, + @Query() yearLeave?: number, + @Query() isProbation?: boolean, + @Query() isRetire?: boolean, + ) { + let queryLike = + "CONCAT(profile.prefix, profile.firstName, ' ', profile.lastName) LIKE :keyword"; + if (searchField == "citizenId") { + queryLike = "profile.citizenId LIKE :keyword"; + } else if (searchField == "position") { + queryLike = "profile.position LIKE :keyword"; + } + const [record, total] = await this.profileRepo + .createQueryBuilder("profile") + .leftJoinAndSelect("profile.posLevel", "posLevel") + .leftJoinAndSelect("profile.posType", "posType") + .leftJoinAndSelect("profile.gender", "gender") + .leftJoinAndSelect("profile.relationship", "relationship") + .leftJoinAndSelect("profile.bloodGroup", "bloodGroup") + .leftJoinAndSelect("profile.current_holders", "current_holders") + .leftJoinAndSelect("current_holders.orgRoot", "orgRoot") + .leftJoinAndSelect("current_holders.orgChild1", "orgChild1") + .leftJoinAndSelect("current_holders.orgChild2", "orgChild2") + .leftJoinAndSelect("current_holders.orgChild3", "orgChild3") + .leftJoinAndSelect("current_holders.orgChild4", "orgChild4") + .select([ + "profile.id", + "profile.prefix", + "profile.firstName", + "profile.lastName", + "profile.citizenId", + "profile.birthDate", + "profile.isProbation", + "profile.dateRetire", + "profile.position", + "posType.posTypeName", + "posLevel.posLevelName", + "current_holders.posMasterNo", + // "orgRoot?.orgRootShortName", + // "orgChild1?.orgRootShortName", + // "orgChild2?.orgRootShortName", + // "orgChild3?.orgRootShortName", + // "orgChild4?.orgRootShortName", + ]) + .andWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? queryLike + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .andWhere( + posType != undefined && posType != null && posType != "" + ? "posType.posTypeName LIKE :keyword1" + : "1=1", + { + keyword1: `${posType}`, + }, + ) + .andWhere( + posLevel != undefined && posLevel != null && posLevel != "" + ? "posLevel.posLevelName LIKE :keyword2" + : "1=1", + { + keyword2: `${posLevel}`, + }, + ) + .andWhere( + isProbation != undefined && isProbation != null + ? `profile.isProbation = ${isProbation}` + : "1=1", + ) + .andWhere( + isRetire != undefined && isRetire != null + ? isRetire == true + ? `profile.dateRetire IS null` + : `profile.dateRetire IS NOT NULL` + : "1=1", + ) + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); + + return new HttpSuccess({ data: record, total }); + } + + /** + * API ค้นหารายชื่อไปครองตำแหน่ง + * + * @summary ORG_063 - ค้นหารายชื่อไปครองตำแหน่ง (ADMIN) #68 + */ + @Post("search") + async searchProfileOrg( + @Body() + requestBody: { + position?: string; + posLevelId?: string; + posTypeId?: string; + page: number; + pageSize: number; + keyword?: string; + }, + ) { + const orgRevision = await this.orgRevisionRepo.findOne({ + where: { + orgRevisionIsDraft: true, + orgRevisionIsCurrent: false, + }, + relations: ["posMasters"], + }); + if (!orgRevision) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); + } + const [profiles, total] = await this.profileRepo + .createQueryBuilder("profile") + .leftJoinAndSelect("profile.next_holders", "next_holders") + .leftJoinAndSelect("profile.posLevel", "posLevel") + .leftJoinAndSelect("profile.posType", "posType") + .where( + requestBody.position != null && requestBody.position != "" + ? "profile.position LIKE :position" + : "1=1", + { + position: `%${requestBody.position}%`, + }, + ) + .andWhere( + new Brackets((qb) => { + qb.where( + requestBody.keyword != null && requestBody.keyword != "" + ? "profile.prefix LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ) + .orWhere( + requestBody.keyword != null && requestBody.keyword != "" + ? "profile.firstName LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ) + .orWhere( + requestBody.keyword != null && requestBody.keyword != "" + ? "profile.lastName LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ) + .orWhere( + requestBody.keyword != null && requestBody.keyword != "" + ? "profile.citizenId LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ); + }), + ) + .andWhere( + requestBody.posTypeId != null && requestBody.posTypeId != "" + ? "profile.posTypeId LIKE :posTypeId" + : "1=1", + { + posTypeId: `%${requestBody.posTypeId}%`, + }, + ) + .andWhere( + requestBody.posLevelId != null && requestBody.posLevelId != "" + ? "profile.posLevelId LIKE :posLevelId" + : "1=1", + { + posLevelId: `%${requestBody.posLevelId}%`, + }, + ) + .andWhere( + new Brackets((qb) => { + qb.where("profile.id NOT IN (:...ids)", { + ids: orgRevision.posMasters + .filter((x) => x.next_holderId != null) + .map((x) => x.next_holderId), + }); + }), + ) + .skip((requestBody.page - 1) * requestBody.pageSize) + .take(requestBody.pageSize) + .getManyAndCount(); + + const data = profiles.map((_data) => ({ + id: _data.id, + prefix: _data.prefix, + firstName: _data.firstName, + lastName: _data.lastName, + citizenId: _data.citizenId, + posLevel: _data.posLevel == null ? null : _data.posLevel.posLevelName, + posType: _data.posType == null ? null : _data.posType.posTypeName, + position: _data.position, + })); + + return new HttpSuccess({ data: data, total }); + } + + /** + * API ข้อมูลทะเบียนประวัติตาม keycloak + * + * @summary ORG_065 - ข้อมูลทะเบียนประวัติตาม keycloak (ADMIN) #70 + * + */ + @Get("keycloak/position") + async getProfileByKeycloak(@Request() request: { user: Record }) { + const profile = await this.profileRepo.findOne({ + where: { keycloak: request.user.sub }, + relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], + }); + if (!profile) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + } + + const orgRevisionPublish = await this.orgRevisionRepo + .createQueryBuilder("orgRevision") + .where("orgRevision.orgRevisionIsDraft = false") + .andWhere("orgRevision.orgRevisionIsCurrent = true") + .getOne(); + if (!orgRevisionPublish) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); + } + + const _profile = { + profileId: profile.id, + prefix: profile.prefix, + firstName: profile.firstName, + lastName: profile.lastName, + citizenId: profile.citizenId, + position: profile.position, + posLevelName: profile.posLevel == null ? null : profile.posLevel.posLevelName, + posLevelRank: profile.posLevel == null ? null : profile.posLevel.posLevelRank, + posLevelId: profile.posLevel == null ? null : profile.posLevel.id, + posTypeName: profile.posType == null ? null : profile.posType.posTypeName, + posTypeRank: profile.posType == null ? null : profile.posType.posTypeRank, + posTypeId: profile.posType == null ? null : profile.posType.id, + rootId: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgRootId, + root: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot + .orgRootName, + child1Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild1Id, + child1: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 + .orgChild1Name, + child2Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild2Id, + child2: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 + .orgChild2Name, + child3Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild3Id, + child3: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 + .orgChild3Name, + child4Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild4Id, + child4: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 == + null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 + .orgChild4Name, + }; + return new HttpSuccess(_profile); + } + + /** + * API ค้นหาข้อมูลทะเบียนประวัติ + * + * @summary ORG_065 - ค้นหาข้อมูลทะเบียนประวัติ (ADMIN) #70 + * + */ + @Post("search-personal") + async getProfileBySearchKeyword( + @Body() + body: { + fieldName: string; + keyword?: string; + }, + ) { + let findProfile: any; + switch (body.fieldName) { + case "idcard": + findProfile = await this.profileRepo.find({ + where: { citizenId: Like(`%${body.keyword}%`) }, + relations: ["posType", "posLevel"], + }); + break; + + case "firstname": + findProfile = await this.profileRepo.find({ + where: { firstName: Like(`%${body.keyword}%`) }, + relations: ["posType", "posLevel"], + }); + break; + + case "lastname": + findProfile = await this.profileRepo.find({ + where: { lastName: Like(`%${body.keyword}%`) }, + relations: ["posType", "posLevel"], + }); + break; + + default: + findProfile = await this.profileRepo.find({ + relations: ["posType", "posLevel"], + }); + break; + } + + const mapDataProfile = await Promise.all( + findProfile.map(async (item: Profile) => { + return { + id: item.id, + prefix: item.prefix, + firstName: item.firstName, + lastName: item.lastName, + position: item.position, + idcard: item.citizenId, + email: item.email, + phone: item.phone, + }; + }), + ); + + return new HttpSuccess(mapDataProfile); + } + + /** + * API ค้นหาผู้บังคับบัญชา + * + * @summary ORG_069 - ค้นหาผู้บังคับบัญชา (ADMIN) #75 + * + */ + @Get("search/commander") + async searchCommander(@Request() request: { user: Record }) { + let fullName_: any = {}; + let position_: any = {}; + let commanderAboveFullname_: any = {}; + let commanderAbovePosition_: any = {}; + let commanderFullname_: any = {}; + let commanderPosition_: any = {}; + + const findProfile = await this.profileRepo.findOne({ + where: { keycloak: request.user.sub }, + }); + + const findRevision = await this.orgRevisionRepo.findOne({ + where: { + orgRevisionIsCurrent: true, + }, + }); + + const findPosMaster = await this.posMasterRepo.findOne({ + where: { + current_holderId: findProfile?.id, + orgRevisionId: findRevision?.id, + }, + }); + + let node = 4; + let childId = findPosMaster?.orgChild4Id; + let condition: any = { orgChild4Id: childId }; + + if (findPosMaster?.orgChild4Id == null && findPosMaster?.orgChild3Id != null) { + node = 3; + childId = findPosMaster?.orgChild3Id; + condition = { orgChild3Id: childId, orgChild4Id: IsNull() }; + } else if (findPosMaster?.orgChild3Id == null && findPosMaster?.orgChild2Id != null) { + node = 2; + childId = findPosMaster?.orgChild2Id; + condition = { orgChild2Id: childId, orgChild3Id: IsNull() }; + } else if (findPosMaster?.orgChild2Id == null && findPosMaster?.orgChild1Id != null) { + node = 1; + childId = findPosMaster?.orgChild1Id; + condition = { orgChild1Id: childId, orgChild2Id: IsNull() }; + } else if (findPosMaster?.orgChild1Id == null) { + node = 0; + childId = findPosMaster?.orgRootId; + condition = { orgRootId: childId, orgChild1Id: IsNull() }; + } + + const findCmd = await this.posMasterRepo.findOne({ + where: { + current_holderId: Not(IsNull()) || Not(""), + orgRevisionId: findRevision?.id, + ...condition, + }, + relations: ["current_holder"], + order: { posMasterOrder: "ASC" }, + }); + let findOSAB: PosMaster | null = null; + let findTSAB: PosMaster | null = null; + //หาผู้บังคับบัญชาที่เหนือขึ้นไปอีก 1 ขั้น + if (node !== 0) { + findOSAB = await AppDataSource.getRepository(PosMaster) + .createQueryBuilder("posMaster") + .leftJoinAndSelect("posMaster.current_holder", "current_holder") + .where("posMaster.current_holderId IS NOT NULL") + .andWhere("posMaster.orgRevisionId = :revisionId", { revisionId: findRevision?.id }) + .andWhere( + new Brackets((qb) => { + if (node === 4) { + qb.andWhere("posMaster.orgChild4Id IS NULL"); + qb.andWhere("posMaster.orgChild3Id = :childId", { + childId: findPosMaster?.orgChild3Id, + }); + } else if (node === 3) { + qb.andWhere("posMaster.orgChild3Id IS NULL"); + qb.andWhere("posMaster.orgChild2Id = :childId", { + childId: findPosMaster?.orgChild2Id, + }); + } else if (node === 2) { + qb.andWhere("posMaster.orgChild2Id IS NULL"); + qb.andWhere("posMaster.orgChild1Id = :childId", { + childId: findPosMaster?.orgChild1Id, + }); + } else if (node === 1) { + qb.andWhere("posMaster.orgChild1Id IS NULL"); + qb.andWhere("posMaster.orgRootId = :childId", { childId: findPosMaster?.orgRootId }); + } + }), + ) + .orderBy("posMaster.posMasterOrder", "ASC") + .getOne(); + } + + //หาผู้บังคับบัญชาที่เหนือขึ้นไปอีก 2 ขั้น + if (node !== 0 && node !== 1) { + findTSAB = await AppDataSource.getRepository(PosMaster) + .createQueryBuilder("posMaster") + .leftJoinAndSelect("posMaster.current_holder", "current_holder") + .where("posMaster.current_holderId IS NOT NULL") + .andWhere("posMaster.orgRevisionId = :revisionId", { revisionId: findRevision?.id }) + .andWhere( + new Brackets((qb) => { + if (node === 4) { + qb.andWhere("posMaster.orgChild3Id IS NULL"); + qb.andWhere("posMaster.orgChild2Id = :childId", { + childId: findPosMaster?.orgChild2Id, + }); + } else if (node === 3) { + qb.andWhere("posMaster.orgChild2Id IS NULL"); + qb.andWhere("posMaster.orgChild1Id = :childId", { + childId: findPosMaster?.orgChild1Id, + }); + } else if (node === 2) { + qb.andWhere("posMaster.orgChild1Id IS NULL"); + qb.andWhere("posMaster.orgRootId = :childId", { + childId: findPosMaster?.orgRootId, + }); + } + }), + ) + .orderBy("posMaster.posMasterOrder", "ASC") + .getOne(); + } + fullName_ = + (findProfile?.prefix ?? "") + + (findProfile?.firstName ?? "") + + " " + + (findProfile?.lastName ?? ""); + position_ = findProfile?.position ?? ""; + commanderFullname_ = + (findCmd?.current_holder?.prefix ?? "") + + (findCmd?.current_holder?.firstName ?? "") + + " " + + (findCmd?.current_holder?.lastName ?? ""); + commanderPosition_ = findCmd?.current_holder?.position ?? ""; + commanderAboveFullname_ = + (findOSAB?.current_holder?.prefix ?? "") + + (findOSAB?.current_holder?.firstName ?? "") + + " " + + (findOSAB?.current_holder?.lastName ?? ""); + commanderAbovePosition_ = findOSAB?.current_holder?.position ?? ""; + + if (findCmd?.current_holderId == findProfile?.id) { + commanderFullname_ = + (findOSAB?.current_holder?.prefix ?? "") + + (findOSAB?.current_holder?.firstName ?? "") + + " " + + (findOSAB?.current_holder?.lastName ?? ""); + commanderPosition_ = findOSAB?.current_holder?.position ?? ""; + commanderAboveFullname_ = + (findTSAB?.current_holder?.prefix ?? "") + + (findTSAB?.current_holder?.firstName ?? "") + + " " + + (findTSAB?.current_holder?.lastName ?? ""); + commanderAbovePosition_ = findTSAB?.current_holder?.position ?? ""; + + const formattedDataTSAB = { + fullname: fullName_, + position: position_, + commanderAboveFullname: commanderAboveFullname_, + commanderAbovePosition: commanderAbovePosition_, + commanderFullname: commanderFullname_, + commanderPosition: commanderPosition_, + }; + return new HttpSuccess(formattedDataTSAB); + } + + const formattedData = { + fullname: fullName_, + position: position_, + commanderAboveFullname: commanderAboveFullname_, + commanderAbovePosition: commanderAbovePosition_, + commanderFullname: commanderFullname_, + commanderPosition: commanderPosition_, + }; + return new HttpSuccess(formattedData); + } + + /** + * API เช็คเลขบัตร + * + * @summary เช็คเลขบัตร (ADMIN) + * + * @param {string} id Id ทะเบียนประวัติ + */ + @Put("citizenId/{id}") + async checkCitizenIdProfile( + @Path() id: string, + @Body() + requestBody: { citizenId: string }, + ) { + const profile = await this.profileRepo.findOne({ + where: { id: Not(id), citizenId: requestBody.citizenId }, + }); + if (profile) { + throw new HttpError( + HttpStatus.INTERNAL_SERVER_ERROR, + "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", + ); + } + return new HttpSuccess(); + } + + /** + * API ค้นหาข้อมูลทะเบียนประวัติ ทดลองปฏิบัติหน้าที่ราชการ + * + * @summary ค้นหาข้อมูลทะเบียนประวัติ ทดลองปฏิบัติหน้าที่ราชการ (ADMIN) + * + */ + @Post("probation") + async getProfileBySearchKeywordProbation( + @Body() + body: { + page: number; + pageSize: number; + keyword?: string; + }, + ) { + const [findProfile, total] = await AppDataSource.getRepository(Profile) + .createQueryBuilder("profile") + .leftJoinAndSelect("profile.posLevel", "posLevel") + .leftJoinAndSelect("profile.current_holders", "current_holders") + .leftJoinAndSelect("current_holders.orgRevision", "orgRevision") + .leftJoinAndSelect("current_holders.orgRoot", "orgRoot") + .leftJoinAndSelect("current_holders.orgChild1", "orgChild1") + .leftJoinAndSelect("current_holders.orgChild2", "orgChild2") + .leftJoinAndSelect("current_holders.orgChild3", "orgChild3") + .leftJoinAndSelect("current_holders.orgChild4", "orgChild4") + .where("profile.prefix LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.firstName LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.lastName LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.position LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("posLevel.posLevelName LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orderBy("profile.citizenId", "ASC") + .skip((body.page - 1) * body.pageSize) + .take(body.pageSize) + .getManyAndCount(); + + const orgRevisionActive = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + }); + + const mapDataProfile = await Promise.all( + findProfile.map(async (item: Profile) => { + return { + id: item.id, + prefix: item.prefix, + firstName: item.firstName, + lastName: item.lastName, + position: item.position, + idcard: item.citizenId, + posLevelName: item.posLevel == null ? null : item.posLevel.posLevelName, + isProbation: item.isProbation, + orgRootName: + item.current_holders == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot == + null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot + ?.orgRootName == null + ? null + : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot + ?.orgRootName, + orgChild1Name: + item.current_holders == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 == + null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 + ?.orgChild1Name == null + ? null + : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) + ?.orgChild1?.orgChild1Name, + orgChild2Name: + item.current_holders == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 == + null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 + ?.orgChild2Name == null + ? null + : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) + ?.orgChild2?.orgChild2Name, + orgChild3Name: + item.current_holders == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 == + null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 + ?.orgChild3Name == null + ? null + : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) + ?.orgChild3?.orgChild3Name, + orgChild4Name: + item.current_holders == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 == + null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 + ?.orgChild4Name == null + ? null + : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) + ?.orgChild4?.orgChild4Name, + }; + }), + ); + + return new HttpSuccess({ data: mapDataProfile, total }); + } + + /** + * API รายชื่อราชการที่เลื่อนเงินเดือน + * + * @summary ORG_072 - รายชื่อราชการที่เลื่อนเงินเดือน #76 + * + */ + @Post("salary/gen") + async salaryGen( + @Body() + body: { + page: number; + pageSize: number; + keyword?: string; + rootId?: string; + year: number; + period: string; + }, + ) { + const findRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true }, + }); + if (!findRevision) { + throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision"); + } + + const [findPosMaster, total] = await AppDataSource.getRepository(PosMaster) + .createQueryBuilder("posMaster") + .leftJoinAndSelect("posMaster.current_holder", "current_holder") + .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") + .leftJoinAndSelect("posMaster.orgChild1", "orgChild1") + .leftJoinAndSelect("posMaster.orgChild2", "orgChild2") + .leftJoinAndSelect("posMaster.orgChild3", "orgChild3") + .leftJoinAndSelect("posMaster.orgChild4", "orgChild4") + .leftJoinAndSelect("posMaster.positions", "positions") + .leftJoinAndSelect("positions.posExecutive", "posExecutive") + .leftJoinAndSelect("current_holder.profileSalary", "profileSalary") + .leftJoinAndSelect("current_holder.profileDiscipline", "profileDiscipline") + .leftJoinAndSelect("current_holder.posLevel", "posLevel") + .leftJoinAndSelect("current_holder.posType", "posType") + .where((qb) => { + if (body.rootId) { + qb.andWhere("posMaster.orgRootId = :rootId", { rootId: body.rootId }); + } + qb.andWhere("posMaster.current_holderId IS NOT NULL"); + qb.andWhere("posMaster.orgRevisionId = :orgRevisionId", { + orgRevisionId: findRevision?.id, + }); + }) + .andWhere( + new Brackets((qb) => { + qb.where( + body.keyword != null && body.keyword != "" + ? "current_holder.prefix LIKE :keyword" + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .orWhere( + body.keyword != null && body.keyword != "" + ? "current_holder.firstName LIKE :keyword" + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .orWhere( + body.keyword != null && body.keyword != "" + ? "current_holder.lastName LIKE :keyword" + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .orWhere( + body.keyword != null && body.keyword != "" + ? "current_holder.position LIKE :keyword" + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + + .orWhere( + body.keyword != null && body.keyword != "" + ? "current_holder.citizenId LIKE :keyword" + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .orWhere( + body.keyword != null && body.keyword != "" + ? "posType.posTypeName LIKE :keyword" + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .orWhere( + body.keyword != null && body.keyword != "" + ? "posLevel.posLevelName LIKE :keyword" + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ); + }), + ) + .orderBy("current_holder.citizenId", "ASC") + .skip((body.page - 1) * body.pageSize) + .take(body.pageSize) + .getManyAndCount(); + if (!findPosMaster) { + throw new HttpError(HttpStatus.NOT_FOUND, "not found. PosMaster"); + } + + const formattedData = findPosMaster.map((item) => { + let orgShortName = ""; + + if (item.orgChild1Id === null) { + orgShortName = item.orgRoot?.orgRootShortName; + } else if (item.orgChild2Id === null) { + orgShortName = item.orgChild1?.orgChild1ShortName; + } else if (item.orgChild3Id === null) { + orgShortName = item.orgChild2?.orgChild2ShortName; + } else if (item.orgChild4Id === null) { + orgShortName = item.orgChild3?.orgChild3ShortName; + } else { + orgShortName = item.orgChild4?.orgChild4ShortName; + } + const posExecutive = + item.positions == null || + item.positions?.find((position) => position.positionIsSelected == true) == null || + item.positions?.find((position) => position.positionIsSelected == true)?.posExecutive == + null || + item.positions?.find((position) => position.positionIsSelected == true)?.posExecutive + ?.posExecutiveName == null + ? null + : item.positions?.find((position) => position.positionIsSelected == true)?.posExecutive + .posExecutiveName; + + const amount = + item.current_holder == null || item.current_holder.profileSalary.length == 0 + ? null + : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount; + let datePeriodStart = new Date( + `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, + ); + let datePeriodEnd = new Date( + `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, + ); + if (body.period.toLocaleUpperCase() == "APR") { + datePeriodStart = new Date(`${body.year}-03-31T00:00:00.000Z`); + datePeriodEnd = new Date(`${body.year}-03-31T00:00:00.000Z`); + } + if (body.period.toLocaleUpperCase() == "OCT") { + datePeriodStart = new Date(`${body.year}-09-30T00:00:00.000Z`); + datePeriodEnd = new Date(`${body.year}-09-30T00:00:00.000Z`); + } + datePeriodStart = new Date( + new Date(datePeriodStart.setDate(datePeriodStart.getDate() + 1)).setMonth( + datePeriodStart.getMonth() - 6, + ), + ); + + return { + prefix: item.current_holder.prefix, + firstName: item.current_holder.firstName, + lastName: item.current_holder.lastName, + citizenId: item.current_holder.citizenId, + posMasterNoPrefix: item.posMasterNoPrefix, + posMasterNo: item.posMasterNo, + posMasterNoSuffix: item.posMasterNoSuffix, + orgShortName: orgShortName, + position: item.current_holder.position, + posType: + item.current_holder.posType == null ? null : item.current_holder.posType.posTypeName, + posLevel: + item.current_holder.posLevel == null ? null : item.current_holder.posLevel.posLevelName, + posExecutive: posExecutive, + amount: amount ? amount : null, + // revisionId: item.orgRevisionId, + rootId: item.orgRootId, + root: item.orgRoot?.orgRootName ? item.orgRoot.orgRootName : null, + child1Id: item.orgChild1Id, + child1: item.orgChild1?.orgChild1Name ? item.orgChild1.orgChild1Name : null, + child2Id: item.orgChild2Id, + child2: item.orgChild2?.orgChild2Name ? item.orgChild2.orgChild2Name : null, + child3Id: item.orgChild3Id, + child3: item.orgChild3?.orgChild3Name ? item.orgChild3.orgChild3Name : null, + child4Id: item.orgChild4Id, + child4: item.orgChild4?.orgChild4Name ? item.orgChild4.orgChild4Name : null, + result: null, + duration: null, + isPunish: + item.current_holder.profileDiscipline.filter( + (x: any) => + new Date( + `${new Date(x.date).getFullYear()}-${String(new Date(x.date).getMonth() + 1).padStart(2, "0")}-${String(new Date(x.date).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, + ) >= datePeriodStart && + new Date( + `${new Date(x.date).getFullYear()}-${String(new Date(x.date).getMonth() + 1).padStart(2, "0")}-${String(new Date(x.date).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, + ) <= datePeriodEnd, + ).length > 0 + ? true + : false, + isSuspension: item.current_holder.dateRetire == null ? false : true, + isAbsent: false, + isLeave: false, + isRetired: + item.current_holder.birthDate == null || + calculateRetireDate(item.current_holder.birthDate).getFullYear() != body.year + ? false + : true, + }; + }); + + return new HttpSuccess({ data: formattedData, total: total }); + } + + /** + * API ข้อมูลทะเบียนประวัติตาม keycloak by revisionId + * + * @summary ข้อมูลทะเบียนประวัติตาม keycloak by revisionId (ADMIN) + * + */ + @Get("keycloak/position/{revisionId}") + async getProfileByKeycloakByRevision( + @Path() revisionId: string, + @Request() request: { user: Record }, + ) { + const profile = await this.profileRepo.findOne({ + where: { keycloak: request.user.sub }, + relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], + }); + if (!profile) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + } + + const _profile = { + profileId: profile.id, + prefix: profile.prefix, + firstName: profile.firstName, + lastName: profile.lastName, + citizenId: profile.citizenId, + position: profile.position, + posLevelName: profile.posLevel == null ? null : profile.posLevel.posLevelName, + posLevelRank: profile.posLevel == null ? null : profile.posLevel.posLevelRank, + posLevelId: profile.posLevel == null ? null : profile.posLevel.id, + posTypeName: profile.posType == null ? null : profile.posType.posTypeName, + posTypeRank: profile.posType == null ? null : profile.posType.posTypeRank, + posTypeId: profile.posType == null ? null : profile.posType.id, + rootId: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRootId, + root: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot.orgRootName, + child1Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1Id, + child1: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 + .orgChild1Name, + child2Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2Id, + child2: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 + .orgChild2Name, + child3Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3Id, + child3: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 + .orgChild3Name, + child4Id: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4Id, + child4: + profile.current_holders == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null + ? null + : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 + .orgChild4Name, + }; + return new HttpSuccess(_profile); + } +} diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index ad2dd415..2d9e6267 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -25,7 +25,7 @@ import { OrgRevision } from "../entities/OrgRevision"; import { PosMaster } from "../entities/PosMaster"; import { PosLevel } from "../entities/PosLevel"; import { PosType } from "../entities/PosType"; -import { calculateRetireDate } from "../interfaces/utils"; +import { calculateRetireDate, calculateRetireYear } from "../interfaces/utils"; import { RequestWithUser } from "../middlewares/user"; @Route("api/v1/org/profile") @@ -259,39 +259,91 @@ export class ProfileController extends Controller { @Query("pageSize") pageSize: number = 10, @Query() searchField?: "firstName" | "lastName" | "fullName" | "citizenId" | "position", @Query() searchKeyword: string = "", + @Query() posType?: string, + @Query() posLevel?: string, + @Query() yearLeave?: number, + @Query() isProbation?: boolean, + @Query() isRetire?: boolean, ) { - if (searchField === "fullName") { - const [record, total] = await this.profileRepo - .createQueryBuilder("profile") - .leftJoinAndSelect("profile.posLevel", "posLevel") - .leftJoinAndSelect("profile.posType", "posType") - .leftJoinAndSelect("profile.gender", "gender") - .leftJoinAndSelect("profile.relationship", "relationship") - .leftJoinAndSelect("profile.bloodGroup", "bloodGroup") - .where("CONCAT(profile.firstName, ' ', profile.lastName) LIKE :fullName", { - fullName: `%${searchKeyword}%`, - }) - .skip((page - 1) * pageSize) - .take(pageSize) - .getManyAndCount(); - - return new HttpSuccess({ data: record, total }); + let queryLike = + "CONCAT(profile.prefix, profile.firstName, ' ', profile.lastName) LIKE :keyword"; + if (searchField == "citizenId") { + queryLike = "profile.citizenId LIKE :keyword"; + } else if (searchField == "position") { + queryLike = "profile.position LIKE :keyword"; } + const [record, total] = await this.profileRepo + .createQueryBuilder("profile") + .leftJoinAndSelect("profile.posLevel", "posLevel") + .leftJoinAndSelect("profile.posType", "posType") + .leftJoinAndSelect("profile.gender", "gender") + .leftJoinAndSelect("profile.relationship", "relationship") + .leftJoinAndSelect("profile.bloodGroup", "bloodGroup") + .leftJoinAndSelect("profile.current_holders", "current_holders") + .leftJoinAndSelect("current_holders.orgRoot", "orgRoot") + .leftJoinAndSelect("current_holders.orgChild1", "orgChild1") + .leftJoinAndSelect("current_holders.orgChild2", "orgChild2") + .leftJoinAndSelect("current_holders.orgChild3", "orgChild3") + .leftJoinAndSelect("current_holders.orgChild4", "orgChild4") + .select([ + "profile.id", + "profile.prefix", + "profile.firstName", + "profile.lastName", + "profile.citizenId", + "profile.birthDate", + "profile.isProbation", + "profile.dateRetire", + "profile.position", + "posType.posTypeName", + "posLevel.posLevelName", + "current_holders.posMasterNo", + // "orgRoot?.orgRootShortName", + // "orgChild1?.orgRootShortName", + // "orgChild2?.orgRootShortName", + // "orgChild3?.orgRootShortName", + // "orgChild4?.orgRootShortName", + ]) + .andWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? queryLike + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .andWhere( + posType != undefined && posType != null && posType != "" + ? "posType.posTypeName LIKE :keyword1" + : "1=1", + { + keyword1: `${posType}`, + }, + ) + .andWhere( + posLevel != undefined && posLevel != null && posLevel != "" + ? "posLevel.posLevelName LIKE :keyword2" + : "1=1", + { + keyword2: `${posLevel}`, + }, + ) + .andWhere( + isProbation != undefined && isProbation != null + ? `profile.isProbation = ${isProbation}` + : "1=1", + ) + .andWhere( + isRetire != undefined && isRetire != null + ? isRetire == true + ? `profile.dateRetire IS null` + : `profile.dateRetire IS NOT NULL` + : "1=1", + ) + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); - const [record, total] = await this.profileRepo.findAndCount({ - relations: { - posLevel: true, - posType: true, - gender: true, - relationship: true, - bloodGroup: true, - }, - where: - searchField && searchKeyword ? [{ [searchField]: Like(`%${searchKeyword}%`) }] : undefined, - order: { createdAt: "ASC" }, - skip: (page - 1) * pageSize, - take: pageSize, - }); return new HttpSuccess({ data: record, total }); } diff --git a/src/entities/Profile.ts b/src/entities/Profile.ts index f8218989..fe2114d0 100644 --- a/src/entities/Profile.ts +++ b/src/entities/Profile.ts @@ -22,6 +22,7 @@ import { Gender } from "./Gender"; import { Relationship } from "./Relationship"; import { BloodGroup } from "./BloodGroup"; import { Religion } from "./Religion"; +import { calculateRetireYear } from "../interfaces/utils"; @Entity("profile") export class Profile extends EntityBase { @@ -126,6 +127,12 @@ export class Profile extends EntityBase { }) isProbation: boolean; + @Column({ + comment: "เกษียณ", + default: false, + }) + isLeave: boolean; + @Column({ nullable: true, type: "datetime", @@ -263,6 +270,10 @@ export class Profile extends EntityBase { @ManyToOne(() => PosType, (posType) => posType.profiles) @JoinColumn({ name: "posTypeId" }) posType: PosType; + + // calculateRetireYear(): number { + // return calculateRetireYear(this.birthDate); + // } } @Entity("profileHistory") diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index d9edd9d9..b791b9e9 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -32,8 +32,8 @@ export function calculateRetireDate(birthDate: Date) { if (dd >= 2) flag = false; break; case 11: + break; case 12: - flag = false; break; } @@ -41,3 +41,25 @@ export function calculateRetireDate(birthDate: Date) { return new Date(`${yy + 61}-09-30T00:00:00.000+07:00`); } + +export function calculateRetireYear(birthDate: Date) { + let dd = birthDate.getDate(); + let mm = birthDate.getMonth(); + let yy = birthDate.getFullYear(); + + let flag = true; + + switch (mm) { + case 10: + if (dd >= 2) flag = false; + break; + case 11: + break; + case 12: + break; + } + + if (flag) return yy + 60; + + return yy + 61; +} diff --git a/src/migration/1711357767283-update_table_profile_add_isLeave.ts b/src/migration/1711357767283-update_table_profile_add_isLeave.ts new file mode 100644 index 00000000..e8254f09 --- /dev/null +++ b/src/migration/1711357767283-update_table_profile_add_isLeave.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableProfileAddIsLeave1711357767283 implements MigrationInterface { + name = 'UpdateTableProfileAddIsLeave1711357767283' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profile\` ADD \`isLeave\` tinyint NOT NULL COMMENT 'เกษียณ' DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`profileHistory\` ADD \`isLeave\` tinyint NOT NULL COMMENT 'เกษียณ' DEFAULT 0`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileHistory\` DROP COLUMN \`isLeave\``); + await queryRunner.query(`ALTER TABLE \`profile\` DROP COLUMN \`isLeave\``); + } + +}