fix emp temp and add script clear org dna at keycloak

This commit is contained in:
Warunee Tamkoo 2026-02-27 11:40:56 +07:00
parent b714dfe239
commit 49a8494a8d
3 changed files with 363 additions and 57 deletions

View file

@ -88,40 +88,101 @@ export class KeycloakAttributeService {
}
// If not found in Profile, try ProfileEmployee (ลูกจ้าง)
const profileEmployeeResult = await this.profileEmployeeRepo
// First, get the profileEmployee to check employeeClass
const profileEmployeeBasic = await this.profileEmployeeRepo
.createQueryBuilder("pe")
.leftJoinAndSelect("pe.current_holders", "epm")
.leftJoinAndSelect("epm.orgRoot", "org")
.leftJoinAndSelect("epm.orgChild1", "orgChild1")
.leftJoinAndSelect("epm.orgChild2", "orgChild2")
.leftJoinAndSelect("epm.orgChild3", "orgChild3")
.leftJoinAndSelect("epm.orgChild4", "orgChild4")
.where("pe.keycloak = :keycloakUserId", { keycloakUserId })
.getOne();
if (
profileEmployeeResult &&
profileEmployeeResult.current_holders &&
profileEmployeeResult.current_holders.length > 0
) {
const currentPos = profileEmployeeResult.current_holders[0];
const orgRootDnaId = currentPos.orgRoot?.ancestorDNA || "";
const orgChild1DnaId = currentPos.orgChild1?.ancestorDNA || "";
const orgChild2DnaId = currentPos.orgChild2?.ancestorDNA || "";
const orgChild3DnaId = currentPos.orgChild3?.ancestorDNA || "";
const orgChild4DnaId = currentPos.orgChild4?.ancestorDNA || "";
if (!profileEmployeeBasic) {
// Return null values if no profile found
return {
profileId: profileEmployeeResult.id,
orgRootDnaId,
orgChild1DnaId,
orgChild2DnaId,
orgChild3DnaId,
orgChild4DnaId,
empType: profileEmployeeResult.employeeClass,
prefix: profileEmployeeResult.prefix,
profileId: null,
orgRootDnaId: null,
orgChild1DnaId: null,
orgChild2DnaId: null,
orgChild3DnaId: null,
orgChild4DnaId: null,
empType: null,
prefix: null,
};
}
// Check employeeClass to determine which table to query
const isPermEmployee = profileEmployeeBasic.employeeClass === "PERM";
if (isPermEmployee) {
// ลูกจ้างประจำ (PERM) - ใช้ EmployeePosMaster
const profileEmployeeResult = await this.profileEmployeeRepo
.createQueryBuilder("pe")
.leftJoinAndSelect("pe.current_holders", "epm")
.leftJoinAndSelect("epm.orgRoot", "org")
.leftJoinAndSelect("epm.orgChild1", "orgChild1")
.leftJoinAndSelect("epm.orgChild2", "orgChild2")
.leftJoinAndSelect("epm.orgChild3", "orgChild3")
.leftJoinAndSelect("epm.orgChild4", "orgChild4")
.where("pe.keycloak = :keycloakUserId", { keycloakUserId })
.getOne();
if (
profileEmployeeResult &&
profileEmployeeResult.current_holders &&
profileEmployeeResult.current_holders.length > 0
) {
const currentPos = profileEmployeeResult.current_holders[0];
const orgRootDnaId = currentPos.orgRoot?.ancestorDNA || "";
const orgChild1DnaId = currentPos.orgChild1?.ancestorDNA || "";
const orgChild2DnaId = currentPos.orgChild2?.ancestorDNA || "";
const orgChild3DnaId = currentPos.orgChild3?.ancestorDNA || "";
const orgChild4DnaId = currentPos.orgChild4?.ancestorDNA || "";
return {
profileId: profileEmployeeResult.id,
orgRootDnaId,
orgChild1DnaId,
orgChild2DnaId,
orgChild3DnaId,
orgChild4DnaId,
empType: profileEmployeeResult.employeeClass,
prefix: profileEmployeeResult.prefix,
};
}
} else {
// ลูกจ้างชั่วคราว (TEMP) - ใช้ EmployeeTempPosMaster
const profileEmployeeResult = await this.profileEmployeeRepo
.createQueryBuilder("pe")
.leftJoinAndSelect("pe.current_holderTemps", "etpm")
.leftJoinAndSelect("etpm.orgRoot", "org")
.leftJoinAndSelect("etpm.orgChild1", "orgChild1")
.leftJoinAndSelect("etpm.orgChild2", "orgChild2")
.leftJoinAndSelect("etpm.orgChild3", "orgChild3")
.leftJoinAndSelect("etpm.orgChild4", "orgChild4")
.where("pe.keycloak = :keycloakUserId", { keycloakUserId })
.getOne();
if (
profileEmployeeResult &&
profileEmployeeResult.current_holderTemps &&
profileEmployeeResult.current_holderTemps.length > 0
) {
const currentPos = profileEmployeeResult.current_holderTemps[0];
const orgRootDnaId = currentPos.orgRoot?.ancestorDNA || "";
const orgChild1DnaId = currentPos.orgChild1?.ancestorDNA || "";
const orgChild2DnaId = currentPos.orgChild2?.ancestorDNA || "";
const orgChild3DnaId = currentPos.orgChild3?.ancestorDNA || "";
const orgChild4DnaId = currentPos.orgChild4?.ancestorDNA || "";
return {
profileId: profileEmployeeResult.id,
orgRootDnaId,
orgChild1DnaId,
orgChild2DnaId,
orgChild3DnaId,
orgChild4DnaId,
empType: profileEmployeeResult.employeeClass,
prefix: profileEmployeeResult.prefix,
};
}
}
// Return null values if no profile found
return {
profileId: null,
@ -187,40 +248,101 @@ export class KeycloakAttributeService {
};
}
} else {
const profileEmployeeResult = await this.profileEmployeeRepo
// First, get the profileEmployee to check employeeClass
const profileEmployeeBasic = await this.profileEmployeeRepo
.createQueryBuilder("pe")
.leftJoinAndSelect("pe.current_holders", "epm")
.leftJoinAndSelect("epm.orgRoot", "org")
.leftJoinAndSelect("pm.orgChild1", "orgChild1")
.leftJoinAndSelect("pm.orgChild2", "orgChild2")
.leftJoinAndSelect("pm.orgChild3", "orgChild3")
.leftJoinAndSelect("pm.orgChild4", "orgChild4")
.where("pe.id = :profileId", { profileId })
.getOne();
if (
profileEmployeeResult &&
profileEmployeeResult.current_holders &&
profileEmployeeResult.current_holders.length > 0
) {
const currentPos = profileEmployeeResult.current_holders[0];
const orgRootDnaId = currentPos.orgRoot?.ancestorDNA || "";
const orgChild1DnaId = currentPos.orgChild1?.ancestorDNA || "";
const orgChild2DnaId = currentPos.orgChild2?.ancestorDNA || "";
const orgChild3DnaId = currentPos.orgChild3?.ancestorDNA || "";
const orgChild4DnaId = currentPos.orgChild4?.ancestorDNA || "";
if (!profileEmployeeBasic) {
return {
profileId: profileEmployeeResult.id,
orgRootDnaId,
orgChild1DnaId,
orgChild2DnaId,
orgChild3DnaId,
orgChild4DnaId,
empType: profileEmployeeResult.employeeClass,
prefix: profileEmployeeResult.prefix,
profileId: null,
orgRootDnaId: null,
orgChild1DnaId: null,
orgChild2DnaId: null,
orgChild3DnaId: null,
orgChild4DnaId: null,
empType: null,
prefix: null,
};
}
// Check employeeClass to determine which table to query
const isPermEmployee = profileEmployeeBasic.employeeClass === "PERM";
if (isPermEmployee) {
// ลูกจ้างประจำ (PERM) - ใช้ EmployeePosMaster
const profileEmployeeResult = await this.profileEmployeeRepo
.createQueryBuilder("pe")
.leftJoinAndSelect("pe.current_holders", "epm")
.leftJoinAndSelect("epm.orgRoot", "org")
.leftJoinAndSelect("epm.orgChild1", "orgChild1")
.leftJoinAndSelect("epm.orgChild2", "orgChild2")
.leftJoinAndSelect("epm.orgChild3", "orgChild3")
.leftJoinAndSelect("epm.orgChild4", "orgChild4")
.where("pe.id = :profileId", { profileId })
.getOne();
if (
profileEmployeeResult &&
profileEmployeeResult.current_holders &&
profileEmployeeResult.current_holders.length > 0
) {
const currentPos = profileEmployeeResult.current_holders[0];
const orgRootDnaId = currentPos.orgRoot?.ancestorDNA || "";
const orgChild1DnaId = currentPos.orgChild1?.ancestorDNA || "";
const orgChild2DnaId = currentPos.orgChild2?.ancestorDNA || "";
const orgChild3DnaId = currentPos.orgChild3?.ancestorDNA || "";
const orgChild4DnaId = currentPos.orgChild4?.ancestorDNA || "";
return {
profileId: profileEmployeeResult.id,
orgRootDnaId,
orgChild1DnaId,
orgChild2DnaId,
orgChild3DnaId,
orgChild4DnaId,
empType: profileEmployeeResult.employeeClass,
prefix: profileEmployeeResult.prefix,
};
}
} else {
// ลูกจ้างชั่วคราว (TEMP) - ใช้ EmployeeTempPosMaster
const profileEmployeeResult = await this.profileEmployeeRepo
.createQueryBuilder("pe")
.leftJoinAndSelect("pe.current_holderTemps", "etpm")
.leftJoinAndSelect("etpm.orgRoot", "org")
.leftJoinAndSelect("etpm.orgChild1", "orgChild1")
.leftJoinAndSelect("etpm.orgChild2", "orgChild2")
.leftJoinAndSelect("etpm.orgChild3", "orgChild3")
.leftJoinAndSelect("etpm.orgChild4", "orgChild4")
.where("pe.id = :profileId", { profileId })
.getOne();
if (
profileEmployeeResult &&
profileEmployeeResult.current_holderTemps &&
profileEmployeeResult.current_holderTemps.length > 0
) {
const currentPos = profileEmployeeResult.current_holderTemps[0];
const orgRootDnaId = currentPos.orgRoot?.ancestorDNA || "";
const orgChild1DnaId = currentPos.orgChild1?.ancestorDNA || "";
const orgChild2DnaId = currentPos.orgChild2?.ancestorDNA || "";
const orgChild3DnaId = currentPos.orgChild3?.ancestorDNA || "";
const orgChild4DnaId = currentPos.orgChild4?.ancestorDNA || "";
return {
profileId: profileEmployeeResult.id,
orgRootDnaId,
orgChild1DnaId,
orgChild2DnaId,
orgChild3DnaId,
orgChild4DnaId,
empType: profileEmployeeResult.employeeClass,
prefix: profileEmployeeResult.prefix,
};
}
}
}
return {
@ -313,6 +435,95 @@ export class KeycloakAttributeService {
}
}
/**
* Clear org DNA attributes in Keycloak for given profiles
* Sets all org DNA fields to empty strings
*
* @param profileIds - Array of profile IDs to clear
* @param profileType - 'PROFILE' for officers or 'PROFILE_EMPLOYEE' for employees
* @returns Object with success/failed counts and details
*/
async clearOrgDnaAttributes(
profileIds: string[],
profileType: "PROFILE" | "PROFILE_EMPLOYEE",
): Promise<{
total: number;
success: number;
failed: number;
details: Array<{ profileId: string; status: "success" | "failed"; error?: string }>;
}> {
const result = {
total: profileIds.length,
success: 0,
failed: 0,
details: [] as Array<{ profileId: string; status: "success" | "failed"; error?: string }>,
};
for (const profileId of profileIds) {
try {
// Get the keycloak userId from the profile
let keycloakUserId: string | null = null;
if (profileType === "PROFILE") {
const profile = await this.profileRepo.findOne({ where: { id: profileId } });
keycloakUserId = profile?.keycloak || "";
} else {
const profileEmployee = await this.profileEmployeeRepo.findOne({
where: { id: profileId },
});
keycloakUserId = profileEmployee?.keycloak || "";
}
if (!keycloakUserId) {
result.failed++;
result.details.push({
profileId,
status: "failed",
error: "No Keycloak user ID found",
});
continue;
}
// Clear org DNA attributes by setting them to empty strings
const clearedAttributes: Record<string, string[]> = {
orgRootDnaId: [""],
orgChild1DnaId: [""],
orgChild2DnaId: [""],
orgChild3DnaId: [""],
orgChild4DnaId: [""],
};
const success = await updateUserAttributes(keycloakUserId, clearedAttributes);
if (success) {
result.success++;
result.details.push({
profileId,
status: "success",
});
console.log(`Cleared org DNA attributes for profile ${profileId} (${profileType})`);
} else {
result.failed++;
result.details.push({
profileId,
status: "failed",
error: "Failed to update Keycloak attributes",
});
}
} catch (error: any) {
result.failed++;
result.details.push({
profileId,
status: "failed",
error: error.message || "Unknown error",
});
console.error(`Error clearing org DNA attributes for profile ${profileId}:`, error);
}
}
return result;
}
/**
* Batch sync multiple users with unlimited count and parallel processing
* Useful for initial sync or periodic updates