From fa79bb5b7a4df7541fe416e2f8a8e15f5186f037 Mon Sep 17 00:00:00 2001 From: Kittapath Date: Sat, 16 Mar 2024 12:05:54 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B9=80=E0=B8=87=E0=B8=B4=E0=B8=99=E0=B9=80?= =?UTF-8?q?=E0=B8=94=E0=B8=B7=E0=B8=AD=E0=B8=99=E0=B8=A5=E0=B8=B9=E0=B8=81?= =?UTF-8?q?=E0=B8=88=E0=B9=89=E0=B8=B2=E0=B8=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/Report2Controller.ts | 63 +- src/controllers/Report_1_Controller.ts | 524 +++--- src/controllers/SalaryPeriodController.ts | 410 ++++- .../SalaryPeriodEmployeeController.ts | 1595 +++++++++++++++++ src/entities/SalaryOrgEmployee.ts | 150 ++ src/entities/SalaryPeriod.ts | 4 + src/entities/SalaryProfileEmployee.ts | 397 ++++ ...6-update_table_salaryOrg_add_recommend1.ts | 20 + 8 files changed, 2893 insertions(+), 270 deletions(-) create mode 100644 src/controllers/SalaryPeriodEmployeeController.ts create mode 100644 src/entities/SalaryOrgEmployee.ts create mode 100644 src/entities/SalaryProfileEmployee.ts create mode 100644 src/migration/1710564694856-update_table_salaryOrg_add_recommend1.ts diff --git a/src/controllers/Report2Controller.ts b/src/controllers/Report2Controller.ts index 9667744..f3a0cbf 100644 --- a/src/controllers/Report2Controller.ts +++ b/src/controllers/Report2Controller.ts @@ -113,7 +113,11 @@ export class Report2Controller extends Controller { * */ @Get("report2/{rootId}/{salaryPeriodId}/{salaryOrgId}") - async SalaryReport2(@Path() rootId: string, @Path() salaryPeriodId: string, @Path() salaryOrgId: string) { + async SalaryReport2( + @Path() rootId: string, + @Path() salaryPeriodId: string, + @Path() salaryOrgId: string, + ) { // const counts = await AppDataSource.getRepository(SalaryProfile) // .createQueryBuilder("salaryProfile") // .leftJoin("salaryProfile.salaryOrg", "salaryOrg") @@ -243,35 +247,38 @@ export class Report2Controller extends Controller { // }, // select: ["posType", "posLevel"], // }); - - const statistics = await this.salaryProfileRepository.find({ - relations: ["salaryOrg", "salaryOrg.salaryPeriod"], - where: { - salaryOrg: { - id:salaryOrgId, - snapshot: "SNAP1", - group: "GROUP2", - rootId: rootId, - salaryPeriod: { - id: salaryPeriodId, - period: "APR", - }, + + const statistics = await this.salaryProfileRepository.find({ + relations: ["salaryOrg", "salaryOrg.salaryPeriod"], + where: { + salaryOrg: { + id: salaryOrgId, + snapshot: "SNAP1", + group: "GROUP2", + rootId: rootId, + salaryPeriod: { + id: salaryPeriodId, + period: "APR", }, }, - }); - - const notPromoSum = (statistics[0]?.salaryOrg?.total ?? 0) - (statistics[0]?.salaryOrg?.fifteenPercent ?? 0); - const haftCount = statistics?.filter(item => item.type === "HAFT").length ?? 0; - const data = { - group: statistics[0]?.salaryOrg.total?"กลุ่ม 2":"", - total: statistics[0]?.salaryOrg.total?statistics[0]?.salaryOrg.total:"", - fifteenPercent: statistics[0]?.salaryOrg.fifteenPercent?statistics[0]?.salaryOrg.fifteenPercent:"", - full: statistics[0]?.salaryOrg.quantityUsed?statistics[0]?.salaryOrg.quantityUsed:"", - remaining: statistics[0]?.salaryOrg.remainQuota?statistics[0]?.salaryOrg.remainQuota:"", - haft: haftCount, - notPromoted: notPromoSum, - reason: null, - }; + }, + }); + + const notPromoSum = + (statistics[0]?.salaryOrg?.total ?? 0) - (statistics[0]?.salaryOrg?.fifteenPercent ?? 0); + const haftCount = statistics?.filter((item) => item.type === "HAFT").length ?? 0; + const data = { + group: statistics[0]?.salaryOrg.total ? "กลุ่ม 2" : "", + total: statistics[0]?.salaryOrg.total ? statistics[0]?.salaryOrg.total : "", + fifteenPercent: statistics[0]?.salaryOrg.fifteenPercent + ? statistics[0]?.salaryOrg.fifteenPercent + : "", + full: statistics[0]?.salaryOrg.quantityUsed ? statistics[0]?.salaryOrg.quantityUsed : "", + remaining: statistics[0]?.salaryOrg.remainQuota ? statistics[0]?.salaryOrg.remainQuota : "", + haft: haftCount, + notPromoted: notPromoSum, + reason: null, + }; return data; } } diff --git a/src/controllers/Report_1_Controller.ts b/src/controllers/Report_1_Controller.ts index 74d004b..1ddd64d 100644 --- a/src/controllers/Report_1_Controller.ts +++ b/src/controllers/Report_1_Controller.ts @@ -24,7 +24,7 @@ import { In, IsNull, Not, MoreThan } from "typeorm"; import { SalaryProfile } from "../entities/SalaryProfile"; import { SalaryPeriod } from "../entities/SalaryPeriod"; import { SalaryOrg } from "../entities/SalaryOrg"; -import Extension from "../interfaces/extension"; +import Extension from "../interfaces/extension"; @Route("api/v1/salary/report/1") @Tags("Report") @@ -43,213 +43,258 @@ export class Report_1_Controller extends Controller { * API รายงานแบบ 1 กท รอบเมษายน * * @summary รายงานแบบ 1 กท รอบเมษายน - * + * * @param {string} rootId Guid, *Id Root * @param {string} salaryPeriodId Guid, *Id Period */ @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, - rootId: rootId, - snapshot: "SNAP2", - }, - order: { - group: "ASC" - }, - relations: ["salaryProfiles"], + 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, + rootId: rootId, + snapshot: "SNAP2", + }, + order: { + group: "ASC", + }, + relations: ["salaryProfiles"], + }); + const salaryProfile = await this.salaryProfile.find({ - where: { - salaryOrgId: salaryOrg?.id, + where: { + salaryOrgId: salaryOrg?.id, type: "FULL", //หนึ่งขั้น }, select: [ - "id", "prefix" , "firstName", "lastName", "root", - "position", "posType", "posLevel", "orgShortName", - "posMasterNo", "amount", "amountSpecial" - ] + "id", + "prefix", + "firstName", + "lastName", + "root", + "position", + "posType", + "posLevel", + "orgShortName", + "posMasterNo", + "amount", + "amountSpecial", + ], }); const mapData = { - effectiveDate : salaryPeriod?.effectiveDate, + 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), + 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, posMasterNo: Extension.ToThaiNumber(String(item.posMasterNo)), - amount: item.amount == undefined || item.amount == null ? "๐" : Extension.ToThaiNumber(String(item.amount)), + amount: + item.amount == undefined || item.amount == null + ? "๐" + : Extension.ToThaiNumber(String(item.amount)), score: null, //สรุปผลการประเมินฯ ระดับและคะแนน - remark: null //หมายเหตุ - })) - } - return mapData + 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"], + 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}, + where: { salaryOrgId: salaryOrg?.id }, select: [ - "id", "prefix" , "firstName", "lastName", "root", - "position", "posType", "posLevel", "orgShortName", - "posMasterNo", "amount", "amountSpecial" - ] + "id", + "prefix", + "firstName", + "lastName", + "root", + "position", + "posType", + "posLevel", + "orgShortName", + "posMasterNo", + "amount", + "amountSpecial", + ], }); const mapData = { - effectiveDate : salaryPeriod?.effectiveDate, - root: salaryProfile[0]?.root, + 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), + 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+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)), + orgShortName: item.orgShortName + 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)), score: null, //สรุปผลการประเมินฯ ระดับและคะแนน - remark: null //หมายเหตุ - })) - } - return mapData + 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 - }, - }); + 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, "ไม่พบรอบการขึ้นเงินเดือน"); - } + 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 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, + 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 + 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; @@ -259,100 +304,125 @@ export class Report_1_Controller extends Controller { * 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 - }, - }); + 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, "ไม่พบรอบการขึ้นเงินเดือน"); - } + 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 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 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 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, + 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 + 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, + 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 + amount: + item.amount == undefined || item.amount == null + ? "๐" + : Extension.ToThaiNumber(String(item.amount)), + remark: null, })); const mapData = { - profileSpecial, - profileNoAmount - } + profileSpecial, + profileNoAmount, + }; return mapData; } } diff --git a/src/controllers/SalaryPeriodController.ts b/src/controllers/SalaryPeriodController.ts index a0f3198..2ec99c0 100644 --- a/src/controllers/SalaryPeriodController.ts +++ b/src/controllers/SalaryPeriodController.ts @@ -26,6 +26,8 @@ import { PosLevel } from "../entities/PosLevel"; import { Salarys } from "../entities/Salarys"; import { SalaryRanks } from "../entities/SalaryRanks"; import CallAPI from "../interfaces/call-api"; +import { SalaryOrgEmployee } from "../entities/SalaryOrgEmployee"; +import { SalaryProfileEmployee } from "../entities/SalaryProfileEmployee"; @Route("api/v1/salary/period") @Tags("Salary") @@ -33,7 +35,9 @@ import CallAPI from "../interfaces/call-api"; export class SalaryPeriodController extends Controller { private salaryPeriodRepository = AppDataSource.getRepository(SalaryPeriod); private salaryOrgRepository = AppDataSource.getRepository(SalaryOrg); + private salaryOrgEmployeeRepository = AppDataSource.getRepository(SalaryOrgEmployee); private salaryProfileRepository = AppDataSource.getRepository(SalaryProfile); + private salaryProfileEmployeeRepository = AppDataSource.getRepository(SalaryProfileEmployee); private posTypeRepository = AppDataSource.getRepository(PosType); private posLevelRepository = AppDataSource.getRepository(PosLevel); private salaryRepository = AppDataSource.getRepository(Salarys); @@ -1466,6 +1470,16 @@ export class SalaryPeriodController extends Controller { }); await this.salaryProfileRepository.remove(salaryProfile); await this.salaryOrgRepository.remove(salaryOrg); + + const salaryOrgEmployee = await this.salaryOrgEmployeeRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, + }); + const salaryProfileEmployee = await this.salaryProfileEmployeeRepository.find({ + where: { salaryOrgId: In(salaryOrgEmployee.map((x) => x.id)) }, + }); + await this.salaryProfileEmployeeRepository.remove(salaryProfileEmployee); + await this.salaryOrgEmployeeRepository.remove(salaryOrgEmployee); + let orgs = await new CallAPI().GetData(request, "org/unauthorize/active/root/id"); let total = 1000; let _orgProfiles = await new CallAPI().PostData(request, "org/unauthorize/salary/gen", { @@ -1493,6 +1507,37 @@ export class SalaryPeriodController extends Controller { }); } } + total = 1000; + let orgProfileEmployees: any; + let _orgProfileEmployees = await new CallAPI().PostData( + request, + "org/unauthorize/profile/salary/employee/gen", + { + page: 1, + pageSize: 1000, + keyword: "", + year: salaryPeriod.year, + period: salaryPeriod.period, + }, + ); + orgProfileEmployees = _orgProfileEmployees.data; + total = _orgProfileEmployees.total; + if (total > 1000) { + const page = Math.ceil(total / 1000); + for (let index = 2; index <= page; index++) { + await new CallAPI() + .PostData(request, "org/unauthorize/profile/salary/orgProfileEmployees/gen", { + page: index, + pageSize: 1000, + keyword: "", + year: salaryPeriod.year, + period: salaryPeriod.period, + }) + .then((x) => { + Array.prototype.push.apply(orgProfileEmployees, x.data); + }); + } + } let revisionId = await new CallAPI().GetData(request, "org/unauthorize/revision/latest"); salaryPeriod.revisionId = revisionId; @@ -1520,6 +1565,28 @@ export class SalaryPeriodController extends Controller { } }), ); + + await Promise.all( + orgs.map(async (rootId: string) => { + let salaryOrgNew = Object.assign(new SalaryOrgEmployee()); + salaryOrgNew.salaryPeriodId = salaryPeriod.id; + salaryOrgNew.status = "PENDING"; + salaryOrgNew.rootId = rootId; + salaryOrgNew.revisionId = salaryPeriod.revisionId; + salaryOrgNew.snapshot = snapshot; + salaryOrgNew.createdUserId = request.user.sub; + salaryOrgNew.createdFullName = request.user.name; + salaryOrgNew.lastUpdateUserId = request.user.sub; + salaryOrgNew.lastUpdateFullName = request.user.name; + salaryOrgNew.group = "GROUP1"; + await this.salaryOrgRepository.save(salaryOrgNew); + // if (salaryPeriod.period != "SPECIAL") { + // delete salaryOrgNew.id; + // salaryOrgNew.group = "GROUP2"; + // await this.salaryOrgRepository.save(salaryOrgNew); + // } + }), + ); if (salaryPeriod.period != "SPECIAL") { await Promise.all( orgProfiles.map(async (profile: any) => { @@ -1575,12 +1642,58 @@ export class SalaryPeriodController extends Controller { } }), ); + await Promise.all( + orgProfiles.map(async (profile: any) => { + const salaryOrgNew = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: profile.rootId, + snapshot: snapshot, + group: "GROUP1", + }, + }); + + if (salaryOrgNew != null) { + let salaryProfileNew = Object.assign(new SalaryProfileEmployee(), 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.salaryOrgEmployeeRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, + }); + const salaryOld = await this.salaryProfileEmployeeRepository.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; + salaryProfileNew.isNext = salaryOld == null ? false : salaryOld.isNext; + } + await this.salaryProfileEmployeeRepository.save(salaryProfileNew); + } + }), + ); } const salaryOrgNew = await this.salaryOrgRepository.find({ where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, relations: ["salaryProfiles"], }); + const salaryOrgEmployeeNew = await this.salaryOrgEmployeeRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, + relations: ["salaryProfiles"], + }); if (salaryPeriod.period == "OCT") { const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({ where: { @@ -1640,6 +1753,58 @@ export class SalaryPeriodController extends Controller { await this.salaryOrgRepository.save(_salaryOrg); }), ); + await Promise.all( + salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => { + let totalAmount = 0; + if (salaryPeriodAPROld != null) { + const salaryOrgSnap2Old: any = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriodAPROld.id, + rootId: _salaryOrg.rootId, + group: _salaryOrg.group, + snapshot: "SNAP2", + }, + relations: ["salaryProfiles"], + }); + totalAmount = + salaryOrgSnap2Old == null + ? 0 + : Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse"); + } + + if (snapshot == "SNAP2") { + const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: _salaryOrg.rootId, + group: _salaryOrg.group, + snapshot: "SNAP1", + }, + }); + if (salaryOrgSnap1 == null) { + const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount"); + _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; + _salaryOrg.spentAmount = salaryOrgSnap1.spentAmount; + _salaryOrg.useAmount = salaryOrgSnap1.useAmount; + _salaryOrg.remainingAmount = salaryOrgSnap1.remainingAmount; + } + } else { + const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount"); + _salaryOrg.currentAmount = totalProfile; + _salaryOrg.sixPercentAmount = totalProfile * 0.06; + _salaryOrg.spentAmount = totalAmount; + _salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount; + } + + await this.salaryOrgEmployeeRepository.save(_salaryOrg); + }), + ); } else if (salaryPeriod.period == "APR") { await Promise.all( salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => { @@ -1674,6 +1839,39 @@ export class SalaryPeriodController extends Controller { await this.salaryOrgRepository.save(_salaryOrg); }), ); + await Promise.all( + salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => { + if (snapshot == "SNAP2") { + const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: _salaryOrg.rootId, + group: _salaryOrg.group, + snapshot: "SNAP1", + }, + }); + if (salaryOrgSnap1 == null) { + _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; + _salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint; + _salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed; + _salaryOrg.remainQuota = salaryOrgSnap1.remainQuota; + } + } 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); + } + + await this.salaryOrgEmployeeRepository.save(_salaryOrg); + }), + ); } return new HttpSuccess(); @@ -1754,25 +1952,23 @@ export class SalaryPeriodController extends Controller { await this.salaryProfileRepository.remove(salaryProfile); let orgs = await new CallAPI().GetData(request, "org/unauthorize/active/root/id"); - let orgProfiles: any; - await new CallAPI() - .PostData(request, "org/unauthorize/profile/salary/gen", { - page: 1, - pageSize: 100, - keyword: "", - year: salaryPeriod.year, - period: salaryPeriod.period, - }) - .then((x) => { - orgProfiles = x.data; - }); - if (orgProfiles.total > 100) { - const page = Math.ceil(orgProfiles.total.length / 100); + let total = 1000; + let _orgProfiles = await new CallAPI().PostData(request, "org/unauthorize/salary/gen", { + page: 1, + pageSize: 1000, + keyword: "", + year: salaryPeriod.year, + period: salaryPeriod.period, + }); + let orgProfiles = _orgProfiles.data; + total = _orgProfiles.total; + if (total > 1000) { + const page = Math.ceil(total / 1000); for (let index = 2; index <= page; index++) { await new CallAPI() .PostData(request, "org/unauthorize/profile/salary/gen", { page: index, - pageSize: 100, + pageSize: 1000, keyword: "", year: salaryPeriod.year, period: salaryPeriod.period, @@ -1782,6 +1978,37 @@ export class SalaryPeriodController extends Controller { }); } } + total = 1000; + let orgProfileEmployees: any; + let _orgProfileEmployees = await new CallAPI().PostData( + request, + "org/unauthorize/profile/salary/employee/gen", + { + page: 1, + pageSize: 1000, + keyword: "", + year: salaryPeriod.year, + period: salaryPeriod.period, + }, + ); + orgProfileEmployees = _orgProfileEmployees.data; + total = _orgProfileEmployees.total; + if (total > 1000) { + const page = Math.ceil(total / 1000); + for (let index = 2; index <= page; index++) { + await new CallAPI() + .PostData(request, "org/unauthorize/profile/salary/orgProfileEmployees/gen", { + page: index, + pageSize: 1000, + keyword: "", + year: salaryPeriod.year, + period: salaryPeriod.period, + }) + .then((x) => { + Array.prototype.push.apply(orgProfileEmployees, x.data); + }); + } + } let revisionId = await new CallAPI().GetData(request, "org/unauthorize/revision/latest"); salaryPeriod.revisionId = revisionId; @@ -1809,6 +2036,28 @@ export class SalaryPeriodController extends Controller { }), ); + await Promise.all( + orgs.map(async (rootId: string) => { + let salaryOrgNew = Object.assign(new SalaryOrgEmployee()); + salaryOrgNew.salaryPeriodId = salaryPeriod.id; + salaryOrgNew.status = "PENDING"; + salaryOrgNew.rootId = rootId; + salaryOrgNew.revisionId = salaryPeriod.revisionId; + salaryOrgNew.snapshot = snapshot; + salaryOrgNew.createdUserId = request.user.sub; + salaryOrgNew.createdFullName = request.user.name; + salaryOrgNew.lastUpdateUserId = request.user.sub; + salaryOrgNew.lastUpdateFullName = request.user.name; + salaryOrgNew.group = "GROUP1"; + await this.salaryOrgRepository.save(salaryOrgNew); + // if (salaryPeriod.period != "SPECIAL") { + // delete salaryOrgNew.id; + // salaryOrgNew.group = "GROUP2"; + // await this.salaryOrgRepository.save(salaryOrgNew); + // } + }), + ); + if (salaryPeriod.period != "SPECIAL") { await Promise.all( orgProfiles.map(async (profile: any) => { @@ -1863,12 +2112,58 @@ export class SalaryPeriodController extends Controller { } }), ); + await Promise.all( + orgProfiles.map(async (profile: any) => { + const salaryOrgNew = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: profile.rootId, + snapshot: snapshot, + group: "GROUP1", + }, + }); + + if (salaryOrgNew != null) { + let salaryProfileNew = Object.assign(new SalaryProfileEmployee(), 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.salaryOrgEmployeeRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: "SNAP1" }, + }); + const salaryOld = await this.salaryProfileEmployeeRepository.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; + salaryProfileNew.isNext = salaryOld == null ? false : salaryOld.isNext; + } + await this.salaryProfileEmployeeRepository.save(salaryProfileNew); + } + }), + ); } const salaryOrgNew = await this.salaryOrgRepository.find({ where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, relations: ["salaryProfiles"], }); + const salaryOrgEmployeeNew = await this.salaryOrgEmployeeRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, + relations: ["salaryProfiles"], + }); if (salaryPeriod.period == "OCT") { const salaryPeriodAPROld = await this.salaryPeriodRepository.findOne({ where: { @@ -1928,6 +2223,58 @@ export class SalaryPeriodController extends Controller { await this.salaryOrgRepository.save(_salaryOrg); }), ); + await Promise.all( + salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => { + let totalAmount = 0; + if (salaryPeriodAPROld != null) { + const salaryOrgSnap2Old: any = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriodAPROld.id, + rootId: _salaryOrg.rootId, + group: _salaryOrg.group, + snapshot: "SNAP2", + }, + relations: ["salaryProfiles"], + }); + totalAmount = + salaryOrgSnap2Old == null + ? 0 + : Extension.sumObjectValues(salaryOrgSnap2Old.salaryProfiles, "amountUse"); + } + + if (snapshot == "SNAP2") { + const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: _salaryOrg.rootId, + group: _salaryOrg.group, + snapshot: "SNAP1", + }, + }); + if (salaryOrgSnap1 == null) { + const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount"); + _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; + _salaryOrg.spentAmount = salaryOrgSnap1.spentAmount; + _salaryOrg.useAmount = salaryOrgSnap1.useAmount; + _salaryOrg.remainingAmount = salaryOrgSnap1.remainingAmount; + } + } else { + const totalProfile = Extension.sumObjectValues(_salaryOrg.salaryProfiles, "amount"); + _salaryOrg.currentAmount = totalProfile; + _salaryOrg.sixPercentAmount = totalProfile * 0.06; + _salaryOrg.spentAmount = totalAmount; + _salaryOrg.remainingAmount = totalProfile * 0.06 - totalAmount; + } + + await this.salaryOrgEmployeeRepository.save(_salaryOrg); + }), + ); } else if (salaryPeriod.period == "APR") { await Promise.all( salaryOrgNew.map(async (_salaryOrg: SalaryOrg) => { @@ -1962,6 +2309,39 @@ export class SalaryPeriodController extends Controller { await this.salaryOrgRepository.save(_salaryOrg); }), ); + await Promise.all( + salaryOrgEmployeeNew.map(async (_salaryOrg: SalaryOrgEmployee) => { + if (snapshot == "SNAP2") { + const salaryOrgSnap1 = await this.salaryOrgEmployeeRepository.findOne({ + where: { + salaryPeriodId: salaryPeriod.id, + rootId: _salaryOrg.rootId, + group: _salaryOrg.group, + snapshot: "SNAP1", + }, + }); + if (salaryOrgSnap1 == null) { + _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; + _salaryOrg.fifteenPoint = salaryOrgSnap1.fifteenPoint; + _salaryOrg.quantityUsed = salaryOrgSnap1.quantityUsed; + _salaryOrg.remainQuota = salaryOrgSnap1.remainQuota; + } + } 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); + } + + await this.salaryOrgEmployeeRepository.save(_salaryOrg); + }), + ); } } diff --git a/src/controllers/SalaryPeriodEmployeeController.ts b/src/controllers/SalaryPeriodEmployeeController.ts new file mode 100644 index 0000000..1ef6fc9 --- /dev/null +++ b/src/controllers/SalaryPeriodEmployeeController.ts @@ -0,0 +1,1595 @@ +import { + Controller, + Get, + Post, + Put, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + Query, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { In, Not, MoreThan, Brackets } from "typeorm"; +import HttpSuccess from "../interfaces/http-success"; +import HttpError from "../interfaces/http-error"; +import HttpStatusCode from "../interfaces/http-status"; +import { CreateSalaryPeriod, SalaryPeriod, UpdateSalaryPeriod } from "../entities/SalaryPeriod"; +import Extension from "../interfaces/extension"; +import CallAPI from "../interfaces/call-api"; +import { SalaryOrgEmployee } from "../entities/SalaryOrgEmployee"; +import { EmployeePosType } from "../entities/EmployeePosType"; +import { + SalaryProfileEmployee, + CreateSalaryProfileEmployee, +} from "../entities/SalaryProfileEmployee"; +import { EmployeePosLevel } from "../entities/EmployeePosLevel"; +import { SalaryEmployee } from "../entities/SalaryEmployee"; +import { SalaryRankEmployee } from "../entities/SalaryRankEmployee"; + +@Route("api/v1/salary/period-employee") +@Tags("SalaryEmployee") +@Security("bearerAuth") +export class SalaryPeriodEmployeeController extends Controller { + private salaryPeriodRepository = AppDataSource.getRepository(SalaryPeriod); + private salaryOrgRepository = AppDataSource.getRepository(SalaryOrgEmployee); + private salaryProfileRepository = AppDataSource.getRepository(SalaryProfileEmployee); + private posTypeRepository = AppDataSource.getRepository(EmployeePosType); + private posLevelRepository = AppDataSource.getRepository(EmployeePosLevel); + private salaryRepository = AppDataSource.getRepository(SalaryEmployee); + private salaryRankRepository = AppDataSource.getRepository(SalaryRankEmployee); + + /** + * API รอบล่าสุด + * + * @summary SLR_030 - รอบล่าสุด #29 + * + */ + @Post("latest") + async GetGroupSalaryPeriodLatest( + @Body() body: { rootId: string; salaryPeriodId: string; snapshot: string }, + ) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { + id: body.salaryPeriodId, + isActive: true, + }, + order: { effectiveDate: "DESC" }, + relations: ["salaryOrgs"], + }); + if (!salaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + + const data = { + group1id: + salaryPeriod.salaryOrgs.find( + (x) => + x.group == "GROUP1" && + x.rootId == body.rootId && + x.snapshot == body.snapshot.toLocaleUpperCase(), + ) == null + ? null + : salaryPeriod.salaryOrgs.find( + (x) => + x.group == "GROUP1" && + x.rootId == body.rootId && + x.snapshot == body.snapshot.toLocaleUpperCase(), + )?.id, + group2id: + salaryPeriod.salaryOrgs.find( + (x) => + x.group == "GROUP2" && + x.rootId == body.rootId && + x.snapshot == body.snapshot.toLocaleUpperCase(), + ) == null + ? null + : salaryPeriod.salaryOrgs.find( + (x) => + x.group == "GROUP2" && + x.rootId == body.rootId && + x.snapshot == body.snapshot.toLocaleUpperCase(), + )?.id, + effectiveDate: salaryPeriod.effectiveDate, + period: salaryPeriod.period, + }; + return new HttpSuccess(data); + } + + /** + * API จำนวนโควตา + * + * @summary SLR_029 - จำนวนโควตา #28 + * + * @param {string} id Guid, *Id กลุ่ม(salaryOrgId/groupId) + */ + @Get("quota/{id}") + async GetSalaryquotaLatest(@Path() id: string) { + const salaryOrg = await this.salaryOrgRepository.findOne({ + where: { + id: id, + }, + relations: ["salaryProfiles"], + }); + if (!salaryOrg) { + 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, + chosen: salaryOrg.quantityUsed, + remaining: salaryOrg.remainQuota, + currentAmount: salaryOrg.currentAmount, + sixPercentAmount: salaryOrg.sixPercentAmount, + spentAmount: salaryOrg.spentAmount, + sixPercentSpentAmount: salaryOrg.sixPercentAmount - salaryOrg.spentAmount, + useAmount: salaryOrg.useAmount, + remainingAmount: salaryOrg.remainingAmount, + totalAmountSpecial: sum, + totalBackup: salaryOrg.salaryProfiles.filter((x) => x.isReserve == true).length, + status: salaryOrg.status, + }; + return new HttpSuccess(data); + } + + /** + * API ลบคนเลื่อนเงินเดือนในรอบ + * + * @summary SLR_024 - ลบคนเลื่อนเงินเดือนในรอบ #23 + * + * @param {string} id profile Id + */ + @Delete("profile/{id}") + async deleteSalaryProfile(@Path() id: string) { + const salaryProfile = await this.salaryProfileRepository.findOne({ + relations: ["salaryOrg", "salaryOrg.salaryPeriod"], + where: { id: id }, + }); + if (!salaryProfile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ"); + } + + await this.salaryProfileRepository.remove(salaryProfile); + + // หาจำนวน 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); + } else if (salaryProfile.salaryOrg.salaryPeriod.period == "OCT") { + const sumAmountUse = await AppDataSource.getRepository(SalaryProfileEmployee) + .createQueryBuilder("salaryProfile") + .select("SUM(salaryProfile.amountUse)", "totalAmount") + .where({ + salaryOrgId: salaryProfile?.salaryOrg.id, + type: In(["HAFT", "FULL", "FULLHAFT"]), + }) + .getRawOne(); + const calRemainAmount = + salaryProfile.salaryOrg.sixPercentAmount - + sumAmountUse.totalAmount - + salaryProfile.salaryOrg.spentAmount; + salaryProfile.salaryOrg.useAmount = sumAmountUse.totalAmount; + salaryProfile.salaryOrg.remainingAmount = calRemainAmount; + await this.salaryOrgRepository.save(salaryProfile?.salaryOrg); + } + } + + return new HttpSuccess(); + } + + /** + * API แก้ไขเงินเดือน + * + * @summary SLR_025 - แก้ไขเงินเดือน #24 + * + * @param {string} id profile Id + * @param {string} amount ฐานเงินเดือน + */ + @Post("change/amount") + async changeAmount(@Body() body: { profileId: string; amount: number }) { + const salaryProfile = await this.salaryProfileRepository.findOne({ + relations: ["salaryOrg", "salaryOrg.salaryPeriod"], + where: { id: body.profileId }, + }); + if (!salaryProfile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ"); + } + salaryProfile.amount = body.amount; + //Type & Level + const Type = await this.posTypeRepository.findOne({ + where: { + posTypeName: salaryProfile.posType, + }, + }); + if (!Type) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง"); + } + const Level = await this.posLevelRepository.findOne({ + where: { + posTypeId: Type.id, + posLevelName: salaryProfile.posLevel, + }, + }); + if (!Level) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง"); + } + let type = salaryProfile.type; + let salaryRanks: any = null; + // //Salary + // const salarys = await this.salaryRepository.findOne({ + // where: { + // posTypeId: Level.posTypeId, + // posLevelId: Level.id, + // isActive: true, + // }, + // }); + // if (!salarys) { + // throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง"); + // } + // let type = salaryProfile.type; + // //SalaryRank + // let salaryRanks: any = null; + // if (salaryProfile.amount != null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryProfile.amount, + // isNext: false, + // }, + // }); + // if (salaryRanks == null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: MoreThan(salaryProfile.amount), + // isNext: false, + // }, + // order: { salary: "DESC" }, + // }); + // } + // if (salaryRanks != null) { + // if (salaryProfile.type == "HAFT") { + // if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryHalf, + // isNext: true, + // }, + // }); + // } + // } else if (salaryProfile.type == "FULL") { + // if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) { + // if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) { + // type = "HAFT"; + // } + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryFull, + // isNext: true, + // }, + // }); + // } + // } else if (salaryProfile.type == "FULLHAFT") { + // if (salaryRanks.salaryFullHalfSpecial != null && salaryRanks.salaryFullHalfSpecial > 0) { + // if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) { + // type = "HAFT"; + // } else if ( + // salaryRanks.salaryHalfSpecial == null || + // salaryRanks.salaryHalfSpecial == 0 + // ) { + // type = "FULL"; + // } + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryFullHalf, + // isNext: true, + // }, + // }); + // } + // } + // } else { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryProfile.amount, + // isNext: true, + // }, + // }); + // if (salaryRanks == null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: MoreThan(salaryProfile.amount), + // isNext: true, + // }, + // order: { salary: "DESC" }, + // }); + // } + // } + // } + + salaryProfile.isNext = false; + if (type == "NONE") { + salaryProfile.amountSpecial = 0; + salaryProfile.amountUse = 0; + salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount; + } else if (type == "PENDING") { + salaryProfile.amountSpecial = 0; + salaryProfile.amountUse = 0; + salaryProfile.positionSalaryAmount = 0; + } else if (type == "HAFT") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryHalfSpecial == null + ? 0 + : salaryRanks.salaryHalfSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryHalf == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryHalf - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else if (type == "FULL") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryFullSpecial == null + ? 0 + : salaryRanks.salaryFullSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryFull == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryFull - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else if (type == "FULLHAFT") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null + ? 0 + : salaryRanks.salaryFullHalfSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryFullHalf == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryFullHalf - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง"); + } + + await this.salaryProfileRepository.save(salaryProfile); + + // หาจำนวน Quota คงเหลือ + if (salaryProfile.salaryOrg.snapshot == "SNAP1") { + if (salaryProfile.salaryOrg.salaryPeriod.period == "APR") { + 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(SalaryProfileEmployee) + .createQueryBuilder("salaryProfile") + .select("SUM(salaryProfile.amountUse)", "totalAmount") + .where({ + salaryOrgId: salaryProfile?.salaryOrg.id, + type: In(["HAFT", "FULL", "FULLHAFT"]), + }) + .getRawOne(); + const calRemainAmount = + salaryProfile.salaryOrg.sixPercentAmount - + sumAmountUse.totalAmount - + salaryProfile.salaryOrg.spentAmount; + salaryProfile.salaryOrg.useAmount = sumAmountUse.totalAmount; + salaryProfile.salaryOrg.remainingAmount = calRemainAmount; + await this.salaryOrgRepository.save(salaryProfile?.salaryOrg); + } + } + return new HttpSuccess(); + } + + /** + * API ย้ายกลุ่ม + * + * @summary SLR_026 - ย้ายกลุ่ม #25 + * + * @param {string} id profile Id + * @param {string} groupId groupId + */ + @Post("change/group") + async changeGroup(@Body() body: { profileId: string; groupId: string }) { + const salaryProfile = await this.salaryProfileRepository.findOne({ + relations: ["salaryOrg", "salaryOrg.salaryPeriod"], + where: { id: body.profileId }, + }); + if (!salaryProfile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ"); + } + const salaryOrg = await this.salaryOrgRepository.findOne({ + relations: ["salaryPeriod"], + where: { id: body.groupId }, + }); + if (!salaryOrg) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลกลุ่มการขอเลื่อนเงินเดือน"); + } + + salaryProfile.salaryOrgId = salaryOrg.id; + await this.salaryProfileRepository.save(salaryProfile); + if (salaryOrg) { + // หาจำนวน Quota คงเหลือ + if (salaryOrg.snapshot == "SNAP1") { + if (salaryOrg.salaryPeriod.period == "APR") { + 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(SalaryProfileEmployee) + .createQueryBuilder("salaryProfile") + .select("SUM(salaryProfile.amountUse)", "totalAmount") + .where({ + salaryOrgId: salaryOrg.id, + type: In(["HAFT", "FULL", "FULLHAFT"]), + }) + .getRawOne(); + const calRemainAmount = + salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount; + salaryOrg.useAmount = sumAmountUse.totalAmount; + salaryOrg.remainingAmount = calRemainAmount; + await this.salaryOrgRepository.save(salaryOrg); + } + } + } + return new HttpSuccess(); + } + + /** + * API แก้ไขขั้น + * + * @summary SLR_025 - แก้ไขขั้น #24 + * + * @param {string} id profile Id + * @param {string} type ประเภทการเลื่อน NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น + */ + @Post("change/type") + async changeType(@Body() body: { profileId: string; type: string; isReserve: boolean }) { + const salaryProfile = await this.salaryProfileRepository.findOne({ + relations: ["salaryOrg", "salaryOrg.salaryPeriod"], + where: { id: body.profileId }, + }); + if (!salaryProfile) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการขอเงินเดือนผู้ใช้งานนี้ในระบบ"); + } + body.type = body.type.toUpperCase(); + + //ตรวจสอบงวดเมษาว่าเลื่อนกี่ขั้น + if (body.type == "FULLHAFT") { + if (salaryProfile?.salaryOrg?.salaryPeriod?.period === "OCT") { + const checkPreviousType = await this.salaryProfileRepository.findOne({ + relations: ["salaryOrg", "salaryOrg.salaryPeriod"], + where: { + citizenId: salaryProfile?.citizenId, + salaryOrg: { + salaryPeriod: { + period: "APR", + year: salaryProfile?.salaryOrg?.salaryPeriod?.year, //ปีที่ตรงกันด้วย + }, + snapshot: "SNAP2", + }, + type: "FULL", + }, + }); + if (checkPreviousType) { + throw new HttpError( + HttpStatusCode.NOT_FOUND, + "ไม่สามารถเลื่อนขั้นบุคลากรเกิน 2 ขั้นต่อปีได้", + ); + } + } + } + + //Type & Level + const Type = await this.posTypeRepository.findOne({ + where: { + posTypeName: salaryProfile.posType, + }, + }); + if (!Type) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง"); + } + const Level = await this.posLevelRepository.findOne({ + where: { + posTypeId: Type.id, + posLevelName: salaryProfile.posLevel, + }, + }); + if (!Level) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง"); + } + let type = salaryProfile.type; + let salaryRanks: any = null; + // //Salary + // const salarys = await this.salaryRepository.findOne({ + // where: { + // posTypeId: Level.posTypeId, + // posLevelId: Level.id, + // isActive: true, + // }, + // }); + // if (!salarys) { + // throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง"); + // } + // salaryProfile.type = body.type; + // salaryProfile.isReserve = body.isReserve; + // let type = salaryProfile.type; + // //SalaryRank + // let salaryRanks: any = null; + // if (salaryProfile.amount != null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryProfile.amount, + // isNext: false, + // }, + // }); + // if (salaryRanks == null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: MoreThan(salaryProfile.amount), + // isNext: false, + // }, + // order: { salary: "DESC" }, + // }); + // } + // if (salaryRanks != null) { + // if (salaryProfile.type == "HAFT") { + // if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryHalf, + // isNext: true, + // }, + // }); + // } + // } else if (salaryProfile.type == "FULL") { + // if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) { + // if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) { + // type = "HAFT"; + // } + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryFull, + // isNext: true, + // }, + // }); + // } + // } else if (salaryProfile.type == "FULLHAFT") { + // if (salaryRanks.salaryFullHalfSpecial != null && salaryRanks.salaryFullHalfSpecial > 0) { + // if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) { + // type = "HAFT"; + // } else if ( + // salaryRanks.salaryHalfSpecial == null || + // salaryRanks.salaryHalfSpecial == 0 + // ) { + // type = "FULL"; + // } + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryFullHalf, + // isNext: true, + // }, + // }); + // } + // } + // } else { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryProfile.amount, + // isNext: true, + // }, + // }); + // if (salaryRanks == null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: MoreThan(salaryProfile.amount), + // isNext: true, + // }, + // order: { salary: "DESC" }, + // }); + // } + // } + // } + + salaryProfile.isNext = false; + if (type == "NONE") { + salaryProfile.amountSpecial = 0; + salaryProfile.amountUse = 0; + salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount; + } else if (type == "PENDING") { + salaryProfile.amountSpecial = 0; + salaryProfile.amountUse = 0; + salaryProfile.positionSalaryAmount = 0; + } else if (type == "HAFT") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryHalfSpecial == null + ? 0 + : salaryRanks.salaryHalfSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryHalf == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryHalf - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else if (type == "FULL") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryFullSpecial == null + ? 0 + : salaryRanks.salaryFullSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryFull == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryFull - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else if (type == "FULLHAFT") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null + ? 0 + : salaryRanks.salaryFullHalfSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryFullHalf == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryFullHalf - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง"); + } + await this.salaryProfileRepository.save(salaryProfile); + + if (salaryProfile.salaryOrg) { + // หาจำนวน Quota คงเหลือ + if (salaryProfile.salaryOrg.snapshot == "SNAP1") { + if (salaryProfile.salaryOrg.salaryPeriod.period == "APR") { + 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(SalaryProfileEmployee) + .createQueryBuilder("salaryProfile") + .select("SUM(salaryProfile.amountUse)", "totalAmount") + .where({ + salaryOrgId: salaryProfile.salaryOrg.id, + type: In(["HAFT", "FULL", "FULLHAFT"]), + }) + .getRawOne(); + const calRemainAmount = + salaryProfile.salaryOrg.sixPercentAmount - + sumAmountUse.totalAmount - + salaryProfile.salaryOrg.spentAmount; + salaryProfile.salaryOrg.useAmount = sumAmountUse.totalAmount; + salaryProfile.salaryOrg.remainingAmount = calRemainAmount; + await this.salaryOrgRepository.save(salaryProfile.salaryOrg); + } + } + } + return new HttpSuccess(); + } + + /** + * API รายการอัตราเงินเดือน + * + * @summary SLR_023 - รายการอัตราเงินเดือน #22 + * + */ + @Put("org/{id}") + async GetListsSalaryProfile( + @Path() id: string, + @Body() + body: { + page: number; + pageSize: number; + keyword?: string; + type?: any; + isRetire?: boolean | null; + }, + ) { + const salaryOrg = await this.salaryOrgRepository.findOne({ + where: { + id: id, + }, + }); + if (!salaryOrg) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + const [salaryProfile, total] = await AppDataSource.getRepository(SalaryProfileEmployee) + .createQueryBuilder("profile") + .andWhere( + new Brackets((qb) => { + qb.andWhere(body.type != null && body.type != "" ? `profile.type LIKE :type` : "1=1", { + type: body.type == null ? "" : `${body.type.toUpperCase()}`, + }) + .andWhere(body.isRetire != null ? `profile.isRetired = ${body.isRetire}` : "1=1") + .andWhere({ + salaryOrgId: salaryOrg.id, + }) + .andWhere( + new Brackets((qb) => { + qb.orWhere("profile.posMasterNoPrefix LIKE :keyword", { + keyword: `%${body.keyword}%`, + }) + .orWhere("profile.posMasterNo LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.posMasterNoSuffix LIKE :keyword", { + keyword: `%${body.keyword}%`, + }) + .orWhere("profile.orgShortName LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.prefix LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.firstName LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.lastName LIKE :keyword", { keyword: `%${body.keyword}%` }) + // .orWhere("profile.citizenId LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.position LIKE :keyword", { keyword: `%${body.keyword}%` }) + // .orWhere("profile.posType LIKE :keyword", { keyword: `%${body.keyword}%` }) + // .orWhere("profile.posLevel LIKE :keyword", { keyword: `%${body.keyword}%` }) + // .orWhere("profile.posExecutive LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.amount LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.amountSpecial LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.amountUse LIKE :keyword", { keyword: `%${body.keyword}%` }) + .orWhere("profile.positionSalaryAmount LIKE :keyword", { + keyword: `%${body.keyword}%`, + }); + }), + ); + }), + ) + .orderBy("profile.citizenId", "ASC") + .addOrderBy("profile.isReserve", "ASC") + .skip((body.page - 1) * body.pageSize) + .take(body.pageSize) + .getManyAndCount(); + + return new HttpSuccess({ data: salaryProfile, total }); + } + + /** + * API แก้คุณสมบัติ + * + * @summary SLR_031 - แก้คุณสมบัติ #30 + * + */ + @Put("org/property/{id}") + async editProperty( + @Path() id: string, + @Body() + body: { + isPunish: any; + isSuspension: any; + isAbsent: any; + isLeave: any; + }, + @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 เพิ่มคนเลื่อนเงินเดือนตามรอบ + * + * @summary SLR_028 - เพิ่มคนเลื่อนเงินเดือนตามรอบ #27 + * + */ + @Post("org/profile") + async addSalaryProfile( + @Body() requestBody: CreateSalaryProfileEmployee, + @Request() request: { user: Record }, + ) { + const salaryOrg = await this.salaryOrgRepository.findOne({ + relations: ["salaryPeriod", "salaryProfiles"], + where: { + id: requestBody.id, + }, + }); + if (!salaryOrg) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + + const salaryOrgAll = await this.salaryOrgRepository.find({ + where: { + salaryPeriodId: salaryOrg.salaryPeriodId, + snapshot: salaryOrg.snapshot, + }, + }); + if (!salaryOrgAll) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + const salaryProfileAll = await this.salaryProfileRepository.findOne({ + where: { + salaryOrgId: In(salaryOrgAll.map((x) => x.id)), + citizenId: requestBody.citizenId, + // prefix: requestBody.prefix, + // firstName: requestBody.firstName, + // lastName: requestBody.lastName, + }, + }); + if (salaryProfileAll != null) { + throw new HttpError( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "ไม่สามารถเพิ่มรายชื่อนี้ได้ เนื่องจากมีการยื่นขอเลื่อนเงินเดือนแล้ว", + ); + } + + let salaryProfile: any = Object.assign(new SalaryProfileEmployee(), requestBody); + delete salaryProfile.id; + salaryProfile.type = salaryProfile.type.toUpperCase(); + //Type & Level + const posType = await this.posTypeRepository.findOne({ + where: { + posTypeName: salaryProfile.posType, + }, + }); + if (!posType) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทตำแหน่ง"); + } + const posLevel = await this.posLevelRepository.findOne({ + where: { + posTypeId: posType.id, + posLevelName: salaryProfile.posLevel, + }, + }); + if (!posLevel) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง"); + } + let type = salaryProfile.type; + let salaryRanks: any = null; + // //Salary + // const salarys = await this.salaryRepository.findOne({ + // where: { + // posTypeId: posLevel.posTypeId, + // posLevelId: posLevel.id, + // isActive: true, + // }, + // }); + // if (!salarys) { + // throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบระดับตำแหน่ง"); + // } + // //SalaryRank + // if (salaryProfile.amount != null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryProfile.amount, + // isNext: false, + // }, + // }); + // if (salaryRanks == null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: MoreThan(salaryProfile.amount), + // isNext: false, + // }, + // order: { salary: "DESC" }, + // }); + // } + // if (salaryRanks != null) { + // if (salaryProfile.type == "HAFT") { + // if (salaryRanks.salaryHalfSpecial != null && salaryRanks.salaryHalfSpecial > 0) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryHalf, + // isNext: true, + // }, + // }); + // } + // } else if (salaryProfile.type == "FULL") { + // if (salaryRanks.salaryFullSpecial != null && salaryRanks.salaryFullSpecial > 0) { + // if (salaryRanks.salaryHalfSpecial == null || salaryRanks.salaryHalfSpecial == 0) { + // type = "HAFT"; + // } + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryFull, + // isNext: true, + // }, + // }); + // } + // } else if (salaryProfile.type == "FULLHAFT") { + // if (salaryRanks.salaryFullHalfSpecial != null && salaryRanks.salaryFullHalfSpecial > 0) { + // if (salaryRanks.salaryFullSpecial == null || salaryRanks.salaryFullSpecial == 0) { + // type = "HAFT"; + // } else if ( + // salaryRanks.salaryHalfSpecial == null || + // salaryRanks.salaryHalfSpecial == 0 + // ) { + // type = "FULL"; + // } + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryRanks.salaryFullHalf, + // isNext: true, + // }, + // }); + // } + // } + // } else { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: salaryProfile.amount, + // isNext: true, + // }, + // }); + // if (salaryRanks == null) { + // salaryRanks = await this.salaryRankRepository.findOne({ + // where: { + // salaryId: salarys.id, + // salary: MoreThan(salaryProfile.amount), + // isNext: true, + // }, + // order: { salary: "DESC" }, + // }); + // } + // } + // } + + salaryProfile.isNext = false; + if (type == "NONE") { + salaryProfile.amountSpecial = 0; + salaryProfile.amountUse = 0; + salaryProfile.positionSalaryAmount = salaryProfile.amount == null ? 0 : salaryProfile.amount; + } else if (type == "PENDING") { + salaryProfile.amountSpecial = 0; + salaryProfile.amountUse = 0; + salaryProfile.positionSalaryAmount = 0; + } else if (type == "HAFT") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryHalfSpecial == null + ? 0 + : salaryRanks.salaryHalfSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryHalf == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryHalf - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryHalf == null ? 0 : salaryRanks.salaryHalf; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else if (type == "FULL") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryFullSpecial == null + ? 0 + : salaryRanks.salaryFullSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryFull == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryFull - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryFull == null ? 0 : salaryRanks.salaryFull; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else if (type == "FULLHAFT") { + salaryProfile.amountSpecial = + salaryRanks == null || salaryRanks.salaryFullHalfSpecial == null + ? 0 + : salaryRanks.salaryFullHalfSpecial; + salaryProfile.amountUse = + salaryRanks == null || + salaryProfile == null || + salaryRanks.salaryFullHalf == null || + salaryProfile.amount == null + ? 0 + : salaryRanks.salaryFullHalf - salaryProfile.amount; + salaryProfile.positionSalaryAmount = + salaryRanks == null || salaryRanks.salaryFullHalf == null ? 0 : salaryRanks.salaryFullHalf; + salaryProfile.isNext = salaryRanks == null ? 0 : salaryRanks.isNext; + } else { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทการเลื่อนขึ้นเงินเดือนไม่ถูกต้อง"); + } + + salaryProfile.salaryOrgId = salaryOrg.id; + salaryProfile.createdUserId = request.user.sub; + salaryProfile.createdFullName = request.user.name; + salaryProfile.lastUpdateUserId = request.user.sub; + salaryProfile.lastUpdateFullName = request.user.name; + await this.salaryProfileRepository.save(salaryProfile); + + // หาจำนวน Quota คงเหลือ + if (salaryOrg.snapshot == "SNAP1") { + const _salaryOrg = await this.salaryOrgRepository.findOne({ + where: { + id: salaryOrg.id, + }, + }); + if (!_salaryOrg) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบรอบการขึ้นเงินเดือน"); + } + 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, + 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 totalProfile = Extension.sumObjectValues(salaryOrg.salaryProfiles, "amount"); + _salaryOrg.currentAmount = totalProfile; + _salaryOrg.sixPercentAmount = totalProfile * 0.06; + + const sumAmountUse = await AppDataSource.getRepository(SalaryProfileEmployee) + .createQueryBuilder("salaryProfile") + .select("SUM(salaryProfile.amountUse)", "totalAmount") + .where({ + salaryOrgId: salaryOrg.id, + type: In(["HAFT", "FULL", "FULLHAFT"]), + }) + .getRawOne(); + const calRemainAmount = + salaryOrg.sixPercentAmount - sumAmountUse.totalAmount - salaryOrg.spentAmount; + _salaryOrg.useAmount = sumAmountUse.totalAmount; + _salaryOrg.remainingAmount = calRemainAmount; + await this.salaryOrgRepository.save(_salaryOrg); + } + } + + 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 สร้างรอบเงินเดือน + * + * @summary SLR_016 - สร้างรอบเงินเดือน #16 + * + */ + @Post() + async create_salary_period( + @Body() requestBody: CreateSalaryPeriod, + @Request() request: { user: Record }, + ) { + const salaryPeriod = Object.assign(new SalaryPeriod(), requestBody); + + const chk_toUpper = ["SPECIAL", "APR", "OCT"]; + if (!chk_toUpper.includes(salaryPeriod.period.toUpperCase())) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง"); + } + + const chk_period = await this.salaryPeriodRepository.findOne({ + where: { + period: salaryPeriod.period, + year: requestBody.year, + }, + }); + + if (chk_period) { + throw new HttpError( + HttpStatusCode.NOT_FOUND, + "ประเภทผังปี " + Extension.ToThaiYear(salaryPeriod.year) + " ซ้ำ", + ); + } + + salaryPeriod.period = salaryPeriod.period.toUpperCase(); + salaryPeriod.createdUserId = request.user.sub; + salaryPeriod.createdFullName = request.user.name; + salaryPeriod.lastUpdateUserId = request.user.sub; + salaryPeriod.lastUpdateFullName = request.user.name; + await this.salaryPeriodRepository.save(salaryPeriod); + + if (salaryPeriod.period == "SPECIAL") { + const snapshot = "SNAP1"; + const salaryOrg = await this.salaryOrgRepository.find({ + where: { salaryPeriodId: salaryPeriod.id, snapshot: snapshot }, + }); + const salaryProfile = await this.salaryProfileRepository.find({ + where: { salaryOrgId: In(salaryOrg.map((x) => x.id)) }, + }); + await this.salaryOrgRepository.remove(salaryOrg); + await this.salaryProfileRepository.remove(salaryProfile); + + let orgs = await new CallAPI().GetData(request, "org/unauthorize/active/root/id"); + let revisionId = await new CallAPI().GetData(request, "org/unauthorize/revision/latest"); + + salaryPeriod.revisionId = revisionId; + await this.salaryPeriodRepository.save(salaryPeriod); + + await Promise.all( + orgs.map(async (rootId: string) => { + let salaryOrgNew = Object.assign(new SalaryOrgEmployee()); + salaryOrgNew.salaryPeriodId = salaryPeriod.id; + salaryOrgNew.status = "PENDING"; + salaryOrgNew.rootId = rootId; + salaryOrgNew.revisionId = salaryPeriod.revisionId; + salaryOrgNew.snapshot = snapshot; + salaryOrgNew.createdUserId = request.user.sub; + salaryOrgNew.createdFullName = request.user.name; + salaryOrgNew.lastUpdateUserId = request.user.sub; + salaryOrgNew.lastUpdateFullName = request.user.name; + salaryOrgNew.group = "GROUP1"; + await this.salaryOrgRepository.save(salaryOrgNew); + }), + ); + } + return new HttpSuccess(salaryPeriod.id); + } + + /** + * API แก้ไขรอบเงินเดือน + * + * @summary SLR_017 - แก้ไขรอบเงินเดือน #17 + * + * @param {string} id Guid, *Id รอบเงินเดือน + */ + @Put("{id}") + async update_salary_period( + @Path() id: string, + @Body() requestBody: UpdateSalaryPeriod, + @Request() request: { user: Record }, + ) { + const chk_SalaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: id }, + }); + if (!chk_SalaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + } + + const chk_toUpper = ["SPECIAL", "APR", "OCT"]; + if (!chk_toUpper.includes(requestBody.period.toUpperCase())) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง"); + } + const chk_period = await this.salaryPeriodRepository.findOne({ + where: { + period: requestBody.period, + id: Not(id), + year: requestBody.year, + }, + }); + + if (chk_period) { + throw new HttpError( + HttpStatusCode.NOT_FOUND, + "ประเภทผังปี " + (requestBody.effectiveDate.getFullYear() + 543) + " ซ้ำ", + ); + } + + chk_SalaryPeriod.period = requestBody.period.toUpperCase(); + chk_SalaryPeriod.lastUpdateUserId = request.user.sub; + chk_SalaryPeriod.lastUpdateFullName = request.user.name; + chk_SalaryPeriod.lastUpdatedAt = new Date(); + this.salaryPeriodRepository.merge(chk_SalaryPeriod, requestBody); + await this.salaryPeriodRepository.save(chk_SalaryPeriod); + if (chk_SalaryPeriod.period == "SPECIAL") { + const snapshot = "SNAP1"; + const salaryOrg = await this.salaryOrgRepository.find({ + where: { salaryPeriodId: chk_SalaryPeriod.id, snapshot: snapshot }, + }); + const salaryProfile = await this.salaryProfileRepository.find({ + where: { salaryOrgId: In(salaryOrg.map((x) => x.id)) }, + }); + await this.salaryOrgRepository.remove(salaryOrg); + await this.salaryProfileRepository.remove(salaryProfile); + + let orgs = await new CallAPI().GetData(request, "org/unauthorize/active/root/id"); + let revisionId = await new CallAPI().GetData(request, "org/unauthorize/revision/latest"); + + chk_SalaryPeriod.revisionId = revisionId; + await this.salaryPeriodRepository.save(chk_SalaryPeriod); + + await Promise.all( + orgs.map(async (rootId: string) => { + let salaryOrgNew = Object.assign(new SalaryOrgEmployee()); + salaryOrgNew.salaryPeriodId = chk_SalaryPeriod.id; + salaryOrgNew.status = "PENDING"; + salaryOrgNew.rootId = rootId; + salaryOrgNew.revisionId = chk_SalaryPeriod.revisionId; + salaryOrgNew.snapshot = snapshot; + salaryOrgNew.createdUserId = request.user.sub; + salaryOrgNew.createdFullName = request.user.name; + salaryOrgNew.lastUpdateUserId = request.user.sub; + salaryOrgNew.lastUpdateFullName = request.user.name; + salaryOrgNew.group = "GROUP1"; + await this.salaryOrgRepository.save(salaryOrgNew); + }), + ); + } + return new HttpSuccess(id); + } + + /** + * API ลบรอบเงินเดือน + * + * @summary SLR_018 - ลบรอบเงินเดือน #18 + * + * @param {string} id Guid, *Id รอบเงินเดือน + */ + @Delete("{id}") + async delete_salary_period(@Path() id: string) { + const SalaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: id }, + }); + if (!SalaryPeriod) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + + if (SalaryPeriod?.period == "SPECIAL") { + const SalaryOrg = await this.salaryOrgRepository.find({ + where: { salaryPeriodId: SalaryPeriod.id }, + relations: ["salaryProfiles"], + }); + const salaryProfile = SalaryOrg.find((x) => x.salaryProfiles.length > 0); + if (salaryProfile) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้"); + + await this.salaryOrgRepository.remove(SalaryOrg); + await this.salaryPeriodRepository.remove(SalaryPeriod); + return new HttpSuccess(); + } else { + const SalaryOrg = await this.salaryOrgRepository.findOne({ + where: { salaryPeriodId: SalaryPeriod.id }, + }); + if (SalaryOrg) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบได้"); + + await this.salaryPeriodRepository.remove(SalaryPeriod); + return new HttpSuccess(); + } + } + + /** + * API รายการรอบเงินเดือน(active) + * + * + */ + @Get("active") + async GetListsSalaryPeriodActive( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, + @Query("keyword") keyword?: string, + ) { + const [salaryPeriod, total] = await AppDataSource.getRepository(SalaryPeriod) + .createQueryBuilder("salaryPeriod") + .where({ isActive: true }) + .select([ + "salaryPeriod.id", + "salaryPeriod.period", + "salaryPeriod.isActive", + "salaryPeriod.isClose", + "salaryPeriod.effectiveDate", + "salaryPeriod.status", + "salaryPeriod.year", + "salaryPeriod.revisionId", + ]) + .orderBy("salaryPeriod.effectiveDate", "DESC") + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); + + return new HttpSuccess({ data: salaryPeriod, total }); + } + + /** + * API รายละเอียดรอบเงินเดือน + * + * @summary SLR_019 - รายละเอียดรอบเงินเดือน #19 + * + * @param {string} id Guid, *Id รอบเงินเดือน + */ + @Get("{id}") + async GetSalaryPeriod_ById(@Path() id: string) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: id }, + select: [ + "id", + "period", + "isActive", + "effectiveDate", + "isClose", + "status", + "year", + "revisionId", + ], + }); + if (!salaryPeriod) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + } + return new HttpSuccess(salaryPeriod); + } + + /** + * API รายการรอบเงินเดือน + * + * @summary SLR_020 - รายการรอบเงินเดือน #20 + * + */ + @Get() + async GetListsSalaryPeriod( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, + @Query("keyword") keyword?: string, + @Query("year") year: number = 2024, + ) { + const [salaryPeriod, total] = await AppDataSource.getRepository(SalaryPeriod) + .createQueryBuilder("salaryPeriod") + .andWhere(year != 0 ? "salaryPeriod.year LIKE :year" : "1=1", { year: `${year}` }) + .orWhere("salaryPeriod.period LIKE :keyword", { keyword: `${keyword}` }) + // .orWhere("salaryPeriod.isActive LIKE :keyword", { keyword: `${keyword}` }) + .select([ + "salaryPeriod.id", + "salaryPeriod.period", + "salaryPeriod.isActive", + "salaryPeriod.isClose", + "salaryPeriod.effectiveDate", + "salaryPeriod.status", + "salaryPeriod.year", + "salaryPeriod.revisionId", + ]) + .orderBy("salaryPeriod.effectiveDate", "DESC") + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); + + return new HttpSuccess({ data: salaryPeriod, total }); + } + + /** + * API เจ้าหน้าที่ส่ง ผอ + * + * + * @param {string} periodId Guid, *Id รอบเงินเดือน + * @param {string} rootId Guid, *Id สำนัก + */ + @Get("officer/approve/{periodId}/{rootId}") + async OfficerApprove(@Path() periodId: string, rootId: string) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: periodId }, + relations: ["salaryOrgs"], + }); + if (!salaryPeriod) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + await Promise.all( + salaryPeriod.salaryOrgs.map(async (x) => { + x.status = "WAITHEAD1"; + await this.salaryPeriodRepository.save(salaryPeriod); + }), + ); + return new HttpSuccess(); + } + + /** + * API ผอ ส่ง สกจ + * + * + * @param {string} orgId Guid, *Id รอบเงินเดือน + * @param {string} rootId Guid, *Id สำนัก + */ + @Get("head/approve/{periodId}/{rootId}") + async HeadApprove(@Path() periodId: string, rootId: string) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: periodId }, + relations: ["salaryOrgs"], + }); + if (!salaryPeriod) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + + await Promise.all( + salaryPeriod.salaryOrgs + .filter((x) => x.rootId == rootId) + .map(async (x) => { + x.status = "WAITOWNER1"; + await this.salaryPeriodRepository.save(salaryPeriod); + }), + ); + return new HttpSuccess(); + } + + /** + * API สกจ อนุมัติ + * + * + * @param {string} orgId Guid, *Id รอบเงินเดือน + * @param {string} rootId Guid, *Id สำนัก + */ + @Get("owner/approve/{periodId}/{rootId}") + async OwnerApprove(@Path() periodId: string, rootId: string) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: periodId }, + relations: ["salaryOrgs"], + }); + if (!salaryPeriod) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + + await Promise.all( + salaryPeriod.salaryOrgs + .filter((x) => x.rootId == rootId) + .map(async (x) => { + x.status = "REPORT"; + await this.salaryPeriodRepository.save(salaryPeriod); + }), + ); + return new HttpSuccess(); + } + + /** + * API สกจ ส่ง ผอ + * + * + * @param {string} orgId Guid, *Id รอบเงินเดือน + * @param {string} rootId Guid, *Id สำนัก + */ + @Put("owner/comment/{periodId}/{rootId}") + async WaitOwnerApprove( + @Path() periodId: string, + rootId: string, + @Body() + body: { + titleRecommend: string; + }, + ) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: periodId }, + relations: ["salaryOrgs"], + }); + if (!salaryPeriod) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + + await Promise.all( + salaryPeriod.salaryOrgs + .filter((x) => x.rootId == rootId) + .map(async (x) => { + x.status = "WAITHEAD2"; + x.ownerRecommend = body.titleRecommend; + await this.salaryPeriodRepository.save(salaryPeriod); + }), + ); + return new HttpSuccess(); + } + + /** + * API ผอ ส่ง เจ้าหน้าที่ + * + * + * @param {string} orgId Guid, *Id รอบเงินเดือน + * @param {string} rootId Guid, *Id สำนัก + */ + @Put("head/comment/{periodId}/{rootId}") + async WaitHeadApprove( + @Path() periodId: string, + rootId: string, + @Body() + body: { + titleRecommend: string; + }, + ) { + const salaryPeriod = await this.salaryPeriodRepository.findOne({ + where: { id: periodId }, + relations: ["salaryOrgs"], + }); + if (!salaryPeriod) + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบผังเงินเดือนนี้"); + + await Promise.all( + salaryPeriod.salaryOrgs + .filter((x) => x.rootId == rootId) + .map(async (x) => { + x.status = "REPORT"; + x.ownerRecommend = body.titleRecommend; + await this.salaryPeriodRepository.save(salaryPeriod); + }), + ); + return new HttpSuccess(); + } +} diff --git a/src/entities/SalaryOrgEmployee.ts b/src/entities/SalaryOrgEmployee.ts new file mode 100644 index 0000000..a2d09bd --- /dev/null +++ b/src/entities/SalaryOrgEmployee.ts @@ -0,0 +1,150 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToOne, OneToMany, Double } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { SalaryPeriod } from "./SalaryPeriod"; +import { SalaryProfileEmployee } from "./SalaryProfileEmployee"; + +@Entity("salaryOrgEmployee") +export class SalaryOrgEmployee extends EntityBase { + @Column({ + comment: "คีย์นอก(FK)ของตาราง salaryPeriod", + length: 40, + }) + salaryPeriodId: string; + + @Column({ + comment: "สถานะ", + }) + status: string; + + @Column({ + comment: "คีย์นอก(FK)ของตาราง orgRoot", + length: 40, + }) + rootId: string; + + @Column({ + nullable: true, + comment: "คีย์นอก(FK)ของตาราง orgRevision", + length: 40, + }) + revisionId: string; + + @Column({ + comment: "รอบการ Snapshot", + length: 20, + default: "SNAP1", + }) + snapshot: string; + + @Column({ + default: 0, + comment: "จำนวนคนทั้งหมด", + }) + total: number; + + @Column({ + default: 0, + comment: "15%ของจำนวนคน(จำนวนเต็ม)", + }) + fifteenPercent: number; + + @Column({ + comment: "15%ของจำนวนคน(จุดทศนิยม)", + type: "double", + default: 0, + }) + fifteenPoint: number; + + @Column({ + comment: "กลุ่ม GROUP1->กลุ่ม1 GROUP2->กลุ่ม2", + length: 10, + }) + group: string; + + @Column({ + comment: "เลือกไปแล้ว", + default: 0, + }) + quantityUsed: number; + + @Column({ + comment: "คงเหลือโควตา", + default: 0, + }) + remainQuota: number; + + @Column({ + comment: "จำนวนเงินคนครองปัจจุบัน", + type: "double", + default: 0, + }) + currentAmount: number; + + @Column({ + comment: "วงเงิน6%", + type: "double", + default: 0, + }) + sixPercentAmount: number; + + @Column({ + comment: "ยอดเงินที่ใช้ไป", + type: "double", + default: 0, + }) + spentAmount: number; + + @Column({ + comment: "ใช้ไปเท่าไหร่", + type: "double", + default: 0, + }) + useAmount: number; + + @Column({ + comment: "เหลือเท่าไหร่", + type: "double", + default: 0, + }) + remainingAmount: number; + + @Column({ + nullable: true, + comment: "คำแนะนำ สกจ", + length: 255, + }) + ownerRecommend: string; + + @Column({ + nullable: true, + comment: "คำแนะนำ ผอ", + length: 255, + }) + headRecommend: string; + + @ManyToOne(() => SalaryPeriod, (salaryPeriod) => salaryPeriod.salaryOrgs) + @JoinColumn({ name: "salaryPeriodId" }) + salaryPeriod: SalaryPeriod; + + @OneToMany(() => SalaryProfileEmployee, (salaryProfile) => salaryProfile.salaryOrg) + salaryProfiles: SalaryProfileEmployee[]; +} + +export class CreateSalaryOrgEmployee { + @Column("uuid") + salaryPeriodId: string; + + @Column() + status: string; + + @Column("uuid") + rootId: string; + + @Column() + total: number; + + @Column() + fifteenPercent: number; +} + +export type UpdateSalaryOrgEmployee = Partial; diff --git a/src/entities/SalaryPeriod.ts b/src/entities/SalaryPeriod.ts index 43bcb3d..ccd2070 100644 --- a/src/entities/SalaryPeriod.ts +++ b/src/entities/SalaryPeriod.ts @@ -1,6 +1,7 @@ import { Entity, Column, ManyToOne, JoinColumn, OneToOne, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; import { SalaryOrg } from "./SalaryOrg"; +import { SalaryOrgEmployee } from "./SalaryOrgEmployee"; @Entity("salaryPeriod") export class SalaryPeriod extends EntityBase { @@ -51,6 +52,9 @@ export class SalaryPeriod extends EntityBase { @OneToMany(() => SalaryOrg, (salaryOrg) => salaryOrg.salaryPeriod) salaryOrgs: SalaryOrg[]; + + @OneToMany(() => SalaryOrgEmployee, (salaryOrgEmployee) => salaryOrgEmployee.salaryPeriod) + salaryOrgEmployees: SalaryOrgEmployee[]; } export class CreateSalaryPeriod { diff --git a/src/entities/SalaryProfileEmployee.ts b/src/entities/SalaryProfileEmployee.ts new file mode 100644 index 0000000..8e1ee76 --- /dev/null +++ b/src/entities/SalaryProfileEmployee.ts @@ -0,0 +1,397 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToOne, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { SalaryOrgEmployee } from "./SalaryOrgEmployee"; + +@Entity("salaryProfileEmployee") +export class SalaryProfileEmployee extends EntityBase { + @Column({ + comment: "คีย์นอก(FK)ของตาราง salaryOrg", + length: 40, + }) + salaryOrgId: string; + + @Column({ + nullable: true, + comment: "คำนำหน้า", + length: 255, + default: null, + }) + prefix: string; + + @Column({ + nullable: true, + comment: "ชื่อ", + length: 255, + default: null, + }) + firstName: string; + + @Column({ + nullable: true, + comment: "สกุล", + length: 255, + default: null, + }) + lastName: string; + + @Column({ + nullable: true, + comment: "เลขบัตรประชาชน", + length: 100, + default: null, + }) + citizenId: string; + + @Column({ + nullable: true, + comment: "Prefix นำหน้าเลขที่ตำแหน่ง เป็น Optional (ไม่ใช่อักษรย่อของหน่วยงาน/ส่วนราชการ)", + length: 100, + default: null, + }) + posMasterNoPrefix: string; + + @Column({ + nullable: true, + comment: "เลขที่ตำแหน่ง เป็นตัวเลข", + default: null, + }) + posMasterNo: number; + + @Column({ + nullable: true, + comment: "Suffix หลังเลขที่ตำแหน่ง เช่น ช.", + length: 100, + default: null, + }) + posMasterNoSuffix: string; + + @Column({ + nullable: true, + comment: "ชื่อย่อหน่วยงาน", + length: 100, + default: null, + }) + orgShortName: string; + + @Column({ + nullable: true, + comment: "ตำแหน่ง", + length: 255, + default: null, + }) + position: string; + + @Column({ + nullable: true, + comment: "ประเภทตำแหน่ง", + length: 100, + default: null, + }) + posType: string; + + @Column({ + nullable: true, + comment: "ระดับตำแหน่ง", + default: null, + }) + posLevel: number; + + // @Column({ + // nullable: true, + // comment: "ตำแหน่งทางการบริหาร", + // length: 255, + // default: null, + // }) + // posExecutive: string; + + @Column({ + nullable: true, + type: "double", + comment: "เงินเดือนฐาน", + default: null, + }) + amount: number | null; + + @Column({ + type: "double", + comment: "เงินพิเศษ", + default: 0, + }) + amountSpecial: number; + + @Column({ + type: "double", + comment: "จำนวนเงินที่ใช้เลื่อน", + default: 0, + }) + amountUse: number; + + @Column({ + type: "double", + comment: "เงินเดือนหลังเลื่อน", + default: 0, + }) + positionSalaryAmount: number; + + @Column({ + comment: + "ประเภทการเลื่อน(ขั้น) PENDING->รายชื่อคนครอง NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น", + length: 20, + default: "PENDING", + }) + type: string; + + @Column({ + comment: "สถานะ", + length: 20, + default: "PENDING", + }) + status: string; + + @Column({ + nullable: true, + comment: "id revision", + length: 40, + }) + revisionId: string; + + @Column({ + nullable: true, + comment: "คีย์นอก(FK)ของตาราง orgRoot", + length: 40, + }) + rootId: string; + + @Column({ + nullable: true, + comment: "ชื่อของหน่วยงาน", + length: 255, + default: null, + }) + root: string; + + @Column({ + nullable: true, + comment: "คีย์นอก(FK)ของตาราง orgChild1", + length: 40, + }) + child1Id: string; + + @Column({ + nullable: true, + comment: "ชื่อส่วนราชการ", + length: 255, + default: null, + }) + child1: string; + + @Column({ + nullable: true, + comment: "คีย์นอก(FK)ของตาราง orgChild2", + length: 40, + }) + child2Id: string; + + @Column({ + nullable: true, + comment: "ชื่อส่วนราชการ", + length: 255, + default: null, + }) + child2: string; + + @Column({ + nullable: true, + comment: "คีย์นอก(FK)ของตาราง orgChild3", + length: 40, + }) + child3Id: string; + + @Column({ + nullable: true, + comment: "ชื่อส่วนราชการ", + length: 255, + default: null, + }) + child3: string; + + @Column({ + nullable: true, + comment: "คีย์นอก(FK)ของตาราง orgChild4", + length: 40, + }) + child4Id: string; + + @Column({ + nullable: true, + comment: "ชื่อส่วนราชการ", + length: 255, + default: null, + }) + child4: string; + + @Column({ + nullable: true, + comment: "ผลการประเมินผลการปฏิบัติราชการ", + default: null, + }) + result: string; + + @Column({ + nullable: true, + comment: "ระยะเวลาการปฏิบัติราชการในรอบครึ่งปี", + default: null, + }) + duration: string; + + @Column({ + nullable: true, + comment: "การลงโทษทางวินัย", + default: null, + }) + isPunish: boolean; + + @Column({ + nullable: true, + comment: "พักราชการ", + default: null, + }) + isSuspension: boolean; + + @Column({ + nullable: true, + comment: "ขาดราชการ", + default: null, + }) + isAbsent: boolean; + + @Column({ + nullable: true, + comment: "วันลา", + default: null, + }) + isLeave: boolean; + + @Column({ + nullable: true, + comment: "เกษียญ", + default: false, + }) + isRetired: boolean; + + @Column({ + nullable: true, + comment: "สำรอง", + default: false, + }) + isReserve: boolean; + + @Column({ + nullable: true, + comment: "ทะลุขั้น", + default: false, + }) + isNext: boolean; + + @ManyToOne(() => SalaryOrgEmployee, (salaryOrg) => salaryOrg.salaryProfiles) + @JoinColumn({ name: "salaryOrgId" }) + salaryOrg: SalaryOrgEmployee; +} + +export class CreateSalaryProfileEmployee { + @Column("uuid") + id: string; + + @Column() + type: string; + + @Column() + prefix: string; + + @Column() + firstName: string; + + @Column() + lastName: string; + + @Column() + citizenId: string; + + @Column() + posMasterNoPrefix: string | null; + + @Column() + posMasterNo: number; + + @Column() + posMasterNoSuffix: string | null; + + @Column() + orgShortName: string | null; + + @Column() + position: string; + + @Column() + posType: string; + + @Column() + posLevel: string; + + // @Column() + // posExecutive: string | null; + + @Column() + amount: number | null; + + @Column("uuid") + rootId: string | null; + + @Column() + root: string | null; + + @Column("uuid") + child1Id: string | null; + + @Column() + child1: string | null; + + @Column("uuid") + child2Id: string | null; + + @Column() + child2: string | null; + + @Column("uuid") + child3Id: string | null; + + @Column() + child3: string | null; + + @Column("uuid") + child4Id: string | null; + + @Column() + child4: string | null; + + @Column() + result: string | null; + + @Column() + duration: string | null; + + @Column() + isPunish: boolean; + + @Column() + isSuspension: boolean; + + @Column() + isAbsent: boolean; + + @Column() + isLeave: boolean; + + @Column() + isRetired: boolean; +} diff --git a/src/migration/1710564694856-update_table_salaryOrg_add_recommend1.ts b/src/migration/1710564694856-update_table_salaryOrg_add_recommend1.ts new file mode 100644 index 0000000..6396ce3 --- /dev/null +++ b/src/migration/1710564694856-update_table_salaryOrg_add_recommend1.ts @@ -0,0 +1,20 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableSalaryOrgAddRecommend11710564694856 implements MigrationInterface { + name = 'UpdateTableSalaryOrgAddRecommend11710564694856' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`salaryOrgEmployee\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`salaryPeriodId\` varchar(40) NOT NULL COMMENT 'คีย์นอก(FK)ของตาราง salaryPeriod', \`status\` varchar(255) NOT NULL COMMENT 'สถานะ', \`rootId\` varchar(40) NOT NULL COMMENT 'คีย์นอก(FK)ของตาราง orgRoot', \`revisionId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgRevision', \`snapshot\` varchar(20) NOT NULL COMMENT 'รอบการ Snapshot' DEFAULT 'SNAP1', \`total\` int NOT NULL COMMENT 'จำนวนคนทั้งหมด' DEFAULT '0', \`fifteenPercent\` int NOT NULL COMMENT '15%ของจำนวนคน(จำนวนเต็ม)' DEFAULT '0', \`fifteenPoint\` double NOT NULL COMMENT '15%ของจำนวนคน(จุดทศนิยม)' DEFAULT '0', \`group\` varchar(10) NOT NULL COMMENT 'กลุ่ม GROUP1->กลุ่ม1 GROUP2->กลุ่ม2', \`quantityUsed\` int NOT NULL COMMENT 'เลือกไปแล้ว' DEFAULT '0', \`remainQuota\` int NOT NULL COMMENT 'คงเหลือโควตา' DEFAULT '0', \`currentAmount\` double NOT NULL COMMENT 'จำนวนเงินคนครองปัจจุบัน' DEFAULT '0', \`sixPercentAmount\` double NOT NULL COMMENT 'วงเงิน6%' DEFAULT '0', \`spentAmount\` double NOT NULL COMMENT 'ยอดเงินที่ใช้ไป' DEFAULT '0', \`useAmount\` double NOT NULL COMMENT 'ใช้ไปเท่าไหร่' DEFAULT '0', \`remainingAmount\` double NOT NULL COMMENT 'เหลือเท่าไหร่' DEFAULT '0', \`ownerRecommend\` varchar(255) NULL COMMENT 'คำแนะนำ สกจ', \`headRecommend\` varchar(255) NULL COMMENT 'คำแนะนำ ผอ', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`salaryProfileEmployee\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`salaryOrgId\` varchar(40) NOT NULL COMMENT 'คีย์นอก(FK)ของตาราง salaryOrg', \`prefix\` varchar(255) NULL COMMENT 'คำนำหน้า', \`firstName\` varchar(255) NULL COMMENT 'ชื่อ', \`lastName\` varchar(255) NULL COMMENT 'สกุล', \`citizenId\` varchar(100) NULL COMMENT 'เลขบัตรประชาชน', \`posMasterNoPrefix\` varchar(100) NULL COMMENT 'Prefix นำหน้าเลขที่ตำแหน่ง เป็น Optional (ไม่ใช่อักษรย่อของหน่วยงาน/ส่วนราชการ)', \`posMasterNo\` int NULL COMMENT 'เลขที่ตำแหน่ง เป็นตัวเลข', \`posMasterNoSuffix\` varchar(100) NULL COMMENT 'Suffix หลังเลขที่ตำแหน่ง เช่น ช.', \`orgShortName\` varchar(100) NULL COMMENT 'ชื่อย่อหน่วยงาน', \`position\` varchar(255) NULL COMMENT 'ตำแหน่ง', \`posType\` varchar(100) NULL COMMENT 'ประเภทตำแหน่ง', \`posLevel\` int NULL COMMENT 'ระดับตำแหน่ง', \`amount\` double NULL COMMENT 'เงินเดือนฐาน', \`amountSpecial\` double NOT NULL COMMENT 'เงินพิเศษ' DEFAULT '0', \`amountUse\` double NOT NULL COMMENT 'จำนวนเงินที่ใช้เลื่อน' DEFAULT '0', \`positionSalaryAmount\` double NOT NULL COMMENT 'เงินเดือนหลังเลื่อน' DEFAULT '0', \`type\` varchar(20) NOT NULL COMMENT 'ประเภทการเลื่อน(ขั้น) PENDING->รายชื่อคนครอง NONE->ไม่ได้เลื่อน HAFT->ครึ่งขั้น FULL->1ขั้น FULLHAFT->1.5ขั้น' DEFAULT 'PENDING', \`status\` varchar(20) NOT NULL COMMENT 'สถานะ' DEFAULT 'PENDING', \`revisionId\` varchar(40) NULL COMMENT 'id revision', \`rootId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgRoot', \`root\` varchar(255) NULL COMMENT 'ชื่อของหน่วยงาน', \`child1Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild1', \`child1\` varchar(255) NULL COMMENT 'ชื่อส่วนราชการ', \`child2Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild2', \`child2\` varchar(255) NULL COMMENT 'ชื่อส่วนราชการ', \`child3Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild3', \`child3\` varchar(255) NULL COMMENT 'ชื่อส่วนราชการ', \`child4Id\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง orgChild4', \`child4\` varchar(255) NULL COMMENT 'ชื่อส่วนราชการ', \`result\` varchar(255) NULL COMMENT 'ผลการประเมินผลการปฏิบัติราชการ', \`duration\` varchar(255) NULL COMMENT 'ระยะเวลาการปฏิบัติราชการในรอบครึ่งปี', \`isPunish\` tinyint NULL COMMENT 'การลงโทษทางวินัย', \`isSuspension\` tinyint NULL COMMENT 'พักราชการ', \`isAbsent\` tinyint NULL COMMENT 'ขาดราชการ', \`isLeave\` tinyint NULL COMMENT 'วันลา', \`isRetired\` tinyint NULL COMMENT 'เกษียญ' DEFAULT 0, \`isReserve\` tinyint NULL COMMENT 'สำรอง' DEFAULT 0, \`isNext\` tinyint NULL COMMENT 'ทะลุขั้น' DEFAULT 0, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`salaryOrgEmployee\` ADD CONSTRAINT \`FK_34789055fe8c215e333b83ca20d\` FOREIGN KEY (\`salaryPeriodId\`) REFERENCES \`salaryPeriod\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`salaryProfileEmployee\` ADD CONSTRAINT \`FK_ba74e4af9c44fd90032d4724a70\` FOREIGN KEY (\`salaryOrgId\`) REFERENCES \`salaryOrgEmployee\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`salaryProfileEmployee\` DROP FOREIGN KEY \`FK_ba74e4af9c44fd90032d4724a70\``); + await queryRunner.query(`ALTER TABLE \`salaryOrgEmployee\` DROP FOREIGN KEY \`FK_34789055fe8c215e333b83ca20d\``); + await queryRunner.query(`DROP TABLE \`salaryProfileEmployee\``); + await queryRunner.query(`DROP TABLE \`salaryOrgEmployee\``); + } + +}