complete script move draf to current
This commit is contained in:
parent
1cab2b3afc
commit
3b97e52bd6
1 changed files with 199 additions and 80 deletions
|
|
@ -7865,7 +7865,6 @@ export class OrganizationController extends Controller {
|
|||
]);
|
||||
|
||||
if (!orgRootDraft) return new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงสร้างร่าง");
|
||||
|
||||
// Part 1: Differential sync of organization structure (bottom-up)
|
||||
// Build mapping incrementally as we process each level
|
||||
const allMappings: AllOrgMappings = {
|
||||
|
|
@ -7876,60 +7875,80 @@ export class OrganizationController extends Controller {
|
|||
orgChild4: { byAncestorDNA: new Map(), byDraftId: new Map() },
|
||||
};
|
||||
|
||||
// Process from bottom (Child4) to top (Root) to handle foreign key constraints
|
||||
// Child4 (leaf nodes - no children depending on them)
|
||||
allMappings.orgChild4 = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild4,
|
||||
this.child4Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
rootDnaId,
|
||||
allMappings,
|
||||
);
|
||||
// Track sync statistics for organization nodes
|
||||
const orgSyncStats: Record<string, { deleted: number; updated: number; inserted: number }> =
|
||||
{};
|
||||
|
||||
// Child3
|
||||
allMappings.orgChild3 = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild3,
|
||||
this.child3Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
rootDnaId,
|
||||
allMappings,
|
||||
);
|
||||
|
||||
// Child2
|
||||
allMappings.orgChild2 = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild2,
|
||||
this.child2Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
rootDnaId,
|
||||
allMappings,
|
||||
);
|
||||
|
||||
// Child1
|
||||
allMappings.orgChild1 = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild1,
|
||||
this.child1Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
rootDnaId,
|
||||
allMappings,
|
||||
);
|
||||
|
||||
// OrgRoot (root level - no parent mapping needed)
|
||||
allMappings.orgRoot = await this.syncOrgLevel(
|
||||
// Process from top (Root) to bottom (Child4) to handle foreign key constraints
|
||||
// OrgRoot (sync first - no parent dependencies)
|
||||
const orgRootResult = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgRoot,
|
||||
this.orgRootRepository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
rootDnaId,
|
||||
allMappings,
|
||||
orgRootDraft?.id,
|
||||
orgRootCurrent?.id,
|
||||
);
|
||||
allMappings.orgRoot = orgRootResult.mapping;
|
||||
orgSyncStats.orgRoot = orgRootResult.counts;
|
||||
|
||||
// Child1 (parent OrgRoot already synced)
|
||||
const child1Result = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild1,
|
||||
this.child1Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
allMappings,
|
||||
orgRootDraft?.id,
|
||||
orgRootCurrent?.id,
|
||||
);
|
||||
allMappings.orgChild1 = child1Result.mapping;
|
||||
orgSyncStats.orgChild1 = child1Result.counts;
|
||||
|
||||
// Child2 (parents OrgRoot and Child1 already synced)
|
||||
const child2Result = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild2,
|
||||
this.child2Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
allMappings,
|
||||
orgRootDraft?.id,
|
||||
orgRootCurrent?.id,
|
||||
);
|
||||
allMappings.orgChild2 = child2Result.mapping;
|
||||
orgSyncStats.orgChild2 = child2Result.counts;
|
||||
|
||||
// Child3 (parents OrgRoot, Child1, Child2 already synced)
|
||||
const child3Result = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild3,
|
||||
this.child3Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
allMappings,
|
||||
orgRootDraft?.id,
|
||||
orgRootCurrent?.id,
|
||||
);
|
||||
allMappings.orgChild3 = child3Result.mapping;
|
||||
orgSyncStats.orgChild3 = child3Result.counts;
|
||||
|
||||
// Child4 (parents OrgRoot, Child1, Child2, Child3 already synced)
|
||||
const child4Result = await this.syncOrgLevel(
|
||||
queryRunner,
|
||||
OrgChild4,
|
||||
this.child4Repository,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
allMappings,
|
||||
orgRootDraft?.id,
|
||||
orgRootCurrent?.id,
|
||||
);
|
||||
allMappings.orgChild4 = child4Result.mapping;
|
||||
orgSyncStats.orgChild4 = child4Result.counts;
|
||||
|
||||
// Part 2: Sync position data using new org IDs from Part 1
|
||||
// 2.1 Clear current_holderId for affected positions (keep existing logic)
|
||||
|
|
@ -8097,17 +8116,44 @@ export class OrganizationController extends Controller {
|
|||
}
|
||||
|
||||
// 2.5 Sync positions table for all affected posMasters
|
||||
const positionSyncStats: { deleted: number; updated: number; inserted: number } = {
|
||||
deleted: 0,
|
||||
updated: 0,
|
||||
inserted: 0,
|
||||
};
|
||||
for (const [draftPosMasterId, currentPosMasterId] of posMasterMapping) {
|
||||
await this.syncPositionsForPosMaster(
|
||||
const stats = await this.syncPositionsForPosMaster(
|
||||
queryRunner,
|
||||
draftPosMasterId,
|
||||
currentPosMasterId,
|
||||
drafRevisionId,
|
||||
currentRevisionId,
|
||||
);
|
||||
positionSyncStats.deleted += stats.deleted;
|
||||
positionSyncStats.updated += stats.updated;
|
||||
positionSyncStats.inserted += stats.inserted;
|
||||
}
|
||||
|
||||
// Build comprehensive summary
|
||||
const summary = {
|
||||
message: "ย้ายโครงสร้างสำเร็จ",
|
||||
organization: {
|
||||
orgRoot: orgSyncStats.orgRoot,
|
||||
orgChild1: orgSyncStats.orgChild1,
|
||||
orgChild2: orgSyncStats.orgChild2,
|
||||
orgChild3: orgSyncStats.orgChild3,
|
||||
orgChild4: orgSyncStats.orgChild4,
|
||||
},
|
||||
positionMaster: {
|
||||
deleted: toDelete.length,
|
||||
updated: toUpdate.length,
|
||||
inserted: toInsert.length,
|
||||
},
|
||||
position: positionSyncStats,
|
||||
};
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
return new HttpSuccess(summary);
|
||||
} catch (error) {
|
||||
console.error("Error moving draft to current:", error);
|
||||
await queryRunner.rollbackTransaction();
|
||||
|
|
@ -8161,23 +8207,49 @@ export class OrganizationController extends Controller {
|
|||
repository: any,
|
||||
draftRevisionId: string,
|
||||
currentRevisionId: string,
|
||||
rootDnaId: string,
|
||||
parentMappings?: AllOrgMappings,
|
||||
): Promise<OrgIdMapping> {
|
||||
draftOrgRootId?: string,
|
||||
currentOrgRootId?: string,
|
||||
): Promise<{
|
||||
mapping: OrgIdMapping;
|
||||
counts: { deleted: number; updated: number; inserted: number };
|
||||
}> {
|
||||
// 1. Fetch draft and current nodes under the given rootDnaId
|
||||
// Build WHERE condition for draft nodes
|
||||
const draftWhere: any = {
|
||||
orgRevisionId: draftRevisionId,
|
||||
};
|
||||
if (
|
||||
draftOrgRootId &&
|
||||
(entityClass === OrgChild1 ||
|
||||
entityClass === OrgChild2 ||
|
||||
entityClass === OrgChild3 ||
|
||||
entityClass === OrgChild4)
|
||||
) {
|
||||
draftWhere.orgRootId = draftOrgRootId;
|
||||
} else if (entityClass === OrgRoot) {
|
||||
draftWhere.id = draftOrgRootId;
|
||||
}
|
||||
|
||||
// Build WHERE condition for current nodes
|
||||
const currentWhere: any = {
|
||||
orgRevisionId: currentRevisionId,
|
||||
};
|
||||
if (
|
||||
currentOrgRootId &&
|
||||
(entityClass === OrgChild1 ||
|
||||
entityClass === OrgChild2 ||
|
||||
entityClass === OrgChild3 ||
|
||||
entityClass === OrgChild4)
|
||||
) {
|
||||
currentWhere.orgRootId = currentOrgRootId;
|
||||
} else if (entityClass === OrgRoot) {
|
||||
currentWhere.id = currentOrgRootId;
|
||||
}
|
||||
|
||||
const [draftNodes, currentNodes] = await Promise.all([
|
||||
repository.find({
|
||||
where: {
|
||||
orgRevisionId: draftRevisionId,
|
||||
ancestorDNA: Like(`${rootDnaId}%`),
|
||||
},
|
||||
}),
|
||||
repository.find({
|
||||
where: {
|
||||
orgRevisionId: currentRevisionId,
|
||||
ancestorDNA: Like(`${rootDnaId}%`),
|
||||
},
|
||||
}),
|
||||
repository.find({ where: draftWhere }),
|
||||
repository.find({ where: currentWhere }),
|
||||
]);
|
||||
|
||||
// 2. Build lookup maps for efficient matching by ancestorDNA
|
||||
|
|
@ -8270,37 +8342,71 @@ export class OrganizationController extends Controller {
|
|||
});
|
||||
|
||||
// Map parent IDs based on entity level
|
||||
if (entityClass === OrgChild1 && draft.orgRootId && parentMappings) {
|
||||
newNode.orgRootId = parentMappings.orgRoot.byDraftId.get(draft.orgRootId);
|
||||
} else if (entityClass === OrgChild2) {
|
||||
if (draft.orgRootId && parentMappings) {
|
||||
if (entityClass === OrgChild1 && draft.orgRootId) {
|
||||
if (draft.orgRootId === draftOrgRootId) {
|
||||
newNode.orgRootId = currentOrgRootId;
|
||||
} else if (parentMappings) {
|
||||
newNode.orgRootId = parentMappings.orgRoot.byDraftId.get(draft.orgRootId);
|
||||
}
|
||||
} else if (entityClass === OrgChild2) {
|
||||
if (draft.orgRootId) {
|
||||
if (draft.orgRootId === draftOrgRootId) {
|
||||
newNode.orgRootId = currentOrgRootId;
|
||||
} else if (parentMappings) {
|
||||
newNode.orgRootId = parentMappings.orgRoot.byDraftId.get(draft.orgRootId);
|
||||
}
|
||||
}
|
||||
if (draft.orgChild1Id && parentMappings) {
|
||||
newNode.orgChild1Id = parentMappings.orgChild1.byDraftId.get(draft.orgChild1Id);
|
||||
const mappedChild1Id = parentMappings.orgChild1.byDraftId.get(draft.orgChild1Id);
|
||||
if (mappedChild1Id) {
|
||||
newNode.orgChild1Id = mappedChild1Id;
|
||||
}
|
||||
}
|
||||
} else if (entityClass === OrgChild3) {
|
||||
if (draft.orgRootId && parentMappings) {
|
||||
newNode.orgRootId = parentMappings.orgRoot.byDraftId.get(draft.orgRootId);
|
||||
if (draft.orgRootId) {
|
||||
if (draft.orgRootId === draftOrgRootId) {
|
||||
newNode.orgRootId = currentOrgRootId;
|
||||
} else if (parentMappings) {
|
||||
newNode.orgRootId = parentMappings.orgRoot.byDraftId.get(draft.orgRootId);
|
||||
}
|
||||
}
|
||||
if (draft.orgChild1Id && parentMappings) {
|
||||
newNode.orgChild1Id = parentMappings.orgChild1.byDraftId.get(draft.orgChild1Id);
|
||||
const mappedChild1Id = parentMappings.orgChild1.byDraftId.get(draft.orgChild1Id);
|
||||
if (mappedChild1Id) {
|
||||
newNode.orgChild1Id = mappedChild1Id;
|
||||
}
|
||||
}
|
||||
if (draft.orgChild2Id && parentMappings) {
|
||||
newNode.orgChild2Id = parentMappings.orgChild2.byDraftId.get(draft.orgChild2Id);
|
||||
const mappedChild2Id = parentMappings.orgChild2.byDraftId.get(draft.orgChild2Id);
|
||||
if (mappedChild2Id) {
|
||||
newNode.orgChild2Id = mappedChild2Id;
|
||||
}
|
||||
}
|
||||
} else if (entityClass === OrgChild4) {
|
||||
if (draft.orgRootId && parentMappings) {
|
||||
newNode.orgRootId = parentMappings.orgRoot.byDraftId.get(draft.orgRootId);
|
||||
if (draft.orgRootId) {
|
||||
if (draft.orgRootId === draftOrgRootId) {
|
||||
newNode.orgRootId = currentOrgRootId;
|
||||
} else if (parentMappings) {
|
||||
newNode.orgRootId = parentMappings.orgRoot.byDraftId.get(draft.orgRootId);
|
||||
}
|
||||
}
|
||||
if (draft.orgChild1Id && parentMappings) {
|
||||
newNode.orgChild1Id = parentMappings.orgChild1.byDraftId.get(draft.orgChild1Id);
|
||||
const mappedChild1Id = parentMappings.orgChild1.byDraftId.get(draft.orgChild1Id);
|
||||
if (mappedChild1Id) {
|
||||
newNode.orgChild1Id = mappedChild1Id;
|
||||
}
|
||||
}
|
||||
if (draft.orgChild2Id && parentMappings) {
|
||||
newNode.orgChild2Id = parentMappings.orgChild2.byDraftId.get(draft.orgChild2Id);
|
||||
const mappedChild2Id = parentMappings.orgChild2.byDraftId.get(draft.orgChild2Id);
|
||||
if (mappedChild2Id) {
|
||||
newNode.orgChild2Id = mappedChild2Id;
|
||||
}
|
||||
}
|
||||
if (draft.orgChild3Id && parentMappings) {
|
||||
newNode.orgChild3Id = parentMappings.orgChild3.byDraftId.get(draft.orgChild3Id);
|
||||
const mappedChild3Id = parentMappings.orgChild3.byDraftId.get(draft.orgChild3Id);
|
||||
if (mappedChild3Id) {
|
||||
newNode.orgChild3Id = mappedChild3Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8310,7 +8416,14 @@ export class OrganizationController extends Controller {
|
|||
mapping.byDraftId.set(draft.id, saved.id);
|
||||
}
|
||||
|
||||
return mapping;
|
||||
return {
|
||||
mapping,
|
||||
counts: {
|
||||
deleted: toDelete.length,
|
||||
updated: toUpdate.length,
|
||||
inserted: toInsert.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -8323,7 +8436,7 @@ export class OrganizationController extends Controller {
|
|||
currentPosMasterId: string,
|
||||
draftRevisionId: string,
|
||||
currentRevisionId: string,
|
||||
): Promise<void> {
|
||||
): Promise<{ deleted: number; updated: number; inserted: number }> {
|
||||
// Fetch draft and current positions for this posMaster
|
||||
const [draftPositions, currentPositions] = await Promise.all([
|
||||
queryRunner.manager.find(Position, {
|
||||
|
|
@ -8347,7 +8460,7 @@ export class OrganizationController extends Controller {
|
|||
currentPositions.map((p: any) => p.id),
|
||||
);
|
||||
}
|
||||
return;
|
||||
return { deleted: currentPositions.length, updated: 0, inserted: 0 };
|
||||
}
|
||||
|
||||
// Build maps for tracking
|
||||
|
|
@ -8365,6 +8478,8 @@ export class OrganizationController extends Controller {
|
|||
}
|
||||
|
||||
// UPDATE and INSERT
|
||||
let updatedCount = 0;
|
||||
let insertedCount = 0;
|
||||
for (const draftPos of draftPositions) {
|
||||
const current: any = currentByOrderNo.get(draftPos.orderNo);
|
||||
|
||||
|
|
@ -8380,6 +8495,7 @@ export class OrganizationController extends Controller {
|
|||
positionArea: draftPos.positionArea,
|
||||
isSpecial: draftPos.isSpecial,
|
||||
});
|
||||
updatedCount++;
|
||||
} else {
|
||||
// INSERT new position
|
||||
const newPosition = queryRunner.manager.create(Position, {
|
||||
|
|
@ -8388,7 +8504,10 @@ export class OrganizationController extends Controller {
|
|||
posMasterId: currentPosMasterId,
|
||||
});
|
||||
await queryRunner.manager.save(newPosition);
|
||||
insertedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return { deleted: toDelete.length, updated: updatedCount, inserted: insertedCount };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue