Merge branch 'fix/org-chart' into develop
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m34s
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m34s
* fix/org-chart: fix: bug query
This commit is contained in:
commit
92e20966d0
2 changed files with 1461 additions and 978 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,121 @@
|
|||
import { AppDataSource } from "../database/data-source";
|
||||
import { PosMaster } from "../entities/PosMaster";
|
||||
|
||||
// Helper function to get aggregated position counts
|
||||
// Type definitions for position counts
|
||||
export interface PositionCountData {
|
||||
totalCount: number;
|
||||
currentVacantCount: number;
|
||||
nextVacantCount: number;
|
||||
}
|
||||
|
||||
export interface PositionCountsByNode {
|
||||
orgRootMap: Map<string, PositionCountData>;
|
||||
orgChild1Map: Map<string, PositionCountData>;
|
||||
orgChild2Map: Map<string, PositionCountData>;
|
||||
orgChild3Map: Map<string, PositionCountData>;
|
||||
orgChild4Map: Map<string, PositionCountData>;
|
||||
}
|
||||
|
||||
// Optimized function using SQL aggregation with GROUP BY
|
||||
// This is much more efficient than loading all records into memory
|
||||
export async function getPositionCountsAggregated(orgRevisionId: string): Promise<PositionCountsByNode> {
|
||||
const posRepo = AppDataSource.getRepository(PosMaster);
|
||||
|
||||
// Helper to build map from query results
|
||||
const buildMap = (results: any[]) => {
|
||||
const map = new Map<string, PositionCountData>();
|
||||
for (const row of results) {
|
||||
if (row.nodeId) {
|
||||
map.set(row.nodeId, {
|
||||
totalCount: parseInt(row.totalCount) || 0,
|
||||
currentVacantCount: parseInt(row.currentVacantCount) || 0,
|
||||
nextVacantCount: parseInt(row.nextVacantCount) || 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
return map;
|
||||
};
|
||||
|
||||
// Execute all aggregation queries in parallel
|
||||
const [
|
||||
orgRootResults,
|
||||
orgChild1Results,
|
||||
orgChild2Results,
|
||||
orgChild3Results,
|
||||
orgChild4Results,
|
||||
] = await Promise.all([
|
||||
// Level 0: orgRoot
|
||||
posRepo
|
||||
.createQueryBuilder("pos")
|
||||
.select("pos.orgRootId", "nodeId")
|
||||
.addSelect("COUNT(*)", "totalCount")
|
||||
.addSelect("SUM(CASE WHEN pos.current_holderId IS NULL OR pos.current_holderId = '' THEN 1 ELSE 0 END)", "currentVacantCount")
|
||||
.addSelect("SUM(CASE WHEN pos.next_holderId IS NULL OR pos.next_holderId = '' THEN 1 ELSE 0 END)", "nextVacantCount")
|
||||
.where("pos.orgRevisionId = :orgRevisionId", { orgRevisionId })
|
||||
.andWhere("pos.orgRootId IS NOT NULL")
|
||||
.groupBy("pos.orgRootId")
|
||||
.getRawMany(),
|
||||
|
||||
// Level 1: orgChild1
|
||||
posRepo
|
||||
.createQueryBuilder("pos")
|
||||
.select("pos.orgChild1Id", "nodeId")
|
||||
.addSelect("COUNT(*)", "totalCount")
|
||||
.addSelect("SUM(CASE WHEN pos.current_holderId IS NULL OR pos.current_holderId = '' THEN 1 ELSE 0 END)", "currentVacantCount")
|
||||
.addSelect("SUM(CASE WHEN pos.next_holderId IS NULL OR pos.next_holderId = '' THEN 1 ELSE 0 END)", "nextVacantCount")
|
||||
.where("pos.orgRevisionId = :orgRevisionId", { orgRevisionId })
|
||||
.andWhere("pos.orgChild1Id IS NOT NULL")
|
||||
.groupBy("pos.orgChild1Id")
|
||||
.getRawMany(),
|
||||
|
||||
// Level 2: orgChild2
|
||||
posRepo
|
||||
.createQueryBuilder("pos")
|
||||
.select("pos.orgChild2Id", "nodeId")
|
||||
.addSelect("COUNT(*)", "totalCount")
|
||||
.addSelect("SUM(CASE WHEN pos.current_holderId IS NULL OR pos.current_holderId = '' THEN 1 ELSE 0 END)", "currentVacantCount")
|
||||
.addSelect("SUM(CASE WHEN pos.next_holderId IS NULL OR pos.next_holderId = '' THEN 1 ELSE 0 END)", "nextVacantCount")
|
||||
.where("pos.orgRevisionId = :orgRevisionId", { orgRevisionId })
|
||||
.andWhere("pos.orgChild2Id IS NOT NULL")
|
||||
.groupBy("pos.orgChild2Id")
|
||||
.getRawMany(),
|
||||
|
||||
// Level 3: orgChild3
|
||||
posRepo
|
||||
.createQueryBuilder("pos")
|
||||
.select("pos.orgChild3Id", "nodeId")
|
||||
.addSelect("COUNT(*)", "totalCount")
|
||||
.addSelect("SUM(CASE WHEN pos.current_holderId IS NULL OR pos.current_holderId = '' THEN 1 ELSE 0 END)", "currentVacantCount")
|
||||
.addSelect("SUM(CASE WHEN pos.next_holderId IS NULL OR pos.next_holderId = '' THEN 1 ELSE 0 END)", "nextVacantCount")
|
||||
.where("pos.orgRevisionId = :orgRevisionId", { orgRevisionId })
|
||||
.andWhere("pos.orgChild3Id IS NOT NULL")
|
||||
.groupBy("pos.orgChild3Id")
|
||||
.getRawMany(),
|
||||
|
||||
// Level 4: orgChild4
|
||||
posRepo
|
||||
.createQueryBuilder("pos")
|
||||
.select("pos.orgChild4Id", "nodeId")
|
||||
.addSelect("COUNT(*)", "totalCount")
|
||||
.addSelect("SUM(CASE WHEN pos.current_holderId IS NULL OR pos.current_holderId = '' THEN 1 ELSE 0 END)", "currentVacantCount")
|
||||
.addSelect("SUM(CASE WHEN pos.next_holderId IS NULL OR pos.next_holderId = '' THEN 1 ELSE 0 END)", "nextVacantCount")
|
||||
.where("pos.orgRevisionId = :orgRevisionId", { orgRevisionId })
|
||||
.andWhere("pos.orgChild4Id IS NOT NULL")
|
||||
.groupBy("pos.orgChild4Id")
|
||||
.getRawMany(),
|
||||
]);
|
||||
|
||||
return {
|
||||
orgRootMap: buildMap(orgRootResults),
|
||||
orgChild1Map: buildMap(orgChild1Results),
|
||||
orgChild2Map: buildMap(orgChild2Results),
|
||||
orgChild3Map: buildMap(orgChild3Results),
|
||||
orgChild4Map: buildMap(orgChild4Results),
|
||||
};
|
||||
}
|
||||
|
||||
// Legacy function - kept for backward compatibility
|
||||
// DEPRECATED: Use getPositionCountsAggregated instead
|
||||
export async function getPositionCounts(orgRevisionId: string) {
|
||||
// Query all posMaster data for this revision with aggregation
|
||||
const rawData = await AppDataSource.getRepository(PosMaster)
|
||||
|
|
@ -276,3 +390,18 @@ export function getRootCounts(map: Map<string, any>, key: string) {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Helper function to get position counts from aggregated maps with defaults
|
||||
export function getPositionCount(
|
||||
map: Map<string, PositionCountData>,
|
||||
key: string | null | undefined
|
||||
): PositionCountData {
|
||||
if (!key) return { totalCount: 0, currentVacantCount: 0, nextVacantCount: 0 };
|
||||
return (
|
||||
map.get(key) || {
|
||||
totalCount: 0,
|
||||
currentVacantCount: 0,
|
||||
nextVacantCount: 0,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue