From a678f950753cf60d1c095342bf7b798608e15d85 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 27 May 2026 14:58:00 +0700 Subject: [PATCH 01/14] revert #2533 --- src/controllers/CommandController.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 5dc501ba..eec261f2 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -7010,7 +7010,7 @@ export class CommandController extends Controller { profile.currentSubDistrictId = currentSubDistrictId ? currentSubDistrictId.id : _null; profile.currentZipCode = item.bodyProfile.currentZipCode; profile.email = item.bodyProfile.email; - profile.dateStart = item.bodySalarys?.commandDateAffect ?? item.bodyProfile.dateStart; + profile.dateStart = item.bodyProfile.dateStart; profile.amount = item.bodyProfile.amount ?? null; profile.amountSpecial = item.bodyProfile.amountSpecial ?? null; profile.isProbation = item.bodyProfile.isProbation; @@ -7080,7 +7080,7 @@ export class CommandController extends Controller { profile.currentSubDistrictId = currentSubDistrictId ? currentSubDistrictId.id : _null; profile.currentZipCode = item.bodyProfile.currentZipCode; profile.email = item.bodyProfile.email; - profile.dateStart = item.bodySalarys?.commandDateAffect ?? item.bodyProfile.dateStart; + profile.dateStart = item.bodyProfile.dateStart; profile.amount = item.bodyProfile.amount ?? null; profile.amountSpecial = item.bodyProfile.amountSpecial ?? null; profile.isProbation = item.bodyProfile.isProbation; @@ -7132,7 +7132,7 @@ export class CommandController extends Controller { profile.email = item.bodyProfile.email; profile.telephoneNumber = item.bodyProfile.telephoneNumber; profile.phone = item.bodyProfile.phone; - profile.dateStart = item.bodySalarys?.commandDateAffect ?? item.bodyProfile.dateStart; + profile.dateStart = item.bodyProfile.dateStart; profile.amount = item.bodyProfile.amount ?? null; profile.amountSpecial = item.bodyProfile.amountSpecial ?? null; profile.leaveCommandId = _null; From 7d463806a9bb84a2f49202af32e1404dceed34a5 Mon Sep 17 00:00:00 2001 From: harid Date: Wed, 27 May 2026 16:41:56 +0700 Subject: [PATCH 02/14] =?UTF-8?q?=E0=B8=9B=E0=B8=B1=E0=B9=8A=E0=B8=A1?= =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=A7=E0=B8=B1=E0=B8=95=E0=B8=B4?= =?UTF-8?q?=E0=B8=84=E0=B8=99=E0=B8=84=E0=B8=A3=E0=B8=AD=E0=B8=87=E0=B8=81?= =?UTF-8?q?=E0=B8=A3=E0=B8=93=E0=B8=B5=E0=B8=A1=E0=B8=B5=E0=B9=81=E0=B8=81?= =?UTF-8?q?=E0=B9=89=E0=B9=84=E0=B8=82=E0=B8=8A=E0=B8=B7=E0=B9=88=E0=B8=AD?= =?UTF-8?q?=E0=B9=81=E0=B8=A5=E0=B8=B0=E0=B8=99=E0=B8=B2=E0=B8=A1=E0=B8=AA?= =?UTF-8?q?=E0=B8=81=E0=B8=B8=E0=B8=A5=20=20#244?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProfileChangeNameController.ts | 4 ++ .../ProfileChangeNameEmployeeController.ts | 4 ++ src/services/PositionService.ts | 58 +++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/controllers/ProfileChangeNameController.ts b/src/controllers/ProfileChangeNameController.ts index 77cff634..fa88a252 100644 --- a/src/controllers/ProfileChangeNameController.ts +++ b/src/controllers/ProfileChangeNameController.ts @@ -25,6 +25,7 @@ import { } from "../entities/ProfileChangeName"; import { updateName } from "../keycloak"; import permission from "../interfaces/permission"; +import { updateHolderProfileHistory } from "../services/PositionService"; import { setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/org/profile/changeName") @Tags("ProfileChangeName") @@ -127,6 +128,9 @@ export class ProfileChangeNameController extends Controller { } } + // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) + await updateHolderProfileHistory(profile.id, req); + return new HttpSuccess(data.id); } diff --git a/src/controllers/ProfileChangeNameEmployeeController.ts b/src/controllers/ProfileChangeNameEmployeeController.ts index c2df9c8c..0a6f2ff0 100644 --- a/src/controllers/ProfileChangeNameEmployeeController.ts +++ b/src/controllers/ProfileChangeNameEmployeeController.ts @@ -24,6 +24,7 @@ import { } from "../entities/ProfileChangeName"; import { ProfileEmployee } from "../entities/ProfileEmployee"; import permission from "../interfaces/permission"; +import { updateHolderProfileHistory } from "../services/PositionService"; import { updateName } from "../keycloak"; import { setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/org/profile-employee/changeName") @@ -133,6 +134,9 @@ export class ProfileChangeNameEmployeeController extends Controller { } } + // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) + await updateHolderProfileHistory(profile.id, req, "EMPLOYEE"); + return new HttpSuccess(data.id); } diff --git a/src/services/PositionService.ts b/src/services/PositionService.ts index b6514eca..37c5f083 100644 --- a/src/services/PositionService.ts +++ b/src/services/PositionService.ts @@ -501,3 +501,61 @@ export async function BatchSavePosMasterHistoryOfficer( return false; } } + +/** + * อัพเดทประวัติคนครองตำแหน่งเมื่อมีการเปลี่ยนแปลงข้อมูล profile + * เช่น เปลี่ยนชื่อ - นามสกุล + * ใช้สำหรับบันทึกประวัติเมื่อ profile ที่ครองตำแหน่งมีการเปลี่ยนแปลง + * + * @param profileId ID ของ profile ที่ต้องการตรวจสอบ + * @param request RequestWithUser สำหรับบันทึกข้อมูลผู้ดำเนินการ + * @param type "OFFICER" สำหรับข้าราชการ | "EMPLOYEE" สำหรับลูกจ้างประจำ (default: "OFFICER") + */ +export async function updateHolderProfileHistory( + profileId: string, + request: RequestWithUser, + type: "OFFICER" | "EMPLOYEE" = "OFFICER", +): Promise { + try { + if (type === "OFFICER") { + const posMasterRepo = AppDataSource.getRepository(PosMaster); + const posMaster = await posMasterRepo.findOne({ + where: { + current_holderId: profileId, + orgRevision: { + orgRevisionIsCurrent: true, + orgRevisionIsDraft: false, + } + }, + relations: { + orgRevision : true + } + }); + + if (posMaster) { + await CreatePosMasterHistoryOfficer(posMaster.id, request); + } + } else if (type === "EMPLOYEE") { + const empPosMasterRepo = AppDataSource.getRepository(EmployeePosMaster); + const employeePosMaster = await empPosMasterRepo.findOne({ + where: { + current_holderId: profileId, + orgRevision: { + orgRevisionIsCurrent: true, + orgRevisionIsDraft: false, + } + }, + relations: { + orgRevision : true + } + }); + + if (employeePosMaster) { + await CreatePosMasterHistoryEmployee(employeePosMaster.id, request); + } + } + } catch (error) { + console.error("updateHolderProfileHistory error:", error); + throw error; + } +} From a36ec74e842c24aa6fa58fcd12a5722efa8f9943 Mon Sep 17 00:00:00 2001 From: harid Date: Wed, 27 May 2026 16:51:03 +0700 Subject: [PATCH 03/14] =?UTF-8?q?=E0=B8=A3=E0=B8=B2=E0=B8=A2=E0=B8=87?= =?UTF-8?q?=E0=B8=B2=E0=B8=99=E0=B9=81=E0=B8=99=E0=B8=9A=E0=B8=97=E0=B9=89?= =?UTF-8?q?=E0=B8=B2=E0=B8=A2=20=E0=B8=82=E0=B9=89=E0=B8=AD=E0=B8=A1?= =?UTF-8?q?=E0=B8=B9=E0=B8=A5=20"=E0=B8=A5=E0=B8=87=E0=B8=A7=E0=B8=B1?= =?UTF-8?q?=E0=B8=99=E0=B8=97=E0=B8=B5=E0=B9=88"=20=E0=B8=AB=E0=B8=B1?= =?UTF-8?q?=E0=B8=A7=E0=B8=81=E0=B8=A3=E0=B8=B0=E0=B8=94=E0=B8=B2=E0=B8=A9?= =?UTF-8?q?=20=E0=B9=83=E0=B8=AB=E0=B9=89=E0=B9=83=E0=B8=8A=E0=B9=89?= =?UTF-8?q?=E0=B8=82=E0=B9=89=E0=B8=AD=E0=B8=A1=E0=B8=B9=E0=B8=A5=20"?= =?UTF-8?q?=E0=B8=A7=E0=B8=B1=E0=B8=99=E0=B8=97=E0=B8=B5=E0=B9=88=E0=B8=A5?= =?UTF-8?q?=E0=B8=87=E0=B8=99=E0=B8=B2=E0=B8=A1"=20#2514?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/CommandController.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index eec261f2..c676ad51 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -2411,9 +2411,9 @@ export class CommandController extends Controller { ? "" : Extension.ToThaiNumber(Extension.ToThaiYear(command.commandYear).toString()), commandExcecuteDate: - command.commandExcecuteDate == null + command.commandAffectDate == null ? "" - : Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandExcecuteDate)), + : Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandAffectDate)), operators: operators.length > 0 ? operators.map((x) => ({ From 9782871c9c26b30c4071302bc7d1b22fe159066b Mon Sep 17 00:00:00 2001 From: harid Date: Wed, 27 May 2026 17:46:44 +0700 Subject: [PATCH 04/14] =?UTF-8?q?=E0=B8=AA=E0=B9=88=E0=B8=87=E0=B8=A3?= =?UTF-8?q?=E0=B8=B2=E0=B8=A2=E0=B8=8A=E0=B8=B7=E0=B9=88=E0=B8=AD=E0=B8=AD?= =?UTF-8?q?=E0=B8=81=E0=B8=84=E0=B8=B3=E0=B8=AA=E0=B8=B1=E0=B9=88=E0=B8=87?= =?UTF-8?q?=E0=B8=A7=E0=B8=B4=E0=B8=99=E0=B8=B1=E0=B8=A2=20=E0=B9=80?= =?UTF-8?q?=E0=B8=9E=E0=B8=B4=E0=B9=88=E0=B8=A1=20CommandCode,=20CommandId?= =?UTF-8?q?=20#2377?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/CommandController.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index c676ad51..f114a24c 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -2618,6 +2618,7 @@ export class CommandController extends Controller { const now = new Date(); let command = new Command(); let commandCode: string = ""; + let commandSysId: string = ""; let _null: any = null; let userProfile: any = null; if ( @@ -2637,6 +2638,7 @@ export class CommandController extends Controller { if (!_command) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบคำสั่งนี้ในระบบ"); } + commandSysId = _command.commandType.commandSysId; commandCode = _command.commandType.code; command = _command; } else { @@ -2651,6 +2653,7 @@ export class CommandController extends Controller { if (!commandType) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ"); } + commandSysId = commandType.commandSysId; commandCode = commandType.code; command.detailHeader = commandType.detailHeader; command.detailBody = commandType.detailBody; @@ -2795,7 +2798,7 @@ export class CommandController extends Controller { const path = commandTypePath(commandCode); if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ"); - if (!["C-PM-26", "C-PM-25"].includes(commandCode)) { + if (commandSysId && commandSysId.toLocaleUpperCase().trim() !== "DISCIPLINE") { await new CallAPI() .PostData(request, path, { refIds: requestBody.persons.filter((x) => x.refId != null).map((x) => x.refId), From 399bf87ba6cf814af317868afab27336ae36b1e7 Mon Sep 17 00:00:00 2001 From: Adisak Date: Thu, 28 May 2026 09:08:58 +0700 Subject: [PATCH 05/14] =?UTF-8?q?#246=20=E0=B9=80=E0=B8=84=E0=B8=A5?= =?UTF-8?q?=E0=B8=B5=E0=B8=99=E0=B8=A3=E0=B9=8C=20isSit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interfaces/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index be2f3bf9..c75bf147 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -280,7 +280,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) { await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) - .set({ current_holderId: null }) + .set({ current_holderId: null, isSit: false }) .where("id = :id", { id: findProfileInposMaster?.id }) .execute(); @@ -293,7 +293,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) { await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) - .set({ next_holderId: null }) + .set({ next_holderId: null, isSit: false }) .where("id = :id", { id: findProfileInposMasterDraft?.id }) .execute(); From ccfb2754fd70c47ba86f3517cbac82d02e177f62 Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Thu, 28 May 2026 09:49:21 +0700 Subject: [PATCH 06/14] API apiKey list return accessType and orgName --- src/controllers/ApiKeyController.ts | 149 +++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 2 deletions(-) diff --git a/src/controllers/ApiKeyController.ts b/src/controllers/ApiKeyController.ts index 4c9664d7..7de6e415 100644 --- a/src/controllers/ApiKeyController.ts +++ b/src/controllers/ApiKeyController.ts @@ -20,6 +20,12 @@ import { In } from "typeorm"; import { RequestWithUser } from "../middlewares/user"; import { ApiName } from "../entities/ApiName"; import { ApiHistory } from "../entities/ApiHistory"; +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 { OrgRevision } from "../entities/OrgRevision"; const jwt = require("jsonwebtoken"); @Route("api/v1/org/apiKey") @@ -33,6 +39,12 @@ export class ApiKeyController extends Controller { private apiKeyRepository = AppDataSource.getRepository(ApiKey); private apiNameRepository = AppDataSource.getRepository(ApiName); private apiHistoryRepository = AppDataSource.getRepository(ApiHistory); + private orgRootRepository = AppDataSource.getRepository(OrgRoot); + private orgChild1Repository = AppDataSource.getRepository(OrgChild1); + private orgChild2Repository = AppDataSource.getRepository(OrgChild2); + private orgChild3Repository = AppDataSource.getRepository(OrgChild3); + private orgChild4Repository = AppDataSource.getRepository(OrgChild4); + private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); /** * API ตรวจสอบและถอดรหัส JWT token @@ -151,6 +163,9 @@ export class ApiKeyController extends Controller { relations: ["apiNames", "apiHistorys"], order: { createdAt: "DESC", apiNames: { createdAt: "DESC" } }, }); + + const orgNames = await this.buildOrgNameBatch(apiKey); + const data = apiKey.map((_data) => ({ id: _data.id, createdAt: _data.createdAt, @@ -163,6 +178,7 @@ export class ApiKeyController extends Controller { dnaChild2Id: _data.dnaChild2Id, dnaChild3Id: _data.dnaChild3Id, dnaChild4Id: _data.dnaChild4Id, + orgName: orgNames.get(_data.id), apiNames: _data.apiNames.map((x) => ({ id: x.id, name: x.name, @@ -174,10 +190,139 @@ export class ApiKeyController extends Controller { return new HttpSuccess(data); } + private async buildOrgNameBatch(apiKeys: ApiKey[]): Promise> { + const currentRevision = await this.orgRevisionRepository.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + }); + + if (!currentRevision) { + return new Map(apiKeys.map((k) => [k.id, null])); + } + + const currentRevisionId = currentRevision.id; + + const rootIds = [...new Set(apiKeys.map((k) => k.dnaRootId).filter(Boolean))]; + const child1Ids = [...new Set(apiKeys.map((k) => k.dnaChild1Id).filter(Boolean))]; + const child2Ids = [...new Set(apiKeys.map((k) => k.dnaChild2Id).filter(Boolean))]; + const child3Ids = [...new Set(apiKeys.map((k) => k.dnaChild3Id).filter(Boolean))]; + const child4Ids = [...new Set(apiKeys.map((k) => k.dnaChild4Id).filter(Boolean))]; + + const [roots, child1s, child2s, child3s, child4s] = await Promise.all([ + rootIds.length > 0 + ? this.orgRootRepository.find({ + where: [ + { id: In(rootIds), orgRevisionId: currentRevisionId }, + { ancestorDNA: In(rootIds), orgRevisionId: currentRevisionId }, + ], + select: ["id", "ancestorDNA", "orgRootName"], + }) + : [], + child1Ids.length > 0 + ? this.orgChild1Repository.find({ + where: [ + { id: In(child1Ids), orgRevisionId: currentRevisionId }, + { ancestorDNA: In(child1Ids), orgRevisionId: currentRevisionId }, + ], + select: ["id", "ancestorDNA", "orgChild1Name"], + }) + : [], + child2Ids.length > 0 + ? this.orgChild2Repository.find({ + where: [ + { id: In(child2Ids), orgRevisionId: currentRevisionId }, + { ancestorDNA: In(child2Ids), orgRevisionId: currentRevisionId }, + ], + select: ["id", "ancestorDNA", "orgChild2Name"], + }) + : [], + child3Ids.length > 0 + ? this.orgChild3Repository.find({ + where: [ + { id: In(child3Ids), orgRevisionId: currentRevisionId }, + { ancestorDNA: In(child3Ids), orgRevisionId: currentRevisionId }, + ], + select: ["id", "ancestorDNA", "orgChild3Name"], + }) + : [], + child4Ids.length > 0 + ? this.orgChild4Repository.find({ + where: [ + { id: In(child4Ids), orgRevisionId: currentRevisionId }, + { ancestorDNA: In(child4Ids), orgRevisionId: currentRevisionId }, + ], + select: ["id", "ancestorDNA", "orgChild4Name"], + }) + : [], + ]); + + const rootMap = new Map( + roots.map((r) => [r.id, { name: r.orgRootName, ancestorDNA: r.ancestorDNA }]), + ); + const child1Map = new Map( + child1s.map((c) => [c.id, { name: c.orgChild1Name, ancestorDNA: c.ancestorDNA }]), + ); + const child2Map = new Map( + child2s.map((c) => [c.id, { name: c.orgChild2Name, ancestorDNA: c.ancestorDNA }]), + ); + const child3Map = new Map( + child3s.map((c) => [c.id, { name: c.orgChild3Name, ancestorDNA: c.ancestorDNA }]), + ); + const child4Map = new Map( + child4s.map((c) => [c.id, { name: c.orgChild4Name, ancestorDNA: c.ancestorDNA }]), + ); + + const result = new Map(); + for (const apiKey of apiKeys) { + if (apiKey.accessType === "ALL") { + result.set(apiKey.id, null); + continue; + } + + const parts: string[] = []; + + const getOrgName = ( + dnaId: string, + orgMap: Map, + ): string | null => { + const byId = orgMap.get(dnaId); + if (byId) return byId.name; + for (const [, value] of orgMap) { + if (value.ancestorDNA === dnaId) return value.name; + } + return null; + }; + + if (apiKey.dnaChild4Id) { + const name = getOrgName(apiKey.dnaChild4Id, child4Map); + if (name) parts.push(name); + } + if (apiKey.dnaChild3Id) { + const name = getOrgName(apiKey.dnaChild3Id, child3Map); + if (name) parts.push(name); + } + if (apiKey.dnaChild2Id) { + const name = getOrgName(apiKey.dnaChild2Id, child2Map); + if (name) parts.push(name); + } + if (apiKey.dnaChild1Id) { + const name = getOrgName(apiKey.dnaChild1Id, child1Map); + if (name) parts.push(name); + } + if (apiKey.dnaRootId) { + const name = getOrgName(apiKey.dnaRootId, rootMap); + if (name) parts.push(name); + } + + result.set(apiKey.id, parts.length > 0 ? parts.join(" ") : null); + } + + return result; + } + /** - * API รายการ Api Key + * API รายการ Api Name * - * @summary รายการ Api Key (ADMIN) + * @summary รายการ Api Name (ADMIN) * */ @Get("name") From 521a748de1df7974c177fa4192e91c9898cee51b Mon Sep 17 00:00:00 2001 From: harid Date: Thu, 28 May 2026 13:02:58 +0700 Subject: [PATCH 07/14] =?UTF-8?q?fix=20=E0=B9=81=E0=B8=81=E0=B9=89?= =?UTF-8?q?=E0=B9=84=E0=B8=82=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=A7=E0=B8=B1?= =?UTF-8?q?=E0=B8=95=E0=B8=B4=E0=B8=AA=E0=B9=88=E0=B8=A7=E0=B8=99=E0=B8=95?= =?UTF-8?q?=E0=B8=B1=E0=B8=A7=20=E0=B9=84=E0=B8=A1=E0=B9=88=E0=B8=9B?= =?UTF-8?q?=E0=B8=B1=E0=B9=8A=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=A7?= =?UTF-8?q?=E0=B8=B1=E0=B8=95=E0=B8=B4=E0=B8=A3=E0=B8=B2=E0=B8=A2=E0=B8=81?= =?UTF-8?q?=E0=B8=B2=E0=B8=A3=E0=B8=84=E0=B8=99=E0=B8=84=E0=B8=A3=E0=B8=AD?= =?UTF-8?q?=E0=B8=87=20#244?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/ProfileController.ts | 25 ++++---------------- src/controllers/ProfileEmployeeController.ts | 24 ++++--------------- 2 files changed, 9 insertions(+), 40 deletions(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 92943776..434e7b77 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -93,6 +93,7 @@ import { CreatePosMasterHistoryOfficer, getTopDegrees, getPosMasterPositions } f import { ProfileLeaveService } from "../services/ProfileLeaveService"; // import { PostRetireToExprofile } from "./ExRetirementController"; import { getPosNumCodeSit } from "../services/CommandService"; +import { updateHolderProfileHistory } from "../services/PositionService"; @Route("api/v1/org/profile") @Tags("Profile") @Security("bearerAuth") @@ -5774,26 +5775,7 @@ export class ProfileController extends Controller { } if (body.citizenId) { - const citizenIdDigits = body.citizenId.toString().split("").map(Number); - const cal = - citizenIdDigits[0] * 13 + - citizenIdDigits[1] * 12 + - citizenIdDigits[2] * 11 + - citizenIdDigits[3] * 10 + - citizenIdDigits[4] * 9 + - citizenIdDigits[5] * 8 + - citizenIdDigits[6] * 7 + - citizenIdDigits[7] * 6 + - citizenIdDigits[8] * 5 + - citizenIdDigits[9] * 4 + - citizenIdDigits[10] * 3 + - citizenIdDigits[11] * 2; - const calStp2 = cal % 11; - const chkDigit = (11 - calStp2) % 10; - - if (citizenIdDigits[12] !== chkDigit) { - throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); - } + Extension.CheckCitizen(body.citizenId); } const record = await this.profileRepo.findOneBy({ id }); const before = structuredClone(record); @@ -5833,6 +5815,9 @@ export class ProfileController extends Controller { } } + // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) + await updateHolderProfileHistory(record.id, request); + return new HttpSuccess(); } diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index f79e27cd..cdf1a4e4 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -84,6 +84,7 @@ import { ProfileDuty } from "../entities/ProfileDuty"; import { CreatePosMasterHistoryEmployee, getTopDegrees } from "../services/PositionService"; import { ProfileLeaveService } from "../services/ProfileLeaveService"; import { CommandCode } from "../entities/CommandCode"; +import { updateHolderProfileHistory } from "../services/PositionService"; @Route("api/v1/org/profile-employee") @Tags("ProfileEmployee") @Security("bearerAuth") @@ -2381,26 +2382,7 @@ export class ProfileEmployeeController extends Controller { } if (body.citizenId) { - const citizenIdDigits = body.citizenId.toString().split("").map(Number); - const cal = - citizenIdDigits[0] * 13 + - citizenIdDigits[1] * 12 + - citizenIdDigits[2] * 11 + - citizenIdDigits[3] * 10 + - citizenIdDigits[4] * 9 + - citizenIdDigits[5] * 8 + - citizenIdDigits[6] * 7 + - citizenIdDigits[7] * 6 + - citizenIdDigits[8] * 5 + - citizenIdDigits[9] * 4 + - citizenIdDigits[10] * 3 + - citizenIdDigits[11] * 2; - const calStp2 = cal % 11; - const chkDigit = (11 - calStp2) % 10; - - if (citizenIdDigits[12] !== chkDigit) { - throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); - } + Extension.CheckCitizen(body.citizenId); } const record = await this.profileRepo.findOneBy({ id }); if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); @@ -2434,6 +2416,8 @@ export class ProfileEmployeeController extends Controller { }), ); await this.profileRepo.save(record); + // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) + await updateHolderProfileHistory(record.id, request, "EMPLOYEE"); return new HttpSuccess(); } From d495137aaf95dcce36b66c13c4631c5f3afa14ab Mon Sep 17 00:00:00 2001 From: harid Date: Thu, 28 May 2026 17:11:06 +0700 Subject: [PATCH 08/14] =?UTF-8?q?devTest=20Controller=20=E0=B8=AA=E0=B8=B3?= =?UTF-8?q?=E0=B8=AB=E0=B8=A3=E0=B8=B1=E0=B8=9A=E0=B8=97=E0=B8=94=E0=B8=AA?= =?UTF-8?q?=E0=B8=AD=E0=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/DevTestController.ts | 576 +++++++++++++++++++++++++++ 1 file changed, 576 insertions(+) create mode 100644 src/controllers/DevTestController.ts diff --git a/src/controllers/DevTestController.ts b/src/controllers/DevTestController.ts new file mode 100644 index 00000000..e3edfaa5 --- /dev/null +++ b/src/controllers/DevTestController.ts @@ -0,0 +1,576 @@ +import { + Controller, + Post, + Put, + Patch, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + Response, + Get, + Query, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import HttpStatus from "../interfaces/http-status"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatusCode from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { Command } from "../entities/Command"; +import { Brackets, LessThan, MoreThan, Double, In, Between, IsNull, Not, Any } from "typeorm"; +import { CommandType } from "../entities/CommandType"; +import { Profile, CreateProfileAllFields } from "../entities/Profile"; +import { RequestWithUser, RequestWithUserWebService } from "../middlewares/user"; +import { OrgRevision } from "../entities/OrgRevision"; +import { ProfileEmployee } from "../entities/ProfileEmployee"; +import { PosMaster } from "../entities/PosMaster"; +import permission from "../interfaces/permission"; +import { viewCurrentTenureOfficer } from "../entities/view/viewCurrentTenureOfficer"; +import { CommandController } from "./CommandController"; +import Extension from "../interfaces/extension"; +import { viewRegistryOfficer } from "../entities/view/viewRegistryOfficer"; +import { viewRegistryEmployee } from "../entities/view/viewRegistryEmployee"; +import { Registry } from "../entities/Registry"; +import { RegistryEmployee } from "../entities/RegistryEmployee"; +import { TenurePositionOfficer } from "../entities/TenurePositionOfficer"; +import { PosMasterAssign, PosMasterAssignDTO } from "../entities/PosMasterAssign"; +import { PermissionProfile } from "../entities/PermissionProfile"; +import { OrgRoot } from "../entities/OrgRoot"; +import { MetaWorkflow } from "../entities/MetaWorkflow"; +import { MetaState } from "../entities/MetaState"; +import { MetaStateOperator } from "../entities/MetaStateOperator"; +import { Workflow } from "../entities/Workflow"; +import { State } from "../entities/State"; +import { StateOperator } from "../entities/StateOperator"; +import { StateOperatorUser } from "../entities/StateOperatorUser"; +import { + commandTypePath, + calculateGovAge, + calculateAge, + calculateRetireDate, + calculateRetireLaw, + removeProfileInOrganize, + setLogDataDiff, +} from "../interfaces/utils"; +import CallAPI from "../interfaces/call-api"; +import { PostRetireToExprofile } from "./ExRetirementController" +import { Position } from "../entities/Position"; +import { PosLevel } from "../entities/PosLevel"; +import { TenureLevelOfficer } from "../entities/TenureLevelOfficer"; +import { TenurePositionEmployee } from "../entities/TenurePositionEmployee"; +import { TenureLevelEmployee } from "../entities/TenureLevelEmployee"; +import { TenurePositionExecutiveOfficer } from "../entities/TenurePositionExecutiveOfficer"; + +@Route("api/v1/org/DevTest") +@Tags("DevTest") +@Security("bearerAuth") +@Response( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) +export class DevTestController extends Controller { + private commandRepository = AppDataSource.getRepository(Command); + private commandTypeRepository = AppDataSource.getRepository(CommandType); + private orgRevisionRepo = AppDataSource.getRepository(OrgRevision); + private orgRootRepo = AppDataSource.getRepository(OrgRoot); + private posMasterRepo = AppDataSource.getRepository(PosMaster); + private profileRepo = AppDataSource.getRepository(Profile); + private profileEmpRepo = AppDataSource.getRepository(ProfileEmployee); + private registryRepo = AppDataSource.getRepository(Registry); + private registryEmployeeRepo = AppDataSource.getRepository(RegistryEmployee); + private posMasterAssignRepository = AppDataSource.getRepository(PosMasterAssign); + private permissionProfilesRepository = AppDataSource.getRepository(PermissionProfile); + private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); + private metaWorkflowRepo = AppDataSource.getRepository(MetaWorkflow); + private metaStateRepo = AppDataSource.getRepository(MetaState); + private metaStateOperatorRepo = AppDataSource.getRepository(MetaStateOperator); + private workflowRepo = AppDataSource.getRepository(Workflow); + private stateRepo = AppDataSource.getRepository(State); + private stateOperatorRepo = AppDataSource.getRepository(StateOperator); + private stateOperatorUserRepo = AppDataSource.getRepository(StateOperatorUser); + private positionRepository = AppDataSource.getRepository(Position); + private positionOfficerRepo = AppDataSource.getRepository(TenurePositionOfficer); + private positionEmployeeRepo = AppDataSource.getRepository(TenurePositionEmployee); + private levelOfficerRepo = AppDataSource.getRepository(TenureLevelOfficer); + private levelEmployeeRepo = AppDataSource.getRepository(TenureLevelEmployee); + private positionExecutiveOfficerRepo = AppDataSource.getRepository( + TenurePositionExecutiveOfficer, + ); + + @Patch("tick-officer-registry") + public async calculateOfficerPosition( + @Request() req: RequestWithUser, + @Body() + body: { + profileIds: string[]; + }, + ) { + + console.log("1.") + /** + * =============================== + * PREPARE DATA + * =============================== + */ + const profile = await this.profileRepo.find({ + where: { id: In(body.profileIds) }, + relations: { + posLevel: true, + posType: true, + }, + }); + + if (!profile.length) return; + + const [{ today }] = await AppDataSource.query( + "SELECT CURRENT_DATE() as today", + ); + + const orgRevision = await this.orgRevisionRepo.findOne({ + select: ["id"], + where: { + orgRevisionIsDraft: false, + orgRevisionIsCurrent: true, + }, + }); + + /** + * =============================== + * TRANSACTION + * =============================== + */ + const queryRunner = AppDataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + console.log("2.") + try { + /** + * =============================== + * RESULT BUFFERS (SAVE ARRAY) + * =============================== + */ + const positionOfficerBulk: any[] = []; + const levelOfficerBulk: any[] = []; + const executiveOfficerBulk: any[] = []; + console.log("3.") + /** + * =============================== + * MAIN LOOP (SINGLE LOOP) + * =============================== + */ + for (const x of profile) { + const currentDate = + x.isLeave && x.leaveDate + ? Extension.toDateOnlyString(x.leaveDate) + : today; + /** + * ==================================== + * PARALLEL STORED PROCEDURES + * ==================================== + */ + const [ + positionResult, + levelResult, + executiveResult, + ] = await Promise.all([ + AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [ + x.id, + currentDate, + ]), + AppDataSource.query("CALL GetProfileSalaryLevel(?, ?)", [ + x.id, + currentDate, + ]), + AppDataSource.query("CALL GetProfileSalaryExecutive(?, ?)", [ + x.id, + currentDate, + ]), + ]); + console.log("4.",x.id) + /** + * ==================================== + * POSITION + * ==================================== + */ + const posRows = positionResult?.[0] ?? []; + const posMap = + posRows.length > 1 + ? posRows.slice(1).map((r: any, i: number) => ({ + days_diff: Number(r.days_diff) || 0, + positionName: posRows[i]?.positionName, + })) + : []; + + const posCal = posMap + .filter((p:any) => p.positionName === x.position) + .reduce( + (a:any, c:any) => ({ + days_diff: a.days_diff + c.days_diff, + positionName: c.positionName, + }), + { days_diff: 0, positionName: null }, + ); + + positionOfficerBulk.push({ + profileId: x.id, + positionName: posCal.positionName, + days_diff: posCal.days_diff, + Years: Math.floor(posCal.days_diff / 365.2524), + Months: Math.floor((posCal.days_diff / 30.4375) % 12), + Days: Math.floor(posCal.days_diff % 30.4375), + }); + console.log("5.",x.id) + /** + * ==================================== + * 2️⃣ POSITION LEVEL + * ==================================== + */ + const lvlRows = levelResult?.[0] ?? []; + const lvlMap = + lvlRows.length > 1 + ? lvlRows.slice(1).map((r: any, i: number) => ({ + days_diff: Number(r.days_diff) || 0, + positionType: lvlRows[i]?.positionType, + positionLevel: lvlRows[i]?.positionLevel, + positionCee: lvlRows[i]?.positionCee, + })) + : []; + + const lvlCal = lvlMap + .filter( + (l:any) => + l.positionLevel === x.posLevel?.posLevelName && + l.positionType === x.posType?.posTypeName, + ) + .reduce( + (a:any, c:any) => ({ + days_diff: a.days_diff + c.days_diff, + positionType: c.positionType, + positionLevel: c.positionLevel, + positionCee: c.positionCee, + }), + { + days_diff: 0, + positionType: null, + positionLevel: null, + positionCee: null, + }, + ); + + levelOfficerBulk.push({ + profileId: x.id, + positionType: lvlCal.positionType, + positionLevel: lvlCal.positionLevel, + positionCee: lvlCal.positionCee, + days_diff: lvlCal.days_diff, + Years: x.posLevel ? (lvlCal.days_diff / 365.2524).toFixed(4) : 0, + Months: x.posLevel ? ((lvlCal.days_diff / 30.4375) % 12).toFixed(4) : 0, + Days: x.posLevel ? (lvlCal.days_diff % 30.4375).toFixed(4) : 0, + }); + console.log("6.",x.id) + /** + * ==================================== + * 3️⃣ POSITION EXECUTIVE + * ==================================== + */ + const exeRows = executiveResult?.[0] ?? []; + const exeMap = + exeRows.length > 1 + ? exeRows.slice(1).map((r: any, i: number) => ({ + days_diff: Number(r.days_diff) || 0, + positionExecutive: exeRows[i]?.positionExecutive, + })) + : []; + + const position = await this.positionRepository.findOne({ + where: { + positionIsSelected: true, + posMaster: { + orgRevisionId: orgRevision?.id, + current_holderId: x.id, + }, + }, + order: { createdAt: "DESC" }, + relations: { + posExecutive: true, + }, + }); + + const exeName = position?.posExecutive?.posExecutiveName; + + const exeCal = exeMap + .filter((e:any) => exeName && e.positionExecutive === exeName) + .reduce( + (a:any, c:any) => ({ + days_diff: a.days_diff + c.days_diff, + positionExecutive: c.positionExecutive, + }), + { days_diff: 0, positionExecutive: null }, + ); + + executiveOfficerBulk.push({ + profileId: x.id, + positionExecutiveName: exeCal.positionExecutive, + days_diff: exeCal.days_diff, + Years: (exeCal.days_diff / 365.2524).toFixed(4), + Months: ((exeCal.days_diff / 30.4375) % 12).toFixed(4), + Days: (exeCal.days_diff % 30.4375).toFixed(4), + }); + } + console.log("7.") + /** + * =============================== + * CLEAR ALL DATA AND SAVE ARRAY (BULK) + * =============================== + */ + await queryRunner.manager + .createQueryBuilder() + .delete() + .from(this.positionOfficerRepo.target) + .execute(); + + await queryRunner.manager + .createQueryBuilder() + .delete() + .from(this.levelOfficerRepo.target) + .execute(); + + await queryRunner.manager + .createQueryBuilder() + .delete() + .from(this.positionExecutiveOfficerRepo.target) + .execute(); + console.log("8.") + await queryRunner.manager.save(this.positionOfficerRepo.target, positionOfficerBulk); + await queryRunner.manager.save(this.levelOfficerRepo.target, levelOfficerBulk); + await queryRunner.manager.save(this.positionExecutiveOfficerRepo.target,executiveOfficerBulk); + console.log("9.") + /** + * =============================== + * REGISTRY OFFICER (SYNC VIEW) + * =============================== + */ + const allRegis = await queryRunner.manager + .getRepository(viewRegistryOfficer) + .createQueryBuilder("registryOfficer") + .where("registryOfficer.profileId IN (:...profileIds)", { + profileIds: new Set(profile.map((p) => p.id)) + }) + .getMany(); + + const mapRegistryData = allRegis.map((x) => ({ + ...x, + isProbation: Boolean(x.isProbation), + isLeave: Boolean(x.isLeave), + isRetirement: Boolean(x.isRetirement), + Educations: x.Educations ? JSON.stringify(x.Educations) : "", + })); + console.log("10.") + + await queryRunner.manager + .createQueryBuilder() + .delete() + .from(this.registryRepo.target) + .execute(); + + if (mapRegistryData.length > 0) { + await queryRunner.manager.save(this.registryRepo.target, mapRegistryData); + } + console.log("11.") + /** + * =============================== + * COMMIT + * =============================== + */ + await queryRunner.commitTransaction(); + } catch (error) { + await queryRunner.rollbackTransaction(); + throw error; + } finally { + await queryRunner.release(); + } + } + + @Post("getDNA") + public async GetData( + @Request() req: RequestWithUser + ){ + let _data: any = { + root: null, + child1: null, + child2: null, + child3: null, + child4: null, + }; + + _data = await new permission().PermissionOrgList(req, "COMMAND"); + return new HttpSuccess(_data); + } + + @Post("calculateGovAge") + public async calculateGovAge( + @Request() req: RequestWithUser, + @Body() + body: { + profileId: string; + }, + ){ + return new HttpSuccess(await calculateGovAge(body.profileId, "OFFICER")); + } + + /** + * @summary Test Job กวาดออกคำสั่ง ทำงานทุกๆตี2 + */ + @Post("cronjobCommand") + async CronjobCommand() { + const commandController = new CommandController(); + await commandController.cronjobCommand(); + } + + /** + * @summary payload & Endpoint ออกคำสั่ง + */ + @Put("path-excec/{id}") + async Bright( + @Path() id: string, + @Request() request: RequestWithUser, + ) { + const command = await this.commandRepository.findOne({ + where: { id: id }, + relations: ["commandType", "commandRecives", "commandSends", "commandSends.commandSendCCs"], + }); + if (!command) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้"); + } + const path = commandTypePath(command.commandType.code); + return new HttpSuccess({ + path: path + "/excecute", + refIds: command.commandRecives + .filter((x) => x.refId != null) + .map((x) => ({ + refId: x.refId, + commandNo: command.commandNo, + commandYear: command.commandYear, + commandId: command.id, + remark: command.positionDetail, + amount: x.amount, + amountSpecial: x.amountSpecial, + positionSalaryAmount: x.positionSalaryAmount, + mouthSalaryAmount: x.mouthSalaryAmount, + commandCode: command.commandType.commandCode, + commandName: command.commandType.name, + commandDateAffect: command.commandExcecuteDate, + commandDateSign: command.commandAffectDate, + })), + }); + } + + /** + * API รายละเอียดรายการคำสั่ง tab4 แนบท้าย + * @summary API รายละเอียดรายการคำสั่ง tab4 แนบท้าย + * @param {string} id Id คำสั่ง + * @param {string} profileId profileId + */ + @Get("tab4/attachment/{id}/{profileId}") + async GetByIdTab4Attachment( + @Path() id: string, + @Path() profileId: string, + @Request() request: RequestWithUser + ) { + await new permission().PermissionGet(request, "COMMAND"); + + let profile: Profile | ProfileEmployee | null = null; + profile = await this.profileRepo.findOne({ where: { id: profileId } }); + if (!profile) { + profile = await this.profileEmpRepo.findOne({ where: { id: profileId } }); + if (!profile) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลากรนี้"); + } + + const command = await this.commandRepository.findOne({ + where: { id }, + relations: ["commandType", "commandRecives"], + }); + if (!command) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้"); + } + + let _command: any = []; + const path = commandTypePath(command.commandType.code); + if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ"); + await new CallAPI() + .PostData(request, path + "/attachment", { + refIds: command.commandRecives + .filter((x) => + x.refId != null && + x.profileId != null && x.profileId == profileId + ) + .map((x) => ({ + refId: x.refId, + Sequence: x.order, + CitizenId: x.citizenId, + Prefix: x.prefix, + FirstName: x.firstName, + LastName: x.lastName, + Amount: x.amount, + PositionSalaryAmount: x.positionSalaryAmount, + MouthSalaryAmount: x.mouthSalaryAmount, + RemarkHorizontal: x.remarkHorizontal, + RemarkVertical: x.remarkVertical, + CommandYear: command.commandYear, + CommandExcecuteDate: command.commandExcecuteDate, + })), + }) + .then(async (res) => { + _command = res; + }) + .catch(() => {}); + + let issue = + command.isBangkok == "OFFICE" + ? "สำนักปลัดกรุงเทพมหานคร" + : command.isBangkok == "BANGKOK" + ? "กรุงเทพมหานคร" + : null; + if (issue == null) { + const orgRevisionActive = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + relations: ["posMasters", "posMasters.orgRoot"], + }); + if (orgRevisionActive != null) { + const profile = await this.profileRepo.findOne({ + where: { + keycloak: command.createdUserId.toString(), + }, + }); + if (profile != null) { + issue = + orgRevisionActive?.posMasters?.filter((x) => x.current_holderId == profile.id)[0] + ?.orgRoot?.orgRootName || null; + } + } + } + if (issue == null) issue = "..................................."; + return new HttpSuccess({ + template: command.commandType.fileAttachment, + reportName: "xlsx-report", + data: { + data: _command, + issuerOrganizationName: issue, + commandNo: command.commandNo == null ? "" : Extension.ToThaiNumber(command.commandNo), + commandYear: + command.commandYear == null + ? "" + : Extension.ToThaiNumber(Extension.ToThaiYear(command.commandYear).toString()), + commandExcecuteDate: + command.commandExcecuteDate == null + ? "" + : Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandExcecuteDate)), + }, + }); + } + +} From 755ae992ddc29e8d2abb6b2af1c4fe6de97a7efd Mon Sep 17 00:00:00 2001 From: Adisak Date: Fri, 29 May 2026 10:12:46 +0700 Subject: [PATCH 09/14] =?UTF-8?q?#246=20=E0=B9=80=E0=B8=AA=E0=B8=A3?= =?UTF-8?q?=E0=B8=B4=E0=B8=A1=E0=B8=84=E0=B8=B3=E0=B8=AA=E0=B8=B1=E0=B9=88?= =?UTF-8?q?=E0=B8=87=20C-PM-25,C-PM-26?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/CommandController.ts | 89 +++++++++------------------- src/interfaces/utils.ts | 51 ++++------------ 2 files changed, 42 insertions(+), 98 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index f114a24c..d732a622 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -41,7 +41,6 @@ import { removeProfileInOrganize, setLogDataDiff, checkReturnCommandType, - checkExceptCommandType, checkCommandType, removePostMasterAct, logPositionIsSelectedChange, @@ -5629,20 +5628,10 @@ export class CommandController extends Controller { _profile.lastUpdateFullName = req.user.name; _profile.lastUpdatedAt = new Date(); if (item.isLeave == true) { - const exceptClear = await checkExceptCommandType(String(item.commandId)); - if (exceptClear.status) { - _profile.leaveReason = item.leaveReason ?? _null; - _profile.leaveCommandId = item.commandId ?? _null; - _profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; - _profile.leaveRemark = exceptClear.leaveRemark ?? _null; - _profile.leaveDate = item.commandDateAffect ?? _null; - _profile.leaveType = exceptClear.LeaveType ?? _null; - } else { - if (orgRevisionRef) { - await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); - } - await removeProfileInOrganize(_profile.id, "OFFICER"); + if (orgRevisionRef) { + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); } + await removeProfileInOrganize(_profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); if (clearProfile.status) { @@ -5821,32 +5810,22 @@ export class CommandController extends Controller { _profile.lastUpdateFullName = req.user.name; _profile.lastUpdatedAt = new Date(); if (item.isLeave == true) { - const exceptClear = await checkExceptCommandType(String(item.commandId)); - if (exceptClear.status) { - _profile.leaveReason = item.leaveReason ?? _null; - _profile.leaveCommandId = item.commandId ?? _null; - _profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; - _profile.leaveRemark = exceptClear.leaveRemark ?? _null; - _profile.leaveDate = item.commandDateAffect ?? _null; - _profile.leaveType = exceptClear.LeaveType ?? _null; - } else { - // บันทึกประวัติก่อนลบตำแหน่ง - const curRevision = await this.orgRevisionRepo.findOne({ - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + // บันทึกประวัติก่อนลบตำแหน่ง + const curRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + }); + if (curRevision) { + const curPosMaster = await this.employeePosMasterRepository.findOne({ + where: { + current_holderId: _profile.id, + orgRevisionId: curRevision.id, + }, }); - if (curRevision) { - const curPosMaster = await this.employeePosMasterRepository.findOne({ - where: { - current_holderId: _profile.id, - orgRevisionId: curRevision.id, - }, - }); - if (curPosMaster) { - await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); - } + if (curPosMaster) { + await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); } - await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } + await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } const clearProfile = await checkCommandType(String(item.commandId)); if (clearProfile.status) { @@ -6166,32 +6145,22 @@ export class CommandController extends Controller { _profile.lastUpdateFullName = req.user.name; _profile.lastUpdatedAt = new Date(); if (item.isLeave == true) { - const exceptClear = await checkExceptCommandType(String(item.commandId)); - if (exceptClear.status) { - _profile.leaveReason = item.leaveReason ?? _null; - _profile.leaveCommandId = item.commandId ?? _null; - _profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; - _profile.leaveRemark = exceptClear.leaveRemark ?? _null; - _profile.leaveDate = item.commandDateAffect ?? _null; - _profile.leaveType = exceptClear.LeaveType ?? _null; - } else { - // บันทึกประวัติก่อนลบตำแหน่ง - const curRevision = await this.orgRevisionRepo.findOne({ - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + // บันทึกประวัติก่อนลบตำแหน่ง + const curRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, + }); + if (curRevision) { + const curPosMaster = await this.employeePosMasterRepository.findOne({ + where: { + current_holderId: _profile.id, + orgRevisionId: curRevision.id, + }, }); - if (curRevision) { - const curPosMaster = await this.employeePosMasterRepository.findOne({ - where: { - current_holderId: _profile.id, - orgRevisionId: curRevision.id, - }, - }); - if (curPosMaster) { - await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); - } + if (curPosMaster) { + await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); } - await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } + await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } const clearProfile = await checkCommandType(String(item.commandId)); if (clearProfile.status) { diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index c75bf147..3a48ab2b 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -326,7 +326,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) { await AppDataSource.getRepository(EmployeePosMaster) .createQueryBuilder() .update(EmployeePosMaster) - .set({ current_holderId: null }) + .set({ current_holderId: null, isSit: false }) .where("id = :id", { id: findProfileInEmpPosMaster?.id }) .execute(); @@ -395,43 +395,6 @@ export async function checkReturnCommandType(commandId: string) { return true; } -export async function checkExceptCommandType(commandId: string) { - const commandRepository = AppDataSource.getRepository(Command); - const commandReciveRepository = AppDataSource.getRepository(CommandRecive); - const _type = await commandRepository.findOne({ - where: { - id: commandId, - }, - relations: ["commandType"], - }); - if (!["C-PM-25", "C-PM-26"].includes(String(_type?.commandType.code))) { - return { status: false, LeaveType: null, leaveRemark: null }; - } - const _commandRecive = await commandReciveRepository.findOne({ - where: { commandId: commandId }, - }); - - let _leaveType: string = ""; - switch (String(_type?.commandType.code)) { - case "C-PM-25": { - _leaveType = "DISCIPLINE_SUSPEND"; //คำสั่งพักจากราชการ - break; - } - case "C-PM-26": { - _leaveType = "DISCIPLINE_TEMP_SUSPEND"; //คำสั่งให้ออกจากราชการไว้ก่อน - break; - } - default: { - _leaveType = ""; - } - } - return { - status: true, - LeaveType: _leaveType, - leaveRemark: _commandRecive ? _commandRecive.remarkVertical : null, - }; -} - export async function checkCommandType(commandId: string) { const commandRepository = AppDataSource.getRepository(Command); const commandReciveRepository = AppDataSource.getRepository(CommandRecive); @@ -451,6 +414,8 @@ export async function checkCommandType(commandId: string) { "C-PM-23", "C-PM-19", "C-PM-20", + "C-PM-25", + "C-PM-26", "C-PM-43", ].includes(String(_type?.commandType.code)) ) { @@ -500,6 +465,16 @@ export async function checkCommandType(commandId: string) { _retireTypeName = "ลาออกจากราชการ"; break; } + case "C-PM-25": { + _leaveType = "DISCIPLINE_SUSPEND"; + _retireTypeName = "พักจากราชการ"; + break; + } + case "C-PM-26": { + _leaveType = "DISCIPLINE_TEMP_SUSPEND"; + _retireTypeName = "ให้ออกจากราชการไว้ก่อน"; + break; + } case "C-PM-43": { _leaveType = "RETIRE_OUT_EMP"; _retireTypeName = "ให้ออกจากราชการ"; From ad9a7dcbb6b4af069e5311df34ae409912a5137e Mon Sep 17 00:00:00 2001 From: harid Date: Fri, 29 May 2026 14:08:25 +0700 Subject: [PATCH 10/14] =?UTF-8?q?fix=20=E0=B8=A3=E0=B8=B0=E0=B8=9A?= =?UTF-8?q?=E0=B8=9A=E0=B9=84=E0=B8=A1=E0=B9=88=E0=B8=9B=E0=B8=B1=E0=B9=8A?= =?UTF-8?q?=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=A7=E0=B8=B1=E0=B8=95?= =?UTF-8?q?=E0=B8=B4=E0=B8=82=E0=B9=89=E0=B8=AD=E0=B8=A1=E0=B8=B9=E0=B8=A5?= =?UTF-8?q?=E0=B9=80=E0=B8=94=E0=B8=B4=E0=B8=A1=E0=B9=83=E0=B8=AB=E0=B9=89?= =?UTF-8?q?=20row=20=E0=B9=81=E0=B8=A3=E0=B8=81=20#2535?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OrganizationDotnetController.ts | 26 +++++++++++++++++++ src/controllers/ProfileController.ts | 16 ++++++++++++ src/controllers/ProfileEmployeeController.ts | 18 +++++++++++++ .../ProfileEmployeeTempController.ts | 18 +++++++++++++ 4 files changed, 78 insertions(+) diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index 8be7aa0f..e83d2911 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -9151,4 +9151,30 @@ export class OrganizationDotnetController extends Controller { }); return new HttpSuccess(filteredPosMasters); } + + /** + * API ตรวจสอบ profileId ที่ลาออกแล้ว + * @summary API ตรวจสอบ profileId ที่ลาออกแล้ว + */ + @Post("check-isLeave") + @Security("internalAuth") + async findProfileIsLeave( + @Body() + req: { profileIds: string[] } + ) { + const profile = await this.profileRepo.find({ + select: { id: true }, + where: { + id: In(req.profileIds), + isLeave: true + } + }); + + if (profile.length === 0) { + return new HttpSuccess([]); + } + + return new HttpSuccess(profile.map(p => p.id)); + } + } diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 434e7b77..0fcf3c3c 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -5779,6 +5779,22 @@ export class ProfileController extends Controller { } const record = await this.profileRepo.findOneBy({ id }); const before = structuredClone(record); + // เช็คว่ามี profileHistory ของ profile นี้หรือไม่ + const historyCount = await this.profileHistoryRepo.count({ + where: { profileId: id }, + }); + + // ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน + if (historyCount === 0) { + await this.profileHistoryRepo.save( + Object.assign(new ProfileHistory(), { + ...before, + birthDateOld: before?.birthDate, + profileId: id, + id: undefined, + }), + ); + } if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index cdf1a4e4..9b2537c0 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -2385,6 +2385,24 @@ export class ProfileEmployeeController extends Controller { Extension.CheckCitizen(body.citizenId); } const record = await this.profileRepo.findOneBy({ id }); + const before = structuredClone(record); + // เช็คว่ามี profileHistory ของ profile นี้หรือไม่ + const historyCount = await this.profileHistoryRepo.count({ + where: { profileEmployeeId: id }, + }); + + // ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน + if (historyCount === 0) { + await this.profileHistoryRepo.save( + Object.assign(new ProfileEmployeeHistory(), { + ...before, + birthDateOld: before?.birthDate, + profileEmployeeId: id, + id: undefined, + }), + ); + } + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") { diff --git a/src/controllers/ProfileEmployeeTempController.ts b/src/controllers/ProfileEmployeeTempController.ts index a8c017ae..406dce69 100644 --- a/src/controllers/ProfileEmployeeTempController.ts +++ b/src/controllers/ProfileEmployeeTempController.ts @@ -1001,6 +1001,24 @@ export class ProfileEmployeeTempController extends Controller { } const record = await this.profileRepo.findOneBy({ id }); + const before = structuredClone(record); + // เช็คว่ามี profileHistory ของ profile นี้หรือไม่ + const historyCount = await this.profileHistoryRepo.count({ + where: { profileEmployeeId: id }, + }); + + // ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน + if (historyCount === 0) { + await this.profileHistoryRepo.save( + Object.assign(new ProfileEmployeeHistory(), { + ...before, + birthDateOld: before?.birthDate, + profileEmployeeId: id, + id: undefined, + }), + ); + } + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") { From 20c6c412b88b55378643dbc1bf572071ba0a9e2d Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Fri, 29 May 2026 14:24:50 +0700 Subject: [PATCH 11/14] remove log success --- src/middlewares/authInternal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/authInternal.ts b/src/middlewares/authInternal.ts index d3d9a5b6..77da531c 100644 --- a/src/middlewares/authInternal.ts +++ b/src/middlewares/authInternal.ts @@ -19,7 +19,7 @@ export async function handleInternalAuth(request: express.Request) { throw new HttpError(HttpStatus.UNAUTHORIZED, "Invalid API Key"); } - console.log(`[InternalAuth] Authentication successful`); + // console.log(`[InternalAuth] Authentication successful`); return { sub: "internal_service", From 185aedc53f96805d7264132ffdfaacc0e6747c12 Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Fri, 29 May 2026 17:23:45 +0700 Subject: [PATCH 12/14] remove log success --- src/controllers/OrganizationDotnetController.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index e83d2911..d785a643 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -2372,7 +2372,7 @@ export class OrganizationDotnetController extends Controller { @Security("internalAuth") async GetProfileForProcessCheckInAsync(@Path() keycloakId: string) { try { - console.log(`[check-keycloak] START - keycloakId=${keycloakId}`); + // console.log(`[check-keycloak] START - keycloakId=${keycloakId}`); /* ========================= * 1. Load profile (Officer) @@ -2447,14 +2447,14 @@ export class OrganizationDotnetController extends Controller { child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null, }; - console.log( - `[check-keycloak] SUCCESS_EMPLOYEE - keycloakId=${keycloakId}, profileType=EMPLOYEE`, - ); + // console.log( + // `[check-keycloak] SUCCESS_EMPLOYEE - keycloakId=${keycloakId}, profileType=EMPLOYEE`, + // ); return new HttpSuccess(mapProfile); } - console.log(`[check-keycloak] OFFICER_FOUND - keycloakId=${keycloakId}`); + // console.log(`[check-keycloak] OFFICER_FOUND - keycloakId=${keycloakId}`); /* ========================================= * 2. current holder (Officer) @@ -2494,9 +2494,9 @@ export class OrganizationDotnetController extends Controller { child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null, }; - console.log( - `[check-keycloak] SUCCESS_OFFICER - keycloakId=${keycloakId}, profileType=OFFICER`, - ); + // console.log( + // `[check-keycloak] SUCCESS_OFFICER - keycloakId=${keycloakId}, profileType=OFFICER`, + // ); return new HttpSuccess(mapProfile); } catch (error: any) { From b0cfbc70363b04dd86a9ceee990117b6b07078bd Mon Sep 17 00:00:00 2001 From: harid Date: Fri, 29 May 2026 17:37:19 +0700 Subject: [PATCH 13/14] fix #2510 --- src/controllers/CommandController.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index d732a622..474470de 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4312,11 +4312,8 @@ export class CommandController extends Controller { body.data.map(async (item) => { const profile = await this.profileRepository.findOne({ where: { id: item.profileId }, - // relations: ["roleKeycloaks"], relations: { - roleKeycloaks: true, - posType: true, - posLevel: true, + roleKeycloaks: true }, }); if (!profile) { @@ -4612,6 +4609,8 @@ export class CommandController extends Controller { await this.positionRepository.save(positionNew, { data: req }); } await CreatePosMasterHistoryOfficer(posMaster.id, req); + profile.posMasterNo = getPosMasterNo(posMaster); + profile.org = getOrgFullName(posMaster); } const newMapProfileSalary = { profileId: profile.id, From 219a2908a3c71ca1265f8eaa203af25db0ba37bf Mon Sep 17 00:00:00 2001 From: Adisak Date: Thu, 4 Jun 2026 09:25:01 +0700 Subject: [PATCH 14/14] =?UTF-8?q?=E0=B9=81=E0=B8=81=E0=B9=89=20format=20?= =?UTF-8?q?=E0=B8=9F=E0=B8=B4=E0=B8=A7=20posMasterNo=20(5)=20=E0=B8=AA?= =?UTF-8?q?=E0=B8=B3=E0=B8=AB=E0=B8=A3=E0=B8=B1=E0=B8=9A=E0=B8=9A=E0=B8=B1?= =?UTF-8?q?=E0=B8=99=E0=B8=97=E0=B8=B6=E0=B8=81=E0=B8=A5=E0=B8=87=E0=B8=A3?= =?UTF-8?q?=E0=B8=B0=E0=B8=9A=E0=B8=9A=E0=B8=97=E0=B8=B5=E0=B9=88=E0=B8=9E?= =?UTF-8?q?=E0=B8=B1=E0=B8=92=E0=B8=99=E0=B8=B2=E0=B8=9A=E0=B8=99=20.net?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.ปรับระดับชั้นงาน-ย้ายลูกจ้าง (เลข Prefix / Suffix ไม่แสดง) 2.รายการอื่นๆ (เลข Prefix / Suffix ไม่แสดง) 3.รายการลาออก (เลข Prefix / Suffix ไม่แสดง) 4.รายการลาออกลูกจ้างฯ (เลข Prefix / Suffix ไม่แสดง) 5.เรื่องร้องเรียน (เลข Prefix / Suffix ไม่แสดง) 6.สืบสวนฯ (เลข Prefix / Suffix ไม่แสดง) 7.สอบสวนฯ (เลข Prefix / Suffix ไม่แสดง) 8.สรุปผลการพิจารณาฯ (เลข Prefix / Suffix ไม่แสดง) --- src/controllers/ProfileController.ts | 80 +++++++++----------- src/controllers/ProfileEmployeeController.ts | 49 ++++-------- 2 files changed, 49 insertions(+), 80 deletions(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 434e7b77..65052de9 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -7935,40 +7935,38 @@ export class ProfileController extends Controller { privacyUser: profile.privacyUser, privacyMgt: profile.privacyMgt, isDeputy: root?.isDeputy ?? false, - // root?.orgRootShortName && posMaster?.posMasterNo - // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` - // : "", }; + const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeDnaId = _profile.child4DnaId; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeDnaId = _profile.child3DnaId; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeDnaId = _profile.child2DnaId; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeDnaId = _profile.child1DnaId; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeDnaId = _profile.rootDnaId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); } @@ -8108,41 +8106,39 @@ export class ProfileController extends Controller { privacyUser: profile.privacyUser, privacyMgt: profile.privacyMgt, isDeputy: root?.isDeputy ?? false, - // root?.orgRootShortName && posMaster?.posMasterNo - // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` - // : "", }; + const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeDnaId = _profile.child4DnaId; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${posMaster?.posMasterNo}`; + _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeDnaId = _profile.child3DnaId; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${posMaster?.posMasterNo}`; + _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeDnaId = _profile.child2DnaId; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${posMaster?.posMasterNo}`; + _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeDnaId = _profile.child1DnaId; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${posMaster?.posMasterNo}`; + _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeDnaId = _profile.rootDnaId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${posMaster?.posMasterNo}`; + _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); } @@ -9313,26 +9309,32 @@ export class ProfileController extends Controller { : "-", }; + const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeShortName = _profile.child4ShortName; + _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeShortName = _profile.child3ShortName; + _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeShortName = _profile.child2ShortName; + _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeShortName = _profile.child1ShortName; + _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeShortName = _profile.rootShortName; + _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); } @@ -9513,38 +9515,28 @@ export class ProfileController extends Controller { const mapDataProfile = await Promise.all( findProfile.map(async (item: Profile) => { const fullName = `${item.prefix}${item.firstName} ${item.lastName}`; - const shortName = - item.current_holders.length == 0 - ? null - : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != - null - ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` - : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != - null - ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` - : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild2 != null - ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` - : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild1 != null - ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` - : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != - null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgRoot != null - ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` - : null; + const holder = item.current_holders?.find((x) => x.orgRevisionId == findRevision.id); + const _numPart = holder ? [holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; + const shortName = !holder + ? null + : holder.orgChild4 != null + ? `${holder.orgChild4.orgChild4ShortName} ${_numPart}` + : holder.orgChild3 != null + ? `${holder.orgChild3.orgChild3ShortName} ${_numPart}` + : holder.orgChild2 != null + ? `${holder.orgChild2.orgChild2ShortName} ${_numPart}` + : holder.orgChild1 != null + ? `${holder.orgChild1.orgChild1ShortName} ${_numPart}` + : holder.orgRoot != null + ? `${holder.orgRoot.orgRootShortName} ${_numPart}` + : null; const root = item.current_holders.length == 0 || - (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) + (holder != null && + holder?.orgRoot == null) ? null - : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; + : holder?.orgRoot; const rootHolder = item.current_holders?.find( (x) => x.orgRevisionId == findRevision.id, diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index cdf1a4e4..bca81433 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -4003,40 +4003,38 @@ export class ProfileEmployeeController extends Controller { salary: profile ? profile.amount : null, amountSpecial: profile ? profile.amountSpecial : null, posNo: null, - // root?.orgRootShortName && posMaster?.posMasterNo - // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` - // : "", }; + const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeDnaId = _profile.child4DnaId; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeDnaId = _profile.child3DnaId; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeDnaId = _profile.child2DnaId; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeDnaId = _profile.child1DnaId; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeDnaId = _profile.rootDnaId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_profile.posMasterNo}`; + _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); } @@ -6444,33 +6442,7 @@ export class ProfileEmployeeController extends Controller { null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4; - const shortName = - profile.current_holders.length == 0 - ? null - : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) - ?.orgChild4 != null - ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4.orgChild4ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` - : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) - ?.orgChild3 != null - ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3.orgChild3ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` - : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != - null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) - ?.orgChild2 != null - ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2.orgChild2ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` - : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != - null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) - ?.orgChild1 != null - ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1.orgChild1ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` - : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != - null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) - ?.orgRoot != null - ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot.orgRootShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` - : null; + const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; const _profile: any = { profileId: profile.id, prefix: profile.prefix, @@ -6512,7 +6484,7 @@ export class ProfileEmployeeController extends Controller { child4ShortName: child4 == null ? null : child4.orgChild4ShortName, node: null, nodeId: null, - posNo: shortName, + posNo: null, salary: profile.amount, education: profile && profile.profileEducations.length > 0 @@ -6527,22 +6499,27 @@ export class ProfileEmployeeController extends Controller { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeShortName = _profile.child4ShortName; + _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeShortName = _profile.child3ShortName; + _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeShortName = _profile.child2ShortName; + _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeShortName = _profile.child1ShortName; + _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeShortName = _profile.rootShortName; + _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); }