diff --git a/src/controllers/EmployeePosTypeController.ts b/src/controllers/EmployeePosTypeController.ts index 08b9859a..05209338 100644 --- a/src/controllers/EmployeePosTypeController.ts +++ b/src/controllers/EmployeePosTypeController.ts @@ -170,6 +170,7 @@ export class EmployeePosTypeController extends Controller { id: empPosLevel.id, posLevelName: empPosLevel.posLevelName, posLevelRank: empPosLevel.posLevelRank, + posLevelAuthority: empPosLevel.posLevelAuthority, })), }; @@ -198,6 +199,7 @@ export class EmployeePosTypeController extends Controller { id: empPosLevel.id, posLevelName: empPosLevel.posLevelName, posLevelRank: empPosLevel.posLevelRank, + posLevelAuthority: empPosLevel.posLevelAuthority, })), })); return new HttpSuccess(mapEmpPosType); diff --git a/src/controllers/EmployeePositionController.ts b/src/controllers/EmployeePositionController.ts index 58c1160d..cdfe1b66 100644 --- a/src/controllers/EmployeePositionController.ts +++ b/src/controllers/EmployeePositionController.ts @@ -28,13 +28,13 @@ import { EmployeePosType } from "../entities/EmployeePosType"; import { EmployeePosLevel } from "../entities/EmployeePosLevel"; import { CreateEmployeePosMaster, EmployeePosMaster } from "../entities/EmployeePosMaster"; import { EmployeePosition } from "../entities/EmployeePosition"; -import { Profile } from "../entities/Profile"; import { OrgRevision } from "../entities/OrgRevision"; import { OrgRoot } from "../entities/OrgRoot"; import { OrgChild1 } from "../entities/OrgChild1"; import { OrgChild2 } from "../entities/OrgChild2"; import { OrgChild3 } from "../entities/OrgChild3"; import { OrgChild4 } from "../entities/OrgChild4"; +import { ProfileEmployee } from "../entities/ProfileEmployee"; @Route("api/v1/org/employee/pos") @Tags("Employee") @@ -50,7 +50,7 @@ export class EmployeePositionController extends Controller { private employeePosLevelRepository = AppDataSource.getRepository(EmployeePosLevel); private employeePosMasterRepository = AppDataSource.getRepository(EmployeePosMaster); private employeePositionRepository = AppDataSource.getRepository(EmployeePosition); - private profileRepository = AppDataSource.getRepository(Profile); + private profileRepository = AppDataSource.getRepository(ProfileEmployee); private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); private orgRootRepository = AppDataSource.getRepository(OrgRoot); private child1Repository = AppDataSource.getRepository(OrgChild1); @@ -227,7 +227,7 @@ export class EmployeePositionController extends Controller { @Get("position/{id}") async detailPosition(@Path() id: string) { const posMaster = await this.employeePosMasterRepository.findOne({ - where: { id:id }, + where: { id: id }, }); if (!posMaster) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); @@ -2015,6 +2015,7 @@ export class EmployeePositionController extends Controller { await this.employeePosMasterRepository.update(id, { isSit: false, next_holderId: null, + current_holderId: null, }); dataMaster.positions.forEach(async (position) => { diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts new file mode 100644 index 00000000..b7b7f06f --- /dev/null +++ b/src/controllers/ProfileEmployeeController.ts @@ -0,0 +1,1208 @@ +import { + Controller, + Post, + Put, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + SuccessResponse, + Response, + Get, + Query, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatusCode from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { Brackets, IsNull, Like, Not } from "typeorm"; +import { OrgRevision } from "../entities/OrgRevision"; +import { calculateRetireDate } from "../interfaces/utils"; +import { EmployeePosMaster } from "../entities/EmployeePosMaster"; +import { ProfileEmployee, CreateProfileEmployee } from "../entities/ProfileEmployee"; +import { EmployeePosLevel } from "../entities/EmployeePosLevel"; +import { EmployeePosType } from "../entities/EmployeePosType"; + +@Route("api/v1/org/profile-employee") +@Tags("Profile") +@Security("bearerAuth") +@Response( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) +@SuccessResponse(HttpStatusCode.OK, "สำเร็จ") +export class ProfileEmployeeController extends Controller { + private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); + private posMasterRepository = AppDataSource.getRepository(EmployeePosMaster); + private profileRepository = AppDataSource.getRepository(ProfileEmployee); + private posLevelRepository = AppDataSource.getRepository(EmployeePosLevel); + private posTypeRepository = AppDataSource.getRepository(EmployeePosType); + + /** + * API สร้างทะเบียนประวัติ + * + * @summary ORG_065 - สร้างทะเบียนประวัติ (ADMIN) #70 + * + */ + @Post() + async createProfile( + @Body() + requestBody: CreateProfileEmployee, + @Request() request: { user: Record }, + ) { + const _profile = await this.profileRepository.findOne({ + where: { citizenId: requestBody.citizenId }, + }); + if (_profile) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", + ); + } + if (requestBody.posLevelId == "") { + requestBody.posLevelId = null; + } + if (requestBody.posLevelId) { + const checkPosLevel = await this.posLevelRepository.findOne({ + where: { id: requestBody.posLevelId }, + }); + if (!checkPosLevel) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); + } + } + + if (requestBody.posTypeId == "") { + requestBody.posTypeId = null; + } + if (requestBody.posTypeId) { + const checkPosType = await this.posTypeRepository.findOne({ + where: { id: requestBody.posTypeId }, + }); + if (!checkPosType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); + } + } + + const checkCitizenId = await this.profileRepository.findOne({ + where: { citizenId: requestBody.citizenId }, + }); + + if (checkCitizenId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); + } + + const profile = Object.assign(new ProfileEmployee(), requestBody); + profile.createdUserId = request.user.sub; + profile.createdFullName = request.user.name; + profile.lastUpdateUserId = request.user.sub; + profile.lastUpdateFullName = request.user.name; + await this.profileRepository.save(profile); + return new HttpSuccess(); + } + + /** + * API แก้ไขทะเบียนประวัติ + * + * @summary ORG_065 - แก้ไขทะเบียนประวัติ (ADMIN) #70 + * + * @param {string} id Id ทะเบียนประวัติ + */ + @Put("{id}") + async updateProfile( + @Path() id: string, + @Body() + requestBody: CreateProfileEmployee, + @Request() request: { user: Record }, + ) { + const profile = await this.profileRepository.findOne({ where: { id: id } }); + if (!profile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); + } + + const _profile = await this.profileRepository.findOne({ + where: { id: Not(id), citizenId: requestBody.citizenId }, + }); + if (_profile) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", + ); + } + + if (requestBody.posLevelId == "") { + requestBody.posLevelId = null; + } + if (requestBody.posLevelId) { + const checkPosLevel = await this.posLevelRepository.findOne({ + where: { id: requestBody.posLevelId }, + }); + if (!checkPosLevel) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); + } + } + + if (requestBody.posTypeId == "") { + requestBody.posTypeId = null; + } + if (requestBody.posTypeId) { + const checkPosType = await this.posTypeRepository.findOne({ + where: { id: requestBody.posTypeId }, + }); + if (!checkPosType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); + } + } + + const checkCitizenId = await this.profileRepository.findOne({ + where: { + id: Not(id), + citizenId: requestBody.citizenId, + }, + }); + + if (checkCitizenId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); + } + + profile.lastUpdateUserId = request.user.sub; + profile.lastUpdateFullName = request.user.name; + this.profileRepository.merge(profile, requestBody); + await this.profileRepository.save(profile); + return new HttpSuccess(); + } + + /** + * API ลบทะเบียนประวัติ + * + * @summary ORG_065 - ลบทะเบียนประวัติ (ADMIN) #70 + * + * @param {string} id Id ทะเบียนประวัติ + */ + @Delete("{id}") + async deleteProfile(@Path() id: string) { + const delProfile = await this.profileRepository.findOne({ + where: { id }, + }); + if (!delProfile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); + } + await this.profileRepository.delete({ id: id }); + return new HttpSuccess(); + } + + /** + * API รายละเอียดรายการทะเบียนประวัติ + * + * @summary ORG_065 - รายละเอียดรายการทะเบียนประวัติ (ADMIN) #70 + * + * @param {string} id Id ทะเบียนประวัติ + */ + @Get("{id}") + async detailProfile(@Path() id: string) { + const profile = await this.profileRepository.findOne({ + where: { id }, + select: [ + "id", + "prefix", + "firstName", + "lastName", + "citizenId", + "position", + "posLevelId", + "posTypeId", + ], + }); + if (!profile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(profile); + } + + /** + * API รายการทะเบียนประวัติ + * + * @summary ORG_065 - รายการทะเบียนประวัติ (ADMIN) #70 + * + */ + @Get() + async listProfile( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, + @Query("keyword") keyword?: string, + ) { + const [profile, total] = await this.profileRepository.findAndCount({ + select: [ + "id", + "prefix", + "firstName", + "lastName", + "citizenId", + "position", + "posLevelId", + "posTypeId", + ], + order: { createdAt: "ASC" }, + skip: (page - 1) * pageSize, + take: pageSize, + }); + if (keyword != undefined && keyword !== "") { + const formattedKeyword = keyword.toLowerCase().replace(/\s+/g, ""); + const filteredProfile = profile.filter( + (x) => + (x.prefix + x.firstName + x.lastName).replace(/\s+/g, "").includes(formattedKeyword) || + x.citizenId?.toString().includes(keyword) || + x.position?.toString().includes(keyword), + ); + + const formattedData = filteredProfile.map((item) => ({ + id: item.id, + prefix: item.prefix, + firstName: item.firstName, + lastName: item.lastName, + citizenId: item.citizenId, + position: item.position, + posLevelId: item.posLevelId, + posTypeId: item.posTypeId, + })); + + return new HttpSuccess({ data: formattedData, total: formattedData.length }); + } + + // if (!profile) { + // return new HttpSuccess([]); + // } + + const formattedData = profile.map((item) => ({ + id: item.id, + prefix: item.prefix, + firstName: item.firstName, + lastName: item.lastName, + citizenId: item.citizenId, + position: item.position, + posLevelId: item.posLevelId, + posTypeId: item.posTypeId, + })); + return new HttpSuccess({ data: formattedData, 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.orgRevisionRepository.findOne({ + where: { + orgRevisionIsDraft: true, + orgRevisionIsCurrent: false, + }, + relations: ["posMasters"], + }); + if (!orgRevision) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); + } + const [profiles, total] = await this.profileRepository + .createQueryBuilder("profileEmployee") + .leftJoinAndSelect("profileEmployee.next_holders", "next_holders") + .leftJoinAndSelect("profileEmployee.posLevel", "posLevel") + .leftJoinAndSelect("profileEmployee.posType", "posType") + .where( + requestBody.position != null && requestBody.position != "" + ? "profileEmployee.position LIKE :position" + : "1=1", + { + position: `%${requestBody.position}%`, + }, + ) + .andWhere( + new Brackets((qb) => { + qb.where( + requestBody.keyword != null && requestBody.keyword != "" + ? "profileEmployee.prefix LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ) + .orWhere( + requestBody.keyword != null && requestBody.keyword != "" + ? "profileEmployee.firstName LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ) + .orWhere( + requestBody.keyword != null && requestBody.keyword != "" + ? "profileEmployee.lastName LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ) + .orWhere( + requestBody.keyword != null && requestBody.keyword != "" + ? "profileEmployee.citizenId LIKE :keyword" + : "1=1", + { + keyword: `%${requestBody.keyword}%`, + }, + ); + }), + ) + .andWhere( + requestBody.posTypeId != null && requestBody.posTypeId != "" + ? "profileEmployee.posTypeId LIKE :posTypeId" + : "1=1", + { + posTypeId: `%${requestBody.posTypeId}%`, + }, + ) + .andWhere( + requestBody.posLevelId != null && requestBody.posLevelId != "" + ? "profileEmployee.posLevelId LIKE :posLevelId" + : "1=1", + { + posLevelId: `%${requestBody.posLevelId}%`, + }, + ) + .andWhere( + new Brackets((qb) => { + qb.where("next_holders.id IS NULL").orWhere("next_holders.id NOT IN (:...ids)", { + ids: orgRevision.posMasters.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.profileRepository.findOne({ + where: { keycloak: request.user.sub }, + relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], + }); + if (!profile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + } + + const orgRevisionPublish = await this.orgRevisionRepository + .createQueryBuilder("orgRevision") + .where("orgRevision.orgRevisionIsDraft = false") + .andWhere("orgRevision.orgRevisionIsCurrent = true") + .getOne(); + if (!orgRevisionPublish) { + throw new HttpError(HttpStatusCode.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.profileRepository.find({ + where: { citizenId: Like(`%${body.keyword}%`) }, + relations: ["posType", "posLevel"], + }); + break; + + case "firstname": + findProfile = await this.profileRepository.find({ + where: { firstName: Like(`%${body.keyword}%`) }, + relations: ["posType", "posLevel"], + }); + break; + + case "lastname": + findProfile = await this.profileRepository.find({ + where: { lastName: Like(`%${body.keyword}%`) }, + relations: ["posType", "posLevel"], + }); + break; + + default: + findProfile = await this.profileRepository.find({ + relations: ["posType", "posLevel"], + }); + break; + } + + const mapDataProfile = await Promise.all( + findProfile.map(async (item: ProfileEmployee) => { + 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.profileRepository.findOne({ + where: { keycloak: request.user.sub }, + }); + + const findRevision = await this.orgRevisionRepository.findOne({ + where: { + orgRevisionIsCurrent: true, + }, + }); + + const findPosMaster = await this.posMasterRepository.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.posMasterRepository.findOne({ + where: { + current_holderId: Not(IsNull()) || Not(""), + orgRevisionId: findRevision?.id, + ...condition, + }, + relations: ["current_holder"], + order: { posMasterOrder: "ASC" }, + }); + let findOSAB: EmployeePosMaster | null = null; + let findTSAB: EmployeePosMaster | null = null; + //หาผู้บังคับบัญชาที่เหนือขึ้นไปอีก 1 ขั้น + if (node !== 0) { + findOSAB = await AppDataSource.getRepository(EmployeePosMaster) + .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(EmployeePosMaster) + .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.profileRepository.findOne({ + where: { id: Not(id), citizenId: requestBody.citizenId }, + }); + if (profile) { + throw new HttpError( + HttpStatusCode.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(ProfileEmployee) + .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.orgRevisionRepository.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + }); + + const mapDataProfile = await Promise.all( + findProfile.map(async (item: ProfileEmployee) => { + 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.orgRevisionRepository.findOne({ + where: { orgRevisionIsCurrent: true }, + }); + if (!findRevision) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. OrgRevision"); + } + + const [findPosMaster, total] = await AppDataSource.getRepository(EmployeePosMaster) + .createQueryBuilder("employeePosMaster") + .leftJoinAndSelect("employeePosMaster.current_holder", "current_holder") + .leftJoinAndSelect("employeePosMaster.orgRoot", "orgRoot") + .leftJoinAndSelect("employeePosMaster.orgChild1", "orgChild1") + .leftJoinAndSelect("employeePosMaster.orgChild2", "orgChild2") + .leftJoinAndSelect("employeePosMaster.orgChild3", "orgChild3") + .leftJoinAndSelect("employeePosMaster.orgChild4", "orgChild4") + .leftJoinAndSelect("employeePosMaster.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("employeePosMaster.orgRootId = :rootId", { rootId: body.rootId }); + } + qb.andWhere("employeePosMaster.current_holderId IS NOT NULL"); + qb.andWhere("employeePosMaster.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(HttpStatusCode.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 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.posTypeName, + posLevel: item.current_holder.posLevel.posLevelName, + amount: null, + // 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: false, + // 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.profileRepository.findOne({ + where: { keycloak: request.user.sub }, + relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], + }); + if (!profile) { + throw new HttpError(HttpStatusCode.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/entities/EmployeePosLevel.ts b/src/entities/EmployeePosLevel.ts index 6380ac04..39ba8a99 100644 --- a/src/entities/EmployeePosLevel.ts +++ b/src/entities/EmployeePosLevel.ts @@ -2,8 +2,10 @@ import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; import { EmployeePosDict } from "./EmployeePosDict"; import { EmployeePosType } from "./EmployeePosType"; +import { EmployeePosition } from "./EmployeePosition"; +import { ProfileEmployee } from "./ProfileEmployee"; -enum EmployeePosLevelAuthoritys { +enum EmployeePosLevelAuthoritys { HEAD = "HEAD", DEPUTY = "DEPUTY", GOVERNOR = "GOVERNOR", @@ -42,8 +44,14 @@ export class EmployeePosLevel extends EntityBase { @JoinColumn({ name: "posTypeId" }) posType: EmployeePosType; + @OneToMany(() => EmployeePosition, (position) => position.posLevel) + positions: EmployeePosition[]; + @OneToMany(() => EmployeePosDict, (posDict) => posDict.posLevel) posDicts: EmployeePosDict[]; + + @OneToMany(() => ProfileEmployee, (profile) => profile.posLevel) + profiles: ProfileEmployee[]; } export class CreateEmployeePosLevel { @@ -60,4 +68,6 @@ export class CreateEmployeePosLevel { posTypeId: string; } -export type UpdateEmployeePosLevel = Partial & { posLevelAuthority: EmployeePosLevelAuthoritys }; +export type UpdateEmployeePosLevel = Partial & { + posLevelAuthority: EmployeePosLevelAuthoritys; +}; diff --git a/src/entities/EmployeePosMaster.ts b/src/entities/EmployeePosMaster.ts index bef2b22c..20dcf1eb 100644 --- a/src/entities/EmployeePosMaster.ts +++ b/src/entities/EmployeePosMaster.ts @@ -9,6 +9,7 @@ import { OrgChild2 } from "./OrgChild2"; import { OrgChild3 } from "./OrgChild3"; import { OrgChild4 } from "./OrgChild4"; import { Profile } from "./Profile"; +import { ProfileEmployee } from "./ProfileEmployee"; enum EmployeePosMasterLine { MAIN = "MAIN", @@ -174,13 +175,13 @@ export class EmployeePosMaster extends EntityBase { @JoinColumn({ name: "orgChild4Id" }) orgChild4: OrgChild4; - @ManyToOne(() => Profile, (posMaster) => posMaster.current_holders) + @ManyToOne(() => ProfileEmployee, (posMaster) => posMaster.current_holders) @JoinColumn({ name: "current_holderId" }) - current_holder: Profile; + current_holder: ProfileEmployee; - @ManyToOne(() => Profile, (posMaster) => posMaster.next_holders) + @ManyToOne(() => ProfileEmployee, (posMaster) => posMaster.next_holders) @JoinColumn({ name: "next_holderId" }) - next_holder: Profile; + next_holder: ProfileEmployee; @OneToMany(() => EmployeePosition, (position) => position.posMaster) positions: EmployeePosition[]; diff --git a/src/entities/EmployeePosType.ts b/src/entities/EmployeePosType.ts index cdb4e4dc..2fd02b2e 100644 --- a/src/entities/EmployeePosType.ts +++ b/src/entities/EmployeePosType.ts @@ -2,6 +2,8 @@ import { Entity, Column, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; import { EmployeePosDict } from "./EmployeePosDict"; import { EmployeePosLevel } from "./EmployeePosLevel"; +import { EmployeePosition } from "./EmployeePosition"; +import { ProfileEmployee } from "./ProfileEmployee"; @Entity("employeePosType") export class EmployeePosType extends EntityBase { @@ -29,8 +31,14 @@ export class EmployeePosType extends EntityBase { @OneToMany(() => EmployeePosLevel, (posLevel) => posLevel.posType) posLevels: EmployeePosLevel[]; + @OneToMany(() => EmployeePosition, (position) => position.posType) + positions: EmployeePosition[]; + @OneToMany(() => EmployeePosDict, (posDict) => posDict.posType) posDicts: EmployeePosDict[]; + + @OneToMany(() => ProfileEmployee, (profile) => profile.posType) + profiles: ProfileEmployee[]; } export class CreateEmployeePosType { diff --git a/src/entities/PosLevel.ts b/src/entities/PosLevel.ts index 94683855..e7c00d7d 100644 --- a/src/entities/PosLevel.ts +++ b/src/entities/PosLevel.ts @@ -55,7 +55,7 @@ export class PosLevel extends EntityBase { posDicts: PosDict[]; @OneToMany(() => Profile, (profile) => profile.posLevel) - posLevels: Profile[]; + profiles: Profile[]; } export class CreatePosLevel { diff --git a/src/entities/PosType.ts b/src/entities/PosType.ts index e8fc862f..de9ab4f7 100644 --- a/src/entities/PosType.ts +++ b/src/entities/PosType.ts @@ -33,7 +33,7 @@ export class PosType extends EntityBase { posDicts: PosDict[]; @OneToMany(() => Profile, (profile) => profile.posType) - posTypes: Profile[]; + profiles: Profile[]; } export class CreatePosType { diff --git a/src/entities/Profile.ts b/src/entities/Profile.ts index 11bd6e0c..6fbfd362 100644 --- a/src/entities/Profile.ts +++ b/src/entities/Profile.ts @@ -135,7 +135,7 @@ export class Profile extends EntityBase { default: null, }) birthDate: Date; - + @OneToMany(() => PosMaster, (posMaster) => posMaster.current_holder) current_holders: PosMaster[]; @@ -177,15 +177,15 @@ export class Profile extends EntityBase { @OneToMany(() => ProfileNopaid, (profileNopaid) => profileNopaid.profile) profileNopaids: ProfileNopaid[]; - + @OneToMany(() => ProfileOther, (profileOther) => profileOther.profile) profileOthers: ProfileOther[]; - @ManyToOne(() => PosLevel, (posLevel) => posLevel.posLevels) + @ManyToOne(() => PosLevel, (posLevel) => posLevel.profiles) @JoinColumn({ name: "posLevelId" }) posLevel: PosLevel; - @ManyToOne(() => PosType, (posType) => posType.posTypes) + @ManyToOne(() => PosType, (posType) => posType.profiles) @JoinColumn({ name: "posTypeId" }) posType: PosType; } diff --git a/src/entities/ProfileEmployee.ts b/src/entities/ProfileEmployee.ts new file mode 100644 index 00000000..f672c379 --- /dev/null +++ b/src/entities/ProfileEmployee.ts @@ -0,0 +1,219 @@ +import { Entity, Column, OneToMany, OneToOne, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { PosMaster } from "./PosMaster"; +import { PosLevel } from "./PosLevel"; +import { PosType } from "./PosType"; +import { ProfileSalary } from "./ProfileSalary"; +import { ProfileDiscipline } from "./ProfileDiscipline"; +import { ProfileCertificate } from "./ProfileCertificate"; +import { ProfileEducation } from "./ProfileEducation"; +import { ProfileTraining } from "./ProfileTraining"; +import { ProfileInsignia } from "./ProfileInsignia"; +import { ProfileHonor } from "./ProfileHonor"; +import { ProfileAssessment } from "./ProfileAssessment"; +import { ProfileLeave } from "./ProfileLeave"; +import { ProfileAbility } from "./ProfileAbility"; +import { ProfileDuty } from "./ProfileDuty"; +import { ProfileNopaid } from "./ProfileNopaid"; +import { ProfileOther } from "./ProfileOther"; +import { EmployeePosLevel } from "./EmployeePosLevel"; +import { EmployeePosType } from "./EmployeePosType"; +import { EmployeePosMaster } from "./EmployeePosMaster"; + +@Entity("profileEmployee") +export class ProfileEmployee extends EntityBase { + @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; + + @Column({ + nullable: true, + length: 40, + comment: "ไอดีกลุ่มงานตำแหน่ง", + }) + posTypeId: string | null; + + @Column({ + nullable: true, + length: 255, + comment: "อีเมล", + }) + email: string; + + @Column({ + nullable: true, + length: 20, + comment: "เบอร์โทร", + }) + phone: string; + + // @Column({ + // nullable: true, + // length: 40, + // comment: + // "คนครองปัจจุบัน เมื่อทำสำเนาโครงสร้างและตำแหน่งพร้อมกับคนครองมา คนครองจะอยู่ในฟิลด์นี้", + // default: null, + // unique: false, + // }) + // current_holderId: string; + + // @Column({ + // nullable: true, + // length: 40, + // comment: + // "คนที่กำลังจะมาครอง ตอนปรับโครงสร้าง ถ้าเลือกให้ใครมาครอง ProfileId ของคนนั้นจะมาอยู่ในช่องนี้ รวมทั้งตอนเลือกตำแหน่งเพื่อบรรจุ แต่งตั้ง เลื่อน ย้าย ในระบบบรรจุแต่งตั้งด้วย", + // default: null, + // unique: false, + // }) + // next_holderId: string; + @Column({ + nullable: true, + comment: "id keycloak", + length: 40, + default: null, + }) + keycloak: string; + + @Column({ + comment: "ทดลองปฏิบัติหน้าที่", + default: false, + }) + isProbation: boolean; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันที่พักราชการ", + default: null, + }) + dateRetire: Date; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันเกิด", + default: null, + }) + birthDate: Date; + + @OneToMany(() => EmployeePosMaster, (posMaster) => posMaster.current_holder) + current_holders: EmployeePosMaster[]; + + @OneToMany(() => EmployeePosMaster, (posMaster) => posMaster.next_holder) + next_holders: EmployeePosMaster[]; + + // @OneToMany(() => ProfileSalary, (profileSalary) => profileSalary.profile) + // profileSalary: ProfileSalary[]; + + // @OneToMany(() => ProfileDiscipline, (profileDiscipline) => profileDiscipline.profile) + // profileDiscipline: ProfileDiscipline[]; + + // @OneToMany(() => ProfileCertificate, (profileCertificate) => profileCertificate.profile) + // profileCertificates: ProfileCertificate[]; + + // @OneToMany(() => ProfileEducation, (profileEducation) => profileEducation.profile) + // profileEducations: ProfileEducation[]; + + // @OneToMany(() => ProfileTraining, (profileTraining) => profileTraining.profile) + // profileTrainings: ProfileTraining[]; + + // @OneToMany(() => ProfileInsignia, (profileInsignia) => profileInsignia.profile) + // profileInsignias: ProfileInsignia[]; + + // @OneToMany(() => ProfileHonor, (profileHonor) => profileHonor.profile) + // profileHonors: ProfileHonor[]; + + // @OneToMany(() => ProfileAssessment, (profileAssessment) => profileAssessment.profile) + // profileAssessments: ProfileAssessment[]; + + // @OneToMany(() => ProfileLeave, (profileLeave) => profileLeave.profile) + // profileLeaves: ProfileLeave[]; + + // @OneToMany(() => ProfileAbility, (profileAbility) => profileAbility.profile) + // profileAbilities: ProfileAbility[]; + + // @OneToMany(() => ProfileDuty, (profileDuty) => profileDuty.profile) + // profileDutys: ProfileDuty[]; + + // @OneToMany(() => ProfileNopaid, (profileNopaid) => profileNopaid.profile) + // profileNopaids: ProfileNopaid[]; + + // @OneToMany(() => ProfileOther, (profileOther) => profileOther.profile) + // profileOthers: ProfileOther[]; + + @ManyToOne(() => EmployeePosLevel, (posLevel) => posLevel.profiles) + @JoinColumn({ name: "posLevelId" }) + posLevel: EmployeePosLevel; + + @ManyToOne(() => EmployeePosType, (posType) => posType.profiles) + @JoinColumn({ name: "posTypeId" }) + posType: EmployeePosType; +} + +export class CreateProfileEmployee { + @Column() + prefix: string; + + @Column() + firstName: string; + + @Column() + lastName: string; + + @Column() + citizenId: string; + + @Column() + position: string; + + @Column("uuid") + posLevelId: string | null; + + @Column("uuid") + posTypeId: string | null; +} + +export type UpdateProfileEmployee = Partial; diff --git a/src/migration/1710487869374-add_table_profileEmployee.ts b/src/migration/1710487869374-add_table_profileEmployee.ts new file mode 100644 index 00000000..3296c5cb --- /dev/null +++ b/src/migration/1710487869374-add_table_profileEmployee.ts @@ -0,0 +1,26 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddTableProfileEmployee1710487869374 implements MigrationInterface { + name = 'AddTableProfileEmployee1710487869374' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` DROP FOREIGN KEY \`FK_00221b20fdf6d460a86f108fc6d\``); + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` DROP FOREIGN KEY \`FK_41945621a3f1e716dc3b2d994c3\``); + await queryRunner.query(`CREATE TABLE \`profileEmployee\` (\`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', \`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 'ไอดีกลุ่มงานตำแหน่ง', \`email\` varchar(255) NULL COMMENT 'อีเมล', \`phone\` varchar(20) NULL COMMENT 'เบอร์โทร', \`keycloak\` varchar(40) NULL COMMENT 'id keycloak', \`isProbation\` tinyint NOT NULL COMMENT 'ทดลองปฏิบัติหน้าที่' DEFAULT 0, \`dateRetire\` datetime NULL COMMENT 'วันที่พักราชการ', \`birthDate\` datetime NULL COMMENT 'วันเกิด', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` ADD CONSTRAINT \`FK_00221b20fdf6d460a86f108fc6d\` FOREIGN KEY (\`current_holderId\`) REFERENCES \`profileEmployee\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` ADD CONSTRAINT \`FK_41945621a3f1e716dc3b2d994c3\` FOREIGN KEY (\`next_holderId\`) REFERENCES \`profileEmployee\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`profileEmployee\` ADD CONSTRAINT \`FK_cc1b55a08a76d0d3e254c37e11e\` FOREIGN KEY (\`posLevelId\`) REFERENCES \`employeePosLevel\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`profileEmployee\` ADD CONSTRAINT \`FK_773469f2924994e83e9835c48f9\` 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 \`profileEmployee\` DROP FOREIGN KEY \`FK_773469f2924994e83e9835c48f9\``); + await queryRunner.query(`ALTER TABLE \`profileEmployee\` DROP FOREIGN KEY \`FK_cc1b55a08a76d0d3e254c37e11e\``); + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` DROP FOREIGN KEY \`FK_41945621a3f1e716dc3b2d994c3\``); + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` DROP FOREIGN KEY \`FK_00221b20fdf6d460a86f108fc6d\``); + await queryRunner.query(`DROP TABLE \`profileEmployee\``); + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` ADD CONSTRAINT \`FK_41945621a3f1e716dc3b2d994c3\` FOREIGN KEY (\`next_holderId\`) REFERENCES \`profile\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeePosMaster\` ADD CONSTRAINT \`FK_00221b20fdf6d460a86f108fc6d\` FOREIGN KEY (\`current_holderId\`) REFERENCES \`profile\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + +}