232 lines
8.2 KiB
TypeScript
232 lines
8.2 KiB
TypeScript
import { EntityManager, EntityTarget, In } from "typeorm";
|
|
import { AppDataSource } from "../database/data-source";
|
|
import { OrgRevision } from "../entities/OrgRevision";
|
|
import { PosMaster } from "../entities/PosMaster";
|
|
import { Position } from "../entities/Position";
|
|
import { OrgRoot } from "../entities/OrgRoot";
|
|
import { OrgChild1 } from "../entities/OrgChild1";
|
|
import { OrgChild2 } from "../entities/OrgChild2";
|
|
import { OrgChild3 } from "../entities/OrgChild3";
|
|
import { OrgChild4 } from "../entities/OrgChild4";
|
|
import { PosMasterAct } from "../entities/PosMasterAct";
|
|
import { PosMasterAssign } from "../entities/PosMasterAssign";
|
|
import { PermissionOrg } from "../entities/PermissionOrg";
|
|
import { PermissionProfile } from "../entities/PermissionProfile";
|
|
import { EmployeePosMaster } from "../entities/EmployeePosMaster";
|
|
import { EmployeeTempPosMaster } from "../entities/EmployeeTempPosMaster";
|
|
import { EmployeePosition } from "../entities/EmployeePosition";
|
|
import { orgStructureCache } from "../utils/OrgStructureCache";
|
|
|
|
export interface ClearOldOrgRevisionSummary {
|
|
orgRevisionId: string;
|
|
orgRevisionName: string;
|
|
deleted: {
|
|
positions: number;
|
|
employeePositionsByPosMaster: number;
|
|
employeePositionsByTempPosMaster: number;
|
|
posMasterActsByParent: number;
|
|
posMasterActsByChild: number;
|
|
posMasterAssigns: number;
|
|
posMasters: number;
|
|
employeePosMasters: number;
|
|
employeeTempPosMasters: number;
|
|
permissionOrgs: number;
|
|
permissionProfiles: number;
|
|
orgChild4s: number;
|
|
orgChild3s: number;
|
|
orgChild2s: number;
|
|
orgChild1s: number;
|
|
orgRoots: number;
|
|
orgRevisions: number;
|
|
};
|
|
}
|
|
|
|
interface OrgRevisionSnapshot {
|
|
id: string;
|
|
orgRevisionName: string;
|
|
orgRevisionIsCurrent: boolean;
|
|
orgRevisionIsDraft: boolean;
|
|
}
|
|
|
|
export async function clearOldOrgRevisionData(
|
|
orgRevisionId: string,
|
|
): Promise<ClearOldOrgRevisionSummary> {
|
|
const result = await AppDataSource.transaction(async (manager) => {
|
|
const orgRevision = await manager.findOne(OrgRevision, {
|
|
where: { id: orgRevisionId },
|
|
select: ["id", "orgRevisionName", "orgRevisionIsCurrent", "orgRevisionIsDraft"],
|
|
});
|
|
|
|
if (!orgRevision) {
|
|
throw new Error(`ไม่พบ orgRevision ที่ต้องการล้างข้อมูล: ${orgRevisionId}`);
|
|
}
|
|
|
|
validateOrgRevisionForDeletion(orgRevision);
|
|
|
|
const [posMasters, orgRoots, employeePosMasters, employeeTempPosMasters] = await Promise.all([
|
|
manager.find(PosMaster, {
|
|
where: { orgRevisionId },
|
|
select: ["id"],
|
|
}),
|
|
manager.find(OrgRoot, {
|
|
where: { orgRevisionId },
|
|
select: ["id"],
|
|
}),
|
|
manager.find(EmployeePosMaster, {
|
|
where: { orgRevisionId },
|
|
select: ["id"],
|
|
}),
|
|
manager.find(EmployeeTempPosMaster, {
|
|
where: { orgRevisionId },
|
|
select: ["id"],
|
|
}),
|
|
]);
|
|
|
|
const posMasterIds = posMasters.map((item) => item.id);
|
|
const orgRootIds = orgRoots.map((item) => item.id);
|
|
const employeePosMasterIds = employeePosMasters.map((item) => item.id);
|
|
const employeeTempPosMasterIds = employeeTempPosMasters.map((item) => item.id);
|
|
|
|
const [
|
|
positionsCount,
|
|
employeePositionsByPosMasterCount,
|
|
employeePositionsByTempPosMasterCount,
|
|
posMasterActsByParentCount,
|
|
posMasterActsByChildCount,
|
|
posMasterAssignsCount,
|
|
permissionOrgsCount,
|
|
permissionProfilesCount,
|
|
orgChild4sCount,
|
|
orgChild3sCount,
|
|
orgChild2sCount,
|
|
orgChild1sCount,
|
|
] = await Promise.all([
|
|
countByIds(manager, Position, "posMasterId", posMasterIds),
|
|
countByIds(manager, EmployeePosition, "posMasterId", employeePosMasterIds),
|
|
countByIds(manager, EmployeePosition, "posMasterTempId", employeeTempPosMasterIds),
|
|
countByIds(manager, PosMasterAct, "posMasterId", posMasterIds),
|
|
countByIds(manager, PosMasterAct, "posMasterChildId", posMasterIds),
|
|
countByIds(manager, PosMasterAssign, "posMasterId", posMasterIds),
|
|
countByIds(manager, PermissionOrg, "orgRootId", orgRootIds),
|
|
countByIds(manager, PermissionProfile, "orgRootId", orgRootIds),
|
|
manager.count(OrgChild4, { where: { orgRevisionId } }),
|
|
manager.count(OrgChild3, { where: { orgRevisionId } }),
|
|
manager.count(OrgChild2, { where: { orgRevisionId } }),
|
|
manager.count(OrgChild1, { where: { orgRevisionId } }),
|
|
]);
|
|
|
|
if (positionsCount > 0) {
|
|
await manager.delete(Position, { posMasterId: In(posMasterIds) });
|
|
}
|
|
if (employeePositionsByPosMasterCount > 0) {
|
|
await manager.delete(EmployeePosition, { posMasterId: In(employeePosMasterIds) });
|
|
}
|
|
if (employeePositionsByTempPosMasterCount > 0) {
|
|
await manager.delete(EmployeePosition, { posMasterTempId: In(employeeTempPosMasterIds) });
|
|
}
|
|
if (posMasterActsByParentCount > 0) {
|
|
await manager.delete(PosMasterAct, { posMasterId: In(posMasterIds) });
|
|
}
|
|
if (posMasterActsByChildCount > 0) {
|
|
await manager.delete(PosMasterAct, { posMasterChildId: In(posMasterIds) });
|
|
}
|
|
if (posMasterAssignsCount > 0) {
|
|
await manager.delete(PosMasterAssign, { posMasterId: In(posMasterIds) });
|
|
}
|
|
|
|
const posMastersCount = posMasterIds.length;
|
|
const employeePosMastersCount = employeePosMasterIds.length;
|
|
const employeeTempPosMastersCount = employeeTempPosMasterIds.length;
|
|
|
|
if (posMastersCount > 0) {
|
|
await manager.delete(PosMaster, { orgRevisionId });
|
|
}
|
|
if (employeePosMastersCount > 0) {
|
|
await manager.delete(EmployeePosMaster, { orgRevisionId });
|
|
}
|
|
if (employeeTempPosMastersCount > 0) {
|
|
await manager.delete(EmployeeTempPosMaster, { orgRevisionId });
|
|
}
|
|
|
|
if (permissionOrgsCount > 0) {
|
|
await manager.delete(PermissionOrg, { orgRootId: In(orgRootIds) });
|
|
}
|
|
if (permissionProfilesCount > 0) {
|
|
await manager.delete(PermissionProfile, { orgRootId: In(orgRootIds) });
|
|
}
|
|
|
|
if (orgChild4sCount > 0) {
|
|
await manager.delete(OrgChild4, { orgRevisionId });
|
|
}
|
|
if (orgChild3sCount > 0) {
|
|
await manager.delete(OrgChild3, { orgRevisionId });
|
|
}
|
|
if (orgChild2sCount > 0) {
|
|
await manager.delete(OrgChild2, { orgRevisionId });
|
|
}
|
|
if (orgChild1sCount > 0) {
|
|
await manager.delete(OrgChild1, { orgRevisionId });
|
|
}
|
|
|
|
const orgRootsCount = orgRootIds.length;
|
|
if (orgRootsCount > 0) {
|
|
await manager.delete(OrgRoot, { orgRevisionId });
|
|
}
|
|
|
|
await manager.delete(OrgRevision, { id: orgRevisionId });
|
|
|
|
return {
|
|
orgRevisionId: orgRevision.id,
|
|
orgRevisionName: orgRevision.orgRevisionName,
|
|
deleted: {
|
|
positions: positionsCount,
|
|
employeePositionsByPosMaster: employeePositionsByPosMasterCount,
|
|
employeePositionsByTempPosMaster: employeePositionsByTempPosMasterCount,
|
|
posMasterActsByParent: posMasterActsByParentCount,
|
|
posMasterActsByChild: posMasterActsByChildCount,
|
|
posMasterAssigns: posMasterAssignsCount,
|
|
posMasters: posMastersCount,
|
|
employeePosMasters: employeePosMastersCount,
|
|
employeeTempPosMasters: employeeTempPosMastersCount,
|
|
permissionOrgs: permissionOrgsCount,
|
|
permissionProfiles: permissionProfilesCount,
|
|
orgChild4s: orgChild4sCount,
|
|
orgChild3s: orgChild3sCount,
|
|
orgChild2s: orgChild2sCount,
|
|
orgChild1s: orgChild1sCount,
|
|
orgRoots: orgRootsCount,
|
|
orgRevisions: 1,
|
|
},
|
|
};
|
|
});
|
|
|
|
orgStructureCache.invalidate(orgRevisionId);
|
|
return result;
|
|
}
|
|
|
|
function validateOrgRevisionForDeletion(orgRevision: OrgRevisionSnapshot): void {
|
|
if (orgRevision.orgRevisionIsCurrent) {
|
|
throw new Error(`ไม่สามารถลบ orgRevision ปัจจุบันได้: ${orgRevision.id}`);
|
|
}
|
|
|
|
if (orgRevision.orgRevisionIsDraft) {
|
|
throw new Error(`ไม่สามารถลบ orgRevision แบบร่างได้ด้วยสคริปต์นี้: ${orgRevision.id}`);
|
|
}
|
|
}
|
|
|
|
async function countByIds<Entity extends object>(
|
|
manager: EntityManager,
|
|
entity: EntityTarget<Entity>,
|
|
field: keyof Entity,
|
|
ids: string[],
|
|
): Promise<number> {
|
|
if (ids.length === 0) {
|
|
return 0;
|
|
}
|
|
|
|
const alias = "entity";
|
|
return manager
|
|
.createQueryBuilder(entity, alias)
|
|
.where(`${alias}.${String(field)} IN (:...ids)`, { ids })
|
|
.getCount();
|
|
}
|