import { AppDataSource } from "../database/data-source"; import { PosMaster } from "../entities/PosMaster"; // Helper function to get aggregated position counts export async function getPositionCounts(orgRevisionId: string) { // Query all posMaster data for this revision with aggregation const rawData = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("pos") .select([ "pos.orgRootId", "pos.orgChild1Id", "pos.orgChild2Id", "pos.orgChild3Id", "pos.orgChild4Id", ]) .where("pos.orgRevisionId = :orgRevisionId", { orgRevisionId }) .getMany(); // Helper to check if value is null or empty string const isNull = (val: any) => val === null || val === ""; // Build maps for each level const orgRootMap = new Map(); const orgChild1Map = new Map(); const orgChild2Map = new Map(); const orgChild3Map = new Map(); const orgChild4Map = new Map(); // Nested maps for root positions (positions at specific levels) const rootPosMap = new Map(); // key: "rootId", "rootId-child1Id", "rootId-child1Id-child2Id", etc. for (const pos of rawData) { const orgRootId = pos.orgRootId || "NULL"; const orgChild1Id = pos.orgChild1Id || "NULL"; const orgChild2Id = pos.orgChild2Id || "NULL"; const orgChild3Id = pos.orgChild3Id || "NULL"; const orgChild4Id = pos.orgChild4Id || "NULL"; // Level 0 (orgRoot) counts if (!orgRootMap.has(orgRootId)) { orgRootMap.set(orgRootId, { totalPosition: 0, totalPositionCurrentUse: 0, totalPositionCurrentVacant: 0, totalPositionNextUse: 0, totalPositionNextVacant: 0, }); } const rootCounts = orgRootMap.get(orgRootId); rootCounts.totalPosition++; if (!isNull(pos.current_holderId)) rootCounts.totalPositionCurrentUse++; else rootCounts.totalPositionCurrentVacant++; if (!isNull(pos.next_holderId)) rootCounts.totalPositionNextUse++; else rootCounts.totalPositionNextVacant++; // Level 1 (orgChild1) counts if (!isNull(pos.orgChild1Id)) { if (!orgChild1Map.has(pos.orgChild1Id)) { orgChild1Map.set(pos.orgChild1Id, { totalPosition: 0, totalPositionCurrentUse: 0, totalPositionCurrentVacant: 0, totalPositionNextUse: 0, totalPositionNextVacant: 0, }); } const child1Counts = orgChild1Map.get(pos.orgChild1Id); child1Counts.totalPosition++; if (!isNull(pos.current_holderId)) child1Counts.totalPositionCurrentUse++; else child1Counts.totalPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child1Counts.totalPositionNextUse++; else child1Counts.totalPositionNextVacant++; } // Level 2 (orgChild2) counts if (!isNull(pos.orgChild2Id)) { if (!orgChild2Map.has(pos.orgChild2Id)) { orgChild2Map.set(pos.orgChild2Id, { totalPosition: 0, totalPositionCurrentUse: 0, totalPositionCurrentVacant: 0, totalPositionNextUse: 0, totalPositionNextVacant: 0, }); } const child2Counts = orgChild2Map.get(pos.orgChild2Id); child2Counts.totalPosition++; if (!isNull(pos.current_holderId)) child2Counts.totalPositionCurrentUse++; else child2Counts.totalPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child2Counts.totalPositionNextUse++; else child2Counts.totalPositionNextVacant++; } // Level 3 (orgChild3) counts if (!isNull(pos.orgChild3Id)) { if (!orgChild3Map.has(pos.orgChild3Id)) { orgChild3Map.set(pos.orgChild3Id, { totalPosition: 0, totalPositionCurrentUse: 0, totalPositionCurrentVacant: 0, totalPositionNextUse: 0, totalPositionNextVacant: 0, }); } const child3Counts = orgChild3Map.get(pos.orgChild3Id); child3Counts.totalPosition++; if (!isNull(pos.current_holderId)) child3Counts.totalPositionCurrentUse++; else child3Counts.totalPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child3Counts.totalPositionNextUse++; else child3Counts.totalPositionNextVacant++; } // Level 4 (orgChild4) counts if (!isNull(pos.orgChild4Id)) { if (!orgChild4Map.has(pos.orgChild4Id)) { orgChild4Map.set(pos.orgChild4Id, { totalPosition: 0, totalPositionCurrentUse: 0, totalPositionCurrentVacant: 0, totalPositionNextUse: 0, totalPositionNextVacant: 0, }); } const child4Counts = orgChild4Map.get(pos.orgChild4Id); child4Counts.totalPosition++; if (!isNull(pos.current_holderId)) child4Counts.totalPositionCurrentUse++; else child4Counts.totalPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child4Counts.totalPositionNextUse++; else child4Counts.totalPositionNextVacant++; } // Root position counts (positions at specific hierarchy levels) // For orgRoot level (all children are null) const rootLevelKey = orgRootId; if (!rootPosMap.has(rootLevelKey)) { rootPosMap.set(rootLevelKey, { totalRootPosition: 0, totalRootPositionCurrentUse: 0, totalRootPositionCurrentVacant: 0, totalRootPositionNextUse: 0, totalRootPositionNextVacant: 0, }); } if (isNull(pos.orgChild1Id) && isNull(pos.orgChild2Id) && isNull(pos.orgChild3Id) && isNull(pos.orgChild4Id)) { const rootLevelCounts = rootPosMap.get(rootLevelKey); rootLevelCounts.totalRootPosition++; if (!isNull(pos.current_holderId)) rootLevelCounts.totalRootPositionCurrentUse++; else rootLevelCounts.totalRootPositionCurrentVacant++; if (!isNull(pos.next_holderId)) rootLevelCounts.totalRootPositionNextUse++; else rootLevelCounts.totalRootPositionNextVacant++; } // For orgChild1 level if (!isNull(pos.orgChild1Id)) { const child1LevelKey = `${orgRootId}-${pos.orgChild1Id}`; if (!rootPosMap.has(child1LevelKey)) { rootPosMap.set(child1LevelKey, { totalRootPosition: 0, totalRootPositionCurrentUse: 0, totalRootPositionCurrentVacant: 0, totalRootPositionNextUse: 0, totalRootPositionNextVacant: 0, }); } if (isNull(pos.orgChild2Id) && isNull(pos.orgChild3Id) && isNull(pos.orgChild4Id)) { const child1LevelCounts = rootPosMap.get(child1LevelKey); child1LevelCounts.totalRootPosition++; if (!isNull(pos.current_holderId)) child1LevelCounts.totalRootPositionCurrentUse++; else child1LevelCounts.totalRootPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child1LevelCounts.totalRootPositionNextUse++; else child1LevelCounts.totalRootPositionNextVacant++; } } // For orgChild2 level if (!isNull(pos.orgChild2Id)) { const child2LevelKey = `${orgRootId}-${pos.orgChild1Id}-${pos.orgChild2Id}`; if (!rootPosMap.has(child2LevelKey)) { rootPosMap.set(child2LevelKey, { totalRootPosition: 0, totalRootPositionCurrentUse: 0, totalRootPositionCurrentVacant: 0, totalRootPositionNextUse: 0, totalRootPositionNextVacant: 0, }); } if (isNull(pos.orgChild3Id) && isNull(pos.orgChild4Id)) { const child2LevelCounts = rootPosMap.get(child2LevelKey); child2LevelCounts.totalRootPosition++; if (!isNull(pos.current_holderId)) child2LevelCounts.totalRootPositionCurrentUse++; else child2LevelCounts.totalRootPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child2LevelCounts.totalRootPositionNextUse++; else child2LevelCounts.totalRootPositionNextVacant++; } } // For orgChild3 level if (!isNull(pos.orgChild3Id)) { const child3LevelKey = `${orgRootId}-${pos.orgChild1Id}-${pos.orgChild2Id}-${pos.orgChild3Id}`; if (!rootPosMap.has(child3LevelKey)) { rootPosMap.set(child3LevelKey, { totalRootPosition: 0, totalRootPositionCurrentUse: 0, totalRootPositionCurrentVacant: 0, totalRootPositionNextUse: 0, totalRootPositionNextVacant: 0, }); } if (isNull(pos.orgChild4Id)) { const child3LevelCounts = rootPosMap.get(child3LevelKey); child3LevelCounts.totalRootPosition++; if (!isNull(pos.current_holderId)) child3LevelCounts.totalRootPositionCurrentUse++; else child3LevelCounts.totalRootPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child3LevelCounts.totalRootPositionNextUse++; else child3LevelCounts.totalRootPositionNextVacant++; } } // For orgChild4 level if (!isNull(pos.orgChild4Id)) { const child4LevelKey = `${orgRootId}-${pos.orgChild1Id}-${pos.orgChild2Id}-${pos.orgChild3Id}-${pos.orgChild4Id}`; if (!rootPosMap.has(child4LevelKey)) { rootPosMap.set(child4LevelKey, { totalRootPosition: 0, totalRootPositionCurrentUse: 0, totalRootPositionCurrentVacant: 0, totalRootPositionNextUse: 0, totalRootPositionNextVacant: 0, }); } const child4LevelCounts = rootPosMap.get(child4LevelKey); child4LevelCounts.totalRootPosition++; if (!isNull(pos.current_holderId)) child4LevelCounts.totalRootPositionCurrentUse++; else child4LevelCounts.totalRootPositionCurrentVacant++; if (!isNull(pos.next_holderId)) child4LevelCounts.totalRootPositionNextUse++; else child4LevelCounts.totalRootPositionNextVacant++; } } return { orgRootMap, orgChild1Map, orgChild2Map, orgChild3Map, orgChild4Map, rootPosMap, }; } // Helper function to get counts from maps with defaults export function getCounts(map: Map, key: string) { return ( map.get(key) || { totalPosition: 0, totalPositionCurrentUse: 0, totalPositionCurrentVacant: 0, totalPositionNextUse: 0, totalPositionNextVacant: 0, } ); } // Helper function to get root position counts export function getRootCounts(map: Map, key: string) { return ( map.get(key) || { totalRootPosition: 0, totalRootPositionCurrentUse: 0, totalRootPositionCurrentVacant: 0, totalRootPositionNextUse: 0, totalRootPositionNextVacant: 0, } ); }