fix save history posMaster null

This commit is contained in:
Warunee Tamkoo 2026-05-06 17:09:55 +07:00
parent a532fcf23d
commit ba7a2315cc

View file

@ -8291,6 +8291,7 @@ export class OrganizationController extends Controller {
if (posMasterDraft.length <= 0) { if (posMasterDraft.length <= 0) {
// Fetch current positions // Fetch current positions
const posMasterCurrent = await this.posMasterRepository.find({ const posMasterCurrent = await this.posMasterRepository.find({
relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"],
where: [ where: [
{ orgRevisionId: currentRevisionId, orgRootId: In(currentOrgIds.orgRoot) }, { orgRevisionId: currentRevisionId, orgRootId: In(currentOrgIds.orgRoot) },
{ orgRevisionId: currentRevisionId, orgChild1Id: In(currentOrgIds.orgChild1) }, { orgRevisionId: currentRevisionId, orgChild1Id: In(currentOrgIds.orgChild1) },
@ -8313,7 +8314,34 @@ export class OrganizationController extends Controller {
const deleteHistoryOps = posMasterCurrent.map((pos) => ({ const deleteHistoryOps = posMasterCurrent.map((pos) => ({
posMasterDnaId: pos.ancestorDNA, posMasterDnaId: pos.ancestorDNA,
profileId: null, profileId: null,
pm: null, pm: {
prefix: null,
firstName: null,
lastName: null,
position: null,
posType: null,
posLevel: null,
posExecutive: null,
profileId: null,
shortName: pos
? [
pos.orgChild4?.orgChild4ShortName,
pos.orgChild3?.orgChild3ShortName,
pos.orgChild2?.orgChild2ShortName,
pos.orgChild1?.orgChild1ShortName,
pos.orgRoot?.orgRootShortName,
].find((s: string | undefined) => typeof s === "string" && s.trim().length > 0) ??
null
: null,
posMasterNoPrefix: pos.posMasterNoPrefix ?? null,
posMasterNo: pos.posMasterNo != null ? String(pos.posMasterNo) : null,
posMasterNoSuffix: pos.posMasterNoSuffix ?? null,
rootDnaId: pos?.orgRoot?.ancestorDNA ?? null,
child1DnaId: pos?.orgChild1?.ancestorDNA ?? null,
child2DnaId: pos?.orgChild2?.ancestorDNA ?? null,
child3DnaId: pos?.orgChild3?.ancestorDNA ?? null,
child4DnaId: pos?.orgChild4?.ancestorDNA ?? null,
} as SavePosMasterHistory,
})); }));
await BatchSavePosMasterHistoryOfficer(queryRunner, deleteHistoryOps); await BatchSavePosMasterHistoryOfficer(queryRunner, deleteHistoryOps);
} }
@ -8348,6 +8376,7 @@ export class OrganizationController extends Controller {
if (nextHolderIds.length > 0) { if (nextHolderIds.length > 0) {
// FIX: Fetch positions first before updating (to avoid race condition) // FIX: Fetch positions first before updating (to avoid race condition)
const posMastersToUpdate = await queryRunner.manager.find(PosMaster, { const posMastersToUpdate = await queryRunner.manager.find(PosMaster, {
relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"],
where: { where: {
orgRevisionId: currentRevisionId, orgRevisionId: currentRevisionId,
current_holderId: In(nextHolderIds), current_holderId: In(nextHolderIds),
@ -8360,7 +8389,34 @@ export class OrganizationController extends Controller {
.map((pos) => ({ .map((pos) => ({
posMasterDnaId: pos.ancestorDNA, posMasterDnaId: pos.ancestorDNA,
profileId: null, profileId: null,
pm: null, pm: {
prefix: null,
firstName: null,
lastName: null,
position: null,
posType: null,
posLevel: null,
posExecutive: null,
profileId: null,
shortName: pos
? [
pos.orgChild4?.orgChild4ShortName,
pos.orgChild3?.orgChild3ShortName,
pos.orgChild2?.orgChild2ShortName,
pos.orgChild1?.orgChild1ShortName,
pos.orgRoot?.orgRootShortName,
].find((s: string | undefined) => typeof s === "string" && s.trim().length > 0) ??
null
: null,
posMasterNoPrefix: pos.posMasterNoPrefix ?? null,
posMasterNo: pos.posMasterNo != null ? String(pos.posMasterNo) : null,
posMasterNoSuffix: pos.posMasterNoSuffix ?? null,
rootDnaId: pos?.orgRoot?.ancestorDNA ?? null,
child1DnaId: pos?.orgChild1?.ancestorDNA ?? null,
child2DnaId: pos?.orgChild2?.ancestorDNA ?? null,
child3DnaId: pos?.orgChild3?.ancestorDNA ?? null,
child4DnaId: pos?.orgChild4?.ancestorDNA ?? null,
} as SavePosMasterHistory,
})); }));
await BatchSavePosMasterHistoryOfficer(queryRunner, historyOps); await BatchSavePosMasterHistoryOfficer(queryRunner, historyOps);
@ -8377,6 +8433,7 @@ export class OrganizationController extends Controller {
// 2.2 Fetch current positions for comparison // 2.2 Fetch current positions for comparison
const posMasterCurrent = await this.posMasterRepository.find({ const posMasterCurrent = await this.posMasterRepository.find({
relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"],
where: [ where: [
{ orgRevisionId: currentRevisionId, orgRootId: In(currentOrgIds.orgRoot) }, { orgRevisionId: currentRevisionId, orgRootId: In(currentOrgIds.orgRoot) },
{ orgRevisionId: currentRevisionId, orgChild1Id: In(currentOrgIds.orgChild1) }, { orgRevisionId: currentRevisionId, orgChild1Id: In(currentOrgIds.orgChild1) },
@ -8406,7 +8463,34 @@ export class OrganizationController extends Controller {
const deleteHistoryOps = toDelete.map((pos) => ({ const deleteHistoryOps = toDelete.map((pos) => ({
posMasterDnaId: pos.ancestorDNA, posMasterDnaId: pos.ancestorDNA,
profileId: null, profileId: null,
pm: null, pm: {
prefix: null,
firstName: null,
lastName: null,
position: null,
posType: null,
posLevel: null,
posExecutive: null,
profileId: null,
shortName: pos
? [
pos.orgChild4?.orgChild4ShortName,
pos.orgChild3?.orgChild3ShortName,
pos.orgChild2?.orgChild2ShortName,
pos.orgChild1?.orgChild1ShortName,
pos.orgRoot?.orgRootShortName,
].find((s: string | undefined) => typeof s === "string" && s.trim().length > 0) ??
null
: null,
posMasterNoPrefix: pos.posMasterNoPrefix ?? null,
posMasterNo: pos.posMasterNo != null ? String(pos.posMasterNo) : null,
posMasterNoSuffix: pos.posMasterNoSuffix ?? null,
rootDnaId: pos?.orgRoot?.ancestorDNA ?? null,
child1DnaId: pos?.orgChild1?.ancestorDNA ?? null,
child2DnaId: pos?.orgChild2?.ancestorDNA ?? null,
child3DnaId: pos?.orgChild3?.ancestorDNA ?? null,
child4DnaId: pos?.orgChild4?.ancestorDNA ?? null,
} as SavePosMasterHistory,
})); }));
await BatchSavePosMasterHistoryOfficer(queryRunner, deleteHistoryOps); await BatchSavePosMasterHistoryOfficer(queryRunner, deleteHistoryOps);
} }
@ -8900,6 +8984,7 @@ export class OrganizationController extends Controller {
where: { where: {
posMasterId: In(currentPosMasterIds), posMasterId: In(currentPosMasterIds),
}, },
relations: ["posType", "posLevel", "posExecutive"],
}), }),
]); ]);
@ -8927,6 +9012,12 @@ export class OrganizationController extends Controller {
const allToInsert: Array<any> = []; const allToInsert: Array<any> = [];
const profileUpdates: Map<string, any> = new Map(); const profileUpdates: Map<string, any> = new Map();
// Collect position and posMaster data for delete history tracking
const deleteHistoryData: Array<{
position: any;
posMaster: PosMaster;
}> = [];
// Create a map for quick lookup of draft PosMasters with relations // Create a map for quick lookup of draft PosMasters with relations
const draftPosMasterMap = new Map(draftPosMasters.map((pm: PosMaster) => [pm.id, pm])); const draftPosMasterMap = new Map(draftPosMasters.map((pm: PosMaster) => [pm.id, pm]));
@ -8946,6 +9037,11 @@ export class OrganizationController extends Controller {
if (draftPositions.length === 0) { if (draftPositions.length === 0) {
allToDelete.push(...currentPositions.map((p: any) => p.id)); allToDelete.push(...currentPositions.map((p: any) => p.id));
allToDeleteHistory.push(...currentPositions.map((p: any) => p.ancestorDNA)); allToDeleteHistory.push(...currentPositions.map((p: any) => p.ancestorDNA));
// Collect data for history tracking
const pm = draftPosMasterMap.get(draftPosMasterId) as PosMaster;
for (const pos of currentPositions) {
deleteHistoryData.push({ position: pos, posMaster: pm });
}
continue; continue;
} }
@ -8954,10 +9050,13 @@ export class OrganizationController extends Controller {
const draftOrderNos = new Set(draftPositions.map((p: any) => p.orderNo)); const draftOrderNos = new Set(draftPositions.map((p: any) => p.orderNo));
// Mark for deletion: current positions not in draft (by orderNo) // Mark for deletion: current positions not in draft (by orderNo)
const pm = draftPosMasterMap.get(draftPosMasterId) as PosMaster;
for (const currentPos of currentPositions) { for (const currentPos of currentPositions) {
if (!draftOrderNos.has(currentPos.orderNo)) { if (!draftOrderNos.has(currentPos.orderNo)) {
allToDelete.push(currentPos.id); allToDelete.push(currentPos.id);
allToDeleteHistory.push(currentPos.ancestorDNA); allToDeleteHistory.push(currentPos.ancestorDNA);
// Collect data for history tracking
deleteHistoryData.push({ position: currentPos, posMaster: pm });
} }
} }
@ -9063,10 +9162,36 @@ export class OrganizationController extends Controller {
// Bulk DELETE // Bulk DELETE
if (allToDelete.length > 0) { if (allToDelete.length > 0) {
await queryRunner.manager.delete(Position, allToDelete); await queryRunner.manager.delete(Position, allToDelete);
const deleteOps = allToDeleteHistory.map((ancestorDNA) => ({ const deleteOps = deleteHistoryData.map(({ position, posMaster }) => ({
posMasterDnaId: ancestorDNA, posMasterDnaId: position.ancestorDNA,
profileId: null, profileId: null,
pm: null, pm: {
prefix: null,
firstName: null,
lastName: null,
position: null,
posType: null,
posLevel: null,
posExecutive: null,
profileId: null,
rootDnaId: posMaster?.orgRoot?.ancestorDNA ?? null,
child1DnaId: posMaster?.orgChild1?.ancestorDNA ?? null,
child2DnaId: posMaster?.orgChild2?.ancestorDNA ?? null,
child3DnaId: posMaster?.orgChild3?.ancestorDNA ?? null,
child4DnaId: posMaster?.orgChild4?.ancestorDNA ?? null,
shortName: posMaster
? [
posMaster.orgChild4?.orgChild4ShortName,
posMaster.orgChild3?.orgChild3ShortName,
posMaster.orgChild2?.orgChild2ShortName,
posMaster.orgChild1?.orgChild1ShortName,
posMaster.orgRoot?.orgRootShortName,
].find((s) => typeof s === "string" && s.trim().length > 0) ?? null
: null,
posMasterNoPrefix: posMaster?.posMasterNoPrefix ?? null,
posMasterNo: posMaster?.posMasterNo != null ? String(posMaster.posMasterNo) : null,
posMasterNoSuffix: posMaster?.posMasterNoSuffix ?? null,
},
})); }));
await BatchSavePosMasterHistoryOfficer(queryRunner, deleteOps); await BatchSavePosMasterHistoryOfficer(queryRunner, deleteOps);
deletedCount = allToDelete.length; deletedCount = allToDelete.length;