From 37245744c9ee6dff9bade70423a11d33df88916b Mon Sep 17 00:00:00 2001 From: Adisak Date: Mon, 5 Jan 2026 11:35:49 +0700 Subject: [PATCH 1/7] #2153 --- src/services/PositionService.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/services/PositionService.ts b/src/services/PositionService.ts index 9d0d5c3b..0562f458 100644 --- a/src/services/PositionService.ts +++ b/src/services/PositionService.ts @@ -41,7 +41,7 @@ export async function CreatePosMasterHistoryOfficer( if (!pm.ancestorDNA) return false; const checkCurrentRevision = await repoOrgRevision.findOne({ - where:{ + where: { id: pm.orgRevisionId, orgRevisionIsCurrent: true, orgRevisionIsDraft: false @@ -54,12 +54,18 @@ export async function CreatePosMasterHistoryOfficer( ? pm.positions.find((p) => p.positionIsSelected === true) ?? null : null; h.ancestorDNA = pm.ancestorDNA ? pm.ancestorDNA : _null; - if(!type || type != "DELETE"){ - if(checkCurrentRevision){ + if (!type || type != "DELETE") { + if (checkCurrentRevision) { h.prefix = pm.current_holder?.prefix || _null; h.firstName = pm.current_holder?.firstName || _null; h.lastName = pm.current_holder?.lastName || _null; - }else{ + h.profileId = pm.current_holder?.id || _null; + h.rootDnaId = pm.orgRoot.ancestorDNA || _null; + h.child1DnaId = pm.orgChild1.ancestorDNA || _null; + h.child2DnaId = pm.orgChild2.ancestorDNA || _null; + h.child3DnaId = pm.orgChild3.ancestorDNA || _null; + h.child4DnaId = pm.orgChild4.ancestorDNA || _null; + } else { h.prefix = pm.next_holder?.prefix || _null; h.firstName = pm.next_holder?.firstName || _null; h.lastName = pm.next_holder?.lastName || _null; From 784b9cc44133e963cc320b03d022c67c16441d48 Mon Sep 17 00:00:00 2001 From: Adisak Date: Mon, 5 Jan 2026 13:11:55 +0700 Subject: [PATCH 2/7] fix --- src/services/PositionService.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/services/PositionService.ts b/src/services/PositionService.ts index 0562f458..1b30f980 100644 --- a/src/services/PositionService.ts +++ b/src/services/PositionService.ts @@ -60,11 +60,11 @@ export async function CreatePosMasterHistoryOfficer( h.firstName = pm.current_holder?.firstName || _null; h.lastName = pm.current_holder?.lastName || _null; h.profileId = pm.current_holder?.id || _null; - h.rootDnaId = pm.orgRoot.ancestorDNA || _null; - h.child1DnaId = pm.orgChild1.ancestorDNA || _null; - h.child2DnaId = pm.orgChild2.ancestorDNA || _null; - h.child3DnaId = pm.orgChild3.ancestorDNA || _null; - h.child4DnaId = pm.orgChild4.ancestorDNA || _null; + h.rootDnaId = pm.orgRoot?.ancestorDNA || _null; + h.child1DnaId = pm.orgChild1?.ancestorDNA || _null; + h.child2DnaId = pm.orgChild2?.ancestorDNA || _null; + h.child3DnaId = pm.orgChild3?.ancestorDNA || _null; + h.child4DnaId = pm.orgChild4?.ancestorDNA || _null; } else { h.prefix = pm.next_holder?.prefix || _null; h.firstName = pm.next_holder?.firstName || _null; From 01cffa44aa8a8425d65e3803fb8cbe87d848ebc2 Mon Sep 17 00:00:00 2001 From: harid Date: Tue, 6 Jan 2026 13:10:57 +0700 Subject: [PATCH 3/7] =?UTF-8?q?comment=20=E0=B8=AD=E0=B8=AD=E0=B8=81?= =?UTF-8?q?=E0=B8=81=E0=B9=88=E0=B8=AD=E0=B8=99=E0=B9=80=E0=B8=9E=E0=B8=A3?= =?UTF-8?q?=E0=B8=B2=E0=B8=B0=E0=B8=A2=E0=B8=B1=E0=B8=87=E0=B9=84=E0=B8=A1?= =?UTF-8?q?=E0=B9=88=E0=B9=84=E0=B8=94=E0=B9=89=E0=B9=83=E0=B8=8A=E0=B9=89?= =?UTF-8?q?=20#2154?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/ProfileController.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index c4cf2eae..dab843ee 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -10810,10 +10810,11 @@ export class ProfileController extends Controller { system?: string; }, ) { - // ค้นหารายชื่อถ้าไม่ส่ง system มาให้ default ตามทะเบียนประวัติ - let _system: string = "SYS_REGISTRY_OFFICER"; - if (body.system) _system = body.system; - let _data = await new permission().PermissionOrgList(request, _system); + // comment ออกก่อนเพราะยังไม่ได้ใช้ + // // ค้นหารายชื่อถ้าไม่ส่ง system มาให้ default ตามทะเบียนประวัติ + // let _system: string = "SYS_REGISTRY_OFFICER"; + // if (body.system) _system = body.system; + // let _data = await new permission().PermissionOrgList(request, _system); const findRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true }, }); From dea1b11e1bf53e331dca2e8dc6007018bd49559d Mon Sep 17 00:00:00 2001 From: mamoss <> Date: Wed, 7 Jan 2026 01:44:18 +0700 Subject: [PATCH 4/7] update search --- .../OrganizationDotnetController.ts | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index bfac03bc..b5803029 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -6161,8 +6161,8 @@ export class OrganizationDotnetController extends Controller { where: { ...typeCondition, createdAt: LessThanOrEqual(date), - firstName: Not("") && Not(IsNull()), - lastName: Not("") && Not(IsNull()), + // firstName: Not("") && Not(IsNull()), + // lastName: Not("") && Not(IsNull()), }, order: { firstName: "ASC", @@ -6171,10 +6171,10 @@ export class OrganizationDotnetController extends Controller { }, }); - // group by firstName + lastName แล้วเลือก create_at ล่าสุด + // group by ancestorDNA แล้วเลือก create_at ล่าสุด const grouped = new Map(); for (const item of profile) { - const key = `${item.firstName}-${item.lastName}`; + const key = `${item.ancestorDNA}`; if (!grouped.has(key)) { grouped.set(key, item); } else { @@ -6187,32 +6187,34 @@ export class OrganizationDotnetController extends Controller { } const profile_ = await Promise.all( - Array.from(grouped.values()).map(async (item: PosMasterHistory) => { - let profile = await this.profileRepo.findOne({ - where: { id: item.profileId }, - }); + Array.from(grouped.values()) + .filter((x) => x.profileId != null) + .map(async (item: PosMasterHistory) => { + let profile = await this.profileRepo.findOne({ + where: { id: item.profileId }, + }); - return { - id: item.id, - prefix: item.prefix, - firstName: item.firstName, - lastName: item.lastName, - citizenId: profile?.citizenId ?? null, - dateStart: profile?.dateStart ?? null, - dateAppoint: profile?.dateAppoint ?? null, - keycloak: profile?.keycloak ?? null, - posNo: item.shortName, - position: item.position, - positionLevel: item.posLevel, - positionType: item.posType, - // oc: Oc, - orgRootId: item.rootDnaId, - orgChild1Id: item.child1DnaId, - orgChild2Id: item.child2DnaId, - orgChild3Id: item.child3DnaId, - orgChild4Id: item.child4DnaId, - }; - }), + return { + id: item.id, + prefix: item.prefix, + firstName: item.firstName, + lastName: item.lastName, + citizenId: profile?.citizenId ?? null, + dateStart: profile?.dateStart ?? null, + dateAppoint: profile?.dateAppoint ?? null, + keycloak: profile?.keycloak ?? null, + posNo: item.shortName, + position: item.position, + positionLevel: item.posLevel, + positionType: item.posType, + // oc: Oc, + orgRootId: item.rootDnaId, + orgChild1Id: item.child1DnaId, + orgChild2Id: item.child2DnaId, + orgChild3Id: item.child3DnaId, + orgChild4Id: item.child4DnaId, + }; + }), ); return new HttpSuccess(profile_); From 3f1aff32dd6952da618cc264175247ac030d1bd0 Mon Sep 17 00:00:00 2001 From: harid Date: Thu, 8 Jan 2026 16:09:25 +0700 Subject: [PATCH 5/7] test #2160 --- src/services/rabbitmq.ts | 167 ++++++++++++++++++++++++++++++--------- 1 file changed, 129 insertions(+), 38 deletions(-) diff --git a/src/services/rabbitmq.ts b/src/services/rabbitmq.ts index 844b4587..6bf7c70d 100644 --- a/src/services/rabbitmq.ts +++ b/src/services/rabbitmq.ts @@ -25,6 +25,7 @@ import { PermissionOrg } from "../entities/PermissionOrg"; import { sendWebSocket } from "./webSocket"; import { CreatePosMasterHistoryOfficer } from "./PositionService"; import { PayloadSendNoti } from "../interfaces/utils"; +import { PermissionProfile } from "../entities/PermissionProfile"; export let sendToQueue: (payload: any) => void; export let sendToQueueOrg: (payload: any) => void; @@ -496,6 +497,8 @@ async function handler_command_noti(msg: amqp.ConsumeMessage): Promise async function handler_org(msg: amqp.ConsumeMessage): Promise { //----> condition before process consume const repoPosmaster = AppDataSource.getRepository(PosMaster); + const posMasterAssignRepository = AppDataSource.getRepository(PosMasterAssign); + const permissionProfilesRepository = AppDataSource.getRepository(PermissionProfile); const repoEmployeePosmaster = AppDataSource.getRepository(EmployeePosMaster); const repoEmployeeTempPosmaster = AppDataSource.getRepository(EmployeeTempPosMaster); const repoProfile = AppDataSource.getRepository(Profile); @@ -557,8 +560,75 @@ async function handler_org(msg: amqp.ConsumeMessage): Promise { "positions.posExecutive", ], }); + // // xxx + // // ดึง assignment ของ revision เดิม + // const oldAssigns = await posMasterAssignRepository.find({ + // relations: ["posMaster"], + // where: { + // posMaster: { + // orgRevisionId: orgRevisionPublish?.id, + // }, + // }, + // }); + // // สร้าง Map: ancestorDNA → assignments[] + // const assignMap = new Map(); + // for (const a of oldAssigns) { + // const dna = a.posMaster.ancestorDNA; + // if (!assignMap.has(dna)) { + // assignMap.set(dna, []); + // } + // assignMap.get(dna)!.push(a); + // } + // const permissionProfiles = await permissionProfilesRepository.find({ + // relations: ["orgRootTree"], + // where: { + // orgRootTree: { + // orgRevisionId: orgRevisionPublish?.id, + // } + // } + // }); + // const permissionMap = new Map(); + // for (const p of permissionProfiles) { + // const dna = p.orgRootTree.ancestorDNA; + // if (!permissionMap.has(dna)) { + // permissionMap.set(dna, []); + // } + // permissionMap.get(dna)!.push(p); + // } + // const newRoots = await orgRootRepository.find({ + // where: { orgRevisionId: orgRevisionDraft?.id }, + // }); + // const newRootMap = new Map( + // newRoots.map(r => [r.ancestorDNA, r.id]) + // ); const _null: any = null; for (const item of posMaster) { + // /* =============================== + // * Clone posMasterAssign & permissionProfiles xxx + // * =============================== */ + // const assigns = assignMap.get(item.ancestorDNA); + + // if (assigns && assigns.length > 0) { + // const newAssigns = assigns.map(({ id, ...rest }) => ({ + // ...rest, // copy ทุก field ยกเว้น id + // posMasterId: item.id, // ผูกกับ posMaster ใหม่ + // })); + + // await posMasterAssignRepository.save(newAssigns); + // } + + // const perms = permissionMap.get(item.ancestorDNA); + // const newRootId = newRootMap.get(item.ancestorDNA); + + // if (perms && perms.length > 0 && newRootId) { + // const newPerms = perms.map(({ id, orgRootTree, ...rest }) => ({ + // ...rest, // profileId, isEdit, isCheck + // orgRootId: newRootId, + // })); + + // await permissionProfilesRepository.save(newPerms); + // } + if (item.next_holderId != null) { const profile = await repoProfile.findOne({ where: { id: item.next_holderId == null ? "" : item.next_holderId }, @@ -1798,13 +1868,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise { posMaster.lastUpdatedAt = new Date(); await posMasterRepository.save(posMaster); - // Copy assignments - await posMasterAssignRepository.save( - posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ - ...rest, - posMasterId: posMaster.id, - })), - ); + // // Copy assignments + // await posMasterAssignRepository.save( + // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ + // ...rest, + // posMasterId: posMaster.id, + // })), + // ); // Create positions for await (const pos of item.positions) { @@ -1895,13 +1965,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise { posMaster.lastUpdatedAt = new Date(); await posMasterRepository.save(posMaster); - // Copy assignments - await posMasterAssignRepository.save( - posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ - ...rest, - posMasterId: posMaster.id, - })), - ); + // // Copy assignments + // await posMasterAssignRepository.save( + // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ + // ...rest, + // posMasterId: posMaster.id, + // })), + // ); // Create positions for await (const pos of item.positions) { @@ -1994,13 +2064,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise { posMaster.lastUpdatedAt = new Date(); await posMasterRepository.save(posMaster); - // Copy assignments - await posMasterAssignRepository.save( - posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ - ...rest, - posMasterId: posMaster.id, - })), - ); + // // Copy assignments + // await posMasterAssignRepository.save( + // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ + // ...rest, + // posMasterId: posMaster.id, + // })), + // ); // Create positions for await (const pos of item.positions) { @@ -2095,13 +2165,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise { posMaster.lastUpdatedAt = new Date(); await posMasterRepository.save(posMaster); - // Copy assignments - await posMasterAssignRepository.save( - posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ - ...rest, - posMasterId: posMaster.id, - })), - ); + // // Copy assignments + // await posMasterAssignRepository.save( + // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ + // ...rest, + // posMasterId: posMaster.id, + // })), + // ); // Create positions for await (const pos of item.positions) { @@ -2199,13 +2269,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise { posMaster.lastUpdatedAt = new Date(); await posMasterRepository.save(posMaster); - // Copy assignments - await posMasterAssignRepository.save( - posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ - ...rest, - posMasterId: posMaster.id, - })), - ); + // // Copy assignments + // await posMasterAssignRepository.save( + // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ + // ...rest, + // posMasterId: posMaster.id, + // })), + // ); // Create positions for await (const pos of item.positions) { @@ -2287,9 +2357,30 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise { await child3Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) }); await child2Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) }); await child1Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) }); - await permissionOrgRepository.delete({ - orgRootId: In(_roots.map((x) => x.id)), - }); + // ถ้าเลือกทำสำเนาให้อัพเดทจากแบบร่างเดิมไปแบบร่างใหม่แทนการลบ xxx + if (["ORG", "ORG_POSITION", "ORG_POSITION_PERSON", "ORG_POSITION_ROLE", "ORG_POSITION_PERSON_ROLE"].includes(requestBody.typeDraft?.toUpperCase())) + { + const _newRoots = await orgRootRepository.find({ + where: { orgRevisionId: revision.id} + }); + const newRootMap = new Map( + _newRoots.map(r => [r.ancestorDNA, r.id]) + ); + for (const oldRoot of _roots) { + const newRootId = newRootMap.get(oldRoot.ancestorDNA); + if (!newRootId) continue; + // อัพเดท orgRootId ที่อยู่ภายใต้ orgRevision แบบร่างเดิมเป็นของ orgRevision แบบร่างใหม่ + await permissionOrgRepository.update( + { orgRootId: oldRoot.id }, + { orgRootId: newRootId } + ); + } + } + else { + await permissionOrgRepository.delete({ + orgRootId: In(_roots.map((x) => x.id)), + }); + } await orgRootRepository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) }); await orgRevisionRepository.remove(_orgRevisions); From f2a3e604300e8999797b44e2240db6a5e29eec2e Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Fri, 9 Jan 2026 10:37:33 +0700 Subject: [PATCH 6/7] fix bug return profile id --- src/controllers/OrganizationDotnetController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index b5803029..706cb318 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -6195,7 +6195,7 @@ export class OrganizationDotnetController extends Controller { }); return { - id: item.id, + id: item.profileId, prefix: item.prefix, firstName: item.firstName, lastName: item.lastName, From 3d34a4c5ef0b325f9cf2d1e1480393c6399de9d0 Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Fri, 9 Jan 2026 10:53:32 +0700 Subject: [PATCH 7/7] migrate table posMaster --- ...7930614165-update_table_posMasterHistory.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/migration/1767930614165-update_table_posMasterHistory.ts diff --git a/src/migration/1767930614165-update_table_posMasterHistory.ts b/src/migration/1767930614165-update_table_posMasterHistory.ts new file mode 100644 index 00000000..d0bec6bf --- /dev/null +++ b/src/migration/1767930614165-update_table_posMasterHistory.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTablePosMasterHistory1767930614165 implements MigrationInterface { + name = 'UpdateTablePosMasterHistory1767930614165' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`posMasterHistory\` ADD \`profileId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง profile'`); + await queryRunner.query(`ALTER TABLE \`posMasterHistory\` ADD \`rootDnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgRoot'`); + await queryRunner.query(`ALTER TABLE \`posMasterHistory\` ADD \`child1DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild1'`); + await queryRunner.query(`ALTER TABLE \`posMasterHistory\` ADD \`child2DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild2'`); + await queryRunner.query(`ALTER TABLE \`posMasterHistory\` ADD \`child3DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild3'`); + await queryRunner.query(`ALTER TABLE \`posMasterHistory\` ADD \`child4DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild4'`); + } + + public async down(queryRunner: QueryRunner): Promise { + } + +}