Merge branch 'develop' into dev

* develop:
  migrate table posMaster
  fix bug return profile id
  test #2160
  update search
  comment ออกก่อนเพราะยังไม่ได้ใช้ #2154
  fix
  #2153
This commit is contained in:
Warunee Tamkoo 2026-01-09 10:56:21 +07:00
commit 7253f51568
5 changed files with 193 additions and 75 deletions

View file

@ -6161,8 +6161,8 @@ export class OrganizationDotnetController extends Controller {
where: { where: {
...typeCondition, ...typeCondition,
createdAt: LessThanOrEqual(date), createdAt: LessThanOrEqual(date),
firstName: Not("") && Not(IsNull()), // firstName: Not("") && Not(IsNull()),
lastName: Not("") && Not(IsNull()), // lastName: Not("") && Not(IsNull()),
}, },
order: { order: {
firstName: "ASC", 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<string, PosMasterHistory>(); const grouped = new Map<string, PosMasterHistory>();
for (const item of profile) { for (const item of profile) {
const key = `${item.firstName}-${item.lastName}`; const key = `${item.ancestorDNA}`;
if (!grouped.has(key)) { if (!grouped.has(key)) {
grouped.set(key, item); grouped.set(key, item);
} else { } else {
@ -6187,32 +6187,34 @@ export class OrganizationDotnetController extends Controller {
} }
const profile_ = await Promise.all( const profile_ = await Promise.all(
Array.from(grouped.values()).map(async (item: PosMasterHistory) => { Array.from(grouped.values())
let profile = await this.profileRepo.findOne({ .filter((x) => x.profileId != null)
where: { id: item.profileId }, .map(async (item: PosMasterHistory) => {
}); let profile = await this.profileRepo.findOne({
where: { id: item.profileId },
});
return { return {
id: item.id, id: item.profileId,
prefix: item.prefix, prefix: item.prefix,
firstName: item.firstName, firstName: item.firstName,
lastName: item.lastName, lastName: item.lastName,
citizenId: profile?.citizenId ?? null, citizenId: profile?.citizenId ?? null,
dateStart: profile?.dateStart ?? null, dateStart: profile?.dateStart ?? null,
dateAppoint: profile?.dateAppoint ?? null, dateAppoint: profile?.dateAppoint ?? null,
keycloak: profile?.keycloak ?? null, keycloak: profile?.keycloak ?? null,
posNo: item.shortName, posNo: item.shortName,
position: item.position, position: item.position,
positionLevel: item.posLevel, positionLevel: item.posLevel,
positionType: item.posType, positionType: item.posType,
// oc: Oc, // oc: Oc,
orgRootId: item.rootDnaId, orgRootId: item.rootDnaId,
orgChild1Id: item.child1DnaId, orgChild1Id: item.child1DnaId,
orgChild2Id: item.child2DnaId, orgChild2Id: item.child2DnaId,
orgChild3Id: item.child3DnaId, orgChild3Id: item.child3DnaId,
orgChild4Id: item.child4DnaId, orgChild4Id: item.child4DnaId,
}; };
}), }),
); );
return new HttpSuccess(profile_); return new HttpSuccess(profile_);

View file

@ -10810,10 +10810,11 @@ export class ProfileController extends Controller {
system?: string; system?: string;
}, },
) { ) {
// ค้นหารายชื่อถ้าไม่ส่ง system มาให้ default ตามทะเบียนประวัติ // comment ออกก่อนเพราะยังไม่ได้ใช้
let _system: string = "SYS_REGISTRY_OFFICER"; // // ค้นหารายชื่อถ้าไม่ส่ง system มาให้ default ตามทะเบียนประวัติ
if (body.system) _system = body.system; // let _system: string = "SYS_REGISTRY_OFFICER";
let _data = await new permission().PermissionOrgList(request, _system); // if (body.system) _system = body.system;
// let _data = await new permission().PermissionOrgList(request, _system);
const findRevision = await this.orgRevisionRepo.findOne({ const findRevision = await this.orgRevisionRepo.findOne({
where: { orgRevisionIsCurrent: true }, where: { orgRevisionIsCurrent: true },
}); });

View file

@ -0,0 +1,18 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class UpdateTablePosMasterHistory1767930614165 implements MigrationInterface {
name = 'UpdateTablePosMasterHistory1767930614165'
public async up(queryRunner: QueryRunner): Promise<void> {
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<void> {
}
}

View file

@ -41,7 +41,7 @@ export async function CreatePosMasterHistoryOfficer(
if (!pm.ancestorDNA) return false; if (!pm.ancestorDNA) return false;
const checkCurrentRevision = await repoOrgRevision.findOne({ const checkCurrentRevision = await repoOrgRevision.findOne({
where:{ where: {
id: pm.orgRevisionId, id: pm.orgRevisionId,
orgRevisionIsCurrent: true, orgRevisionIsCurrent: true,
orgRevisionIsDraft: false orgRevisionIsDraft: false
@ -54,12 +54,18 @@ export async function CreatePosMasterHistoryOfficer(
? pm.positions.find((p) => p.positionIsSelected === true) ?? null ? pm.positions.find((p) => p.positionIsSelected === true) ?? null
: null; : null;
h.ancestorDNA = pm.ancestorDNA ? pm.ancestorDNA : _null; h.ancestorDNA = pm.ancestorDNA ? pm.ancestorDNA : _null;
if(!type || type != "DELETE"){ if (!type || type != "DELETE") {
if(checkCurrentRevision){ if (checkCurrentRevision) {
h.prefix = pm.current_holder?.prefix || _null; h.prefix = pm.current_holder?.prefix || _null;
h.firstName = pm.current_holder?.firstName || _null; h.firstName = pm.current_holder?.firstName || _null;
h.lastName = pm.current_holder?.lastName || _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.prefix = pm.next_holder?.prefix || _null;
h.firstName = pm.next_holder?.firstName || _null; h.firstName = pm.next_holder?.firstName || _null;
h.lastName = pm.next_holder?.lastName || _null; h.lastName = pm.next_holder?.lastName || _null;

View file

@ -25,6 +25,7 @@ import { PermissionOrg } from "../entities/PermissionOrg";
import { sendWebSocket } from "./webSocket"; import { sendWebSocket } from "./webSocket";
import { CreatePosMasterHistoryOfficer } from "./PositionService"; import { CreatePosMasterHistoryOfficer } from "./PositionService";
import { PayloadSendNoti } from "../interfaces/utils"; import { PayloadSendNoti } from "../interfaces/utils";
import { PermissionProfile } from "../entities/PermissionProfile";
export let sendToQueue: (payload: any) => void; export let sendToQueue: (payload: any) => void;
export let sendToQueueOrg: (payload: any) => void; export let sendToQueueOrg: (payload: any) => void;
@ -496,6 +497,8 @@ async function handler_command_noti(msg: amqp.ConsumeMessage): Promise<boolean>
async function handler_org(msg: amqp.ConsumeMessage): Promise<boolean> { async function handler_org(msg: amqp.ConsumeMessage): Promise<boolean> {
//----> condition before process consume //----> condition before process consume
const repoPosmaster = AppDataSource.getRepository(PosMaster); const repoPosmaster = AppDataSource.getRepository(PosMaster);
const posMasterAssignRepository = AppDataSource.getRepository(PosMasterAssign);
const permissionProfilesRepository = AppDataSource.getRepository(PermissionProfile);
const repoEmployeePosmaster = AppDataSource.getRepository(EmployeePosMaster); const repoEmployeePosmaster = AppDataSource.getRepository(EmployeePosMaster);
const repoEmployeeTempPosmaster = AppDataSource.getRepository(EmployeeTempPosMaster); const repoEmployeeTempPosmaster = AppDataSource.getRepository(EmployeeTempPosMaster);
const repoProfile = AppDataSource.getRepository(Profile); const repoProfile = AppDataSource.getRepository(Profile);
@ -557,8 +560,75 @@ async function handler_org(msg: amqp.ConsumeMessage): Promise<boolean> {
"positions.posExecutive", "positions.posExecutive",
], ],
}); });
// // xxx
// // ดึง assignment ของ revision เดิม
// const oldAssigns = await posMasterAssignRepository.find({
// relations: ["posMaster"],
// where: {
// posMaster: {
// orgRevisionId: orgRevisionPublish?.id,
// },
// },
// });
// // สร้าง Map: ancestorDNA → assignments[]
// const assignMap = new Map<string, PosMasterAssign[]>();
// 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<string, PermissionProfile[]>();
// 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; const _null: any = null;
for (const item of posMaster) { 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) { if (item.next_holderId != null) {
const profile = await repoProfile.findOne({ const profile = await repoProfile.findOne({
where: { id: item.next_holderId == null ? "" : item.next_holderId }, where: { id: item.next_holderId == null ? "" : item.next_holderId },
@ -1798,13 +1868,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise<boolean> {
posMaster.lastUpdatedAt = new Date(); posMaster.lastUpdatedAt = new Date();
await posMasterRepository.save(posMaster); await posMasterRepository.save(posMaster);
// Copy assignments // // Copy assignments
await posMasterAssignRepository.save( // await posMasterAssignRepository.save(
posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({
...rest, // ...rest,
posMasterId: posMaster.id, // posMasterId: posMaster.id,
})), // })),
); // );
// Create positions // Create positions
for await (const pos of item.positions) { for await (const pos of item.positions) {
@ -1895,13 +1965,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise<boolean> {
posMaster.lastUpdatedAt = new Date(); posMaster.lastUpdatedAt = new Date();
await posMasterRepository.save(posMaster); await posMasterRepository.save(posMaster);
// Copy assignments // // Copy assignments
await posMasterAssignRepository.save( // await posMasterAssignRepository.save(
posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({
...rest, // ...rest,
posMasterId: posMaster.id, // posMasterId: posMaster.id,
})), // })),
); // );
// Create positions // Create positions
for await (const pos of item.positions) { for await (const pos of item.positions) {
@ -1994,13 +2064,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise<boolean> {
posMaster.lastUpdatedAt = new Date(); posMaster.lastUpdatedAt = new Date();
await posMasterRepository.save(posMaster); await posMasterRepository.save(posMaster);
// Copy assignments // // Copy assignments
await posMasterAssignRepository.save( // await posMasterAssignRepository.save(
posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({
...rest, // ...rest,
posMasterId: posMaster.id, // posMasterId: posMaster.id,
})), // })),
); // );
// Create positions // Create positions
for await (const pos of item.positions) { for await (const pos of item.positions) {
@ -2095,13 +2165,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise<boolean> {
posMaster.lastUpdatedAt = new Date(); posMaster.lastUpdatedAt = new Date();
await posMasterRepository.save(posMaster); await posMasterRepository.save(posMaster);
// Copy assignments // // Copy assignments
await posMasterAssignRepository.save( // await posMasterAssignRepository.save(
posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({
...rest, // ...rest,
posMasterId: posMaster.id, // posMasterId: posMaster.id,
})), // })),
); // );
// Create positions // Create positions
for await (const pos of item.positions) { for await (const pos of item.positions) {
@ -2199,13 +2269,13 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise<boolean> {
posMaster.lastUpdatedAt = new Date(); posMaster.lastUpdatedAt = new Date();
await posMasterRepository.save(posMaster); await posMasterRepository.save(posMaster);
// Copy assignments // // Copy assignments
await posMasterAssignRepository.save( // await posMasterAssignRepository.save(
posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({ // posMasterAssign.map(({ id, ...rest }: PosMasterAssign) => ({
...rest, // ...rest,
posMasterId: posMaster.id, // posMasterId: posMaster.id,
})), // })),
); // );
// Create positions // Create positions
for await (const pos of item.positions) { for await (const pos of item.positions) {
@ -2287,9 +2357,30 @@ async function handler_org_draft(msg: amqp.ConsumeMessage): Promise<boolean> {
await child3Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) }); await child3Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
await child2Repository.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 child1Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
await permissionOrgRepository.delete({ // ถ้าเลือกทำสำเนาให้อัพเดทจากแบบร่างเดิมไปแบบร่างใหม่แทนการลบ xxx
orgRootId: In(_roots.map((x) => x.id)), 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 orgRootRepository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
await orgRevisionRepository.remove(_orgRevisions); await orgRevisionRepository.remove(_orgRevisions);