diff --git a/src/controllers/ReportController.ts b/src/controllers/ReportController.ts index 1139f2d3..5edcc77c 100644 --- a/src/controllers/ReportController.ts +++ b/src/controllers/ReportController.ts @@ -1,4 +1,14 @@ -import { Controller, Get, Route, Security, Tags, SuccessResponse, Response, Path, Query } from "tsoa"; +import { + Controller, + Get, + Route, + Security, + Tags, + SuccessResponse, + Response, + Path, + Query, +} from "tsoa"; import { AppDataSource } from "../database/data-source"; import HttpSuccess from "../interfaces/http-success"; import HttpStatusCode from "../interfaces/http-status"; @@ -37,7 +47,7 @@ export class ReportController extends Controller { private posMasterRepository = AppDataSource.getRepository(PosMaster); private profileRepository = AppDataSource.getRepository(Profile); private empPosMasterRepository = AppDataSource.getRepository(EmployeePosMaster); - /** + /** * API รายงานสถิติข้อมูลข้าราชการ กทม. สามัญ * * @summary รายงานสถิติข้อมูลข้าราชการ กทม. สามัญ @@ -60,69 +70,79 @@ export class ReportController extends Controller { const minAge = ageMin ?? 18; const maxAge = ageMax ?? 60; - + if (minAge > maxAge) { throw new HttpError(HttpStatus.NOT_FOUND, "ageMin cannot be greater than ageMax"); } - const yearInAD = year?year:null; + const yearInAD = year ? year : null; const currentRevision = await this.orgRevisionRepository.findOne({ - where:{ - orgRevisionIsCurrent: true - } + where: { + orgRevisionIsCurrent: true, + }, }); const rawdataProfile = await this.posMasterRepository - .createQueryBuilder('posMaster') - .leftJoinAndSelect('posMaster.current_holder', 'current_holder') - .leftJoinAndSelect('posMaster.positions', 'positions') - .leftJoinAndSelect('posMaster.orgRoot', 'orgRoot') - .leftJoinAndSelect('positions.posExecutive', 'posExecutive') - .leftJoinAndSelect('current_holder.posType', 'posType') - .leftJoinAndSelect('current_holder.posLevel', 'posLevel') - .leftJoinAndSelect('current_holder.profileEducations', 'profileEducations') - .where('posMaster.orgRevisionId = :currentRevisionId', { currentRevisionId: currentRevision?.id }) - .andWhere(rootId?'posMaster.orgRootId = :rootId': "1=1", { rootId: rootId }) - .andWhere('posMaster.current_holderId Is Not Null') - .andWhere('positions.positionIsSelected = :positionIsSelected', { positionIsSelected: true }) - .andWhere( yearInAD && yearInAD != null? 'YEAR(current_holder.dateAppoint) = :year': "1=1", { year: yearInAD }) - .andWhere(` + .createQueryBuilder("posMaster") + .leftJoinAndSelect("posMaster.current_holder", "current_holder") + .leftJoinAndSelect("posMaster.positions", "positions") + .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") + .leftJoinAndSelect("positions.posExecutive", "posExecutive") + .leftJoinAndSelect("current_holder.posType", "posType") + .leftJoinAndSelect("current_holder.posLevel", "posLevel") + .leftJoinAndSelect("current_holder.profileEducations", "profileEducations") + .where("posMaster.orgRevisionId = :currentRevisionId", { + currentRevisionId: currentRevision?.id, + }) + .andWhere(rootId ? "posMaster.orgRootId = :rootId" : "1=1", { rootId: rootId }) + .andWhere("posMaster.current_holderId Is Not Null") + .andWhere("positions.positionIsSelected = :positionIsSelected", { positionIsSelected: true }) + .andWhere(yearInAD && yearInAD != null ? "YEAR(current_holder.dateAppoint) = :year" : "1=1", { + year: yearInAD, + }) + .andWhere( + ` TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) >= :minAge AND TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) <= :maxAge - `, { minAge, maxAge }) - .orderBy("posType.posTypeName","ASC") - .getMany(); - if(!rawdataProfile){ + `, + { minAge, maxAge }, + ) + .orderBy("posType.posTypeName", "ASC") + .getMany(); + if (!rawdataProfile) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } - const mapData = rawdataProfile - .map((x) => { - const latestEducation = x.current_holder.profileEducations.sort((a:any, b:any) => b.endDate - a.startDate)[0]; + const mapData = rawdataProfile.map((x) => { + const latestEducation = x.current_holder.profileEducations.sort( + (a: any, b: any) => b.endDate - a.startDate, + )[0]; return { name: x.current_holder.firstName + " " + x.current_holder.lastName, - affiliation: x.orgRoot.orgRootName??"-", - gender: x.current_holder.gender??"-", - positionName: x.positions[0]?x.positions[0].positionName:"-", - status: x.current_holder.relationship??"-", - posType: x.current_holder.posType.posTypeName??"-", - posLevel: x.current_holder.posLevel.posLevelName??"-", + affiliation: x.orgRoot.orgRootName ?? "-", + gender: x.current_holder.gender ?? "-", + positionName: x.positions[0] ? x.positions[0].positionName : "-", + status: x.current_holder.relationship ?? "-", + posType: x.current_holder.posType.posTypeName ?? "-", + posLevel: x.current_holder.posLevel.posLevelName ?? "-", degree: latestEducation ? latestEducation.educationLevel : "-", - posExecutive: x.positions[0].posExecutive?x.positions[0].posExecutive.posExecutiveName:"-", + posExecutive: x.positions[0].posExecutive + ? x.positions[0].posExecutive.posExecutiveName + : "-", currentPreiodPos: "-", levelPeriodPos: "-", }; }); - const groupedData = mapData.reduce((acc:any, item) => { - const key = `${item.posType} - ${item.affiliation} - ${item.gender} - ${item.degree || 'ไม่พบข้อมูล'} - ${item.status || 'ไม่พบข้อมูล'} - ${item.positionName} - ${item.posLevel} - ${item.posExecutive || 'ไม่พบข้อมูล'} `; + const groupedData = mapData.reduce((acc: any, item) => { + const key = `${item.posType} - ${item.affiliation} - ${item.gender} - ${item.degree || "ไม่พบข้อมูล"} - ${item.status || "ไม่พบข้อมูล"} - ${item.positionName} - ${item.posLevel} - ${item.posExecutive || "ไม่พบข้อมูล"} `; if (!acc[key]) { acc[key] = { - posType: item.posType && item.posType != "" ? item.posType: "-", - affiliation: item.affiliation && item.affiliation != "" ? item.affiliation: "-", - gender: item.gender && item.gender != "" ? item.gender: "-", - degree: item.degree && item.degree != "" ? item.degree: "-", - status: item.status && item.status != "" ? item.status: "-", - positionName: item.positionName && item.positionName != "" ? item.positionName: "-", - posLevel: item.posLevel && item.posLevel != "" ? item.posLevel: "-", - posExecutive: item.posExecutive && item.posExecutive != "" ? item.posExecutive: "-", + posType: item.posType && item.posType != "" ? item.posType : "-", + affiliation: item.affiliation && item.affiliation != "" ? item.affiliation : "-", + gender: item.gender && item.gender != "" ? item.gender : "-", + degree: item.degree && item.degree != "" ? item.degree : "-", + status: item.status && item.status != "" ? item.status : "-", + positionName: item.positionName && item.positionName != "" ? item.positionName : "-", + posLevel: item.posLevel && item.posLevel != "" ? item.posLevel : "-", + posExecutive: item.posExecutive && item.posExecutive != "" ? item.posExecutive : "-", currentPreiodPos: "-", levelPeriodPos: "-", count: 0, @@ -132,23 +152,25 @@ export class ReportController extends Controller { return acc; }, {}); - + const result = Object.values(groupedData).map((item: any) => ({ - ...item , - count: Extension.ToThaiNumber(item.count.toString()), + ...item, + count: Extension.ToThaiNumber(item.count.toString()), })); - + return new HttpSuccess({ template: "registry-officer", reportName: "xlsx-report", data: { - year: year?Extension.ToThaiNumber(year.toString()):Extension.ToThaiNumber(new Date().getFullYear().toString()), + year: year + ? Extension.ToThaiNumber((year + 543).toString()) + : Extension.ToThaiNumber((new Date().getFullYear() + 543).toString()), date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), - list: result + list: result, }, }); } - /** + /** * API รายงานสถิติข้อมูลลูกจ้างประจำ กทม. * * @summary รายงานสถิติข้อมูลลูกจ้างประจำ กทม. @@ -171,64 +193,73 @@ export class ReportController extends Controller { const minAge = ageMin ?? 18; const maxAge = ageMax ?? 60; - + if (minAge > maxAge) { throw new HttpError(HttpStatus.NOT_FOUND, "ageMin cannot be greater than ageMax"); } - const yearInAD = year?year:null; + const yearInAD = year ? year : null; const currentRevision = await this.orgRevisionRepository.findOne({ - where:{ - orgRevisionIsCurrent: true - } + where: { + orgRevisionIsCurrent: true, + }, }); const rawdataProfile = await this.empPosMasterRepository - .createQueryBuilder('posMaster') - .leftJoinAndSelect('posMaster.current_holder', 'current_holder') - .leftJoinAndSelect('posMaster.positions', 'positions') - .leftJoinAndSelect('posMaster.orgRoot', 'orgRoot') - .leftJoinAndSelect('current_holder.posType', 'posType') - .leftJoinAndSelect('current_holder.posLevel', 'posLevel') - .leftJoinAndSelect('current_holder.profileEducations', 'profileEducations') - .where('posMaster.orgRevisionId = :currentRevisionId', { currentRevisionId: currentRevision?.id }) - .andWhere(rootId?'posMaster.orgRootId = :rootId': "1=1", { rootId: rootId }) - .andWhere('posMaster.current_holderId Is Not Null') - .andWhere('positions.positionIsSelected = :positionIsSelected', { positionIsSelected: true }) - .andWhere( yearInAD && yearInAD != null? 'YEAR(current_holder.dateAppoint) = :year': "1=1", { year: yearInAD }) - .andWhere(` + .createQueryBuilder("posMaster") + .leftJoinAndSelect("posMaster.current_holder", "current_holder") + .leftJoinAndSelect("posMaster.positions", "positions") + .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") + .leftJoinAndSelect("current_holder.posType", "posType") + .leftJoinAndSelect("current_holder.posLevel", "posLevel") + .leftJoinAndSelect("current_holder.profileEducations", "profileEducations") + .where("posMaster.orgRevisionId = :currentRevisionId", { + currentRevisionId: currentRevision?.id, + }) + .andWhere(rootId ? "posMaster.orgRootId = :rootId" : "1=1", { rootId: rootId }) + .andWhere("posMaster.current_holderId Is Not Null") + .andWhere("positions.positionIsSelected = :positionIsSelected", { positionIsSelected: true }) + .andWhere(yearInAD && yearInAD != null ? "YEAR(current_holder.dateAppoint) = :year" : "1=1", { + year: yearInAD, + }) + .andWhere( + ` TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) >= :minAge AND TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) <= :maxAge - `, { minAge, maxAge }) - .orderBy("posType.posTypeName","ASC") - .getMany(); - if(!rawdataProfile){ + `, + { minAge, maxAge }, + ) + .orderBy("posType.posTypeName", "ASC") + .getMany(); + if (!rawdataProfile) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } const mapData = rawdataProfile.map((x) => { - const latestEducation = x.current_holder.profileEducations.sort((a:any, b:any) => b.endDate - a.startDate)[0]; + const latestEducation = x.current_holder.profileEducations.sort( + (a: any, b: any) => b.endDate - a.startDate, + )[0]; return { name: x.current_holder.firstName + " " + x.current_holder.lastName, - affiliation: x.orgRoot.orgRootName??"-", - gender: x.current_holder.gender??"-", - positionName: x.positions[0]?x.positions[0].positionName: "-", - status: x.current_holder.relationship??"-", - posType: x.current_holder.posType.posTypeName??"-", - posLevel: x.current_holder.posLevel.posLevelName??"-", - degree: latestEducation ? latestEducation.educationLevel : "-", + affiliation: x.orgRoot.orgRootName ?? "-", + gender: x.current_holder.gender ?? "-", + positionName: x.positions[0] ? x.positions[0].positionName : "-", + status: x.current_holder.relationship ?? "-", + posType: x.current_holder.posType.posTypeName ?? "-", + posLevel: x.current_holder.posLevel.posLevelName ?? "-", + degree: latestEducation ? latestEducation.educationLevel : "-", period: "-", }; }); - const groupedData = mapData.reduce((acc:any, item) => { - const key = `${item.affiliation} - ${item.gender} - ${item.degree || 'ไม่พบข้อมูล'} - ${item.status || 'ไม่พบข้อมูล'} - ${item.posType} - ${item.positionName} - ${item.posLevel} + const groupedData = mapData.reduce((acc: any, item) => { + const key = `${item.affiliation} - ${item.gender} - ${item.degree || "ไม่พบข้อมูล"} - ${item.status || "ไม่พบข้อมูล"} - ${item.posType} - ${item.positionName} - ${item.posLevel} `; if (!acc[key]) { acc[key] = { - affiliation: item.affiliation && item.affiliation != ""?item.affiliation:"-", - gender: item.gender && item.gender != ""?item.gender:"-", - degree: item.degree && item.degree != ""?item.degree:"-", - status: item.status && item.status != ""?item.status:"-", - posType: item.posType && item.posType != ""?item.posType:"-", - positionName: item.positionName && item.positionName != ""?item.positionName:"-", + affiliation: item.affiliation && item.affiliation != "" ? item.affiliation : "-", + gender: item.gender && item.gender != "" ? item.gender : "-", + degree: item.degree && item.degree != "" ? item.degree : "-", + status: item.status && item.status != "" ? item.status : "-", + posType: item.posType && item.posType != "" ? item.posType : "-", + positionName: item.positionName && item.positionName != "" ? item.positionName : "-", posLevel: Extension.ToThaiNumber(item.posLevel.toString()), period: "-", count: 0, @@ -240,20 +271,21 @@ export class ReportController extends Controller { }, {}); const result = Object.values(groupedData).map((item: any) => ({ - ...item , - count: Extension.ToThaiNumber(item.count.toString()) + ...item, + count: Extension.ToThaiNumber(item.count.toString()), })); - + return new HttpSuccess({ template: "registry-emp", reportName: "xlsx-report", data: { - year: year?Extension.ToThaiNumber(year.toString()):Extension.ToThaiNumber(new Date().getFullYear().toString()), + year: year + ? Extension.ToThaiNumber((year + 543).toString()) + : Extension.ToThaiNumber((new Date().getFullYear() + 543).toString()), date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), - list: result + list: result, }, }); - } /** @@ -6468,11 +6500,11 @@ export class ReportController extends Controller { @Get("report4/{rootId}") async findReport4(@Path() rootId: string) { - const orgRootData = await this.orgRootRepository.findOne({ - where: { id: rootId } + const orgRootData = await this.orgRootRepository.findOne({ + where: { id: rootId }, }); if (!orgRootData) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); - + const posMaster = await this.posMasterRepository .createQueryBuilder("posMaster") .leftJoinAndSelect("posMaster.positions", "position") @@ -6482,17 +6514,20 @@ export class ReportController extends Controller { .orderBy("posType.posTypeRank", "ASC") .addOrderBy("posLevel.posLevelRank", "ASC") .getMany(); - - const _posMaster = posMaster - .map((x) => ({ - type: [...new Set(x.positions.flatMap((y) => y.posType.posTypeName))].join(","), - typeRank: [...new Set(x.positions.flatMap((y) => y.posType.posTypeRank))].join(""), - level: [...new Set(x.positions.flatMap((y) => y.posLevel.posLevelName))].join(","), - levelRank: [...new Set(x.positions.flatMap((y) => `${y.posType.posTypeRank}${y.posLevel.posLevelRank}`))].join(""), - positions: [...new Set(x.positions.flatMap((y) => y.positionName))].join(""), - })) - const groupedData = _posMaster.reduce((acc:any, curr:any) => { + const _posMaster = posMaster.map((x) => ({ + type: [...new Set(x.positions.flatMap((y) => y.posType.posTypeName))].join(","), + typeRank: [...new Set(x.positions.flatMap((y) => y.posType.posTypeRank))].join(""), + level: [...new Set(x.positions.flatMap((y) => y.posLevel.posLevelName))].join(","), + levelRank: [ + ...new Set( + x.positions.flatMap((y) => `${y.posType.posTypeRank}${y.posLevel.posLevelRank}`), + ), + ].join(""), + positions: [...new Set(x.positions.flatMap((y) => y.positionName))].join(""), + })); + + const groupedData = _posMaster.reduce((acc: any, curr: any) => { const key = `${curr.type}|${curr.typeRank}|${curr.level}|${curr.levelRank}`; if (!acc[key]) { acc[key] = { ...curr, total: 1 }; @@ -6501,7 +6536,7 @@ export class ReportController extends Controller { } return acc; }, {}); - + let result = Object.values(groupedData) .map((x: any) => ({ type: x.type, @@ -6523,16 +6558,16 @@ export class ReportController extends Controller { let _total: number = 0; let _reslut = new Array(); - result.forEach((x:any, idx:number) => { + result.forEach((x: any, idx: number) => { allTotal += x.total; total += x.total; - if(x.type === tmpType) { + if (x.type === tmpType) { _reslut.push({ ...x, - type: "" - }) - }else { - if(x.type !== tmpType && tmpType != "") { + type: "", + }); + } else { + if (x.type !== tmpType && tmpType != "") { _total = total - x.total; _reslut.push({ type: "", @@ -6541,13 +6576,13 @@ export class ReportController extends Controller { levelRank: "", total: _total, remark: "", - }) + }); total = x.total; _total = 0; } _reslut.push({ - ...x - }) + ...x, + }); } tmpType = x.type; }); @@ -6559,7 +6594,7 @@ export class ReportController extends Controller { levelRank: "", total: total, remark: "", - }) + }); _reslut.push({ type: "", typeRank: "", @@ -6569,24 +6604,24 @@ export class ReportController extends Controller { remark: "", }); - return new HttpSuccess({ - template: "report4", - reportName: "report4", - data: { + return new HttpSuccess({ + template: "report4", + reportName: "report4", + data: { dateCurrent: Extension.ToThaiShortDate(new Date()), rootName: orgRootData ? orgRootData.orgRootName : "-", - data: _reslut - } - }); + data: _reslut, + }, + }); } @Get("report4-employee/{rootId}") async findReportEmp4(@Path() rootId: string) { - const orgRootData = await this.orgRootRepository.findOne({ - where: { id: rootId } + const orgRootData = await this.orgRootRepository.findOne({ + where: { id: rootId }, }); if (!orgRootData) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); - + const posMaster = await this.empPosMasterRepository .createQueryBuilder("posMaster") .leftJoinAndSelect("posMaster.positions", "position") @@ -6596,17 +6631,20 @@ export class ReportController extends Controller { .orderBy("posType.posTypeRank", "ASC") .addOrderBy("posLevel.posLevelRank", "ASC") .getMany(); - - const _posMaster = posMaster - .map((x) => ({ - type: [...new Set(x.positions.flatMap((y) => y.posType.posTypeName))].join(","), - typeRank: [...new Set(x.positions.flatMap((y) => y.posType.posTypeRank))].join(""), - level: [...new Set(x.positions.flatMap((y) => y.posLevel.posLevelName))].join(","), - levelRank: [...new Set(x.positions.flatMap((y) => `${y.posType.posTypeRank}${y.posLevel.posLevelRank}`))].join(""), - positions: [...new Set(x.positions.flatMap((y) => y.positionName))].join(""), - })) - const groupedData = _posMaster.reduce((acc:any, curr:any) => { + const _posMaster = posMaster.map((x) => ({ + type: [...new Set(x.positions.flatMap((y) => y.posType.posTypeName))].join(","), + typeRank: [...new Set(x.positions.flatMap((y) => y.posType.posTypeRank))].join(""), + level: [...new Set(x.positions.flatMap((y) => y.posLevel.posLevelName))].join(","), + levelRank: [ + ...new Set( + x.positions.flatMap((y) => `${y.posType.posTypeRank}${y.posLevel.posLevelRank}`), + ), + ].join(""), + positions: [...new Set(x.positions.flatMap((y) => y.positionName))].join(""), + })); + + const groupedData = _posMaster.reduce((acc: any, curr: any) => { const key = `${curr.type}|${curr.typeRank}|${curr.level}|${curr.levelRank}`; if (!acc[key]) { acc[key] = { ...curr, total: 1 }; @@ -6615,14 +6653,14 @@ export class ReportController extends Controller { } return acc; }, {}); - + let result = Object.values(groupedData) .map((x: any) => ({ type: x.type, typeRank: parseInt(x.typeRank), level: x.level, levelRank: parseInt(x.levelRank), - + total: x.total, remark: x.positions, })) @@ -6638,16 +6676,16 @@ export class ReportController extends Controller { let _total: number = 0; let _reslut = new Array(); - result.forEach((x:any, idx:number) => { + result.forEach((x: any, idx: number) => { allTotal += x.total; total += x.total; - if(x.type === tmpType) { + if (x.type === tmpType) { _reslut.push({ ...x, - type: "" - }) - }else { - if(x.type !== tmpType && tmpType != "") { + type: "", + }); + } else { + if (x.type !== tmpType && tmpType != "") { _total = total - x.total; _reslut.push({ type: "", @@ -6656,13 +6694,13 @@ export class ReportController extends Controller { levelRank: "", total: _total, remark: "", - }) + }); total = x.total; _total = 0; } _reslut.push({ - ...x - }) + ...x, + }); } tmpType = x.type; }); @@ -6674,7 +6712,7 @@ export class ReportController extends Controller { levelRank: "", total: total, remark: "", - }) + }); _reslut.push({ type: "", typeRank: "", @@ -6684,15 +6722,14 @@ export class ReportController extends Controller { remark: "", }); - return new HttpSuccess({ - template: "report4", - reportName: "report4", - data: { + return new HttpSuccess({ + template: "report4", + reportName: "report4", + data: { dateCurrent: Extension.ToThaiShortDate(new Date()), rootName: orgRootData ? orgRootData.orgRootName : "-", - data: _reslut - } - }); + data: _reslut, + }, + }); } - }