import { Controller, Get, Post, Put, Delete, Route, Security, Tags, Body, Path, Request, SuccessResponse, Response, Query, } from "tsoa"; import { AppDataSource } from "../database/data-source"; import HttpSuccess from "../interfaces/http-success"; import HttpStatusCode from "../interfaces/http-status"; import { KpiUserDevelopment, CreateKpiUserDevelopment, UpdateKpiUserDevelopment, KpiUserDevelopmentDataPoint, } from "../entities/kpiUserDevelopment"; import HttpError from "../interfaces/http-error"; import { KpiUserEvaluation } from "../entities/kpiUserEvaluation"; import { Not, Brackets } from "typeorm"; import { DevelopmentProject } from "../entities/developmentProject"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; import { addLogSequence, setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/kpi/user/achievement/development") @Tags("KpiUserDevelopment") @Security("bearerAuth") @Response( HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", ) @SuccessResponse(HttpStatusCode.OK, "สำเร็จ") export class KpiUserDevelopmentController extends Controller { private kpiUserDevelopmentRepository = AppDataSource.getRepository(KpiUserDevelopment); private kpiUserEvaluationRepository = AppDataSource.getRepository(KpiUserEvaluation); private developmentProjectRepository = AppDataSource.getRepository(DevelopmentProject); /** * API เพิ่มพัฒนาตนเอง * * @summary - เพิ่มพัฒนาตนเอง # * */ @Post() async createKpiUserDevelopment( @Body() requestBody: CreateKpiUserDevelopment, @Request() request: RequestWithUser, ) { await new permission().PermissionCreate(request, "SYS_KPI_LIST"); const chkUserEvaluation = await this.kpiUserEvaluationRepository.findOne({ where: { id: requestBody.kpiUserEvaluationId }, }); if (!chkUserEvaluation) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบประเมินผู้ใช้งาน"); } const chkName = await this.kpiUserDevelopmentRepository.findOne({ where: { name: requestBody.name }, }); if (chkName) { throw new HttpError(HttpStatusCode.NOT_FOUND, "มีชื่อนี้ในระบบแล้ว"); } const kpiUserDevelopment = Object.assign(new KpiUserDevelopment(), requestBody); if (!kpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); } // const chk_indicator = await this.kpiUserDevelopmentRepository.findOne({ // where: { // kpiUserEvaluationId: requestBody.kpiUserEvaluationId, // }, // }); // if ( // (chk_indicator && chk_indicator.including == requestBody.including) || // (chk_indicator && chk_indicator.includingName == requestBody.includingName) // ) { // throw new HttpError( // HttpStatusCode.CONFLICT, // "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ", // ); // } let before:any = null; kpiUserDevelopment.createdUserId = request.user.sub; kpiUserDevelopment.createdFullName = request.user.name; kpiUserDevelopment.lastUpdateUserId = request.user.sub; kpiUserDevelopment.lastUpdateFullName = request.user.name; await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request }); setLogDataDiff(request, { before, after: kpiUserDevelopment }); if (requestBody.developmentProjects != null) { await Promise.all( requestBody.developmentProjects.map(async (x) => { let data = new DevelopmentProject(); data.name = x; data.createdUserId = request.user.sub; data.createdFullName = request.user.name; data.lastUpdateUserId = request.user.sub; data.lastUpdateFullName = request.user.name; data.kpiUserDevelopmentId = kpiUserDevelopment.id; await this.developmentProjectRepository.save(data, { data: request }); setLogDataDiff(request, { before, after: data }); }), ); } return new HttpSuccess(kpiUserDevelopment.id); } /** * API แก้ไขพัฒนาตนเอง * * @summary - แก้ไขพัฒนาตนเอง # * * @param {string} id Id พัฒนาตนเอง */ @Put("{id}") async editKpiUserDevelopment( @Path() id: string, @Body() requestBody: UpdateKpiUserDevelopment, @Request() request: RequestWithUser, ) { await new permission().PermissionUpdate(request, "SYS_KPI_LIST"); const kpiUserDevelopment = await this.kpiUserDevelopmentRepository.findOne({ where: { id }, relations: { developmentProjects: true, }, }); if (!kpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลพัฒนาตนเองนี้"); } const chkUserEvaluation = await this.kpiUserEvaluationRepository.findOne({ where: { id: requestBody.kpiUserEvaluationId }, }); if (!chkUserEvaluation) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบประเมินผู้ใช้งาน"); } const chkName = await this.kpiUserDevelopmentRepository.find({ where: { id: Not(id), name: requestBody.name, }, }); if (chkName && chkName.length > 0) { throw new HttpError(HttpStatusCode.NOT_FOUND, "มีชื่อนี้ในระบบแล้ว"); } // const chk_indicator = await this.kpiUserDevelopmentRepository.findOne({ // where: { // id: Not(id), // kpiUserEvaluationId: requestBody.kpiUserEvaluationId, // }, // }); // if ( // (chk_indicator && chk_indicator.including == requestBody.including) || // (chk_indicator && chk_indicator.includingName == requestBody.includingName) // ) { // throw new HttpError( // HttpStatusCode.CONFLICT, // "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ", // ); // } await this.developmentProjectRepository.remove(kpiUserDevelopment.developmentProjects, { data: request, }); const before = structuredClone(kpiUserDevelopment); kpiUserDevelopment.lastUpdateUserId = request.user.sub; kpiUserDevelopment.lastUpdateFullName = request.user.name; Object.assign(kpiUserDevelopment, requestBody); await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request }); setLogDataDiff(request, { before, after: kpiUserDevelopment }); if (requestBody.developmentProjects != null) { await Promise.all( requestBody.developmentProjects.map(async (x) => { let data = new DevelopmentProject(); data.name = x; data.createdUserId = request.user.sub; data.createdFullName = request.user.name; data.lastUpdateUserId = request.user.sub; data.lastUpdateFullName = request.user.name; data.kpiUserDevelopmentId = kpiUserDevelopment.id; await this.developmentProjectRepository.save(data, { data: request }); setLogDataDiff(request, { before: null, after: data }); }), ); } return new HttpSuccess(kpiUserDevelopment.id); } /** * API ลบพัฒนาตนเอง * * @summary - ลบพัฒนาตนเอง # * */ @Delete("{id}") async deleteKpiUserDevelopment(@Path() id: string, @Request() request: RequestWithUser) { await new permission().PermissionDelete(request, "SYS_KPI_LIST"); const delKpiUserDevelopment = await this.kpiUserDevelopmentRepository.findOne({ where: { id }, relations: ["developmentProjects"], }); if (!delKpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลพัฒนาตนเองนี้"); } await this.developmentProjectRepository.remove(delKpiUserDevelopment.developmentProjects, { data: request, }); await this.kpiUserDevelopmentRepository.remove(delKpiUserDevelopment, { data: request }); return new HttpSuccess(); } /** * API รายละเอียดพัฒนาตนเอง * * @summary - รายละเอียดพัฒนาตนเอง # * * @param {string} id Id พัฒนาตนเอง */ @Get("{id}") async GetKpiUserDevelopmentDetail(@Request() request: RequestWithUser, @Path() id: string) { await new permission().PermissionGet(request, "SYS_KPI_LIST"); const getKpiUserDevelopment = await this.kpiUserDevelopmentRepository.findOne({ relations: ["kpiUserEvaluation", "developmentProjects"], where: { id: id }, }); if (!getKpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลพัฒนาตนเองนี้"); } const mapKpiUserDevelopment = { id: getKpiUserDevelopment.id, evaluationId: getKpiUserDevelopment.kpiUserEvaluation.id, target: getKpiUserDevelopment.target, summary: getKpiUserDevelopment.summary, point: getKpiUserDevelopment.point, name: getKpiUserDevelopment.name, achievement10: getKpiUserDevelopment.achievement10, achievement5: getKpiUserDevelopment.achievement5, achievement0: getKpiUserDevelopment.achievement0, isDevelopment70: getKpiUserDevelopment.isDevelopment70, isDevelopment20: getKpiUserDevelopment.isDevelopment20, isDevelopment10: getKpiUserDevelopment.isDevelopment10, reasonDevelopment70: getKpiUserDevelopment.reasonDevelopment70, reasonDevelopment20: getKpiUserDevelopment.reasonDevelopment20, reasonDevelopment10: getKpiUserDevelopment.reasonDevelopment10, selectType: getKpiUserDevelopment.selectType, selectTypeYear: getKpiUserDevelopment.selectTypeYear, selectTypeId: getKpiUserDevelopment.selectTypeId, developmentProjects: getKpiUserDevelopment.developmentProjects.map((x) => x.name).sort(), }; return new HttpSuccess(mapKpiUserDevelopment); } /** * API รายการพัฒนาตนเอง * * @summary - รายการพัฒนาตนเอง # * */ @Get() async GetKpiUserDevelopment(@Request() request: RequestWithUser, @Query("id") id: string) { await new permission().PermissionGet(request, "SYS_KPI_LIST"); const kpiUserDevelopment = await this.kpiUserDevelopmentRepository.find({ where: { kpiUserEvaluationId: id, }, relations: ["kpiUserEvaluation"], order: { createdAt: "ASC" }, }); const mapKpiUserDevelopment = kpiUserDevelopment.map((item) => ({ id: item.id, evaluationId: item.kpiUserEvaluation.id, target: item.target, summary: item.summary, point: item.point, name: item.name, achievement10: item.achievement10, achievement5: item.achievement5, achievement0: item.achievement0, isDevelopment70: item.isDevelopment70, isDevelopment20: item.isDevelopment20, isDevelopment10: item.isDevelopment10, })); return new HttpSuccess(mapKpiUserDevelopment); } /** * API กรอกระดับคะแนนพัฒนาตนเอง * * @summary กรอกระดับคะแนนพัฒนาตนเอง * * */ @Post("point") async CreateKpiUserDevelopmentPoint( @Body() requestBody: KpiUserDevelopmentDataPoint[], @Request() request: RequestWithUser, ) { await new permission().PermissionCreate(request, "SYS_KPI_LIST"); for (const item of requestBody) { const kpiUserDevelopment = await this.kpiUserDevelopmentRepository.findOne({ where: { id: item.id }, }); if (!kpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, `ไม่พบข้อมูลพัฒนาตนเองนี้: ${item.id}`); } const before = null; this.kpiUserDevelopmentRepository.merge(kpiUserDevelopment, item); kpiUserDevelopment.lastUpdateUserId = request.user.sub; kpiUserDevelopment.lastUpdateFullName = request.user.name; await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request }); setLogDataDiff(request, { before, after: kpiUserDevelopment }); } return new HttpSuccess(); } /** * API * * @summary รายการประเมินผลการปฏิบัติราชการระดับบุคคลทั้งหมด Admin * */ @Post("admin") async listKpiDevelopmentByStatusKP7( @Request() request: { user: Record }, @Body() requestBody: { page: number; pageSize: number; kpiPeriodId?: string; keyword?: string; // status?: string | null; // results?: string | null; // reqedit?: string | null; // evaluating?: boolean | null; }, ) { let conditionFullName = "CONCAT(kpiUserEvaluation.prefix, kpiUserEvaluation.firstName, ' ', kpiUserEvaluation.lastName) LIKE :keyword"; const [kpiUserDevelopment, total] = await AppDataSource.getRepository(KpiUserDevelopment) .createQueryBuilder("kpiUserDevelopment") .leftJoinAndSelect("kpiUserDevelopment.kpiUserEvaluation", "kpiUserEvaluation") .leftJoinAndSelect("kpiUserEvaluation.kpiPeriod", "kpiPeriod") .where("kpiUserEvaluation.evaluationStatus = :status", { status: "KP7" }) .andWhere("kpiUserEvaluation.kpiPeriodId = :kpiPeriodId", { kpiPeriodId: requestBody.kpiPeriodId, }) .andWhere( new Brackets((qb) => { qb.orWhere("kpiUserEvaluation.prefix LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere("kpiUserEvaluation.firstName LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere("kpiUserEvaluation.lastName LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere("kpiUserEvaluation.org LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere("kpiUserEvaluation.position LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere("kpiUserEvaluation.posTypeName LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere("kpiUserEvaluation.posLevelName LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere("kpiUserDevelopment.name LIKE :keyword", { keyword: `%${requestBody.keyword}%`, }) .orWhere(conditionFullName, { keyword: `%${requestBody.keyword}%`, }); }), ) .orderBy("kpiUserDevelopment.createdAt", "ASC") .skip((requestBody.page - 1) * requestBody.pageSize) .take(requestBody.pageSize) .getManyAndCount(); const mapData = kpiUserDevelopment.map((item) => { const fullNameParts = [ item.kpiUserEvaluation.child4, item.kpiUserEvaluation.child3, item.kpiUserEvaluation.child2, item.kpiUserEvaluation.child1, item.kpiUserEvaluation.org, ]; const organization = fullNameParts .filter((part) => part !== undefined && part !== null) .join("/"); return { id: item.id, durationKPI: item.kpiUserEvaluation.kpiPeriod.durationKPI, developmentName: item.name, prefix: item.kpiUserEvaluation.prefix ? item.kpiUserEvaluation.prefix : null, firstname: item.kpiUserEvaluation.firstName ? item.kpiUserEvaluation.firstName : null, lastname: item.kpiUserEvaluation.lastName ? item.kpiUserEvaluation.lastName : null, kpiPeriodId: item.kpiUserEvaluation.kpiPeriodId ? item.kpiUserEvaluation.kpiPeriodId : null, root: item.kpiUserEvaluation.org ? item.kpiUserEvaluation.org : null, position: item.kpiUserEvaluation.position ? item.kpiUserEvaluation.position : null, posTypeName: item.kpiUserEvaluation.posTypeName ? item.kpiUserEvaluation.posTypeName : null, posLevelName: item.kpiUserEvaluation.posLevelName ? item.kpiUserEvaluation.posLevelName : null, organization: organization ? organization : null, }; }); return new HttpSuccess({ data: mapData, total }); } /** * API รายการพัฒนาตนเอง Admin * * @summary - รายการพัฒนาตนเอง Admin # * */ @Get("admin/detail/{id}") async GetKpiDevelopmentStatusKP7ById( @Request() request: RequestWithUser, @Path("id") id: string, ) { await new permission().PermissionGet(request, "SYS_RESULT"); const kpiUserDevelopment = await this.kpiUserDevelopmentRepository.findOne({ relations: [ "kpiUserEvaluation", "kpiUserEvaluation.kpiPeriod", "developmentProjects", // "kpiUserEvaluation.kpiUserCapacitys", // "kpiUserEvaluation.kpiUserCapacitys.kpiCapacity", ], where: { id: id, }, }); if (!kpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลพัฒนาตนเองนี้"); } const formattedData = { id: kpiUserDevelopment.id, evaluationId: kpiUserDevelopment.kpiUserEvaluation.id, target: kpiUserDevelopment.target, summary: kpiUserDevelopment.summary, point: kpiUserDevelopment.point, name: kpiUserDevelopment.name, achievement10: kpiUserDevelopment.achievement10, achievement5: kpiUserDevelopment.achievement5, achievement0: kpiUserDevelopment.achievement0, isDevelopment70: kpiUserDevelopment.isDevelopment70, isDevelopment20: kpiUserDevelopment.isDevelopment20, isDevelopment10: kpiUserDevelopment.isDevelopment10, // capacity: // kpiUserDevelopment?.kpiUserEvaluation.kpiUserCapacitys.map((kpiUserCapacity) => ({ // capacityPoint: kpiUserCapacity.point, // capacityName: kpiUserCapacity.kpiCapacity.name, // })) ?? [], developmentProjects: kpiUserDevelopment.developmentProjects.map((x) => x.name).sort(), }; return new HttpSuccess(formattedData); } /** * API รายละเอียดพัฒนาตนเอง * * @summary - รายละเอียดพัฒนาตนเอง # * * @param {string} id Id พัฒนาตนเอง */ @Get("registry/{type}/{id}") async GetKpiUserDevelopmentDetailRegistryOfficer(@Request() request: RequestWithUser, @Path() id: string, @Path() type: string) { const getKpiUserDevelopment = await this.kpiUserDevelopmentRepository.findOne({ relations: ["kpiUserEvaluation", "developmentProjects"], where: { id: id }, }); if (!getKpiUserDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลพัฒนาตนเองนี้"); } if(type.trim().toLocaleUpperCase() == "OFFICER"){ await new permission().PermissionOrgUserGet(request, "SYS_REGISTRY_OFFICER", getKpiUserDevelopment.kpiUserEvaluation.profileId); }else if(type.trim().toLocaleUpperCase() == "EMPLOYEE"){ await new permission().PermissionOrgUserGet(request, "SYS_REGISTRY_EMP", getKpiUserDevelopment.kpiUserEvaluation.profileId); }else if(type.trim().toLocaleUpperCase() == "TEMP"){ await new permission().PermissionOrgUserGet(request, "SYS_REGISTRY_TEMP", getKpiUserDevelopment.kpiUserEvaluation.profileId); }else{ throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถเข้าถึงข้อมูลนี้ได้"); } const mapKpiUserDevelopment = { id: getKpiUserDevelopment.id, evaluationId: getKpiUserDevelopment.kpiUserEvaluation.id, target: getKpiUserDevelopment.target, summary: getKpiUserDevelopment.summary, point: getKpiUserDevelopment.point, name: getKpiUserDevelopment.name, achievement10: getKpiUserDevelopment.achievement10, achievement5: getKpiUserDevelopment.achievement5, achievement0: getKpiUserDevelopment.achievement0, isDevelopment70: getKpiUserDevelopment.isDevelopment70, isDevelopment20: getKpiUserDevelopment.isDevelopment20, isDevelopment10: getKpiUserDevelopment.isDevelopment10, reasonDevelopment70: getKpiUserDevelopment.reasonDevelopment70, reasonDevelopment20: getKpiUserDevelopment.reasonDevelopment20, reasonDevelopment10: getKpiUserDevelopment.reasonDevelopment10, selectType: getKpiUserDevelopment.selectType, selectTypeYear: getKpiUserDevelopment.selectTypeYear, selectTypeId: getKpiUserDevelopment.selectTypeId, developmentProjects: getKpiUserDevelopment.developmentProjects.map((x) => x.name).sort(), }; return new HttpSuccess(mapKpiUserDevelopment); } }