From 45a393edcfd3bc01776e10a1f7d78120f67e3617 Mon Sep 17 00:00:00 2001 From: "DESKTOP-2S5P7D1\\Windows 10" Date: Tue, 12 Nov 2024 13:36:53 +0700 Subject: [PATCH 01/10] no message --- src/entities/Appoint.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/entities/Appoint.ts b/src/entities/Appoint.ts index 9295ea2..ed4a268 100644 --- a/src/entities/Appoint.ts +++ b/src/entities/Appoint.ts @@ -52,13 +52,13 @@ export class CreateAppoint { export type Person = { profileId: string - name: string - position: string - positionType: string - positionLevel: string - role: string - posNo: string - actFullName: string + name?: string + position?: string + positionType?: string + positionLevel?: string + role?: string + posNo?: string + actFullName?: string } export class UpdateAppoint { From b21e16f21518a61fb66783b516a6d0643df7dc51 Mon Sep 17 00:00:00 2001 From: "DESKTOP-2S5P7D1\\Windows 10" Date: Tue, 12 Nov 2024 13:59:05 +0700 Subject: [PATCH 02/10] =?UTF-8?q?=E0=B8=81=E0=B8=A3=E0=B8=A3=E0=B8=A1?= =?UTF-8?q?=E0=B8=81=E0=B8=B2=E0=B8=A3=20null=20=E0=B9=84=E0=B8=94?= =?UTF-8?q?=E0=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/Appoint.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/entities/Appoint.ts b/src/entities/Appoint.ts index ed4a268..491d765 100644 --- a/src/entities/Appoint.ts +++ b/src/entities/Appoint.ts @@ -52,13 +52,13 @@ export class CreateAppoint { export type Person = { profileId: string - name?: string - position?: string - positionType?: string - positionLevel?: string - role?: string - posNo?: string - actFullName?: string + name?: string | null + position?: string | null + positionType?: string | null + positionLevel?: string | null + role?: string | null + posNo?: string | null + actFullName?: string | null } export class UpdateAppoint { From ac28c1c36f16a133ab4e7ac4aa8bf44af6038057 Mon Sep 17 00:00:00 2001 From: "DESKTOP-2S5P7D1\\Windows 10" Date: Tue, 12 Nov 2024 14:09:16 +0700 Subject: [PATCH 03/10] =?UTF-8?q?null=20=E0=B8=81=E0=B8=A3=E0=B8=A3?= =?UTF-8?q?=E0=B8=A1=E0=B8=81=E0=B8=B2=E0=B8=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/AppointController.ts | 310 ++++++++++++--------------- src/entities/Appoint.ts | 4 +- 2 files changed, 143 insertions(+), 171 deletions(-) diff --git a/src/controllers/AppointController.ts b/src/controllers/AppointController.ts index 5a9d32b..932c528 100644 --- a/src/controllers/AppointController.ts +++ b/src/controllers/AppointController.ts @@ -1,204 +1,176 @@ -import { - Controller, - Route, - Security, - Tags, - Body, - Request, - SuccessResponse, - Response, - Get, - Put, - Post, - Path, - Delete, - Query, -} from "tsoa"; -import { setLogDataDiff } from "../interfaces/utils"; +import { Controller, Route, Security, Tags, Body, Request, SuccessResponse, Response, Get, Put, Post, Path, Delete, Query } from "tsoa" +import { setLogDataDiff } from "../interfaces/utils" -import { AppDataSource } from "../database/data-source"; -import HttpSuccess from "../interfaces/http-success"; -import HttpStatusCode from "../interfaces/http-status"; -import HttpError from "../interfaces/http-error"; -import permission from "../interfaces/permission"; -import { RequestWithUser } from "../middlewares/user"; -import { Appoint, CreateAppoint, Person, UpdateAppoint } from "../entities/Appoint"; -import { AppointDirector } from "../entities/AppointDirector"; +import { AppDataSource } from "../database/data-source" +import HttpSuccess from "../interfaces/http-success" +import HttpStatusCode from "../interfaces/http-status" +import HttpError from "../interfaces/http-error" +import permission from "../interfaces/permission" +import { RequestWithUser } from "../middlewares/user" +import { Appoint, CreateAppoint, Person, UpdateAppoint } from "../entities/Appoint" +import { AppointDirector } from "../entities/AppointDirector" @Route("api/v1/probation/appoint") @Tags("Appoint Director") @Security("bearerAuth") -@Response( - HttpStatusCode.INTERNAL_SERVER_ERROR, - "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", -) +@Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง") export class AppointController extends Controller { - private appointRepository = AppDataSource.getRepository(Appoint); - private appointDirectorRepository = AppDataSource.getRepository(AppointDirector); + private appointRepository = AppDataSource.getRepository(Appoint) + private appointDirectorRepository = AppDataSource.getRepository(AppointDirector) - /** - * API รายการแต่งตั้งคณะกรรมการฯ ทดลองงาน - * - * @summary รายการแต่งตั้งคณะกรรมการฯ - * - */ - @Get("") - async GetList( - @Query() keyword: string = "", - @Query("page") page: number = 1, - @Query("pageSize") pageSize: number = 10, - @Request() request: RequestWithUser, - ) { - await new permission().PermissionList(request, "SYS_PROBATION"); - const _data = await new permission().PermissionOrgList(request, "SYS_PROBATION"); + /** + * API รายการแต่งตั้งคณะกรรมการฯ ทดลองงาน + * + * @summary รายการแต่งตั้งคณะกรรมการฯ + * + */ + @Get("") + async GetList(@Query() keyword: string = "", @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, @Request() request: RequestWithUser) { + await new permission().PermissionList(request, "SYS_PROBATION") + const _data = await new permission().PermissionOrgList(request, "SYS_PROBATION") - const conditions: any = {}; + const conditions: any = {} - if (_data.root != undefined && _data.root != null && _data.root[0] != null) { - conditions.root = _data.root; - } + if (_data.root != undefined && _data.root != null && _data.root[0] != null) { + conditions.root = _data.root + } - if (_data.child1 != undefined && _data.child1 != null && _data.child1[0] != null) { - conditions.child1 = _data.child1; - } + if (_data.child1 != undefined && _data.child1 != null && _data.child1[0] != null) { + conditions.child1 = _data.child1 + } - if (_data.child2 != undefined && _data.child2 != null && _data.child2[0] != null) { - conditions.child2 = _data.child2; - } + if (_data.child2 != undefined && _data.child2 != null && _data.child2[0] != null) { + conditions.child2 = _data.child2 + } - if (_data.child3 != undefined && _data.child3 != null && _data.child3[0] != null) { - conditions.child3 = _data.child3; - } + if (_data.child3 != undefined && _data.child3 != null && _data.child3[0] != null) { + conditions.child3 = _data.child3 + } - if (_data.child4 != undefined && _data.child4 != null && _data.child4[0] != null) { - conditions.child4 = _data.child4; - } + if (_data.child4 != undefined && _data.child4 != null && _data.child4[0] != null) { + conditions.child4 = _data.child4 + } - const appoint = await this.appointRepository.find({ - relations: ["personal"], - where: { personal: conditions }, - }); + const appoint = await this.appointRepository.find({ + relations: ["personal"], + where: { personal: conditions }, + }) - return new HttpSuccess(appoint); - } + return new HttpSuccess(appoint) + } - /** - * API รายการแต่งตั้งคณะกรรมการฯ ที่ออกคำสั่งแล้วทดลองงาน - * - * @summary รายการแต่งตั้งคณะกรรมการฯ ที่ออกคำสั่งแล้ว - * - */ - @Get("list/{id}") - async GetListCommand(@Request() request: RequestWithUser, @Path() id: string) { - const appoint = await this.appointRepository.find({ - relations: ["directors"], - where: { profileId: id, status: "DONE" }, - }); + /** + * API รายการแต่งตั้งคณะกรรมการฯ ที่ออกคำสั่งแล้วทดลองงาน + * + * @summary รายการแต่งตั้งคณะกรรมการฯ ที่ออกคำสั่งแล้ว + * + */ + @Get("list/{id}") + async GetListCommand(@Request() request: RequestWithUser, @Path() id: string) { + const appoint = await this.appointRepository.find({ + relations: ["directors"], + where: { profileId: id, status: "DONE" }, + }) - return new HttpSuccess(appoint); - } + return new HttpSuccess(appoint) + } - /** - * API สร้างการแต่งตั้งคณะกรรมการฯ ทดลองงาน - * - * @summary สร้างการแต่งตั้งคณะกรรมการฯ - * - */ - @Post("") - async Create(@Request() request: RequestWithUser, @Body() requestBody: CreateAppoint) { - await new permission().PermissionCreate(request, "SYS_PROBATION"); + /** + * API สร้างการแต่งตั้งคณะกรรมการฯ ทดลองงาน + * + * @summary สร้างการแต่งตั้งคณะกรรมการฯ + * + */ + @Post("") + async Create(@Request() request: RequestWithUser, @Body() requestBody: CreateAppoint) { + await new permission().PermissionCreate(request, "SYS_PROBATION") - const data: any = { - topic: requestBody.topic, - profileId: requestBody.profileId, - createdUserId: request.user.sub, - createdFullName: request.user.name, - }; - const before = null; - const appoint = await this.appointRepository.save(data, { data: request }); - setLogDataDiff(request, { before, after: appoint }); + const data: any = { + topic: requestBody.topic, + profileId: requestBody.profileId, + createdUserId: request.user.sub, + createdFullName: request.user.name, + } + const before = null + const appoint = await this.appointRepository.save(data, { data: request }) + setLogDataDiff(request, { before, after: appoint }) - return new HttpSuccess(appoint.id); - } + return new HttpSuccess(appoint.id) + } - /** - * API ดึงข้อมูลแต่งตั้งคณะกรรมการฯ - * - * @summary API ดึงข้อมูลแต่งตั้งคณะกรรมการฯ ตาม id - * - */ - @Get("{id}") - async GetById(@Request() request: RequestWithUser, @Path() id: string) { - let _workflow = await new permission().Workflow(request, id, "SYS_PROBATION"); - if (_workflow == false) await new permission().PermissionGet(request, "SYS_PROBATION"); + /** + * API ดึงข้อมูลแต่งตั้งคณะกรรมการฯ + * + * @summary API ดึงข้อมูลแต่งตั้งคณะกรรมการฯ ตาม id + * + */ + @Get("{id}") + async GetById(@Request() request: RequestWithUser, @Path() id: string) { + let _workflow = await new permission().Workflow(request, id, "SYS_PROBATION") + if (_workflow == false) await new permission().PermissionGet(request, "SYS_PROBATION") - const appoint = await this.appointRepository.findOne({ - select: ["id", "topic", "status", "profileId"], - where: { id }, - relations: ["directors"], - }); + const appoint = await this.appointRepository.findOne({ + select: ["id", "topic", "status", "profileId"], + where: { id }, + relations: ["directors"], + }) - return new HttpSuccess(appoint); - } + return new HttpSuccess(appoint) + } - /** - * API แก้ไขการแต่งตั้งคณะกรรมการฯ ทดลองงาน - * - * @summary แก้ไขการแต่งตั้งคณะกรรมการฯ - * - */ - @Put("{id}") - async Update( - @Request() request: RequestWithUser, - @Body() requestBody: UpdateAppoint, - @Path() id: string, - ) { - await new permission().PermissionUpdate(request, "SYS_PROBATION"); + /** + * API แก้ไขการแต่งตั้งคณะกรรมการฯ ทดลองงาน + * + * @summary แก้ไขการแต่งตั้งคณะกรรมการฯ + * + */ + @Put("{id}") + async Update(@Request() request: RequestWithUser, @Body() requestBody: UpdateAppoint, @Path() id: string) { + await new permission().PermissionUpdate(request, "SYS_PROBATION") - const appoint: any = await this.appointRepository.findOne({ where: { id } }); + const appoint: any = await this.appointRepository.findOne({ where: { id } }) - if (!appoint) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการแต่งตั้งคณะกรรมการฯ"); - } + if (!appoint) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลการแต่งตั้งคณะกรรมการฯ") + } - const before = appoint; + const before = appoint - appoint.topic = requestBody.topic; - appoint.updateUserId = request.user.sub; - appoint.updateFullName = request.user.name; + appoint.topic = requestBody.topic + appoint.updateUserId = request.user.sub + appoint.updateFullName = request.user.name + await this.appointDirectorRepository.delete({ appointId: id }) + const directors: any = await requestBody.persons.map((x: Person) => ({ + ...x, + appointId: id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + })) + await this.appointDirectorRepository.save(directors) - await this.appointDirectorRepository.delete({ appointId: id }); - const directors = await requestBody.persons.map((x: Person) => ({ - ...x, - appointId: id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })); - await this.appointDirectorRepository.save(directors); + await this.appointRepository.save(appoint, { data: request }) + setLogDataDiff(request, { before, after: appoint }) - await this.appointRepository.save(appoint, { data: request }); - setLogDataDiff(request, { before, after: appoint }); + return new HttpSuccess() + } - return new HttpSuccess(); - } + /** + * API ลบรายการแต่งตั้งคณะกรรมการฯ + * + * @summary ลบรายการแต่งตั้งคณะกรรมการฯ + * + */ + @Delete("{id}") + public async deleteRole(@Path() id: string, @Request() request: RequestWithUser) { + await new permission().PermissionDelete(request, "SYS_PROBATION") - /** - * API ลบรายการแต่งตั้งคณะกรรมการฯ - * - * @summary ลบรายการแต่งตั้งคณะกรรมการฯ - * - */ - @Delete("{id}") - public async deleteRole(@Path() id: string, @Request() request: RequestWithUser) { - await new permission().PermissionDelete(request, "SYS_PROBATION"); + await this.appointDirectorRepository.delete({ appointId: id }) - await this.appointDirectorRepository.delete({ appointId: id }); + const result = await this.appointRepository.delete({ id }) + if (!result) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล") - const result = await this.appointRepository.delete({ id }); - if (!result) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); - - return new HttpSuccess(); - } + return new HttpSuccess() + } } diff --git a/src/entities/Appoint.ts b/src/entities/Appoint.ts index 491d765..cbe21b5 100644 --- a/src/entities/Appoint.ts +++ b/src/entities/Appoint.ts @@ -52,11 +52,11 @@ export class CreateAppoint { export type Person = { profileId: string - name?: string | null + name: string | null position?: string | null positionType?: string | null positionLevel?: string | null - role?: string | null + role: string | null posNo?: string | null actFullName?: string | null } From 465ff35a4c30cb5a6ebf1238a47c1df3426588d3 Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Wed, 20 Nov 2024 11:00:05 +0700 Subject: [PATCH 04/10] add get assign list for user (use kpi) --- src/controllers/AssignController.ts | 1288 +++++++++++++++------------ 1 file changed, 705 insertions(+), 583 deletions(-) diff --git a/src/controllers/AssignController.ts b/src/controllers/AssignController.ts index 5213d2f..ab1c222 100644 --- a/src/controllers/AssignController.ts +++ b/src/controllers/AssignController.ts @@ -1,651 +1,773 @@ -import { Controller, Post, Put, Route, Security, Tags, Body, Request, SuccessResponse, Response, Get, Query } from "tsoa" -import { AppDataSource } from "../database/data-source" -import HttpSuccess from "../interfaces/http-success" -import HttpStatusCode from "../interfaces/http-status" -import HttpError from "../interfaces/http-error" -import { RequestWithUser } from "../middlewares/user" -import { findEndDate, setLogDataDiff } from "../interfaces/utils" -import { Personal } from "../entities/Personal" -import permission from "../interfaces/permission" -import { Assign, CreateAssign } from "../entities/Assign" -import { AssignDirector, CreateAssignDirector } from "../entities/AssignDirector" -import { AssignJob, CreateAssignJob } from "../entities/AssignJob" -import { AssignKnowledge, CreateAssignKnowledge } from "../entities/AssignKnowledge" -import { AssignLaw, CreateAssignLaw } from "../entities/AssignLaw" -import { AssignSkill, CreateAssignSkill } from "../entities/AssignSkill" -import { AssignCompetency, CreateAssignCompetency } from "../entities/AssignCompetency" -import { AssignCompetencyGroup, CreateAssignCompetencyGroup } from "../entities/AssignCompetencyGroup" -import { AssignOutput, CreateAssignOutput } from "../entities/AssignOutput" -import { Law } from "../entities/Law" -import CallAPI from "../interfaces/call-api" +import { + Controller, + Post, + Put, + Route, + Security, + Tags, + Body, + Request, + SuccessResponse, + Response, + Get, + Query, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatusCode from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { RequestWithUser } from "../middlewares/user"; +import { findEndDate, setLogDataDiff } from "../interfaces/utils"; +import { Personal } from "../entities/Personal"; +import permission from "../interfaces/permission"; +import { Assign, CreateAssign } from "../entities/Assign"; +import { AssignDirector, CreateAssignDirector } from "../entities/AssignDirector"; +import { AssignJob, CreateAssignJob } from "../entities/AssignJob"; +import { AssignKnowledge, CreateAssignKnowledge } from "../entities/AssignKnowledge"; +import { AssignLaw, CreateAssignLaw } from "../entities/AssignLaw"; +import { AssignSkill, CreateAssignSkill } from "../entities/AssignSkill"; +import { AssignCompetency, CreateAssignCompetency } from "../entities/AssignCompetency"; +import { + AssignCompetencyGroup, + CreateAssignCompetencyGroup, +} from "../entities/AssignCompetencyGroup"; +import { AssignOutput, CreateAssignOutput } from "../entities/AssignOutput"; +import { Law } from "../entities/Law"; +import CallAPI from "../interfaces/call-api"; @Route("api/v1/probation/assign") @Tags("ฟอร์มมอบหมายงาน") @Security("bearerAuth") -@Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง") +@Response( + HttpStatusCode.INTERNAL_SERVER_ERROR, + "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", +) export class AssignController extends Controller { - private assignRepository = AppDataSource.getRepository(Assign) - private personalRepository = AppDataSource.getRepository(Personal) - private assignDirectorRepository = AppDataSource.getRepository(AssignDirector) - private assignJobRepository = AppDataSource.getRepository(AssignJob) - private assignKnowledgeRepository = AppDataSource.getRepository(AssignKnowledge) - private assignLawRepository = AppDataSource.getRepository(AssignLaw) - private assignSkillRepository = AppDataSource.getRepository(AssignSkill) - private assignCompetencyRepository = AppDataSource.getRepository(AssignCompetency) - private assignCompetencyGroupRepository = AppDataSource.getRepository(AssignCompetencyGroup) - private assignOutputRepository = AppDataSource.getRepository(AssignOutput) - private lawsRepository = AppDataSource.getRepository(Law) + private assignRepository = AppDataSource.getRepository(Assign); + private personalRepository = AppDataSource.getRepository(Personal); + private assignDirectorRepository = AppDataSource.getRepository(AssignDirector); + private assignJobRepository = AppDataSource.getRepository(AssignJob); + private assignKnowledgeRepository = AppDataSource.getRepository(AssignKnowledge); + private assignLawRepository = AppDataSource.getRepository(AssignLaw); + private assignSkillRepository = AppDataSource.getRepository(AssignSkill); + private assignCompetencyRepository = AppDataSource.getRepository(AssignCompetency); + private assignCompetencyGroupRepository = AppDataSource.getRepository(AssignCompetencyGroup); + private assignOutputRepository = AppDataSource.getRepository(AssignOutput); + private lawsRepository = AppDataSource.getRepository(Law); - /** - * API เพิ่มข้อมูลการมอบหมายงาน - * - * @summary เพิ่มข้อมูลการมอบหมายงาน - * - */ - @Post("") - async AddAssign(@Request() request: RequestWithUser, @Body() requestBody: CreateAssign) { - await new permission().PermissionUpdate(request, "SYS_PROBATION") - const person = await this.personalRepository.findOne({ - where: { - personal_id: requestBody.personalId, - }, - }) + /** + * API เพิ่มข้อมูลการมอบหมายงาน + * + * @summary เพิ่มข้อมูลการมอบหมายงาน + * + */ + @Post("") + async AddAssign(@Request() request: RequestWithUser, @Body() requestBody: CreateAssign) { + await new permission().PermissionUpdate(request, "SYS_PROBATION"); + const person = await this.personalRepository.findOne({ + where: { + personal_id: requestBody.personalId, + }, + }); - if (!person) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล") - } + if (!person) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล"); + } - const roundNo = await this.assignRepository.count({ - where: { - active: 1, - personal_id: requestBody.personalId, - }, - }) + const roundNo = await this.assignRepository.count({ + where: { + active: 1, + personal_id: requestBody.personalId, + }, + }); - const data: any = { - ...requestBody, - round_no: roundNo + 1, - personal_id: requestBody.personalId, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - } - const before = null - const assign = await this.assignRepository.save(data, { data: request }) - setLogDataDiff(request, { before, after: data }) + const data: any = { + ...requestBody, + round_no: roundNo + 1, + personal_id: requestBody.personalId, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }; + const before = null; + const assign = await this.assignRepository.save(data, { data: request }); + setLogDataDiff(request, { before, after: data }); - const jobs = await requestBody.assign_jobs.map((x: CreateAssignJob, index: number) => ({ - ...x, - id: index + 1, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignJobRepository.save(jobs, { data: request }) - setLogDataDiff(request, { before, after: jobs }) + const jobs = await requestBody.assign_jobs.map((x: CreateAssignJob, index: number) => ({ + ...x, + id: index + 1, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + })); + await this.assignJobRepository.save(jobs, { data: request }); + setLogDataDiff(request, { before, after: jobs }); - const knowledges = await requestBody.assign_knowledges.map((x: CreateAssignKnowledge, index: number) => ({ - knowledge_level: x.level, - knowledge_id: x.id, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignKnowledgeRepository.save(knowledges, { data: request }) - setLogDataDiff(request, { before, after: knowledges }) + const knowledges = await requestBody.assign_knowledges.map( + (x: CreateAssignKnowledge, index: number) => ({ + knowledge_level: x.level, + knowledge_id: x.id, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignKnowledgeRepository.save(knowledges, { data: request }); + setLogDataDiff(request, { before, after: knowledges }); - const laws = await requestBody.assign_law.map((x: CreateAssignLaw, index: number) => ({ - ordering: index + 1, - law_id: x.id, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignLawRepository.save(laws, { data: request }) - setLogDataDiff(request, { before, after: laws }) + const laws = await requestBody.assign_law.map((x: CreateAssignLaw, index: number) => ({ + ordering: index + 1, + law_id: x.id, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + })); + await this.assignLawRepository.save(laws, { data: request }); + setLogDataDiff(request, { before, after: laws }); - const skills = await requestBody.assign_skill.map((x: CreateAssignSkill, index: number) => ({ - skill_id: index + 1, - skill_level: x.level, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignSkillRepository.save(skills, { data: request }) - setLogDataDiff(request, { before, after: skills }) + const skills = await requestBody.assign_skill.map((x: CreateAssignSkill, index: number) => ({ + skill_id: index + 1, + skill_level: x.level, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + })); + await this.assignSkillRepository.save(skills, { data: request }); + setLogDataDiff(request, { before, after: skills }); - const competencise = await requestBody.assign_competency.map((x: CreateAssignCompetency, index: number) => ({ - competency_id: x.id, - competency_level: x.level, - competency_name: x.name, - competency_description: x.description, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignCompetencyRepository.save(competencise, { data: request }) - setLogDataDiff(request, { before, after: competencise }) + const competencise = await requestBody.assign_competency.map( + (x: CreateAssignCompetency, index: number) => ({ + competency_id: x.id, + competency_level: x.level, + competency_name: x.name, + competency_description: x.description, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignCompetencyRepository.save(competencise, { data: request }); + setLogDataDiff(request, { before, after: competencise }); - const competencyGroups = await requestBody.assign_competency_group.map((x: CreateAssignCompetencyGroup, index: number) => ({ - competency_group_id: x.id, - competency_group_level: x.level, - competency_group_name: x.name, - competency_group_description: x.description, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignCompetencyGroupRepository.save(competencyGroups, { - data: request, - }) - setLogDataDiff(request, { before, after: competencyGroups }) + const competencyGroups = await requestBody.assign_competency_group.map( + (x: CreateAssignCompetencyGroup, index: number) => ({ + competency_group_id: x.id, + competency_group_level: x.level, + competency_group_name: x.name, + competency_group_description: x.description, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignCompetencyGroupRepository.save(competencyGroups, { + data: request, + }); + setLogDataDiff(request, { before, after: competencyGroups }); - const outputs = await requestBody.assign_outputs.map((x: CreateAssignOutput, index: number) => ({ - ...x, - id: index + 1, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignOutputRepository.save(outputs, { data: request }) - setLogDataDiff(request, { before, after: outputs }) + const outputs = await requestBody.assign_outputs.map( + (x: CreateAssignOutput, index: number) => ({ + ...x, + id: index + 1, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignOutputRepository.save(outputs, { data: request }); + setLogDataDiff(request, { before, after: outputs }); - const directors = await requestBody.assign_director.map((x: CreateAssignDirector, index: number) => ({ - ...x, - assign_id: assign.id, - fullname: x.name, - ordering: index + 1, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignDirectorRepository.save(directors, { data: request }) - setLogDataDiff(request, { before, after: directors }) + const directors = await requestBody.assign_director.map( + (x: CreateAssignDirector, index: number) => ({ + ...x, + assign_id: assign.id, + fullname: x.name, + ordering: index + 1, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignDirectorRepository.save(directors, { data: request }); + setLogDataDiff(request, { before, after: directors }); - return new HttpSuccess() - } + return new HttpSuccess(); + } - /** - * API แก้ไขข้อมูลการมอบหมายงาน - * - * @summary แก้ไขแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ - * - */ - @Put("") - async EditAssign(@Query() assign_id: string, @Request() request: RequestWithUser, @Body() requestBody: CreateAssign) { - await new permission().PermissionUpdate(request, "SYS_PROBATION") + /** + * API แก้ไขข้อมูลการมอบหมายงาน + * + * @summary แก้ไขแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ + * + */ + @Put("") + async EditAssign( + @Query() assign_id: string, + @Request() request: RequestWithUser, + @Body() requestBody: CreateAssign, + ) { + await new permission().PermissionUpdate(request, "SYS_PROBATION"); - const assign = await this.assignRepository.findOne({ - where: { id: assign_id }, - }) - let before = assign + const assign = await this.assignRepository.findOne({ + where: { id: assign_id }, + }); + let before = assign; - if (!assign) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบมอบหมายงาน") - } + if (!assign) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบมอบหมายงาน"); + } - const person = await this.personalRepository.findOne({ - where: { - personal_id: requestBody.personalId, - }, - }) + const person = await this.personalRepository.findOne({ + where: { + personal_id: requestBody.personalId, + }, + }); - if (!person) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล") - } + if (!person) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล"); + } - const data: any = { - ...requestBody, - id: assign_id, - updateUserId: request.user.sub, - updateFullName: request.user.name, - } + const data: any = { + ...requestBody, + id: assign_id, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }; - await this.assignJobRepository.delete({ assign_id }) - const jobs = await requestBody.assign_jobs.map((x: CreateAssignJob, index: number) => ({ - ...x, - id: index + 1, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignJobRepository.save(jobs) + await this.assignJobRepository.delete({ assign_id }); + const jobs = await requestBody.assign_jobs.map((x: CreateAssignJob, index: number) => ({ + ...x, + id: index + 1, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + })); + await this.assignJobRepository.save(jobs); - await this.assignKnowledgeRepository.delete({ assign_id }) - const knowledges = await requestBody.assign_knowledges.map((x: CreateAssignKnowledge, index: number) => ({ - knowledge_level: x.level, - knowledge_id: x.id, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignKnowledgeRepository.save(knowledges) + await this.assignKnowledgeRepository.delete({ assign_id }); + const knowledges = await requestBody.assign_knowledges.map( + (x: CreateAssignKnowledge, index: number) => ({ + knowledge_level: x.level, + knowledge_id: x.id, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignKnowledgeRepository.save(knowledges); - await this.assignLawRepository.delete({ assign_id }) - const laws = await requestBody.assign_law.map((x: CreateAssignLaw, index: number) => ({ - ordering: index + 1, - law_id: x.id, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignLawRepository.save(laws) + await this.assignLawRepository.delete({ assign_id }); + const laws = await requestBody.assign_law.map((x: CreateAssignLaw, index: number) => ({ + ordering: index + 1, + law_id: x.id, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + })); + await this.assignLawRepository.save(laws); - await this.assignSkillRepository.delete({ assign_id }) - const skills = await requestBody.assign_skill.map((x: CreateAssignSkill, index: number) => ({ - skill_id: index + 1, - skill_level: x.level, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignSkillRepository.save(skills) + await this.assignSkillRepository.delete({ assign_id }); + const skills = await requestBody.assign_skill.map((x: CreateAssignSkill, index: number) => ({ + skill_id: index + 1, + skill_level: x.level, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + })); + await this.assignSkillRepository.save(skills); - await this.assignCompetencyRepository.delete({ assign_id }) - const competencise = await requestBody.assign_competency.map((x: CreateAssignCompetency, index: number) => ({ - competency_id: x.id, - competency_level: x.level, - competency_name: x.name, - competency_description: x.description, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignCompetencyRepository.save(competencise) + await this.assignCompetencyRepository.delete({ assign_id }); + const competencise = await requestBody.assign_competency.map( + (x: CreateAssignCompetency, index: number) => ({ + competency_id: x.id, + competency_level: x.level, + competency_name: x.name, + competency_description: x.description, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignCompetencyRepository.save(competencise); - await this.assignCompetencyGroupRepository.delete({ assign_id }) - const competencyGroups = await requestBody.assign_competency_group.map((x: CreateAssignCompetencyGroup, index: number) => ({ - competency_group_id: x.id, - competency_group_level: x.level, - competency_group_name: x.name, - competency_group_description: x.description, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignCompetencyGroupRepository.save(competencyGroups) + await this.assignCompetencyGroupRepository.delete({ assign_id }); + const competencyGroups = await requestBody.assign_competency_group.map( + (x: CreateAssignCompetencyGroup, index: number) => ({ + competency_group_id: x.id, + competency_group_level: x.level, + competency_group_name: x.name, + competency_group_description: x.description, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignCompetencyGroupRepository.save(competencyGroups); - await this.assignOutputRepository.delete({ assign_id }) - const outputs = await requestBody.assign_outputs.map((x: CreateAssignOutput, index: number) => ({ - ...x, - id: index + 1, - assign_id: assign.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignOutputRepository.save(outputs) + await this.assignOutputRepository.delete({ assign_id }); + const outputs = await requestBody.assign_outputs.map( + (x: CreateAssignOutput, index: number) => ({ + ...x, + id: index + 1, + assign_id: assign.id, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignOutputRepository.save(outputs); - await this.assignDirectorRepository.delete({ assign_id }) - const directors = await requestBody.assign_director.map((x: CreateAssignDirector, index: number) => ({ - ...x, - assign_id: assign.id, - fullname: x.name, - ordering: index + 1, - createdUserId: request.user.sub, - createdFullName: request.user.name, - updateUserId: request.user.sub, - updateFullName: request.user.name, - })) - await this.assignDirectorRepository.save(directors) + await this.assignDirectorRepository.delete({ assign_id }); + const directors = await requestBody.assign_director.map( + (x: CreateAssignDirector, index: number) => ({ + ...x, + assign_id: assign.id, + fullname: x.name, + ordering: index + 1, + createdUserId: request.user.sub, + createdFullName: request.user.name, + updateUserId: request.user.sub, + updateFullName: request.user.name, + }), + ); + await this.assignDirectorRepository.save(directors); - await this.assignRepository.save(data, { data: request }) - setLogDataDiff(request, { before, after: data }) + await this.assignRepository.save(data, { data: request }); + setLogDataDiff(request, { before, after: data }); - // #noted cronjob - // แจ้งผู้ดูแลและผู้บังคับบัญชาเข้ามาบันทึกผลทุก 2 เดือน - const dateSaveForm = await findEndDate(2, requestBody.date_start) - requestBody.assign_director - .filter(x => x.role == "mentor" || x.role == "commander") - .map(async director => { - await new CallAPI() - .PostData(request, "/placement/noti", { - subject: `ถึงกำหนดบันทึกผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, - body: `ถึงกำหนดบันทึกผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, - receiverUserId: director.personal_id, - payload: "", - isSendMail: true, - isSendInbox: true, - receiveDate: dateSaveForm, - }) - .catch(error => { - console.error("Error calling API:", error) - }) - }) + // #noted cronjob + // แจ้งผู้ดูแลและผู้บังคับบัญชาเข้ามาบันทึกผลทุก 2 เดือน + const dateSaveForm = await findEndDate(2, requestBody.date_start); + requestBody.assign_director + .filter((x) => x.role == "mentor" || x.role == "commander") + .map(async (director) => { + await new CallAPI() + .PostData(request, "/placement/noti", { + subject: `ถึงกำหนดบันทึกผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, + body: `ถึงกำหนดบันทึกผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, + receiverUserId: director.personal_id, + payload: "", + isSendMail: true, + isSendInbox: true, + receiveDate: dateSaveForm, + }) + .catch((error) => { + console.error("Error calling API:", error); + }); + }); - // แจ้งผู้บังคับบัญชา และคณะกรรมการเข้ามาประเมินทุก 3 เดือน - const dateEvaluate = await findEndDate(3, requestBody.date_start) - requestBody.assign_director - .filter(x => x.role == "commander" || x.role == "chairman") - .map(async director => { - await new CallAPI() - .PostData(request, "/placement/noti", { - subject: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, - body: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, - receiverUserId: director.personal_id, - payload: "", - isSendMail: true, - isSendInbox: true, - receiveDate: dateEvaluate, - }) - .catch(error => { - console.error("Error calling API:", error) - }) - }) + // แจ้งผู้บังคับบัญชา และคณะกรรมการเข้ามาประเมินทุก 3 เดือน + const dateEvaluate = await findEndDate(3, requestBody.date_start); + requestBody.assign_director + .filter((x) => x.role == "commander" || x.role == "chairman") + .map(async (director) => { + await new CallAPI() + .PostData(request, "/placement/noti", { + subject: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, + body: `ถึงกำหนดประเมินผลการทดลองปฏิบัติหน้าที่ราชการครั้งที่ 1 ${requestBody.fullname}`, + receiverUserId: director.personal_id, + payload: "", + isSendMail: true, + isSendInbox: true, + receiveDate: dateEvaluate, + }) + .catch((error) => { + console.error("Error calling API:", error); + }); + }); - // แจ้งประธาน 6 เดือน - const dateResult = await findEndDate(6, requestBody.date_start) - requestBody.assign_director - .filter(x => x.role == "chairman") - .map(async director => { - await new CallAPI() - .PostData(request, "/placement/noti", { - subject: `ถึงกำหนดรายงานการประเมินผลการทดลองปฏิบัติหน้าที่ราชการ ${requestBody.fullname}`, - body: `ถึงกำหนดรายงานการประเมินผลการทดลองปฏิบัติหน้าที่ราชการ ${requestBody.fullname}`, - receiverUserId: director.personal_id, - payload: "", - isSendMail: true, - isSendInbox: true, - // isSendNotification: true - receiveDate: dateResult, - }) - .catch(error => { - console.error("Error calling API:", error) - }) - }) + // แจ้งประธาน 6 เดือน + const dateResult = await findEndDate(6, requestBody.date_start); + requestBody.assign_director + .filter((x) => x.role == "chairman") + .map(async (director) => { + await new CallAPI() + .PostData(request, "/placement/noti", { + subject: `ถึงกำหนดรายงานการประเมินผลการทดลองปฏิบัติหน้าที่ราชการ ${requestBody.fullname}`, + body: `ถึงกำหนดรายงานการประเมินผลการทดลองปฏิบัติหน้าที่ราชการ ${requestBody.fullname}`, + receiverUserId: director.personal_id, + payload: "", + isSendMail: true, + isSendInbox: true, + // isSendNotification: true + receiveDate: dateResult, + }) + .catch((error) => { + console.error("Error calling API:", error); + }); + }); - return new HttpSuccess() - } + return new HttpSuccess(); + } - /** - * API รายการข้อมูลการมอบหมายงาน - * - * @summary รายการการมอบหมายงาน - * - */ - @Get("assign-list") - async ListPersonal(@Request() request: RequestWithUser, @Query() personal_id: string) { - let _workflow = await new permission().Workflow(request, personal_id, "SYS_PROBATION") - if (_workflow == false) await new permission().PermissionGet(request, "SYS_PROBATION") - const lists = await this.assignRepository.find({ - select: ["id", "round_no", "date_start", "date_finish"], - where: { personal_id }, - order: { round_no: "ASC" }, - }) + /** + * API รายการข้อมูลการมอบหมายงาน + * + * @summary รายการการมอบหมายงาน + * + */ + @Get("assign-list") + async ListPersonal(@Request() request: RequestWithUser, @Query() personal_id: string) { + let _workflow = await new permission().Workflow(request, personal_id, "SYS_PROBATION"); + if (_workflow == false) await new permission().PermissionGet(request, "SYS_PROBATION"); + const lists = await this.assignRepository.find({ + select: ["id", "round_no", "date_start", "date_finish"], + where: { personal_id }, + order: { round_no: "ASC" }, + }); - let result: any = [] + let result: any = []; - await Promise.all( - lists.map(async item => { - const director = await this.assignDirectorRepository.find({ - where: { assign_id: item.id }, - order: { ordering: "ASC" }, - }) + await Promise.all( + lists.map(async (item) => { + const director = await this.assignDirectorRepository.find({ + where: { assign_id: item.id }, + order: { ordering: "ASC" }, + }); - let mentors = "" - const mentorList = await director.filter(x => x.role == "mentor") - if (mentorList.length > 0) { - for (let index = 0; index < mentorList.length; index++) { - const e = await mentorList[index] - mentors += e.fullname - if (index < mentorList.length - 1) { - mentors += ", " - } - } - } + let mentors = ""; + const mentorList = await director.filter((x) => x.role == "mentor"); + if (mentorList.length > 0) { + for (let index = 0; index < mentorList.length; index++) { + const e = await mentorList[index]; + mentors += e.fullname; + if (index < mentorList.length - 1) { + mentors += ", "; + } + } + } - const commanderData = await (director.find(x => x.role == "commander") ?? null) - const commander = commanderData ? commanderData.fullname : null + const commanderData = await (director.find((x) => x.role == "commander") ?? null); + const commander = commanderData ? commanderData.fullname : null; - const chairmanData = await (director.find(x => x.role == "chairman") ?? null) - const chairman = chairmanData ? chairmanData.fullname : null + const chairmanData = await (director.find((x) => x.role == "chairman") ?? null); + const chairman = chairmanData ? chairmanData.fullname : null; - await result.push({ - ...item, - mentors: mentors, - commander: commander, - chairman: chairman, - }) - }) - ) + await result.push({ + ...item, + mentors: mentors, + commander: commander, + chairman: chairman, + }); + }), + ); - return new HttpSuccess(result) - } + return new HttpSuccess(result); + } - /** - * API ดึงข้อมูลแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ - * - * @summary ดึงข้อมูลแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ - * - */ - @Get("") - async GetAssign(@Query() assign_id: string, @Request() request: RequestWithUser) { - let _workflow = await new permission().Workflow(request, assign_id, "SYS_PROBATION") - if (_workflow == false) await new permission().PermissionGet(request, "SYS_PROBATION") + /** + * API รายการข้อมูลการทดลองงานของผู้ใช้งาน ใช้เพื่อดูข้อมูลตอนทำ KPI + * + * @summary รายการข้อมูลการทดลองงานของผู้ใช้งาน + * + */ + @Get("assign-user-list") + async ListPersonalUser(@Request() request: RequestWithUser, @Query() personal_id: string) { + const lists = await this.assignRepository.find({ + select: ["id", "round_no", "date_start", "date_finish"], + where: { personal_id }, + order: { round_no: "ASC" }, + }); - const assign = await this.assignRepository.findOne({ - select: [ - "id", - "personal_id", - "appointId", - "round_no", - "date_start", - "date_finish", - "other_desc", - "other4_desc", - "other5_no1_desc", - "experimenter_dated", - "active", - "createdAt", - "updatedAt", - "reportPersonId" - ], - where: { id: assign_id }, - }) + let result: any = []; - if (!assign) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบมอบหมายงาน") - } + await Promise.all( + lists.map(async (item) => { + const director = await this.assignDirectorRepository.find({ + where: { assign_id: item.id }, + order: { ordering: "ASC" }, + }); - const profileData = await this.personalRepository.findOne({ - select: ["personal_id", "prefixName", "firstName", "lastName", "positionName", "positionLevelName", "positionLineName", "orgRootName", "organization"], - where: { - personal_id: assign.personal_id, - }, - }) + let mentors = ""; + const mentorList = await director.filter((x) => x.role == "mentor"); + if (mentorList.length > 0) { + for (let index = 0; index < mentorList.length; index++) { + const e = await mentorList[index]; + mentors += e.fullname; + if (index < mentorList.length - 1) { + mentors += ", "; + } + } + } - if (!profileData) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล") - } + const commanderData = await (director.find((x) => x.role == "commander") ?? null); + const commander = commanderData ? commanderData.fullname : null; - const profile = { - ...profileData, - name: `${profileData.prefixName}${profileData.firstName} ${profileData.lastName}`, - Position: profileData.positionName, - Department: "-", - OrganizationOrganization: profileData.orgRootName, - Oc: profileData.organization, - } + const chairmanData = await (director.find((x) => x.role == "chairman") ?? null); + const chairman = chairmanData ? chairmanData.fullname : null; - const jobs = await this.assignJobRepository.find({ - select: ["id", "activity_desc", "goal_desc"], - where: { assign_id }, - }) + await result.push({ + ...item, + mentors: mentors, + commander: commander, + chairman: chairman, + }); + }), + ); - const knowledgeData = await this.assignKnowledgeRepository.find({ - relations: ["knowledge"], - where: { assign_id }, - }) - const knowledges = await knowledgeData.map(x => ({ - id: x.knowledge_id, - level: x.knowledge_level, - title: x.knowledge.title, - description: - x.knowledge_level == 1 - ? x.knowledge.level1 - : x.knowledge_level == 2 - ? x.knowledge.level2 - : x.knowledge_level == 3 - ? x.knowledge.level3 - : x.knowledge_level == 4 - ? x.knowledge.level4 - : x.knowledge_level == 5 - ? x.knowledge.level5 - : "", - })) + return new HttpSuccess(result); + } - const lawData = await this.lawsRepository.find({ - where: { active: 1 }, - }) + /** + * API ดึงข้อมูลแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ + * + * @summary ดึงข้อมูลแบบมอบหมายงานการทดลองปฏิบัติหน้าที่ราชการ + * + */ + @Get("") + async GetAssign(@Query() assign_id: string, @Request() request: RequestWithUser) { + let _workflow = await new permission().Workflow(request, assign_id, "SYS_PROBATION"); + if (_workflow == false) await new permission().PermissionGet(request, "SYS_PROBATION"); - const laws = await Promise.all( - lawData.map(async x => { - const assignLaw = await this.assignLawRepository.countBy({ - assign_id: assign_id, - law_id: x.id, - }) + const assign = await this.assignRepository.findOne({ + select: [ + "id", + "personal_id", + "appointId", + "round_no", + "date_start", + "date_finish", + "other_desc", + "other4_desc", + "other5_no1_desc", + "experimenter_dated", + "active", + "createdAt", + "updatedAt", + "reportPersonId", + ], + where: { id: assign_id }, + }); - return { - id: x.id, - selected: assignLaw > 0 ? 1 : 0, - description: x.description, - status_select: x.status_select, - } - }) - ) + if (!assign) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลแบบมอบหมายงาน"); + } - const skillsData = await this.assignSkillRepository.find({ - relations: ["skill"], - where: { assign_id }, - }) + const profileData = await this.personalRepository.findOne({ + select: [ + "personal_id", + "prefixName", + "firstName", + "lastName", + "positionName", + "positionLevelName", + "positionLineName", + "orgRootName", + "organization", + ], + where: { + personal_id: assign.personal_id, + }, + }); - const skills = await skillsData.map(x => ({ - id: x.skill_id, - level: x.skill_level, - title: x.skill.title, - description: - x.skill_level == 1 - ? x.skill.level1 - : x.skill_level == 2 - ? x.skill.level2 - : x.skill_level == 3 - ? x.skill.level3 - : x.skill_level == 4 - ? x.skill.level4 - : x.skill_level == 5 - ? x.skill.level5 - : "", - })) + if (!profileData) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคล"); + } - const competencyData = await this.assignCompetencyRepository.find({ - select: ["competency_id", "competency_level", "competency_name", "competency_description"], - where: { assign_id }, - }) + const profile = { + ...profileData, + name: `${profileData.prefixName}${profileData.firstName} ${profileData.lastName}`, + Position: profileData.positionName, + Department: "-", + OrganizationOrganization: profileData.orgRootName, + Oc: profileData.organization, + }; - const competencys = await competencyData.map(x => ({ - id: x.competency_id, - level: x.competency_level, - name: x.competency_name, - description: x.competency_description, - })) + const jobs = await this.assignJobRepository.find({ + select: ["id", "activity_desc", "goal_desc"], + where: { assign_id }, + }); - const competencyGroupData = await this.assignCompetencyGroupRepository.find({ - select: ["competency_group_id", "competency_group_level", "competency_group_name", "competency_group_description"], - where: { assign_id }, - }) - const competency_groups = await competencyGroupData.map(x => ({ - id: x.competency_group_id, - level: x.competency_group_level, - name: x.competency_group_name, - description: x.competency_group_description, - })) + const knowledgeData = await this.assignKnowledgeRepository.find({ + relations: ["knowledge"], + where: { assign_id }, + }); + const knowledges = await knowledgeData.map((x) => ({ + id: x.knowledge_id, + level: x.knowledge_level, + title: x.knowledge.title, + description: + x.knowledge_level == 1 + ? x.knowledge.level1 + : x.knowledge_level == 2 + ? x.knowledge.level2 + : x.knowledge_level == 3 + ? x.knowledge.level3 + : x.knowledge_level == 4 + ? x.knowledge.level4 + : x.knowledge_level == 5 + ? x.knowledge.level5 + : "", + })); - const outputs = await this.assignOutputRepository.find({ - select: ["id", "output_desc", "indicator_desc"], - where: { assign_id }, - }) + const lawData = await this.lawsRepository.find({ + where: { active: 1 }, + }); - const director = await this.assignDirectorRepository.find({ - where: { assign_id }, - order: { ordering: "ASC" }, - }) + const laws = await Promise.all( + lawData.map(async (x) => { + const assignLaw = await this.assignLawRepository.countBy({ + assign_id: assign_id, + law_id: x.id, + }); - let mentors = [] - const mentorList = await director.filter(x => x.role == "mentor") - if (mentorList.length > 0) { - for (let index = 0; index < mentorList.length; index++) { - const e = await mentorList[index] - mentors.push({ - ...e, - name: e.fullname, - label: e.fullname + " " + (e.position ? `(${e.position}, ${e.posType}: ${e.posLevel})` : ""), - Position: e.position, // report - }) - } - } + return { + id: x.id, + selected: assignLaw > 0 ? 1 : 0, + description: x.description, + status_select: x.status_select, + }; + }), + ); - const commanderData = await (director.find(x => x.role == "commander") ?? null) - const commander = await (commanderData - ? { - ...commanderData, - name: commanderData.fullname, - label: commanderData.fullname + " " + (commanderData.position ? `(${commanderData.position}, ${commanderData.posType}: ${commanderData.posLevel})` : ""), - Position: commanderData.position, // report - } - : null) + const skillsData = await this.assignSkillRepository.find({ + relations: ["skill"], + where: { assign_id }, + }); - const chairmanData = await (director.find(x => x.role == "chairman") ?? null) - const chairman = await (chairmanData - ? { - ...chairmanData, - name: chairmanData.fullname, - label: chairmanData.fullname + " " + (chairmanData.position ? `(${chairmanData.position}, ${chairmanData.posType}: ${chairmanData.posLevel})` : ""), - Position: chairmanData.position, // report - } - : null) + const skills = await skillsData.map((x) => ({ + id: x.skill_id, + level: x.skill_level, + title: x.skill.title, + description: + x.skill_level == 1 + ? x.skill.level1 + : x.skill_level == 2 + ? x.skill.level2 + : x.skill_level == 3 + ? x.skill.level3 + : x.skill_level == 4 + ? x.skill.level4 + : x.skill_level == 5 + ? x.skill.level5 + : "", + })); - return new HttpSuccess({ - assign, - profile, - jobs, - knowledges, - laws, - skills, - competencys, - competency_groups, - outputs, - mentors, - commander, - chairman, - }) - } + const competencyData = await this.assignCompetencyRepository.find({ + select: ["competency_id", "competency_level", "competency_name", "competency_description"], + where: { assign_id }, + }); + + const competencys = await competencyData.map((x) => ({ + id: x.competency_id, + level: x.competency_level, + name: x.competency_name, + description: x.competency_description, + })); + + const competencyGroupData = await this.assignCompetencyGroupRepository.find({ + select: [ + "competency_group_id", + "competency_group_level", + "competency_group_name", + "competency_group_description", + ], + where: { assign_id }, + }); + const competency_groups = await competencyGroupData.map((x) => ({ + id: x.competency_group_id, + level: x.competency_group_level, + name: x.competency_group_name, + description: x.competency_group_description, + })); + + const outputs = await this.assignOutputRepository.find({ + select: ["id", "output_desc", "indicator_desc"], + where: { assign_id }, + }); + + const director = await this.assignDirectorRepository.find({ + where: { assign_id }, + order: { ordering: "ASC" }, + }); + + let mentors = []; + const mentorList = await director.filter((x) => x.role == "mentor"); + if (mentorList.length > 0) { + for (let index = 0; index < mentorList.length; index++) { + const e = await mentorList[index]; + mentors.push({ + ...e, + name: e.fullname, + label: + e.fullname + " " + (e.position ? `(${e.position}, ${e.posType}: ${e.posLevel})` : ""), + Position: e.position, // report + }); + } + } + + const commanderData = await (director.find((x) => x.role == "commander") ?? null); + const commander = await (commanderData + ? { + ...commanderData, + name: commanderData.fullname, + label: + commanderData.fullname + + " " + + (commanderData.position + ? `(${commanderData.position}, ${commanderData.posType}: ${commanderData.posLevel})` + : ""), + Position: commanderData.position, // report + } + : null); + + const chairmanData = await (director.find((x) => x.role == "chairman") ?? null); + const chairman = await (chairmanData + ? { + ...chairmanData, + name: chairmanData.fullname, + label: + chairmanData.fullname + + " " + + (chairmanData.position + ? `(${chairmanData.position}, ${chairmanData.posType}: ${chairmanData.posLevel})` + : ""), + Position: chairmanData.position, // report + } + : null); + + return new HttpSuccess({ + assign, + profile, + jobs, + knowledges, + laws, + skills, + competencys, + competency_groups, + outputs, + mentors, + commander, + chairman, + }); + } } From 76a3a53385f399d77e53eb63f363f305eaf0d75e Mon Sep 17 00:00:00 2001 From: waruneeauy Date: Mon, 2 Dec 2024 12:24:59 +0700 Subject: [PATCH 05/10] updated search keyword --- src/controllers/PersonalController.ts | 110 ++++++++++++++++++-------- 1 file changed, 79 insertions(+), 31 deletions(-) diff --git a/src/controllers/PersonalController.ts b/src/controllers/PersonalController.ts index 3b34557..cd9c5e6 100644 --- a/src/controllers/PersonalController.ts +++ b/src/controllers/PersonalController.ts @@ -20,6 +20,7 @@ import { setLogDataDiff } from "../interfaces/utils"; import { Personal, PostPersonal } from "../entities/Personal"; import permission from "../interfaces/permission"; import { Assign } from "../entities/Assign"; +import { Brackets } from "typeorm"; @Route("api/v1/probation/personal") @Tags("Personal") @@ -101,6 +102,7 @@ export class PersonalController extends Controller { @Get("list") async ListPersonal( @Query() status: string = "", + @Query() keyword: string = "", @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, @Request() request: RequestWithUser, @@ -133,12 +135,39 @@ export class PersonalController extends Controller { conditions.child4 = _data.child4; } - const [lists, total] = await this.personalRepository.findAndCount({ - order: { createdAt: "DESC" }, - where: conditions, - skip: (page - 1) * pageSize, - take: pageSize, - }); + const searchKeyword = await (keyword ? keyword.trim() : null); + + const [lists, total] = await AppDataSource.getRepository(Personal) + .createQueryBuilder("personal") + .where(conditions) + .andWhere( + new Brackets((qb) => { + qb.orWhere( + searchKeyword + ? `CONCAT(prefixName, firstName," ",lastName) like '%${keyword}%'` + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ); + qb.orWhere(searchKeyword ? `positionName like '%${keyword}%'` : "1=1", { + keyword: `%${searchKeyword}%`, + }); + qb.orWhere(searchKeyword ? `positionLevelName like '%${keyword}%'` : "1=1", { + keyword: `%${searchKeyword}%`, + }); + qb.orWhere(searchKeyword ? `organization like '%${keyword}%'` : "1=1", { + keyword: `%${searchKeyword}%`, + }); + qb.orWhere(searchKeyword ? `order_number like '%${keyword}%'` : "1=1", { + keyword: `%${searchKeyword}%`, + }); + }), + ) + .orderBy("updatedAt", "DESC") + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); if (!lists) { throw new HttpError(HttpStatusCode.INTERNAL_SERVER_ERROR, "ไม่สามารถแสดงข้อมูลได้"); @@ -146,32 +175,51 @@ export class PersonalController extends Controller { let result: any = []; - await Promise.all( - lists.map(async (item, index) => { - const probation_no = await this.assignRepository.count({ - where: { - personal_id: item.personal_id, - }, - }); + for (let i = 0; i < lists.length; i++) { + const probation_no = await this.assignRepository.count({ + where: { personal_id: lists[i].personal_id }, + }); - await result.push({ - personal_id: item.personal_id, - ordering: index + 1, - name: item.prefixName + item.firstName + " " + item.lastName, - idcard: item.idcard, - prefixName: item.prefixName, - firstName: item.firstName, - lastName: item.lastName, - position_line: item.positionName, - position_level: item.positionLevelName, - position_type: item.positionTypeName, - organization: item.organization, - probation_no: probation_no, - order_number: item.order_number, - probation_status: item.probation_status, - }); - }), - ); + await result.push({ + personal_id: lists[i].personal_id, + ordering: i + 1, + name: lists[i].prefixName + lists[i].firstName + " " + lists[i].lastName, + idcard: lists[i].idcard, + position_line: lists[i].positionName, + position_level: lists[i].positionLevelName, + position_type: lists[i].positionTypeName, + organization: lists[i].organization, + probation_no: probation_no, + order_number: lists[i].order_number, + probation_status: lists[i].probation_status, + }); + } + // await Promise.all( + // lists.map(async (item, index) => { + // const probation_no = await this.assignRepository.count({ + // where: { + // personal_id: item.personal_id, + // }, + // }); + + // await result.push({ + // personal_id: item.personal_id, + // ordering: index + 1, + // name: item.prefixName + item.firstName + " " + item.lastName, + // idcard: item.idcard, + // // prefixName: item.prefixName, + // // firstName: item.firstName, + // // lastName: item.lastName, + // position_line: item.positionName, + // position_level: item.positionLevelName, + // position_type: item.positionTypeName, + // organization: item.organization, + // probation_no: probation_no, + // order_number: item.order_number, + // probation_status: item.probation_status, + // }); + // }), + // ); return new HttpSuccess({ data: result, total: total }); } From 34ceb5a2266110cb291d4874b1be783129e073bc Mon Sep 17 00:00:00 2001 From: "DESKTOP-2S5P7D1\\Windows 10" Date: Tue, 3 Dec 2024 13:39:23 +0700 Subject: [PATCH 06/10] test build --- .github/workflows/release.yaml | 1 + Dockerfile | 35 ---------------------------------- docker/Dockerfile | 34 +++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 35 deletions(-) delete mode 100644 Dockerfile create mode 100644 docker/Dockerfile diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 4142249..f258019 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -53,6 +53,7 @@ jobs: with: context: . platforms: linux/amd64 + file: docker/Dockerfile push: true tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest - name: Remote Deployment diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 4ca0f48..0000000 --- a/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM node:18-alpine as builder - -# Create app directory -WORKDIR /app - -# Install app dependencies -COPY package*.json ./ - -RUN npm ci - -COPY . . - -RUN npm run build - -FROM node:18-alpine - -ENV NODE_ENV production -USER node - -# Create app directory -WORKDIR /app - -# Install app dependencies -COPY package*.json ./ -# COPY .env ./ - -RUN npm ci --production - -COPY --from=builder /app/dist ./dist - -# COPY entrypoint.sh /usr/local/bin/entrypoint.sh -# RUN chmod u+x /usr/local/bin/entrypoint.sh - -# ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -CMD [ "node", "dist/app.js" ] \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..07492be --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,34 @@ +# Build Stage +FROM node:lts-alpine AS build-stage + +# Create app directory +WORKDIR /app + +# Install app dependencies +COPY package*.json ./ + +RUN npm ci + +# Copy source files and build the app +COPY . . +RUN npm run build + +# Production Stage +FROM node:lts-alpine + +ENV NODE_ENV production +USER node + +# Create app directory +WORKDIR /app + +# Copy built app from build stage +COPY --from=build-stage /app/dist ./dist + +# Install only production dependencies +COPY package*.json ./ +RUN npm ci --production + +# Define the entrypoint and default command +# If you have a custom entrypoint script +CMD [ "node", "dist/app.js" ] From c40b7858b6a45129c16f7d3c5af9b4f43002b2d5 Mon Sep 17 00:00:00 2001 From: Bright Date: Wed, 4 Dec 2024 16:29:20 +0700 Subject: [PATCH 07/10] add fields --- src/controllers/PersonalController.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/controllers/PersonalController.ts b/src/controllers/PersonalController.ts index cd9c5e6..bcba3e6 100644 --- a/src/controllers/PersonalController.ts +++ b/src/controllers/PersonalController.ts @@ -184,6 +184,9 @@ export class PersonalController extends Controller { personal_id: lists[i].personal_id, ordering: i + 1, name: lists[i].prefixName + lists[i].firstName + " " + lists[i].lastName, + prefix: lists[i].prefixName, + firstName: lists[i].firstName, + lastName: lists[i].lastName, idcard: lists[i].idcard, position_line: lists[i].positionName, position_level: lists[i].positionLevelName, From 798b0145c862b65a07c275f2c6daba8479ce6e2b Mon Sep 17 00:00:00 2001 From: Bright Date: Wed, 4 Dec 2024 16:37:18 +0700 Subject: [PATCH 08/10] change name --- src/controllers/PersonalController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/PersonalController.ts b/src/controllers/PersonalController.ts index bcba3e6..22ce421 100644 --- a/src/controllers/PersonalController.ts +++ b/src/controllers/PersonalController.ts @@ -184,7 +184,7 @@ export class PersonalController extends Controller { personal_id: lists[i].personal_id, ordering: i + 1, name: lists[i].prefixName + lists[i].firstName + " " + lists[i].lastName, - prefix: lists[i].prefixName, + prefixName: lists[i].prefixName, firstName: lists[i].firstName, lastName: lists[i].lastName, idcard: lists[i].idcard, From 19381e99f7e2d38cdabed53727645cc429101894 Mon Sep 17 00:00:00 2001 From: "DESKTOP-2S5P7D1\\Windows 10" Date: Sat, 7 Dec 2024 09:30:42 +0700 Subject: [PATCH 09/10] test build discord --- .github/workflows/release.yaml | 60 ++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f258019..fe370b6 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,5 +1,5 @@ -name: release-test -run-name: release-test ${{ github.actor }} +name: release +run-name: release ${{ github.actor }} on: push: tags: @@ -7,14 +7,13 @@ on: workflow_dispatch: env: REGISTRY: docker.frappet.com - # IMAGE_NAME: ehr/bma-ehr-node-service IMAGE_NAME: ehr/bma-ehr-probation DEPLOY_HOST: frappet.com - # COMPOSE_PATH: /home/frappet/docker/bma-ehr COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-probation + jobs: # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=test-v1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd - release-test: + release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -68,21 +67,40 @@ jobs: docker compose pull docker compose up -d echo "${{ steps.gen_ver.outputs.image_ver }}"> success - - uses: snow-actions/line-notify@v1.1.0 + - name: Notify Discord Success if: success() - with: - access_token: ${{ secrets.TOKEN_LINE }} - message: | - -Success✅✅✅ - Image: ${{env.IMAGE_NAME}} - Version: ${{ steps.gen_ver.outputs.IMAGE_VER }} - By: ${{github.actor}} - - uses: snow-actions/line-notify@v1.1.0 + run: | + curl -H "Content-Type: application/json" \ + -X POST \ + -d '{ + "embeds": [{ + "title": "✅ Deployment Success!", + "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`", + "color": 3066993, + "footer": { + "text": "Release Notification", + "icon_url": "https://example.com/success-icon.png" + }, + "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" + }] + }' \ + ${{ secrets.DISCORD_WEBHOOK }} + + - name: Notify Discord Failure if: failure() - with: - access_token: ${{ secrets.TOKEN_LINE }} - message: | - -Failure❌❌❌ - Image: ${{env.IMAGE_NAME}} - Version: ${{ steps.gen_ver.outputs.IMAGE_VER }} - By: ${{github.actor}} + run: | + curl -H "Content-Type: application/json" \ + -X POST \ + -d '{ + "embeds": [{ + "title": "❌ Deployment Failed!", + "description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`", + "color": 15158332, + "footer": { + "text": "Release Notification", + "icon_url": "https://example.com/failure-icon.png" + }, + "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'" + }] + }' \ + ${{ secrets.DISCORD_WEBHOOK }} From 7a9e3c5c1160a0525869904fd2554abf3f5ce4c6 Mon Sep 17 00:00:00 2001 From: "DESKTOP-2S5P7D1\\Windows 10" Date: Sat, 14 Dec 2024 01:04:01 +0700 Subject: [PATCH 10/10] edit permission --- src/interfaces/call-api.ts | 174 +++++++++++++++++------------------ src/interfaces/permission.ts | 38 ++++++++ src/middlewares/logs.ts | 144 +++++++++++++++-------------- 3 files changed, 193 insertions(+), 163 deletions(-) diff --git a/src/interfaces/call-api.ts b/src/interfaces/call-api.ts index 78f0f14..db76a72 100644 --- a/src/interfaces/call-api.ts +++ b/src/interfaces/call-api.ts @@ -1,96 +1,86 @@ -import { - Controller, - Request, - Get, - Post, - Put, - Delete, - Patch, - Route, - Security, - Tags, - Path, -} from "tsoa"; -import axios from "axios"; -import { addLogSequence } from "./utils"; +import { Path } from "tsoa" +import axios from "axios" +import { addLogSequence } from "./utils" class CallAPI { - //Get - public async GetData(request: any, @Path() path: any) { - const token = request.headers.authorization; - const url = process.env.API_URL + path; - try { - const response = await axios.get(url, { - headers: { - Authorization: `${token}`, - "Content-Type": "application/json", - 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; - } - } - //Post - public async PostData(request: any, @Path() path: any, sendData: any) { - const token = request.headers.authorization; - const url = process.env.API_URL + path; - try { - const response = await axios.post(url, sendData, { - headers: { - Authorization: `${token}`, - "Content-Type": "application/json", - 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; - } - } + //Get + public async GetData(request: any, @Path() path: any, log = true) { + const token = "Bearer " + request.headers.authorization.replace("Bearer ", "") + const url = process.env.API_URL + path + try { + const response = await axios.get(url, { + headers: { + Authorization: `${token}`, + "Content-Type": "application/json", + api_key: process.env.API_KEY, + }, + }) + if (log) + 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) { + if (log) + addLogSequence(request, { + action: "request", + status: "error", + description: "unconnected", + request: { + method: "GET", + url: url, + response: JSON.stringify(error), + }, + }) + throw error + } + } + //Post + public async PostData(request: any, @Path() path: any, sendData: any) { + const token = "Bearer " + request.headers.authorization.replace("Bearer ", "") + const url = process.env.API_URL + path + try { + const response = await axios.post(url, sendData, { + headers: { + Authorization: `${token}`, + "Content-Type": "application/json", + 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 + } + } } -export default CallAPI; +export default CallAPI diff --git a/src/interfaces/permission.ts b/src/interfaces/permission.ts index a04c877..a4b989e 100644 --- a/src/interfaces/permission.ts +++ b/src/interfaces/permission.ts @@ -3,8 +3,11 @@ import { RequestWithUser } from "../middlewares/user" import CallAPI from "./call-api" import HttpError from "./http-error" import HttpStatus from "./http-status" +import { promisify } from "util" class CheckAuth { + private redis = require("redis") + public async Permission(req: RequestWithUser, system: string, action: string) { if (req.headers.hasOwnProperty("api_key") && req.headers["api_key"] && req.headers["api_key"] == process.env.API_KEY) { return null @@ -155,6 +158,41 @@ class CheckAuth { return false }) } + public async checkOrg(token: any, keycloakId: string) { + const redisClient = await this.redis.createClient({ + host: process.env.REDIS_HOST, + port: process.env.REDIS_PORT, + }) + const getAsync = promisify(redisClient.get).bind(redisClient) + let reply = await getAsync("org_" + keycloakId) + if (reply != null) { + reply = JSON.parse(reply) + } else { + try { + if (!keycloakId) throw "Error calling API No KeycloakId" + 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) { return await this.Permission(req, system, "CREATE") } diff --git a/src/middlewares/logs.ts b/src/middlewares/logs.ts index e31fd34..44245fc 100644 --- a/src/middlewares/logs.ts +++ b/src/middlewares/logs.ts @@ -1,79 +1,81 @@ -import { NextFunction, Request, Response } from "express"; -import { Client } from "@elastic/elasticsearch"; +import { NextFunction, Request, Response } from "express" +import { Client } from "@elastic/elasticsearch" +import permission from "../interfaces/permission" if (!process.env.ELASTICSEARCH_INDEX) { - throw new Error("Require ELASTICSEARCH_INDEX to store log."); + throw new Error("Require ELASTICSEARCH_INDEX to store log.") } -const ELASTICSEARCH_INDEX = process.env.ELASTICSEARCH_INDEX; +const ELASTICSEARCH_INDEX = process.env.ELASTICSEARCH_INDEX const LOG_LEVEL_MAP: Record = { - 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: "probation", - 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(); + debug: 4, + info: 3, + warning: 2, + error: 1, + none: 0, } -export default logMiddleware; +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", async () => { + 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 + + let token: any + token = req.headers["authorization"] + + const rootId = await new permission().checkOrg(token, req.app.locals.logData.userId) + + const obj = { + logType: res.statusCode >= 500 ? "error" : res.statusCode >= 400 ? "warning" : "info", + ip: req.ip, + rootId: rootId ? rootId.orgRootId : null, + systemName: "probation", + 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