diff --git a/src/controllers/ReportController.ts b/src/controllers/ReportController.ts index 2ed861f..ef6598e 100644 --- a/src/controllers/ReportController.ts +++ b/src/controllers/ReportController.ts @@ -102,8 +102,8 @@ export class ReportController extends Controller { return new HttpSuccess({ template: "SalaryRank", reportName: "SalaryRank", data: { - nameType: salarys.salaryType == "OFFICER" ? "ผังข้าราชการกรุงเทพมหานครสามัญ" : - salarys.salaryType == "EMPLOYEE" ? "ผังลูกจ้างประจำกรุงเทพมหานคร" : "", + nameType: salarys.name == "OFFICER" ? "ผังข้าราชการกรุงเทพมหานครสามัญ" : + salarys.name == "EMPLOYEE" ? "ผังลูกจ้างประจำกรุงเทพมหานคร" : "", level: posLevel?.posLevelName == null ? "" : posLevel?.posLevelName, type: posType?.posTypeName == null ? "" : posType?.posTypeName, date: salarys.date == null ? "" : diff --git a/src/controllers/Report_1_Controller.ts b/src/controllers/Report_1_Controller.ts index 348598a..e4ea968 100644 --- a/src/controllers/Report_1_Controller.ts +++ b/src/controllers/Report_1_Controller.ts @@ -20,7 +20,7 @@ import { AppDataSource } from "../database/data-source"; import HttpSuccess from "../interfaces/http-success"; import HttpStatusCode from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; -import { In, IsNull, Not } from "typeorm"; +import { In, IsNull, Not, MoreThan } from "typeorm"; import { SalaryProfile } from "../entities/SalaryProfile"; import { SalaryPeriod } from "../entities/SalaryPeriod"; import { SalaryOrg } from "../entities/SalaryOrg"; @@ -40,18 +40,33 @@ export class Report_1_Controller extends Controller { private salaryProfile = AppDataSource.getRepository(SalaryProfile); /** - * API รายงานแบบ 1 กท + * API รายงานแบบ 1 กท รอบเมษายน * - * @summary รายงานแบบ 1 กท + * @summary รายงานแบบ 1 กท รอบเมษายน * * @param {string} rootId Guid, *Id Root * @param {string} salaryPeriodId Guid, *Id Period */ - @Get("{rootId}/{salaryPeriodId}") - async SalaryReport4( - @Path() rootId : string = "c6164a42-539d-401a-b289-653282c08e37", - @Path() salaryPeriodId: string = "31cfc7de-b93b-4998-bbf1-25c21f141ac2", + @Get("03/{rootId}/{salaryPeriodId}") + async SalaryReport3( + // @Path() rootId : string = "c6164a42-539d-401a-b289-653282c08e37", + // @Path() salaryPeriodId: string = "31cfc7de-b93b-4998-bbf1-25c21f141ac2", + @Path() rootId : string, + @Path() salaryPeriodId: string, ) { + + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { + id: salaryPeriodId, + period: "APR", + isActive: true + }, + }); + + if (!salaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + const salaryOrg = await this.salaryOrgRepository.findOne({ where: { salaryPeriodId: salaryPeriodId, @@ -60,42 +75,285 @@ export class Report_1_Controller extends Controller { }, order: { group: "ASC" - } - // relations: ["salaryProfiles"], + }, + relations: ["salaryProfiles"], }); - if (!salaryOrg) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); - } - const salaryPeriod = await this.salaryPeriodRepository.findOne({ + + const salaryProfile = await this.salaryProfile.find({ where: { - id: String(salaryOrg.salaryPeriodId), - period: "APR", - isActive: true + salaryOrgId: salaryOrg?.id, + type: "FULL", //หนึ่งขั้น }, + select: [ + "id", "prefix" , "firstName", "lastName", "root", + "position", "posType", "posLevel", "orgShortName", + "posMasterNo", "amount", "amountSpecial" + ] }); + const mapData = { + effectiveDate : salaryPeriod?.effectiveDate, + // root: salaryProfile[0]?.root, + profile: salaryProfile.map((item, index) => ({ + no: Extension.ToThaiNumber(String(index+1)), + fullname: item.prefix + item.firstName +" "+ item.lastName, + position: item.position + "/" + + (item.child4==undefined && item.child4==null ? "" : item.child4+"/")+ + (item.child3==undefined && item.child3==null ? "" : item.child3+"/")+ + (item.child2==undefined && item.child2==null ? "" : item.child2+"/")+ + (item.child1==undefined && item.child1==null ? "" : item.child1+"/")+ + (item.root==undefined && item.root==null ? "" : item.root), + posLevel: item.posLevel, + orgShortName: item.orgShortName+item.posMasterNo, + amount: item.amount == undefined || item.amount == null ? "๐" : Extension.ToThaiNumber(String(item.amount)), + amountSpecial: item.amountSpecial == undefined || item.amountSpecial == null ? "๐" : Extension.ToThaiNumber(String(item.amountSpecial)), + score: null, //สรุปผลการประเมินฯ ระดับและคะแนน + remark: null //หมายเหตุ + })) + } + return mapData + } + + /** + * API รายงานแบบ 1 กท รอบเมษายน + * + * @summary รายงานแบบ 1 กท รอบเมษายน + * + * @param {string} rootId Guid, *Id Root + * @param {string} salaryPeriodId Guid, *Id Period + */ + @Get("04/{rootId}/{salaryPeriodId}") + async SalaryReport4( + // @Path() rootId : string = "c6164a42-539d-401a-b289-653282c08e37", + // @Path() salaryPeriodId: string = "31cfc7de-b93b-4998-bbf1-25c21f141ac2", + @Path() rootId : string, + @Path() salaryPeriodId: string, + ) { + + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { + id: salaryPeriodId, + period: "APR", + isActive: true + }, + }); + + if (!salaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + + const salaryOrg = await this.salaryOrgRepository.findOne({ + where: { + salaryPeriodId: salaryPeriodId, + rootId: rootId, + snapshot: "SNAP2", + }, + order: { + group: "ASC" + }, + relations: ["salaryProfiles"], + }); + const salaryProfile = await this.salaryProfile.find({ - where: { salaryOrgId: salaryOrg.id}, - select: ["id", "prefix" , "firstName", "lastName", "root", - "position", "posType", "posLevel", "orgShortName", "posMasterNo", "amount", "amountSpecial"] + where: { salaryOrgId: salaryOrg?.id}, + select: [ + "id", "prefix" , "firstName", "lastName", "root", + "position", "posType", "posLevel", "orgShortName", + "posMasterNo", "amount", "amountSpecial" + ] }); const mapData = { effectiveDate : salaryPeriod?.effectiveDate, root: salaryProfile[0]?.root, profile: salaryProfile.map((item, index) => ({ - no: index+1, + no: Extension.ToThaiNumber(String(index+1)), fullname: item.prefix + item.firstName +" "+ item.lastName, - position: item.position + " / " + item.posType, + position: item.position + "/" + + (item.child4==undefined && item.child4==null ? "" : item.child4+"/")+ + (item.child3==undefined && item.child3==null ? "" : item.child3+"/")+ + (item.child2==undefined && item.child2==null ? "" : item.child2+"/")+ + (item.child1==undefined && item.child1==null ? "" : item.child1+"/")+ + (item.root==undefined && item.root==null ? "" : item.root), posLevel: item.posLevel, orgShortName: item.orgShortName+item.posMasterNo, - amount: item.amount, - amountSpecial: item.amountSpecial, - root: item.root, + amount: item.amount == undefined || item.amount == null ? "๐" : Extension.ToThaiNumber(String(item.amount)), + amountSpecial: item.amountSpecial == undefined || item.amountSpecial == null ? "๐" : Extension.ToThaiNumber(String(item.amountSpecial)), score: null, //สรุปผลการประเมินฯ ระดับและคะแนน remark: null //หมายเหตุ })) } return mapData - } + } + + /** + * API รายงานคำสั่งเลื่อนเงินเดือน รอบเมษายน + * + * @summary รายงานคำสั่งเลื่อนเงินเดือน รอบเมษายน + * + * @param {string} rootId Guid, *Id Root + * @param {string} salaryPeriodId Guid, *Id Period + */ + @Get("07/{rootId}/{salaryPeriodId}") + async SalaryReport7( + // @Path() rootId : string = "c6164a42-539d-401a-b289-653282c08e37", + // @Path() salaryPeriodId: string = "31cfc7de-b93b-4998-bbf1-25c21f141ac2", + @Path() rootId : string, + @Path() salaryPeriodId: string, + ) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { + id: salaryPeriodId, + period: "APR", + isActive: true + }, + }); + + if (!salaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + + const salaryOrg = await this.salaryOrgRepository.findOne({ + where: { + salaryPeriodId: salaryPeriodId, + rootId: rootId, + snapshot: "SNAP2", + }, + order: { + group: "ASC" + }, + relations: ["salaryProfiles"], + }); + + const salaryProfile = await this.salaryProfile.find({ + where: { + salaryOrgId: salaryOrg?.id, + amountSpecial: IsNull() || 0, + amountUse: MoreThan(1), + }, + select: [ + "id", "prefix" , "firstName", "lastName", "root", + "position", "posType", "posLevel", "orgShortName", "posMasterNo", + "amount", "amountUse", "positionSalaryAmount" + ], + order: { + posMasterNo: "ASC" + } + }); + + const mapData = salaryProfile.map((item, index) => ({ + no: Extension.ToThaiNumber(String(index+1)), + fullname: item.prefix + item.firstName +" "+ item.lastName, + position: item.position, + posType: item.posType, + posLevel: item.posLevel, + posMasterNo: Extension.ToThaiNumber(String(item.posMasterNo)), + amount: item.amount == undefined || item.amount == null ? "๐" : Extension.ToThaiNumber(String(item.amount)), + positionSalaryAmount: item.positionSalaryAmount == undefined || item.positionSalaryAmount == null ? "๐" : Extension.ToThaiNumber(String(item.positionSalaryAmount)), + remark: null + })); + + return mapData; + } + + /** + * API รายงานคำสั่งค่าตอบแทนพิเศษ และผู้ไม่ได้เลื่อน รอบเมษายน + * + * @summary รายงานคำสั่งคำสั่งค่าตอบแทนพิเศษ และผู้ไม่ได้เลื่อน รอบเมษายน + * + * @param {string} rootId Guid, *Id Root + * @param {string} salaryPeriodId Guid, *Id Period + */ + @Get("08/{rootId}/{salaryPeriodId}") + async SalaryReport8( + // @Path() rootId : string = "c6164a42-539d-401a-b289-653282c08e37", + // @Path() salaryPeriodId: string = "31cfc7de-b93b-4998-bbf1-25c21f141ac2", + @Path() rootId : string, + @Path() salaryPeriodId: string, + ) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { + id: salaryPeriodId, + period: "APR", + isActive: true + }, + }); + + if (!salaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + + const salaryOrg = await this.salaryOrgRepository.findOne({ + where: { + salaryPeriodId: salaryPeriodId, + rootId: rootId, + snapshot: "SNAP2", + }, + order: { + group: "ASC" + }, + relations: ["salaryProfiles"], + }); + + const salaryProfileSpecial = await this.salaryProfile.find({ + where: { + salaryOrgId: salaryOrg?.id, + amountSpecial: MoreThan(1), + }, + select: [ + "id", "prefix" , "firstName", "lastName", "root", + "position", "posType", "posLevel", "orgShortName", + "posMasterNo", "amount", "amountSpecial", + ], + order: { + posMasterNo: "ASC" + } + }); + + const salaryProfileNoAmount = await this.salaryProfile.find({ + where: { + salaryOrgId: salaryOrg?.id, + amountUse: IsNull() || 0, + positionSalaryAmount: IsNull() || 0, + }, + select: [ + "id", "prefix" , "firstName", "lastName", "root", + "position", "posType", "posLevel", "orgShortName", + "posMasterNo", "amount", + ], + order: { + posMasterNo: "ASC" + } + }); + + + const profileSpecial = salaryProfileSpecial.map((item, index) => ({ + no: Extension.ToThaiNumber(String(index+1)), + fullname: item.prefix + item.firstName +" "+ item.lastName, + position: item.position, + posType: item.posType, + posLevel: item.posLevel, + posMasterNo: Extension.ToThaiNumber(String(item.posMasterNo)), + amount: item.amount == undefined || item.amount == null ? "๐" : Extension.ToThaiNumber(String(item.amount)), + amountSpecial: item.amountSpecial == undefined || item.amountSpecial == null ? "๐" : Extension.ToThaiNumber(String(item.amountSpecial)), + remark: null + })); + + const profileNoAmount = salaryProfileNoAmount.map((item, index) => ({ + no: Extension.ToThaiNumber(String(index+1)), + fullname: item.prefix + item.firstName +" "+ item.lastName, + position: item.position, + posType: item.posType, + posLevel: item.posLevel, + posMasterNo: Extension.ToThaiNumber(String(item.posMasterNo)), + amount: item.amount == undefined || item.amount == null ? "๐" : Extension.ToThaiNumber(String(item.amount)), + remark: null + })); + + const mapData = { + profileSpecial, + profileNoAmount + } + return mapData; + } } diff --git a/src/controllers/SalaryController.ts b/src/controllers/SalaryController.ts index a4842eb..31826c8 100644 --- a/src/controllers/SalaryController.ts +++ b/src/controllers/SalaryController.ts @@ -43,7 +43,7 @@ export class Salary extends Controller { */ @Post() @Example({ - salaryType: "string", //*ประเภทผัง (OFFICER->"ข้าราชการกรุงเทพมหานครสามัญ",EMPLOYEE->"ลูกจ้างประจำกรุงเทพมหานคร") + name: "string", //*ชื่อผัง posTypeId: "string(Guid)", //*ระดับของตำแหน่ง posLevelId: "string(Guid)", //*ประเภทของตำแหน่ง isActive: "boolean", //*สถานะการใช้งาน @@ -62,11 +62,6 @@ export class Salary extends Controller { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); } - const chk_salaryType = ["OFFICER", "EMPLOYEE"]; - if (!chk_salaryType.includes(salarys.salaryType.toUpperCase())) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง"); - } - const chk_posTypeId = await this.poTypeRepository.findOne({ where: { id: salarys.posTypeId }, }); @@ -83,7 +78,7 @@ export class Salary extends Controller { const chk_3fields = await this.salaryRepository.findOne({ where: { - salaryType: salarys.salaryType, + name: salarys.name, posTypeId: salarys.posTypeId, posLevelId: salarys.posLevelId, }, @@ -91,7 +86,7 @@ export class Salary extends Controller { if (chk_3fields && salarys.isActive) { salarys.isActive = false; } - salarys.salaryType = salarys.salaryType.toUpperCase(); + salarys.name = salarys.name; salarys.isSpecial = salarys.isSpecial; salarys.createdUserId = request.user.sub; salarys.createdFullName = request.user.name; @@ -113,7 +108,7 @@ export class Salary extends Controller { */ @Put("{id}") @Example({ - salaryType: "string", //*ประเภทผัง (OFFICER->"ข้าราชการกรุงเทพมหานครสามัญ",EMPLOYEE->"ลูกจ้างประจำกรุงเทพมหานคร") + name: "string", //*ชื่อผัง posTypeId: "string(Guid)", //*ระดับของตำแหน่ง posLevelId: "string(Guid)", //*ประเภทของตำแหน่ง isActive: "boolean", //*สถานะการใช้งาน @@ -144,7 +139,7 @@ export class Salary extends Controller { const chk_3fields = await this.salaryRepository.findOne({ where: { - salaryType: requestBody.salaryType, + name: requestBody.name, posTypeId: requestBody.posTypeId, posLevelId: requestBody.posLevelId, isActive: true, @@ -160,11 +155,6 @@ export class Salary extends Controller { await this.salaryRepository.save(chk_3fields); } - const chk_salaryType = ["OFFICER", "EMPLOYEE"]; - if (!chk_salaryType.includes(String(requestBody.salaryType).toUpperCase())) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง"); - } - const chk_posTypeId = await this.poTypeRepository.findOne({ where: { id: requestBody.posTypeId }, }); @@ -233,7 +223,7 @@ export class Salary extends Controller { */ @Get("{id}") @Example({ - salaryType: "string", //*ประเภทผัง (OFFICER->"ข้าราชการกรุงเทพมหานครสามัญ",EMPLOYEE->"ลูกจ้างประจำกรุงเทพมหานคร") + name: "string", //*ชื่อผัง posTypeId: "string(Guid)", //*ระดับของตำแหน่ง posLevelId: "string(Guid)", //*ประเภทของตำแหน่ง isActive: "boolean", //*สถานะการใช้งาน @@ -247,7 +237,7 @@ export class Salary extends Controller { const salary = await this.salaryRepository.findOne({ where: { id: id }, select: [ - "salaryType", + "name", "isSpecial", "posTypeId", "posLevelId", @@ -282,14 +272,21 @@ export class Salary extends Controller { const [salary, total] = await this.salaryRepository.findAndCount({ relations: ["posLevel_", "posType_"], order: { - startDate: "DESC", + // startDate: "DESC", + isActive: "ASC", + posType_: { + posTypeRank: "ASC" + }, + posLevel_: { + posLevelRank: "ASC" + }, }, ...(keyword ? {} : { skip: (page - 1) * pageSize, take: pageSize }), }); if (keyword != undefined && keyword !== "") { const filteredSalary = salary.filter( (x) => - x.salaryType?.toString().includes(keyword) || + x.name?.toString().includes(keyword) || x.isSpecial?.toString().includes(keyword) || //new 20.02.67 x.posLevel_?.posLevelName?.toString().includes(keyword) || x.posType_?.posTypeName?.toString().includes(keyword) || @@ -302,7 +299,7 @@ export class Salary extends Controller { const formattedData = filteredSalary.map((item) => ({ id: item.id, - salaryType: item.salaryType, + name: item.name, isSpecial: item.isSpecial, posTypeId: item.posType_?.id, posType: item.posType_?.posTypeName, @@ -320,7 +317,7 @@ export class Salary extends Controller { const formattedData = salary.map((item) => ({ id: item.id, - salaryType: item.salaryType, + name: item.name, isSpecial: item.isSpecial, posTypeId: item.posType_?.id, posType: item.posType_?.posTypeName, @@ -333,7 +330,6 @@ export class Salary extends Controller { details: item.details, })); return new HttpSuccess({ data: formattedData, total }); - } /** diff --git a/src/controllers/SalaryPeriodController.ts b/src/controllers/SalaryPeriodController.ts index e039e9f..cb6ea42 100644 --- a/src/controllers/SalaryPeriodController.ts +++ b/src/controllers/SalaryPeriodController.ts @@ -118,6 +118,9 @@ export class SalaryPeriodController extends Controller { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); } + const sum = salaryOrg.salaryProfiles.reduce((accumulator, object) => { + return accumulator + object.amountSpecial; + }, 0); const data = { total: salaryOrg.total, fifteenPercent: salaryOrg.fifteenPercent, @@ -129,6 +132,8 @@ export class SalaryPeriodController extends Controller { sixPercentSpentAmount: salaryOrg.sixPercentAmount - salaryOrg.spentAmount, useAmount: salaryOrg.useAmount, remainingAmount: salaryOrg.remainingAmount, + totalAmountSpecial: sum, + totalBackup: salaryOrg.salaryProfiles.filter((x) => x.isReserve == true).length, }; return new HttpSuccess(data); } @@ -175,7 +180,9 @@ export class SalaryPeriodController extends Controller { }) .getRawOne(); const calRemainAmount = - salaryProfile?.salaryOrg.sixPercentAmount - sumAmountUse.totalAmount; + salaryProfile.salaryOrg.sixPercentAmount - + sumAmountUse.totalAmount - + salaryProfile.salaryOrg.spentAmount; salaryProfile.salaryOrg.useAmount = sumAmountUse.totalAmount; salaryProfile.salaryOrg.remainingAmount = calRemainAmount; await this.salaryOrgRepository.save(salaryProfile?.salaryOrg); @@ -246,8 +253,7 @@ export class SalaryPeriodController extends Controller { if (salaryProfile.type == "NONE") { salaryProfile.amountSpecial = 0; salaryProfile.amountUse = 0; - salaryProfile.positionSalaryAmount = - salaryProfile.amount == null ? 0 : salaryProfile.amount; + salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount; } else if (salaryProfile.type == "PENDING") { salaryProfile.amountSpecial = 0; salaryProfile.amountUse = 0; @@ -263,11 +269,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryHalf == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryHalf - salaryProfile.amount + salaryRanks.salaryHalfSpecial; + : salaryRanks.salaryHalf - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryHalf == null - ? 0 - : salaryRanks.salaryHalf; + salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf; } else if (salaryProfile.type == "FULL") { salaryProfile.amountSpecial = salaryRanks == null || salaryRanks.salaryFullSpecial == null @@ -279,11 +283,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryFull == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryFull - salaryProfile.amount + salaryRanks.salaryFullSpecial; + : salaryRanks.salaryFull - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryFull == null - ? 0 - : salaryRanks.salaryFull; + salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull; } else if (salaryProfile.type == "FULLHAFT") { salaryProfile.amountSpecial = salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null @@ -295,11 +297,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryFullHalf == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryFullHalf - salaryProfile.amount + salaryRanks.salaryFullHalfSpecial; + : salaryRanks.salaryFullHalf - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryFullHalf == null - ? 0 - : salaryRanks.salaryFullHalf; + salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf; } else { throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง"); } @@ -309,16 +309,18 @@ export class SalaryPeriodController extends Controller { // หาจำนวน Quota คงเหลือ if (salaryProfile.salaryOrg.snapshot == "SNAP1") { if (salaryProfile.salaryOrg.salaryPeriod.period == "APR") { - const amountFullType = await this.salaryProfileRepository.count({ - where: { - salaryOrgId: salaryProfile?.salaryOrg.id, - type: "FULL", - }, - }); - const calRemainQuota = salaryProfile?.salaryOrg.fifteenPercent - amountFullType; - salaryProfile.salaryOrg.quantityUsed = amountFullType; - salaryProfile.salaryOrg.remainQuota = calRemainQuota; - await this.salaryOrgRepository.save(salaryProfile?.salaryOrg); + if (salaryProfile.isReserve == false) { + const amountFullType = await this.salaryProfileRepository.count({ + where: { + salaryOrgId: salaryProfile?.salaryOrg.id, + type: "FULL", + }, + }); + const calRemainQuota = salaryProfile?.salaryOrg.fifteenPercent - amountFullType; + salaryProfile.salaryOrg.quantityUsed = amountFullType; + salaryProfile.salaryOrg.remainQuota = calRemainQuota; + await this.salaryOrgRepository.save(salaryProfile?.salaryOrg); + } } else if (salaryProfile.salaryOrg.salaryPeriod.period == "OCT") { const sumAmountUse = await AppDataSource.getRepository(SalaryProfile) .createQueryBuilder("salaryProfile") @@ -329,7 +331,9 @@ export class SalaryPeriodController extends Controller { }) .getRawOne(); const calRemainAmount = - salaryProfile?.salaryOrg.sixPercentAmount - sumAmountUse.totalAmount; + salaryProfile.salaryOrg.sixPercentAmount - + sumAmountUse.totalAmount - + salaryProfile.salaryOrg.spentAmount; salaryProfile.salaryOrg.useAmount = sumAmountUse.totalAmount; salaryProfile.salaryOrg.remainingAmount = calRemainAmount; await this.salaryOrgRepository.save(salaryProfile?.salaryOrg); @@ -369,16 +373,18 @@ export class SalaryPeriodController extends Controller { // หาจำนวน Quota คงเหลือ if (salaryOrg.snapshot == "SNAP1") { if (salaryOrg.salaryPeriod.period == "APR") { - const amountFullType = await this.salaryProfileRepository.count({ - where: { - salaryOrgId: salaryOrg.id, - type: "FULL", - }, - }); - const calRemainQuota = salaryOrg.fifteenPercent - amountFullType; - salaryOrg.quantityUsed = amountFullType; - salaryOrg.remainQuota = calRemainQuota; - await this.salaryOrgRepository.save(salaryOrg); + if (salaryProfile.isReserve == false) { + const amountFullType = await this.salaryProfileRepository.count({ + where: { + salaryOrgId: salaryOrg.id, + type: "FULL", + }, + }); + const calRemainQuota = salaryOrg.fifteenPercent - amountFullType; + salaryOrg.quantityUsed = amountFullType; + salaryOrg.remainQuota = calRemainQuota; + await this.salaryOrgRepository.save(salaryOrg); + } } else if (salaryOrg.salaryPeriod.period == "OCT") { const sumAmountUse = await AppDataSource.getRepository(SalaryProfile) .createQueryBuilder("salaryProfile") @@ -388,7 +394,8 @@ export class SalaryPeriodController extends Controller { type: In(["HAFT", "FULL", "FULLHAFT"]), }) .getRawOne(); - const calRemainAmount = salaryOrg.sixPercentAmount - sumAmountUse.totalAmount; + const calRemainAmount = + salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount; salaryOrg.useAmount = sumAmountUse.totalAmount; salaryOrg.remainingAmount = calRemainAmount; await this.salaryOrgRepository.save(salaryOrg); @@ -407,7 +414,7 @@ export class SalaryPeriodController extends Controller { * @param {string} type ประเภทการเลื่อน NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น */ @Post("change/type") - async changeType(@Body() body: { profileId: string; type: string }) { + async changeType(@Body() body: { profileId: string; type: string; isReserve: boolean }) { const salaryProfile = await this.salaryProfileRepository.findOne({ relations: ["salaryOrg", "salaryOrg.salaryPeriod"], where: { id: body.profileId }, @@ -485,8 +492,7 @@ export class SalaryPeriodController extends Controller { if (body.type == "NONE") { salaryProfile.amountSpecial = 0; salaryProfile.amountUse = 0; - salaryProfile.positionSalaryAmount = - salaryProfile.amount == null ? 0 : salaryProfile.amount; + salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount; } else if (body.type == "PENDING") { salaryProfile.amountSpecial = 0; salaryProfile.amountUse = 0; @@ -502,11 +508,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryHalf == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryHalf - salaryProfile.amount + salaryRanks.salaryHalfSpecial; + : salaryRanks.salaryHalf - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryHalf == null - ? 0 - : salaryRanks.salaryHalf; + salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf; } else if (body.type == "FULL") { salaryProfile.amountSpecial = salaryRanks == null || salaryRanks.salaryFullSpecial == null @@ -518,11 +522,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryFull == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryFull - salaryProfile.amount + salaryRanks.salaryFullSpecial; + : salaryRanks.salaryFull - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryFull == null - ? 0 - : salaryRanks.salaryFull; + salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull; } else if (body.type == "FULLHAFT") { salaryProfile.amountSpecial = salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null @@ -534,31 +536,32 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryFullHalf == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryFullHalf - salaryProfile.amount + salaryRanks.salaryFullHalfSpecial; + : salaryRanks.salaryFullHalf - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryFullHalf == null - ? 0 - : salaryRanks.salaryFullHalf; + salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf; } else { throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง"); } salaryProfile.type = body.type; + salaryProfile.isReserve = body.isReserve; await this.salaryProfileRepository.save(salaryProfile); if (salaryProfile.salaryOrg) { // หาจำนวน Quota คงเหลือ if (salaryProfile.salaryOrg.snapshot == "SNAP1") { if (salaryProfile.salaryOrg.salaryPeriod.period == "APR") { - const amountFullType = await this.salaryProfileRepository.count({ - where: { - salaryOrgId: salaryProfile.salaryOrg.id, - type: "FULL", - }, - }); - const calRemainQuota = salaryProfile.salaryOrg.fifteenPercent - amountFullType; - salaryProfile.salaryOrg.quantityUsed = amountFullType; - salaryProfile.salaryOrg.remainQuota = calRemainQuota; - await this.salaryOrgRepository.save(salaryProfile.salaryOrg); + if (body.isReserve == false) { + const amountFullType = await this.salaryProfileRepository.count({ + where: { + salaryOrgId: salaryProfile.salaryOrg.id, + type: "FULL", + }, + }); + const calRemainQuota = salaryProfile.salaryOrg.fifteenPercent - amountFullType; + salaryProfile.salaryOrg.quantityUsed = amountFullType; + salaryProfile.salaryOrg.remainQuota = calRemainQuota; + await this.salaryOrgRepository.save(salaryProfile.salaryOrg); + } } else if (salaryProfile.salaryOrg.salaryPeriod.period == "OCT") { const sumAmountUse = await AppDataSource.getRepository(SalaryProfile) .createQueryBuilder("salaryProfile") @@ -569,7 +572,9 @@ export class SalaryPeriodController extends Controller { }) .getRawOne(); const calRemainAmount = - salaryProfile.salaryOrg.sixPercentAmount - sumAmountUse.totalAmount; + salaryProfile.salaryOrg.sixPercentAmount - + sumAmountUse.totalAmount - + salaryProfile.salaryOrg.spentAmount; salaryProfile.salaryOrg.useAmount = sumAmountUse.totalAmount; salaryProfile.salaryOrg.remainingAmount = calRemainAmount; await this.salaryOrgRepository.save(salaryProfile.salaryOrg); @@ -652,6 +657,43 @@ export class SalaryPeriodController extends Controller { return new HttpSuccess({ data: salaryProfile, total }); } + /** + * API แก้คุณสมบัติ + * + * @summary SLR_031 - แก้คุณสมบัติ #30 + * + */ + @Put("org/property/{id}") + async editProperty( + @Path() id: string, + @Body() + body: { + isPunish: boolean; + isSuspension: boolean; + isAbsent: boolean; + isLeave: boolean; + }, + @Request() request: { user: Record }, + ) { + const salaryProfile = await this.salaryProfileRepository.findOne({ + where: { + id: id, + }, + }); + if (!salaryProfile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเพิ่มเงินเดือนของบุคคลนี้"); + } + salaryProfile.isPunish = body.isPunish; + salaryProfile.isSuspension = body.isSuspension; + salaryProfile.isAbsent = body.isAbsent; + salaryProfile.isLeave = body.isLeave; + salaryProfile.lastUpdateUserId = request.user.sub; + salaryProfile.lastUpdateFullName = request.user.name; + salaryProfile.lastUpdatedAt = new Date(); + await this.salaryProfileRepository.save(salaryProfile); + return new HttpSuccess(); + } + /** * API เพิ่มคนเลื่อนเงินเดือนตามรอบ * @@ -664,7 +706,7 @@ export class SalaryPeriodController extends Controller { @Request() request: { user: Record }, ) { const salaryOrg = await this.salaryOrgRepository.findOne({ - relations: ["salaryPeriod"], + relations: ["salaryPeriod", "salaryProfiles"], where: { id: requestBody.id, }, @@ -744,8 +786,7 @@ export class SalaryPeriodController extends Controller { if (salaryProfile.type == "NONE") { salaryProfile.amountSpecial = 0; salaryProfile.amountUse = 0; - salaryProfile.positionSalaryAmount = - salaryProfile.amount == null ? 0 : salaryProfile.amount; + salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount; } else if (salaryProfile.type == "PENDING") { salaryProfile.amountSpecial = 0; salaryProfile.amountUse = 0; @@ -761,11 +802,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryHalf == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryHalf - salaryProfile.amount + salaryRanks.salaryHalfSpecial; + : salaryRanks.salaryHalf - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryHalf == null - ? 0 - : salaryRanks.salaryHalf; + salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf; } else if (salaryProfile.type == "FULL") { salaryProfile.amountSpecial = salaryRanks == null || salaryRanks.salaryFullSpecial == null @@ -777,11 +816,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryFull == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryFull - salaryProfile.amount + salaryRanks.salaryFullSpecial; + : salaryRanks.salaryFull - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryFull == null - ? 0 - : salaryRanks.salaryFull; + salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull; } else if (salaryProfile.type == "FULLHAFT") { salaryProfile.amountSpecial = salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null @@ -793,11 +830,9 @@ export class SalaryPeriodController extends Controller { salaryRanks.salaryFullHalf == null || salaryProfile.amount == null ? 0 - : salaryRanks.salaryFullHalf - salaryProfile.amount + salaryRanks.salaryFullHalfSpecial; + : salaryRanks.salaryFullHalf - salaryProfile.amount; salaryProfile.positionSalaryAmount = - salaryRanks == null || salaryRanks.salaryFullHalf == null - ? 0 - : salaryRanks.salaryFullHalf; + salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf; } else { salaryProfile.amountSpecial = 0; salaryProfile.amountUse = 0; @@ -814,6 +849,10 @@ export class SalaryPeriodController extends Controller { // หาจำนวน Quota คงเหลือ if (salaryOrg.snapshot == "SNAP1") { if (salaryOrg.salaryPeriod.period == "APR") { + salaryOrg.total = salaryOrg.salaryProfiles.length; + salaryOrg.fifteenPercent = Math.floor((salaryOrg.salaryProfiles.length * 15) / 100); + salaryOrg.fifteenPoint = (salaryOrg.salaryProfiles.length * 15) % 100; + const amountFullType = await this.salaryProfileRepository.count({ where: { salaryOrgId: salaryOrg.id, @@ -825,6 +864,10 @@ export class SalaryPeriodController extends Controller { salaryOrg.remainQuota = calRemainQuota; await this.salaryOrgRepository.save(salaryOrg); } else if (salaryOrg.salaryPeriod.period == "OCT") { + const totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount"); + salaryOrg.currentAmount = totalProfile; + salaryOrg.sixPercentAmount = totalProfile * 0.06; + const sumAmountUse = await AppDataSource.getRepository(SalaryProfile) .createQueryBuilder("salaryProfile") .select("SUM(salaryProfile.amountUse)", "totalAmount") @@ -833,7 +876,8 @@ export class SalaryPeriodController extends Controller { type: In(["HAFT", "FULL", "FULLHAFT"]), }) .getRawOne(); - const calRemainAmount = salaryOrg.sixPercentAmount - sumAmountUse.totalAmount; + const calRemainAmount = + salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount; salaryOrg.useAmount = sumAmountUse.totalAmount; salaryOrg.remainingAmount = calRemainAmount; await this.salaryOrgRepository.save(salaryOrg); @@ -843,6 +887,26 @@ export class SalaryPeriodController extends Controller { return new HttpSuccess(salaryProfile.id); } + /** + * API ปิดรอบเงินเดือน + * + * @summary SLR_032 - ปิดรอบเงินเดือน #31 + * + * @param {string} id Guid, *Id รอบเงินเดือน + */ + @Get("close/{id}") + async closeSalaryPeriod_ById(@Path() id: string) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: id }, + }); + if (!salaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + } + salaryPeriod.isClose = !salaryPeriod.isClose; + await this.salaryPeriodRepository.save(salaryPeriod); + return new HttpSuccess(); + } + /** * API สร้างรอบเงินเดือน * @@ -973,7 +1037,7 @@ export class SalaryPeriodController extends Controller { "period", "isActive", "effectiveDate", - "isActive", + "isClose", "status", "year", "revisionId", @@ -1007,6 +1071,7 @@ export class SalaryPeriodController extends Controller { "salaryPeriod.id", "salaryPeriod.period", "salaryPeriod.isActive", + "salaryPeriod.isClose", "salaryPeriod.effectiveDate", "salaryPeriod.status", "salaryPeriod.year", @@ -1096,60 +1161,61 @@ export class SalaryPeriodController extends Controller { await this.salaryOrgRepository.save(salaryOrgNew); }), ); - - 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"; - } - const salaryOrgNew = await this.salaryOrgRepository.findOne({ - where: { - salaryPeriodId: salaryPeriod.id, - rootId: profile.rootId, - snapshot: snapshot, - group: group, - }, - }); - - if (salaryOrgNew != null) { - let salaryProfileNew = Object.assign(new SalaryProfile(), profile); - delete profile.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; - - if (snapshot == "SNAP2") { - const salaryOrgOld = await this.salaryOrgRepository.find({ - where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, - }); - const salaryOld = await this.salaryProfileRepository.findOne({ - where: { - citizenId: salaryProfileNew.citizenId, - salaryOrgId: In(salaryOrgOld.map((x) => x.id)), - }, - }); - 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; + if (salaryPeriod.period != "SPECIAL") { + 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"; } - await this.salaryProfileRepository.save(salaryProfileNew); - } - }), - ); + const salaryOrgNew = await this.salaryOrgRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: profile.rootId, + snapshot: snapshot, + group: group, + }, + }); + + if (salaryOrgNew != null) { + let salaryProfileNew = Object.assign(new SalaryProfile(), profile); + delete profile.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; + + if (snapshot == "SNAP2") { + const salaryOrgOld = await this.salaryOrgRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, + }); + const salaryOld = await this.salaryProfileRepository.findOne({ + where: { + citizenId: salaryProfileNew.citizenId, + salaryOrgId: In(salaryOrgOld.map((x) => x.id)), + }, + }); + 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; + } + await this.salaryProfileRepository.save(salaryProfileNew); + } + }), + ); + } const salaryOrgNew = await this.salaryOrgRepository.find({ where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, @@ -1195,6 +1261,7 @@ export class SalaryPeriodController extends Controller { _salaryOrg.currentAmount = totalProfile; _salaryOrg.sixPercentAmount = totalProfile * 0.06; _salaryOrg.spentAmount = totalAmount; + _salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount; } else { _salaryOrg.currentAmount = salaryOrgSnap1.currentAmount; _salaryOrg.sixPercentAmount = salaryOrgSnap1.sixPercentAmount; @@ -1207,12 +1274,13 @@ export class SalaryPeriodController extends Controller { _salaryOrg.currentAmount = totalProfile; _salaryOrg.sixPercentAmount = totalProfile * 0.06; _salaryOrg.spentAmount = totalAmount; + _salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount; } await this.salaryOrgRepository.save(_salaryOrg); }), ); - } else { + } else if (salaryPeriod.period == "APR") { await Promise.all( salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => { if (snapshot == "SNAP2") { @@ -1228,6 +1296,7 @@ export class SalaryPeriodController extends Controller { _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); } else { _salaryOrg.total = salaryOrgSnap1.total; _salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent; @@ -1239,6 +1308,7 @@ export class SalaryPeriodController extends Controller { _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); } await this.salaryOrgRepository.save(_salaryOrg); @@ -1374,58 +1444,60 @@ export class SalaryPeriodController extends Controller { }), ); - 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"; - } - const salaryOrgNew = await this.salaryOrgRepository.findOne({ - where: { - salaryPeriodId: salaryPeriod.id, - rootId: profile.rootId, - snapshot: snapshot, - group: group, - }, - }); - - if (salaryOrgNew != null) { - let salaryProfileNew = Object.assign(new SalaryProfile(), profile); - 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; - - if (snapshot == "SNAP2") { - const salaryOrgOld = await this.salaryOrgRepository.find({ - where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, - }); - const salaryOld = await this.salaryProfileRepository.findOne({ - where: { - citizenId: salaryProfileNew.citizenId, - salaryOrgId: In(salaryOrgOld.map((x) => x.id)), - }, - }); - salaryProfileNew.type = salaryOld == null ? 0 : 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; + if (salaryPeriod.period != "SPECIAL") { + 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"; } - await this.salaryProfileRepository.save(salaryProfileNew); - } - }), - ); + const salaryOrgNew = await this.salaryOrgRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: profile.rootId, + snapshot: snapshot, + group: group, + }, + }); + + if (salaryOrgNew != null) { + let salaryProfileNew = Object.assign(new SalaryProfile(), profile); + 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; + + if (snapshot == "SNAP2") { + const salaryOrgOld = await this.salaryOrgRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, + }); + const salaryOld = await this.salaryProfileRepository.findOne({ + where: { + citizenId: salaryProfileNew.citizenId, + salaryOrgId: In(salaryOrgOld.map((x) => x.id)), + }, + }); + salaryProfileNew.type = salaryOld == null ? 0 : 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; + } + await this.salaryProfileRepository.save(salaryProfileNew); + } + }), + ); + } const salaryOrgNew = await this.salaryOrgRepository.find({ where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, @@ -1471,6 +1543,7 @@ export class SalaryPeriodController extends Controller { _salaryOrg.currentAmount = totalProfile; _salaryOrg.sixPercentAmount = totalProfile * 0.06; _salaryOrg.spentAmount = totalAmount; + _salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount; } else { _salaryOrg.currentAmount = salaryOrgSnap1.currentAmount; _salaryOrg.sixPercentAmount = salaryOrgSnap1.sixPercentAmount; @@ -1483,12 +1556,13 @@ export class SalaryPeriodController extends Controller { _salaryOrg.currentAmount = totalProfile; _salaryOrg.sixPercentAmount = totalProfile * 0.06; _salaryOrg.spentAmount = totalAmount; + _salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount; } await this.salaryOrgRepository.save(_salaryOrg); }), ); - } else { + } else if (salaryPeriod.period == "APR") { await Promise.all( salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => { if (snapshot == "SNAP2") { @@ -1504,6 +1578,7 @@ export class SalaryPeriodController extends Controller { _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); } else { _salaryOrg.total = salaryOrgSnap1.total; _salaryOrg.fifteenPercent = salaryOrgSnap1.fifteenPercent; @@ -1515,6 +1590,7 @@ export class SalaryPeriodController extends Controller { _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); } await this.salaryOrgRepository.save(_salaryOrg); diff --git a/src/entities/SalaryPeriod.ts b/src/entities/SalaryPeriod.ts index d88a18d..0c3223d 100644 --- a/src/entities/SalaryPeriod.ts +++ b/src/entities/SalaryPeriod.ts @@ -16,6 +16,12 @@ export class SalaryPeriod extends EntityBase { }) isActive: boolean; + @Column({ + comment: "ปิดรอบ", + default: false, + }) + isClose: boolean; + @Column({ nullable: true, type: "datetime", diff --git a/src/entities/SalaryProfile.ts b/src/entities/SalaryProfile.ts index 9c2377a..28a52fa 100644 --- a/src/entities/SalaryProfile.ts +++ b/src/entities/SalaryProfile.ts @@ -233,38 +233,45 @@ export class SalaryProfile extends EntityBase { @Column({ nullable: true, - comment: "ผลการประเมิน", + comment: "ผลการประเมินผลการปฏิบัติราชการ", default: null, }) result: string; @Column({ nullable: true, - comment: "ระยะเวลา", + comment: "ระยะเวลาการปฏิบัติราชการในรอบครึ่งปี", default: null, }) duration: string; @Column({ nullable: true, - comment: "การลงโทษ", - default: null, + comment: "การลงโทษทางวินัย", + default: false, }) - punish: string; + isPunish: boolean; @Column({ nullable: true, comment: "พักราชการ", - default: null, + default: false, }) - retired: string; + isSuspension: boolean; @Column({ nullable: true, comment: "ขาดราชการ", - default: null, + default: false, }) - retired2: string; + isAbsent: boolean; + + @Column({ + nullable: true, + comment: "วันลา", + default: false, + }) + isLeave: boolean; @Column({ nullable: true, @@ -273,6 +280,13 @@ export class SalaryProfile extends EntityBase { }) isRetired: boolean; + @Column({ + nullable: true, + comment: "สำรอง", + default: false, + }) + isReserve: boolean; + @ManyToOne(() => SalaryOrg, (salaryOrg) => salaryOrg.salaryProfiles) @JoinColumn({ name: "salaryOrgId" }) salaryOrg: SalaryOrg; @@ -361,13 +375,16 @@ export class CreateSalaryProfile { duration: string | null; @Column() - punish: string | null; + isPunish: boolean; @Column() - retired: string | null; + isSuspension: boolean; @Column() - retired2: string | null; + isAbsent: boolean; + + @Column() + isLeave: boolean; @Column() isRetired: boolean; diff --git a/src/entities/Salarys.ts b/src/entities/Salarys.ts index dd65fea..c85faf7 100644 --- a/src/entities/Salarys.ts +++ b/src/entities/Salarys.ts @@ -7,10 +7,10 @@ import { PosLevel } from "./PosLevel"; @Entity("salarys") export class Salarys extends EntityBase { @Column({ - comment: "ประเภทผัง", + comment: "ชื่อผัง", length: 255, }) - salaryType: string; + name: string; @Column({ length: 40, @@ -80,9 +80,8 @@ export class Salarys extends EntityBase { } export class CreateSalary { - @Column() - salaryType: string; + name: string; @Column("uuid") posTypeId: string; @@ -94,13 +93,13 @@ export class CreateSalary { isActive: boolean; @Column() - date?: Date; + date?: Date | null; @Column() - startDate?: Date; + startDate?: Date | null; @Column() - endDate?: Date; + endDate?: Date | null; @Column() details?: string | null; @@ -110,9 +109,8 @@ export class CreateSalary { } export class UpdateSalary { - @Column() - salaryType: string; + name: string; @Column("uuid") posTypeId: string; @@ -124,13 +122,13 @@ export class UpdateSalary { isActive: boolean; @Column() - date?: Date; + date?: Date | null; @Column() - startDate?: Date; + startDate?: Date | null; @Column() - endDate?: Date; + endDate?: Date | null; @Column() details?: string | null; @@ -139,4 +137,4 @@ export class UpdateSalary { isSpecial: boolean; } -// export type UpdateSalary = Partial ; \ No newline at end of file +// export type UpdateSalary = Partial ; diff --git a/src/migration/1709797298860-rename_fiels.ts b/src/migration/1709797298860-rename_fiels.ts new file mode 100644 index 0000000..fd2cdef --- /dev/null +++ b/src/migration/1709797298860-rename_fiels.ts @@ -0,0 +1,26 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class RenameFiels1709797298860 implements MigrationInterface { + name = 'RenameFiels1709797298860' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`salarys\` CHANGE \`salaryType\` \`name\` varchar(255) NOT NULL COMMENT 'ประเภทผัง'`); + await queryRunner.query(`ALTER TABLE \`salaryPeriod\` ADD \`isClose\` tinyint NOT NULL COMMENT 'ปิดรอบ' DEFAULT 0`); + await queryRunner.query(`ALTER TABLE \`salarys\` DROP COLUMN \`name\``); + await queryRunner.query(`ALTER TABLE \`salarys\` ADD \`name\` varchar(255) NOT NULL COMMENT 'ชื่อผัง'`); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` CHANGE \`amountSpecial\` \`amountSpecial\` double NOT NULL COMMENT 'เงินพิเศษ' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` CHANGE \`amountUse\` \`amountUse\` double NOT NULL COMMENT 'จำนวนเงินที่ใช้เลื่อน' DEFAULT '0'`); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` CHANGE \`positionSalaryAmount\` \`positionSalaryAmount\` double NOT NULL COMMENT 'เงินเดือนหลังเลื่อน' DEFAULT '0'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`salaryProfile\` CHANGE \`positionSalaryAmount\` \`positionSalaryAmount\` double NULL COMMENT 'เงินเดือนหลังเลื่อน'`); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` CHANGE \`amountUse\` \`amountUse\` double NULL COMMENT 'จำนวนเงินที่ใช้เลื่อน'`); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` CHANGE \`amountSpecial\` \`amountSpecial\` double NULL COMMENT 'เงินพิเศษ'`); + await queryRunner.query(`ALTER TABLE \`salarys\` DROP COLUMN \`name\``); + await queryRunner.query(`ALTER TABLE \`salarys\` ADD \`name\` varchar(255) NOT NULL COMMENT 'ประเภทผัง'`); + await queryRunner.query(`ALTER TABLE \`salaryPeriod\` DROP COLUMN \`isClose\``); + await queryRunner.query(`ALTER TABLE \`salarys\` CHANGE \`name\` \`salaryType\` varchar(255) NOT NULL COMMENT 'ประเภทผัง'`); + } + +} diff --git a/src/migration/1709801227584-update_table_salaryProfile_add_isClose.ts b/src/migration/1709801227584-update_table_salaryProfile_add_isClose.ts new file mode 100644 index 0000000..44eacd1 --- /dev/null +++ b/src/migration/1709801227584-update_table_salaryProfile_add_isClose.ts @@ -0,0 +1,63 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableSalaryProfileAddIsClose1709801227584 implements MigrationInterface { + name = "UpdateTableSalaryProfileAddIsClose1709801227584"; + + public async up(queryRunner: QueryRunner): Promise { + // await queryRunner.query(`ALTER TABLE \`salarys\` CHANGE \`salaryType\` \`name\` varchar(255) NOT NULL COMMENT 'ประเภทผัง'`); + // await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`punish\``); + // await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`retired\``); + // await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`retired2\``); + // await queryRunner.query(`ALTER TABLE \`salaryPeriod\` ADD \`isClose\` tinyint NOT NULL COMMENT 'ปิดรอบ' DEFAULT 0`); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` ADD \`isPunish\` tinyint NULL COMMENT 'การลงโทษทางวินัย' DEFAULT 0`, + ); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` ADD \`isSuspension\` tinyint NULL COMMENT 'พักราชการ' DEFAULT 0`, + ); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` ADD \`isAbsent\` tinyint NULL COMMENT 'ขาดราชการ' DEFAULT 0`, + ); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` ADD \`isLeave\` tinyint NULL COMMENT 'วันลา' DEFAULT 0`, + ); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` ADD \`isReserve\` tinyint NULL COMMENT 'สำรอง' DEFAULT 0`, + ); + // await queryRunner.query(`ALTER TABLE \`salarys\` DROP COLUMN \`name\``); + // await queryRunner.query(`ALTER TABLE \`salarys\` ADD \`name\` varchar(255) NOT NULL COMMENT 'ชื่อผัง'`); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` CHANGE \`result\` \`result\` varchar(255) NULL COMMENT 'ผลการประเมินผลการปฏิบัติราชการ'`, + ); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` CHANGE \`duration\` \`duration\` varchar(255) NULL COMMENT 'ระยะเวลาการปฏิบัติราชการในรอบครึ่งปี'`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` CHANGE \`duration\` \`duration\` varchar(255) NULL COMMENT 'ระยะเวลา'`, + ); + await queryRunner.query( + `ALTER TABLE \`salaryProfile\` CHANGE \`result\` \`result\` varchar(255) NULL COMMENT 'ผลการประเมิน'`, + ); + // await queryRunner.query(`ALTER TABLE \`salarys\` DROP COLUMN \`name\``); + // await queryRunner.query(`ALTER TABLE \`salarys\` ADD \`name\` varchar(255) NOT NULL COMMENT 'ประเภทผัง'`); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`isReserve\``); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`isLeave\``); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`isAbsent\``); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`isSuspension\``); + await queryRunner.query(`ALTER TABLE \`salaryProfile\` DROP COLUMN \`isPunish\``); + // await queryRunner.query(`ALTER TABLE \`salaryPeriod\` DROP COLUMN \`isClose\``); + // await queryRunner.query( + // `ALTER TABLE \`salaryProfile\` ADD \`retired2\` varchar(255) NULL COMMENT 'ขาดราชการ'`, + // ); + // await queryRunner.query( + // `ALTER TABLE \`salaryProfile\` ADD \`retired\` varchar(255) NULL COMMENT 'พักราชการ'`, + // ); + // await queryRunner.query( + // `ALTER TABLE \`salaryProfile\` ADD \`punish\` varchar(255) NULL COMMENT 'การลงโทษ'`, + // ); + // await queryRunner.query(`ALTER TABLE \`salarys\` CHANGE \`name\` \`salaryType\` varchar(255) NOT NULL COMMENT 'ประเภทผัง'`); + } +}