diff --git a/src/controllers/ApiWebServiceController.ts b/src/controllers/ApiWebServiceController.ts index 1b4ffb51..ae8e469d 100644 --- a/src/controllers/ApiWebServiceController.ts +++ b/src/controllers/ApiWebServiceController.ts @@ -8,6 +8,7 @@ import { isPermissionRequest } from "../middlewares/authWebService"; import { RequestWithUserWebService } from "../middlewares/user"; import { OrgRevision } from "../entities/OrgRevision"; 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"; @@ -269,6 +270,7 @@ export class ApiWebServiceController extends Controller { let condition: string = "1=1"; if (system == "registry") { tbMain = "Profile"; + condition = `Profile.isActive = true`; } else if (system == "registry_emp") { tbMain = "ProfileEmployee"; condition = `ProfileEmployee.employeeClass = "PERM"`; @@ -559,17 +561,48 @@ export class ApiWebServiceController extends Controller { queryBuilder.leftJoin("PosMaster.current_holder", "Profile"); } + // สำหรับ registry system: เก็บ posMaster เพื่อดึง org IDs แล้วค่อย query ancestorDNA + let includeOrgAncestorDna = false; + if (system === "registry") { + // Always join posMaster for registry systems (inner join to exclude profiles without current posMaster) + // Only include posMaster from current revision + if (tbMain === "Profile") { + queryBuilder.innerJoin("Profile.current_holders", "posMaster", "posMaster.orgRevisionId = :currentRevisionId"); + queryBuilder.setParameter("currentRevisionId", this.currentRevisionId); + + // Add org ID fields from posMaster to propertyKey + propertyKey.push("posMaster.orgRootId"); + propertyKey.push("posMaster.orgChild1Id"); + propertyKey.push("posMaster.orgChild2Id"); + propertyKey.push("posMaster.orgChild3Id"); + propertyKey.push("posMaster.orgChild4Id"); + } else if (tbMain === "ProfileEmployee") { + // For registry_emp and registry_temp, also use inner join with current revision + if (posMasterAlias === "employeeTempPosMaster") { + queryBuilder.innerJoin("ProfileEmployee.current_holderTemps", "employeeTempPosMaster", "employeeTempPosMaster.orgRevisionId = :currentRevisionId"); + } else { + queryBuilder.innerJoin("ProfileEmployee.current_holders", "employeePosMaster", "employeePosMaster.orgRevisionId = :currentRevisionId"); + } + queryBuilder.setParameter("currentRevisionId", this.currentRevisionId); + } + + // Mark that we need to include ancestorDNA fields + includeOrgAncestorDna = true; + } + // join กับ posMaster/employeePosMaster/employeeTempPosMaster เพื่อกรองตามสิทธิ์การเข้าถึง if ((tbMain === "Profile" || tbMain === "ProfileEmployee") && posMasterCondition !== "1=1") { if (tbMain === "Profile") { - queryBuilder.leftJoin("Profile.current_holders", "posMaster"); + queryBuilder.innerJoin("Profile.current_holders", "posMaster", "posMaster.orgRevisionId = :currentRevisionIdPerm"); + queryBuilder.setParameter("currentRevisionIdPerm", this.currentRevisionId); } else if (tbMain === "ProfileEmployee") { // Use the correct relation based on posMasterAlias if (posMasterAlias === "employeeTempPosMaster") { - queryBuilder.leftJoin("ProfileEmployee.current_holderTemps", "employeeTempPosMaster"); + queryBuilder.innerJoin("ProfileEmployee.current_holderTemps", "employeeTempPosMaster", "employeeTempPosMaster.orgRevisionId = :currentRevisionIdPerm"); } else { - queryBuilder.leftJoin("ProfileEmployee.current_holders", "employeePosMaster"); + queryBuilder.innerJoin("ProfileEmployee.current_holders", "employeePosMaster", "employeePosMaster.orgRevisionId = :currentRevisionIdPerm"); } + queryBuilder.setParameter("currentRevisionIdPerm", this.currentRevisionId); } } @@ -610,6 +643,49 @@ export class ApiWebServiceController extends Controller { .getManyAndCount(); } + // สำหรับ registry: ดึง ancestorDNA จาก org tables + let orgRootAncestorMap: Record = {}; + let orgChild1AncestorMap: Record = {}; + let orgChild2AncestorMap: Record = {}; + let orgChild3AncestorMap: Record = {}; + let orgChild4AncestorMap: Record = {}; + + if (includeOrgAncestorDna && items.length > 0) { + // Collect all unique org IDs + const orgRootIds = new Set(); + const orgChild1Ids = new Set(); + const orgChild2Ids = new Set(); + const orgChild3Ids = new Set(); + const orgChild4Ids = new Set(); + + items.forEach((item) => { + if (item["current_holders"] && Array.isArray(item["current_holders"]) && item["current_holders"].length > 0) { + const posMaster = item["current_holders"][0]; + if (posMaster.orgRootId) orgRootIds.add(posMaster.orgRootId); + if (posMaster.orgChild1Id) orgChild1Ids.add(posMaster.orgChild1Id); + if (posMaster.orgChild2Id) orgChild2Ids.add(posMaster.orgChild2Id); + if (posMaster.orgChild3Id) orgChild3Ids.add(posMaster.orgChild3Id); + if (posMaster.orgChild4Id) orgChild4Ids.add(posMaster.orgChild4Id); + } + }); + + // Query org tables to get ancestorDNA + const [orgRoots, orgChild1s, orgChild2s, orgChild3s, orgChild4s] = await Promise.all([ + orgRootIds.size > 0 ? AppDataSource.getRepository(OrgRoot).createQueryBuilder("orgRoot").select(["orgRoot.id", "orgRoot.ancestorDNA"]).where("orgRoot.id IN (:...ids)", { ids: Array.from(orgRootIds) }).getMany() : [], + orgChild1Ids.size > 0 ? AppDataSource.getRepository(OrgChild1).createQueryBuilder("orgChild1").select(["orgChild1.id", "orgChild1.ancestorDNA"]).where("orgChild1.id IN (:...ids)", { ids: Array.from(orgChild1Ids) }).getMany() : [], + orgChild2Ids.size > 0 ? AppDataSource.getRepository(OrgChild2).createQueryBuilder("orgChild2").select(["orgChild2.id", "orgChild2.ancestorDNA"]).where("orgChild2.id IN (:...ids)", { ids: Array.from(orgChild2Ids) }).getMany() : [], + orgChild3Ids.size > 0 ? AppDataSource.getRepository(OrgChild3).createQueryBuilder("orgChild3").select(["orgChild3.id", "orgChild3.ancestorDNA"]).where("orgChild3.id IN (:...ids)", { ids: Array.from(orgChild3Ids) }).getMany() : [], + orgChild4Ids.size > 0 ? AppDataSource.getRepository(OrgChild4).createQueryBuilder("orgChild4").select(["orgChild4.id", "orgChild4.ancestorDNA"]).where("orgChild4.id IN (:...ids)", { ids: Array.from(orgChild4Ids) }).getMany() : [], + ]); + + // Create separate maps for each org level + orgRoots.forEach((org: any) => { orgRootAncestorMap[org.id] = org.ancestorDNA; }); + orgChild1s.forEach((org: any) => { orgChild1AncestorMap[org.id] = org.ancestorDNA; }); + orgChild2s.forEach((org: any) => { orgChild2AncestorMap[org.id] = org.ancestorDNA; }); + orgChild3s.forEach((org: any) => { orgChild3AncestorMap[org.id] = org.ancestorDNA; }); + orgChild4s.forEach((org: any) => { orgChild4AncestorMap[org.id] = org.ancestorDNA; }); + } + // ลบ Main.id // const results = items.map(({ id, ...x }) => x); // const results = items.map(({ pk, ...x }) => x); @@ -641,6 +717,31 @@ export class ApiWebServiceController extends Controller { delete flattened[config.joinRelation]; } }); + + // แปลง ancestorDNA เป็น orgRootId, orgChild1Id, etc. + if (includeOrgAncestorDna) { + if (rest["current_holders"] && Array.isArray(rest["current_holders"]) && rest["current_holders"].length > 0) { + const posMaster = rest["current_holders"][0]; + + // Get ancestorDNA from separate maps using org IDs + // Always set the fields, use null if no value + flattened.orgRootId = (posMaster.orgRootId && orgRootAncestorMap[posMaster.orgRootId]) ? orgRootAncestorMap[posMaster.orgRootId] : null; + flattened.orgChild1Id = (posMaster.orgChild1Id && orgChild1AncestorMap[posMaster.orgChild1Id]) ? orgChild1AncestorMap[posMaster.orgChild1Id] : null; + flattened.orgChild2Id = (posMaster.orgChild2Id && orgChild2AncestorMap[posMaster.orgChild2Id]) ? orgChild2AncestorMap[posMaster.orgChild2Id] : null; + flattened.orgChild3Id = (posMaster.orgChild3Id && orgChild3AncestorMap[posMaster.orgChild3Id]) ? orgChild3AncestorMap[posMaster.orgChild3Id] : null; + flattened.orgChild4Id = (posMaster.orgChild4Id && orgChild4AncestorMap[posMaster.orgChild4Id]) ? orgChild4AncestorMap[posMaster.orgChild4Id] : null; + } else { + // No current_holders, set all to null + flattened.orgRootId = null; + flattened.orgChild1Id = null; + flattened.orgChild2Id = null; + flattened.orgChild3Id = null; + flattened.orgChild4Id = null; + } + + // Delete current_holders array + delete flattened["current_holders"]; + } return flattened; }