diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 58a9b149..81004807 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,7 +11,7 @@ env: DEPLOY_HOST: frappet.com COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-org jobs: - # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=test-v1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd + # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357 release-test: runs-on: ubuntu-latest steps: diff --git a/src/controllers/OrganizationController.ts b/src/controllers/OrganizationController.ts index 076a9e3a..38fd52b0 100644 --- a/src/controllers/OrganizationController.ts +++ b/src/controllers/OrganizationController.ts @@ -1600,7 +1600,7 @@ export class OrganizationController extends Controller { * * @param {string} id Id revison */ - @Get("/get/publish") + @Get("get/publish") async runPublish() { const today = new Date(); today.setHours(0, 0, 0, 0); // Set time to the beginning of the day @@ -3056,19 +3056,19 @@ export class OrganizationController extends Controller { "orgChild1s.orgChild2s.orgChild3s.orgChild4s", ], order: { - orgChild1s:{ + orgChild1s: { orgChild1Order: "ASC", - orgChild2s:{ + orgChild2s: { orgChild2Order: "ASC", - orgChild3s:{ + orgChild3s: { orgChild3Order: "ASC", - orgChild4s:{ + orgChild4s: { orgChild4Order: "ASC", - } - } - } + }, + }, + }, }, - } + }, }); return new HttpSuccess(data); } @@ -3088,4 +3088,264 @@ export class OrganizationController extends Controller { } return new HttpSuccess(findRevision.id); } + + /** + * API รายละเอียดโครงสร้าง + * + * @summary รายละเอียดโครงสร้าง (ADMIN) + * + */ + @Get("act/{id}") + async detailAct(@Path() id: string) { + const orgRevision = await this.orgRevisionRepository.findOne({ where: { id } }); + if (!orgRevision) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + + const orgRootData = await AppDataSource.getRepository(OrgRoot) + .createQueryBuilder("orgRoot") + .where("orgRoot.orgRevisionId = :id", { id }) + .leftJoinAndSelect("orgRoot.posMasters", "posMasters") + .leftJoinAndSelect("posMasters.current_holder", "current_holder") + .orderBy("orgRoot.orgRootOrder", "ASC") + .getMany(); + + const orgRootIds = orgRootData.map((orgRoot) => orgRoot.id) || null; + const orgChild1Data = + orgRootIds && orgRootIds.length > 0 + ? await AppDataSource.getRepository(OrgChild1) + .createQueryBuilder("orgChild1") + .where("orgChild1.orgRootId IN (:...ids)", { ids: orgRootIds }) + .leftJoinAndSelect("orgChild1.posMasters", "posMasters") + .leftJoinAndSelect("posMasters.current_holder", "current_holder") + .orderBy("orgChild1.orgChild1Order", "ASC") + .getMany() + : []; + + const orgChild1Ids = orgChild1Data.map((orgChild1) => orgChild1.id) || null; + const orgChild2Data = + orgChild1Ids && orgChild1Ids.length > 0 + ? await AppDataSource.getRepository(OrgChild2) + .createQueryBuilder("orgChild2") + .where("orgChild2.orgChild1Id IN (:...ids)", { ids: orgChild1Ids }) + .leftJoinAndSelect("orgChild2.posMasters", "posMasters") + .leftJoinAndSelect("posMasters.current_holder", "current_holder") + .orderBy("orgChild2.orgChild2Order", "ASC") + .getMany() + : []; + + const orgChild2Ids = orgChild2Data.map((orgChild2) => orgChild2.id) || null; + const orgChild3Data = + orgChild2Ids && orgChild2Ids.length > 0 + ? await AppDataSource.getRepository(OrgChild3) + .createQueryBuilder("orgChild3") + .where("orgChild3.orgChild2Id IN (:...ids)", { ids: orgChild2Ids }) + .leftJoinAndSelect("orgChild3.posMasters", "posMasters") + .leftJoinAndSelect("posMasters.current_holder", "current_holder") + .orderBy("orgChild3.orgChild3Order", "ASC") + .getMany() + : []; + + const orgChild3Ids = orgChild3Data.map((orgChild3) => orgChild3.id) || null; + const orgChild4Data = + orgChild3Ids && orgChild3Ids.length > 0 + ? await AppDataSource.getRepository(OrgChild4) + .createQueryBuilder("orgChild4") + .where("orgChild4.orgChild3Id IN (:...ids)", { ids: orgChild3Ids }) + .leftJoinAndSelect("orgChild4.posMasters", "posMasters") + .leftJoinAndSelect("posMasters.current_holder", "current_holder") + .orderBy("orgChild4.orgChild4Order", "ASC") + .getMany() + : []; + + // const formattedData = orgRootData.map((orgRoot) => { + const formattedData = await Promise.all( + orgRootData.map(async (orgRoot) => { + return { + orgTreeId: orgRoot.id, + orgLevel: 0, + orgName: orgRoot.orgRootName, + orgTreeName: orgRoot.orgRootName, + orgTreeShortName: orgRoot.orgRootShortName, + orgTreeCode: orgRoot.orgRootCode, + orgCode: orgRoot.orgRootCode + "00", + orgRootName: orgRoot.orgRootName, + labelName: + orgRoot.orgRootName + " " + orgRoot.orgRootCode + "00" + " " + orgRoot.orgRootShortName, + posMaster: await Promise.all( + orgRoot.posMasters + .filter( + (x) => x.orgChild1Id != null && x.current_holderId != null && x.posMasterOrder <= 3, + ) + .map(async (x) => ({ + orgTreeId: orgRoot.id, + orgLevel: 0, + fullNameCurrentHolder: + x.current_holder == null + ? null + : `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`, + })), + ), + children: await Promise.all( + orgChild1Data + .filter((orgChild1) => orgChild1.orgRootId === orgRoot.id) + .map(async (orgChild1) => ({ + orgTreeId: orgChild1.id, + orgRootId: orgRoot.id, + orgLevel: 1, + orgName: `${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`, + orgTreeName: orgChild1.orgChild1Name, + orgTreeShortName: orgChild1.orgChild1ShortName, + orgTreeCode: orgChild1.orgChild1Code, + orgCode: orgRoot.orgRootCode + orgChild1.orgChild1Code, + orgRootName: orgRoot.orgRootName, + labelName: + orgChild1.orgChild1Name + + " " + + orgRoot.orgRootCode + + orgChild1.orgChild1Code + + " " + + orgChild1.orgChild1ShortName, + posMaster: await Promise.all( + orgChild1.posMasters + .filter( + (x) => + x.orgChild2Id != null && + x.current_holderId != null && + x.posMasterOrder <= 3, + ) + .map(async (x) => ({ + orgTreeId: orgChild1.id, + orgLevel: 1, + fullNameCurrentHolder: + x.current_holder == null + ? null + : `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`, + })), + ), + + children: await Promise.all( + orgChild2Data + .filter((orgChild2) => orgChild2.orgChild1Id === orgChild1.id) + .map(async (orgChild2) => ({ + orgTreeId: orgChild2.id, + orgRootId: orgChild1.id, + orgLevel: 2, + orgName: `${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`, + orgTreeName: orgChild2.orgChild2Name, + orgTreeShortName: orgChild2.orgChild2ShortName, + orgTreeCode: orgChild2.orgChild2Code, + orgCode: orgRoot.orgRootCode + orgChild2.orgChild2Code, + orgRootName: orgRoot.orgRootName, + labelName: + orgChild2.orgChild2Name + + " " + + orgRoot.orgRootCode + + orgChild2.orgChild2Code + + " " + + orgChild2.orgChild2ShortName, + posMaster: await Promise.all( + orgChild2.posMasters + .filter( + (x) => + x.orgChild3Id != null && + x.current_holderId != null && + x.posMasterOrder <= 3, + ) + .map(async (x) => ({ + orgTreeId: orgChild2.id, + orgLevel: 2, + fullNameCurrentHolder: + x.current_holder == null + ? null + : `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`, + })), + ), + + children: await Promise.all( + orgChild3Data + .filter((orgChild3) => orgChild3.orgChild2Id === orgChild2.id) + .map(async (orgChild3) => ({ + orgTreeId: orgChild3.id, + orgRootId: orgChild2.id, + orgLevel: 3, + orgName: `${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`, + orgTreeName: orgChild3.orgChild3Name, + orgTreeShortName: orgChild3.orgChild3ShortName, + orgTreeCode: orgChild3.orgChild3Code, + orgCode: orgRoot.orgRootCode + orgChild3.orgChild3Code, + orgRootName: orgRoot.orgRootName, + labelName: + orgChild3.orgChild3Name + + " " + + orgRoot.orgRootCode + + orgChild3.orgChild3Code + + " " + + orgChild3.orgChild3ShortName, + posMaster: await Promise.all( + orgChild3.posMasters + .filter( + (x) => + x.orgChild4Id != null && + x.current_holderId != null && + x.posMasterOrder <= 3, + ) + .map(async (x) => ({ + orgTreeId: orgChild3.id, + orgLevel: 3, + fullNameCurrentHolder: + x.current_holder == null + ? null + : `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`, + })), + ), + + children: await Promise.all( + orgChild4Data + .filter((orgChild4) => orgChild4.orgChild3Id === orgChild3.id) + .map(async (orgChild4) => ({ + orgTreeId: orgChild4.id, + orgRootId: orgChild3.id, + orgLevel: 4, + orgName: `${orgChild4.orgChild4Name}/${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`, + orgTreeName: orgChild4.orgChild4Name, + orgTreeShortName: orgChild4.orgChild4ShortName, + orgTreeCode: orgChild4.orgChild4Code, + orgCode: orgRoot.orgRootCode + orgChild4.orgChild4Code, + orgRootName: orgRoot.orgRootName, + labelName: + orgChild4.orgChild4Name + + " " + + orgRoot.orgRootCode + + orgChild4.orgChild4Code + + " " + + orgChild4.orgChild4ShortName, + posMaster: await Promise.all( + orgChild4.posMasters + .filter( + (x) => x.current_holderId != null && x.posMasterOrder <= 3, + ) + .map(async (x) => ({ + orgTreeId: orgChild4.id, + orgLevel: 4, + fullNameCurrentHolder: + x.current_holder == null + ? null + : `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`, + })), + ), + })), + ), + })), + ), + })), + ), + })), + ), + }; + }), + ); + + return new HttpSuccess(formattedData); + } } diff --git a/src/controllers/PosMasterActController.ts b/src/controllers/PosMasterActController.ts new file mode 100644 index 00000000..f7ba6dc3 --- /dev/null +++ b/src/controllers/PosMasterActController.ts @@ -0,0 +1,241 @@ +import { + Controller, + Get, + Post, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + SuccessResponse, + Response, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatusCode from "../interfaces/http-status"; +import { PosLevel, CreatePosLevel } from "../entities/PosLevel"; +import HttpError from "../interfaces/http-error"; +import { PosMasterAct } from "../entities/PosMasterAct"; +import { PosMaster } from "../entities/PosMaster"; +import { LessThan, MoreThan } from "typeorm"; + +@Route("api/v1/org/pos/act") +@Tags("PosMasterAct") +@Security("bearerAuth") +@Response( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) +@SuccessResponse(HttpStatusCode.OK, "สำเร็จ") +export class PosMasterActController extends Controller { + private posMasterActRepository = AppDataSource.getRepository(PosMasterAct); + private posMasterRepository = AppDataSource.getRepository(PosMaster); + + /** + * API เพิ่มรักษาการในตำแหน่ง + * + * @summary เพิ่มรักษาการในตำแหน่ง (ADMIN) + * + */ + @Post() + async createPosMasterAct( + @Body() requestBody: { posMasterId: string; posMasterChildId: string }, + @Request() request: { user: Record }, + ) { + const posMaster = await this.posMasterRepository.findOne({ + where: { + id: requestBody.posMasterId, + }, + }); + if (posMaster == null) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + } + + const posMasterChild = await this.posMasterRepository.findOne({ + where: { + id: requestBody.posMasterChildId, + }, + }); + if (posMasterChild == null) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + } + + const posMasterActOld = await this.posMasterActRepository.findOne({ + where: { + posMasterId: requestBody.posMasterId, + }, + order: { posMasterOrder: "DESC" }, + }); + let num = 0; + if (posMasterActOld != null) { + num = posMasterActOld.posMasterOrder; + } + + const posMasterAct = new PosMasterAct(); + posMasterAct.posMasterOrder = num + 1; + posMasterAct.posMasterId = requestBody.posMasterId; + posMasterAct.posMasterChildId = requestBody.posMasterChildId; + posMasterAct.createdUserId = request.user.sub; + posMasterAct.createdFullName = request.user.name; + posMasterAct.lastUpdateUserId = request.user.sub; + posMasterAct.lastUpdateFullName = request.user.name; + await this.posMasterActRepository.save(posMasterAct); + return new HttpSuccess(posMasterAct); + } + + /** + * API ลบรักษาการในตำแหน่ง + * + * @summary ลบรักษาการในตำแหน่ง (ADMIN) + * + * @param {string} id Id รักษาการในตำแหน่ง + */ + @Delete("{id}") + async deletePosMasterAct(@Path() id: string) { + let result: any; + const posMasterAct = await this.posMasterActRepository.findOne({ + where: { + id: id, + }, + }); + try { + result = await this.posMasterActRepository.delete({ id: id }); + } catch { + throw new HttpError( + HttpStatusCode.NOT_FOUND, + "ไม่สามารถลบได้เนื่องจากมีการใช้งานระดับตำแหน่งนี้อยู่", + ); + } + if (result.affected == undefined || result.affected <= 0) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); + } + + if (posMasterAct != null) { + const posMasterActList = await this.posMasterActRepository.find({ + where: { + posMasterId: posMasterAct.posMasterId, + }, + }); + let num = 0; + posMasterActList.forEach(async (p) => { + p.posMasterOrder = num + 1; + await this.posMasterActRepository.save(p); + num = num + 1; + }); + } + return new HttpSuccess(); + } + + /** + * API สลับรักษาการในตำแหน่ง + * + * @summary สลับรักษาการในตำแหน่ง (ADMIN) + * + */ + @Get("swap/{direction}/{posMasterActId}") + async swapPosMasterAct( + @Path() direction: string, + posMasterActId: string, + @Request() request: { user: Record }, + ) { + const source_item = await this.posMasterActRepository.findOne({ + where: { + id: posMasterActId, + }, + }); + if (source_item == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); + const sourceOrder = source_item.posMasterOrder; + + if (direction.trim().toUpperCase() == "UP") { + const dest_item = await this.posMasterActRepository.findOne({ + where: { posMasterId: source_item.posMasterId, posMasterOrder: LessThan(sourceOrder) }, + order: { posMasterOrder: "DESC" }, + }); + if (dest_item == null) return new HttpSuccess(); + var destOrder = dest_item.posMasterOrder; + dest_item.posMasterOrder = sourceOrder; + source_item.posMasterOrder = destOrder; + await Promise.all([ + this.posMasterActRepository.save(source_item), + this.posMasterActRepository.save(dest_item), + ]); + } else { + const dest_item = await this.posMasterActRepository.findOne({ + where: { posMasterId: source_item.posMasterId, posMasterOrder: MoreThan(sourceOrder) }, + order: { posMasterOrder: "ASC" }, + }); + if (dest_item == null) return new HttpSuccess(); + var destOrder = dest_item.posMasterOrder; + dest_item.posMasterOrder = sourceOrder; + source_item.posMasterOrder = destOrder; + await Promise.all([ + this.posMasterActRepository.save(source_item), + this.posMasterActRepository.save(dest_item), + ]); + } + return new HttpSuccess(); + } + + /** + * API รายละเอียดรักษาการในตำแหน่ง + * + * @summary รายละเอียดรักษาการในตำแหน่ง (ADMIN) + * + * @param {string} id Id รักษาการในตำแหน่ง + */ + @Get("{id}") + async GetPosMasterActDetail(@Path() id: string) { + const posMaster = await this.posMasterRepository.findOne({ + relations: [ + "posMasterActs", + "posMasterActs.posMasterChild", + "posMasterActs.posMasterChild.orgRoot", + "posMasterActs.posMasterChild.orgChild1", + "posMasterActs.posMasterChild.orgChild2", + "posMasterActs.posMasterChild.orgChild3", + "posMasterActs.posMasterChild.orgChild4", + "posMasterActs.posMasterChild.current_holder", + "posMasterActs.posMasterChild.current_holder.posLevel", + "posMasterActs.posMasterChild.current_holder.posType", + ], + where: { id: id }, + }); + if (!posMaster) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); + } + + const data = await Promise.all( + posMaster.posMasterActs + .sort((a, b) => a.posMasterOrder - b.posMasterOrder) + .map((item) => { + const shortName = + item.posMasterChild != null && item.posMasterChild.orgChild4 != null + ? `${item.posMasterChild.orgChild4.orgChild4ShortName}${item.posMasterChild.posMasterNo}` + : item.posMasterChild != null && item.posMasterChild?.orgChild3 != null + ? `${item.posMasterChild.orgChild3.orgChild3ShortName}${item.posMasterChild.posMasterNo}` + : item.posMasterChild != null && item.posMasterChild?.orgChild2 != null + ? `${item.posMasterChild.orgChild2.orgChild2ShortName}${item.posMasterChild.posMasterNo}` + : item.posMasterChild != null && item.posMasterChild?.orgChild1 != null + ? `${item.posMasterChild.orgChild1.orgChild1ShortName}${item.posMasterChild.posMasterNo}` + : item.posMasterChild != null && item.posMasterChild?.orgRoot != null + ? `${item.posMasterChild.orgRoot.orgRootShortName}${item.posMasterChild.posMasterNo}` + : null; + return { + id: item.id, + posMasterOrder: item.posMasterOrder, + citizenId: item.posMasterChild?.current_holder?.citizenId ?? null, + prefix: item.posMasterChild?.current_holder?.prefix ?? null, + firstName: item.posMasterChild?.current_holder?.firstName ?? null, + lastName: item.posMasterChild?.current_holder?.lastName ?? null, + posLevel: item.posMasterChild?.current_holder?.posLevel?.posLevelName ?? null, + posType: item.posMasterChild?.current_holder?.posType?.posTypeName ?? null, + position: item.posMasterChild?.current_holder?.position ?? null, + posNo: shortName, + }; + }), + ); + return new HttpSuccess(data); + } +} diff --git a/src/controllers/PositionController.ts b/src/controllers/PositionController.ts index 2488ccfb..24505bac 100644 --- a/src/controllers/PositionController.ts +++ b/src/controllers/PositionController.ts @@ -1274,7 +1274,7 @@ export class PositionController extends Controller { }); const authRoleName = await this.authRoleRepo.findOne({ - where: { id: String(posMaster.authRoleId) } + where: { id: String(posMaster.authRoleId) }, }); let profile: any; @@ -1366,7 +1366,8 @@ export class PositionController extends Controller { profilePostype: type == null || type.posTypeName == null ? null : type.posTypeName, profilePoslevel: level == null || level.posLevelName == null ? null : level.posLevelName, authRoleId: posMaster.authRoleId, - authRoleName: authRoleName == null || authRoleName.roleName == null ? null : authRoleName.roleName, + authRoleName: + authRoleName == null || authRoleName.roleName == null ? null : authRoleName.roleName, positions: positions.map((position: any) => ({ id: position.id, positionName: position.positionName, @@ -2743,6 +2744,14 @@ export class PositionController extends Controller { posMasterNoSuffix: posMaster.posMasterNoSuffix, orgShortname: shortName, isSit: posMaster.isSit, + 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}`, isPosition: posMaster.positions.filter((x) => x.positionName == body.position).length > 0, positions: posMaster.positions.map((position) => ({ id: position.id, @@ -3181,4 +3190,81 @@ export class PositionController extends Controller { ); return new HttpSuccess({ data: formattedData, total }); } + + /** + * API ค้นหาตำแหน่งในระบบสมัครสอบ ขรก. + * + * @summary ค้นหาตำแหน่งในระบบสมัครสอบ ขรก. + * + */ + @Post("act/search") + async searchAct( + @Body() + body: { + posmasterId: string; + }, + ) { + const posMasterMain = await this.posMasterRepository.findOne({ + where: { id: body.posmasterId }, + relations: ["posMasterActs"], + }); + if (posMasterMain == null) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); + } + let posId: any = posMasterMain.posMasterActs.map((x) => x.posMasterChildId); + posId.push(body.posmasterId); + let typeCondition: any = { + orgRootId: posMasterMain.orgRootId == null ? IsNull() : posMasterMain.orgRootId, + orgChild1Id: posMasterMain.orgChild1Id == null ? IsNull() : posMasterMain.orgChild1Id, + orgChild2Id: posMasterMain.orgChild2Id == null ? IsNull() : posMasterMain.orgChild2Id, + orgChild3Id: posMasterMain.orgChild3Id == null ? IsNull() : posMasterMain.orgChild3Id, + orgChild4Id: posMasterMain.orgChild4Id == null ? IsNull() : posMasterMain.orgChild4Id, + current_holderId: Not(IsNull()), + id: Not(In(posId)), + }; + const posMaster = await this.posMasterRepository.find({ + where: typeCondition, + relations: [ + "orgRoot", + "orgChild1", + "orgChild2", + "orgChild3", + "orgChild4", + "current_holder", + "current_holder.posLevel", + "current_holder.posType", + ], + }); + + const data = await Promise.all( + posMaster + .sort((a, b) => a.posMasterOrder - b.posMasterOrder) + .map((item) => { + const shortName = + item.orgChild4 != null + ? `${item.orgChild4.orgChild4ShortName}${item.posMasterNo}` + : item?.orgChild3 != null + ? `${item.orgChild3.orgChild3ShortName}${item.posMasterNo}` + : item?.orgChild2 != null + ? `${item.orgChild2.orgChild2ShortName}${item.posMasterNo}` + : item?.orgChild1 != null + ? `${item.orgChild1.orgChild1ShortName}${item.posMasterNo}` + : item?.orgRoot != null + ? `${item.orgRoot.orgRootShortName}${item.posMasterNo}` + : null; + return { + id: item.id, + citizenId: item.current_holder?.citizenId ?? null, + prefix: item.current_holder?.prefix ?? null, + firstName: item.current_holder?.firstName ?? null, + lastName: item.current_holder?.lastName ?? null, + posLevel: item.current_holder?.posLevel?.posLevelName ?? null, + posType: item.current_holder?.posType?.posTypeName ?? null, + position: item.current_holder?.position ?? null, + posNo: shortName, + }; + }), + ); + return new HttpSuccess(data); + } } diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index c35f1969..db9003c0 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -748,6 +748,42 @@ export class ProfileController extends Controller { return new HttpSuccess(profile.id); } + /** + * API สร้างทะเบียนประวัติใหม่ + * + * @summary ORG_065 - สร้างทะเบียนประวัติใหม่ (ADMIN) #XXX + * + */ + @Post("allv2") + async createProfileAllV2( + @Request() request: RequestWithUser, + @Body() body: CreateProfileAllFields, + ) { + const profileExist = await this.profileRepo.findOneBy({ citizenId: body.citizenId }); + if (profileExist) { + return new HttpSuccess(profileExist.id); + } + + if (body.posLevelId === "") body.posLevelId = null; + if (body.posTypeId === "") body.posTypeId = null; + + if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); + } + + if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); + } + + const profile: Profile = Object.assign(new Profile(), body); + profile.createdUserId = request.user.sub; + profile.createdFullName = request.user.name; + profile.lastUpdateUserId = request.user.sub; + profile.lastUpdateFullName = request.user.name; + await this.profileRepo.save(profile); + return new HttpSuccess(profile.id); + } + /** * API ออกคำสั่ง คำสั่งให้ข้าราชการที่มีผลการทดลองปฏิบัติหน้าที่ราชการไม่ต่ำกว่ามาตรฐานที่กำหนดรับราชการต่อไป * @@ -784,10 +820,11 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: //profile.position, + //profile.position, + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -879,10 +916,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -961,8 +998,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย ปลดออกจากราชการ"; + profile.leaveReason = "ได้รับโทษทางวินัย ปลดออกจากราชการ"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -971,10 +1007,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1053,8 +1089,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย ไล่ออกจากราชการ"; + profile.leaveReason = "ได้รับโทษทางวินัย ไล่ออกจากราชการ"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1063,10 +1098,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1145,8 +1180,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย พักจากราชการ"; + profile.leaveReason = "ได้รับโทษทางวินัย พักจากราชการ"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1155,10 +1189,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1237,8 +1271,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย ให้ออกจากราชการไว้ก่อน"; + profile.leaveReason = "ได้รับโทษทางวินัย ให้ออกจากราชการไว้ก่อน"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1247,10 +1280,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1329,8 +1362,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย ลงโทษ ภาคทัณฑ์"; + profile.leaveReason = "ได้รับโทษทางวินัย ลงโทษ ภาคทัณฑ์"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1339,10 +1371,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1421,8 +1453,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย ลงโทษ ตัดเงินเดือน"; + profile.leaveReason = "ได้รับโทษทางวินัย ลงโทษ ตัดเงินเดือน"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1431,10 +1462,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1513,8 +1544,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย ลงโทษ ลดขั้นเงินเดือน"; + profile.leaveReason = "ได้รับโทษทางวินัย ลงโทษ ลดขั้นเงินเดือน"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1523,10 +1553,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1605,8 +1635,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย เพิ่มโทษ"; + profile.leaveReason = "ได้รับโทษทางวินัย เพิ่มโทษ"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1615,10 +1644,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1697,8 +1726,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย ยุติเรื่อง"; + profile.leaveReason = "ได้รับโทษทางวินัย ยุติเรื่อง"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1707,10 +1735,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -1789,8 +1817,7 @@ export class ProfileController extends Controller { } let dateLeave_: any = body.date; profile.isLeave = true; - profile.leaveReason = - "ได้รับโทษทางวินัย งดโทษ"; + profile.leaveReason = "ได้รับโทษทางวินัย งดโทษ"; profile.dateLeave = dateLeave_; profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; @@ -1799,10 +1826,10 @@ export class ProfileController extends Controller { date: body.date, refCommandNo: body.refCommandNo, templateDoc: body.salaryRef, - position: + position: profile.profileSalary.length > 0 - ? profile.profileSalary[profile.profileSalary.length - 1].position - : null, + ? profile.profileSalary[profile.profileSalary.length - 1].position + : null, positionType: profile.profileSalary.length > 0 ? profile.profileSalary[profile.profileSalary.length - 1].positionType @@ -4258,7 +4285,7 @@ export class ProfileController extends Controller { date: requestBody.dateLeave, amount: profileSalary?.amount ?? null, positionSalaryAmount: profileSalary?.positionSalaryAmount ?? null, - mouthSalaryAmount: profileSalary?.mouthSalaryAmount?? null, + mouthSalaryAmount: profileSalary?.mouthSalaryAmount ?? null, posNo: profileSalary?.posNo ?? null, position: profileSalary?.position ?? null, positionLine: profileSalary?.positionLine ?? null, diff --git a/src/entities/PosMaster.ts b/src/entities/PosMaster.ts index 856d56c1..d3895306 100644 --- a/src/entities/PosMaster.ts +++ b/src/entities/PosMaster.ts @@ -10,6 +10,7 @@ import { OrgChild3 } from "./OrgChild3"; import { OrgChild4 } from "./OrgChild4"; import { Profile } from "./Profile"; import { AuthRole } from "./AuthRole"; +import { PosMasterAct } from "./PosMasterAct"; enum PosMasterLine { MAIN = "MAIN", @@ -217,6 +218,12 @@ export class PosMaster extends EntityBase { @OneToMany(() => Position, (position) => position.posMaster) positions: Position[]; + + @OneToMany(() => PosMasterAct, (posMasterAct) => posMasterAct.posMaster) + posMasterActs: PosMasterAct[]; + + @OneToMany(() => PosMasterAct, (posMasterAct) => posMasterAct.posMasterChild) + posMasterActChilds: PosMasterAct[]; } export class CreatePosMaster { diff --git a/src/entities/PosMasterAct.ts b/src/entities/PosMasterAct.ts new file mode 100644 index 00000000..8745233f --- /dev/null +++ b/src/entities/PosMasterAct.ts @@ -0,0 +1,44 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToOne, OneToMany, ManyToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { PosMaster } from "./PosMaster"; + +@Entity("posMasterAct") +export class PosMasterAct extends EntityBase { + @Column({ + nullable: true, + comment: "ลำดับที่แสดงผล", + default: null, + }) + posMasterOrder: number; + + @Column({ + nullable: true, + default: null, + length: 40, + comment: "คีย์นอก(FK)ของตาราง posMaster", + }) + posMasterId: string; + + @ManyToOne(() => PosMaster, (posMaster) => posMaster.posMasterActs) + @JoinColumn({ name: "posMasterId" }) + posMaster: PosMaster; + + @Column({ + nullable: true, + default: null, + length: 40, + comment: "คีย์นอก(FK)ของตาราง posMasterChild", + }) + posMasterChildId: string; + + @ManyToOne(() => PosMaster, (posMaster) => posMaster.posMasterActChilds) + @JoinColumn({ name: "posMasterChildId" }) + posMasterChild: PosMaster; +} + +export class CreatePosMaster { + @Column() + posMasterNoPrefix: string; +} + +export type UpdatePosMaster = Partial; diff --git a/src/migration/1718807439080-update_table_kpi_add_summary1.ts b/src/migration/1718807439080-update_table_kpi_add_summary1.ts new file mode 100644 index 00000000..0f04d1a9 --- /dev/null +++ b/src/migration/1718807439080-update_table_kpi_add_summary1.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableKpiAddSummary11718807439080 implements MigrationInterface { + name = 'UpdateTableKpiAddSummary11718807439080' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`posMasterAct\` (\`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', \`posMasterOrder\` int NULL COMMENT 'ลำดับที่แสดงผล', \`posMasterId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง posMaster', \`posMasterChildId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง posMasterChild', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`posMasterAct\` ADD CONSTRAINT \`FK_ef186d66137edc512471eaef51b\` FOREIGN KEY (\`posMasterId\`) REFERENCES \`posMaster\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`posMasterAct\` ADD CONSTRAINT \`FK_0f07f317c0771dadcdac1f71a6d\` FOREIGN KEY (\`posMasterChildId\`) REFERENCES \`posMaster\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`posMasterAct\` DROP FOREIGN KEY \`FK_0f07f317c0771dadcdac1f71a6d\``); + await queryRunner.query(`ALTER TABLE \`posMasterAct\` DROP FOREIGN KEY \`FK_ef186d66137edc512471eaef51b\``); + await queryRunner.query(`DROP TABLE \`posMasterAct\``); + } + +}