From 3aeb893d55f9af3a00d34261afc64adc579a6d71 Mon Sep 17 00:00:00 2001 From: Adisak Date: Fri, 28 Nov 2025 17:59:44 +0700 Subject: [PATCH] revert --- src/controllers/SalaryPeriodController.ts | 109 ++++++++++------------ 1 file changed, 49 insertions(+), 60 deletions(-) diff --git a/src/controllers/SalaryPeriodController.ts b/src/controllers/SalaryPeriodController.ts index b39b904..7100697 100644 --- a/src/controllers/SalaryPeriodController.ts +++ b/src/controllers/SalaryPeriodController.ts @@ -1209,8 +1209,8 @@ export class SalaryPeriodController extends Controller { * @param {string} id profile Id * @param {string} type ประเภทการเลื่อน NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น */ - @Post("oldchange/type-multi") - async oldchangeTypeMulti( + @Post("change/type-multi") + async changeTypeMulti( @Body() body: { profileId: string[]; type: string; isReserve: boolean; remark?: string | null }, @Request() req: RequestWithUser, ) { @@ -1545,8 +1545,8 @@ export class SalaryPeriodController extends Controller { } //NEW CHANGE TYPE-MULTI - @Post("change/type-multi") - async changeTypeMulti( + @Post("newchange/type-multi") + async newchangeTypeMulti( @Body() body: { profileId: string[]; type: string; isReserve: boolean; remark?: string | null }, @Request() req: RequestWithUser, ) { @@ -1572,28 +1572,25 @@ export class SalaryPeriodController extends Controller { const salaries = await this.salaryRepository.find({ where: { isActive: true } }); const salaryRanks = await this.salaryRankRepository.find(); + // Map lookup const posTypeMap = new Map(posTypes.map(x => [x.posTypeName, x])); const posLevelMap = new Map(posLevels.map(x => [`${x.posTypeId}|${x.posLevelName}`, x])); const salaryMap = new Map( salaries.map(x => [`${x.posTypeId}|${x.posLevelId}|${x.isSpecial ? 1 : 0}`, x]), ); - const ranksBySalaryId = salaryRanks.reduce((acc, r: any) => { if (!acc[r.salaryId]) acc[r.salaryId] = []; acc[r.salaryId].push(r); return acc; }, {} as Record); - // ----------------------------- - // 3) Loop profiles - // ----------------------------- const profilesToSave: SalaryProfile[] = []; const orgNeedRecalc = new Set(); for (const profile of salaryProfiles) { const bodyType = body.type?.toUpperCase() ?? profile.type; - // --- ตรวจ FULLHAFT → หา APR snapshot2 (เหมือนเดิม) --- + // --- ตรวจ FULLHAFT → หา APR snapshot2 --- if (bodyType === "FULLHAFT" && profile.salaryOrg.salaryPeriod.period === "OCT") { const checkPrev = await this.salaryProfileRepository.findOne({ relations: ["salaryOrg", "salaryOrg.salaryPeriod"], @@ -1612,11 +1609,6 @@ export class SalaryPeriodController extends Controller { } } - // reserve & remark - profile.type = bodyType; - profile.isReserve = bodyType === "FULL" ? body.isReserve : false; - profile.remark = body.remark ?? ""; - // --- apply posType/posLevel/salary --- const posType = posTypeMap.get(profile.posType); if (!posType) throw new HttpError(404, "ไม่พบประเภทตำแหน่ง"); @@ -1630,13 +1622,11 @@ export class SalaryPeriodController extends Controller { const salaryId = Number(salaryBase.id); const ranks = ranksBySalaryId[salaryId] ?? []; - // --- หา rank --- + // --- หา rank ตาม amount ก่อน dynamic type adjustment --- let rank: SalaryRanks | null = null; - if (profile.amount != null) { const amount = profile.amount; - // หา rank ที่ใช้ type เดิม (เหมือนเดิม) const possible = ranks .filter((r: any) => r.salary >= amount && !r.isNext) .sort((a: any, b: any) => a.salary - b.salary); @@ -1648,59 +1638,57 @@ export class SalaryPeriodController extends Controller { .sort((a: any, b: any) => a.salary - b.salary); rank = next[0] ?? null; } + } - // --- FULLHAFT dynamic type adjustment (เหมือนเดิม) --- - if (bodyType === "FULLHAFT" && rank) { - const halfSpecial = rank.salaryHalfSpecial ?? 0; - const fullSpecial = rank.salaryFullSpecial ?? 0; - const fullHalfSpecial = rank.salaryFullHalfSpecial ?? 0; + // --- คำนวณเงินเดือนตาม rank เดิมก่อน dynamic type adjustment --- + const calc = (sp: keyof SalaryRanks, next: keyof SalaryRanks) => ({ + amountSpecial: rank?.[sp] ?? 0, + amountUse: profile.amount != null && rank?.[next] != null + ? Number(rank[next]) - Number(profile.amount) + : 0, + positionSalaryAmount: rank?.[next] ?? 0, + isNext: rank?.isNext ?? 0 + }); - if (fullHalfSpecial > 0) { - if (fullSpecial === 0) profile.type = "HAFT"; - else if (halfSpecial === 0) profile.type = "FULL"; - else profile.type = "FULLHAFT"; - } + // --- FULLHAFT dynamic type adjustment หลังคำนวณเงินเดือน --- + let finalType = bodyType; + if (bodyType === "FULLHAFT" && rank) { + const halfSpecial = rank.salaryHalfSpecial ?? 0; + const fullSpecial = rank.salaryFullSpecial ?? 0; + const fullHalfSpecial = rank.salaryFullHalfSpecial ?? 0; + + if (fullHalfSpecial > 0) { + if (fullSpecial === 0) finalType = "HAFT"; + else if (halfSpecial === 0) finalType = "FULL"; + else finalType = "FULLHAFT"; } } - // --- คำนวณเงินเดือน (logic เหมือนเดิม) --- - const calc = (sp: keyof SalaryRanks, next: keyof SalaryRanks) => { - const amountNext = rank?.[next] ?? 0; - return { - amountSpecial: rank?.[sp] ?? 0, - amountUse: profile.amount != null ? Number(amountNext) - Number(profile.amount) : 0, - positionSalaryAmount: amountNext, - isNext: rank?.isNext ?? 0, - }; - }; + profile.type = finalType; + profile.isReserve = finalType === "FULL" ? body.isReserve : false; + profile.remark = body.remark ?? ""; - switch (profile.type) { - case "NONE": - profile.amountSpecial = 0; - profile.amountUse = 0; - profile.positionSalaryAmount = profile.amount ?? 0; - break; - case "PENDING": - profile.amountSpecial = 0; - profile.amountUse = 0; - profile.positionSalaryAmount = 0; - break; - case "HAFT": - Object.assign(profile, calc("salaryHalfSpecial", "salaryHalf")); - break; - case "FULL": - Object.assign(profile, calc("salaryFullSpecial", "salaryFull")); - break; - case "FULLHAFT": - Object.assign(profile, calc("salaryFullHalfSpecial", "salaryFullHalf")); - break; + if (finalType === "NONE") { + profile.amountSpecial = 0; + profile.amountUse = 0; + profile.positionSalaryAmount = profile.amount ?? 0; + } else if (finalType === "PENDING") { + profile.amountSpecial = 0; + profile.amountUse = 0; + profile.positionSalaryAmount = 0; + } else if (finalType === "HAFT") { + Object.assign(profile, calc("salaryHalfSpecial", "salaryHalf")); + } else if (finalType === "FULL") { + Object.assign(profile, calc("salaryFullSpecial", "salaryFull")); + } else if (finalType === "FULLHAFT") { + Object.assign(profile, calc("salaryFullHalfSpecial", "salaryFullHalf")); } profile.lastUpdateUserId = req.user.sub; profile.lastUpdateFullName = req.user.name; profile.lastUpdatedAt = new Date(); - // --- log diff (เหมือนเดิม) --- + // --- log diff --- const before = structuredClone(profile); profilesToSave.push(profile); setLogDataDiff(req, { before, after: profile }); @@ -1714,7 +1702,7 @@ export class SalaryPeriodController extends Controller { await this.salaryProfileRepository.save(profilesToSave); // ----------------------------- - // 5) Recalculate SalaryOrg (คง logic เดิม) + // 5) Recalculate SalaryOrg // ----------------------------- for (const orgId of orgNeedRecalc) { const org = await this.salaryOrgRepository.findOne({ @@ -1747,7 +1735,7 @@ export class SalaryPeriodController extends Controller { org.useAmount = useAmount; org.remainingAmount = org.sixPercentAmount - useAmount; - // --- SNAP2 APR recalc (เหมือนเดิม) --- + // --- SNAP2 APR recalc --- const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({ where: { period: "APR", year: org.salaryPeriod.year } }); @@ -1778,6 +1766,7 @@ export class SalaryPeriodController extends Controller { + /** * API รายการอัตราเงินเดือน *