import { Controller, Get, Post, Route, Security, Tags, Body, Path } from "tsoa"; import { AppDataSource } from "../database/data-source"; import HttpSuccess from "../interfaces/http-success"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; import { Development } from "../entities/Development"; import { DevelopmentHistory } from "../entities/DevelopmentHistory"; import { PosType } from "../entities/PosType"; import { PosLevel } from "../entities/PosLevel"; import Extension from "../interfaces/extension"; import { DevelopmentScholarship } from "../entities/DevelopmentScholarship"; import { IsNull, Not } from "typeorm"; @Route("api/v1/development/report") @Tags("Report") @Security("bearerAuth") export class ReportController extends Controller { private developmentScholarshipRepository = AppDataSource.getRepository(DevelopmentScholarship); /** * API Report รายการโครงการ/หลักสูตรการฝึกอบรมที่หน่วยงานของกรุงเทพมหานครเป็นผู้จัด * * @summary DEV_0xx - Report รายการโครงการ/หลักสูตรการฝึกอบรมที่หน่วยงานของกรุงเทพมหานครเป็นผู้จัด #xx * * @param {string} type type ประเภท report */ @Get("main") async GetReportDevelopemtMain(/*@Path() type: string*/) { // const _type = type.trim().toUpperCase(); const formattedData = { org: "_type", }; //ตารางรายละเอียด กับ แบบรายงาน const dataDevelopment = await AppDataSource.getRepository(Development) .createQueryBuilder("development") .leftJoinAndSelect("development.developmentHistorys", "history") .leftJoinAndSelect("development.developmentPlannedGoals", "planGoals") .leftJoinAndSelect("development.strategyChild1Actual", "strategy1") .leftJoinAndSelect("development.strategyChild2Actual", "strategy2") .leftJoinAndSelect("development.strategyChild3Actual", "strategy3") .leftJoinAndSelect("development.strategyChild4Actual", "strategy4") .leftJoinAndSelect("development.strategyChild5Actual", "strategy5") .where("development.status = :status", { status: "FINISH" }) .andWhere("development.strategyChild1ActualId IS NOT NULL") .select([ "development.id AS id", "development.projectName AS projectName", "development.year AS year", "development.totalDate AS totalDate", "development.budget AS budget", "SUM(DISTINCT planGoals.amount) AS goalParticipants", "COUNT(DISTINCT history.id) AS actualParticipants", "strategy1.strategyChild1Name AS strategy1", "strategy2.strategyChild2Name AS strategy2", "strategy3.strategyChild3Name AS strategy3", "strategy4.strategyChild4Name AS strategy4", "strategy5.strategyChild5Name AS strategy5", "development.accept AS acceptBudget", "development.receive AS receiveBudget", "development.obstacle AS obstacle", "development.root AS root", ]) .groupBy("development.id") .getRawMany(); const mappedDataDev = dataDevelopment.map((item, index) => { let budget = null; if (item.budget == "REGULATIONBUDGET") { budget = "งบตามข้อบัญญัติ"; }else if (item.budget == "OTHERBUDGET") { budget = "เงินนอกงบประมาณ"; }else if (item.budget == "BANGKOKBUDGET") { budget = "ไม่ใช้งบประมาณ"; } return { strategy: item.strategy1, projectName: item.projectName, totalDate: item.totalDate != null && item.totalDate != "" ? Extension.ToThaiNumber(item.totalDate.toLocaleString()): "-", goalParticipants: item.goalParticipants != null && item.goalParticipants != "" ? Extension.ToThaiNumber(item.goalParticipants.toLocaleString()): "-", actualParticipants: item.actualParticipants != null && item.actualParticipants != "" ? Extension.ToThaiNumber(item.actualParticipants.toLocaleString()): "-", budget: budget, acceptBudget: item.acceptBudget != null && item.acceptBudget != "" ? Extension.ToThaiNumber(item.acceptBudget.toLocaleString()): "-", receiveBudget: item.receiveBudget != null && item.receiveBudget != "" ? Extension.ToThaiNumber(item.receiveBudget.toLocaleString()): "-", obstacle: item.obstacle, root: item.root, output: "-", outcome: "-", position: "-", indicators: "-", devResult: "-", positionActual: "-", }; }); const resultAllStrategy = await AppDataSource.getRepository(Development) .createQueryBuilder("development") .leftJoinAndSelect("development.strategyChild1Actual", "strategy1") .where("development.status = :status", { status: "FINISH" }) .andWhere("development.strategyChild1ActualId IS NOT NULL") .select([ "development.rootId AS rootId", "development.strategyChild1ActualId AS strategyId", "strategy1.strategyChild1Name AS strategyName", "COUNT(development.id) AS devCount", "SUM(development.receive) AS receiveBudget", "development.root AS root", ]) .groupBy("development.rootId, development.strategyChild1ActualId, strategy1.strategyChild1Name, development.root") .orderBy("strategy1.createdAt", "ASC") .getRawMany(); interface Strategy { strategyId: string; strategyName: string; devCount: string; receiveBudget: string; sumDev: string; sumTraget: string; sumBudget: string; sumRowDev: string, sumRowTarget: string, sumRowBudget: string, } interface GroupedData { rootId: string; root: string; strategy: Strategy[]; } const groupedData: GroupedData[] = resultAllStrategy.reduce((acc: GroupedData[], item) => { const existingRoot = acc.find(entry => entry.rootId === item.rootId); if (existingRoot) { existingRoot.strategy.push({ strategyId: item.strategyId, strategyName: item.strategyName, devCount: item.devCount?item.devCount:"-", receiveBudget: item.receiveBudget?item.receiveBudget:"-", sumDev: "", sumTraget: "", sumBudget: "", sumRowDev:"", sumRowTarget:"", sumRowBudget:"", }); } else { acc.push({ rootId: item.rootId, root: item.root, strategy: [{ strategyId: item.strategyId, strategyName: item.strategyName, devCount: item.devCount?item.devCount:"-", receiveBudget: item.receiveBudget?item.receiveBudget:"-", sumDev: "", sumTraget: "", sumBudget: "", sumRowDev:"", sumRowTarget:"", sumRowBudget:"", }] }); } return acc; }, []); let sumDev1 = 0; let sumTraget1 = 0; let sumBudget1 = 0; let sumDev2 = 0; let sumTraget2 = 0; let sumBudget2 = 0; let sumDev3 = 0; let sumTraget3 = 0; let sumBudget3 = 0; let sumDev4 = 0; let sumTraget4 = 0; let sumBudget4 = 0; const reformattedData = groupedData.map((group,x) => { const sumRowDev = (group.strategy[0] && group.strategy[0].devCount !== "-" ? Number(group.strategy[0].devCount) : 0) + (group.strategy[1] && group.strategy[1].devCount !== "-" ? Number(group.strategy[1].devCount) : 0) + (group.strategy[2] && group.strategy[2].devCount !== "-" ? Number(group.strategy[2].devCount) : 0); (group.strategy[3] && group.strategy[3].devCount !== "-" ? Number(group.strategy[3].devCount) : 0); const sumRowBudget = (group.strategy[0] && group.strategy[0].receiveBudget !== "-" ? Number(group.strategy[0].receiveBudget) : 0) + (group.strategy[1] && group.strategy[1].receiveBudget !== "-" ? Number(group.strategy[1].receiveBudget) : 0) + (group.strategy[2] && group.strategy[2].receiveBudget !== "-" ? Number(group.strategy[2].receiveBudget) : 0); (group.strategy[3] && group.strategy[3].receiveBudget !== "-" ? Number(group.strategy[3].receiveBudget) : 0); sumDev1 = groupedData.reduce((sum, group) => { const devCount = group.strategy[0] && group.strategy[0].devCount !== "-" ? Number(group.strategy[0].devCount) : 0; return sum + devCount; }, 0); sumBudget1 = groupedData.reduce((sum, group) => { const devCount = group.strategy[0] && group.strategy[0].receiveBudget !== "-" ? Number(group.strategy[0].receiveBudget) : 0; return sum + devCount; }, 0); sumDev2 = groupedData.reduce((sum, group) => { const devCount = group.strategy[1] && group.strategy[1].devCount !== "-" ? Number(group.strategy[1].devCount) : 0; return sum + devCount; }, 0); sumBudget2 = groupedData.reduce((sum, group) => { const devCount = group.strategy[1] && group.strategy[1].receiveBudget !== "-" ? Number(group.strategy[1].receiveBudget) : 0; return sum + devCount; }, 0); sumDev3 = groupedData.reduce((sum, group) => { const devCount = group.strategy[2] && group.strategy[2].devCount !== "-" ? Number(group.strategy[2].devCount) : 0; return sum + devCount; }, 0); sumBudget3 = groupedData.reduce((sum, group) => { const devCount = group.strategy[2] && group.strategy[2].receiveBudget !== "-" ? Number(group.strategy[2].receiveBudget) : 0; return sum + devCount; }, 0); sumDev4 = groupedData.reduce((sum, group) => { const devCount = group.strategy[3] && group.strategy[3].devCount !== "-" ? Number(group.strategy[3].devCount) : 0; return sum + devCount; }, 0); sumBudget4 = groupedData.reduce((sum, group) => { const devCount = group.strategy[3] && group.strategy[3].receiveBudget !== "-" ? Number(group.strategy[3].receiveBudget) : 0; return sum + devCount; }, 0); const formattedGroup = { rowNo: x?Extension.ToThaiNumber((x + 1).toString()):Extension.ToThaiNumber("๑"), rootId: group.rootId, root: group.root, strategyName1: group.strategy[0]&&group.strategy[0].strategyName?group.strategy[0].strategyName:"-", devCount1: group.strategy[0]&&group.strategy[0].devCount?Extension.ToThaiNumber(group.strategy[0].devCount.toLocaleString()):"-", target1: "-", receiveBudget1: group.strategy[0]&&group.strategy[0].receiveBudget?Extension.ToThaiNumber(group.strategy[0].receiveBudget.toLocaleString()):"-", strategyName2: group.strategy[1]&&group.strategy[1].strategyName?group.strategy[1].strategyName:"-", devCount2: group.strategy[1]&&group.strategy[1].devCount?Extension.ToThaiNumber(group.strategy[1].devCount.toLocaleString()):"-", target2: "-", receiveBudget2: group.strategy[1]&&group.strategy[1].receiveBudget?Extension.ToThaiNumber(group.strategy[1].receiveBudget.toLocaleString()):"-", strategyName3: group.strategy[2]&&group.strategy[2].strategyName?group.strategy[2].strategyName:"-", devCount3: group.strategy[2]&&group.strategy[2].devCount?Extension.ToThaiNumber(group.strategy[2].devCount.toLocaleString()):"-", target3: "-", receiveBudget3: group.strategy[2]&&group.strategy[2].receiveBudget?Extension.ToThaiNumber(group.strategy[2].receiveBudget.toLocaleString()):"-", strategyName4: group.strategy[3]&&group.strategy[3].strategyName?group.strategy[3].strategyName:"-", devCount4: group.strategy[3]&&group.strategy[3].devCount?Extension.ToThaiNumber(group.strategy[3].devCount.toLocaleString()):"-", target4: "-", receiveBudget4: group.strategy[3]&&group.strategy[3].receiveBudget?Extension.ToThaiNumber(group.strategy[3].receiveBudget.toLocaleString()):"-", sumRowDev: sumRowDev?Extension.ToThaiNumber(sumRowDev.toLocaleString()):"-", sumRowTarget: "-", sumRowBudget: sumRowBudget?Extension.ToThaiNumber(sumRowBudget.toLocaleString()):"-", // strategy: Array(4).fill(null).map((_, index) => { // const strategy = group.strategy[index] || { // strategyName: "", // devCount: "", // target: "", // receiveBudget: "", // sumDev: "", // sumTraget: "", // sumBudget: "", // sumRowDev: "", // sumRowTarget: "", // sumRowBudget: "", // }; // return { // [`strategyName${index + 1}`]: strategy.strategyName ?? "", // [`devCount${index + 1}`]: strategy.devCount ?? "", // [`target${index + 1}`]: "", // [`receiveBudget${index + 1}`]: strategy.receiveBudget ?? "", // [`sumDev${index + 1}`]: strategy.sumDev ?? "", // [`sumTraget${index + 1}`]: strategy.sumTraget ?? "", // [`sumBudget${index + 1}`]: strategy.sumBudget ?? "", // [`sumRowDev`]: strategy.sumRowDev ?? "", // [`sumRowTarget`]: strategy.sumRowTarget ?? "", // [`sumRowBudget`]: strategy.sumRowBudget ?? "", // }; // }), }; return formattedGroup; }); return new HttpSuccess({ template: "development", reportName: "development", data: { data: mappedDataDev, resultAllStrategy: reformattedData, sumDev1: Extension.ToThaiNumber(sumDev1.toLocaleString())??"-", sumTraget1: Extension.ToThaiNumber(sumTraget1.toLocaleString())??"-", sumBudget1: Extension.ToThaiNumber(sumBudget1.toLocaleString())??"-", sumDev2: Extension.ToThaiNumber(sumDev2.toLocaleString())??"-", sumTraget2: Extension.ToThaiNumber(sumTraget2.toLocaleString())??"-", sumBudget2: Extension.ToThaiNumber(sumBudget2.toLocaleString())??"-", sumDev3: Extension.ToThaiNumber(sumDev3.toLocaleString())??"-", sumTraget3: Extension.ToThaiNumber(sumTraget3.toLocaleString())??"-", sumBudget3: Extension.ToThaiNumber(sumBudget3.toLocaleString())??"-", sumDev4: Extension.ToThaiNumber(sumDev4.toLocaleString())??"-", sumTraget4: Extension.ToThaiNumber(sumTraget4.toLocaleString())??"-", sumBudget4: Extension.ToThaiNumber(sumBudget4.toLocaleString())??"-", sumAllDev: Extension.ToThaiNumber((sumDev1 + sumDev2 + sumDev3 + sumDev4).toLocaleString())??"-", sumTraget: Extension.ToThaiNumber((sumTraget1 +sumTraget2 +sumTraget3 +sumTraget4).toLocaleString())??"-", sumAllBudget: Extension.ToThaiNumber((sumBudget1 + sumBudget2 + sumBudget3 + sumBudget4).toLocaleString())??"-", }, }); } /** * API Report รายการประวัติการฝึกอบรม/ดูงานของข้าราชการกรุงเทพมหานครสามัญ * * @summary DEV_0xx - Report รายการประวัติการฝึกอบรม/ดูงานของข้าราชการกรุงเทพมหานครสามัญ #xx * */ @Post("history-officer") async PostReportDevelopemtHistoryOfficer( @Body() body: { year: number; root: string; }, ) { const development = await AppDataSource.getRepository(DevelopmentHistory) .createQueryBuilder("developmentHistory") .leftJoinAndSelect("developmentHistory.posLevel", "posLevel") .leftJoinAndSelect("developmentHistory.posType", "posType") .leftJoinAndSelect("developmentHistory.development", "development") .andWhere(body.year != 0 && body.year != null ? "development.year = :year" : "1=1", { year: body.year, }) .andWhere(body.root != null ? "development.root = :root" : "1=1", { root: body.root, }) .andWhere("developmentHistory.type = :type", { type: "OFFICER" }) .select([ "developmentHistory.citizenId", "developmentHistory.rank", "developmentHistory.position", "developmentHistory.posExecutive", "developmentHistory.developmentId", "developmentHistory.prefix", "developmentHistory.firstName", "developmentHistory.lastName", "posLevel.posLevelName", "posType.posTypeName", "development.projectName", "development.root", ]) .getMany(); const formattedData = development.map((item) => ({ id: item.id, citizenId: Extension.ToThaiNumber(item.citizenId.toString()), fullName: item.prefix + item.firstName + " " + item.lastName, position: item.position, posType: item.posType ? item.posType.posTypeName : null, posLevel: item.posLevel ? item.posLevel.posLevelName : null, posExecutive: item.posExecutive, projectName: item.development ? item.development.projectName : null, root: item.root, })); return new HttpSuccess({ template: "developmentHistoryOfficer", reportName: "developmentHistoryOfficer", data: { data: formattedData, }, }); } /** * API Report รายการประวัติฝึกอบรม/ดูงานลูกจ้าง * * @summary DEV_0xx - Report รายการประวัติฝึกอบรม/ดูงานลูกจ้าง #xx * * @param {number} year year ปี report */ @Post("history-employee") async PostReportDevelopemtHistoryEmployee( @Body() body: { year: number; root: string; }, ) { const development = await AppDataSource.getRepository(DevelopmentHistory) .createQueryBuilder("developmentHistory") .leftJoinAndSelect("developmentHistory.employeePosLevel", "employeePosLevel") .leftJoinAndSelect("developmentHistory.employeePosType", "employeePosType") .leftJoinAndSelect("developmentHistory.development", "development") .andWhere(body.year != 0 && body.year != null ? "development.year = :year" : "1=1", { year: body.year, }) .andWhere(body.root != null ? "development.root = :root" : "1=1", { root: body.root, }) .andWhere("developmentHistory.type = :type", { type: "EMPLOYEE" }) .select([ "developmentHistory.citizenId", "developmentHistory.position", "developmentHistory.developmentId", "developmentHistory.prefix", "developmentHistory.firstName", "developmentHistory.lastName", "employeePosLevel.posLevelName", "employeePosType.posTypeName", "employeePosType.posTypeShortName", "development.projectName", "development.root", ]) .getMany(); const formattedData = development.map((item) => ({ id: item.id, citizenId: Extension.ToThaiNumber(item.citizenId.toString()), fullName: item.prefix + item.firstName + " " + item.lastName, position: item.position, employeePosType: item.employeePosType ? item.employeePosType.posTypeName : null, employeePosLevel: item.employeePosType.posTypeShortName + " " + Extension.ToThaiNumber(item.employeePosLevel.posLevelName.toString()), projectName: item.development ? item.development.projectName : null, root: item.root, })); return new HttpSuccess({ template: "developmentHistoryEmployee", reportName: "developmentHistoryEmployee", data: { data: formattedData, }, }); } /** * API Report รายการข้าราชการฯที่ได้รับทุนการศึกษา/ฝึกอบรม * * @summary DEV_0xx - Report รายการข้าราชการฯที่ได้รับทุนการศึกษา/ฝึกอบรม #xx * */ @Get("scholarship") async GetReportDevelopemtScholarship() { const formattedData = { org: "_type", }; return new HttpSuccess({ template: "development", reportName: "development", data: { data: formattedData, }, }); } /** * API Report ข้าราชการฯที่ได้รับทุนการศึกษา/ฝึกอบรมใน detail * * @summary DEV_0xx - Report ข้าราชการฯที่ได้รับทุนการศึกษา/ฝึกอบรมใน detail #xx * * @param {string} id Id scholarship */ @Get("scholarship/{id}") async GetReportDevelopemtScholarshipDetail(@Path() id: string) { const getDevelopment = await this.developmentScholarshipRepository.findOne({ where: { id: id }, }); if (!getDevelopment) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทุนการศึกษา/ฝึกอบรมนี้"); } if (getDevelopment.scholarshipType != null) { switch (getDevelopment.scholarshipType.trim().toUpperCase()) { case "DOMESTICE": getDevelopment.scholarshipType = "การศึกษาในประเทศ"; break; case "NOABROAD": getDevelopment.scholarshipType = "ฝึกอบรมในประเทศที่ส่งไปพัฒนากับหน่วยวงานภายนอก (หลักสูตรที่ไม่มีการไปต่างประเทศ)"; break; case "ABROAD": getDevelopment.scholarshipType = "ฝึกอบรมในประเทศที่ส่งไปพัฒนากับหน่วยวงานภายนอก (หลักสูตรที่มีการไปต่างประเทศ)"; break; case "EXECUTIVE": getDevelopment.scholarshipType = "ฝึกอบรมในประเทศที่ส่งไปพัฒนากับหน่วยวงานภายนอก (หลักสูตรประเภทนักบริหาร)"; break; case "RESEARCH": getDevelopment.scholarshipType = "ศึกษา ฝึกอบรม ประชุม ดูงาน และปฏิบัติการวิจัย ณ ต่างประเทศ"; break; default: break; } } const formattedData = { id: getDevelopment.id, firstName: getDevelopment.firstName, lastName: getDevelopment.lastName, position: getDevelopment.position, org: getDevelopment.org, degreeLevel: getDevelopment.degreeLevel, course: getDevelopment.course, field: getDevelopment.field, studyPlace: getDevelopment.studyPlace, scholarshipType: getDevelopment.scholarshipType, bookNoDate: getDevelopment.bookNoDate == null ? "" : Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.bookNoDate)), startDate: getDevelopment.startDate == null ? "" : Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.startDate)), endDate: getDevelopment.endDate == null ? "" : Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.endDate)), reportBackNo: getDevelopment.reportBackNo == null ? "" : Extension.ToThaiNumber(getDevelopment.reportBackNo), reportBackNoDate: getDevelopment.reportBackNoDate == null ? "" : Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.reportBackNoDate)), governmentDate: getDevelopment.governmentDate == null ? "" : Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.governmentDate)), graduatedDate: getDevelopment.graduatedDate == null ? "" : Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.graduatedDate)), graduatedReason: getDevelopment.graduatedReason == null ? "" : getDevelopment.graduatedReason, useOfficialTime: getDevelopment.useOfficialTime, useOffTime: getDevelopment.useOfficialTime == true ? "🗹 ใช้ ☐ ไม่ใช้" : "☐ ใช้ 🗹 ไม่ใช้", isGraduated: getDevelopment.isGraduated, isG1: getDevelopment.isGraduated == true ? "🗹" : "☐", isG2: getDevelopment.isGraduated == true ? "☐" : "🗹", totalPeriod: getDevelopment.totalPeriod == null || getDevelopment.totalPeriod == "" ? "" : Extension.ToThaiNumber(getDevelopment.totalPeriod), }; return new HttpSuccess({ template: "repatriation", reportName: "repatriation", data: formattedData, }); } }