From b369a52734895d8072346f8488174d953185d4d6 Mon Sep 17 00:00:00 2001 From: kittapath Date: Thu, 20 Feb 2025 13:29:29 +0700 Subject: [PATCH] add posmaster temp --- .../EmployeeTempPositionController.ts | 2357 +++++++++++++++++ src/entities/AuthRole.ts | 4 + src/entities/EmployeePosMaster.ts | 12 +- src/entities/EmployeePosition.ts | 11 + src/entities/EmployeeTempPosMaster.ts | 271 ++ src/entities/OrgChild1.ts | 11 + src/entities/OrgChild2.ts | 11 + src/entities/OrgChild3.ts | 11 + src/entities/OrgChild4.ts | 11 + src/entities/OrgRevision.ts | 7 + src/entities/OrgRoot.ts | 8 + src/entities/ProfileEmployee.ts | 7 + .../1740032788782-addtableorgtemp.ts | 36 + 13 files changed, 2751 insertions(+), 6 deletions(-) create mode 100644 src/controllers/EmployeeTempPositionController.ts create mode 100644 src/entities/EmployeeTempPosMaster.ts create mode 100644 src/migration/1740032788782-addtableorgtemp.ts diff --git a/src/controllers/EmployeeTempPositionController.ts b/src/controllers/EmployeeTempPositionController.ts new file mode 100644 index 00000000..ad573e5e --- /dev/null +++ b/src/controllers/EmployeeTempPositionController.ts @@ -0,0 +1,2357 @@ +import { + Controller, + Get, + Post, + Put, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + Response, + 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 { In, IsNull, Like, Not, Brackets } from "typeorm"; +import { + EmployeePosDict, + CreateEmployeePosDict, + UpdateEmployeePosDict, +} from "../entities/EmployeePosDict"; +import { EmployeePosType } from "../entities/EmployeePosType"; +import { EmployeePosLevel } from "../entities/EmployeePosLevel"; +import { + CreateEmployeeTempPosMaster, + EmployeeTempPosMaster, +} from "../entities/EmployeeTempPosMaster"; +import { EmployeePosition } from "../entities/EmployeePosition"; +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"; +import { AuthRole } from "../entities/AuthRole"; +import { RequestWithUser } from "../middlewares/user"; +import permission from "../interfaces/permission"; +import { setLogDataDiff } from "../interfaces/utils"; +@Route("api/v1/org/employee-temp/pos") +@Tags("Employee") +@Security("bearerAuth") +@Response( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) +export class EmployeePositionController extends Controller { + private employeePosDictRepository = AppDataSource.getRepository(EmployeePosDict); + private employeePosTypeRepository = AppDataSource.getRepository(EmployeePosType); + private employeePosLevelRepository = AppDataSource.getRepository(EmployeePosLevel); + private employeeTempPosMasterRepository = AppDataSource.getRepository(EmployeeTempPosMaster); + private employeePositionRepository = AppDataSource.getRepository(EmployeePosition); + private profileRepository = AppDataSource.getRepository(ProfileEmployee); + private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); + private orgRootRepository = AppDataSource.getRepository(OrgRoot); + private child1Repository = AppDataSource.getRepository(OrgChild1); + private child2Repository = AppDataSource.getRepository(OrgChild2); + private child3Repository = AppDataSource.getRepository(OrgChild3); + private child4Repository = AppDataSource.getRepository(OrgChild4); + private authRoleRepo = AppDataSource.getRepository(AuthRole); + + /** + * API เพิ่มตำแหน่งลูกจ้างประจำ + * + * @summary ORG_ - เพิ่มตำแหน่งลูกจ้างประจำ (ADMIN) # + * + */ + @Post("position") + async CreateEmployeePosition( + @Body() + requestBody: CreateEmployeePosDict, + @Request() request: RequestWithUser, + ) { + // await new permission().PermissionCreate(request, "SYS_ORG_TEMP"); + const empPosDict = Object.assign(new EmployeePosDict(), requestBody); + if (!empPosDict) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + + const EmpPosType = await this.employeePosTypeRepository.findOne({ + where: { id: String(requestBody.posTypeId) }, + }); + if (!EmpPosType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลกลุ่มงานนี้"); + } + + const EmpPosLevel = await this.employeePosLevelRepository.findOne({ + where: { id: String(requestBody.posLevelId) }, + }); + if (!EmpPosLevel) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับชั้นงานนี้"); + } + + const rowRepeated = await this.employeePosDictRepository.findOne({ + where: { + posDictName: String(requestBody.posDictName), + posTypeId: String(requestBody.posTypeId), + posLevelId: String(requestBody.posLevelId), + }, + }); + if (rowRepeated) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ข้อมูล Row นี้มีอยู่ในระบบแล้ว"); + } + const before = null; + empPosDict.createdUserId = request.user.sub; + empPosDict.createdFullName = request.user.name; + empPosDict.createdAt = new Date(); + empPosDict.lastUpdateUserId = request.user.sub; + empPosDict.lastUpdateFullName = request.user.name; + empPosDict.lastUpdatedAt = new Date(); + await this.employeePosDictRepository.save(empPosDict, { data: request }); + setLogDataDiff(request, { before, after: empPosDict }); + return new HttpSuccess(empPosDict.id); + } + + /** + * API แก้ไขตำแหน่งลูกจ้างประจำ + * + * @summary แก้ไขตำแหน่งลูกจ้างประจำ (ADMIN) + * + */ + @Put("position/{id}") + async updatePosition( + @Path() id: string, + @Body() + requestBody: UpdateEmployeePosDict, + @Request() request: RequestWithUser, + ) { + // await new permission().PermissionUpdate(request, "SYS_ORG_TEMP"); + const empPosDict = await this.employeePosDictRepository.findOne({ + where: { id: id }, + }); + if (!empPosDict) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งลูกจ้างประจำนี้"); + } + + const checkEmpPosTypeId = await this.employeePosTypeRepository.findOne({ + where: { id: requestBody.posTypeId }, + }); + if (!checkEmpPosTypeId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลกลุ่มงานนี้"); + } + + const checkEmpPosLevelId = await this.employeePosLevelRepository.findOne({ + where: { id: requestBody.posLevelId }, + }); + if (!checkEmpPosLevelId) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับกลุ่มงานนี้"); + } + + const rowRepeated = await this.employeePosDictRepository.findOne({ + where: { + id: Not(id), + posDictName: requestBody.posDictName, + posTypeId: requestBody.posTypeId, + posLevelId: requestBody.posLevelId, + }, + }); + if (rowRepeated) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ข้อมูล Row นี้มีอยู่ในระบบแล้ว"); + } + const before = structuredClone(empPosDict); + empPosDict.lastUpdateUserId = request.user.sub; + empPosDict.lastUpdateFullName = request.user.name; + empPosDict.lastUpdatedAt = new Date(); + this.employeePosDictRepository.merge(empPosDict, requestBody); + await this.employeePosDictRepository.save(empPosDict, { data: request }); + setLogDataDiff(request, { before, after: empPosDict }); + return new HttpSuccess(empPosDict.id); + } + + /** + * API ลบตำแหน่งลูกจ้างประจำ + * + * @summary ORG_ - ลบตำแหน่งลูกจ้างประจำ (ADMIN) # + * + * @param {string} id Id ตำแหน่งลูกจ้างประจำ + */ + @Delete("position/{id}") + async delete(@Path() id: string, @Request() request: RequestWithUser) { + // await new permission().PermissionDelete(request, "SYS_ORG_TEMP"); + const delEmpPosDict = await this.employeePosDictRepository.findOne({ where: { id } }); + if (!delEmpPosDict) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งลูกจ้างประจำนี้"); + } + await this.employeePosDictRepository.remove(delEmpPosDict, { data: request }); + return new HttpSuccess(); + } + + /** + * API รายละเอียดอัตรากำลังลูกจ้างประจำ + * + * + */ + @Get("position/{id}") + async detailPosition(@Path() id: string) { + const posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { id: id }, + }); + if (!posMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + const positions = await this.employeePositionRepository.find({ + where: { posMasterTempId: posMaster.id }, + relations: ["posType", "posLevel"], + order: { lastUpdatedAt: "ASC" }, + }); + const formattedData = { + id: posMaster.id, + posMasterNoPrefix: posMaster.posMasterNoPrefix, + posMasterNo: posMaster.posMasterNo, + posMasterNoSuffix: posMaster.posMasterNoSuffix, + reason: posMaster.reason, + // isOfficer: posMaster.isOfficer, + isStaff: posMaster.isStaff, + isDirector: posMaster.isDirector, + positionSign: posMaster.positionSign, + positions: positions.map((position) => ({ + id: position.id, + positionName: position.positionName, + posTypeId: position.posTypeId, + posTypeName: position.posType == null ? null : position.posType.posTypeName, + posTypeShortName: position.posType == null ? null : position.posType.posTypeShortName, + posLevelId: position.posLevelId, + posLevelName: + position.posLevel == null || position.posType == null + ? null + : `${position.posType.posTypeShortName} ${position.posLevel.posLevelName}`, + positionIsSelected: position.positionIsSelected, + })), + }; + return new HttpSuccess(formattedData); + } + + /** + * API ค้นหารายการตำแหน่งลูกจ้างประจำ + * + * @summary ORG_ - ค้นหารายการตำแหน่งลูกจ้างประจำ (ADMIN) # + * + */ + @Get("position") + async GetEmpPosition(@Query("keyword") keyword?: string, @Query("type") type?: string) { + let findData: any; + switch (type) { + case "positionName": + findData = await this.employeePosDictRepository.find({ + where: { posDictName: Like(`%${keyword}%`) }, + relations: ["posType", "posLevel"], + order: { + posDictName: "ASC", + createdAt: "DESC", + posType: { + posTypeRank: "ASC", + createdAt: "DESC", + }, + posLevel: { + posLevelName: "ASC", + createdAt: "DESC", + }, + }, + }); + break; + + case "positionType": + const findEmpTypes: EmployeePosType[] = await this.employeePosTypeRepository.find({ + where: { posTypeName: Like(`%${keyword}%`) }, + select: ["id"], + }); + findData = await this.employeePosDictRepository.find({ + where: { posTypeId: In(findEmpTypes.map((x) => x.id)) }, + relations: ["posType", "posLevel"], + order: { + posDictName: "ASC", + createdAt: "DESC", + posType: { + posTypeRank: "ASC", + createdAt: "DESC", + }, + posLevel: { + posLevelName: "ASC", + createdAt: "DESC", + }, + }, + }); + break; + + case "positionLevel": + if (!isNaN(Number(keyword))) { + let findEmpLevels; + if (Number(keyword) === 0) { + findEmpLevels = await this.employeePosLevelRepository.find(); + } else { + findEmpLevels = await this.employeePosLevelRepository.find({ + where: { posLevelName: Number(keyword) }, + }); + } + findData = await this.employeePosDictRepository.find({ + where: { posLevelId: In(findEmpLevels.map((x) => x.id)) }, + relations: ["posType", "posLevel"], + order: { + posDictName: "ASC", + createdAt: "DESC", + posType: { + posTypeRank: "ASC", + createdAt: "DESC", + }, + posLevel: { + posLevelName: "ASC", + createdAt: "DESC", + }, + }, + }); + } else { + //กรณีเลือกค้นหาจาก"ระดับชั้นงาน" แต่กรอกไม่ใช่ number ให้ปล่อยมาหมดเลย + findData = await this.employeePosDictRepository.find({ + relations: ["posType", "posLevel"], + order: { + posDictName: "ASC", + createdAt: "DESC", + posType: { + posTypeRank: "ASC", + createdAt: "DESC", + }, + posLevel: { + posLevelName: "ASC", + createdAt: "DESC", + }, + }, + }); + } + break; + + default: + findData = await this.employeePosDictRepository.find({ + relations: ["posType", "posLevel"], + order: { + posDictName: "ASC", + createdAt: "DESC", + posType: { + posTypeRank: "ASC", + createdAt: "DESC", + }, + posLevel: { + posLevelName: "ASC", + createdAt: "DESC", + }, + }, + }); + break; + } + const mapDataEmpPosDict = await Promise.all( + findData.map(async (item: any) => { + let posTypeName = null; + let posLevelName = null; + let posTypeShortName = null; + + if (item.posType !== null && item.posType !== undefined) { + posTypeName = item.posType.posTypeName; + } + if (item.posLevel !== null && item.posLevel !== undefined) { + posLevelName = item.posLevel.posLevelName; + } + if (item.posType !== null && item.posType !== undefined) { + posTypeShortName = item.posType.posTypeShortName; + } + + return { + id: item.id, + posDictName: item.posDictName, + posTypeId: item.posTypeId, + posTypeName: posTypeName, + posTypeShortName: posTypeShortName, + posLevelId: item.posLevelId, + posLevelName: `${posTypeShortName} ${posLevelName}`, + createdAt: item.createdAt, + lastUpdatedAt: item.lastUpdatedAt, + lastUpdateFullName: item.lastUpdateFullName, + }; + }), + ); + return new HttpSuccess(mapDataEmpPosDict); + } + + /** + * API เพิ่มอัตรากำลัง + * + * @summary ORG_ - เพิ่มอัตรากำลัง (ADMIN) + * + */ + @Post("master") + async createEmpMaster( + @Body() + requestBody: CreateEmployeeTempPosMaster, + @Request() request: RequestWithUser, + ) { + await new permission().PermissionCreate(request, "SYS_ORG_TEMP"); + const posMaster = Object.assign(new EmployeeTempPosMaster(), requestBody); + if (!posMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + + let orgRoot: any = null; + let SName: any = null; + if (requestBody.orgRootId != null) + orgRoot = await this.orgRootRepository.findOne({ + where: { id: requestBody.orgRootId }, + }); + if (!orgRoot) { + let orgChild1: any = null; + if (requestBody.orgChild1Id != null) + orgChild1 = await this.child1Repository.findOne({ + where: { id: requestBody.orgChild1Id }, + }); + if (!orgChild1) { + let orgChild2: any = null; + if (requestBody.orgChild2Id != null) + orgChild2 = await this.child2Repository.findOne({ + where: { id: requestBody.orgChild2Id }, + }); + if (!orgChild2) { + let orgChild3: any = null; + if (requestBody.orgChild3Id != null) + orgChild3 = await this.child3Repository.findOne({ + where: { id: requestBody.orgChild3Id }, + }); + if (!orgChild3) { + let orgChild4: any = null; + if (requestBody.orgChild4Id != null) + orgChild4 = await this.child4Repository.findOne({ + where: { id: requestBody.orgChild4Id }, + }); + if (!orgChild4) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงสร้าง"); + } else { + const order: any = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgChild4Id: orgChild4.id, + }, + order: { posMasterOrder: "DESC" }, + }); + posMaster.posMasterOrder = + order !== null && order !== undefined && order.posMasterOrder + ? order.posMasterOrder + 1 + : 1; + posMaster.orgRootId = orgChild4.orgRootId; + posMaster.orgChild1Id = orgChild4.orgChild1Id; + posMaster.orgChild2Id = orgChild4.orgChild2Id; + posMaster.orgChild3Id = orgChild4.orgChild3Id; + posMaster.orgChild4Id = orgChild4.id; + posMaster.orgRevisionId = orgChild4.orgRevisionId; + SName = orgChild4.orgChild4ShortName; + } + } else { + const order: any = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgChild3Id: orgChild3.id, + orgChild4Id: IsNull() || "", + }, + order: { posMasterOrder: "DESC" }, + }); + posMaster.posMasterOrder = + order !== null && order !== undefined && order.posMasterOrder + ? order.posMasterOrder + 1 + : 1; + posMaster.orgRootId = orgChild3.orgRootId; + posMaster.orgChild1Id = orgChild3.orgChild1Id; + posMaster.orgChild2Id = orgChild3.orgChild2Id; + posMaster.orgChild3Id = orgChild3.id; + posMaster.orgRevisionId = orgChild3.orgRevisionId; + SName = orgChild3.orgChild3ShortName; + } + } else { + const order: any = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgChild2Id: orgChild2.id, + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + }, + order: { posMasterOrder: "DESC" }, + }); + posMaster.posMasterOrder = + order !== null && order !== undefined && order.posMasterOrder + ? order.posMasterOrder + 1 + : 1; + posMaster.orgRootId = orgChild2.orgRootId; + posMaster.orgChild1Id = orgChild2.orgChild1Id; + posMaster.orgChild2Id = orgChild2.id; + posMaster.orgRevisionId = orgChild2.orgRevisionId; + SName = orgChild2.orgChild2ShortName; + } + } else { + const order: any = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgChild1Id: orgChild1.id, + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + }, + order: { posMasterOrder: "DESC" }, + }); + posMaster.posMasterOrder = + order !== null && order !== undefined && order.posMasterOrder + ? order.posMasterOrder + 1 + : 1; + posMaster.orgRootId = orgChild1.orgRootId; + posMaster.orgChild1Id = orgChild1.id; + posMaster.orgRevisionId = orgChild1.orgRevisionId; + SName = orgChild1.orgChild1ShortName; + } + } else { + const order: any = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRootId: orgRoot.id, + orgChild1Id: IsNull() || "", + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + }, + order: { posMasterOrder: "DESC" }, + }); + posMaster.posMasterOrder = + order !== null && order !== undefined && order.posMasterOrder + ? order.posMasterOrder + 1 + : 1; + posMaster.orgRootId = orgRoot.id; + posMaster.orgRevisionId = orgRoot.orgRevisionId; + SName = orgRoot.orgRootShortName; + } + + const chk_SName0 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgRoot: { orgRootShortName: SName }, + orgChild1Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + }, + relations: ["orgRoot"], + }); + if (chk_SName0 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName1 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild1: { orgChild1ShortName: SName }, + orgChild2Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + }, + relations: ["orgChild1"], + }); + if (chk_SName1 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName2 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild2: { orgChild2ShortName: SName }, + orgChild3Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + }, + relations: ["orgChild2"], + }); + if (chk_SName2 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName3 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild3: { orgChild3ShortName: SName }, + orgChild4Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + }, + relations: ["orgChild3"], + }); + if (chk_SName3 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName4 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild4: { orgChild4ShortName: SName }, + posMasterNo: requestBody.posMasterNo, + }, + relations: ["orgChild4"], + }); + if (chk_SName4 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + const before = null; + posMaster.createdUserId = request.user.sub; + posMaster.createdFullName = request.user.name; + posMaster.createdAt = new Date(); + posMaster.lastUpdateUserId = request.user.sub; + posMaster.lastUpdateFullName = request.user.name; + posMaster.lastUpdatedAt = new Date(); + await this.employeeTempPosMasterRepository.save(posMaster, { data: request }); + setLogDataDiff(request, { before, after: posMaster }); + await Promise.all( + requestBody.positions.map(async (x: any) => { + const position = Object.assign(new EmployeePosition()); + position.positionName = x.posDictName; + position.posTypeId = x.posTypeId == "" ? null : x.posTypeId; + position.posLevelId = x.posLevelId == "" ? null : x.posLevelId; + position.positionIsSelected = false; + position.posMasterTempId = posMaster.id; + position.createdUserId = request.user.sub; + position.createdFullName = request.user.name; + position.createdAt = new Date(); + position.lastUpdateUserId = request.user.sub; + position.lastUpdateFullName = request.user.name; + position.lastUpdatedAt = new Date(); + await this.employeePositionRepository.save(position, { data: request }); + }), + ); + return new HttpSuccess(posMaster.id); + } + + /** + * API แก้ไขเลขที่ตำแหน่ง + * + * @summary ORG_ - แก้ไขเลขที่ตำแหน่ง (ADMIN) + * + */ + @Put("master/{id}") + async updateEmpMaster( + @Path() id: string, + @Body() + requestBody: CreateEmployeeTempPosMaster, + @Request() request: RequestWithUser, + ) { + await new permission().PermissionUpdate(request, "SYS_ORG_TEMP"); + const posMaster = await this.employeeTempPosMasterRepository.findOne({ where: { id: id } }); + if (!posMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลอัตรากำลัง"); + } + let _null: any = null; + posMaster.posMasterNo = requestBody.posMasterNo; + posMaster.isDirector = requestBody.isDirector; + // posMaster.isStaff = requestBody.isStaff == null?_null:requestBody.isStaff; + // posMaster.positionSign = requestBody.positionSign == null ? _null : requestBody.positionSign; + // posMaster.isOfficer = requestBody.isOfficer; + posMaster.posMasterNoPrefix = requestBody.posMasterNoPrefix; + posMaster.posMasterNoSuffix = requestBody.posMasterNoSuffix; + posMaster.reason = requestBody.reason == null ? "" : requestBody.reason; + posMaster.orgRootId = null; + posMaster.orgChild1Id = null; + posMaster.orgChild2Id = null; + posMaster.orgChild3Id = null; + posMaster.orgChild4Id = null; + + let orgRoot: any = null; + let SName: any = null; + if (requestBody.orgRootId != null) + orgRoot = await this.orgRootRepository.findOne({ + where: { id: requestBody.orgRootId }, + }); + if (!orgRoot) { + let orgChild1: any = null; + if (requestBody.orgChild1Id != null) + orgChild1 = await this.child1Repository.findOne({ + where: { id: requestBody.orgChild1Id }, + }); + if (!orgChild1) { + let orgChild2: any = null; + if (requestBody.orgChild2Id != null) + orgChild2 = await this.child2Repository.findOne({ + where: { id: requestBody.orgChild2Id }, + }); + if (!orgChild2) { + let orgChild3: any = null; + if (requestBody.orgChild3Id != null) + orgChild3 = await this.child3Repository.findOne({ + where: { id: requestBody.orgChild3Id }, + }); + if (!orgChild3) { + let orgChild4: any = null; + if (requestBody.orgChild4Id != null) + orgChild4 = await this.child4Repository.findOne({ + where: { id: requestBody.orgChild4Id }, + }); + if (!orgChild4) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงสร้าง"); + } else { + posMaster.orgRootId = orgChild4.orgRootId; + posMaster.orgChild1Id = orgChild4.orgChild1Id; + posMaster.orgChild2Id = orgChild4.orgChild2Id; + posMaster.orgChild3Id = orgChild4.orgChild3Id; + posMaster.orgChild4Id = orgChild4.id; + posMaster.orgRevisionId = orgChild4.orgRevisionId; + SName = orgChild4.orgChild4ShortName; + } + } else { + posMaster.orgRootId = orgChild3.orgRootId; + posMaster.orgChild1Id = orgChild3.orgChild1Id; + posMaster.orgChild2Id = orgChild3.orgChild2Id; + posMaster.orgChild3Id = orgChild3.id; + posMaster.orgRevisionId = orgChild3.orgRevisionId; + SName = orgChild3.orgChild3ShortName; + } + } else { + posMaster.orgRootId = orgChild2.orgRootId; + posMaster.orgChild1Id = orgChild2.orgChild1Id; + posMaster.orgChild2Id = orgChild2.id; + posMaster.orgRevisionId = orgChild2.orgRevisionId; + SName = orgChild2.orgChild2ShortName; + } + } else { + posMaster.orgRootId = orgChild1.orgRootId; + posMaster.orgChild1Id = orgChild1.id; + posMaster.orgRevisionId = orgChild1.orgRevisionId; + SName = orgChild1.orgChild1ShortName; + } + } else { + posMaster.orgRootId = orgRoot.id; + posMaster.orgRevisionId = orgRoot.orgRevisionId; + SName = orgRoot.orgRootShortName; + } + + const chk_SName0 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgRoot: { orgRootShortName: SName }, + orgChild1Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + id: Not(posMaster.id), + }, + relations: ["orgRoot"], + }); + if (chk_SName0 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName1 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild1: { orgChild1ShortName: SName }, + orgChild2Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + id: Not(posMaster.id), + }, + relations: ["orgChild1"], + }); + if (chk_SName1 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName2 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild2: { orgChild2ShortName: SName }, + orgChild3Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + id: Not(posMaster.id), + }, + relations: ["orgChild2"], + }); + if (chk_SName2 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName3 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild3: { orgChild3ShortName: SName }, + orgChild4Id: IsNull(), + posMasterNo: requestBody.posMasterNo, + id: Not(posMaster.id), + }, + relations: ["orgChild3"], + }); + if (chk_SName3 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + + const chk_SName4 = await this.employeeTempPosMasterRepository.findOne({ + where: { + orgRevisionId: posMaster.orgRevisionId, + orgChild4: { orgChild4ShortName: SName }, + posMasterNo: requestBody.posMasterNo, + id: Not(posMaster.id), + }, + relations: ["orgChild4"], + }); + if (chk_SName4 != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถใส่เลขที่ตำแหน่งซ้ำกันได้", + ); + } + const before = structuredClone(posMaster); + posMaster.createdUserId = request.user.sub; //สงสัยว่าทำให้ bug แก้ไขไม่ได้ + posMaster.createdFullName = request.user.name; + posMaster.createdAt = new Date(); + posMaster.lastUpdateUserId = request.user.sub; + posMaster.lastUpdateFullName = request.user.name; + posMaster.lastUpdatedAt = new Date(); + await this.employeeTempPosMasterRepository.save(posMaster, { data: request }); + setLogDataDiff(request, { before, after: posMaster }); + await this.employeePositionRepository.delete({ posMasterTempId: posMaster.id }); + + await Promise.all( + requestBody.positions.map(async (x: any) => { + const position = Object.assign(new EmployeePosition()); + position.positionName = x.posDictName; + position.posTypeId = x.posTypeId == "" ? null : x.posTypeId; + position.posLevelId = x.posLevelId == "" ? null : x.posLevelId; + position.positionIsSelected = false; + position.posMasterTempId = posMaster.id; + position.createdUserId = request.user.sub; + position.createdFullName = request.user.name; + position.createdAt = new Date(); + position.lastUpdateUserId = request.user.sub; + position.lastUpdateFullName = request.user.name; + position.lastUpdatedAt = new Date(); + await this.employeePositionRepository.save(position, { data: request }); + }), + ); + return new HttpSuccess(posMaster.id); + } + + /** + * API รายละเอียดอัตรากำลัง + * + * @summary ORG_ - รายละเอียดอัตรากำลัง (ADMIN) + * + */ + // @Get("position/{id}") + // async detailEmpPosition(@Path() id: string) { + // const posMaster = await this.employeeTempPosMasterRepository.findOne({ + // where: { id }, + // }); + // if (!posMaster) { + // throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + // } + // const positions = await this.employeePositionRepository.find({ + // where: { posMasterTempId: posMaster.id }, + // relations: ["posType", "posLevel"], + // order: { lastUpdatedAt: "ASC" }, + // }); + // const formattedData = { + // id: posMaster.id, + // posMasterNoPrefix: posMaster.posMasterNoPrefix, + // posMasterNo: posMaster.posMasterNo, + // posMasterNoSuffix: posMaster.posMasterNoSuffix, + // positions: positions.map((position) => ({ + // id: position.id, + // positionName: position.positionName, + // posTypeId: position.posTypeId, + // posTypeName: position.posType == null ? null : position.posType.posTypeName, + // posLevelId: position.posLevelId, + // posLevelName: position.posLevel == null ? null : position.posLevel.posLevelName, + // positionIsSelected: position.positionIsSelected, + // })), + // }; + // return new HttpSuccess(formattedData); + // } + + /** + * API ลบอัตรากำลัง + * + * @summary ORG_ - ลบอัตรากำลัง (ADMIN) + * + * @param {string} id Id ตำแหน่ง + */ + @Delete("master/{id}") + async deleteEmpPosMaster(@Path() id: string, @Request() request: RequestWithUser) { + await new permission().PermissionCreate(request, "SYS_ORG_TEMP"); + const delPosMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { id }, + }); + if (!delPosMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งในสายงานนี้"); + } + await this.employeePositionRepository.delete({ posMasterTempId: id }); + await this.employeeTempPosMasterRepository.delete({ id }); + return new HttpSuccess(); + } + + /** + * API รายการอัตรากำลัง + * + * @summary ORG_ - รายการอัตรากำลัง (ADMIN) + * + */ + @Post("master/list") + async listEmp( + @Body() + body: { + id: string; + revisionId: string; + type: number; + isAll: boolean; + page: number; + pageSize: number; + keyword?: string; + }, + ) { + let typeCondition: any = {}; + let checkChildConditions: any = {}; + let keywordAsInt: any; + let searchShortName = ""; + let searchShortName0 = `CONCAT(orgRoot.orgRootShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName1 = `CONCAT(orgChild1.orgChild1ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName2 = `CONCAT(orgChild2.orgChild2ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName3 = `CONCAT(orgChild3.orgChild3ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName4 = `CONCAT(orgChild4.orgChild4ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + + if (body.type === 0) { + typeCondition = { + orgRootId: body.id, + }; + if (!body.isAll) { + checkChildConditions = { + orgChild1Id: IsNull(), + }; + searchShortName = `CONCAT(orgRoot.orgRootShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; + } else { + } + } else if (body.type === 1) { + typeCondition = { + orgChild1Id: body.id, + }; + if (!body.isAll) { + checkChildConditions = { + orgChild2Id: IsNull(), + }; + searchShortName = `CONCAT(orgChild1.orgChild1ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; + } else { + } + } else if (body.type === 2) { + typeCondition = { + orgChild2Id: body.id, + }; + if (!body.isAll) { + checkChildConditions = { + orgChild3Id: IsNull(), + }; + searchShortName = `CONCAT(orgChild2.orgChild2ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; + } else { + } + } else if (body.type === 3) { + typeCondition = { + orgChild3Id: body.id, + }; + if (!body.isAll) { + checkChildConditions = { + orgChild4Id: IsNull(), + }; + searchShortName = `CONCAT(orgChild3.orgChild3ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; + } else { + } + } else if (body.type === 4) { + typeCondition = { + orgChild4Id: body.id, + }; + searchShortName = `CONCAT(orgChild4.orgChild4ShortName,posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; + } + let findPosition: any; + let masterId = new Array(); + if (body.keyword != null && body.keyword != "") { + const findTypes: EmployeePosType[] = await this.employeePosTypeRepository.find({ + where: { posTypeName: Like(`%${body.keyword}%`) }, + select: ["id"], + }); + findPosition = await this.employeePositionRepository.find({ + where: { posTypeId: In(findTypes.map((x) => x.id)) }, + select: ["posMasterTempId"], + }); + masterId = masterId.concat(findPosition.map((position: any) => position.posMasterTempId)); + // const findLevel: EmployeePosLevel[] = await this.employeePosLevelRepository.find({ + // where: { posLevelName: Like(`%${body.keyword}%`) }, + // select: ["id"], + // }); + // findPosition = await this.employeePositionRepository.find({ + // where: { posLevelId: In(findLevel.map((x) => x.id)) }, + // select: ["posMasterTempId"], + // }); + // masterId = masterId.concat(findPosition.map((position: any) => position.posMasterTempId)); + findPosition = await this.employeePositionRepository.find({ + where: { positionName: Like(`%${body.keyword}%`) }, + select: ["posMasterTempId"], + }); + masterId = masterId.concat(findPosition.map((position: any) => position.posMasterTempId)); + keywordAsInt = body.keyword == null ? null : parseInt(body.keyword, 10); + if (isNaN(keywordAsInt)) { + keywordAsInt = "P@ssw0rd!z"; + } + masterId = [...new Set(masterId)]; + } + + const revisionCondition = { + orgRevisionId: body.revisionId, + }; + const conditions = [ + { + ...checkChildConditions, + ...typeCondition, + ...revisionCondition, + ...(body.keyword && + (masterId.length > 0 + ? { id: In(masterId) } + : { posMasterNo: Like(`%${body.keyword}%`) })), + }, + ]; + + const [posMaster, total] = await AppDataSource.getRepository(EmployeeTempPosMaster) + .createQueryBuilder("posMaster") + .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") + .leftJoinAndSelect("posMaster.orgChild1", "orgChild1") + .leftJoinAndSelect("posMaster.orgChild2", "orgChild2") + .leftJoinAndSelect("posMaster.orgChild3", "orgChild3") + .leftJoinAndSelect("posMaster.orgChild4", "orgChild4") + .leftJoinAndSelect("posMaster.current_holder", "current_holder") + .leftJoinAndSelect("posMaster.next_holder", "next_holder") + .leftJoinAndSelect("posMaster.orgRevision", "orgRevision") + .leftJoinAndSelect("posMaster.positions", "positions") + .leftJoinAndSelect("positions.posType", "posType") + .leftJoinAndSelect("positions.posLevel", "posLevel") + .where(conditions) + .orWhere( + new Brackets((qb) => { + qb.andWhere( + body.keyword != null && body.keyword != "" + ? body.isAll == false + ? searchShortName + : `CASE WHEN posMaster.orgChild1 is null THEN ${searchShortName0} WHEN posMaster.orgChild2 is null THEN ${searchShortName1} WHEN posMaster.orgChild3 is null THEN ${searchShortName2} WHEN posMaster.orgChild4 is null THEN ${searchShortName3} ELSE ${searchShortName4} END LIKE '%${body.keyword}%'` + : "1=1", + ) + .andWhere(checkChildConditions) + .andWhere(typeCondition) + .andWhere(revisionCondition); + }), + ) + .orWhere( + new Brackets((qb) => { + qb.andWhere( + body.keyword != null && body.keyword != "" + ? `CONCAT(current_holder.prefix, current_holder.firstName," ",current_holder.lastName) like '%${body.keyword}%'` + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .andWhere(checkChildConditions) + .andWhere(typeCondition) + .andWhere(revisionCondition); + }), + ) + .orWhere( + new Brackets((qb) => { + qb.andWhere( + body.keyword != null && body.keyword != "" + ? `CASE WHEN orgRevision.orgRevisionIsDraft = true THEN CONCAT(next_holder.prefix, next_holder.firstName,' ', next_holder.lastName) ELSE CONCAT(current_holder.prefix, current_holder.firstName,' ' , current_holder.lastName) END LIKE '%${body.keyword}%'` + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .andWhere(checkChildConditions) + .andWhere(typeCondition) + .andWhere(revisionCondition); + }), + ) + .orWhere( + new Brackets((qb) => { + qb.andWhere( + body.keyword != null && body.keyword != "" + ? `CONCAT(posType.posTypeShortName,' ',posLevel.posLevelName) like '%${body.keyword}%'` + : "1=1", + { + keyword: `%${body.keyword}%`, + }, + ) + .andWhere(checkChildConditions) + .andWhere(typeCondition) + .andWhere(revisionCondition); + }), + ) + .orderBy("posMaster.posMasterOrder", "ASC") + .skip((body.page - 1) * body.pageSize) + .take(body.pageSize) + .getManyAndCount(); + + const formattedData = await Promise.all( + posMaster.map(async (posMaster) => { + const positions = await this.employeePositionRepository.find({ + where: { + posMasterTempId: posMaster.id, + }, + relations: ["posLevel", "posType"], + }); + + const authRoleName = await this.authRoleRepo.findOne({ + where: { id: String(posMaster.authRoleId) }, + }); + + let profile: any; + const chkRevision = await this.orgRevisionRepository.findOne({ + where: { id: posMaster.orgRevisionId }, + }); + if (chkRevision?.orgRevisionIsCurrent && !chkRevision?.orgRevisionIsDraft) { + profile = await this.profileRepository.findOne({ + where: { id: String(posMaster.current_holderId) }, + }); + } else if (!chkRevision?.orgRevisionIsCurrent && chkRevision?.orgRevisionIsDraft) { + profile = await this.profileRepository.findOne({ + where: { id: String(posMaster.next_holderId) }, + }); + } + const type = await this.employeePosTypeRepository.findOne({ + where: { id: String(profile?.posTypeId) }, + }); + const level = await this.employeePosLevelRepository.findOne({ + where: { id: String(profile?.posLevelId) }, + }); + + let shortName = ""; + + if ( + posMaster.orgRootId !== null && + posMaster.orgChild1Id == null && + posMaster.orgChild2Id == null && + posMaster.orgChild3Id == null + ) { + body.type = 0; + shortName = posMaster.orgRoot.orgRootShortName; + } else if ( + posMaster.orgRootId !== null && + posMaster.orgChild1Id !== null && + posMaster.orgChild2Id == null && + posMaster.orgChild3Id == null + ) { + body.type = 1; + shortName = posMaster.orgChild1.orgChild1ShortName; + } else if ( + posMaster.orgRootId !== null && + posMaster.orgChild1Id !== null && + posMaster.orgChild2Id !== null && + posMaster.orgChild3Id == null + ) { + body.type = 2; + shortName = posMaster.orgChild2.orgChild2ShortName; + } else if ( + posMaster.orgRootId !== null && + posMaster.orgChild1Id !== null && + posMaster.orgChild2Id !== null && + posMaster.orgChild3Id !== null + ) { + body.type = 3; + shortName = posMaster.orgChild3.orgChild3ShortName; + } else if ( + posMaster.orgRootId !== null && + posMaster.orgChild1Id !== null && + posMaster.orgChild2Id !== null && + posMaster.orgChild3Id !== null + ) { + body.type = 4; + shortName = posMaster.orgChild4.orgChild4ShortName; + } + + return { + id: posMaster.id, + orgRootId: posMaster.orgRootId, + orgChild1Id: posMaster.orgChild1Id, + orgChild2Id: posMaster.orgChild2Id, + orgChild3Id: posMaster.orgChild3Id, + orgChild4Id: posMaster.orgChild4Id, + posMasterNoPrefix: posMaster.posMasterNoPrefix ? posMaster.posMasterNoPrefix : null, + posMasterNo: posMaster.posMasterNo ? posMaster.posMasterNo : null, + posMasterNoSuffix: posMaster.posMasterNoSuffix ? posMaster.posMasterNoSuffix : null, + reason: posMaster.reason, + fullNameCurrentHolder: + posMaster.current_holder == null + ? null + : `${posMaster.current_holder.prefix}${posMaster.current_holder.firstName} ${posMaster.current_holder.lastName}`, + fullNameNextHolder: + posMaster.next_holder == null + ? null + : `${posMaster.next_holder.prefix}${posMaster.next_holder.firstName} ${posMaster.next_holder.lastName}`, + orgShortname: shortName, + isSit: posMaster.isSit, + profilePosition: profile == null ? null : profile.position, + profilePostype: type == null ? null : type.posTypeName, + profilePoslevel: + level == null || type == null ? null : `${type.posTypeShortName} ${level.posLevelName}`, + authRoleId: posMaster.authRoleId, + authRoleName: + authRoleName == null || authRoleName.roleName == null ? null : authRoleName.roleName, + positions: positions.map((position) => ({ + id: position.id, + positionName: position.positionName, + posTypeId: position.posTypeId, + posTypeName: position.posType == null ? null : position.posType.posTypeName, + posTypeShortName: position.posType == null ? null : position.posType.posTypeShortName, + posLevelId: position.posLevelId, + posLevelName: + position.posLevel == null || position.posType == null + ? null + : `${position.posType.posTypeShortName} ${position.posLevel.posLevelName}`, + positionIsSelected: position.positionIsSelected, + })), + }; + }), + ); + return new HttpSuccess({ data: formattedData, total }); + } + + /** + * API จัดลำดับตำแหน่ง + * + * @summary ORG_ - จัดลำดับตำแหน่ง (ADMIN) + * + */ + @Post("sort") + async SortEmp( + @Body() requestBody: { id: string; type: number; sortId: string[] }, + @Request() request: RequestWithUser, + ) { + await new permission().PermissionUpdate(request, "SYS_ORG_TEMP"); + switch (requestBody.type) { + case 0: { + const rootId = await this.employeeTempPosMasterRepository.findOne({ + where: { orgRootId: requestBody.id }, + }); + if (!rootId?.id) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found rootId: " + requestBody.id); + } + const listPosMasterTempId_0 = await this.employeeTempPosMasterRepository.find({ + where: { + orgRootId: requestBody.id, + orgChild1Id: IsNull(), + orgChild2Id: IsNull(), + orgChild3Id: IsNull(), + orgChild4Id: IsNull(), + }, + select: ["id", "posMasterOrder"], + }); + if (!listPosMasterTempId_0) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found masterId type 0."); + } + const sortData_0 = listPosMasterTempId_0.map((data) => ({ + id: data.id, + posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, + })); + await this.employeeTempPosMasterRepository.save(sortData_0); + break; + } + + case 1: { + const child1Id = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild1Id: requestBody.id }, + }); + if (!child1Id?.id) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child1Id: " + requestBody.id); + } + const listPosMasterTempId_1 = await this.employeeTempPosMasterRepository.find({ + where: { + orgRootId: Not(IsNull()), + orgChild1Id: requestBody.id, + orgChild2Id: IsNull(), + orgChild3Id: IsNull(), + orgChild4Id: IsNull(), + }, + select: ["id", "posMasterOrder"], + }); + if (!listPosMasterTempId_1) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found masterId type 1."); + } + const sortData_1 = listPosMasterTempId_1.map((data) => ({ + id: data.id, + posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, + })); + await this.employeeTempPosMasterRepository.save(sortData_1); + break; + } + + case 2: { + const child2Id = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild2Id: requestBody.id }, + }); + if (!child2Id?.id) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child2Id: " + requestBody.id); + } + const listPosMasterTempId_2 = await this.employeeTempPosMasterRepository.find({ + where: { + orgRootId: Not(IsNull()), + orgChild1Id: Not(IsNull()), + orgChild2Id: requestBody.id, + orgChild3Id: IsNull(), + orgChild4Id: IsNull(), + }, + select: ["id", "posMasterOrder"], + }); + if (!listPosMasterTempId_2) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found masterId type 2."); + } + const sortData_2 = listPosMasterTempId_2.map((data) => ({ + id: data.id, + posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, + })); + await this.employeeTempPosMasterRepository.save(sortData_2); + break; + } + + case 3: { + const child3Id = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild3Id: requestBody.id }, + }); + if (!child3Id?.id) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found chil3Id: " + requestBody.id); + } + const listPosMasterTempId_3 = await this.employeeTempPosMasterRepository.find({ + where: { + orgRootId: Not(IsNull()), + orgChild1Id: Not(IsNull()), + orgChild2Id: Not(IsNull()), + orgChild3Id: requestBody.id, + orgChild4Id: IsNull(), + }, + select: ["id", "posMasterOrder"], + }); + if (!listPosMasterTempId_3) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found masterId type 3."); + } + const sortData_3 = listPosMasterTempId_3.map((data) => ({ + id: data.id, + posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, + })); + await this.employeeTempPosMasterRepository.save(sortData_3); + break; + } + + case 4: { + const child4Id = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild4Id: requestBody.id }, + }); + if (!child4Id?.id) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child4Id: " + requestBody.id); + } + const listPosMasterTempId_4 = await this.employeeTempPosMasterRepository.find({ + where: { + orgRootId: Not(IsNull()), + orgChild1Id: Not(IsNull()), + orgChild2Id: Not(IsNull()), + orgChild3Id: Not(IsNull()), + orgChild4Id: requestBody.id, + }, + select: ["id", "posMasterOrder"], + }); + if (!listPosMasterTempId_4) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found masterId type 4."); + } + const sortData_4 = listPosMasterTempId_4.map((data) => ({ + id: data.id, + posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, + })); + await this.employeeTempPosMasterRepository.save(sortData_4); + break; + } + + default: + throw new HttpError(HttpStatusCode.NOT_FOUND, "not found type: " + requestBody.type); + } + return new HttpSuccess(); + } + + /** + * API ดูประวัติอัตรากำลัง + * + * @summary ORG_ - ดูประวัติอัตรากำลัง (ADMIN) + * + * @param {string} id Id อัตรากำลัง + */ + @Get("history/{id}") + async getEmpHistoryPosMater(@Path() id: string) { + const posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { id }, + }); + if (!posMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + } + const posMasters = await this.employeeTempPosMasterRepository.find({ + where: { + ancestorDNA: + posMaster.ancestorDNA == null || posMaster.ancestorDNA == "" + ? "123" + : posMaster.ancestorDNA, + }, + order: { lastUpdatedAt: "DESC" }, + relations: [ + "orgRoot", + "orgChild1", + "orgChild2", + "orgChild3", + "orgChild4", + "current_holder", + "positions", + "positions.posLevel", + "positions.posType", + ], + }); + const _data = posMasters.map((item) => ({ + id: item.id, + orgShortName: + item.orgRoot == null + ? null + : item.orgChild1 == null + ? item.orgRoot.orgRootShortName + : item.orgChild2 == null + ? item.orgChild1.orgChild1ShortName + : item.orgChild3 == null + ? item.orgChild2.orgChild2ShortName + : item.orgChild4 == null + ? item.orgChild3.orgChild3ShortName + : item.orgChild4.orgChild4ShortName, + lastUpdatedAt: item.lastUpdatedAt ? item.lastUpdatedAt : null, + posMasterNoPrefix: item.posMasterNoPrefix ? item.posMasterNoPrefix : null, + posMasterNo: item.posMasterNo ? item.posMasterNo : null, + posMasterNoSuffix: item.posMasterNoSuffix ? item.posMasterNoSuffix : null, + reason: item.reason ? item.reason : null, + position: item.positions.map((x) => x.positionName).join("/"), + posLevel: item.positions.map((x) => x.posLevel.posLevelName).join("/"), + posType: item.positions.map((x) => x.posType.posTypeName).join("/"), + fullname: + (item?.current_holder?.prefix ?? "") + + "" + + (item?.current_holder?.firstName ?? "") + + " " + + (item?.current_holder?.lastName ?? ""), + })); + return new HttpSuccess(_data); + } + + /** + * API ย้ายอัตรากำลัง + * + * @summary ORG_ - ย้ายอัตรากำลัง (ADMIN) + * + */ + @Post("move") + async moveEmpPosMaster( + @Body() requestBody: { id: string; type: number; positionMaster: string[] }, + @Request() request: RequestWithUser, + ) { + await new permission().PermissionUpdate(request, "SYS_ORG_TEMP"); + const posMasters = await this.employeeTempPosMasterRepository.find({ + where: { id: In(requestBody.positionMaster) }, + }); + + const type0LastPosMasterNo = + requestBody.type == 0 + ? await this.employeeTempPosMasterRepository.find({ + where: { + orgRootId: requestBody.id, + orgChild1Id: IsNull(), + }, + }) + : []; + + const type1LastPosMasterNo = + requestBody.type == 1 + ? await this.employeeTempPosMasterRepository.find({ + where: { + orgChild1Id: requestBody.id, + orgChild2Id: IsNull(), + }, + }) + : []; + + const type2LastPosMasterNo = + requestBody.type == 2 + ? await this.employeeTempPosMasterRepository.find({ + where: { + orgChild2Id: requestBody.id, + orgChild3Id: IsNull(), + }, + }) + : []; + + const type3LastPosMasterNo = + requestBody.type == 3 + ? await this.employeeTempPosMasterRepository.find({ + where: { + orgChild3Id: requestBody.id, + orgChild4Id: IsNull(), + }, + }) + : []; + + const type4LastPosMasterNo = + requestBody.type == 4 + ? await this.employeeTempPosMasterRepository.find({ + where: { + orgChild4Id: requestBody.id, + }, + }) + : []; + + const allLastPosMasterNo = [ + ...type0LastPosMasterNo, + ...type1LastPosMasterNo, + ...type2LastPosMasterNo, + ...type3LastPosMasterNo, + ...type4LastPosMasterNo, + ]; + + // let maxPosMasterNo = Math.max(...allLastPosMasterNo.map((pos) => pos.posMasterNo), 0); + + let maxPosMasterOrder = Math.max(...allLastPosMasterNo.map((pos) => pos.posMasterOrder), 0); + await Promise.all( + posMasters.map(async (posMaster: any) => { + let change = true; + + if (requestBody.type == 0) { + const org = await this.orgRootRepository.findOne({ + where: { id: requestBody.id }, + }); + if (org != null) { + const _posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { orgRootId: org.id, posMasterNo: posMaster.posMasterNo }, + }); + if (_posMaster != null) + throw new HttpError( + HttpStatusCode.NOT_FOUND, + `เลขที่ตำแหน่ง ${org.orgRootShortName}${posMaster.posMasterNo} มีอยู่ในระบบอยู่แล้ว`, + ); + if ( + posMaster.orgRootId == org.id && + posMaster.orgChild1Id == null && + posMaster.orgChild2Id == null && + posMaster.orgChild3Id == null && + posMaster.orgChild4Id == null + ) + change = false; + posMaster.orgRootId = org.id; + posMaster.orgRevisionId = org.orgRevisionId; + posMaster.orgChild1Id = null; + posMaster.orgChild2Id = null; + posMaster.orgChild3Id = null; + posMaster.orgChild4Id = null; + } + } + if (requestBody.type == 1) { + const org = await this.child1Repository.findOne({ + where: { id: requestBody.id }, + }); + if (org != null) { + const _posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild1Id: org.id, posMasterNo: posMaster.posMasterNo }, + }); + if (_posMaster != null) + throw new HttpError( + HttpStatusCode.NOT_FOUND, + `เลขที่ตำแหน่ง ${org.orgChild1ShortName}${posMaster.posMasterNo} มีอยู่ในระบบอยู่แล้ว`, + ); + if ( + posMaster.orgChild1Id == org.id && + posMaster.orgChild2Id == null && + posMaster.orgChild3Id == null && + posMaster.orgChild4Id == null + ) + change = false; + posMaster.orgRootId = org.orgRootId; + posMaster.orgChild1Id = org.id; + posMaster.orgRevisionId = org.orgRevisionId; + posMaster.orgChild2Id = null; + posMaster.orgChild3Id = null; + posMaster.orgChild4Id = null; + } + } + if (requestBody.type == 2) { + const org = await this.child2Repository.findOne({ + where: { id: requestBody.id }, + }); + if (org != null) { + const _posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild2Id: org.id, posMasterNo: posMaster.posMasterNo }, + }); + if (_posMaster != null) + throw new HttpError( + HttpStatusCode.NOT_FOUND, + `เลขที่ตำแหน่ง ${org.orgChild2ShortName}${posMaster.posMasterNo} มีอยู่ในระบบอยู่แล้ว`, + ); + if ( + posMaster.orgChild2Id == org.id && + posMaster.orgChild3Id == null && + posMaster.orgChild4Id == null + ) + change = false; + posMaster.orgRootId = org.orgRootId; + posMaster.orgChild1Id = org.orgChild1Id; + posMaster.orgChild2Id = org.id; + posMaster.orgRevisionId = org.orgRevisionId; + posMaster.orgChild3Id = null; + posMaster.orgChild4Id = null; + } + } + if (requestBody.type == 3) { + const org = await this.child3Repository.findOne({ + where: { id: requestBody.id }, + }); + if (org != null) { + const _posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild3Id: org.id, posMasterNo: posMaster.posMasterNo }, + }); + if (_posMaster != null) + throw new HttpError( + HttpStatusCode.NOT_FOUND, + `เลขที่ตำแหน่ง ${org.orgChild3ShortName}${posMaster.posMasterNo} มีอยู่ในระบบอยู่แล้ว`, + ); + if (posMaster.orgChild3Id == org.id && posMaster.orgChild4Id == null) change = false; + posMaster.orgRootId = org.orgRootId; + posMaster.orgChild1Id = org.orgChild1Id; + posMaster.orgChild2Id = org.orgChild2Id; + posMaster.orgChild3Id = org.id; + posMaster.orgRevisionId = org.orgRevisionId; + posMaster.orgChild4Id = null; + } + } + if (requestBody.type == 4) { + const org = await this.child4Repository.findOne({ + where: { id: requestBody.id }, + }); + if (org != null) { + const _posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { orgChild4Id: org.id, posMasterNo: posMaster.posMasterNo }, + }); + if (_posMaster != null) + throw new HttpError( + HttpStatusCode.NOT_FOUND, + `เลขที่ตำแหน่ง ${org.orgChild4ShortName}${posMaster.posMasterNo} มีอยู่ในระบบอยู่แล้ว`, + ); + if (posMaster.orgChild4Id == org.id) change = false; + posMaster.orgRootId = org.orgRootId; + posMaster.orgChild1Id = org.orgChild1Id; + posMaster.orgChild2Id = org.orgChild2Id; + posMaster.orgChild3Id = org.orgChild3Id; + posMaster.orgChild4Id = org.id; + posMaster.orgRevisionId = org.orgRevisionId; + } + } + if (change == true) { + posMaster.posMasterOrder = maxPosMasterOrder += 1; + posMaster.createdUserId = request.user.sub; + posMaster.createdFullName = request.user.name; + posMaster.createdAt = new Date(); + posMaster.lastUpdateUserId = request.user.sub; + posMaster.lastUpdateFullName = request.user.name; + posMaster.lastUpdatedAt = new Date(); + await this.employeeTempPosMasterRepository.save(posMaster); + } + }), + ); + return new HttpSuccess(); + } + + /** + * API ตำแหน่งทั้งหมด + * + * @summary ORG_ - ตำแหน่งทั้งหมด (ADMIN) + * + */ + @Post("summary") + async PositionEmpSummary(@Body() requestBody: { id: string; type: number; isNode: boolean }) { + let summary: any; + let totalPosition: any; + let totalPositionCurrentUse: any; + let totalPositionCurrentVacant: any; + let totalPositionNextUse: any; + let totalPositionNextVacant: any; + + if (requestBody.isNode === true) { + switch (requestBody.type) { + case 0: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { orgRootId: requestBody.id }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + next_holderId: IsNull() || "", + }, + }); + break; + } + case 1: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { orgChild1Id: requestBody.id }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild1Id: requestBody.id, + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild1Id: requestBody.id, + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild1Id: requestBody.id, + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild1Id: requestBody.id, + next_holderId: IsNull() || "", + }, + }); + break; + } + case 2: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { orgChild2Id: requestBody.id }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild2Id: requestBody.id, + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild2Id: requestBody.id, + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild2Id: requestBody.id, + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild2Id: requestBody.id, + next_holderId: IsNull() || "", + }, + }); + break; + } + case 3: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { orgChild3Id: requestBody.id }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild3Id: requestBody.id, + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild3Id: requestBody.id, + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild3Id: requestBody.id, + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild3Id: requestBody.id, + next_holderId: IsNull() || "", + }, + }); + break; + } + case 4: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { orgChild4Id: requestBody.id }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild4Id: requestBody.id, + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild4Id: requestBody.id, + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild4Id: requestBody.id, + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgChild4Id: requestBody.id, + next_holderId: IsNull() || "", + }, + }); + break; + } + default: + break; + } + } else { + switch (requestBody.type) { + case 0: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + orgChild1Id: IsNull() || "", + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + orgChild1Id: IsNull() || "", + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + orgChild1Id: IsNull() || "", + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + orgChild1Id: IsNull() || "", + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: requestBody.id, + orgChild1Id: IsNull() || "", + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + next_holderId: IsNull() || "", + }, + }); + break; + } + case 1: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: requestBody.id, + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: requestBody.id, + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: requestBody.id, + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: requestBody.id, + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: requestBody.id, + orgChild2Id: IsNull() || "", + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + next_holderId: IsNull() || "", + }, + }); + break; + } + case 2: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: requestBody.id, + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: requestBody.id, + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: requestBody.id, + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: requestBody.id, + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: requestBody.id, + orgChild3Id: IsNull() || "", + orgChild4Id: IsNull() || "", + next_holderId: IsNull() || "", + }, + }); + break; + } + case 3: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: requestBody.id, + orgChild4Id: IsNull() || "", + }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: requestBody.id, + orgChild4Id: IsNull() || "", + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: requestBody.id, + orgChild4Id: IsNull() || "", + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: requestBody.id, + orgChild4Id: IsNull() || "", + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: requestBody.id, + orgChild4Id: IsNull() || "", + next_holderId: IsNull() || "", + }, + }); + break; + } + case 4: { + totalPosition = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: Not(IsNull()) || Not(""), + orgChild4Id: requestBody.id, + }, + }); + totalPositionCurrentUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: Not(IsNull()) || Not(""), + orgChild4Id: requestBody.id, + current_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionCurrentVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: Not(IsNull()) || Not(""), + orgChild4Id: requestBody.id, + current_holderId: IsNull() || "", + }, + }); + totalPositionNextUse = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: Not(IsNull()) || Not(""), + orgChild4Id: requestBody.id, + next_holderId: Not(IsNull()) || Not(""), + }, + }); + totalPositionNextVacant = await this.employeeTempPosMasterRepository.count({ + where: { + orgRootId: Not(IsNull()) || Not(""), + orgChild1Id: Not(IsNull()) || Not(""), + orgChild2Id: Not(IsNull()) || Not(""), + orgChild3Id: Not(IsNull()) || Not(""), + orgChild4Id: requestBody.id, + next_holderId: IsNull() || "", + }, + }); + break; + } + default: + break; + } + } + + summary = { + totalPosition: totalPosition, + totalPositionCurrentUse: totalPositionCurrentUse, + totalPositionCurrentVacant: totalPositionCurrentVacant, + totalPositionNextUse: totalPositionNextUse, + totalPositionNextVacant: totalPositionNextVacant, + }; + return new HttpSuccess(summary); + } + /** + * API สร้างคนครองตำแหน่ง + * + * @summary ORG_ - สร้างคนครองตำแหน่ง (ADMIN) + * + */ + @Post("profile") + async createEmpHolder( + @Body() requestBody: { posMaster: string; position: string; profileId: string; isSit: boolean }, + @Request() request: RequestWithUser, + ) { + await new permission().PermissionCreate(request, "SYS_ORG_TEMP"); + const dataMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { id: requestBody.posMaster }, + relations: ["positions"], + }); + if (!dataMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + } + dataMaster.positions.forEach(async (position) => { + if (position.id === requestBody.position) { + position.positionIsSelected = true; + const profile = await this.profileRepository.findOne({ + where: { id: requestBody.profileId }, + }); + if (profile != null) { + const _null: any = null; + profile.posLevelId = position?.posLevelId ?? _null; + profile.posTypeId = position?.posTypeId ?? _null; + profile.position = position?.positionName ?? _null; + await this.profileRepository.save(profile); + } + } else { + position.positionIsSelected = false; + } + await this.employeePositionRepository.save(position); + }); + + dataMaster.isSit = requestBody.isSit; + dataMaster.current_holderId = requestBody.profileId; + // dataMaster.next_holderId = requestBody.profileId; + await this.employeeTempPosMasterRepository.save(dataMaster); + + return new HttpSuccess(); + } + + /** + * API ลบคนครองตำแหน่ง + * + * @summary ORG_ - ลบคนครองตำแหน่ง (ADMIN) + * + * @param {string} id *Id posMaster + */ + @Post("profile/delete/{id}") + async deleteEmpHolder(@Path() id: string, @Request() request: RequestWithUser) { + await new permission().PermissionDelete(request, "SYS_ORG_TEMP"); + const dataMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { id: id }, + relations: ["positions"], + }); + if (!dataMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + } + await this.employeeTempPosMasterRepository.update(id, { + isSit: false, + next_holderId: null, + current_holderId: null, + }); + + dataMaster.positions.forEach(async (position) => { + await this.employeePositionRepository.update(position.id, { + positionIsSelected: false, + }); + }); + + return new HttpSuccess(); + } + + /** + * API สืบทอดตำแหน่ง + * + * @summary ORG_ - สืบทอดตำแหน่ง (ADMIN) + * + */ + @Post("dna") + async dnaEmp( + @Body() requestBody: { draftPositionId: string; publishPositionId: string }, + @Request() request: RequestWithUser, + ) { + await new permission().PermissionDelete(request, "SYS_ORG_TEMP"); + const findDraft = await this.orgRevisionRepository.findOne({ + where: { + orgRevisionIsDraft: true, + }, + }); + if (!findDraft) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงสร้างที่เผยแพร่"); + } + + const dataPublish = await this.employeeTempPosMasterRepository.findOne({ + where: { + id: requestBody.publishPositionId, + }, + }); + if (!dataPublish) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + } + + const dataDraft = await this.employeeTempPosMasterRepository.findOne({ + where: { + id: requestBody.draftPositionId, + }, + }); + if (!dataDraft) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + } + + await this.employeeTempPosMasterRepository.update( + { orgRevisionId: findDraft.id, ancestorDNA: dataPublish.ancestorDNA }, + { ancestorDNA: "" }, + ); + if (dataPublish.ancestorDNA == null || dataPublish.ancestorDNA == "") + dataPublish.ancestorDNA = dataPublish.id; + dataDraft.ancestorDNA = dataPublish.ancestorDNA; + await this.employeeTempPosMasterRepository.save(dataDraft); + await this.employeeTempPosMasterRepository.save(dataPublish); + + return new HttpSuccess(); + } + + /** + * API บันทึกตำแหน่งใหม่ + * + * @summary บันทึกตำแหน่งใหม่ + * + */ + @Post("report/current") + async reportApproveCurrent( + @Body() + body: { + posmasterId: string; + positionId: string; + profileId: string; + }, + @Request() request: RequestWithUser, + ) { + await new permission().PermissionCreate(request, "SYS_ORG_TEMP"); + const posMaster = await this.employeeTempPosMasterRepository.findOne({ + where: { id: body.posmasterId }, + relations: ["orgRoot"], + }); + if (posMaster == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + + const posMasterOld = await this.employeeTempPosMasterRepository.findOne({ + where: { + current_holderId: body.profileId, + orgRevisionId: posMaster.orgRevisionId, + }, + }); + if (posMasterOld != null) posMasterOld.current_holderId = null; + // if (posMasterOld != null) posMasterOld.next_holderId = null; + + const positionOld = await this.employeePositionRepository.findOne({ + where: { + posMasterTempId: posMasterOld?.id, + positionIsSelected: true, + }, + }); + if (positionOld != null) { + positionOld.positionIsSelected = false; + await this.employeePositionRepository.save(positionOld); + } + + const checkPosition = await this.employeePositionRepository.find({ + where: { + posMasterTempId: body.posmasterId, + positionIsSelected: true, + }, + }); + if (checkPosition.length > 0) { + const clearPosition = checkPosition.map((positions) => ({ + ...positions, + positionIsSelected: false, + })); + await this.employeePositionRepository.save(clearPosition); + } + + const profile = await this.profileRepository.findOne({ + where: { id: body.profileId }, + }); + if (profile == null) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); + + posMaster.current_holderId = body.profileId; + // posMaster.next_holderId = body.profileId; + if (posMasterOld != null) await this.employeeTempPosMasterRepository.save(posMasterOld); + await this.employeeTempPosMasterRepository.save(posMaster); + + const positionNew = await this.employeePositionRepository.findOne({ + where: { + id: body.positionId, + posMasterTempId: body.posmasterId, + }, + }); + if (positionNew != null) { + positionNew.positionIsSelected = true; + profile.posLevelId = positionNew.posLevelId; + profile.posTypeId = positionNew.posTypeId; + profile.position = positionNew.positionName; + profile.employeeOc = posMaster?.orgRoot?.orgRootName ?? null; + profile.positionEmployeePositionId = positionNew.positionName; + // profile.positionEmployeeLineId = "PERM"; + // profile.positionEmployeeGroupId = "PERM"; + + await this.profileRepository.save(profile); + await this.employeePositionRepository.save(positionNew); + } + return new HttpSuccess(); + } +} diff --git a/src/entities/AuthRole.ts b/src/entities/AuthRole.ts index d3df0a36..3dbd29ea 100644 --- a/src/entities/AuthRole.ts +++ b/src/entities/AuthRole.ts @@ -3,6 +3,7 @@ import { EntityBase } from "./base/Base"; import { AuthRoleAttr } from "./AuthRoleAttr"; import { PosMaster } from "./PosMaster"; import { EmployeePosMaster } from "../entities/EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; @Entity("authRole") export class AuthRole extends EntityBase { @@ -30,6 +31,9 @@ export class AuthRole extends EntityBase { @OneToMany(() => EmployeePosMaster, (posMasters) => posMasters.authRole) posMasterEmps: EmployeePosMaster[]; + + @OneToMany(() => EmployeeTempPosMaster, (posMasters) => posMasters.authRole) + posMasterEmpTemps: EmployeeTempPosMaster[]; } export class CreateAuthRole { diff --git a/src/entities/EmployeePosMaster.ts b/src/entities/EmployeePosMaster.ts index 59028072..ed79835f 100644 --- a/src/entities/EmployeePosMaster.ts +++ b/src/entities/EmployeePosMaster.ts @@ -197,27 +197,27 @@ export class EmployeePosMaster extends EntityBase { @JoinColumn({ name: "authRoleId" }) authRole: AuthRole; - @ManyToOne(() => OrgRevision, (orgRevision) => orgRevision.posMasters) + @ManyToOne(() => OrgRevision, (orgRevision) => orgRevision.employeePosMasters) @JoinColumn({ name: "orgRevisionId" }) orgRevision: OrgRevision; - @ManyToOne(() => OrgRoot, (orgRoot) => orgRoot.posMasters) + @ManyToOne(() => OrgRoot, (orgRoot) => orgRoot.employeePosMasters) @JoinColumn({ name: "orgRootId" }) orgRoot: OrgRoot; - @ManyToOne(() => OrgChild1, (orgChild1) => orgChild1.posMasters) + @ManyToOne(() => OrgChild1, (orgChild1) => orgChild1.employeePosMasters) @JoinColumn({ name: "orgChild1Id" }) orgChild1: OrgChild1; - @ManyToOne(() => OrgChild2, (orgChild2) => orgChild2.posMasters) + @ManyToOne(() => OrgChild2, (orgChild2) => orgChild2.employeePosMasters) @JoinColumn({ name: "orgChild2Id" }) orgChild2: OrgChild2; - @ManyToOne(() => OrgChild3, (orgChild3) => orgChild3.posMasters) + @ManyToOne(() => OrgChild3, (orgChild3) => orgChild3.employeePosMasters) @JoinColumn({ name: "orgChild3Id" }) orgChild3: OrgChild3; - @ManyToOne(() => OrgChild4, (orgChild4) => orgChild4.posMasters) + @ManyToOne(() => OrgChild4, (orgChild4) => orgChild4.employeePosMasters) @JoinColumn({ name: "orgChild4Id" }) orgChild4: OrgChild4; diff --git a/src/entities/EmployeePosition.ts b/src/entities/EmployeePosition.ts index e363ba69..4a78a471 100644 --- a/src/entities/EmployeePosition.ts +++ b/src/entities/EmployeePosition.ts @@ -3,6 +3,7 @@ import { EntityBase } from "./base/Base"; import { EmployeePosType } from "./EmployeePosType"; import { EmployeePosLevel } from "./EmployeePosLevel"; import { EmployeePosMaster } from "./EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; @Entity("employeePosition") export class EmployeePosition extends EntityBase { @@ -38,10 +39,20 @@ export class EmployeePosition extends EntityBase { }) posMasterId: string; + @Column({ + length: 40, + comment: "เชื่อมโยงกับตารางเลขที่ตำแหน่ง", + }) + posMasterTempId: string; + @ManyToOne(() => EmployeePosMaster, (posMaster) => posMaster) @JoinColumn({ name: "posMasterId" }) posMaster: EmployeePosMaster; + @ManyToOne(() => EmployeePosMaster, (posMaster) => posMaster) + @JoinColumn({ name: "posMasterTempId" }) + posMasterTemp: EmployeeTempPosMaster; + @ManyToOne(() => EmployeePosType, (posType) => posType) @JoinColumn({ name: "posTypeId" }) posType: EmployeePosType; diff --git a/src/entities/EmployeeTempPosMaster.ts b/src/entities/EmployeeTempPosMaster.ts new file mode 100644 index 00000000..82112df1 --- /dev/null +++ b/src/entities/EmployeeTempPosMaster.ts @@ -0,0 +1,271 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { CreateEmployeePosDict } from "./EmployeePosDict"; +import { OrgRevision } from "./OrgRevision"; +import { EmployeePosition } from "./EmployeePosition"; +import { OrgRoot } from "./OrgRoot"; +import { OrgChild1 } from "./OrgChild1"; +import { OrgChild2 } from "./OrgChild2"; +import { OrgChild3 } from "./OrgChild3"; +import { OrgChild4 } from "./OrgChild4"; +import { ProfileEmployee } from "./ProfileEmployee"; +import { AuthRole } from "./AuthRole"; + +enum EmployeeTempPosMasterLine { + MAIN = "MAIN", + SUPPORT = "SUPPORT", +} + +@Entity("employeeTempPosMaster") +export class EmployeeTempPosMaster extends EntityBase { + @Column({ + nullable: true, + comment: "Prefix นำหน้าเลขที่ตำแหน่ง เป็น Optional (ไม่ใช่อักษรย่อของหน่วยงาน/ส่วนราชการ)", + length: 16, + default: null, + }) + posMasterNoPrefix: string; + + @Column({ + nullable: true, + comment: "เลขที่ตำแหน่ง เป็นตัวเลข", + default: null, + }) + posMasterNo: number; + + @Column({ + nullable: true, + comment: "Suffix หลังเลขที่ตำแหน่ง เช่น ช.", + length: 16, + default: null, + }) + posMasterNoSuffix: string; + + @Column({ + nullable: true, + type: "datetime", + comment: "วัน-เวลาที่สร้าง", + default: null, + }) + posMasterCreatedAt: Date; + + @Column({ + nullable: true, + comment: + "รหัส DNA ใช้ในกรณีที่มีการทำสำเนาโครงสร้างและตำแหน่ง ตำแหน่งที่ทำสำเนามากับตำแหน่งเก่าจะต้องมี DNA เดียวกัน เพื่อให้ track ประวัติการแก้ไขตำแหน่งย้อนหลังได้", + length: 40, + default: null, + }) + ancestorDNA: string; + + @Column({ + nullable: true, + comment: "ลำดับที่แสดงผล", + default: null, + }) + posMasterOrder: number; + + @Column({ + nullable: true, + comment: "ลำดับความสำคัญ", + default: null, + }) + posMasterPriority: number; + + @Column({ + nullable: true, + comment: "สายงานในอัตรากำลัง (หลัก / สนับสนุน) คนละฟิลด์กับสายงานของตำแหน่ง", + type: "enum", + enum: EmployeeTempPosMasterLine, + default: null, + }) + posMasterLine: EmployeeTempPosMasterLine; + + @Column({ + comment: "นั่งทับตำแหน่งไหม", + default: false, + }) + isSit: boolean; + + @Column({ + comment: "เป็นผู้อำนวยการ", + default: false, + }) + isDirector: boolean; + + @Column({ + comment: "เป็นเจ้าหน้าที่", + default: false, + }) + isStaff: boolean; + + // @Column({ + // comment: "เป็นสกจ", + // default: false, + // }) + // isOfficer: boolean; + + @Column({ + nullable: true, + comment: "ตำแหน่งใต้ลายเซ็นต์", + type: "text", + default: null, + }) + positionSign: string; + + @Column({ + nullable: true, + comment: "หมายเหตุ", + type: "text", + default: null, + }) + reason: string; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง orgRoot", + default: null, + }) + orgRootId?: string | null; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง orgChild1", + default: null, + }) + orgChild1Id?: string | null; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง orgChild2", + default: null, + }) + orgChild2Id?: string | null; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง orgChild3", + default: null, + }) + orgChild3Id?: string | null; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง orgChild4", + default: null, + }) + orgChild4Id?: string | null; + + @Column({ + nullable: true, + length: 40, + comment: + "คนครองปัจจุบัน เมื่อทำสำเนาโครงสร้างและตำแหน่งพร้อมกับคนครองมา คนครองจะอยู่ในฟิลด์นี้", + default: null, + }) + current_holderId?: string | null; + + @Column({ + nullable: true, + length: 40, + comment: + "คนที่กำลังจะมาครอง ตอนปรับโครงสร้าง ถ้าเลือกให้ใครมาครอง ProfileId ของคนนั้นจะมาอยู่ในช่องนี้ รวมทั้งตอนเลือกตำแหน่งเพื่อบรรจุ แต่งตั้ง เลื่อน ย้าย ในระบบบรรจุแต่งตั้งด้วย", + default: null, + }) + next_holderId?: string | null; + + @Column({ + length: 40, + comment: "คีย์นอก(FK)ของตาราง orgRevision", + }) + orgRevisionId: string; //fk + + @Column({ + nullable: true, + default: null, + length: 40, + comment: "คีย์นอก(FK)ของตาราง authRole", + }) + authRoleId: string; + + @ManyToOne(() => AuthRole, (authRole) => authRole.posMasterEmpTemps) + @JoinColumn({ name: "authRoleId" }) + authRole: AuthRole; + + @ManyToOne(() => OrgRevision, (orgRevision) => orgRevision.employeeTempPosMasters) + @JoinColumn({ name: "orgRevisionId" }) + orgRevision: OrgRevision; + + @ManyToOne(() => OrgRoot, (orgRoot) => orgRoot.employeeTempPosMasters) + @JoinColumn({ name: "orgRootId" }) + orgRoot: OrgRoot; + + @ManyToOne(() => OrgChild1, (orgChild1) => orgChild1.employeeTempPosMasters) + @JoinColumn({ name: "orgChild1Id" }) + orgChild1: OrgChild1; + + @ManyToOne(() => OrgChild2, (orgChild2) => orgChild2.employeeTempPosMasters) + @JoinColumn({ name: "orgChild2Id" }) + orgChild2: OrgChild2; + + @ManyToOne(() => OrgChild3, (orgChild3) => orgChild3.employeeTempPosMasters) + @JoinColumn({ name: "orgChild3Id" }) + orgChild3: OrgChild3; + + @ManyToOne(() => OrgChild4, (orgChild4) => orgChild4.employeeTempPosMasters) + @JoinColumn({ name: "orgChild4Id" }) + orgChild4: OrgChild4; + + @ManyToOne(() => ProfileEmployee, (posMaster) => posMaster.current_holderTemps) + @JoinColumn({ name: "current_holderId" }) + current_holder: ProfileEmployee; + + @ManyToOne(() => ProfileEmployee, (posMaster) => posMaster.next_holderTemps) + @JoinColumn({ name: "next_holderId" }) + next_holder: ProfileEmployee; + + @OneToMany(() => EmployeePosition, (position) => position.posMasterTemp) + positions: EmployeePosition[]; +} + +export class CreateEmployeeTempPosMaster { + @Column() + posMasterNoPrefix: string; + + @Column() + posMasterNo: number; + + @Column() + posMasterNoSuffix: string; + + @Column("uuid") + positions: CreateEmployeePosDict[]; + + @Column("uuid") + orgRootId?: string | null; + + @Column("uuid") + orgChild1Id?: string | null; + + @Column("uuid") + orgChild2Id?: string | null; + + @Column("uuid") + orgChild3Id?: string | null; + + @Column("uuid") + orgChild4Id?: string | null; + + @Column() + reason: string | null; + + @Column() + isDirector: boolean; +} + +export type UpdateEmployeeTempPosMaster = Partial; diff --git a/src/entities/OrgChild1.ts b/src/entities/OrgChild1.ts index 81c709d0..9578a936 100644 --- a/src/entities/OrgChild1.ts +++ b/src/entities/OrgChild1.ts @@ -6,6 +6,8 @@ import { OrgRevision } from "./OrgRevision"; import { OrgChild3 } from "./OrgChild3"; import { OrgChild4 } from "./OrgChild4"; import { PosMaster } from "./PosMaster"; +import { EmployeePosMaster } from "./EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; enum OrgChild1Rank { DEPARTMENT = "DEPARTMENT", @@ -187,6 +189,15 @@ export class OrgChild1 extends EntityBase { @OneToMany(() => PosMaster, (posMaster) => posMaster.orgChild1) posMasters: PosMaster[]; + + @OneToMany(() => EmployeePosMaster, (employeePosMaster) => employeePosMaster.orgChild1) + employeePosMasters: EmployeePosMaster[]; + + @OneToMany( + () => EmployeeTempPosMaster, + (employeeTempposMaster) => employeeTempposMaster.orgChild1, + ) + employeeTempPosMasters: EmployeeTempPosMaster[]; } export class CreateOrgChild1 { diff --git a/src/entities/OrgChild2.ts b/src/entities/OrgChild2.ts index a222a7ce..ea83797c 100644 --- a/src/entities/OrgChild2.ts +++ b/src/entities/OrgChild2.ts @@ -6,6 +6,8 @@ import { OrgChild3 } from "./OrgChild3"; import { OrgChild4 } from "./OrgChild4"; import { OrgRevision } from "./OrgRevision"; import { PosMaster } from "./PosMaster"; +import { EmployeePosMaster } from "./EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; enum OrgChild2Rank { DEPARTMENT = "DEPARTMENT", @@ -181,6 +183,15 @@ export class OrgChild2 extends EntityBase { @OneToMany(() => PosMaster, (posMaster) => posMaster.orgChild2) posMasters: PosMaster[]; + + @OneToMany(() => EmployeePosMaster, (employeePosMaster) => employeePosMaster.orgChild2) + employeePosMasters: EmployeePosMaster[]; + + @OneToMany( + () => EmployeeTempPosMaster, + (employeeTempposMaster) => employeeTempposMaster.orgChild2, + ) + employeeTempPosMasters: EmployeeTempPosMaster[]; } export class CreateOrgChild2 { diff --git a/src/entities/OrgChild3.ts b/src/entities/OrgChild3.ts index 95b45952..63d22058 100644 --- a/src/entities/OrgChild3.ts +++ b/src/entities/OrgChild3.ts @@ -6,6 +6,8 @@ import { OrgRevision } from "./OrgRevision"; import { OrgChild1 } from "./OrgChild1"; import { OrgRoot } from "./OrgRoot"; import { PosMaster } from "./PosMaster"; +import { EmployeePosMaster } from "./EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; enum OrgChild3Rank { DEPARTMENT = "DEPARTMENT", @@ -189,6 +191,15 @@ export class OrgChild3 extends EntityBase { @OneToMany(() => PosMaster, (posMaster) => posMaster.orgChild3) posMasters: PosMaster[]; + + @OneToMany(() => EmployeePosMaster, (employeePosMaster) => employeePosMaster.orgChild3) + employeePosMasters: EmployeePosMaster[]; + + @OneToMany( + () => EmployeeTempPosMaster, + (employeeTempposMaster) => employeeTempposMaster.orgChild3, + ) + employeeTempPosMasters: EmployeeTempPosMaster[]; } export class CreateOrgChild3 { diff --git a/src/entities/OrgChild4.ts b/src/entities/OrgChild4.ts index 67845dda..69f0b7cf 100644 --- a/src/entities/OrgChild4.ts +++ b/src/entities/OrgChild4.ts @@ -6,6 +6,8 @@ import { OrgChild2 } from "./OrgChild2"; import { OrgChild3 } from "./OrgChild3"; import { OrgRevision } from "./OrgRevision"; import { PosMaster } from "./PosMaster"; +import { EmployeePosMaster } from "./EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; enum OrgChild4Rank { DEPARTMENT = "DEPARTMENT", @@ -195,6 +197,15 @@ export class OrgChild4 extends EntityBase { @OneToMany(() => PosMaster, (posMaster) => posMaster.orgChild4) posMasters: PosMaster[]; + + @OneToMany(() => EmployeePosMaster, (employeePosMaster) => employeePosMaster.orgChild4) + employeePosMasters: EmployeePosMaster[]; + + @OneToMany( + () => EmployeeTempPosMaster, + (employeeTempposMaster) => employeeTempposMaster.orgChild4, + ) + employeeTempPosMasters: EmployeeTempPosMaster[]; } export class CreateOrgChild4 { diff --git a/src/entities/OrgRevision.ts b/src/entities/OrgRevision.ts index 47864ab8..4ff1ec8a 100644 --- a/src/entities/OrgRevision.ts +++ b/src/entities/OrgRevision.ts @@ -7,6 +7,7 @@ import { OrgChild2 } from "./OrgChild2"; import { OrgChild3 } from "./OrgChild3"; import { OrgChild4 } from "./OrgChild4"; import { EmployeePosMaster } from "./EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; @Entity("orgRevision") export class OrgRevision extends EntityBase { @@ -65,6 +66,12 @@ export class OrgRevision extends EntityBase { @OneToMany(() => EmployeePosMaster, (employeePosMaster) => employeePosMaster.orgRevision) employeePosMasters: EmployeePosMaster[]; + @OneToMany( + () => EmployeeTempPosMaster, + (employeeTempPosMaster) => employeeTempPosMaster.orgRevision, + ) + employeeTempPosMasters: EmployeeTempPosMaster[]; + @OneToMany(() => OrgRoot, (orgRoot) => orgRoot.orgRevision) orgRoots: OrgRoot[]; diff --git a/src/entities/OrgRoot.ts b/src/entities/OrgRoot.ts index 6d91daa0..83f566c5 100644 --- a/src/entities/OrgRoot.ts +++ b/src/entities/OrgRoot.ts @@ -7,6 +7,8 @@ import { OrgChild3 } from "./OrgChild3"; import { OrgChild4 } from "./OrgChild4"; import { PosMaster } from "./PosMaster"; import { PermissionOrg } from "./PermissionOrg"; +import { EmployeePosMaster } from "./EmployeePosMaster"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; enum OrgRootRank { DEPARTMENT = "DEPARTMENT", @@ -170,6 +172,12 @@ export class OrgRoot extends EntityBase { @OneToMany(() => PosMaster, (posMaster) => posMaster.orgRoot) posMasters: PosMaster[]; + @OneToMany(() => EmployeePosMaster, (employeePosMaster) => employeePosMaster.orgRoot) + employeePosMasters: EmployeePosMaster[]; + + @OneToMany(() => EmployeeTempPosMaster, (employeeTempposMaster) => employeeTempposMaster.orgRoot) + employeeTempPosMasters: EmployeeTempPosMaster[]; + @OneToMany(() => OrgChild1, (orgChild1) => orgChild1.orgRoot) orgChild1s: OrgChild1[]; diff --git a/src/entities/ProfileEmployee.ts b/src/entities/ProfileEmployee.ts index c6ee449a..6bf72fd4 100644 --- a/src/entities/ProfileEmployee.ts +++ b/src/entities/ProfileEmployee.ts @@ -35,6 +35,7 @@ import { ProfileDevelopment } from "./ProfileDevelopment"; import { DevelopmentRequest } from "./DevelopmentRequest"; import { RoleKeycloak } from "./RoleKeycloak"; import { StateOperatorUser } from "./StateOperatorUser"; +import { EmployeeTempPosMaster } from "./EmployeeTempPosMaster"; @Entity("profileEmployee") export class ProfileEmployee extends EntityBase { @@ -674,6 +675,12 @@ export class ProfileEmployee extends EntityBase { @OneToMany(() => EmployeePosMaster, (v) => v.next_holder) next_holders: EmployeePosMaster[]; + @OneToMany(() => EmployeeTempPosMaster, (v) => v.current_holder) + current_holderTemps: EmployeeTempPosMaster[]; + + @OneToMany(() => EmployeeTempPosMaster, (v) => v.next_holder) + next_holderTemps: EmployeeTempPosMaster[]; + @OneToMany(() => ProfileSalary, (v) => v.profileEmployee) profileSalary: ProfileSalary[]; diff --git a/src/migration/1740032788782-addtableorgtemp.ts b/src/migration/1740032788782-addtableorgtemp.ts new file mode 100644 index 00000000..bee9699e --- /dev/null +++ b/src/migration/1740032788782-addtableorgtemp.ts @@ -0,0 +1,36 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Addtableorgtemp1740032788782 implements MigrationInterface { + name = 'Addtableorgtemp1740032788782' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`employeeTempPosMaster\` (\`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', \`posMasterNoPrefix\` varchar(16) NULL COMMENT 'Prefix นำหน้าเลขที่ตำแหน่ง เป็น Optional (ไม่ใช่อักษรย่อของหน่วยงาน/ส่วนราชการ)', \`posMasterNo\` int NULL COMMENT 'เลขที่ตำแหน่ง เป็นตัวเลข', \`posMasterNoSuffix\` varchar(16) NULL COMMENT 'Suffix หลังเลขที่ตำแหน่ง เช่น ช.', \`posMasterCreatedAt\` datetime NULL COMMENT 'วัน-เวลาที่สร้าง', \`ancestorDNA\` varchar(40) NULL COMMENT 'รหัส DNA ใช้ในกรณีที่มีการทำสำเนาโครงสร้างและตำแหน่ง ตำแหน่งที่ทำสำเนามากับตำแหน่งเก่าจะต้องมี DNA เดียวกัน เพื่อให้ track ประวัติการแก้ไขตำแหน่งย้อนหลังได้', \`posMasterOrder\` int NULL COMMENT 'ลำดับที่แสดงผล', \`posMasterPriority\` int NULL COMMENT 'ลำดับความสำคัญ', \`posMasterLine\` enum ('MAIN', 'SUPPORT') NULL COMMENT 'สายงานในอัตรากำลัง (หลัก / สนับสนุน) คนละฟิลด์กับสายงานของตำแหน่ง', \`isSit\` tinyint NOT NULL COMMENT 'นั่งทับตำแหน่งไหม' DEFAULT 0, \`isDirector\` tinyint NOT NULL COMMENT 'เป็นผู้อำนวยการ' DEFAULT 0, \`isStaff\` tinyint NOT NULL COMMENT 'เป็นเจ้าหน้าที่' DEFAULT 0, \`positionSign\` text NULL COMMENT 'ตำแหน่งใต้ลายเซ็นต์', \`reason\` text NULL COMMENT 'หมายเหตุ', \`orgRootId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgRoot', \`orgChild1Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild1', \`orgChild2Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild2', \`orgChild3Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild3', \`orgChild4Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild4', \`current_holderId\` varchar(40) NULL COMMENT 'คนครองปัจจุบัน เมื่อทำสำเนาโครงสร้างและตำแหน่งพร้อมกับคนครองมา คนครองจะอยู่ในฟิลด์นี้', \`next_holderId\` varchar(40) NULL COMMENT 'คนที่กำลังจะมาครอง ตอนปรับโครงสร้าง ถ้าเลือกให้ใครมาครอง ProfileId ของคนนั้นจะมาอยู่ในช่องนี้ รวมทั้งตอนเลือกตำแหน่งเพื่อบรรจุ แต่งตั้ง เลื่อน ย้าย ในระบบบรรจุแต่งตั้งด้วย', \`orgRevisionId\` varchar(40) NOT NULL COMMENT 'คีย์นอก(FK)ของตาราง orgRevision', \`authRoleId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง authRole', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`employeePosition\` ADD \`posMasterTempId\` varchar(40) NOT NULL COMMENT 'เชื่อมโยงกับตารางเลขที่ตำแหน่ง'`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_fbdaed7e18a082ec271453c3af3\` FOREIGN KEY (\`authRoleId\`) REFERENCES \`authRole\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_6882777277ba389e6d87251451e\` FOREIGN KEY (\`orgRevisionId\`) REFERENCES \`orgRevision\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_4ea59a95b75b76d9fecf18b3329\` FOREIGN KEY (\`orgRootId\`) REFERENCES \`orgRoot\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_d5df44e2dfbfb67f9303ef53664\` FOREIGN KEY (\`orgChild1Id\`) REFERENCES \`orgChild1\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_507c4ec071a564b871018afd99f\` FOREIGN KEY (\`orgChild2Id\`) REFERENCES \`orgChild2\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_50eb54a5cda9103e1ca5b28fbc7\` FOREIGN KEY (\`orgChild3Id\`) REFERENCES \`orgChild3\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_099675941952365232292ee5b79\` FOREIGN KEY (\`orgChild4Id\`) REFERENCES \`orgChild4\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_2544a0337043dd5a593b1698336\` FOREIGN KEY (\`current_holderId\`) REFERENCES \`profileEmployee\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` ADD CONSTRAINT \`FK_d7e32a7900d32a7358d64464a91\` FOREIGN KEY (\`next_holderId\`) REFERENCES \`profileEmployee\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`employeePosition\` ADD CONSTRAINT \`FK_d98cc02c1c2f9830afcb1493b00\` FOREIGN KEY (\`posMasterTempId\`) REFERENCES \`employeePosMaster\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`employeePosition\` DROP FOREIGN KEY \`FK_d98cc02c1c2f9830afcb1493b00\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_d7e32a7900d32a7358d64464a91\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_2544a0337043dd5a593b1698336\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_099675941952365232292ee5b79\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_50eb54a5cda9103e1ca5b28fbc7\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_507c4ec071a564b871018afd99f\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_d5df44e2dfbfb67f9303ef53664\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_4ea59a95b75b76d9fecf18b3329\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_6882777277ba389e6d87251451e\``); + await queryRunner.query(`ALTER TABLE \`employeeTempPosMaster\` DROP FOREIGN KEY \`FK_fbdaed7e18a082ec271453c3af3\``); + await queryRunner.query(`ALTER TABLE \`employeePosition\` DROP COLUMN \`posMasterTempId\``); + await queryRunner.query(`DROP TABLE \`employeeTempPosMaster\``); + } + +}