From 13f6f801147009b0fb9844d1c3e561e35de62b02 Mon Sep 17 00:00:00 2001 From: Bright Date: Thu, 11 Jul 2024 14:58:07 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B8=A3=E0=B8=A7=E0=B8=A1=20report=20kpi=204,?= =?UTF-8?q?5,6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/ReportController.ts | 492 +++++++++++++++++++++++++++- src/interfaces/extension.ts | 10 + 2 files changed, 499 insertions(+), 3 deletions(-) diff --git a/src/controllers/ReportController.ts b/src/controllers/ReportController.ts index 7a8f95e..b9a65e7 100644 --- a/src/controllers/ReportController.ts +++ b/src/controllers/ReportController.ts @@ -11,9 +11,9 @@ import { Path, Request, Query, -} from "tsoa"; +} from "tsoa"; import { AppDataSource } from "../database/data-source"; -import { Brackets, IsNull, Not } from "typeorm"; +import { Brackets, IsNull, Not, In } from "typeorm"; import HttpSuccess from "../interfaces/http-success"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; @@ -24,7 +24,7 @@ import Extension from "../interfaces/extension"; import { KpiRole } from "../entities/kpiRole"; import { KpiPlan } from "../entities/kpiPlan"; import { KpiUserDevelopment } from "../entities/kpiUserDevelopment"; - +import CallAPI from "../interfaces/call-api"; @Route("api/v1/kpi/report") @Tags("Report") @Security("bearerAuth") @@ -294,16 +294,502 @@ export class ReportController extends Controller { templateName = "KPI4"; reportName = "KPI4"; //use_filter + const yearNow = new Date().getFullYear(); + if (requestBody.profileId) { + //ชั่วคราว + const profileEvaluationNowYearIds = await AppDataSource.getRepository(KpiUserEvaluation) + .createQueryBuilder("kpiUserEvaluation") + .leftJoinAndSelect("kpiUserEvaluation.kpiPeriod", "kpiPeriod") + .where("kpiUserEvaluation.profileId = :profileId", { profileId: requestBody.profileId }) + // .where("kpiPeriod.year = :year", { year: yearNow }) + .groupBy("kpiUserEvaluation.kpiPeriodId") + .select("MIN(kpiUserEvaluation.id) as id") + .getRawMany(); + // const profileEvaluationNextYearIds = await AppDataSource.getRepository(KpiUserEvaluation) + // .createQueryBuilder("kpiUserEvaluation") + // .leftJoinAndSelect("kpiUserEvaluation.kpiPeriod", "kpiPeriod") + // .where("kpiUserEvaluation.profileId = :profileId", { profileId: requestBody.profileId }) + // .where("kpiPeriod.year = :year", { year: yearNow + 1 }) + // .groupBy("kpiUserEvaluation.kpiPeriodId") + // .select("MIN(kpiUserEvaluation.id) as id") + // .getRawMany(); + // const profileEvaluationCombianIds = profileEvaluationNowYearIds.concat(profileEvaluationNextYearIds); + + const profileEvaluations = await this.kpiUserEvaluationRepository.find({ + relations: ["kpiPeriod"], + where: { id: In(profileEvaluationNowYearIds.map((evaluation) => evaluation.id)) }, + }); + + const groupedEvaluations = profileEvaluations.reduce((acc: any, evaluation: any) => { + const year = evaluation.kpiPeriod.year; + const profileId = evaluation.profileId; + const key = `${profileId}-${year}`; + + if (!acc[key]) { + acc[key] = { + fullName: evaluation.prefix + evaluation.firstName + " " + evaluation.lastName, + profileId: profileId, + year: Extension.ToThaiNumber(Extension.ToThaiYear(year).toString()), // Set year once here + evaluations: [], + }; + } + + acc[key].evaluations.push(evaluation); + return acc; + }, {}); + + // สร้าง formatData + const combinedDatas = Object.values(groupedEvaluations).map((group: any) => { + const data: any = { + fullName: group.fullName, + year: group.year, + }; + + group.evaluations.forEach((evaluation: any) => { + if (evaluation.kpiPeriod.durationKPI === "APR") { + data.summaryPointAPR1 = + evaluation.summaryPoint >= 90 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointAPR2 = + evaluation.summaryPoint >= 80 && evaluation.summaryPoint < 90 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointAPR3 = + evaluation.summaryPoint >= 70 && evaluation.summaryPoint < 80 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointAPR4 = + evaluation.summaryPoint >= 60 && evaluation.summaryPoint < 70 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointAPR5 = + evaluation.summaryPoint < 60 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.periodAPR = evaluation.kpiPeriod.durationKPI; + } else if (evaluation.kpiPeriod.durationKPI === "OCT") { + data.summaryPointOCT1 = + evaluation.summaryPoint >= 90 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointOCT2 = + evaluation.summaryPoint >= 80 && evaluation.summaryPoint < 90 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointOCT3 = + evaluation.summaryPoint >= 70 && evaluation.summaryPoint < 80 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointOCT4 = + evaluation.summaryPoint >= 60 && evaluation.summaryPoint < 70 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.summaryPointOCT5 = + evaluation.summaryPoint < 60 + ? Extension.ToThaiNumber(evaluation.summaryPoint.toString()) + : null; + data.periodOCT = evaluation.kpiPeriod.durationKPI; + } + }); + + return data; + }); + formattedData = { + combinedDatas: combinedDatas.length > 0 ? combinedDatas:[{}], + fullName: combinedDatas[0]["fullName"], + }; + } } if (requestBody.type == "KPI5") { templateName = "KPI5"; reportName = "KPI5"; //use_filter + interface KPIData { + fullName: string | null; + position: string | null; + posType: string | null; + posLevel: string | null; + affiliation: string | null; + summaryPointAPR1: string | null; + textPointAPR1: string | null; + periodAPR1: string | null; + yearAPR1: string | null; + summaryPointOCT1: string | null; + textPointOCT1: string | null; + periodOCT1: string | null; + yearOCT1: string | null; + summaryPointAPR2: string | null; + textPointAPR2: string | null; + periodAPR2: string | null; + yearAPR2: string | null; + summaryPointOCT2: string | null; + textPointOCT2: string | null; + periodOCT2: string | null; + yearOCT2: string | null; + summaryPointAPR3: string | null; + textPointAPR3: string | null; + periodAPR3: string | null; + yearAPR3: string | null; + summaryPointOCT3: string | null; + textPointOCT3: string | null; + periodOCT3: string | null; + yearOCT3: string | null; + summaryPointAPR4: string | null; + textPointAPR4: string | null; + periodAPR4: string | null; + yearAPR4: string | null; + summaryPointOCT4: string | null; + textPointOCT4: string | null; + periodOCT4: string | null; + yearOCT4: string | null; + summaryPointAPR5: string | null; + textPointAPR5: string | null; + periodAPR5: string | null; + yearAPR5: string | null; + summaryPointOCT5: string | null; + textPointOCT5: string | null; + periodOCT5: string | null; + yearOCT5: string | null; + year1: string | null; + year2: string | null; + year3: string | null; + year4: string | null; + year5: string | null; + } + const yearNow = new Date().getFullYear(); + if (requestBody.profileId) { + const profileEvaluationIds = await AppDataSource.getRepository(KpiUserEvaluation) + .createQueryBuilder("kpiUserEvaluation") + .leftJoinAndSelect("kpiUserEvaluation.kpiPeriod", "kpiPeriod") + .where("kpiUserEvaluation.profileId = :profileId", { profileId: requestBody.profileId }) + .andWhere("kpiPeriod.year BETWEEN :startYear AND :endYear", { + startYear: yearNow - 4, + endYear: yearNow, + }) + .groupBy("kpiUserEvaluation.kpiPeriodId") + .select("MIN(kpiUserEvaluation.id) as id") + .getRawMany(); + + const profileEvaluation = await this.kpiUserEvaluationRepository.find({ + relations: ["kpiPeriod"], + where: { id: In(profileEvaluationIds.map((evaluation) => evaluation.id)) }, + }); + + const combinedData: KPIData = profileEvaluation.reduce( + (acc: KPIData, x) => { + const fullNameParts = [x.child4, x.child3, x.child2, x.child1, x.org]; + + const affiliation = fullNameParts + .filter((part) => part !== undefined && part !== null) + .join("/"); + + if (!acc.fullName) { + acc.fullName = x.prefix + " " + x.firstName + " " + x.lastName; + acc.position = x.position; + acc.posType = x.posTypeName; + acc.posLevel = x.posLevelName; + acc.affiliation = affiliation; + } + + if (x.kpiPeriod.year === yearNow - 4 && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR1 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR1 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR1 = x.kpiPeriod.durationKPI; + acc.yearAPR1 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 4 && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT1 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT1 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT1 = x.kpiPeriod.durationKPI; + acc.yearOCT1 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 3 && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR2 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR2 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR2 = x.kpiPeriod.durationKPI; + acc.yearAPR2 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 3 && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT2 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT2 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT2 = x.kpiPeriod.durationKPI; + acc.yearOCT2 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 2 && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR3 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR3 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR3 = x.kpiPeriod.durationKPI; + acc.yearAPR3 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 2 && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT3 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT3 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT3 = x.kpiPeriod.durationKPI; + acc.yearOCT3 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 1 && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR4 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR4 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR4 = x.kpiPeriod.durationKPI; + acc.yearAPR4 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 1 && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT4 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT4 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT4 = x.kpiPeriod.durationKPI; + acc.yearOCT4 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR5 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR5 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR5 = x.kpiPeriod.durationKPI; + acc.yearAPR5 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT5 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT5 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT5 = x.kpiPeriod.durationKPI; + acc.yearOCT5 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + return acc; + }, + { + fullName: null, + position: null, + posType: null, + posLevel: null, + affiliation: null, + summaryPointAPR1: null, + textPointAPR1: null, + periodAPR1: null, + yearAPR1: null, + summaryPointOCT1: null, + textPointOCT1: null, + periodOCT1: null, + yearOCT1: null, + summaryPointAPR2: null, + textPointAPR2: null, + periodAPR2: null, + yearAPR2: null, + summaryPointOCT2: null, + textPointOCT2: null, + periodOCT2: null, + yearOCT2: null, + summaryPointAPR3: null, + textPointAPR3: null, + periodAPR3: null, + yearAPR3: null, + summaryPointOCT3: null, + textPointOCT3: null, + periodOCT3: null, + yearOCT3: null, + summaryPointAPR4: null, + textPointAPR4: null, + periodAPR4: null, + yearAPR4: null, + summaryPointOCT4: null, + textPointOCT4: null, + periodOCT4: null, + yearOCT4: null, + summaryPointAPR5: null, + textPointAPR5: null, + periodAPR5: null, + yearAPR5: null, + summaryPointOCT5: null, + textPointOCT5: null, + periodOCT5: null, + yearOCT5: null, + year1: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow - 4).toString()), + year2: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow - 3).toString()), + year3: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow - 2).toString()), + year4: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow - 1).toString()), + year5: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow).toString()), + }, + ); + formattedData = combinedData; + } } if (requestBody.type == "KPI6") { templateName = "KPI6"; reportName = "KPI6"; //use_filter + interface KPIData { + fullName: string | null; + position: string | null; + posType: string | null; + posLevel: string | null; + affiliation: string | null; + summaryPointAPR1: string | null; + textPointAPR1: string | null; + periodAPR1: string | null; + yearAPR1: string | null; + summaryPointOCT1: string | null; + textPointOCT1: string | null; + periodOCT1: string | null; + yearOCT1: string | null; + summaryPointAPR2: string | null; + textPointAPR2: string | null; + periodAPR2: string | null; + yearAPR2: string | null; + summaryPointOCT2: string | null; + textPointOCT2: string | null; + periodOCT2: string | null; + yearOCT2: string | null; + summaryPointAPR3: string | null; + textPointAPR3: string | null; + periodAPR3: string | null; + yearAPR3: string | null; + summaryPointOCT3: string | null; + textPointOCT3: string | null; + periodOCT3: string | null; + yearOCT3: string | null; + year1: string | null; + year2: string | null; + year3: string | null; + } + const yearNow = new Date().getFullYear(); + if (requestBody.profileId) { + const profileEvaluationIds = await AppDataSource.getRepository(KpiUserEvaluation) + .createQueryBuilder("kpiUserEvaluation") + .leftJoinAndSelect("kpiUserEvaluation.kpiPeriod", "kpiPeriod") + .where("kpiUserEvaluation.profileId = :profileId", { profileId: requestBody.profileId }) + .andWhere("kpiPeriod.year BETWEEN :startYear AND :endYear", { + startYear: yearNow - 2, + endYear: yearNow, + }) + .groupBy("kpiUserEvaluation.kpiPeriodId") + .select("MIN(kpiUserEvaluation.id) as id") + .getRawMany(); + + const profileEvaluation = await this.kpiUserEvaluationRepository.find({ + relations: ["kpiPeriod"], + where: { id: In(profileEvaluationIds.map((evaluation) => evaluation.id)) }, + }); + + const combinedData: KPIData = profileEvaluation.reduce( + (acc: KPIData, x) => { + const fullNameParts = [x.child4, x.child3, x.child2, x.child1, x.org]; + + const affiliation = fullNameParts + .filter((part) => part !== undefined && part !== null) + .join("/"); + + if (!acc.fullName) { + acc.fullName = x.prefix + " " + x.firstName + " " + x.lastName; + acc.position = x.position; + acc.posType = x.posTypeName; + acc.posLevel = x.posLevelName; + acc.affiliation = affiliation; + } + + if (x.kpiPeriod.year === yearNow - 2 && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR1 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR1 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR1 = x.kpiPeriod.durationKPI; + acc.yearAPR1 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 2 && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT1 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT1 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT1 = x.kpiPeriod.durationKPI; + acc.yearOCT1 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 1 && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR2 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR2 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR2 = x.kpiPeriod.durationKPI; + acc.yearAPR2 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow - 1 && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT2 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT2 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT2 = x.kpiPeriod.durationKPI; + acc.yearOCT2 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow && x.kpiPeriod.durationKPI === "APR") { + acc.summaryPointAPR3 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointAPR3 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodAPR3 = x.kpiPeriod.durationKPI; + acc.yearAPR3 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + if (x.kpiPeriod.year === yearNow && x.kpiPeriod.durationKPI === "OCT") { + acc.summaryPointOCT3 = Extension.ToThaiNumber(x.summaryPoint.toString()) ?? null; + acc.textPointOCT3 = Extension.textPoint(x.summaryPoint) ?? null; + acc.periodOCT3 = x.kpiPeriod.durationKPI; + acc.yearOCT3 = + Extension.ToThaiNumber(Extension.ToThaiYear(x.kpiPeriod.year).toString()) ?? null; + } + + return acc; + }, + { + fullName: null, + position: null, + posType: null, + posLevel: null, + affiliation: null, + summaryPointAPR1: null, + textPointAPR1: null, + periodAPR1: null, + yearAPR1: null, + summaryPointOCT1: null, + textPointOCT1: null, + periodOCT1: null, + yearOCT1: null, + summaryPointAPR2: null, + textPointAPR2: null, + periodAPR2: null, + yearAPR2: null, + summaryPointOCT2: null, + textPointOCT2: null, + periodOCT2: null, + yearOCT2: null, + summaryPointAPR3: null, + textPointAPR3: null, + periodAPR3: null, + yearAPR3: null, + summaryPointOCT3: null, + textPointOCT3: null, + periodOCT3: null, + yearOCT3: null, + year1: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow - 2).toString()), + year2: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow - 1).toString()), + year3: Extension.ToThaiNumber(Extension.ToThaiYear(yearNow).toString()), + }, + ); + formattedData = combinedData; + } } if (requestBody.type == "KPI7") { templateName = "KPI7"; diff --git a/src/interfaces/extension.ts b/src/interfaces/extension.ts index 89dc332..65394ce 100644 --- a/src/interfaces/extension.ts +++ b/src/interfaces/extension.ts @@ -25,6 +25,16 @@ class Extension { } } + public static textPoint(val: number | undefined) { + if (val == undefined) val = -1; + if (val >= 0 && val <= 60) return "ต้องปรับปรุง"; + if (val >= 60 && val <= 69) return "พอใช้"; + if (val >= 70 && val <= 79) return "ดี"; + if (val >= 80 && val <= 89) return "ดีมาก"; + if (val >= 90 && val <= 100) return "ดีเด่น"; + else return "-"; + } + public static ToThaiMonth(value: number) { switch (value) { case 1: