Merge branch 'develop' into dev
* develop: update #29 test throw report api add \n add \n orgName fix word add noti and test fix word #28 revert code to normal revert checkOrg test safeStringify revert test try catch fix update timezone
This commit is contained in:
commit
9a282ab2be
7 changed files with 248 additions and 91 deletions
|
|
@ -9,10 +9,14 @@ import error from "./middlewares/error";
|
||||||
import { AppDataSource } from "./database/data-source";
|
import { AppDataSource } from "./database/data-source";
|
||||||
import { RegisterRoutes } from "./routes";
|
import { RegisterRoutes } from "./routes";
|
||||||
import logMiddleware from "./middlewares/logs";
|
import logMiddleware from "./middlewares/logs";
|
||||||
|
import { DateSerializer } from "./interfaces/date-serializer";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
await AppDataSource.initialize();
|
await AppDataSource.initialize();
|
||||||
|
|
||||||
|
// Setup custom Date serialization for local timezone
|
||||||
|
DateSerializer.setupDateSerialization();
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
|
|
|
||||||
|
|
@ -438,11 +438,11 @@ export class kpiCapacityController extends Controller {
|
||||||
async listKpiCapacity(
|
async listKpiCapacity(
|
||||||
@Request() request: RequestWithUser,
|
@Request() request: RequestWithUser,
|
||||||
@Query("page") page: number = 1,
|
@Query("page") page: number = 1,
|
||||||
@Query("pageSize") pageSize: number = 10,
|
@Query("pageSize") pageSize?: number,
|
||||||
@Query("type") type?: string,
|
@Query("type") type?: string,
|
||||||
@Query("keyword") keyword?: string,
|
@Query("keyword") keyword?: string,
|
||||||
) {
|
) {
|
||||||
const [kpiCapacity, total] = await AppDataSource.getRepository(KpiCapacity)
|
let query = await AppDataSource.getRepository(KpiCapacity)
|
||||||
.createQueryBuilder("kpiCapacity")
|
.createQueryBuilder("kpiCapacity")
|
||||||
.leftJoinAndSelect("kpiCapacity.kpiCapacityDetails", "kpiCapacityDetail")
|
.leftJoinAndSelect("kpiCapacity.kpiCapacityDetails", "kpiCapacityDetail")
|
||||||
.andWhere(
|
.andWhere(
|
||||||
|
|
@ -452,8 +452,13 @@ export class kpiCapacityController extends Controller {
|
||||||
)
|
)
|
||||||
.andWhere(type == undefined ? "1=1" : { type: type })
|
.andWhere(type == undefined ? "1=1" : { type: type })
|
||||||
.orderBy("kpiCapacity.createdAt", "ASC")
|
.orderBy("kpiCapacity.createdAt", "ASC")
|
||||||
.skip((page - 1) * pageSize)
|
|
||||||
.take(pageSize)
|
if (pageSize) {
|
||||||
|
query = query.skip((page - 1) * pageSize)
|
||||||
|
.take(pageSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
const [kpiCapacity, total] = await query
|
||||||
.getManyAndCount();
|
.getManyAndCount();
|
||||||
|
|
||||||
const mapFormula = kpiCapacity.map((item) => ({
|
const mapFormula = kpiCapacity.map((item) => ({
|
||||||
|
|
|
||||||
|
|
@ -533,7 +533,7 @@ export class KpiUserDevelopmentController extends Controller {
|
||||||
|
|
||||||
const organization = fullNameParts
|
const organization = fullNameParts
|
||||||
.filter((part) => part !== undefined && part !== null)
|
.filter((part) => part !== undefined && part !== null)
|
||||||
.join(" ");
|
.join("\n");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,7 @@ export class KpiUserEvaluationController extends Controller {
|
||||||
|
|
||||||
const organization = fullNameParts
|
const organization = fullNameParts
|
||||||
.filter((part) => part !== undefined && part !== null)
|
.filter((part) => part !== undefined && part !== null)
|
||||||
.join(" ");
|
.join("\n");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
|
@ -667,6 +667,14 @@ export class KpiUserEvaluationController extends Controller {
|
||||||
@Body() requestBody: createKpiUserEvaluation,
|
@Body() requestBody: createKpiUserEvaluation,
|
||||||
@Request() request: RequestWithUser,
|
@Request() request: RequestWithUser,
|
||||||
) {
|
) {
|
||||||
|
if(requestBody.evaluatorId == requestBody.commanderId ||
|
||||||
|
requestBody.commanderId == requestBody.commanderHighId ||
|
||||||
|
requestBody.evaluatorId == requestBody.commanderHighId){
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่สามารถเลือกผู้ประเมินหรือผู้บังคับบัญชาซ้ำกันได้",
|
||||||
|
);
|
||||||
|
}
|
||||||
// await new permission().PermissionCreate(request, "SYS_KPI_LIST");
|
// await new permission().PermissionCreate(request, "SYS_KPI_LIST");
|
||||||
const kpiPeriod = await this.kpiPeriodRepository.findOne({
|
const kpiPeriod = await this.kpiPeriodRepository.findOne({
|
||||||
where: { id: requestBody.kpiPeriodId },
|
where: { id: requestBody.kpiPeriodId },
|
||||||
|
|
@ -1117,6 +1125,25 @@ export class KpiUserEvaluationController extends Controller {
|
||||||
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
|
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (requestBody.status.trim().toUpperCase() == "EVALUATOR") {
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti/profiles", {
|
||||||
|
subject: `${kpiUserEvaluation.prefix}${kpiUserEvaluation.firstName} ${kpiUserEvaluation.lastName} ส่งคำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลให้พิจารณา`,
|
||||||
|
body: `${kpiUserEvaluation.prefix}${kpiUserEvaluation.firstName} ${kpiUserEvaluation.lastName} ส่งคำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลให้พิจารณา`,
|
||||||
|
receiverUserIds: [
|
||||||
|
{
|
||||||
|
receiverUserId: kpiUserEvaluation.evaluatorId,
|
||||||
|
notiLink: `${process.env.VITE_URL_USER}/KPI-evaluator/${kpiUserEvaluation.id}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
isSendNotification: true,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
const before = structuredClone(kpiUserEvaluation);
|
const before = structuredClone(kpiUserEvaluation);
|
||||||
kpiUserEvaluation.evaluationReqEdit = requestBody.status.trim().toUpperCase();
|
kpiUserEvaluation.evaluationReqEdit = requestBody.status.trim().toUpperCase();
|
||||||
kpiUserEvaluation.lastUpdateUserId = request.user.sub;
|
kpiUserEvaluation.lastUpdateUserId = request.user.sub;
|
||||||
|
|
@ -1318,60 +1345,73 @@ export class KpiUserEvaluationController extends Controller {
|
||||||
@Body() requestBody: { reason: string; actor: string },
|
@Body() requestBody: { reason: string; actor: string },
|
||||||
@Request() request: RequestWithUser,
|
@Request() request: RequestWithUser,
|
||||||
) {
|
) {
|
||||||
const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({
|
try{
|
||||||
where: { id: id },
|
const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({
|
||||||
});
|
where: { id: id },
|
||||||
if (!kpiUserEvaluation) {
|
});
|
||||||
|
if (!kpiUserEvaluation) {
|
||||||
|
throw new HttpError(
|
||||||
|
HttpStatusCode.NOT_FOUND,
|
||||||
|
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti/profiles", {
|
||||||
|
subject: `${kpiUserEvaluation.prefix}${kpiUserEvaluation.firstName} ${kpiUserEvaluation.lastName} มีความเห็นต่างเนื่องจาก: ${requestBody.reason}`,
|
||||||
|
body: `${kpiUserEvaluation.prefix}${kpiUserEvaluation.firstName} ${kpiUserEvaluation.lastName} มีความเห็นต่างเนื่องจาก: ${requestBody.reason}`,
|
||||||
|
receiverUserIds: [
|
||||||
|
{
|
||||||
|
receiverUserId: kpiUserEvaluation.evaluatorId,
|
||||||
|
notiLink: `${process.env.VITE_URL_USER}/KPI-evaluator/${kpiUserEvaluation.id}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
isSendNotification: true,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {});
|
||||||
|
const before = structuredClone(kpiUserEvaluation);
|
||||||
|
let _null: any = null;
|
||||||
|
kpiUserEvaluation.evaluationStatus = "EVALUATING_EVALUATOR";
|
||||||
|
kpiUserEvaluation.isReasonCommander = _null;
|
||||||
|
kpiUserEvaluation.reasonCommander = _null;
|
||||||
|
kpiUserEvaluation.reasonReject = requestBody.reason;
|
||||||
|
kpiUserEvaluation.actorReject = requestBody.actor;
|
||||||
|
kpiUserEvaluation.actorNameReject = request.user.name;
|
||||||
|
kpiUserEvaluation.lastUpdateUserId = request.user.sub;
|
||||||
|
kpiUserEvaluation.lastUpdateFullName = request.user.name;
|
||||||
|
kpiUserEvaluation.lastUpdatedAt = new Date();
|
||||||
|
let kpiReject = {
|
||||||
|
kpiUserEvaluationId: kpiUserEvaluation.id,
|
||||||
|
reason: requestBody.reason,
|
||||||
|
actor: requestBody.actor,
|
||||||
|
fullname: `${kpiUserEvaluation.prefixEvaluator}${kpiUserEvaluation.firstNameEvaluator} ${kpiUserEvaluation.lastNameEvaluator}`,
|
||||||
|
profileId: kpiUserEvaluation.evaluatorId,
|
||||||
|
createdUserId: request.user.sub,
|
||||||
|
createdFullName: request.user.name,
|
||||||
|
lastUpdateUserId: request.user.sub,
|
||||||
|
lastUpdateFullName: request.user.name,
|
||||||
|
createdAt: new Date(),
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
};
|
||||||
|
await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request });
|
||||||
|
await this.kpiUserRejectResultRepository.save(kpiReject);
|
||||||
|
setLogDataDiff(request, { before, after: kpiUserEvaluation });
|
||||||
|
return new HttpSuccess(kpiUserEvaluation.id);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error("เกิดข้อผิดพลาดระหว่างการประมวลผล:", error);
|
||||||
|
|
||||||
|
if (error instanceof HttpError) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
throw new HttpError(
|
throw new HttpError(
|
||||||
HttpStatusCode.NOT_FOUND,
|
HttpStatusCode.INTERNAL_SERVER_ERROR,
|
||||||
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
|
"เกิดข้อผิดพลาดภายในระบบ กรุณาลองใหม่อีกครั้ง",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await new CallAPI()
|
|
||||||
.PostData(request, "/placement/noti/profiles", {
|
|
||||||
subject: `${kpiUserEvaluation.prefix}${kpiUserEvaluation.firstName} ${kpiUserEvaluation.lastName} มีความเห็นต่างเนื่องจาก: ${requestBody.reason}`,
|
|
||||||
body: `${kpiUserEvaluation.prefix}${kpiUserEvaluation.firstName} ${kpiUserEvaluation.lastName} มีความเห็นต่างเนื่องจาก: ${requestBody.reason}`,
|
|
||||||
receiverUserIds: [
|
|
||||||
{
|
|
||||||
receiverUserId: kpiUserEvaluation.evaluatorId,
|
|
||||||
notiLink: `${process.env.VITE_URL_USER}/KPI-evaluator/${kpiUserEvaluation.id}`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
payload: "",
|
|
||||||
isSendMail: true,
|
|
||||||
isSendInbox: true,
|
|
||||||
isSendNotification: true,
|
|
||||||
})
|
|
||||||
.then(() => {})
|
|
||||||
.catch(() => {});
|
|
||||||
const before = structuredClone(kpiUserEvaluation);
|
|
||||||
let _null: any = null;
|
|
||||||
kpiUserEvaluation.evaluationStatus = "EVALUATING_EVALUATOR";
|
|
||||||
kpiUserEvaluation.isReasonCommander = _null;
|
|
||||||
kpiUserEvaluation.reasonCommander = _null;
|
|
||||||
kpiUserEvaluation.reasonReject = requestBody.reason;
|
|
||||||
kpiUserEvaluation.actorReject = requestBody.actor;
|
|
||||||
kpiUserEvaluation.actorNameReject = request.user.name;
|
|
||||||
kpiUserEvaluation.lastUpdateUserId = request.user.sub;
|
|
||||||
kpiUserEvaluation.lastUpdateFullName = request.user.name;
|
|
||||||
kpiUserEvaluation.lastUpdatedAt = new Date();
|
|
||||||
let kpiReject = {
|
|
||||||
kpiUserEvaluationId: kpiUserEvaluation.id,
|
|
||||||
reason: requestBody.reason,
|
|
||||||
actor: requestBody.actor,
|
|
||||||
fullname: `${kpiUserEvaluation.prefixEvaluator}${kpiUserEvaluation.firstNameEvaluator} ${kpiUserEvaluation.lastNameEvaluator}`,
|
|
||||||
profileId: kpiUserEvaluation.evaluatorId,
|
|
||||||
createdUserId: request.user.sub,
|
|
||||||
createdFullName: request.user.name,
|
|
||||||
lastUpdateUserId: request.user.sub,
|
|
||||||
lastUpdateFullName: request.user.name,
|
|
||||||
createdAt: new Date(),
|
|
||||||
lastUpdatedAt: new Date(),
|
|
||||||
};
|
|
||||||
await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request });
|
|
||||||
await this.kpiUserRejectResultRepository.save(kpiReject);
|
|
||||||
setLogDataDiff(request, { before, after: kpiUserEvaluation });
|
|
||||||
return new HttpSuccess(kpiUserEvaluation.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1817,6 +1857,23 @@ export class KpiUserEvaluationController extends Controller {
|
||||||
item.evaluationStatus = "NEW";
|
item.evaluationStatus = "NEW";
|
||||||
} else {
|
} else {
|
||||||
item.evaluationReqEdit = "COMMANDER";
|
item.evaluationReqEdit = "COMMANDER";
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti/profiles", {
|
||||||
|
subject: `${item.prefix}${item.firstName} ${item.lastName} ส่งคำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลให้พิจารณา`,
|
||||||
|
body: `${item.prefix}${item.firstName} ${item.lastName} ส่งคำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลให้พิจารณา`,
|
||||||
|
receiverUserIds: [
|
||||||
|
{
|
||||||
|
receiverUserId: item.commanderId,
|
||||||
|
notiLink: `${process.env.VITE_URL_USER}/KPI-evaluator/${item.id}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
isSendNotification: true,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (role == "COMMANDER") {
|
} else if (role == "COMMANDER") {
|
||||||
|
|
@ -1826,11 +1883,45 @@ export class KpiUserEvaluationController extends Controller {
|
||||||
item.evaluationStatus = "NEW";
|
item.evaluationStatus = "NEW";
|
||||||
} else {
|
} else {
|
||||||
item.evaluationReqEdit = "COMMANDER_HIGH";
|
item.evaluationReqEdit = "COMMANDER_HIGH";
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti/profiles", {
|
||||||
|
subject: `${item.prefix}${item.firstName} ${item.lastName} ส่งคำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลให้พิจารณา`,
|
||||||
|
body: `${item.prefix}${item.firstName} ${item.lastName} ส่งคำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลให้พิจารณา`,
|
||||||
|
receiverUserIds: [
|
||||||
|
{
|
||||||
|
receiverUserId: item.commanderHighId,
|
||||||
|
notiLink: `${process.env.VITE_URL_USER}/KPI-evaluator/${item.id}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
isSendNotification: true,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
item.evaluationReqEdit = requestBody.status.trim().toUpperCase();
|
item.evaluationReqEdit = requestBody.status.trim().toUpperCase();
|
||||||
item.evaluationStatus = "NEW";
|
item.evaluationStatus = "NEW";
|
||||||
|
await new CallAPI()
|
||||||
|
.PostData(request, "/placement/noti/profiles", {
|
||||||
|
subject: `คำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลได้รับการพิจารณาแล้ว`,
|
||||||
|
body: `คำขอแก้ไขข้อตกลงการประเมินผลการปฏิบัติราชการระดับบุคคลได้รับการพิจารณาแล้ว`,
|
||||||
|
receiverUserIds: [
|
||||||
|
{
|
||||||
|
receiverUserId: item.profileId,
|
||||||
|
notiLink: `${process.env.VITE_URL_USER}/KPI-evaluator/${item.id}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
payload: "",
|
||||||
|
isSendMail: true,
|
||||||
|
isSendInbox: true,
|
||||||
|
isSendNotification: true,
|
||||||
|
})
|
||||||
|
.then(() => {})
|
||||||
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
item.evaluationReqEdit = requestBody.status.trim().toUpperCase();
|
item.evaluationReqEdit = requestBody.status.trim().toUpperCase();
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import { KpiCapacity } from "../entities/kpiCapacity";
|
||||||
import { KpiPlan } from "../entities/kpiPlan";
|
import { KpiPlan } from "../entities/kpiPlan";
|
||||||
import { KpiRole } from "../entities/kpiRole";
|
import { KpiRole } from "../entities/kpiRole";
|
||||||
import CallAPI from "../interfaces/call-api";
|
import CallAPI from "../interfaces/call-api";
|
||||||
|
import { throws } from "assert";
|
||||||
@Route("api/v1/kpi/report")
|
@Route("api/v1/kpi/report")
|
||||||
@Tags("Report")
|
@Tags("Report")
|
||||||
@Security("bearerAuth")
|
@Security("bearerAuth")
|
||||||
|
|
@ -571,7 +572,9 @@ export class ReportController extends Controller {
|
||||||
"AVG(kpiUserEvaluation.summaryPoint) as avgSummaryPoint"
|
"AVG(kpiUserEvaluation.summaryPoint) as avgSummaryPoint"
|
||||||
])
|
])
|
||||||
.getRawMany();
|
.getRawMany();
|
||||||
|
if(!profileEvaluationNowYearIds || profileEvaluationNowYearIds.length === 0){
|
||||||
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรายงานการประเมินผลฯ ระดับบุคคลของบุคคลนี้");
|
||||||
|
}
|
||||||
// const profileEvaluations = await this.kpiUserEvaluationRepository.find({
|
// const profileEvaluations = await this.kpiUserEvaluationRepository.find({
|
||||||
// relations: ["kpiPeriod"],
|
// relations: ["kpiPeriod"],
|
||||||
// where: { id: In(profileEvaluationNowYearIds.map((evaluation) => evaluation.id)) },
|
// where: { id: In(profileEvaluationNowYearIds.map((evaluation) => evaluation.id)) },
|
||||||
|
|
@ -775,6 +778,9 @@ export class ReportController extends Controller {
|
||||||
relations: ["kpiPeriod"],
|
relations: ["kpiPeriod"],
|
||||||
where: { id: In(profileEvaluationIds.map((evaluation) => evaluation.id)) },
|
where: { id: In(profileEvaluationIds.map((evaluation) => evaluation.id)) },
|
||||||
});
|
});
|
||||||
|
if(!profileEvaluation || profileEvaluation.length === 0){
|
||||||
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรายงานการประเมินผลฯ ระดับบุคคลของบุคคลนี้");
|
||||||
|
}
|
||||||
|
|
||||||
const combinedData: KPIData = profileEvaluation.reduce(
|
const combinedData: KPIData = profileEvaluation.reduce(
|
||||||
(acc: KPIData, x) => {
|
(acc: KPIData, x) => {
|
||||||
|
|
@ -1155,6 +1161,9 @@ export class ReportController extends Controller {
|
||||||
relations: ["kpiPeriod"],
|
relations: ["kpiPeriod"],
|
||||||
where: { id: In(profileEvaluationIds.map((evaluation) => evaluation.id)) },
|
where: { id: In(profileEvaluationIds.map((evaluation) => evaluation.id)) },
|
||||||
});
|
});
|
||||||
|
if(!profileEvaluation || profileEvaluation.length === 0){
|
||||||
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรายงานการประเมินผลฯ ระดับบุคคลของบุคคลนี้");
|
||||||
|
}
|
||||||
|
|
||||||
const combinedData: KPIData = profileEvaluation.reduce(
|
const combinedData: KPIData = profileEvaluation.reduce(
|
||||||
(acc: KPIData, x) => {
|
(acc: KPIData, x) => {
|
||||||
|
|
@ -1493,6 +1502,9 @@ export class ReportController extends Controller {
|
||||||
.groupBy("kpiUserEvaluation.kpiPeriodId")
|
.groupBy("kpiUserEvaluation.kpiPeriodId")
|
||||||
.select("MIN(kpiUserEvaluation.id) as id")
|
.select("MIN(kpiUserEvaluation.id) as id")
|
||||||
.getRawMany();
|
.getRawMany();
|
||||||
|
if(!profileEvaluationIds || profileEvaluationIds.length === 0){
|
||||||
|
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรายงานการประเมินผลฯ ระดับบุคคลของบุคคลนี้");
|
||||||
|
}
|
||||||
if (profileEvaluationIds.length > 0) {
|
if (profileEvaluationIds.length > 0) {
|
||||||
userInfo = await this.kpiUserEvaluationRepository.find({
|
userInfo = await this.kpiUserEvaluationRepository.find({
|
||||||
where: {
|
where: {
|
||||||
|
|
@ -1525,7 +1537,6 @@ export class ReportController extends Controller {
|
||||||
const dev20text = "การเรียนรู้จากผู้อื่น (Coach/Mentor/Consulting)";
|
const dev20text = "การเรียนรู้จากผู้อื่น (Coach/Mentor/Consulting)";
|
||||||
const dev70text = "การลงมือปฏิบัติ (โดยผู้บังคับบัญชามอบหมาย)";
|
const dev70text = "การลงมือปฏิบัติ (โดยผู้บังคับบัญชามอบหมาย)";
|
||||||
const combianText = [dev10text, dev20text, dev70text];
|
const combianText = [dev10text, dev20text, dev70text];
|
||||||
|
|
||||||
formattedUserDevelopmentLists = userDevelopmentLists.map(
|
formattedUserDevelopmentLists = userDevelopmentLists.map(
|
||||||
(development: any, index: number) => ({
|
(development: any, index: number) => ({
|
||||||
no: Extension.ToThaiNumber((index + 1).toString()),
|
no: Extension.ToThaiNumber((index + 1).toString()),
|
||||||
|
|
@ -1671,7 +1682,7 @@ export class ReportController extends Controller {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
formattedData = {
|
formattedData = {
|
||||||
root: data && data.rootName != null ? data.rootName : "-",
|
root: data && data.rootName != null ? data.rootName : "-",
|
||||||
period: data?.durationKPI == "APR" ? "๑" : data?.durationKPI == "OCT" ? "๒" : "-",
|
period: data?.durationKPI == "APR" ? "๑ เมษายน" : data?.durationKPI == "OCT" ? "๑ ตุลาคม" : "-",
|
||||||
year: data.year ? Extension.ToThaiNumber((data.year + 543).toString()) : "-",
|
year: data.year ? Extension.ToThaiNumber((data.year + 543).toString()) : "-",
|
||||||
date: Extension.ToThaiNumber(Extension.ToThaiFullDate2(date).toString()),
|
date: Extension.ToThaiNumber(Extension.ToThaiFullDate2(date).toString()),
|
||||||
userEvaluations:
|
userEvaluations:
|
||||||
|
|
|
||||||
24
src/interfaces/date-serializer.ts
Normal file
24
src/interfaces/date-serializer.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Custom Date serializer for local timezone
|
||||||
|
export class DateSerializer {
|
||||||
|
static toLocalTime(date: Date): string | null {
|
||||||
|
if (!date) return null;
|
||||||
|
|
||||||
|
// Convert UTC date to Thailand timezone (+07:00)
|
||||||
|
const offset = 7 * 60; // Thailand is UTC+7
|
||||||
|
const localTime = new Date(date.getTime() + offset * 60 * 1000);
|
||||||
|
|
||||||
|
// Format as ISO string but replace Z with +07:00
|
||||||
|
const isoString = localTime.toISOString();
|
||||||
|
return isoString.replace("Z", "+07:00");
|
||||||
|
}
|
||||||
|
|
||||||
|
static setupDateSerialization() {
|
||||||
|
// Override Date.prototype.toJSON to use local time
|
||||||
|
Date.prototype.toJSON = function () {
|
||||||
|
const offset = 7 * 60; // Thailand timezone offset in minutes
|
||||||
|
const localTime = new Date(this.getTime() + offset * 60 * 1000);
|
||||||
|
const isoString = localTime.toISOString();
|
||||||
|
return isoString.replace("Z", "+07:00");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -184,39 +184,61 @@ class CheckAuth {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async checkOrg(token: any, keycloakId: string) {
|
public async checkOrg(token: any, keycloakId: string) {
|
||||||
const redisClient = await this.redis.createClient({
|
try {
|
||||||
host: process.env.REDIS_HOST,
|
// Validate required environment variables
|
||||||
port: process.env.REDIS_PORT,
|
const REDIS_HOST = process.env.REDIS_HOST;
|
||||||
})
|
const REDIS_PORT = process.env.REDIS_PORT ? Number(process.env.REDIS_PORT) : 6379;
|
||||||
const getAsync = promisify(redisClient.get).bind(redisClient)
|
|
||||||
try {
|
|
||||||
let reply = await getAsync("org_" + keycloakId)
|
|
||||||
if (reply != null) {
|
|
||||||
reply = JSON.parse(reply)
|
|
||||||
} else {
|
|
||||||
if (!keycloakId) throw new Error("No KeycloakId provided")
|
|
||||||
const x = await new CallAPI().GetData(
|
|
||||||
{
|
|
||||||
headers: { authorization: token },
|
|
||||||
},
|
|
||||||
`/org/permission/checkOrg/${keycloakId}`,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
const data = {
|
if (!REDIS_HOST) {
|
||||||
orgRootId: x.orgRootId,
|
throw new Error("REDIS_HOST is not set in environment variables");
|
||||||
orgChild1Id: x.orgChild1Id,
|
}
|
||||||
orgChild2Id: x.orgChild2Id,
|
|
||||||
orgChild3Id: x.orgChild3Id,
|
|
||||||
orgChild4Id: x.orgChild4Id,
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
console.log(`[REDIS] Connecting to Redis at ${REDIS_HOST}:${REDIS_PORT}`);
|
||||||
}
|
|
||||||
} catch (error) {
|
// Create Redis client
|
||||||
console.error("Error calling API:", error)
|
const redisClient = this.redis.createClient({
|
||||||
throw error
|
socket: {
|
||||||
}
|
host: REDIS_HOST,
|
||||||
|
port: REDIS_PORT,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
redisClient.on("error", (err: any) => {
|
||||||
|
console.error("[REDIS] Connection error:", err.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
await redisClient.connect();
|
||||||
|
console.log("[REDIS] Connected successfully!");
|
||||||
|
|
||||||
|
const getAsync = promisify(redisClient.get).bind(redisClient);
|
||||||
|
|
||||||
|
let reply = await getAsync("org_" + keycloakId);
|
||||||
|
if (reply != null) {
|
||||||
|
reply = JSON.parse(reply);
|
||||||
|
} else {
|
||||||
|
if (!keycloakId) throw new Error("No KeycloakId provided");
|
||||||
|
const x = await new CallAPI().GetData(
|
||||||
|
{
|
||||||
|
headers: { authorization: token },
|
||||||
|
},
|
||||||
|
`/org/permission/checkOrg/${keycloakId}`,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
orgRootId: x.orgRootId,
|
||||||
|
orgChild1Id: x.orgChild1Id,
|
||||||
|
orgChild2Id: x.orgChild2Id,
|
||||||
|
orgChild3Id: x.orgChild3Id,
|
||||||
|
orgChild4Id: x.orgChild4Id,
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error calling API:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public async PermissionCreate(req: RequestWithUser, system: string) {
|
public async PermissionCreate(req: RequestWithUser, system: string) {
|
||||||
return await this.Permission(req, system, "CREATE");
|
return await this.Permission(req, system, "CREATE");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue