Merge branch 'nice' into develop

# Conflicts:
#	src/controllers/KpiUserCapacityController.ts
#	src/controllers/KpiUserEvaluationController.ts
This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2024-08-22 14:27:49 +07:00
commit dfd9ebb3c1
21 changed files with 526 additions and 236 deletions

View file

@ -25,6 +25,8 @@ import { KpiCapacityDetail } from "../entities/kpiCapacityDetail";
import { Like, In } from "typeorm";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/capacity")
@Tags("kpiCapacity")
@Security("bearerAuth")
@ -75,11 +77,14 @@ export class kpiCapacityController extends Controller {
name: requestBody.name,
description: requestBody.description,
});
const before = null;
kpiCapacity.createdUserId = request.user.sub;
kpiCapacity.createdFullName = request.user.name;
kpiCapacity.lastUpdateUserId = request.user.sub;
kpiCapacity.lastUpdateFullName = request.user.name;
await this.kpiCapacityRepository.save(kpiCapacity);
await this.kpiCapacityRepository.save(kpiCapacity, { data: request });
setLogDataDiff(request, { before, after: kpiCapacity });
let idx: number = 0;
for (const data of requestBody.capacityDetails) {
@ -95,7 +100,8 @@ export class kpiCapacityController extends Controller {
kpiCapacityDetail.createdFullName = request.user.name;
kpiCapacityDetail.lastUpdateUserId = request.user.sub;
kpiCapacityDetail.lastUpdateFullName = request.user.name;
await this.kpiCapacityDetailRepository.save(kpiCapacityDetail);
await this.kpiCapacityDetailRepository.save(kpiCapacityDetail, { data: request });
setLogDataDiff(request, { before, after: kpiCapacityDetail });
}
return new HttpSuccess(kpiCapacity.id);
@ -146,15 +152,17 @@ export class kpiCapacityController extends Controller {
name: requestBody.name,
description: requestBody.description,
});
const before = structuredClone(kpiCapacity);
kpiCapacity.lastUpdateUserId = request.user.sub;
kpiCapacity.lastUpdateFullName = request.user.name;
this.kpiCapacityRepository.merge(kpiCapacity, _kpiCapacity);
await this.kpiCapacityRepository.save(kpiCapacity);
await this.kpiCapacityRepository.save(kpiCapacity, { data: request });
setLogDataDiff(request, { before, after: kpiCapacity });
const _kpiCapacityDetailsOld = await this.kpiCapacityDetailRepository.find({
where: { kpiCapacityId: kpiCapacity.id },
});
await this.kpiCapacityDetailRepository.remove(_kpiCapacityDetailsOld);
await this.kpiCapacityDetailRepository.remove(_kpiCapacityDetailsOld, { data: request });
let idx: number = 0;
for (const data of requestBody.capacityDetails) {
@ -166,11 +174,14 @@ export class kpiCapacityController extends Controller {
description: data.description,
kpiCapacityId: kpiCapacity.id,
});
const beforeDetail = structuredClone(kpiCapacityDetail);
kpiCapacityDetail.createdUserId = request.user.sub;
kpiCapacityDetail.createdFullName = request.user.name;
kpiCapacityDetail.lastUpdateUserId = request.user.sub;
kpiCapacityDetail.lastUpdateFullName = request.user.name;
await this.kpiCapacityDetailRepository.save(kpiCapacityDetail);
await this.kpiCapacityDetailRepository.save(kpiCapacityDetail, { data: request });
setLogDataDiff(request, { before: beforeDetail, after: kpiCapacityDetail });
}
return new HttpSuccess(kpiCapacity.id);
@ -374,9 +385,9 @@ export class kpiCapacityController extends Controller {
where: { kpiCapacityId: id },
});
if (kpiCapacityDetails.length > 0) {
await this.kpiCapacityDetailRepository.remove(kpiCapacityDetails);
await this.kpiCapacityDetailRepository.remove(kpiCapacityDetails, { data: request });
}
await this.kpiCapacityRepository.remove(kpiCapacity);
await this.kpiCapacityRepository.remove(kpiCapacity, { data: request });
return new HttpSuccess();
}
}

View file

@ -19,6 +19,8 @@ import HttpStatusCode from "../interfaces/http-status";
import { KpiEvaluation, updateKpiEvaluation } from "../entities/kpiEvaluation";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/evaluation")
@Tags("kpiEvaluation")
@Security("bearerAuth")
@ -49,11 +51,13 @@ export class kpiEvaluationController extends Controller {
if (!kpiEvaluation) {
throw new HttpError(HttpStatusCode.NOT_FOUND, `ไม่พบข้อมูลเกณฑ์การประเมินนี้: ${item.id}`);
}
const before = structuredClone(kpiEvaluation);
this.kpiEvaluationRepository.merge(kpiEvaluation, item);
kpiEvaluation.lastUpdateUserId = request.user.sub;
kpiEvaluation.lastUpdateFullName = request.user.name;
await this.kpiEvaluationRepository.save(kpiEvaluation);
await this.kpiEvaluationRepository.save(kpiEvaluation, { data: request });
setLogDataDiff(request, { before, after: kpiEvaluation });
updatedIds.push(item.id);
}

View file

@ -23,6 +23,8 @@ import HttpStatusCode from "../interfaces/http-status";
import { KpiGroup, createKpiGroup, updateKpiGroup } from "../entities/kpiGroup";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/group")
@Tags("kpiGroup")
@Security("bearerAuth")
@ -54,11 +56,15 @@ export class kpiGroupController extends Controller {
if (chkkpinameGroup) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อกลุ่มงานนี้มีอยู่ในระบบแล้ว");
}
const before = null;
kpiGroup.createdUserId = request.user.sub;
kpiGroup.createdFullName = request.user.name;
kpiGroup.lastUpdateUserId = request.user.sub;
kpiGroup.lastUpdateFullName = request.user.name;
await this.kpiGroupRepository.save(kpiGroup);
await this.kpiGroupRepository.save(kpiGroup, { data: request });
setLogDataDiff(request, { before, after: kpiGroup });
return new HttpSuccess(kpiGroup.id);
}
@ -89,10 +95,14 @@ export class kpiGroupController extends Controller {
if (chkkpinameGroup) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ชื่อกลุ่มงานนี้มีอยู่ในระบบแล้ว");
}
const before = structuredClone(kpiGroup);
this.kpiGroupRepository.merge(kpiGroup, requestBody);
kpiGroup.lastUpdateUserId = request.user.sub;
kpiGroup.lastUpdateFullName = request.user.name;
await this.kpiGroupRepository.save(kpiGroup);
await this.kpiGroupRepository.save(kpiGroup, { data: request });
setLogDataDiff(request, { before, after: kpiGroup });
return new HttpSuccess(id);
}
@ -130,7 +140,7 @@ export class kpiGroupController extends Controller {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลกลุ่มงานนี้");
}
await this.kpiGroupRepository.remove(kpiGroup);
await this.kpiGroupRepository.remove(kpiGroup, { data: request });
return new HttpSuccess();
}

View file

@ -25,6 +25,8 @@ import { KpiCapacity } from "../entities/kpiCapacity";
import { Position } from "../entities/position";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/link")
@Tags("kpiLink")
@Security("bearerAuth")
@ -56,6 +58,7 @@ export class kpiLinkController extends Controller {
if (!chkkpiGroup) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเชื่อมโยง");
}
const before = null;
const kpiLink = Object.assign(new KpiLink(), requestBody, {
createdUserId: request.user.sub,
@ -64,7 +67,8 @@ export class kpiLinkController extends Controller {
lastUpdateFullName: request.user.name,
kpiGroup: chkkpiGroup,
});
await this.kpiLinkRepository.save(kpiLink);
await this.kpiLinkRepository.save(kpiLink, { data: request });
setLogDataDiff(request, { before, after: kpiLink });
if (requestBody.positions != null) {
await Promise.all(
@ -76,7 +80,8 @@ export class kpiLinkController extends Controller {
position.createdFullName = request.user.name;
position.lastUpdateUserId = request.user.sub;
position.lastUpdateFullName = request.user.name;
await this.positionRepository.save(position);
await this.positionRepository.save(position, { data: request });
setLogDataDiff(request, { before, after: position });
}),
);
}
@ -91,7 +96,8 @@ export class kpiLinkController extends Controller {
}
kpiLink.kpiCapacitys = chkCapacity;
await this.kpiLinkRepository.save(kpiLink);
await this.kpiLinkRepository.save(kpiLink, { data: request });
setLogDataDiff(request, { before, after: kpiLink });
return new HttpSuccess(kpiLink.id);
}
@ -119,8 +125,9 @@ export class kpiLinkController extends Controller {
if (!chkKpiLink) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเชื่อมโยง");
}
const before = structuredClone(chkKpiLink);
await this.positionRepository.remove(chkKpiLink.positions);
await this.positionRepository.remove(chkKpiLink.positions, { data: request });
Object.assign(chkKpiLink, {
...requestBody,
kpiCapacitys: [],
@ -139,7 +146,8 @@ export class kpiLinkController extends Controller {
position.createdFullName = request.user.name;
position.lastUpdateUserId = request.user.sub;
position.lastUpdateFullName = request.user.name;
await this.positionRepository.save(position);
await this.positionRepository.save(position, { data: request });
setLogDataDiff(request, { before: null, after: position });
}),
);
}
@ -154,7 +162,8 @@ export class kpiLinkController extends Controller {
}
chkKpiLink.kpiCapacitys = chkCapacity;
await this.kpiLinkRepository.save(chkKpiLink);
await this.kpiLinkRepository.save(chkKpiLink, { data: request });
setLogDataDiff(request, { before, after: chkKpiLink });
return new HttpSuccess(chkKpiLink.id);
}
@ -208,8 +217,9 @@ export class kpiLinkController extends Controller {
if (!kpiLink) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการเชื่อมโยง");
}
kpiLink.kpiCapacitys = [];
await this.kpiLinkRepository.save(kpiLink);
await this.kpiLinkRepository.save(kpiLink, { data: request });
await this.positionRepository.delete({ kpiLinkId: id });
await this.kpiLinkRepository.delete({ id: id });

View file

@ -30,6 +30,7 @@ import { KpiUserCapacity } from "../entities/kpiUserCapacity";
import { KpiUserSpecial } from "../entities/kpiUserSpecial";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/period")
@Tags("kpiPeriod")
@ -70,13 +71,16 @@ export class kpiPeriodController extends Controller {
if (chkkpiPeriod) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "รอบการประเมินผลนี้มีอยู่ในระบบแล้ว");
}
const before = null;
const kpiPeriod = Object.assign(new KpiPeriod(), requestBody);
kpiPeriod.durationKPI = requestBody.durationKPI.trim().toUpperCase();
kpiPeriod.createdUserId = request.user.sub;
kpiPeriod.createdFullName = request.user.name;
kpiPeriod.lastUpdateUserId = request.user.sub;
kpiPeriod.lastUpdateFullName = request.user.name;
await this.kpiPeriodRepository.save(kpiPeriod);
await this.kpiPeriodRepository.save(kpiPeriod, { data: request });
setLogDataDiff(request, { before, after: kpiPeriod });
return new HttpSuccess(kpiPeriod.id);
}
@ -112,6 +116,7 @@ export class kpiPeriodController extends Controller {
if (chkkpiPeriod) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "รอบการประเมินผลนี้มีอยู่ในระบบแล้ว");
}
const before = structuredClone(kpiPeriod);
requestBody.durationKPI = requestBody.durationKPI.trim().toUpperCase();
this.kpiPeriodRepository.merge(kpiPeriod, requestBody);
@ -119,7 +124,9 @@ export class kpiPeriodController extends Controller {
kpiPeriod.createdFullName = request.user.name;
kpiPeriod.lastUpdateUserId = request.user.sub;
kpiPeriod.lastUpdateFullName = request.user.name;
await this.kpiPeriodRepository.save(kpiPeriod);
await this.kpiPeriodRepository.save(kpiPeriod, { data: request });
setLogDataDiff(request, { before, after: kpiPeriod });
return new HttpSuccess(id);
}
@ -133,7 +140,7 @@ export class kpiPeriodController extends Controller {
startDate: "datetime", //วันเริ่มต้น
endDate: "datetime", //วันสิ้นสุด
})
async CloseKpiPeriodById(@Path() id: string) {
async CloseKpiPeriodById(@Path() id: string, @Request() request: RequestWithUser) {
const kpiPeriod = await this.kpiPeriodRepository.findOne({
where: { id: id },
});
@ -143,8 +150,12 @@ export class kpiPeriodController extends Controller {
"ไม่พบข้อมูลรอบการประเมินผลการปฏิบัติหน้าที่ราชการนี้",
);
}
const before = structuredClone(kpiPeriod);
kpiPeriod.isActive = false;
await this.kpiPeriodRepository.save(kpiPeriod);
await this.kpiPeriodRepository.save(kpiPeriod, { data: request });
setLogDataDiff(request, { before, after: kpiPeriod });
return new HttpSuccess(kpiPeriod);
}
@ -158,7 +169,7 @@ export class kpiPeriodController extends Controller {
startDate: "datetime", //วันเริ่มต้น
endDate: "datetime", //วันสิ้นสุด
})
async OpenKpiPeriodById(@Path() id: string) {
async OpenKpiPeriodById(@Path() id: string, @Request() request: RequestWithUser) {
const kpiPeriod = await this.kpiPeriodRepository.findOne({
where: { id: id },
});
@ -168,8 +179,12 @@ export class kpiPeriodController extends Controller {
"ไม่พบข้อมูลรอบการประเมินผลการปฏิบัติหน้าที่ราชการนี้",
);
}
const before = structuredClone(kpiPeriod);
kpiPeriod.isActive = true;
await this.kpiPeriodRepository.save(kpiPeriod);
await this.kpiPeriodRepository.save(kpiPeriod, { data: request });
setLogDataDiff(request, { before, after: kpiPeriod });
return new HttpSuccess(kpiPeriod);
}
@ -303,18 +318,18 @@ export class kpiPeriodController extends Controller {
where: { kpiUserEvaluationId: In(kpiPlan.map((x) => x.id)) },
});
await this.kpiUserRoleRepository.remove(kpiUserRole);
await this.kpiUserPlannedRepository.remove(kpiUserPlanned);
await this.kpiUserRoleRepository.remove(kpiUserRole, { data: request });
await this.kpiUserPlannedRepository.remove(kpiUserPlanned, { data: request });
await this.kpiUserRoleRepository.remove(_kpiUserRole);
await this.kpiUserPlannedRepository.remove(_kpiUserPlanned);
await this.kpiUserCapacityRepository.remove(_kpiUserCapacity);
await this.kpiUserSpecialRepository.remove(_kpiUserSpecial);
await this.kpiUserRoleRepository.remove(_kpiUserRole, { data: request });
await this.kpiUserPlannedRepository.remove(_kpiUserPlanned, { data: request });
await this.kpiUserCapacityRepository.remove(_kpiUserCapacity, { data: request });
await this.kpiUserSpecialRepository.remove(_kpiUserSpecial, { data: request });
await this.kpiRoleRepository.remove(kpiRole);
await this.kpiPlanRepository.remove(kpiPlan);
await this.kpiUserEvaluationRepository.remove(kpiUserEvaluation);
await this.kpiPeriodRepository.remove(kpiPeriod);
await this.kpiRoleRepository.remove(kpiRole, { data: request });
await this.kpiPlanRepository.remove(kpiPlan, { data: request });
await this.kpiUserEvaluationRepository.remove(kpiUserEvaluation, { data: request });
await this.kpiPeriodRepository.remove(kpiPeriod, { data: request });
return new HttpSuccess();
}
}

View file

@ -26,6 +26,8 @@ import { KpiSpecial } from "../entities/kpiSpecial";
import { KpiRole } from "../entities/kpiRole";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/plan")
@Tags("kpiPlan")
@Security("bearerAuth")
@ -177,12 +179,15 @@ export class kpiPlanController extends Controller {
})
.getRawOne();
}
const before = null;
kpiPlan.including = maxIncludingPlan.maxIncluding + 1;
kpiPlan.createdUserId = request.user.sub;
kpiPlan.createdFullName = request.user.name;
kpiPlan.lastUpdateUserId = request.user.sub;
kpiPlan.lastUpdateFullName = request.user.name;
await this.kpiPlanRepository.save(kpiPlan);
await this.kpiPlanRepository.save(kpiPlan, { data: request });
setLogDataDiff(request, { before, after: kpiPlan });
const history = new KpiPlanHistory();
history.kpiPlanId = kpiPlan.id;
@ -190,7 +195,8 @@ export class kpiPlanController extends Controller {
history.createdFullName = request.user.name;
history.lastUpdateUserId = request.user.sub;
history.lastUpdateFullName = request.user.name;
await this.kpiPlanHistoryRepository.save(history);
await this.kpiPlanHistoryRepository.save(history, { data: request });
setLogDataDiff(request, { before: null, after: history });
return new HttpSuccess(kpiPlan.id);
}
@ -267,19 +273,25 @@ export class kpiPlanController extends Controller {
kpiPlan.strategyChild5Id = requestBody.strategy <= 4 ? null : x.strategyChild5Id;
})
.catch((x) => {});
const before = structuredClone(kpiPlan);
kpiPlan.createdUserId = request.user.sub;
kpiPlan.createdFullName = request.user.name;
kpiPlan.lastUpdateUserId = request.user.sub;
kpiPlan.lastUpdateFullName = request.user.name;
await this.kpiPlanRepository.save(kpiPlan);
await this.kpiPlanRepository.save(kpiPlan, { data: request });
setLogDataDiff(request, { before, after: kpiPlan });
const history = new KpiPlanHistory();
history.kpiPlanId = kpiPlan.id;
history.createdUserId = request.user.sub;
history.createdFullName = request.user.name;
history.lastUpdateUserId = request.user.sub;
history.lastUpdateFullName = request.user.name;
await this.kpiPlanHistoryRepository.save(history);
await this.kpiPlanHistoryRepository.save(history, { data: request });
setLogDataDiff(request, { before: null, after: history });
return new HttpSuccess(id);
}
@ -522,7 +534,7 @@ export class kpiPlanController extends Controller {
type = 4;
}
await this.kpiPlanHistoryRepository.delete({ kpiPlanId: id });
await this.kpiPlanRepository.remove(kpiPlan);
await this.kpiPlanRepository.remove(kpiPlan, { data: request });
if (kpiPlan) {
let remainingKpiPlans: any;
@ -579,7 +591,7 @@ export class kpiPlanController extends Controller {
remainingKpiPlans.forEach((kpiPlan: any, index: any) => {
kpiPlan.including = index + 1;
});
await this.kpiPlanRepository.save(remainingKpiPlans);
await this.kpiPlanRepository.save(remainingKpiPlans, { data: request });
}
return new HttpSuccess();

View file

@ -29,6 +29,8 @@ import { KpiUserSpecial } from "../entities/kpiUserSpecial";
import { KpiUserCapacity } from "../entities/kpiUserCapacity";
import { KpiUserDevelopment } from "../entities/kpiUserDevelopment";
import { KpiUserPlanned } from "../entities/kpiUserPlanned";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/reason")
@Tags("kpiReason")
@ -69,7 +71,7 @@ export class kpiReasonController extends Controller {
@Path() user: string,
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
if (user.trim().toUpperCase() == "USER") {
const kpiUserEvaluation = await this.kpiUserPlan.findOne({
@ -112,12 +114,16 @@ export class kpiReasonController extends Controller {
? "DONE"
: "EVALUATOR";
}
const before = structuredClone(kpiUserEvaluationReason);
kpiUserEvaluationReason.kpiUserPlannedId = id;
kpiUserEvaluationReason.createdUserId = request.user.sub;
kpiUserEvaluationReason.createdFullName = request.user.name;
kpiUserEvaluationReason.lastUpdateUserId = request.user.sub;
kpiUserEvaluationReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonPlan.save(kpiUserEvaluationReason);
await this.kpiUserEvaluationReasonPlan.save(kpiUserEvaluationReason, { data: request });
setLogDataDiff(request, { before, after: kpiUserEvaluationReason });
return new HttpSuccess(kpiUserEvaluationReason.id);
} else {
const kpiReason = await this.kpiUserEvaluationReasonPlan.findOne({
@ -149,9 +155,13 @@ export class kpiReasonController extends Controller {
kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.status = "DONE";
}
const before = structuredClone(kpiReason);
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonPlan.save(kpiReason);
await this.kpiUserEvaluationReasonPlan.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
}
@ -167,7 +177,7 @@ export class kpiReasonController extends Controller {
async sendKpiPlanReason(
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
const kpiReason = await this.kpiUserEvaluationReasonPlan.findOne({
where: { id: id },
@ -179,6 +189,7 @@ export class kpiReasonController extends Controller {
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
);
}
const before = structuredClone(kpiReason);
kpiReason.status =
kpiReason.kpiUserPlanned.kpiUserEvaluation.evaluatorId == null ||
@ -188,7 +199,9 @@ export class kpiReasonController extends Controller {
kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonPlan.save(kpiReason);
await this.kpiUserEvaluationReasonPlan.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
@ -285,7 +298,7 @@ export class kpiReasonController extends Controller {
@Path() user: string,
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
if (user.trim().toUpperCase() == "USER") {
const kpiUserEvaluation = await this.kpiUserRole.findOne({
@ -328,13 +341,16 @@ export class kpiReasonController extends Controller {
? "DONE"
: "EVALUATOR";
}
const before = structuredClone(kpiUserEvaluationReason);
kpiUserEvaluationReason.kpiUserRoleId = id;
kpiUserEvaluationReason.createdUserId = request.user.sub;
kpiUserEvaluationReason.createdFullName = request.user.name;
kpiUserEvaluationReason.lastUpdateUserId = request.user.sub;
kpiUserEvaluationReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonRole.save(kpiUserEvaluationReason);
await this.kpiUserEvaluationReasonRole.save(kpiUserEvaluationReason, { data: request });
setLogDataDiff(request, { before, after: kpiUserEvaluationReason });
return new HttpSuccess(kpiUserEvaluationReason.id);
} else {
const kpiReason = await this.kpiUserEvaluationReasonRole.findOne({
@ -366,9 +382,13 @@ export class kpiReasonController extends Controller {
kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.status = "DONE";
}
const before = structuredClone(kpiReason);
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonRole.save(kpiReason);
await this.kpiUserEvaluationReasonRole.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
}
@ -384,7 +404,7 @@ export class kpiReasonController extends Controller {
async sendKpiRoleReason(
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
const kpiReason = await this.kpiUserEvaluationReasonRole.findOne({
where: { id: id },
@ -396,6 +416,7 @@ export class kpiReasonController extends Controller {
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
);
}
const before = structuredClone(kpiReason);
kpiReason.status =
kpiReason.kpiUserRole.kpiUserEvaluation.evaluatorId == null ||
@ -405,7 +426,9 @@ export class kpiReasonController extends Controller {
kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonRole.save(kpiReason);
await this.kpiUserEvaluationReasonRole.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
@ -502,7 +525,7 @@ export class kpiReasonController extends Controller {
@Path() user: string,
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
if (user.trim().toUpperCase() == "USER") {
const kpiUserEvaluation = await this.kpiUserSpecial.findOne({
@ -548,12 +571,16 @@ export class kpiReasonController extends Controller {
? "DONE"
: "EVALUATOR";
}
const before = structuredClone(kpiUserEvaluationReason);
kpiUserEvaluationReason.kpiUserSpecialId = id;
kpiUserEvaluationReason.createdUserId = request.user.sub;
kpiUserEvaluationReason.createdFullName = request.user.name;
kpiUserEvaluationReason.lastUpdateUserId = request.user.sub;
kpiUserEvaluationReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonSpecial.save(kpiUserEvaluationReason);
await this.kpiUserEvaluationReasonSpecial.save(kpiUserEvaluationReason, { data: request });
setLogDataDiff(request, { before, after: kpiUserEvaluationReason });
return new HttpSuccess(kpiUserEvaluationReason.id);
} else {
const kpiReason = await this.kpiUserEvaluationReasonSpecial.findOne({
@ -585,9 +612,13 @@ export class kpiReasonController extends Controller {
kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.status = "DONE";
}
const before = structuredClone(kpiReason);
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonSpecial.save(kpiReason);
await this.kpiUserEvaluationReasonSpecial.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
}
@ -603,7 +634,7 @@ export class kpiReasonController extends Controller {
async sendKpiSpecialReason(
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
const kpiReason = await this.kpiUserEvaluationReasonSpecial.findOne({
where: { id: id },
@ -615,6 +646,7 @@ export class kpiReasonController extends Controller {
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
);
}
const before = structuredClone(kpiReason);
kpiReason.status =
kpiReason.kpiUserSpecial.kpiUserEvaluation.evaluatorId == null ||
@ -624,7 +656,9 @@ export class kpiReasonController extends Controller {
kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonSpecial.save(kpiReason);
await this.kpiUserEvaluationReasonSpecial.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
@ -721,7 +755,7 @@ export class kpiReasonController extends Controller {
@Path() user: string,
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
if (user.trim().toUpperCase() == "USER") {
const kpiUserEvaluation = await this.kpiUserDevelopment.findOne({
@ -763,12 +797,18 @@ export class kpiReasonController extends Controller {
}
kpiUserEvaluationReason.status = "DONE";
}
const before = structuredClone(kpiUserEvaluationReason);
kpiUserEvaluationReason.kpiUserDevelopmentId = id;
kpiUserEvaluationReason.createdUserId = request.user.sub;
kpiUserEvaluationReason.createdFullName = request.user.name;
kpiUserEvaluationReason.lastUpdateUserId = request.user.sub;
kpiUserEvaluationReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonDevelopment.save(kpiUserEvaluationReason);
await this.kpiUserEvaluationReasonDevelopment.save(kpiUserEvaluationReason, {
data: request,
});
setLogDataDiff(request, { before, after: kpiUserEvaluationReason });
return new HttpSuccess(kpiUserEvaluationReason.id);
} else {
const kpiReason = await this.kpiUserEvaluationReasonDevelopment.findOne({
@ -800,9 +840,13 @@ export class kpiReasonController extends Controller {
kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.status = "DONE";
}
const before = structuredClone(kpiReason);
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonDevelopment.save(kpiReason);
await this.kpiUserEvaluationReasonDevelopment.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
}
@ -818,7 +862,7 @@ export class kpiReasonController extends Controller {
async sendKpiDevelopmentReason(
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
const kpiReason = await this.kpiUserEvaluationReasonDevelopment.findOne({
where: { id: id },
@ -830,6 +874,7 @@ export class kpiReasonController extends Controller {
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
);
}
const before = structuredClone(kpiReason);
kpiReason.status =
kpiReason.kpiUserDevelopment.kpiUserEvaluation.evaluatorId == null ||
@ -839,7 +884,9 @@ export class kpiReasonController extends Controller {
kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonDevelopment.save(kpiReason);
await this.kpiUserEvaluationReasonDevelopment.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
@ -940,7 +987,7 @@ export class kpiReasonController extends Controller {
@Path() user: string,
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
if (user.trim().toUpperCase() == "USER") {
const kpiUserEvaluation = await this.kpiUserCapacity.findOne({
@ -982,12 +1029,16 @@ export class kpiReasonController extends Controller {
}
kpiUserEvaluationReason.status = "DONE";
}
const before = structuredClone(kpiUserEvaluationReason);
kpiUserEvaluationReason.kpiUserCapacityId = id;
kpiUserEvaluationReason.createdUserId = request.user.sub;
kpiUserEvaluationReason.createdFullName = request.user.name;
kpiUserEvaluationReason.lastUpdateUserId = request.user.sub;
kpiUserEvaluationReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonCapacity.save(kpiUserEvaluationReason);
await this.kpiUserEvaluationReasonCapacity.save(kpiUserEvaluationReason, { data: request });
setLogDataDiff(request, { before, after: kpiUserEvaluationReason });
return new HttpSuccess(kpiUserEvaluationReason.id);
} else {
const kpiReason = await this.kpiUserEvaluationReasonCapacity.findOne({
@ -1019,9 +1070,13 @@ export class kpiReasonController extends Controller {
kpiReason.reasonCommanderHigh = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.status = "DONE";
}
const before = structuredClone(kpiReason);
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonCapacity.save(kpiReason);
await this.kpiUserEvaluationReasonCapacity.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}
}
@ -1037,7 +1092,7 @@ export class kpiReasonController extends Controller {
async sendKpiCapacityReason(
@Path() id: string,
@Body() requestBody: updateKpiUserReasonEvaluation,
@Request() request: { user: Record<string, any> },
@Request() request: RequestWithUser,
) {
const kpiReason = await this.kpiUserEvaluationReasonCapacity.findOne({
where: { id: id },
@ -1049,6 +1104,7 @@ export class kpiReasonController extends Controller {
"ไม่พบข้อมูลรายการประเมินผลการปฏิบัติราชการระดับบุคคลนี้",
);
}
const before = structuredClone(kpiReason);
kpiReason.status =
kpiReason.kpiUserCapacity.kpiUserEvaluation.evaluatorId == null ||
@ -1058,7 +1114,9 @@ export class kpiReasonController extends Controller {
kpiReason.reason = requestBody.reason == null ? "" : requestBody.reason;
kpiReason.lastUpdateUserId = request.user.sub;
kpiReason.lastUpdateFullName = request.user.name;
await this.kpiUserEvaluationReasonCapacity.save(kpiReason);
await this.kpiUserEvaluationReasonCapacity.save(kpiReason, { data: request });
setLogDataDiff(request, { before, after: kpiReason });
return new HttpSuccess(kpiReason.id);
}

View file

@ -24,6 +24,9 @@ import { Brackets, IsNull, Like } from "typeorm";
import { KpiRoleHistory } from "../entities/kpiRoleHistory";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/role")
@Tags("kpiRole")
@Security("bearerAuth")
@ -170,12 +173,16 @@ export class kpiRoleController extends Controller {
})
.getRawOne();
}
const before = null;
kpiRole.including = maxIncludingRole.maxIncluding + 1;
kpiRole.createdUserId = request.user.sub;
kpiRole.createdFullName = request.user.name;
kpiRole.lastUpdateUserId = request.user.sub;
kpiRole.lastUpdateFullName = request.user.name;
await this.kpiRoleRepository.save(kpiRole);
await this.kpiRoleRepository.save(kpiRole, { data: request });
setLogDataDiff(request, { before, after: kpiRole });
const history = new KpiRoleHistory();
history.kpiRoleId = kpiRole.id;
@ -183,7 +190,8 @@ export class kpiRoleController extends Controller {
history.createdFullName = request.user.name;
history.lastUpdateUserId = request.user.sub;
history.lastUpdateFullName = request.user.name;
await this.kpiRoleHistoryRepository.save(history);
await this.kpiRoleHistoryRepository.save(history, { data: request });
setLogDataDiff(request, { before, after: kpiRole });
return new HttpSuccess(kpiRole.id);
}
@ -242,19 +250,25 @@ export class kpiRoleController extends Controller {
kpiRole.child4ShortName = requestBody.node <= 3 ? null : x.child4ShortName;
})
.catch((x) => {});
let before = null;
before = structuredClone(kpiRole);
kpiRole.createdUserId = request.user.sub;
kpiRole.createdFullName = request.user.name;
kpiRole.lastUpdateUserId = request.user.sub;
kpiRole.lastUpdateFullName = request.user.name;
await this.kpiRoleRepository.save(kpiRole);
await this.kpiRoleRepository.save(kpiRole, { data: request });
setLogDataDiff(request, { before, after: kpiRole });
before = null;
const history = new KpiRoleHistory();
history.kpiRoleId = kpiRole.id;
history.createdUserId = request.user.sub;
history.createdFullName = request.user.name;
history.lastUpdateUserId = request.user.sub;
history.lastUpdateFullName = request.user.name;
await this.kpiRoleHistoryRepository.save(history);
await this.kpiRoleHistoryRepository.save(history, { data: request });
setLogDataDiff(request, { before, after: kpiRole });
return new HttpSuccess(id);
}
@ -485,7 +499,7 @@ export class kpiRoleController extends Controller {
type = 4;
}
await this.kpiRoleHistoryRepository.delete({ kpiRoleId: id });
await this.kpiRoleRepository.remove(kpiRole);
await this.kpiRoleRepository.remove(kpiRole, { data: request });
if (kpiRole) {
let remainingKpiRoles: any;
@ -547,7 +561,7 @@ export class kpiRoleController extends Controller {
remainingKpiRoles.forEach((kpiRole: any, index: any) => {
kpiRole.including = index + 1;
});
await this.kpiRoleRepository.save(remainingKpiRoles);
await this.kpiRoleRepository.save(remainingKpiRoles, { data: request });
}
return new HttpSuccess();
}

View file

@ -21,6 +21,8 @@ import { KpiSpecial, CreateKpiSpecial, UpdateKpiSpecial } from "../entities/kpiS
import { Brackets, Not } from "typeorm";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/special")
@Tags("kpiSpecial")
@Security("bearerAuth")
@ -59,11 +61,15 @@ export class kpiSpecialController extends Controller {
if (!kpiSpecial) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
const before = null;
kpiSpecial.createdUserId = request.user.sub;
kpiSpecial.createdFullName = request.user.name;
kpiSpecial.lastUpdateUserId = request.user.sub;
kpiSpecial.lastUpdateFullName = request.user.name;
await this.kpiSpecialRepository.save(kpiSpecial);
await this.kpiSpecialRepository.save(kpiSpecial, { data: request });
setLogDataDiff(request, { before, after: kpiSpecial });
return new HttpSuccess(kpiSpecial.id);
}
@ -100,10 +106,14 @@ export class kpiSpecialController extends Controller {
"ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ",
);
}
const before = structuredClone(kpiSpecial);
kpiSpecial.lastUpdateUserId = request.user.sub;
kpiSpecial.lastUpdateFullName = request.user.name;
Object.assign(kpiSpecial, requestBody);
await this.kpiSpecialRepository.save(kpiSpecial);
await this.kpiSpecialRepository.save(kpiSpecial, { data: request });
setLogDataDiff(request, { before, after: kpiSpecial });
return new HttpSuccess(id);
}
@ -224,7 +234,7 @@ export class kpiSpecialController extends Controller {
if (!kpiSpecial) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตัวชี้วัด Specialนี้");
}
await this.kpiSpecialRepository.remove(kpiSpecial);
await this.kpiSpecialRepository.remove(kpiSpecial, { data: request });
return new HttpSuccess();
}
}

View file

@ -24,6 +24,8 @@ import { KpiUserCapacity, KpiUserCapacityDataPoint } from "../entities/kpiUserCa
import { Not } from "typeorm";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { request } from "axios";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/user/capacity")
@Tags("kpiUserCapacity")
@ -84,12 +86,16 @@ export class KpiUserCapacityController extends Controller {
"ไม่สามารถเพิ่มข้อมูลได้เนื่องจากรายการสมรรถนะซ้ำ",
);
}
const before = null;
const kpiUserCapacity = Object.assign(new KpiUserCapacity(), requestBody);
kpiUserCapacity.createdUserId = request.user.sub;
kpiUserCapacity.createdFullName = request.user.name;
kpiUserCapacity.lastUpdateUserId = request.user.sub;
kpiUserCapacity.lastUpdateFullName = request.user.name;
await this.kpiUserCapacityRepository.save(kpiUserCapacity);
await this.kpiUserCapacityRepository.save(kpiUserCapacity, { data: request });
setLogDataDiff(request, { before, after: kpiUserCapacity });
return new HttpSuccess(kpiUserCapacity.id);
}
@ -150,11 +156,14 @@ export class KpiUserCapacityController extends Controller {
"ไม่สามารถแก้ไขข้อมูลได้เนื่องจากรายการสมรรถนะซ้ำ",
);
}
const before = structuredClone(kpiUserCapacity);
const _kpiUserCapacity = Object.assign(new KpiUserCapacity(), requestBody);
kpiUserCapacity.lastUpdateUserId = request.user.sub;
kpiUserCapacity.lastUpdateFullName = request.user.name;
this.kpiUserCapacityRepository.merge(kpiUserCapacity, _kpiUserCapacity);
await this.kpiUserCapacityRepository.save(kpiUserCapacity);
await this.kpiUserCapacityRepository.save(kpiUserCapacity, { data: request });
setLogDataDiff(request, { before, after: kpiUserCapacity });
return new HttpSuccess(kpiUserCapacity.id);
}
@ -271,10 +280,13 @@ export class KpiUserCapacityController extends Controller {
`ไม่พบข้อมูลพฤติกรรมการปฎิบัติราชการ (สมรรถนะ): ${item.id}`,
);
}
const before = structuredClone(kpiUserCapacity);
this.kpiUserCapacityRepository.merge(kpiUserCapacity, item);
kpiUserCapacity.lastUpdateUserId = request.user.sub;
kpiUserCapacity.lastUpdateFullName = request.user.name;
await this.kpiUserCapacityRepository.save(kpiUserCapacity);
await this.kpiUserCapacityRepository.save(kpiUserCapacity, { data: request });
setLogDataDiff(request, { before, after: kpiUserCapacity });
}
return new HttpSuccess();
}

View file

@ -29,6 +29,7 @@ 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")
@ -89,12 +90,13 @@ export class KpiUserDevelopmentController extends Controller {
// "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ",
// );
// }
let before = 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);
await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request });
setLogDataDiff(request, { before, after: kpiUserDevelopment });
if (requestBody.developmentProjects != null) {
await Promise.all(
@ -106,7 +108,8 @@ export class KpiUserDevelopmentController extends Controller {
data.lastUpdateUserId = request.user.sub;
data.lastUpdateFullName = request.user.name;
data.kpiUserDevelopmentId = kpiUserDevelopment.id;
await this.developmentProjectRepository.save(data);
await this.developmentProjectRepository.save(data, { data: request });
setLogDataDiff(request, { before, after: data });
}),
);
}
@ -169,12 +172,17 @@ export class KpiUserDevelopmentController extends Controller {
// "ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ",
// );
// }
await this.developmentProjectRepository.remove(kpiUserDevelopment.developmentProjects);
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);
await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request });
setLogDataDiff(request, { before, after: kpiUserDevelopment });
if (requestBody.developmentProjects != null) {
await Promise.all(
requestBody.developmentProjects.map(async (x) => {
@ -185,7 +193,8 @@ export class KpiUserDevelopmentController extends Controller {
data.lastUpdateUserId = request.user.sub;
data.lastUpdateFullName = request.user.name;
data.kpiUserDevelopmentId = kpiUserDevelopment.id;
await this.developmentProjectRepository.save(data);
await this.developmentProjectRepository.save(data, { data: request });
setLogDataDiff(request, { before: null, after: data });
}),
);
}
@ -208,8 +217,10 @@ export class KpiUserDevelopmentController extends Controller {
if (!delKpiUserDevelopment) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลพัฒนาตนเองนี้");
}
await this.developmentProjectRepository.remove(delKpiUserDevelopment.developmentProjects);
await this.kpiUserDevelopmentRepository.remove(delKpiUserDevelopment);
await this.developmentProjectRepository.remove(delKpiUserDevelopment.developmentProjects, {
data: request,
});
await this.kpiUserDevelopmentRepository.remove(delKpiUserDevelopment, { data: request });
return new HttpSuccess();
}
@ -310,10 +321,12 @@ export class KpiUserDevelopmentController extends Controller {
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);
await this.kpiUserDevelopmentRepository.save(kpiUserDevelopment, { data: request });
setLogDataDiff(request, { before, after: kpiUserDevelopment });
}
return new HttpSuccess();
}

View file

@ -10,9 +10,11 @@ import {
Body,
Path,
Request,
Example,
SuccessResponse,
Response,
Query,
ArrayValidator,
} from "tsoa";
import { AppDataSource } from "../database/data-source";
import HttpSuccess from "../interfaces/http-success";
@ -29,7 +31,7 @@ import {
updateKpiUserReqEditEvaluation,
updateKpiUserResultEvaluation,
} from "../entities/kpiUserEvaluation";
import { In, Brackets, IsNull, Not } from "typeorm";
import { Like, In, Brackets, IsNull, Not } from "typeorm";
import CallAPI from "../interfaces/call-api";
import { KpiCapacity } from "../entities/kpiCapacity";
import { Position } from "../entities/position";
@ -192,123 +194,6 @@ export class KpiUserEvaluationController extends Controller {
return new HttpSuccess({ data: mapData, total });
}
/**
* API
*
* @summary
*
*/
@Post("list-announce")
async listKpiListEvaluationAnnounce(
@Request() request: RequestWithUser,
@Body()
requestBody: {
page: number;
pageSize: number;
kpiPeriodId?: string;
keyword?: string;
status?: string | null;
results?: string | null;
reqedit?: string | null;
evaluating?: boolean | null;
},
) {
await new permission().PermissionDelete(request, "SYS_RESULT");
let conditionFullName =
"CONCAT(kpiUserEvaluation.prefix, kpiUserEvaluation.firstName, ' ', kpiUserEvaluation.lastName) LIKE :keyword";
const [kpiUserEvaluation, total] = await AppDataSource.getRepository(KpiUserEvaluation)
.createQueryBuilder("kpiUserEvaluation")
.andWhere(requestBody.kpiPeriodId ? "kpiPeriodId LIKE :kpiPeriodId" : "1=1", {
kpiPeriodId: requestBody.kpiPeriodId,
})
.andWhere(
requestBody.status != null && requestBody.status != undefined
? "evaluationstatus LIKE :status"
: "1=1",
{
status:
requestBody.status == null || requestBody.status == undefined
? null
: requestBody.status.trim().toUpperCase(),
},
)
.andWhere(
requestBody.results != null && requestBody.results != undefined
? "evaluationResults LIKE :results"
: "1=1",
{
results:
requestBody.results == null || requestBody.results == undefined
? null
: requestBody.results.trim().toUpperCase(),
},
)
.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(conditionFullName, {
keyword: `%${requestBody.keyword}%`,
});
}),
)
.orderBy("kpiUserEvaluation.createdAt", "ASC")
.skip((requestBody.page - 1) * requestBody.pageSize)
.take(requestBody.pageSize)
.getManyAndCount();
const mapData = kpiUserEvaluation.map((item) => {
const fullNameParts = [item.child4, item.child3, item.child2, item.child1, item.org];
const organization = fullNameParts
.filter((part) => part !== undefined && part !== null)
.join("/");
return {
id: item.id,
profileId: item.profileId,
prefix: item.prefix,
firstname: item.firstName,
lastname: item.lastName,
kpiPeriodId: item.kpiPeriodId,
evaluationStatus: item.evaluationStatus,
evaluationResults: item.evaluationResults,
createdAt: item.createdAt,
evaluatorId: item.evaluatorId,
commanderId: item.commanderId,
commanderHighId: item.commanderHighId,
root: item.org ? item.org : null,
rootId: item.orgId ? item.orgId : null,
position: item.position ? item.position : null,
// posTypeId: item.posTypeId,
posTypeName: item.posTypeName ? item.posTypeName : null,
// posLevelId: item.posLevelId,
posLevelName: item.posLevelName ? item.posLevelName : null,
organization: organization ? organization : null,
};
});
return new HttpSuccess({ data: mapData, total });
}
/**
* API
*
@ -317,7 +202,7 @@ export class KpiUserEvaluationController extends Controller {
*/
@Post("list")
async listKpiListEvaluation(
@Request() request: RequestWithUser,
@Request() request: { user: Record<string, any> },
@Body()
requestBody: {
page: number;
@ -330,7 +215,6 @@ export class KpiUserEvaluationController extends Controller {
evaluating?: boolean | null;
},
) {
await new permission().PermissionDelete(request, "SYS_KPI_LIST");
let conditionFullName =
"CONCAT(kpiUserEvaluation.prefix, kpiUserEvaluation.firstName, ' ', kpiUserEvaluation.lastName) LIKE :keyword";
const [kpiUserEvaluation, total] = await AppDataSource.getRepository(KpiUserEvaluation)
@ -1558,8 +1442,10 @@ export class KpiUserEvaluationController extends Controller {
* @param {string} id Guid, *Id (USER)
*/
@Get("reason/{id}")
async getReasonKpiEvaluation(@Path() id: string, @Request() request: RequestWithUser) {
await new permission().PermissionGet(request, "SYS_KPI_LIST");
async getReasonKpiEvaluation(
@Path() id: string,
@Request() request: { user: Record<string, any> },
) {
const kpiUserEvaluation = await this.kpiUserEvalutionRepository.findOne({
where: { id: id },
select: [
@ -1625,7 +1511,7 @@ export class KpiUserEvaluationController extends Controller {
kpiUserEvaluation.evaluationStatus = "SUMMARY";
kpiUserEvaluation.lastUpdateUserId = request.user.sub;
kpiUserEvaluation.lastUpdateFullName = request.user.name;
await this.kpiUserEvalutionRepository.save(kpiUserEvaluation);
await this.kpiUserEvalutionRepository.save(kpiUserEvaluation, { data: request });
return new HttpSuccess(kpiUserEvaluation);
}
}

View file

@ -29,6 +29,7 @@ import { KpiUserEvaluation } from "../entities/kpiUserEvaluation";
import { KpiPlan } from "../entities/kpiPlan";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/user/achievement/planned")
@Tags("KpiUserPlanned")
@ -88,6 +89,7 @@ export class KpiUserPlannedController extends Controller {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
const before = null;
kpiUserPlanned.startDate = requestBody.startDate == undefined ? null : requestBody.startDate;
kpiUserPlanned.endDate = requestBody.endDate == undefined ? null : requestBody.endDate;
kpiUserPlanned.createdUserId = request.user.sub;
@ -102,7 +104,8 @@ export class KpiUserPlannedController extends Controller {
// kpiUserPlanned.achievement3 = request.user.achievement3;
// kpiUserPlanned.achievement4 = request.user.achievement4;
// kpiUserPlanned.achievement5 = request.user.achievement5;
await this.kpiUserPlannedRepository.save(kpiUserPlanned);
await this.kpiUserPlannedRepository.save(kpiUserPlanned, { data: request });
setLogDataDiff(request, { before, after: kpiUserPlanned });
return new HttpSuccess(kpiUserPlanned.id);
}
@ -138,7 +141,7 @@ export class KpiUserPlannedController extends Controller {
"ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ",
);
}
const before = structuredClone(kpiUserPlanned);
kpiUserPlanned.lastUpdateUserId = request.user.sub;
kpiUserPlanned.lastUpdateFullName = request.user.name;
// kpiUserPlanned.documentInfoEvidence = request.user.documentInfoEvidence;
@ -153,7 +156,8 @@ export class KpiUserPlannedController extends Controller {
Object.assign(kpiUserPlanned, requestBody);
kpiUserPlanned.startDate = requestBody.startDate == undefined ? null : requestBody.startDate;
kpiUserPlanned.endDate = requestBody.endDate == undefined ? null : requestBody.endDate;
await this.kpiUserPlannedRepository.save(kpiUserPlanned);
await this.kpiUserPlannedRepository.save(kpiUserPlanned, { data: request });
setLogDataDiff(request, { before, after: kpiUserPlanned });
return new HttpSuccess(kpiUserPlanned.id);
}
@ -171,7 +175,7 @@ export class KpiUserPlannedController extends Controller {
if (!delKpiUserPlanned) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลงานตามแผนปฏิบัติราชการประจำปีนี้");
}
await this.kpiUserPlannedRepository.remove(delKpiUserPlanned);
await this.kpiUserPlannedRepository.remove(delKpiUserPlanned, { data: request });
return new HttpSuccess();
}
@ -292,10 +296,12 @@ export class KpiUserPlannedController extends Controller {
`ไม่พบข้อมูลงานตามแผนปฏิบัติราชการประจำปีนี้: ${item.id}`,
);
}
const before = structuredClone(kpiUserPlanned);
this.kpiUserPlannedRepository.merge(kpiUserPlanned, item);
kpiUserPlanned.lastUpdateUserId = request.user.sub;
kpiUserPlanned.lastUpdateFullName = request.user.name;
await this.kpiUserPlannedRepository.save(kpiUserPlanned);
await this.kpiUserPlannedRepository.save(kpiUserPlanned, { data: request });
setLogDataDiff(request, { before, after: kpiUserPlanned });
}
return new HttpSuccess();
}

View file

@ -29,6 +29,7 @@ import { KpiUserEvaluation } from "../entities/kpiUserEvaluation";
import { KpiRole } from "../entities/kpiRole";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/user/achievement/role")
@Tags("KpiUserRole")
@ -91,13 +92,16 @@ export class KpiUserRoleController extends Controller {
);
}
const before = null;
kpiUserRole.startDate = requestBody.startDate == undefined ? null : requestBody.startDate;
kpiUserRole.endDate = requestBody.endDate == undefined ? null : requestBody.endDate;
kpiUserRole.createdUserId = request.user.sub;
kpiUserRole.createdFullName = request.user.name;
kpiUserRole.lastUpdateUserId = request.user.sub;
kpiUserRole.lastUpdateFullName = request.user.name;
await this.kpiUserRoleRepository.save(kpiUserRole);
await this.kpiUserRoleRepository.save(kpiUserRole, { data: request });
setLogDataDiff(request, { before, after: kpiUserRole });
return new HttpSuccess(kpiUserRole.id);
}
@ -149,13 +153,15 @@ export class KpiUserRoleController extends Controller {
"ไม่สามารถเพิ่มข้อมูลได้เนื่องจากข้อมูลตัวชี้วัดซ้ำ",
);
}
const before = structuredClone(kpiUserRole);
kpiUserRole.lastUpdateUserId = request.user.sub;
kpiUserRole.lastUpdateFullName = request.user.name;
Object.assign(kpiUserRole, requestBody);
kpiUserRole.startDate = requestBody.startDate == undefined ? null : requestBody.startDate;
kpiUserRole.endDate = requestBody.endDate == undefined ? null : requestBody.endDate;
await this.kpiUserRoleRepository.save(kpiUserRole);
await this.kpiUserRoleRepository.save(kpiUserRole, { data: request });
setLogDataDiff(request, { before, after: kpiUserRole });
return new HttpSuccess(kpiUserRole.id);
}
@ -173,7 +179,7 @@ export class KpiUserRoleController extends Controller {
if (!delKpiUserRole) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลงานตามหน้าที่ความรับผิดชอบหลักนี้");
}
await this.kpiUserRoleRepository.remove(delKpiUserRole);
await this.kpiUserRoleRepository.remove(delKpiUserRole, { data: request });
return new HttpSuccess();
}
@ -295,10 +301,12 @@ export class KpiUserRoleController extends Controller {
`ไม่พบข้อมูลงานตามหน้าที่ความรับผิดชอบหลักนี้: ${item.id}`,
);
}
const before = null;
this.kpiUserRoleRepository.merge(kpiUserRole, item);
kpiUserRole.lastUpdateUserId = request.user.sub;
kpiUserRole.lastUpdateFullName = request.user.name;
await this.kpiUserRoleRepository.save(kpiUserRole);
await this.kpiUserRoleRepository.save(kpiUserRole, { data: request });
setLogDataDiff(request, { before, after: kpiUserRole });
}
return new HttpSuccess();
}

View file

@ -29,6 +29,7 @@ import { KpiSpecial } from "../entities/kpiSpecial";
import { Not } from "typeorm";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { addLogSequence, setLogDataDiff } from "../interfaces/utils";
@Route("api/v1/kpi/user/achievement/special")
@Tags("KpiUserSpecial")
@ -93,6 +94,7 @@ export class KpiUserSpecialController extends Controller {
includingName: String(requestBody.includingName),
},
});
let before = null;
if (!chk_kpiSpecial) {
const kpiSpecial = Object.assign(new KpiSpecial(), requestBody);
if (!kpiSpecial) {
@ -102,7 +104,8 @@ export class KpiUserSpecialController extends Controller {
kpiSpecial.createdFullName = request.user.name;
kpiSpecial.lastUpdateUserId = request.user.sub;
kpiSpecial.lastUpdateFullName = request.user.name;
await this.kpiSpecialRepository.save(kpiSpecial);
await this.kpiSpecialRepository.save(kpiSpecial, { data: request });
setLogDataDiff(request, { before, after: kpiSpecial });
}
kpiUserSpecial.startDate = requestBody.startDate == undefined ? null : requestBody.startDate;
kpiUserSpecial.endDate = requestBody.endDate == undefined ? null : requestBody.endDate;
@ -110,7 +113,9 @@ export class KpiUserSpecialController extends Controller {
kpiUserSpecial.createdFullName = request.user.name;
kpiUserSpecial.lastUpdateUserId = request.user.sub;
kpiUserSpecial.lastUpdateFullName = request.user.name;
await this.kpiUserSpecialRepository.save(kpiUserSpecial);
await this.kpiUserSpecialRepository.save(kpiUserSpecial, { data: request });
setLogDataDiff(request, { before, after: kpiUserSpecial });
return new HttpSuccess(kpiUserSpecial.id);
}
@ -165,23 +170,29 @@ export class KpiUserSpecialController extends Controller {
includingName: String(requestBody.includingName),
},
});
let before = null;
if (!chk_kpiSpecial) {
const kpiSpecial = Object.assign(new KpiSpecial(), requestBody);
if (!kpiSpecial) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
before = structuredClone(kpiSpecial);
kpiSpecial.createdUserId = request.user.sub;
kpiSpecial.createdFullName = request.user.name;
kpiSpecial.lastUpdateUserId = request.user.sub;
kpiSpecial.lastUpdateFullName = request.user.name;
await this.kpiSpecialRepository.save(kpiSpecial);
await this.kpiSpecialRepository.save(kpiSpecial, { data: request });
setLogDataDiff(request, { before, after: kpiSpecial });
}
before = structuredClone(kpiUserSpecial);
kpiUserSpecial.lastUpdateUserId = request.user.sub;
kpiUserSpecial.lastUpdateFullName = request.user.name;
Object.assign(kpiUserSpecial, requestBody);
kpiUserSpecial.startDate = requestBody.startDate == undefined ? null : requestBody.startDate;
kpiUserSpecial.endDate = requestBody.endDate == undefined ? null : requestBody.endDate;
await this.kpiUserSpecialRepository.save(kpiUserSpecial);
await this.kpiUserSpecialRepository.save(kpiUserSpecial, { data: request });
setLogDataDiff(request, { before, after: kpiUserSpecial });
return new HttpSuccess(kpiUserSpecial.id);
}
@ -198,7 +209,7 @@ export class KpiUserSpecialController extends Controller {
if (!delKpiUserSpecial) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลงานที่ได้รับมอบหมายพิเศษนี้");
}
await this.kpiUserSpecialRepository.remove(delKpiUserSpecial);
await this.kpiUserSpecialRepository.remove(delKpiUserSpecial, { data: request });
return new HttpSuccess();
}
@ -330,10 +341,12 @@ export class KpiUserSpecialController extends Controller {
`ไม่พบข้อมูลงานที่ได้รับมอบหมายพิเศษนี้: ${item.id}`,
);
}
const before = null;
this.kpiUserSpecialRepository.merge(kpiUserSpecial, item);
kpiUserSpecial.lastUpdateUserId = request.user.sub;
kpiUserSpecial.lastUpdateFullName = request.user.name;
await this.kpiUserSpecialRepository.save(kpiUserSpecial);
await this.kpiUserSpecialRepository.save(kpiUserSpecial, { data: request });
setLogDataDiff(request, { before, after: kpiUserSpecial });
}
return new HttpSuccess();
}

View file

@ -1,6 +1,46 @@
import "dotenv/config";
import "reflect-metadata";
import { DataSource } from "typeorm";
import { DataSource, LogLevel, LogMessage } from "typeorm";
import { Logger } from "typeorm";
import { QueryRunner } from "typeorm/browser";
import { RequestWithUser } from "../middlewares/user";
import { addLogSequence } from "../interfaces/utils";
export class MyCustomLogger implements Logger {
log(level: "log" | "info" | "warn", message: any, queryRunner?: QueryRunner) {}
logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner): void {
const req = queryRunner?.data as RequestWithUser;
if (req?.app?.locals.logData?.sequence) {
addLogSequence(req, {
action: "database",
status: "success",
description: "Query Data.",
query: [
"Query: " + query + (parameters ? " - Parameters:" + JSON.stringify(parameters) : ""),
],
});
}
// const req = queryRunner?.data as RequestWithUser | undefined;
// const logData = req?.app?.locals.logData?.sequence?.at(-1);
// if (logData && !logData.query) logData.query = [];
// if (logData) logData.query.push(
// "Query: " + query + (parameters ? (" - Parameters:" + JSON.stringify(parameters)) : '')
// );
}
logMigration(message: string, queryRunner?: QueryRunner) {}
logQueryError(
error: string | Error,
query: string,
parameters?: any[],
queryRunner?: QueryRunner,
) {}
logQuerySlow(time: number, query: string, parameters?: any[], queryRunner?: QueryRunner) {}
logSchemaBuild(message: string, queryRunner?: QueryRunner) {}
}
export const AppDataSource = new DataSource({
type: "mysql",
@ -11,7 +51,7 @@ export const AppDataSource = new DataSource({
password: process.env.DB_PASSWORD,
connectorPackage: "mysql2",
synchronize: false,
logging: true,
logging: ["query", "error"],
entities:
process.env.NODE_ENV !== "production"
? ["src/entities/**/*.ts"]
@ -21,7 +61,5 @@ export const AppDataSource = new DataSource({
? ["src/migration/**/*.ts"]
: ["dist/migration/**/*{.ts,.js}"],
subscribers: [],
logger: new MyCustomLogger(),
});
// console.log(AppDataSource);
// export default database;

View file

@ -12,6 +12,7 @@ import {
Path,
} from "tsoa";
import axios from "axios";
import { addLogSequence } from "./utils";
class CallAPI {
//Get
@ -26,8 +27,28 @@ class CallAPI {
api_key: process.env.API_KEY,
},
});
addLogSequence(request, {
action: "request",
status: "success",
description: "connected",
request: {
method: "GET",
url: url,
response: JSON.stringify(response.data.result),
},
});
return response.data.result;
} catch (error) {
addLogSequence(request, {
action: "request",
status: "error",
description: "unconnected",
request: {
method: "GET",
url: url,
response: JSON.stringify(error),
},
});
throw error;
}
}
@ -43,8 +64,30 @@ class CallAPI {
api_key: process.env.API_KEY,
},
});
addLogSequence(request, {
action: "request",
status: "success",
description: "connected",
request: {
method: "POST",
url: url,
payload: JSON.stringify(sendData),
response: JSON.stringify(response.data.result),
},
});
return response.data.result;
} catch (error) {
addLogSequence(request, {
action: "request",
status: "error",
description: "unconnected",
request: {
method: "POST",
url: url,
payload: JSON.stringify(sendData),
response: JSON.stringify(error),
},
});
throw error;
}
}

37
src/interfaces/utils.ts Normal file
View file

@ -0,0 +1,37 @@
import { RequestWithUser } from "../middlewares/user";
export type DataDiff = {
before: any;
after: any;
};
export type LogSequence = {
action: string;
status: "success" | "error";
description: string;
query?: any;
request?: {
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
url?: string;
payload?: string;
response?: string;
};
};
export function setLogDataDiff(req: RequestWithUser, data: DataDiff) {
req.app.locals.logData.dataDiff = {
before: JSON.stringify(data.before),
after: JSON.stringify(data.after),
};
}
export function addLogSequence(req: RequestWithUser, data: LogSequence) {
if (!req?.app?.locals?.logData?.sequence) {
req.app.locals.logData.sequence = [];
}
req.app.locals.logData.sequence = req.app.locals.logData.sequence.concat(data);
}
export function editLogSequence(req: RequestWithUser, index: number, data: LogSequence) {
req.app.locals.logData.sequence[index] = data;
}

View file

@ -3,15 +3,13 @@ import { createDecoder, createVerifier } from "fast-jwt";
import HttpError from "../interfaces/http-error";
import HttpStatus from "../interfaces/http-status";
import { addLogSequence } from "../interfaces/utils";
import { RequestWithUser } from "./user";
if (!process.env.AUTH_PUBLIC_KEY && !process.env.AUTH_REALM_URL) {
throw new Error("Require keycloak AUTH_PUBLIC_KEY or AUTH_REALM_URL.");
}
if (
process.env.AUTH_PUBLIC_KEY &&
process.env.AUTH_REALM_URL &&
!process.env.AUTH_PREFERRED_MODE
) {
if (process.env.AUTH_PUBLIC_KEY && process.env.AUTH_REALM_URL && !process.env.AUTH_PREFERRED_MODE) {
throw new Error(
"AUTH_PREFFERRED must be specified if AUTH_PUBLIC_KEY and AUTH_REALM_URL is provided.",
);
@ -26,7 +24,7 @@ const jwtVerify = createVerifier({
const jwtDecode = createDecoder();
export async function expressAuthentication(
request: express.Request,
request: RequestWithUser,
securityName: string,
_scopes?: string[],
) {
@ -56,6 +54,18 @@ export async function expressAuthentication(
if (process.env.AUTH_PUBLIC_KEY) payload = await verifyOffline(token);
break;
}
if (!request.app.locals.logData) {
request.app.locals.logData = {};
}
// addLogSequence(request, {
// action: "database",
// status: "success",
// description: "Query Data.",
// });
request.app.locals.logData.userId = payload.sub;
request.app.locals.logData.userName = payload.name;
request.app.locals.logData.user = payload.preferred_username;
return payload;
}

View file

@ -4,6 +4,12 @@ import HttpStatus from "../interfaces/http-status";
import { ValidateError } from "tsoa";
function error(error: Error, _req: Request, res: Response, _next: NextFunction) {
const logData = _req.app.locals.logData.sequence?.at(-1);
if (logData) {
logData.status = "error";
logData.description = error.message;
}
if (error instanceof HttpError) {
return res.status(error.status).json({
status: error.status,

74
src/middlewares/logs.ts Normal file
View file

@ -0,0 +1,74 @@
import { NextFunction, Request, Response } from "express";
import { Client } from "@elastic/elasticsearch";
if (!process.env.ELASTICSEARCH_INDEX) {
throw new Error("Require ELASTICSEARCH_INDEX to store log.");
}
const ELASTICSEARCH_INDEX = process.env.ELASTICSEARCH_INDEX;
const LOG_LEVEL_MAP: Record<string, number> = {
debug: 4,
info: 3,
warning: 2,
error: 1,
none: 0,
};
const elasticsearch = new Client({
node: `${process.env.ELASTICSEARCH_PROTOCOL}://${process.env.ELASTICSEARCH_HOST}:${process.env.ELASTICSEARCH_PORT}`,
});
async function logMiddleware(req: Request, res: Response, next: NextFunction) {
if (!req.url.startsWith("/api/")) return next();
let data: any;
const originalJson = res.json;
res.json = function (v: any) {
data = v;
return originalJson.call(this, v);
};
const timestamp = new Date().toISOString();
const start = performance.now();
req.app.locals.logData = {};
res.on("finish", () => {
if (!req.url.startsWith("/api/")) return;
const level = LOG_LEVEL_MAP[process.env.LOG_LEVEL ?? "debug"] || 4;
if (level === 1 && res.statusCode < 500) return;
if (level === 2 && res.statusCode < 400) return;
if (level === 3 && res.statusCode < 200) return;
const obj = {
logType: res.statusCode >= 500 ? "error" : res.statusCode >= 400 ? "warning" : "info",
ip: req.ip,
systemName: "KPI",
startTimeStamp: timestamp,
endTimeStamp: new Date().toISOString(),
processTime: performance.now() - start,
host: req.hostname,
method: req.method,
endpoint: req.url,
responseCode: String(res.statusCode === 304 ? 200 : res.statusCode),
responseDescription: data?.message,
input: (level === 4 && JSON.stringify(req.body, null, 2)) || undefined,
output: (level === 4 && JSON.stringify(data, null, 2)) || undefined,
...req.app.locals.logData,
};
elasticsearch.index({
index: ELASTICSEARCH_INDEX,
document: obj,
});
});
return next();
}
export default logMiddleware;