hrms-api-development/src/controllers/ReportController.ts

509 lines
22 KiB
TypeScript
Raw Normal View History

2024-09-03 15:18:30 +07:00
import { Controller, Get, Post, Route, Security, Tags, Body, Path } from "tsoa";
2024-04-09 11:38:13 +07:00
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";
2024-09-03 15:18:30 +07:00
import { DevelopmentHistory } from "../entities/DevelopmentHistory";
2024-04-09 11:38:13 +07:00
import { PosType } from "../entities/PosType";
import { PosLevel } from "../entities/PosLevel";
import Extension from "../interfaces/extension";
import { DevelopmentScholarship } from "../entities/DevelopmentScholarship";
2025-01-17 20:02:52 +07:00
import { IsNull, Not } from "typeorm";
2024-04-09 11:38:13 +07:00
@Route("api/v1/development/report")
@Tags("Report")
@Security("bearerAuth")
export class ReportController extends Controller {
private developmentScholarshipRepository = AppDataSource.getRepository(DevelopmentScholarship);
2024-04-09 11:38:13 +07:00
/**
* API Report /
*
* @summary DEV_0xx - Report / #xx
*
* @param {string} type type report
*/
2024-07-17 13:19:20 +07:00
@Get("main")
async GetReportDevelopemtMain(/*@Path() type: string*/) {
2025-01-17 20:02:52 +07:00
2024-07-17 12:47:36 +07:00
// const _type = type.trim().toUpperCase();
2024-04-09 11:38:13 +07:00
const formattedData = {
2024-07-17 12:47:36 +07:00
org: "_type",
2024-04-09 11:38:13 +07:00
};
2025-01-17 20:02:52 +07:00
//ตารางรายละเอียด กับ แบบรายงาน
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.toString()): "-",
goalParticipants: item.goalParticipants != null && item.goalParticipants != "" ? Extension.ToThaiNumber(item.goalParticipants.toString()): "-",
actualParticipants: item.actualParticipants != null && item.actualParticipants != "" ? Extension.ToThaiNumber(item.actualParticipants.toString()): "-",
budget: budget,
acceptBudget: item.acceptBudget != null && item.acceptBudget != "" ? Extension.ToThaiNumber(item.acceptBudget.toString()): "-",
receiveBudget: item.receiveBudget != null && item.receiveBudget != "" ? Extension.ToThaiNumber(item.receiveBudget.toString()): "-",
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,
2025-01-20 18:20:09 +07:00
devCount: item.devCount?item.devCount:"-",
receiveBudget: item.receiveBudget?item.receiveBudget:"-",
2025-01-17 20:02:52 +07:00
sumDev: "",
sumTraget: "",
sumBudget: "",
sumRowDev:"",
sumRowTarget:"",
sumRowBudget:"",
});
} else {
acc.push({
rootId: item.rootId,
root: item.root,
strategy: [{
strategyId: item.strategyId,
strategyName: item.strategyName,
2025-01-20 18:20:09 +07:00
devCount: item.devCount?item.devCount:"-",
receiveBudget: item.receiveBudget?item.receiveBudget:"-",
2025-01-17 20:02:52 +07:00
sumDev: "",
sumTraget: "",
sumBudget: "",
sumRowDev:"",
sumRowTarget:"",
sumRowBudget:"",
}]
});
}
return acc;
}, []);
const reformattedData = groupedData.map((group,x) => {
2025-01-20 18:20:09 +07:00
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);
2025-01-17 20:02:52 +07:00
const formattedGroup = {
rowNo: x?Extension.ToThaiNumber((x + 1).toString()):Extension.ToThaiNumber("๑"),
rootId: group.rootId,
root: group.root,
2025-01-20 18:20:09 +07:00
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.toString()):"-",
target1: "-",
receiveBudget1: group.strategy[0]&&group.strategy[0].receiveBudget?Extension.ToThaiNumber(group.strategy[0].receiveBudget.toString()):"-",
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.toString()):"-",
target2: "-",
receiveBudget2: group.strategy[1]&&group.strategy[1].receiveBudget?Extension.ToThaiNumber(group.strategy[1].receiveBudget.toString()):"-",
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.toString()):"-",
target3: "-",
receiveBudget3: group.strategy[2]&&group.strategy[2].receiveBudget?Extension.ToThaiNumber(group.strategy[2].receiveBudget.toString()):"-",
2025-01-17 20:02:52 +07:00
2025-01-20 18:20:09 +07:00
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.toString()):"-",
target4: "-",
receiveBudget4: group.strategy[3]&&group.strategy[3].receiveBudget?Extension.ToThaiNumber(group.strategy[3].receiveBudget.toString()):"-",
sumRowDev: sumRowDev?Extension.ToThaiNumber(sumRowDev.toString()):"-",
sumRowTarget: "-",
sumRowBudget: sumRowBudget?Extension.ToThaiNumber(sumRowBudget.toString()):"-",
// 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 ?? "",
// };
// }),
2025-01-17 20:02:52 +07:00
};
return formattedGroup;
});
2024-04-09 11:38:13 +07:00
return new HttpSuccess({
template: "development",
reportName: "development",
data: {
2025-01-17 20:02:52 +07:00
data: mappedDataDev,
resultAllStrategy: reformattedData,
2025-01-20 18:20:09 +07:00
sumDev1: "-",
sumTraget1: "-",
sumBudget1: "-",
sumDev2: "-",
sumTraget2: "-",
sumBudget2: "-",
sumDev3: "-",
sumTraget3: "-",
sumBudget3: "-",
sumDev4: "-",
sumTraget4: "-",
sumBudget4: "-",
2024-04-09 11:38:13 +07:00
},
});
}
/**
* 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,
}));
2024-04-09 11:38:13 +07:00
return new HttpSuccess({
template: "developmentHistoryOfficer",
reportName: "developmentHistoryOfficer",
2024-04-09 11:38:13 +07:00
data: {
data: formattedData,
},
});
}
/**
* API Report /
*
* @summary DEV_0xx - Report / #xx
*
* @param {number} year year report
2024-04-09 11:38:13 +07:00
*/
@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,
}));
2024-04-09 11:38:13 +07:00
return new HttpSuccess({
template: "developmentHistoryEmployee",
reportName: "developmentHistoryEmployee",
2024-04-09 11:38:13 +07:00
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;
default:
break;
}
}
const formattedData = {
id: getDevelopment.id,
firstName: getDevelopment.firstName,
lastName: getDevelopment.lastName,
position: getDevelopment.position,
2024-04-19 09:28:57 +07:00
org: getDevelopment.org,
degreeLevel: getDevelopment.degreeLevel,
course: getDevelopment.course,
field: getDevelopment.field,
studyPlace: getDevelopment.studyPlace,
scholarshipType: getDevelopment.scholarshipType,
2024-04-19 09:28:57 +07:00
bookNoDate:
getDevelopment.bookNoDate == null
? ""
2024-07-17 13:58:37 +07:00
: Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.bookNoDate)),
startDate:
getDevelopment.startDate == null
? ""
2024-07-17 13:58:37 +07:00
: Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.startDate)),
endDate:
getDevelopment.endDate == null
? ""
2024-07-17 13:58:37 +07:00
: Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.endDate)),
reportBackNo:
getDevelopment.reportBackNo == null
? ""
: Extension.ToThaiNumber(getDevelopment.reportBackNo),
reportBackNoDate:
getDevelopment.reportBackNoDate == null
? ""
2024-07-17 13:58:37 +07:00
: Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.reportBackNoDate)),
governmentDate:
getDevelopment.governmentDate == null
? ""
2024-07-17 13:58:37 +07:00
: Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.governmentDate)),
graduatedDate:
getDevelopment.graduatedDate == null
? ""
2024-07-17 13:58:37 +07:00
: Extension.ToThaiNumber(Extension.ToThaiFullDate3(getDevelopment.graduatedDate)),
2024-09-03 15:18:30 +07:00
graduatedReason: getDevelopment.graduatedReason == null ? "" : getDevelopment.graduatedReason,
useOfficialTime: getDevelopment.useOfficialTime,
useOffTime: getDevelopment.useOfficialTime == true ? "🗹 ใช้ ☐ ไม่ใช้" : "☐ ใช้ 🗹 ไม่ใช้",
isGraduated: getDevelopment.isGraduated,
isG1: getDevelopment.isGraduated == true ? "🗹" : "☐",
isG2: getDevelopment.isGraduated == true ? "☐" : "🗹",
2024-07-17 12:47:36 +07:00
totalPeriod:
getDevelopment.totalPeriod == null || getDevelopment.totalPeriod == ""
2024-07-17 12:47:36 +07:00
? ""
: Extension.ToThaiNumber(getDevelopment.totalPeriod),
};
return new HttpSuccess({
template: "repatriation",
reportName: "repatriation",
data: formattedData,
});
}
2024-04-09 11:38:13 +07:00
}