diff --git a/src/controllers/SalaryPeriodController.ts b/src/controllers/SalaryPeriodController.ts index fbeae26..22db76e 100644 --- a/src/controllers/SalaryPeriodController.ts +++ b/src/controllers/SalaryPeriodController.ts @@ -2722,99 +2722,107 @@ export class SalaryPeriodController extends Controller { }), ); if (salaryPeriod.period != "SPECIAL") { - console.log(`step1`); - await Promise.all( - orgProfiles.map(async (profile: any) => { - let group = "GROUP1"; - if ( - (profile.posType == "ทั่วไป" && profile.posLevel == "ทักษะพิเศษ") || - (profile.posType == "วิชาการ" && profile.posLevel == "เชี่ยวชาญ") || - (profile.posType == "วิชาการ" && profile.posLevel == "ทรงคุณวุฒิ") || - (profile.posType == "อำนวยการ" && profile.posLevel == "สูง") || - (profile.posType == "บริหาร" && profile.posLevel == "ต้น") || - (profile.posType == "บริหาร" && profile.posLevel == "สูง") - ) { - group = "GROUP2"; - } - console.log(`step2`); - const salaryOrgNew = await this.salaryOrgRepository.findOne({ - where: { - salaryPeriodId: salaryPeriod.id, - rootId: profile.rootId, - snapshot: snapshot, - group: group, - }, - }); - console.log(`step3`); - const profilesToSave: SalaryProfile[] = []; - if (salaryOrgNew != null) { - console.log(`step4`); - let salaryProfileNew = Object.assign(new SalaryProfile(), profile); - delete salaryProfileNew.id; - - const beforeSalaryProfileNew = structuredClone(salaryProfileNew); - - salaryProfileNew.salaryOrgId = salaryOrgNew.id; - salaryProfileNew.revisionId = salaryPeriod.revisionId; - salaryProfileNew.createdUserId = request.user.sub; - salaryProfileNew.createdFullName = request.user.name; - salaryProfileNew.lastUpdateUserId = request.user.sub; - salaryProfileNew.lastUpdateFullName = request.user.name; - salaryProfileNew.createdAt = new Date(); - salaryProfileNew.lastUpdatedAt = new Date(); - - if (snapshot == "SNAP2") { - console.log(`step5`); - try{ - // const salaryOrgOld = await this.salaryOrgRepository.find({ - // where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, - // }); - // console.log(`ก่อนหา salaryOld`); - // const salaryOld = await this.salaryProfileRepository.findOne({ - // where: { - // citizenId: salaryProfileNew.citizenId, - // salaryOrgId: In(salaryOrgOld.map((x) => x.id)), - // }, - // }); - const salaryOld = await this.salaryProfileRepository - .createQueryBuilder("profile") - .innerJoin("profile.salaryOrg", "org") - .where("org.salaryPeriodId = :periodId", { periodId: salaryPeriod.id }) - .andWhere("org.snapshot = :snapshot", { snapshot: "SNAP1" }) - .andWhere("profile.citizenId = :citizenId", { citizenId: salaryProfileNew.citizenId }) - .getOne(); - - salaryProfileNew.type = salaryOld == null ? "PENDING" : salaryOld.type; - salaryProfileNew.amount = salaryOld == null ? 0 : salaryOld.amount; - salaryProfileNew.amountSpecial = salaryOld == null ? 0 : salaryOld.amountSpecial; - salaryProfileNew.amountUse = salaryOld == null ? 0 : salaryOld.amountUse; - salaryProfileNew.positionSalaryAmount = - salaryOld == null ? 0 : salaryOld.positionSalaryAmount; - salaryProfileNew.remark = salaryOld == null ? null : salaryOld.remark; - salaryProfileNew.isNext = salaryOld == null ? false : salaryOld.isNext; - salaryProfileNew.isSpecial = salaryOld == null ? false : salaryOld.isSpecial; - salaryProfileNew.isReserve = salaryOld == null ? false : salaryOld.isReserve; - salaryProfileNew.isRetired = salaryOld == null ? false : salaryOld.isRetired; - salaryProfileNew.isGood = salaryOld == null ? false : salaryOld.isGood; - } catch (err) { - console.error(`❌ error processing employee:`, err); - } - } - profilesToSave.push(salaryProfileNew); - console.log(`step6`); - // console.log( - // `✅ [SNAP: ${snapshot}] Push SalaryProfile: ${salaryProfileNew.citizenId} (${salaryProfileNew.fullName ?? "-"})`, - // ); - // await this.salaryProfileRepository.save(salaryProfileNew, { data: request }); - await this.salaryProfileRepository.save(profilesToSave, { chunk: 100, data: request }); - setLogDataDiff(request, { before: beforeSalaryProfileNew, after: salaryProfileNew }); - } else { - console.warn(`⚠️ [SNAP: ${snapshot}] ไม่พบ salaryOrg สำหรับ rootId: ${profile.rootId}`); - } - }), + //console.log(`step1`); + console.time("⏱ Step1: Load SalaryOrg (New)"); + const salaryOrgList = await this.salaryOrgRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot }, + }); + const salaryOrgMap = new Map( + salaryOrgList.map((org) => [`${org.rootId}-${org.group}`, org]) ); + console.timeEnd("⏱ Step1: Load SalaryOrg (New)"); + + console.time("⏱ Step2: Load SalaryProfileOld (SNAP1)"); + let salaryOldMap = new Map(); + if (snapshot === "SNAP2") { + const salaryOldList = await this.salaryProfileRepository + .createQueryBuilder("profile") + .innerJoin("profile.salaryOrg", "org") + .where("org.salaryPeriodId = :periodId", { periodId: salaryPeriod.id }) + .andWhere("org.snapshot = :snapshot", { snapshot: "SNAP1" }) + .getMany(); + + salaryOldMap = new Map( + salaryOldList.map((item) => [item.citizenId, item]) + ); + } + console.timeEnd("⏱ Step2: Load SalaryProfileOld (SNAP1)"); + + console.time("⏱ Step3: Process Profiles"); + + const allProfilesToSave: SalaryProfile[] = []; + + for (const profile of orgProfiles) { + let group = "GROUP1"; + const { posType, posLevel } = profile; + + if ( + (posType === "ทั่วไป" && posLevel === "ทักษะพิเศษ") || + (posType === "วิชาการ" && ["เชี่ยวชาญ", "ทรงคุณวุฒิ"].includes(posLevel)) || + (posType === "อำนวยการ" && posLevel === "สูง") || + (posType === "บริหาร" && ["ต้น", "สูง"].includes(posLevel)) + ) { + group = "GROUP2"; + } + + const salaryOrgNew = salaryOrgMap.get(`${profile.rootId}-${group}`); + if (!salaryOrgNew) { + console.warn(`⚠️ [SNAP: ${snapshot}] ไม่พบ salaryOrg สำหรับ rootId: ${profile.rootId}`); + continue; + } + + const salaryProfileNew = Object.assign(new SalaryProfile(), profile); + delete salaryProfileNew.id; + + salaryProfileNew.salaryOrgId = salaryOrgNew.id; + salaryProfileNew.revisionId = salaryPeriod.revisionId; + salaryProfileNew.createdUserId = request.user.sub; + salaryProfileNew.createdFullName = request.user.name; + salaryProfileNew.lastUpdateUserId = request.user.sub; + salaryProfileNew.lastUpdateFullName = request.user.name; + salaryProfileNew.createdAt = new Date(); + salaryProfileNew.lastUpdatedAt = new Date(); + + if (snapshot === "SNAP2") { + const salaryOld = salaryOldMap.get(salaryProfileNew.citizenId); + salaryProfileNew.type = salaryOld?.type ?? "PENDING"; + salaryProfileNew.amount = salaryOld?.amount ?? 0; + salaryProfileNew.amountSpecial = salaryOld?.amountSpecial ?? 0; + salaryProfileNew.amountUse = salaryOld?.amountUse ?? 0; + salaryProfileNew.positionSalaryAmount = salaryOld?.positionSalaryAmount ?? 0; + salaryProfileNew.remark = salaryOld?.remark ?? null; + salaryProfileNew.isNext = salaryOld?.isNext ?? false; + salaryProfileNew.isSpecial = salaryOld?.isSpecial ?? false; + salaryProfileNew.isReserve = salaryOld?.isReserve ?? false; + salaryProfileNew.isRetired = salaryOld?.isRetired ?? false; + salaryProfileNew.isGood = salaryOld?.isGood ?? false; + } + + const beforeSalaryProfileNew = structuredClone(salaryProfileNew); + setLogDataDiff(request, { before: beforeSalaryProfileNew, after: salaryProfileNew }); + allProfilesToSave.push(salaryProfileNew); + } + + console.timeEnd("⏱ Step3: Process Profiles"); + + console.time("⏱ Step4: Save All Profiles"); + // await this.salaryProfileRepository.save(allProfilesToSave, { chunk: 500, data: request }); + + await this.salaryProfileRepository + .createQueryBuilder() + .insert() + .into(SalaryProfile) + .values(allProfilesToSave) + .orIgnore() + .execute(); + console.timeEnd("⏱ Step4: Save All Profiles"); + + console.timeEnd("⏱ TOTAL SalaryProfile Process"); + + //**********************/ console.log("mlength", orgProfileEmployees.length); // const profilesEmpToSave: SalaryProfileEmployee[] = []; + console.time("⏱ SalaryProfileEmployee - Total Time"); await Promise.all( orgProfileEmployees.map(async (profile: any) => { const salaryOrgNew = await this.salaryOrgEmployeeRepository.findOne({ @@ -2825,9 +2833,9 @@ export class SalaryPeriodController extends Controller { group: "GROUP1", }, }); - console.log(`step7`); + //console.log(`step7`); if (salaryOrgNew != null) { - console.log(`step8`); + //console.log(`step8`); let salaryProfileNew = Object.assign(new SalaryProfileEmployee(), profile); delete salaryProfileNew.id; const beforeSalaryProfileNew = structuredClone(salaryProfileNew); @@ -2842,7 +2850,7 @@ export class SalaryPeriodController extends Controller { salaryProfileNew.lastUpdatedAt = new Date(); if (snapshot == "SNAP2") { - console.log(`step9`); + //console.log(`step9`); const salaryOrgOld = await this.salaryOrgEmployeeRepository.find({ where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, }); @@ -2876,10 +2884,10 @@ export class SalaryPeriodController extends Controller { salaryProfileNew.isGood = salaryOld == null ? false : salaryOld.isGood; } // profilesEmpToSave.push(salaryProfileNew); - console.log(`step10`); - console.log( - `✅ [SNAP: ${snapshot}] Push SalaryProfileEmployee: ${salaryProfileNew.citizenId} (${salaryProfileNew.fullName ?? "-"})`, - ); + //console.log(`step10`); + // console.log( + // `✅ [SNAP: ${snapshot}] Push SalaryProfileEmployee: ${salaryProfileNew.citizenId} (${salaryProfileNew.fullName ?? "-"})`, + // ); await this.salaryProfileEmployeeRepository.save(salaryProfileNew, { data: request }); // await this.salaryProfileEmployeeRepository.save(profilesEmpToSave, { chunk: 100, data: request }); setLogDataDiff(request, { before: beforeSalaryProfileNew, after: salaryProfileNew }); @@ -2890,6 +2898,7 @@ export class SalaryPeriodController extends Controller { } }), ); + console.timeEnd("⏱ SalaryProfileEmployee - Total Time"); } const salaryOrgNew = await this.salaryOrgRepository.find({ @@ -3135,21 +3144,21 @@ export class SalaryPeriodController extends Controller { _salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100); _salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100; _salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100); - console.log("fifteenAPR: case 1"); + // console.log("fifteenAPR: case 1"); } else { _salaryOrg.total = salaryOrgSnap1.total; _salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent; _salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint; _salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed; _salaryOrg.remainQuota = salaryOrgSnap1.remainQuota; - console.log("fifteenAPR: case 2"); + // console.log("fifteenAPR: case 2"); } } else { _salaryOrg.total = _salaryOrg.salaryProfiles.length; _salaryOrg.fifteenPercent = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100); _salaryOrg.fifteenPoint = (_salaryOrg.salaryProfiles.length * 15) % 100; _salaryOrg.remainQuota = Math.floor((_salaryOrg.salaryProfiles.length * 15) / 100); - console.log("fifteenAPR: case 3"); + // console.log("fifteenAPR: case 3"); } _salaryOrg.createdUserId = request.user.sub;