fix เลือกตำแหน่งในสายงานหาย เมื่อมีการเปลี่ยนแปลงข้อมูลตำแหน่งในโครงสร้าง #2505
All checks were successful
Build & Deploy on Dev / build (push) Successful in 57s

This commit is contained in:
harid 2026-05-21 16:51:55 +07:00
parent ba185f8de8
commit 3d01a166a8

View file

@ -3589,6 +3589,8 @@ export class CommandController extends Controller {
positionLevel: string | null; positionLevel: string | null;
posmasterId: string; posmasterId: string;
positionId: string; positionId: string;
posExecutiveId?: string | null;
positionField?: string | null;
commandId?: string | null; commandId?: string | null;
orgRoot?: string | null; orgRoot?: string | null;
orgChild1?: string | null; orgChild1?: string | null;
@ -3685,12 +3687,51 @@ export class CommandController extends Controller {
history.profileSalaryId = data.id; history.profileSalaryId = data.id;
await this.salaryHistoryRepo.save(history, { data: req }); await this.salaryHistoryRepo.save(history, { data: req });
const posMaster = await this.posMasterRepository.findOne({ // STEP 1: หา posMaster ที่จะใช้งานตาม id ที่ส่งมา
let posMaster = await this.posMasterRepository.findOne({
where: { id: item.posmasterId }, where: { id: item.posmasterId },
relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"], relations: {
orgRevision: true,
orgRoot: true,
orgChild1: true,
orgChild2: true,
orgChild3: true,
orgChild4: true,
},
}); });
if (posMaster == null)
// เช็คว่า posMaster ที่หามาอยู่ในโครงสร้างปัจจุบันหรือไม่
const isCurrent =
posMaster?.orgRevision?.orgRevisionIsCurrent === true &&
posMaster?.orgRevision?.orgRevisionIsDraft === false;
// ถ้าไม่อยู่ในโครงสร้างปัจจุบัน ให้หาตัวใหม่จาก ancestorDNA
if (!isCurrent && posMaster?.ancestorDNA) {
posMaster = await this.posMasterRepository.findOne({
where: {
ancestorDNA: posMaster.ancestorDNA,
orgRevision: {
orgRevisionIsCurrent: true,
orgRevisionIsDraft: false,
},
},
relations: {
orgRevision: true,
orgRoot: true,
orgChild1: true,
orgChild2: true,
orgChild3: true,
orgChild4: true,
},
});
}
if (posMaster == null) {
console.error(
`[CommandController] PosMaster not found - posMasterId: ${item.posmasterId}, `
);
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
}
const posMasterOld = await this.posMasterRepository.findOne({ const posMasterOld = await this.posMasterRepository.findOne({
where: { where: {
@ -3716,7 +3757,7 @@ export class CommandController extends Controller {
const checkPosition = await this.positionRepository.find({ const checkPosition = await this.positionRepository.find({
where: { where: {
posMasterId: item.posmasterId, posMasterId: posMaster.id, // ใช้ posMaster ตัวใหม่ (ที่อาจจะเปลี่ยนจาก ancestorDNA)
positionIsSelected: true, positionIsSelected: true,
}, },
}); });
@ -3738,13 +3779,107 @@ export class CommandController extends Controller {
} }
await this.posMasterRepository.save(posMaster); await this.posMasterRepository.save(posMaster);
const positionNew = await this.positionRepository.findOne({ // STEP 2: กำหนด position ใหม่
// Match position ตามลำดับ priority:
// Condition 1: match จาก positionId
// Condition 2: match 7 ฟิลด์ (positionName, posTypeId, posLevelId, positionField, positionArea, positionExecutiveField, posExecutiveId)
// Condition 3: match 3 ฟิลด์ (positionName, posTypeId, posLevelId)
// Fallback: เลือก position แรกใน posMaster
let positionNew: Position | null = null;
// ═══════════════════════════════════════════════════════════
// CONDITION 1: เช็คจาก positionId ตรง
// ═══════════════════════════════════════════════════════════
if (item.positionId) {
const positionById = await this.positionRepository.findOne({
where: { where: {
id: item.positionId, id: item.positionId,
posMasterId: item.posmasterId, posMasterId: posMaster.id, // ต้องอยู่ใน posMaster ที่ถูกต้อง
}, },
relations: ["posExecutive"], relations: ["posExecutive"],
}); });
if (positionById) {
positionNew = positionById;
}
}
// ═══════════════════════════════════════════════════════════
// CONDITION 2: Match 7 ฟิลด์ (ถ้า Condition 1 ไม่ match)
// ═══════════════════════════════════════════════════════════
if (!positionNew && item.positionName && item.positionType && item.positionLevel) {
// สร้าง where clause แบบ dynamic - ใส่เฉพาะฟิลด์ที่มีค่า
const whereCondition: any = {
posMasterId: posMaster.id,
positionName: item.positionName,
posTypeId: item.positionType, // positionType = posTypeId
posLevelId: item.positionLevel, // positionLevel = posLevelId
};
// เพิ่มเฉพาะฟิลด์ที่มีค่า (ไม่ใช่ null, undefined, หรือ string ว่าง)
if (item.positionField) {
whereCondition.positionField = item.positionField;
}
if (item.posExecutiveId) {
whereCondition.posExecutiveId = item.posExecutiveId;
}
if (item.positionExecutiveField) {
whereCondition.positionExecutiveField = item.positionExecutiveField;
}
if (item.positionArea) {
whereCondition.positionArea = item.positionArea;
}
const positionBy7Fields = await this.positionRepository.findOne({
where: whereCondition,
relations: ["posExecutive"],
});
if (positionBy7Fields) {
positionNew = positionBy7Fields;
}
}
// ═══════════════════════════════════════════════════════════
// CONDITION 3: Match 3 ฟิลด์ (ถ้า Condition 2 ไม่ match)
// ═══════════════════════════════════════════════════════════
if (!positionNew && item.positionName && item.positionType && item.positionLevel) {
const positionBy3Fields = await this.positionRepository.findOne({
where: {
posMasterId: posMaster.id,
positionName: item.positionName,
posTypeId: item.positionType, // positionType = posTypeId
posLevelId: item.positionLevel, // positionLevel = posLevelId
},
relations: ["posExecutive"],
});
if (positionBy3Fields) {
positionNew = positionBy3Fields;
}
}
// // ═══════════════════════════════════════════════════════════
// // FALLBACK: ถ้าทั้ง 3 ไม่ match ให้เลือก position แรกใน posMaster
// // ═══════════════════════════════════════════════════════════
// if (!positionNew) {
// const fallbackPositions = await this.positionRepository.find({
// where: {
// posMasterId: posMaster.id,
// },
// relations: ["posExecutive"],
// order: {
// orderNo: "ASC",
// },
// take: 1,
// });
// if (fallbackPositions.length > 0) {
// positionNew = fallbackPositions[0];
// }
// }
// ถ้าไม่ใช่ตำแหน่งนั่งทับ (isSit = false) ถึงจะอัพเดทตำแหน่งในทะเบียนประวัติ // ถ้าไม่ใช่ตำแหน่งนั่งทับ (isSit = false) ถึงจะอัพเดทตำแหน่งในทะเบียนประวัติ
if (positionNew != null) { if (positionNew != null) {
positionNew.positionIsSelected = true; positionNew.positionIsSelected = true;
@ -3984,6 +4119,8 @@ export class CommandController extends Controller {
isLeave: boolean; isLeave: boolean;
leaveReason?: string | null; leaveReason?: string | null;
dateLeave?: Date | null; dateLeave?: Date | null;
posExecutiveId?: string | null;
positionField?: string | null;
commandId?: string | null; commandId?: string | null;
isGovernment?: boolean | null; isGovernment?: boolean | null;
orgRoot?: string | null; orgRoot?: string | null;
@ -4207,10 +4344,45 @@ export class CommandController extends Controller {
//ปลดตำแหน่งเดิมที่ไม่ถูกปลดออกจากกิ่งครั้งเมื่อออกคำสั่งพักราชการหรือออกราชการไว้ //ปลดตำแหน่งเดิมที่ไม่ถูกปลดออกจากกิ่งครั้งเมื่อออกคำสั่งพักราชการหรือออกราชการไว้
await removeProfileInOrganize(profile.id, "OFFICER"); await removeProfileInOrganize(profile.id, "OFFICER");
//ปั๊มตำแหน่งใหม่ //ปั๊มตำแหน่งใหม่
const posMaster = await this.posMasterRepository.findOne({ // หา posMaster และเช็ค orgRevisionIsCurrent
let posMaster = await this.posMasterRepository.findOne({
where: { id: item.posmasterId?.toString() }, where: { id: item.posmasterId?.toString() },
relations: {
orgRevision: true,
orgRoot: true,
orgChild1: true,
orgChild2: true,
orgChild3: true,
orgChild4: true,
},
}); });
// เช็คว่า posMaster ที่หามาอยู่ในโครงสร้างปัจจุบันหรือไม่
const isCurrent =
posMaster?.orgRevision?.orgRevisionIsCurrent === true &&
posMaster?.orgRevision?.orgRevisionIsDraft === false;
// ถ้าไม่อยู่ในโครงสร้างปัจจุบัน ให้หาตัวใหม่จาก ancestorDNA
if (!isCurrent && posMaster?.ancestorDNA) {
posMaster = await this.posMasterRepository.findOne({
where: {
ancestorDNA: posMaster.ancestorDNA,
orgRevision: {
orgRevisionIsCurrent: true,
orgRevisionIsDraft: false,
},
},
relations: {
orgRevision: true,
orgRoot: true,
orgChild1: true,
orgChild2: true,
orgChild3: true,
orgChild4: true,
},
});
}
if (posMaster) { if (posMaster) {
const checkPosition = await this.positionRepository.find({ const checkPosition = await this.positionRepository.find({
where: { where: {
@ -4230,11 +4402,77 @@ export class CommandController extends Controller {
// posMaster.conditionReason = _null; // posMaster.conditionReason = _null;
// posMaster.isCondition = false; // posMaster.isCondition = false;
await this.posMasterRepository.save(posMaster); await this.posMasterRepository.save(posMaster);
const positionNew = await this.positionRepository.findOne({
// Match position ตามลำดับ priority
let positionNew: Position | null = null;
// CONDITION 1: Match 7 ฟิลด์ (ไม่มี positionId ใน body สำหรับกรณีพักราชการ)
if (item.positionNameNew && item.positionTypeNew && item.positionLevelNew) {
const whereCondition: any = {
posMasterId: posMaster.id,
positionName: item.positionNameNew,
posTypeId: item.positionTypeNew,
posLevelId: item.positionLevelNew,
};
if (item.positionField) {
whereCondition.positionField = item.positionField;
}
if (item.posExecutiveId) {
whereCondition.posExecutiveId = item.posExecutiveId;
}
if (item.positionExecutiveField) {
whereCondition.positionExecutiveField = item.positionExecutiveField;
}
if (item.positionArea) {
whereCondition.positionArea = item.positionArea;
}
const positionBy7Fields = await this.positionRepository.findOne({
where: whereCondition,
relations: ["posExecutive"],
});
if (positionBy7Fields) {
positionNew = positionBy7Fields;
}
}
// CONDITION 2: Match 3 ฟิลด์ (ถ้า Condition 1 ไม่ match)
if (!positionNew && item.positionNameNew && item.positionTypeNew && item.positionLevelNew) {
const positionBy3Fields = await this.positionRepository.findOne({
where: { where: {
posMasterId: posMaster.id, posMasterId: posMaster.id,
positionName: item.positionNameNew,
posTypeId: item.positionTypeNew,
posLevelId: item.positionLevelNew,
}, },
relations: ["posExecutive"],
}); });
if (positionBy3Fields) {
positionNew = positionBy3Fields;
}
}
// // FALLBACK: เลือก position แรก (ถ้าไม่เจอทั้ง 2 condition)
// if (!positionNew) {
// const fallbackPositions = await this.positionRepository.find({
// where: {
// posMasterId: posMaster.id,
// },
// relations: ["posExecutive"],
// order: {
// orderNo: "ASC",
// },
// take: 1,
// });
// if (fallbackPositions.length > 0) {
// positionNew = fallbackPositions[0];
// }
// }
if (positionNew) { if (positionNew) {
positionNew.positionIsSelected = true; positionNew.positionIsSelected = true;
await this.positionRepository.save(positionNew, { data: req }); await this.positionRepository.save(positionNew, { data: req });
@ -6329,6 +6567,13 @@ export class CommandController extends Controller {
bodyPosition?: { bodyPosition?: {
posmasterId: string; posmasterId: string;
positionId: string; positionId: string;
positionName: string;
posTypeId: string;
posLevelId: string;
posExecutiveId: string | null;
positionField: string | null;
positionExecutiveField: string | null;
positionArea: string | null;
} | null; } | null;
bodyMarry?: { bodyMarry?: {
marry?: boolean | null; marry?: boolean | null;
@ -6948,8 +7193,12 @@ export class CommandController extends Controller {
}); });
} }
if (posMaster == null) if (posMaster == null) {
console.error(
`[CreateOfficerProfile] not found posMasterId: ${item.bodyPosition.posmasterId}`
);
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
}
// STEP 2: เคลียร์ข้อมูลตำแหน่งเก่าที่ครองอยู่ ในโครงสร้างปัจจุบัน // STEP 2: เคลียร์ข้อมูลตำแหน่งเก่าที่ครองอยู่ ในโครงสร้างปัจจุบัน
const posMasterOld = await this.posMasterRepository.findOne({ const posMasterOld = await this.posMasterRepository.findOne({
@ -7003,40 +7252,104 @@ export class CommandController extends Controller {
await this.posMasterRepository.save(posMaster); await this.posMasterRepository.save(posMaster);
// STEP 5: กำหนด position ใหม่ // STEP 5: กำหนด position ใหม่
// เช็คว่า posMaster เปลี่ยนจากเก่าเป็นใหม่หรือไม่ // Match position ตามลำดับ priority:
const originalPosMasterId = item.bodyPosition.posmasterId; // Condition 1: match จาก positionId
const isPosMasterChanged = originalPosMasterId !== posMaster.id; // Condition 2: match 7 ฟิลด์ (positionName, posTypeId, posLevelId, positionField, positionArea, positionExecutiveField, posExecutiveId)
// Condition 3: match 3 ฟิลด์ (positionName, posTypeId, posLevelId)
// Fallback: เลือก position แรกใน posMaster
let positionNew = null; let positionNew: Position | null = null;
if (isPosMasterChanged) { // ═══════════════════════════════════════════════════════════
// posMaster เปลี่ยน ต้องหา position ใหม่จากคุณสมบัติของ position เก่า // CONDITION 1: เช็คจาก positionId ตรง
// 1. หา position เก่าจาก id ที่ส่งมา // ═══════════════════════════════════════════════════════════
const positionOld = await this.positionRepository.findOne({ if (item.bodyPosition?.positionId) {
where: { id: item.bodyPosition.positionId }, const positionById = await this.positionRepository.findOne({
});
if (positionOld) {
// 2. ใช้ posTypeId + posLevelId + positionName หา position ใหม่ใน posMaster ตัวใหม่
positionNew = await this.positionRepository.findOne({
where: {
posMasterId: posMaster.id, // ใช้ posMaster ตัวใหม่
posTypeId: positionOld.posTypeId,
posLevelId: positionOld.posLevelId,
positionName: positionOld.positionName,
},
});
}
} else {
// posMaster ไม่เปลี่ยน - ใช้วิธีเดิม
positionNew = await this.positionRepository.findOne({
where: { where: {
id: item.bodyPosition.positionId, id: item.bodyPosition.positionId,
posMasterId: posMaster.id, posMasterId: posMaster.id, // ต้องอยู่ใน posMaster ที่ถูกต้อง
}, },
relations: ["posExecutive"], relations: ["posExecutive"],
}); });
if (positionById) {
positionNew = positionById;
} }
}
// ═══════════════════════════════════════════════════════════
// CONDITION 2: Match 7 ฟิลด์ (ถ้า Condition 1 ไม่ match)
// ═══════════════════════════════════════════════════════════
if (!positionNew && item.bodyPosition) {
// สร้าง where clause แบบ dynamic - ใส่เฉพาะฟิลด์ที่ไม่ใช่ null
const whereCondition: any = {
posMasterId: posMaster.id,
positionName: item.bodyPosition.positionName,
posTypeId: item.bodyPosition.posTypeId,
posLevelId: item.bodyPosition.posLevelId,
};
if (item.bodyPosition.positionField) {
whereCondition.positionField = item.bodyPosition.positionField;
}
if (item.bodyPosition.posExecutiveId) {
whereCondition.posExecutiveId = item.bodyPosition.posExecutiveId;
}
if (item.bodyPosition.positionExecutiveField) {
whereCondition.positionExecutiveField = item.bodyPosition.positionExecutiveField;
}
if (item.bodyPosition.positionArea) {
whereCondition.positionArea = item.bodyPosition.positionArea;
}
const positionBy7Fields = await this.positionRepository.findOne({
where: whereCondition,
relations: ["posExecutive"],
});
if (positionBy7Fields) {
positionNew = positionBy7Fields;
}
}
// ═══════════════════════════════════════════════════════════
// CONDITION 3: Match 3 ฟิลด์ (ถ้า Condition 2 ไม่ match)
// ═══════════════════════════════════════════════════════════
if (!positionNew && item.bodyPosition) {
const positionBy3Fields = await this.positionRepository.findOne({
where: {
posMasterId: posMaster.id,
positionName: item.bodyPosition.positionName,
posTypeId: item.bodyPosition.posTypeId,
posLevelId: item.bodyPosition.posLevelId,
},
relations: ["posExecutive"],
});
if (positionBy3Fields) {
positionNew = positionBy3Fields;
}
}
// // ═══════════════════════════════════════════════════════════
// // FALLBACK: ถ้าทั้ง 3 ไม่ match ให้เลือก position แรกใน posMaster
// // ═══════════════════════════════════════════════════════════
// if (!positionNew) {
// const fallbackPositions = await this.positionRepository.find({
// where: {
// posMasterId: posMaster.id,
// },
// relations: ["posExecutive"],
// order: {
// orderNo: "ASC",
// },
// take: 1,
// });
// if (fallbackPositions.length > 0) {
// positionNew = fallbackPositions[0];
// }
// }
// ถ้าไม่ใช่ตำแหน่งนั่งทับ (isSit = false) ถึงจะอัพเดทตำแหน่งในทะเบียนประวัติ // ถ้าไม่ใช่ตำแหน่งนั่งทับ (isSit = false) ถึงจะอัพเดทตำแหน่งในทะเบียนประวัติ
if (positionNew != null) { if (positionNew != null) {