From 122e00d065f852e407f64a9513f9e445bc365038 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:10:22 +0700 Subject: [PATCH 1/7] refactor!: merge information into profile --- src/entities/BloodGroup.ts | 7 +- src/entities/Gender.ts | 7 +- src/entities/Profile.ts | 129 ++++++++++++++++++---- src/entities/ProfileInformation.ts | 169 ----------------------------- src/entities/Relationship.ts | 7 +- 5 files changed, 119 insertions(+), 200 deletions(-) delete mode 100644 src/entities/ProfileInformation.ts diff --git a/src/entities/BloodGroup.ts b/src/entities/BloodGroup.ts index 11e3fb1e..1c4fcc9d 100644 --- a/src/entities/BloodGroup.ts +++ b/src/entities/BloodGroup.ts @@ -1,7 +1,6 @@ import { Entity, Column, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; - -import { ProfileInformation } from "./ProfileInformation"; +import { Profile } from "./Profile"; @Entity("bloodGroup") export class BloodGroup extends EntityBase { @@ -13,8 +12,8 @@ export class BloodGroup extends EntityBase { }) name: string; - @OneToMany(() => ProfileInformation, (profileInformation) => profileInformation.bloodGroupId) - profileInformations: ProfileInformation[]; + @OneToMany(() => Profile, (v) => v.bloodGroup) + profile: Profile[]; } export class CreateBloodGroup { diff --git a/src/entities/Gender.ts b/src/entities/Gender.ts index 79d7e6b7..960ff541 100644 --- a/src/entities/Gender.ts +++ b/src/entities/Gender.ts @@ -1,7 +1,6 @@ import { Entity, Column, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; - -import { ProfileInformation } from "./ProfileInformation"; +import { Profile } from "./Profile"; @Entity("gender") export class Gender extends EntityBase { @@ -13,8 +12,8 @@ export class Gender extends EntityBase { }) name: string; - @OneToMany(() => ProfileInformation, (profileInformation) => profileInformation.genderId) - profileInformations: ProfileInformation[]; + @OneToMany(() => Profile, (v) => v.gender) + profile: Profile[]; } export class CreateGender { diff --git a/src/entities/Profile.ts b/src/entities/Profile.ts index 55a300f5..c2f7fe44 100644 --- a/src/entities/Profile.ts +++ b/src/entities/Profile.ts @@ -1,4 +1,4 @@ -import { Entity, Column, OneToMany, OneToOne, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { Entity, Column, OneToMany, JoinColumn, ManyToOne } from "typeorm"; import { EntityBase } from "./base/Base"; import { PosMaster } from "./PosMaster"; import { PosLevel } from "./PosLevel"; @@ -16,9 +16,11 @@ import { ProfileAbility } from "./ProfileAbility"; import { ProfileDuty } from "./ProfileDuty"; import { ProfileNopaid } from "./ProfileNopaid"; import { ProfileOther } from "./ProfileOther"; -import { ProfileInformation } from "./ProfileInformation"; import { ProfileFamilyHistory } from "./ProfileFamily"; import { ProfileGovernment } from "./ProfileGovernment"; +import { Gender } from "./Gender"; +import { Relationship } from "./Relationship"; +import { BloodGroup } from "./BloodGroup"; @Entity("profile") export class Profile extends EntityBase { @@ -139,6 +141,63 @@ export class Profile extends EntityBase { }) birthDate: Date; + @Column({ + nullable: true, + comment: "เชื้อชาติ", + length: 255, + default: null, + }) + ethnicity: string; + + @Column({ + nullable: true, + comment: "ศาสนา", + length: 255, + default: null, + }) + religion: string; + + @Column({ + nullable: true, + comment: "เบอร์โทร", + length: 255, + default: null, + }) + telephoneNumber: string; + + @Column({ + nullable: true, + comment: "เพศ", + length: 40, + default: null, + }) + genderId: string; + + @ManyToOne(() => Gender, (v) => v.profile) + gender: Gender; + + @Column({ + nullable: true, + comment: "ความสัมพันธ์", + length: 40, + default: null, + }) + relationshipId: string; + + @ManyToOne(() => Relationship, (v) => v.profile) + relationship: Relationship; + + @Column({ + nullable: true, + comment: "กรุ๊ปเลือด", + length: 40, + default: null, + }) + bloodGroupId: string; + + @ManyToOne(() => BloodGroup, (v) => v.profile) + bloodGroup: BloodGroup; + @OneToMany(() => PosMaster, (posMaster) => posMaster.current_holder) current_holders: PosMaster[]; @@ -190,6 +249,9 @@ export class Profile extends EntityBase { @OneToMany(() => ProfileGovernment, (profileGovernment) => profileGovernment.profile) profileGovernment: ProfileGovernment[]; + @OneToMany(() => ProfileHistory, (v) => v.profile) + histories: ProfileHistory[]; + @ManyToOne(() => PosLevel, (posLevel) => posLevel.profiles) @JoinColumn({ name: "posLevelId" }) posLevel: PosLevel; @@ -197,32 +259,61 @@ export class Profile extends EntityBase { @ManyToOne(() => PosType, (posType) => posType.profiles) @JoinColumn({ name: "posTypeId" }) posType: PosType; +} - @OneToMany(() => ProfileInformation, (profileInformation) => profileInformation.profile) - profileInformation: ProfileInformation[]; +@Entity("profileHistory") +export class ProfileHistory extends Profile { + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง ProfileInformation", + default: null, + }) + profileId: string; + + @ManyToOne(() => Profile, (v) => v.histories, { onDelete: "CASCADE" }) + profile: Profile; } export class CreateProfile { - @Column() prefix: string; - - @Column() firstName: string; - - @Column() lastName: string; - - @Column() - citizenId: string; - - @Column() position: string; - - @Column("uuid") + email: string | null; + phone: string | null; + isProbation: boolean | null; + dateRetire: Date | null; + birthDate: Date | null; + ethnicity: string | null; + religion: string | null; + telephoneNumber: string | null; + citizenId: string; posLevelId: string | null; - - @Column("uuid") posTypeId: string | null; + genderId: string | null; + relationshipId: string | null; + bloodGroupId: string | null; } -export type UpdateProfile = Partial; +export type UpdateProfile = { + prefix?: string | null; + firstName?: string | null; + lastName?: string | null; + position?: string | null; + email?: string | null; + phone?: string | null; + keycloak?: string | null; + isProbation?: boolean | null; + dateRetire?: Date | null; + birthDate?: Date | null; + ethnicity?: string | null; + religion?: string | null; + telephoneNumber?: string | null; + citizenId?: string | null; + posLevelId?: string | null; + posTypeId?: string | null; + genderId?: string | null; + relationshipId?: string | null; + bloodGroupId?: string | null; +}; diff --git a/src/entities/ProfileInformation.ts b/src/entities/ProfileInformation.ts deleted file mode 100644 index e6157a5e..00000000 --- a/src/entities/ProfileInformation.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; -import { EntityBase } from "./base/Base"; - -import { Profile } from "./Profile"; -import { BloodGroup } from "./BloodGroup"; -import { Relationship } from "./Relationship"; -import { Gender } from "./Gender"; - -@Entity("profileInformation") -export class ProfileInformation extends EntityBase { - @Column({ - nullable: true, - comment: "เลขประจำตัวประชาชน", - default: null, - length: 13, - }) - citizenId: string; - - @Column({ - nullable: true, - comment: "คำนำหน้าชื่อ", - length: 40, - default: null, - }) - prefix: string; - - @Column({ - nullable: true, - comment: "ชื่อ", - length: 255, - default: null, - }) - firstName: string; - - @Column({ - nullable: true, - comment: "นามสกุล", - length: 255, - default: null, - }) - lastName: string; - - @Column({ - nullable: true, - type: "datetime", - comment: "วันเกิด", - default: null, - }) - birthDate: Date; - - @Column({ - nullable: true, - comment: "เชื้อชาติ", - length: 255, - default: null, - }) - ethnicity: string; - - @Column({ - nullable: true, - comment: "ศาสนา", - length: 255, - default: null, - }) - religion: string; - - @Column({ - nullable: true, - comment: "เบอร์โทร", - length: 255, - default: null, - }) - telephoneNumber: string; - - @OneToMany(() => ProfileInformationHistory, (v) => v.profileInformation) - profileInformationHistory: ProfileInformationHistory[]; - - @Column({ - nullable: true, - comment: "เพศ", - length: 40, - default: null, - }) - genderId: string; - - @ManyToOne(() => Gender, (v) => v.profileInformations) - @JoinColumn({ name: "genderId" }) - gender: Gender; - - @Column({ - nullable: true, - comment: "ความสัมพันธ์", - length: 40, - default: null, - }) - relationshipId: string; - - @ManyToOne(() => Relationship, (v) => v.profileInformations) - @JoinColumn({ name: "relationshipId" }) - relationship: Relationship; - - @Column({ - nullable: true, - comment: "กรุ๊ปเลือด", - length: 40, - default: null, - }) - bloodGroupId: string; - - @ManyToOne(() => BloodGroup, (v) => v.profileInformations) - @JoinColumn({ name: "bloodGroupId" }) - bloodGroup: BloodGroup; - - @Column({ - nullable: true, - length: 40, - comment: "คีย์นอก(FK)ของตาราง Profile", - default: null, - }) - profileId: string; - - @ManyToOne(() => Profile, (v) => v.profileInformation) - @JoinColumn({ name: "profileId" }) - profile: Profile; -} - -export class CreateProfileInformation { - profileId: string | null; - citizenId: string | null; - prefix: string | null; - firstName: string | null; - lastName: string | null; - birthDate: Date | null; - ethnicity: string | null; - religion: string | null; - telephoneNumber: string | null; - genderId: string | null; - relationshipId: string | null; - bloodGroupId: string | null; -} - -export type UpdateProfileInformation = { - citizenId?: string | null; - prefix?: string | null; - firstName?: string | null; - lastName?: string | null; - birthDate?: Date | null; - ethnicity?: string | null; - religion?: string | null; - telephoneNumber?: string | null; - genderId?: string | null; - relationshipId?: string | null; - bloodGroupId?: string | null; -}; - -@Entity("profileInformationHistory") -export class ProfileInformationHistory extends ProfileInformation { - @Column({ - nullable: true, - length: 40, - comment: "คีย์นอก(FK)ของตาราง ProfileInformation", - default: null, - }) - profileInformationId: string; - - @ManyToOne(() => ProfileInformation, (v) => v.profileInformationHistory, { onDelete: "CASCADE" }) - @JoinColumn({ name: "profileInformationId" }) - profileInformation: ProfileInformation; -} diff --git a/src/entities/Relationship.ts b/src/entities/Relationship.ts index a9b3edd7..7e84710f 100644 --- a/src/entities/Relationship.ts +++ b/src/entities/Relationship.ts @@ -1,7 +1,7 @@ import { Entity, Column, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; -import { ProfileInformation } from "./ProfileInformation"; +import { Profile } from "./Profile"; @Entity("relationship") export class Relationship extends EntityBase { @@ -13,12 +13,11 @@ export class Relationship extends EntityBase { }) name: string; - @OneToMany(() => ProfileInformation, (profileInformation) => profileInformation.relationshipId) - profileInformations: ProfileInformation[]; + @OneToMany(() => Profile, (v) => v.relationship) + profile: Profile[]; } export class CreateRelationship { - @Column() name: string; } From 8a1400d84057cfd80a56ea1834b9263288e06c46 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:15:00 +0700 Subject: [PATCH 2/7] refactor!: merge information into profile endpoint --- src/controllers/ProfileController.ts | 295 ++++++------------ .../ProfileInformationController.ts | 204 ------------ 2 files changed, 102 insertions(+), 397 deletions(-) delete mode 100644 src/controllers/ProfileInformationController.ts diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 76b226c2..2c8f4463 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -16,31 +16,32 @@ import { } from "tsoa"; import { AppDataSource } from "../database/data-source"; import HttpSuccess from "../interfaces/http-success"; -import HttpStatusCode from "../interfaces/http-status"; +import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; -import { Profile, CreateProfile, UpdateProfile } from "../entities/Profile"; -import { Brackets, In, IsNull, Like, Not } from "typeorm"; +import { Profile, CreateProfile, UpdateProfile, ProfileHistory } from "../entities/Profile"; +import { Brackets, IsNull, Like, Not } from "typeorm"; import { OrgRevision } from "../entities/OrgRevision"; import { PosMaster } from "../entities/PosMaster"; import { PosLevel } from "../entities/PosLevel"; import { PosType } from "../entities/PosType"; -import { request } from "http"; import { calculateRetireDate } from "../interfaces/utils"; +import { RequestWithUser } from "../middlewares/user"; @Route("api/v1/org/profile") @Tags("Profile") @Security("bearerAuth") @Response( - HttpStatusCode.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", ) -@SuccessResponse(HttpStatusCode.OK, "สำเร็จ") +@SuccessResponse(HttpStatus.OK, "สำเร็จ") export class ProfileController extends Controller { - private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); - private posMasterRepository = AppDataSource.getRepository(PosMaster); - private profileRepository = AppDataSource.getRepository(Profile); - private posLevelRepository = AppDataSource.getRepository(PosLevel); - private posTypeRepository = AppDataSource.getRepository(PosType); + private orgRevisionRepo = AppDataSource.getRepository(OrgRevision); + private posMasterRepo = AppDataSource.getRepository(PosMaster); + private profileRepo = AppDataSource.getRepository(Profile); + private profileHistoryRepo = AppDataSource.getRepository(ProfileHistory); + private posLevelRepo = AppDataSource.getRepository(PosLevel); + private posTypeRepo = AppDataSource.getRepository(PosType); /** * API สร้างทะเบียนประวัติ @@ -49,58 +50,32 @@ export class ProfileController extends Controller { * */ @Post() - async createProfile( - @Body() - requestBody: CreateProfile, - @Request() request: { user: Record }, - ) { - const _profile = await this.profileRepository.findOne({ - where: { citizenId: requestBody.citizenId }, - }); - if (_profile) { + async createProfile(@Request() request: RequestWithUser, @Body() body: CreateProfile) { + if (await this.profileRepo.findOneBy({ citizenId: body.citizenId })) { throw new HttpError( - HttpStatusCode.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", ); } - if (requestBody.posLevelId == "") { - requestBody.posLevelId = null; - } - if (requestBody.posLevelId) { - const checkPosLevel = await this.posLevelRepository.findOne({ - where: { id: requestBody.posLevelId }, - }); - if (!checkPosLevel) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); - } + + if (!body.posLevelId) body.posLevelId = null; + if (!body.posTypeId) body.posTypeId = null; + + if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); } - if (requestBody.posTypeId == "") { - requestBody.posTypeId = null; - } - if (requestBody.posTypeId) { - const checkPosType = await this.posTypeRepository.findOne({ - where: { id: requestBody.posTypeId }, - }); - if (!checkPosType) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); - } + if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); } - const checkCitizenId = await this.profileRepository.findOne({ - where: { citizenId: requestBody.citizenId }, - }); - - if (checkCitizenId) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); - } - - const profile = Object.assign(new Profile(), requestBody); + const profile = Object.assign(new Profile(), body); profile.createdUserId = request.user.sub; profile.createdFullName = request.user.name; profile.lastUpdateUserId = request.user.sub; profile.lastUpdateFullName = request.user.name; - await this.profileRepository.save(profile); + await this.profileRepo.save(profile); + return new HttpSuccess(); } @@ -113,65 +88,48 @@ export class ProfileController extends Controller { */ @Put("{id}") async updateProfile( + @Request() request: RequestWithUser, @Path() id: string, - @Body() - requestBody: CreateProfile, - @Request() request: { user: Record }, + @Body() body: UpdateProfile, ) { - const profile = await this.profileRepository.findOne({ where: { id: id } }); - if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); + const exists = + !!body.citizenId && + (await this.profileRepo.findOne({ + where: { id: Not(id), citizenId: body.citizenId }, + })); + + if (exists) { + throw new HttpError(HttpStatus.CONFLICT, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); } - const _profile = await this.profileRepository.findOne({ - where: { id: Not(id), citizenId: requestBody.citizenId }, - }); - if (_profile) { - throw new HttpError( - HttpStatusCode.INTERNAL_SERVER_ERROR, - "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", - ); + if (!body.posLevelId) body.posLevelId = null; + if (!body.posTypeId) body.posTypeId = null; + + if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); } - if (requestBody.posLevelId == "") { - requestBody.posLevelId = null; - } - if (requestBody.posLevelId) { - const checkPosLevel = await this.posLevelRepository.findOne({ - where: { id: requestBody.posLevelId }, - }); - if (!checkPosLevel) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); - } + if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); } - if (requestBody.posTypeId == "") { - requestBody.posTypeId = null; - } - if (requestBody.posTypeId) { - const checkPosType = await this.posTypeRepository.findOne({ - where: { id: requestBody.posTypeId }, - }); - if (!checkPosType) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); - } - } + const record = await this.profileRepo.findOneBy({ id }); - const checkCitizenId = await this.profileRepository.findOne({ - where: { - id: Not(id), - citizenId: requestBody.citizenId, - }, - }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); - if (checkCitizenId) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); - } + await this.profileHistoryRepo.save( + Object.assign(new ProfileHistory(), { + ...record, + id: undefined, + }), + ); + + Object.assign(record, body); + record.lastUpdateUserId = request.user.sub; + record.lastUpdateFullName = request.user.name; + + await this.profileRepo.save(record); - profile.lastUpdateUserId = request.user.sub; - profile.lastUpdateFullName = request.user.name; - this.profileRepository.merge(profile, requestBody); - await this.profileRepository.save(profile); return new HttpSuccess(); } @@ -184,13 +142,12 @@ export class ProfileController extends Controller { */ @Delete("{id}") async deleteProfile(@Path() id: string) { - const delProfile = await this.profileRepository.findOne({ - where: { id }, - }); - if (!delProfile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); + const result = await this.profileRepo.delete({ id }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); } - await this.profileRepository.delete({ id: id }); + return new HttpSuccess(); } @@ -202,27 +159,20 @@ export class ProfileController extends Controller { * @param {string} id Id ทะเบียนประวัติ */ @Get("{id}") - async detailProfile(@Path() id: string) { - const profile = await this.profileRepository.findOne({ + async getProfile(@Path() id: string) { + const profile = await this.profileRepo.findOne({ relations: { posLevel: true, posType: true, + gender: true, + relationship: true, + bloodGroup: true, }, where: { id }, - select: [ - "id", - "prefix", - "firstName", - "lastName", - "citizenId", - "position", - "posLevelId", - "posTypeId", - ], }); - if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); - } + + if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + return new HttpSuccess(profile); } @@ -238,73 +188,32 @@ export class ProfileController extends Controller { @Query("pageSize") pageSize: number = 10, @Query("keyword") keyword?: string, ) { - const [profile, total] = await this.profileRepository.findAndCount({ - select: [ - "id", - "prefix", - "firstName", - "lastName", - "citizenId", - "position", - "posLevelId", - "posTypeId", - ], + const [record, total] = await this.profileRepo.findAndCount({ + relations: { + posLevel: true, + posType: true, + gender: true, + relationship: true, + bloodGroup: true, + }, where: { citizenId: Like(`%${keyword}%`), position: Like(`%${keyword}%`), prefix: Like(`%${keyword}%`), firstName: Like(`%${keyword}%`), lastName: Like(`%${keyword}%`), - // posLevel: { posLevelName: keyword }, - // posType: { posTypeName: Like(`%${keyword}%`) }, - // salaryEmployeeMins: { group: keyword }, - // salaryEmployee: { group: keyword }, }, order: { createdAt: "ASC" }, skip: (page - 1) * pageSize, take: pageSize, }); - // if (keyword != undefined && keyword !== "") { - // const formattedKeyword = keyword.toLowerCase().replace(/\s+/g, ""); - // const filteredProfile = profile.filter( - // (x) => - // (x.prefix + x.firstName + x.lastName).replace(/\s+/g, "").includes(formattedKeyword) || - // x.citizenId?.toString().includes(keyword) || - // x.position?.toString().includes(keyword), - // ); - - // const formattedData = filteredProfile.map((item) => ({ - // id: item.id, - // prefix: item.prefix, - // firstName: item.firstName, - // lastName: item.lastName, - // citizenId: item.citizenId, - // position: item.position, - // posLevelId: item.posLevelId, - // posTypeId: item.posTypeId, - // })); - - // return new HttpSuccess({ data: formattedData, total: formattedData.length }); - // } - - const formattedData = profile.map((item) => ({ - id: item.id, - prefix: item.prefix, - firstName: item.firstName, - lastName: item.lastName, - citizenId: item.citizenId, - position: item.position, - posLevelId: item.posLevelId, - posTypeId: item.posTypeId, - })); - return new HttpSuccess({ data: formattedData, total }); + return new HttpSuccess({ data: record, total }); } /** * API ค้นหารายชื่อไปครองตำแหน่ง * * @summary ORG_063 - ค้นหารายชื่อไปครองตำแหน่ง (ADMIN) #68 - * */ @Post("search") async searchProfileOrg( @@ -318,7 +227,7 @@ export class ProfileController extends Controller { keyword?: string; }, ) { - const orgRevision = await this.orgRevisionRepository.findOne({ + const orgRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsDraft: true, orgRevisionIsCurrent: false, @@ -326,9 +235,9 @@ export class ProfileController extends Controller { relations: ["posMasters"], }); if (!orgRevision) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); } - const [profiles, total] = await this.profileRepository + const [profiles, total] = await this.profileRepo .createQueryBuilder("profile") .leftJoinAndSelect("profile.next_holders", "next_holders") .leftJoinAndSelect("profile.posLevel", "posLevel") @@ -428,21 +337,21 @@ export class ProfileController extends Controller { */ @Get("keycloak/position") async getProfileByKeycloak(@Request() request: { user: Record }) { - const profile = await this.profileRepository.findOne({ + const profile = await this.profileRepo.findOne({ where: { keycloak: request.user.sub }, relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], }); if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } - const orgRevisionPublish = await this.orgRevisionRepository + const orgRevisionPublish = await this.orgRevisionRepo .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = false") .andWhere("orgRevision.orgRevisionIsCurrent = true") .getOne(); if (!orgRevisionPublish) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); } const _profile = { @@ -549,28 +458,28 @@ export class ProfileController extends Controller { let findProfile: any; switch (body.fieldName) { case "idcard": - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ where: { citizenId: Like(`%${body.keyword}%`) }, relations: ["posType", "posLevel"], }); break; case "firstname": - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ where: { firstName: Like(`%${body.keyword}%`) }, relations: ["posType", "posLevel"], }); break; case "lastname": - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ where: { lastName: Like(`%${body.keyword}%`) }, relations: ["posType", "posLevel"], }); break; default: - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ relations: ["posType", "posLevel"], }); break; @@ -609,17 +518,17 @@ export class ProfileController extends Controller { let commanderFullname_: any = {}; let commanderPosition_: any = {}; - const findProfile = await this.profileRepository.findOne({ + const findProfile = await this.profileRepo.findOne({ where: { keycloak: request.user.sub }, }); - const findRevision = await this.orgRevisionRepository.findOne({ + const findRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true, }, }); - const findPosMaster = await this.posMasterRepository.findOne({ + const findPosMaster = await this.posMasterRepo.findOne({ where: { current_holderId: findProfile?.id, orgRevisionId: findRevision?.id, @@ -648,7 +557,7 @@ export class ProfileController extends Controller { condition = { orgRootId: childId, orgChild1Id: IsNull() }; } - const findCmd = await this.posMasterRepository.findOne({ + const findCmd = await this.posMasterRepo.findOne({ where: { current_holderId: Not(IsNull()) || Not(""), orgRevisionId: findRevision?.id, @@ -791,12 +700,12 @@ export class ProfileController extends Controller { @Body() requestBody: { citizenId: string }, ) { - const profile = await this.profileRepository.findOne({ + const profile = await this.profileRepo.findOne({ where: { id: Not(id), citizenId: requestBody.citizenId }, }); if (profile) { throw new HttpError( - HttpStatusCode.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", ); } @@ -838,7 +747,7 @@ export class ProfileController extends Controller { .take(body.pageSize) .getManyAndCount(); - const orgRevisionActive = await this.orgRevisionRepository.findOne({ + const orgRevisionActive = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, }); @@ -928,11 +837,11 @@ export class ProfileController extends Controller { period: string; }, ) { - const findRevision = await this.orgRevisionRepository.findOne({ + const findRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true }, }); if (!findRevision) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. OrgRevision"); + throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision"); } const [findPosMaster, total] = await AppDataSource.getRepository(PosMaster) @@ -1024,7 +933,7 @@ export class ProfileController extends Controller { .take(body.pageSize) .getManyAndCount(); if (!findPosMaster) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. PosMaster"); + throw new HttpError(HttpStatus.NOT_FOUND, "not found. PosMaster"); } const formattedData = findPosMaster.map((item) => { @@ -1142,12 +1051,12 @@ export class ProfileController extends Controller { @Path() revisionId: string, @Request() request: { user: Record }, ) { - const profile = await this.profileRepository.findOne({ + const profile = await this.profileRepo.findOne({ where: { keycloak: request.user.sub }, relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], }); if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } const _profile = { diff --git a/src/controllers/ProfileInformationController.ts b/src/controllers/ProfileInformationController.ts deleted file mode 100644 index 8f106478..00000000 --- a/src/controllers/ProfileInformationController.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { - Controller, - Post, - Put, - Delete, - Route, - Security, - Tags, - Body, - Path, - Request, - SuccessResponse, - Response, - Get, - Query, - Patch, - Example, -} from "tsoa"; - -import HttpSuccess from "../interfaces/http-success"; -import HttpError from "../interfaces/http-error"; -import HttpStatus from "../interfaces/http-status"; - -import { - ProfileInformationHistory, - ProfileInformation, - CreateProfileInformation, - UpdateProfileInformation, -} from "../entities/ProfileInformation"; -import { RequestWithUser } from "../middlewares/user"; -import { Profile } from "../entities/Profile"; - -import { AppDataSource } from "../database/data-source"; - -@Route("api/v1/org/profile/information") -@Tags("ProfileInformation") -@Security("bearerAuth") -export class ProfileInformationController extends Controller { - private profileRepo = AppDataSource.getRepository(Profile); - private profileInformationRepo = AppDataSource.getRepository(ProfileInformation); - private profileInformationHistoryRepo = AppDataSource.getRepository(ProfileInformationHistory); - - @Get("{profileId}") - @Example({ - status: 200, - message: "สำเร็จ", - result: [ - { - id: "42deba79-0725-403f-898d-6c142b2842a5", - createdAt: "2024-03-19T19:47:26.512Z", - createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", - lastUpdatedAt: "2024-03-19T20:01:15.000Z", - lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", - createdFullName: "สาวิตรี ศรีสมัย", - lastUpdateFullName: "สาวิตรี ศรีสมัย", - citizenId: "1849900687228", - prefix: "นาย", - firstName: "ธนพนธ์", - lastName: "แสงจันทร์", - birthDate: "2024-03-20T02:59:27.000Z", - ethnicity: "ไทย", - religion: "-", - telephoneNumber: "0639195701", - genderId: "74ec022c-b961-47f4-985e-2d9cbb10984c", - relationshipId: "5872f993-6dc3-44c7-85d3-f56825abd96d", - bloodGroupId: "fab11ded-8177-4e23-a791-78a10bc92333", - profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", - }, - ], - }) - public async detailProfileInformation(@Path() profileId: string) { - const getProfileInformation = await this.profileInformationRepo.findOne({ - relations: { - bloodGroup: true, - relationship: true, - gender: true, - }, - where: { profileId }, - }); - if (!getProfileInformation) { - throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); - } - return new HttpSuccess(getProfileInformation); - } - - @Get("history/{informationId}") - @Example({ - status: 200, - message: "สำเร็จ", - result: [ - { - id: "9abba9df-5fa0-4056-847d-4b3680b61ee5", - createdAt: "2024-03-19T20:07:24.320Z", - createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", - lastUpdatedAt: "2024-03-19T20:07:24.320Z", - lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", - createdFullName: "string", - lastUpdateFullName: "สาวิตรี ศรีสมัย", - citizenId: "1849900687228", - prefix: "นาย", - firstName: "ธนพนธ์", - lastName: "แสงจันทร์", - birthDate: "2024-03-20T03:05:41.000Z", - ethnicity: "ไทย", - religion: "-", - telephoneNumber: "0639195701", - genderId: "74ec022c-b961-47f4-985e-2d9cbb10984c", - relationshipId: "5872f993-6dc3-44c7-85d3-f56825abd96d", - bloodGroupId: "fab11ded-8177-4e23-a791-78a10bc92333", - profileId: null, - profileInformationId: "42deba79-0725-403f-898d-6c142b2842a5", - }, - ], - }) - public async getProfileInformationHistory(@Path() informationId: string) { - const record = await this.profileInformationHistoryRepo.find({ - relations: { - bloodGroup: true, - relationship: true, - gender: true, - }, - where: { - profileInformationId: informationId, - }, - }); - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); - } - return new HttpSuccess(record); - } - - @Post() - public async newProfileInformation( - @Request() req: RequestWithUser, - @Body() body: CreateProfileInformation, - ) { - if (!body.profileId) { - throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); - } - - const profile = await this.profileRepo.findOneBy({ id: body.profileId }); - if (!profile) { - throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); - } - - const data = new ProfileInformation(); - const meta = { - createdUserId: req.user.sub, - createdFullName: req.user.name, - lastUpdateUserId: req.user.sub, - lastUpdateFullName: req.user.name, - }; - - Object.assign(data, { ...body, ...meta }); - - await this.profileInformationRepo.save(data); - - return new HttpSuccess(); - } - - @Patch("{informationId}") - public async editProfileInformation( - @Body() requestBody: UpdateProfileInformation, - @Request() req: RequestWithUser, - @Path() informationId: string, - ) { - const record = await this.profileInformationRepo.findOneBy({ id: informationId }); - if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); - - const history = new ProfileInformationHistory(); - - console.log(requestBody); - - Object.assign(history, { ...record, id: undefined }); - Object.assign(record, requestBody); - - history.profileInformationId = informationId; - history.lastUpdateFullName = req.user.name; - history.createdUserId = req.user.sub; - history.lastUpdateUserId = req.user.sub; - record.lastUpdateFullName = req.user.name; - - await Promise.all([ - this.profileInformationRepo.save(record), - this.profileInformationHistoryRepo.save(history), - ]); - - return new HttpSuccess(); - } - - @Delete("{informationId}") - public async deleteProfileInformation(@Path() informationId: string) { - await this.profileInformationHistoryRepo.delete({ - profileInformationId: informationId, - }); - - const result = await this.profileInformationRepo.delete({ id: informationId }); - - if (result.affected && result.affected <= 0) - throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); - - return new HttpSuccess(); - } -} From ed7b15ebbe5dcd221a4cd5894a5d75915cc025cd Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:40:25 +0700 Subject: [PATCH 3/7] fix: when no keyword, list cannot be found --- src/controllers/ProfileController.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 2c8f4463..6733096d 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -186,7 +186,7 @@ export class ProfileController extends Controller { async listProfile( @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, - @Query("keyword") keyword?: string, + @Query("keyword") keyword: string = "", ) { const [record, total] = await this.profileRepo.findAndCount({ relations: { @@ -196,13 +196,15 @@ export class ProfileController extends Controller { relationship: true, bloodGroup: true, }, - where: { - citizenId: Like(`%${keyword}%`), - position: Like(`%${keyword}%`), - prefix: Like(`%${keyword}%`), - firstName: Like(`%${keyword}%`), - lastName: Like(`%${keyword}%`), - }, + where: [ + { citizenId: Like(`%${keyword}%`) }, + { position: Like(`%${keyword}%`) }, + { prefix: Like(`%${keyword}%`) }, + { firstName: Like(`%${keyword}%`) }, + { lastName: Like(`%${keyword}%`) }, + { email: Like(`%${keyword}%`) }, + { telephoneNumber: Like(`%${keyword}%`) }, + ], order: { createdAt: "ASC" }, skip: (page - 1) * pageSize, take: pageSize, From 4b61617123edfec6770e2f29d5e5d2a7405a6a38 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:41:18 +0700 Subject: [PATCH 4/7] refactor: shorten var name --- src/controllers/ProfileEmployeeController.ts | 74 ++++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index 6b7e2bbb..6727ba09 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -35,11 +35,11 @@ import { EmployeePosType } from "../entities/EmployeePosType"; ) @SuccessResponse(HttpStatusCode.OK, "สำเร็จ") export class ProfileEmployeeController extends Controller { - private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); - private posMasterRepository = AppDataSource.getRepository(EmployeePosMaster); - private profileRepository = AppDataSource.getRepository(ProfileEmployee); - private posLevelRepository = AppDataSource.getRepository(EmployeePosLevel); - private posTypeRepository = AppDataSource.getRepository(EmployeePosType); + private orgRevisionRepo = AppDataSource.getRepository(OrgRevision); + private posMasterRepo = AppDataSource.getRepository(EmployeePosMaster); + private profileRepo = AppDataSource.getRepository(ProfileEmployee); + private posLevelRepo = AppDataSource.getRepository(EmployeePosLevel); + private posTypeRepo = AppDataSource.getRepository(EmployeePosType); /** * API สร้างทะเบียนประวัติ @@ -53,7 +53,7 @@ export class ProfileEmployeeController extends Controller { requestBody: CreateProfileEmployee, @Request() request: { user: Record }, ) { - const _profile = await this.profileRepository.findOne({ + const _profile = await this.profileRepo.findOne({ where: { citizenId: requestBody.citizenId }, }); if (_profile) { @@ -66,7 +66,7 @@ export class ProfileEmployeeController extends Controller { requestBody.posLevelId = null; } if (requestBody.posLevelId) { - const checkPosLevel = await this.posLevelRepository.findOne({ + const checkPosLevel = await this.posLevelRepo.findOne({ where: { id: requestBody.posLevelId }, }); if (!checkPosLevel) { @@ -78,7 +78,7 @@ export class ProfileEmployeeController extends Controller { requestBody.posTypeId = null; } if (requestBody.posTypeId) { - const checkPosType = await this.posTypeRepository.findOne({ + const checkPosType = await this.posTypeRepo.findOne({ where: { id: requestBody.posTypeId }, }); if (!checkPosType) { @@ -86,7 +86,7 @@ export class ProfileEmployeeController extends Controller { } } - const checkCitizenId = await this.profileRepository.findOne({ + const checkCitizenId = await this.profileRepo.findOne({ where: { citizenId: requestBody.citizenId }, }); @@ -99,7 +99,7 @@ export class ProfileEmployeeController extends Controller { profile.createdFullName = request.user.name; profile.lastUpdateUserId = request.user.sub; profile.lastUpdateFullName = request.user.name; - await this.profileRepository.save(profile); + await this.profileRepo.save(profile); return new HttpSuccess(); } @@ -117,12 +117,12 @@ export class ProfileEmployeeController extends Controller { requestBody: CreateProfileEmployee, @Request() request: { user: Record }, ) { - const profile = await this.profileRepository.findOne({ where: { id: id } }); + const profile = await this.profileRepo.findOne({ where: { id: id } }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); } - const _profile = await this.profileRepository.findOne({ + const _profile = await this.profileRepo.findOne({ where: { id: Not(id), citizenId: requestBody.citizenId }, }); if (_profile) { @@ -136,7 +136,7 @@ export class ProfileEmployeeController extends Controller { requestBody.posLevelId = null; } if (requestBody.posLevelId) { - const checkPosLevel = await this.posLevelRepository.findOne({ + const checkPosLevel = await this.posLevelRepo.findOne({ where: { id: requestBody.posLevelId }, }); if (!checkPosLevel) { @@ -148,7 +148,7 @@ export class ProfileEmployeeController extends Controller { requestBody.posTypeId = null; } if (requestBody.posTypeId) { - const checkPosType = await this.posTypeRepository.findOne({ + const checkPosType = await this.posTypeRepo.findOne({ where: { id: requestBody.posTypeId }, }); if (!checkPosType) { @@ -156,7 +156,7 @@ export class ProfileEmployeeController extends Controller { } } - const checkCitizenId = await this.profileRepository.findOne({ + const checkCitizenId = await this.profileRepo.findOne({ where: { id: Not(id), citizenId: requestBody.citizenId, @@ -169,8 +169,8 @@ export class ProfileEmployeeController extends Controller { profile.lastUpdateUserId = request.user.sub; profile.lastUpdateFullName = request.user.name; - this.profileRepository.merge(profile, requestBody); - await this.profileRepository.save(profile); + this.profileRepo.merge(profile, requestBody); + await this.profileRepo.save(profile); return new HttpSuccess(); } @@ -183,13 +183,13 @@ export class ProfileEmployeeController extends Controller { */ @Delete("{id}") async deleteProfile(@Path() id: string) { - const delProfile = await this.profileRepository.findOne({ + const delProfile = await this.profileRepo.findOne({ where: { id }, }); if (!delProfile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); } - await this.profileRepository.delete({ id: id }); + await this.profileRepo.delete({ id: id }); return new HttpSuccess(); } @@ -202,7 +202,7 @@ export class ProfileEmployeeController extends Controller { */ @Get("{id}") async detailProfile(@Path() id: string) { - const profile = await this.profileRepository.findOne({ + const profile = await this.profileRepo.findOne({ where: { id }, select: [ "id", @@ -233,7 +233,7 @@ export class ProfileEmployeeController extends Controller { @Query("pageSize") pageSize: number = 10, @Query("keyword") keyword?: string, ) { - const [profile, total] = await this.profileRepository.findAndCount({ + const [profile, total] = await this.profileRepo.findAndCount({ select: [ "id", "prefix", @@ -302,7 +302,7 @@ export class ProfileEmployeeController extends Controller { keyword?: string; }, ) { - const orgRevision = await this.orgRevisionRepository.findOne({ + const orgRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsDraft: true, orgRevisionIsCurrent: false, @@ -312,7 +312,7 @@ export class ProfileEmployeeController extends Controller { if (!orgRevision) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); } - const [profiles, total] = await this.profileRepository + const [profiles, total] = await this.profileRepo .createQueryBuilder("profileEmployee") .leftJoinAndSelect("profileEmployee.next_holders", "next_holders") .leftJoinAndSelect("profileEmployee.posLevel", "posLevel") @@ -412,7 +412,7 @@ export class ProfileEmployeeController extends Controller { */ @Get("keycloak/position") async getProfileByKeycloak(@Request() request: { user: Record }) { - const profile = await this.profileRepository.findOne({ + const profile = await this.profileRepo.findOne({ where: { keycloak: request.user.sub }, relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], }); @@ -420,7 +420,7 @@ export class ProfileEmployeeController extends Controller { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } - const orgRevisionPublish = await this.orgRevisionRepository + const orgRevisionPublish = await this.orgRevisionRepo .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = false") .andWhere("orgRevision.orgRevisionIsCurrent = true") @@ -533,28 +533,28 @@ export class ProfileEmployeeController extends Controller { let findProfile: any; switch (body.fieldName) { case "idcard": - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ where: { citizenId: Like(`%${body.keyword}%`) }, relations: ["posType", "posLevel"], }); break; case "firstname": - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ where: { firstName: Like(`%${body.keyword}%`) }, relations: ["posType", "posLevel"], }); break; case "lastname": - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ where: { lastName: Like(`%${body.keyword}%`) }, relations: ["posType", "posLevel"], }); break; default: - findProfile = await this.profileRepository.find({ + findProfile = await this.profileRepo.find({ relations: ["posType", "posLevel"], }); break; @@ -593,17 +593,17 @@ export class ProfileEmployeeController extends Controller { let commanderFullname_: any = {}; let commanderPosition_: any = {}; - const findProfile = await this.profileRepository.findOne({ + const findProfile = await this.profileRepo.findOne({ where: { keycloak: request.user.sub }, }); - const findRevision = await this.orgRevisionRepository.findOne({ + const findRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true, }, }); - const findPosMaster = await this.posMasterRepository.findOne({ + const findPosMaster = await this.posMasterRepo.findOne({ where: { current_holderId: findProfile?.id, orgRevisionId: findRevision?.id, @@ -632,7 +632,7 @@ export class ProfileEmployeeController extends Controller { condition = { orgRootId: childId, orgChild1Id: IsNull() }; } - const findCmd = await this.posMasterRepository.findOne({ + const findCmd = await this.posMasterRepo.findOne({ where: { current_holderId: Not(IsNull()) || Not(""), orgRevisionId: findRevision?.id, @@ -775,7 +775,7 @@ export class ProfileEmployeeController extends Controller { @Body() requestBody: { citizenId: string }, ) { - const profile = await this.profileRepository.findOne({ + const profile = await this.profileRepo.findOne({ where: { id: Not(id), citizenId: requestBody.citizenId }, }); if (profile) { @@ -822,7 +822,7 @@ export class ProfileEmployeeController extends Controller { .take(body.pageSize) .getManyAndCount(); - const orgRevisionActive = await this.orgRevisionRepository.findOne({ + const orgRevisionActive = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, }); @@ -912,7 +912,7 @@ export class ProfileEmployeeController extends Controller { period: string; }, ) { - const findRevision = await this.orgRevisionRepository.findOne({ + const findRevision = await this.orgRevisionRepo.findOne({ where: { orgRevisionIsCurrent: true }, }); if (!findRevision) { @@ -1114,7 +1114,7 @@ export class ProfileEmployeeController extends Controller { @Path() revisionId: string, @Request() request: { user: Record }, ) { - const profile = await this.profileRepository.findOne({ + const profile = await this.profileRepo.findOne({ where: { keycloak: request.user.sub }, relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], }); From 3c21e5351a95fc1a1bd2c30869e273e1c382dc52 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:28:02 +0700 Subject: [PATCH 5/7] feat: profile employee with more info --- src/entities/BloodGroup.ts | 4 + src/entities/Gender.ts | 4 + src/entities/ProfileEmployee.ts | 206 ++++++++++++++++++-------------- src/entities/Relationship.ts | 4 + 4 files changed, 126 insertions(+), 92 deletions(-) diff --git a/src/entities/BloodGroup.ts b/src/entities/BloodGroup.ts index 1c4fcc9d..ad2fb4de 100644 --- a/src/entities/BloodGroup.ts +++ b/src/entities/BloodGroup.ts @@ -1,6 +1,7 @@ import { Entity, Column, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; import { Profile } from "./Profile"; +import { ProfileEmployee } from "./ProfileEmployee"; @Entity("bloodGroup") export class BloodGroup extends EntityBase { @@ -14,6 +15,9 @@ export class BloodGroup extends EntityBase { @OneToMany(() => Profile, (v) => v.bloodGroup) profile: Profile[]; + + @OneToMany(() => Profile, (v) => v.bloodGroup) + profileEmployee: ProfileEmployee[]; } export class CreateBloodGroup { diff --git a/src/entities/Gender.ts b/src/entities/Gender.ts index 960ff541..834818a4 100644 --- a/src/entities/Gender.ts +++ b/src/entities/Gender.ts @@ -1,6 +1,7 @@ import { Entity, Column, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; import { Profile } from "./Profile"; +import { ProfileEmployee } from "./ProfileEmployee"; @Entity("gender") export class Gender extends EntityBase { @@ -14,6 +15,9 @@ export class Gender extends EntityBase { @OneToMany(() => Profile, (v) => v.gender) profile: Profile[]; + + @OneToMany(() => ProfileEmployee, (v) => v.gender) + profileEmployee: ProfileEmployee[]; } export class CreateGender { diff --git a/src/entities/ProfileEmployee.ts b/src/entities/ProfileEmployee.ts index aa15bbe9..1dd89307 100644 --- a/src/entities/ProfileEmployee.ts +++ b/src/entities/ProfileEmployee.ts @@ -1,26 +1,13 @@ -import { Entity, Column, OneToMany, OneToOne, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { Entity, Column, OneToMany, ManyToOne } from "typeorm"; import { EntityBase } from "./base/Base"; -import { PosMaster } from "./PosMaster"; -import { PosLevel } from "./PosLevel"; -import { PosType } from "./PosType"; -import { ProfileSalary } from "./ProfileSalary"; -import { ProfileDiscipline } from "./ProfileDiscipline"; -import { ProfileCertificate } from "./ProfileCertificate"; -import { ProfileEducation } from "./ProfileEducation"; -import { ProfileTraining } from "./ProfileTraining"; -import { ProfileInsignia } from "./ProfileInsignia"; -import { ProfileHonor } from "./ProfileHonor"; -import { ProfileAssessment } from "./ProfileAssessment"; -import { ProfileLeave } from "./ProfileLeave"; -import { ProfileAbility } from "./ProfileAbility"; -import { ProfileDuty } from "./ProfileDuty"; -import { ProfileNopaid } from "./ProfileNopaid"; -import { ProfileOther } from "./ProfileOther"; import { EmployeePosLevel } from "./EmployeePosLevel"; import { EmployeePosType } from "./EmployeePosType"; import { EmployeePosMaster } from "./EmployeePosMaster"; import { ProfileSalaryEmployee } from "./ProfileSalaryEmployee"; import { ProfileDisciplineEmployee } from "./ProfileDisciplineEmployee"; +import { BloodGroup } from "./BloodGroup"; +import { Relationship } from "./Relationship"; +import { Gender } from "./Gender"; @Entity("profileEmployee") export class ProfileEmployee extends EntityBase { @@ -92,25 +79,6 @@ export class ProfileEmployee extends EntityBase { }) phone: string; - // @Column({ - // nullable: true, - // length: 40, - // comment: - // "คนครองปัจจุบัน เมื่อทำสำเนาโครงสร้างและตำแหน่งพร้อมกับคนครองมา คนครองจะอยู่ในฟิลด์นี้", - // default: null, - // unique: false, - // }) - // current_holderId: string; - - // @Column({ - // nullable: true, - // length: 40, - // comment: - // "คนที่กำลังจะมาครอง ตอนปรับโครงสร้าง ถ้าเลือกให้ใครมาครอง ProfileId ของคนนั้นจะมาอยู่ในช่องนี้ รวมทั้งตอนเลือกตำแหน่งเพื่อบรรจุ แต่งตั้ง เลื่อน ย้าย ในระบบบรรจุแต่งตั้งด้วย", - // default: null, - // unique: false, - // }) - // next_holderId: string; @Column({ nullable: true, comment: "id keycloak", @@ -149,81 +117,135 @@ export class ProfileEmployee extends EntityBase { }) salaryLevel: number | null; - @OneToMany(() => EmployeePosMaster, (posMaster) => posMaster.current_holder) + @Column({ + nullable: true, + comment: "เชื้อชาติ", + length: 255, + default: null, + }) + ethnicity: string; + + @Column({ + nullable: true, + comment: "ศาสนา", + length: 255, + default: null, + }) + religion: string; + + @Column({ + nullable: true, + comment: "เบอร์โทร", + length: 255, + default: null, + }) + telephoneNumber: string; + + @Column({ + nullable: true, + comment: "เพศ", + length: 40, + default: null, + }) + genderId: string; + + @ManyToOne(() => Gender, (v) => v.profileEmployee) + gender: Gender; + + @Column({ + nullable: true, + comment: "ความสัมพันธ์", + length: 40, + default: null, + }) + relationshipId: string; + + @ManyToOne(() => Relationship, (v) => v.profileEmployee) + relationship: Relationship; + + @Column({ + nullable: true, + comment: "กรุ๊ปเลือด", + length: 40, + default: null, + }) + bloodGroupId: string; + + @ManyToOne(() => BloodGroup, (v) => v.profileEmployee) + bloodGroup: BloodGroup; + + @OneToMany(() => EmployeePosMaster, (v) => v.current_holder) current_holders: EmployeePosMaster[]; - @OneToMany(() => EmployeePosMaster, (posMaster) => posMaster.next_holder) + @OneToMany(() => EmployeePosMaster, (v) => v.next_holder) next_holders: EmployeePosMaster[]; - @OneToMany(() => ProfileSalaryEmployee, (profileSalary) => profileSalary.profile) + @OneToMany(() => ProfileSalaryEmployee, (v) => v.profile) profileSalary: ProfileSalaryEmployee[]; - @OneToMany(() => ProfileDisciplineEmployee, (profileDiscipline) => profileDiscipline.profile) + @OneToMany(() => ProfileDisciplineEmployee, (v) => v.profile) profileDiscipline: ProfileDisciplineEmployee[]; - // @OneToMany(() => ProfileCertificate, (profileCertificate) => profileCertificate.profile) - // profileCertificates: ProfileCertificate[]; - - // @OneToMany(() => ProfileEducation, (profileEducation) => profileEducation.profile) - // profileEducations: ProfileEducation[]; - - // @OneToMany(() => ProfileTraining, (profileTraining) => profileTraining.profile) - // profileTrainings: ProfileTraining[]; - - // @OneToMany(() => ProfileInsignia, (profileInsignia) => profileInsignia.profile) - // profileInsignias: ProfileInsignia[]; - - // @OneToMany(() => ProfileHonor, (profileHonor) => profileHonor.profile) - // profileHonors: ProfileHonor[]; - - // @OneToMany(() => ProfileAssessment, (profileAssessment) => profileAssessment.profile) - // profileAssessments: ProfileAssessment[]; - - // @OneToMany(() => ProfileLeave, (profileLeave) => profileLeave.profile) - // profileLeaves: ProfileLeave[]; - - // @OneToMany(() => ProfileAbility, (profileAbility) => profileAbility.profile) - // profileAbilities: ProfileAbility[]; - - // @OneToMany(() => ProfileDuty, (profileDuty) => profileDuty.profile) - // profileDutys: ProfileDuty[]; - - // @OneToMany(() => ProfileNopaid, (profileNopaid) => profileNopaid.profile) - // profileNopaids: ProfileNopaid[]; - - // @OneToMany(() => ProfileOther, (profileOther) => profileOther.profile) - // profileOthers: ProfileOther[]; - - @ManyToOne(() => EmployeePosLevel, (posLevel) => posLevel.profiles) - @JoinColumn({ name: "posLevelId" }) + @ManyToOne(() => EmployeePosLevel, (v) => v.profiles) posLevel: EmployeePosLevel; - @ManyToOne(() => EmployeePosType, (posType) => posType.profiles) - @JoinColumn({ name: "posTypeId" }) + @ManyToOne(() => EmployeePosType, (v) => v.profiles) posType: EmployeePosType; + + @OneToMany(() => ProfileEmployeeHistory, (v) => v.profileEmployee) + histories: ProfileEmployeeHistory[]; +} + +@Entity("profileEmployeeHistory") +export class ProfileEmployeeHistory extends ProfileEmployee { + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง ProfileInformation", + default: null, + }) + profileEmployeeId: string; + + @ManyToOne(() => ProfileEmployee, (v) => v.histories, { onDelete: "CASCADE" }) + profileEmployee: ProfileEmployee; } export class CreateProfileEmployee { - @Column() prefix: string; - - @Column() firstName: string; - - @Column() lastName: string; - - @Column() - citizenId: string; - - @Column() position: string; - - @Column("uuid") + isProbation: boolean | null; + dateRetire: Date | null; + birthDate: Date | null; + salaryLevel: number | null; + ethnicity: string | null; + religion: string | null; + telephoneNumber: string | null; + citizenId: string; posLevelId: string | null; - - @Column("uuid") posTypeId: string | null; + genderId: string | null; + relationshipId: string | null; + bloodGroupId: string | null; } -export type UpdateProfileEmployee = Partial; +export type UpdateProfileEmployee = { + prefix?: string | null; + firstName?: string | null; + lastName?: string | null; + position?: string | null; + isProbation?: boolean | null; + dateRetire?: Date | null; + birthDate?: Date | null; + salaryLevel?: number | null; + ethnicity?: string | null; + religion?: string | null; + telephoneNumber?: string | null; + citizenId?: string; + posLevelId?: string | null; + posTypeId?: string | null; + genderId?: string | null; + relationshipId?: string | null; + bloodGroupId?: string | null; +}; diff --git a/src/entities/Relationship.ts b/src/entities/Relationship.ts index 7e84710f..d95bf7ac 100644 --- a/src/entities/Relationship.ts +++ b/src/entities/Relationship.ts @@ -2,6 +2,7 @@ import { Entity, Column, OneToMany } from "typeorm"; import { EntityBase } from "./base/Base"; import { Profile } from "./Profile"; +import { ProfileEmployee } from "./ProfileEmployee"; @Entity("relationship") export class Relationship extends EntityBase { @@ -15,6 +16,9 @@ export class Relationship extends EntityBase { @OneToMany(() => Profile, (v) => v.relationship) profile: Profile[]; + + @OneToMany(() => ProfileEmployee, (v) => v.relationship) + profileEmployee: ProfileEmployee[]; } export class CreateRelationship { From 6924017849973306372a3c26c79c12e371252db1 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:28:39 +0700 Subject: [PATCH 6/7] fix: update without pos field always result in null --- src/controllers/ProfileController.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 6733096d..98f15f81 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -58,8 +58,8 @@ export class ProfileController extends Controller { ); } - if (!body.posLevelId) body.posLevelId = null; - if (!body.posTypeId) body.posTypeId = null; + if (body.posLevelId === "") body.posLevelId = null; + if (body.posTypeId === "") body.posTypeId = null; if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); @@ -102,8 +102,8 @@ export class ProfileController extends Controller { throw new HttpError(HttpStatus.CONFLICT, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); } - if (!body.posLevelId) body.posLevelId = null; - if (!body.posTypeId) body.posTypeId = null; + if (body.posLevelId === "") body.posLevelId = null; + if (body.posTypeId === "") body.posTypeId = null; if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); @@ -120,6 +120,7 @@ export class ProfileController extends Controller { await this.profileHistoryRepo.save( Object.assign(new ProfileHistory(), { ...record, + profileId: id, id: undefined, }), ); @@ -176,6 +177,24 @@ export class ProfileController extends Controller { return new HttpSuccess(profile); } + @Get("history/{id}") + async getProfileHistory(@Path() id: string) { + const profile = await this.profileHistoryRepo.find({ + relations: { + posLevel: true, + posType: true, + gender: true, + relationship: true, + bloodGroup: true, + }, + where: { profileId: id }, + }); + + if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + return new HttpSuccess(profile); + } + /** * API รายการทะเบียนประวัติ * From c288da6b3aca5a205f61ffa31f420d75bc9ce4e3 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:29:24 +0700 Subject: [PATCH 7/7] feat: profile employee with information endpoint --- src/controllers/ProfileEmployeeController.ts | 270 ++++++++----------- 1 file changed, 111 insertions(+), 159 deletions(-) diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index 6727ba09..4b8ba5d4 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -16,28 +16,35 @@ import { } from "tsoa"; import { AppDataSource } from "../database/data-source"; import HttpSuccess from "../interfaces/http-success"; -import HttpStatusCode from "../interfaces/http-status"; +import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; import { Brackets, IsNull, Like, Not } from "typeorm"; import { OrgRevision } from "../entities/OrgRevision"; import { calculateRetireDate } from "../interfaces/utils"; import { EmployeePosMaster } from "../entities/EmployeePosMaster"; -import { ProfileEmployee, CreateProfileEmployee } from "../entities/ProfileEmployee"; +import { + ProfileEmployee, + CreateProfileEmployee, + UpdateProfileEmployee, + ProfileEmployeeHistory, +} from "../entities/ProfileEmployee"; import { EmployeePosLevel } from "../entities/EmployeePosLevel"; import { EmployeePosType } from "../entities/EmployeePosType"; +import { RequestWithUser } from "../middlewares/user"; @Route("api/v1/org/profile-employee") @Tags("Profile") @Security("bearerAuth") @Response( - HttpStatusCode.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", ) -@SuccessResponse(HttpStatusCode.OK, "สำเร็จ") +@SuccessResponse(HttpStatus.OK, "สำเร็จ") export class ProfileEmployeeController extends Controller { private orgRevisionRepo = AppDataSource.getRepository(OrgRevision); private posMasterRepo = AppDataSource.getRepository(EmployeePosMaster); private profileRepo = AppDataSource.getRepository(ProfileEmployee); + private profileHistoryRepo = AppDataSource.getRepository(ProfileEmployeeHistory); private posLevelRepo = AppDataSource.getRepository(EmployeePosLevel); private posTypeRepo = AppDataSource.getRepository(EmployeePosType); @@ -48,58 +55,32 @@ export class ProfileEmployeeController extends Controller { * */ @Post() - async createProfile( - @Body() - requestBody: CreateProfileEmployee, - @Request() request: { user: Record }, - ) { - const _profile = await this.profileRepo.findOne({ - where: { citizenId: requestBody.citizenId }, - }); - if (_profile) { + async createProfile(@Body() body: CreateProfileEmployee, @Request() request: RequestWithUser) { + if (await this.profileRepo.findOneBy({ citizenId: body.citizenId })) { throw new HttpError( - HttpStatusCode.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", ); } - if (requestBody.posLevelId == "") { - requestBody.posLevelId = null; - } - if (requestBody.posLevelId) { - const checkPosLevel = await this.posLevelRepo.findOne({ - where: { id: requestBody.posLevelId }, - }); - if (!checkPosLevel) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); - } + + if (body.posLevelId === "") body.posLevelId = null; + if (body.posTypeId === "") body.posTypeId = null; + + if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); } - if (requestBody.posTypeId == "") { - requestBody.posTypeId = null; - } - if (requestBody.posTypeId) { - const checkPosType = await this.posTypeRepo.findOne({ - where: { id: requestBody.posTypeId }, - }); - if (!checkPosType) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); - } + if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); } - const checkCitizenId = await this.profileRepo.findOne({ - where: { citizenId: requestBody.citizenId }, - }); - - if (checkCitizenId) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); - } - - const profile = Object.assign(new ProfileEmployee(), requestBody); + const profile = Object.assign(new ProfileEmployee(), body); profile.createdUserId = request.user.sub; profile.createdFullName = request.user.name; profile.lastUpdateUserId = request.user.sub; profile.lastUpdateFullName = request.user.name; await this.profileRepo.save(profile); + return new HttpSuccess(); } @@ -112,65 +93,49 @@ export class ProfileEmployeeController extends Controller { */ @Put("{id}") async updateProfile( + @Request() request: RequestWithUser, @Path() id: string, - @Body() - requestBody: CreateProfileEmployee, - @Request() request: { user: Record }, + @Body() body: UpdateProfileEmployee, ) { - const profile = await this.profileRepo.findOne({ where: { id: id } }); - if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); + const exists = + !!body.citizenId && + (await this.profileRepo.findOne({ + where: { id: Not(id), citizenId: body.citizenId }, + })); + + if (exists) { + throw new HttpError(HttpStatus.CONFLICT, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); } - const _profile = await this.profileRepo.findOne({ - where: { id: Not(id), citizenId: requestBody.citizenId }, - }); - if (_profile) { - throw new HttpError( - HttpStatusCode.INTERNAL_SERVER_ERROR, - "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", - ); + if (body.posLevelId === "") body.posLevelId = null; + if (body.posTypeId === "") body.posTypeId = null; + + if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); } - if (requestBody.posLevelId == "") { - requestBody.posLevelId = null; - } - if (requestBody.posLevelId) { - const checkPosLevel = await this.posLevelRepo.findOne({ - where: { id: requestBody.posLevelId }, - }); - if (!checkPosLevel) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); - } + if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); } - if (requestBody.posTypeId == "") { - requestBody.posTypeId = null; - } - if (requestBody.posTypeId) { - const checkPosType = await this.posTypeRepo.findOne({ - where: { id: requestBody.posTypeId }, - }); - if (!checkPosType) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); - } - } + const record = await this.profileRepo.findOneBy({ id }); - const checkCitizenId = await this.profileRepo.findOne({ - where: { - id: Not(id), - citizenId: requestBody.citizenId, - }, - }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); - if (checkCitizenId) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว"); - } + await this.profileHistoryRepo.save( + Object.assign(new ProfileEmployeeHistory(), { + ...record, + profileEmployeeId: id, + id: undefined, + }), + ); + + Object.assign(record, body); + record.lastUpdateUserId = request.user.sub; + record.lastUpdateFullName = request.user.name; + + await this.profileRepo.save(record); - profile.lastUpdateUserId = request.user.sub; - profile.lastUpdateFullName = request.user.name; - this.profileRepo.merge(profile, requestBody); - await this.profileRepo.save(profile); return new HttpSuccess(); } @@ -183,13 +148,12 @@ export class ProfileEmployeeController extends Controller { */ @Delete("{id}") async deleteProfile(@Path() id: string) { - const delProfile = await this.profileRepo.findOne({ - where: { id }, - }); - if (!delProfile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); + const result = await this.profileRepo.delete({ id }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); } - await this.profileRepo.delete({ id: id }); + return new HttpSuccess(); } @@ -203,21 +167,18 @@ export class ProfileEmployeeController extends Controller { @Get("{id}") async detailProfile(@Path() id: string) { const profile = await this.profileRepo.findOne({ + relations: { + posLevel: true, + posType: true, + gender: true, + relationship: true, + bloodGroup: true, + }, where: { id }, - select: [ - "id", - "prefix", - "firstName", - "lastName", - "citizenId", - "position", - "posLevelId", - "posTypeId", - ], }); - if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); - } + + if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + return new HttpSuccess(profile); } @@ -231,57 +192,48 @@ export class ProfileEmployeeController extends Controller { async listProfile( @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, - @Query("keyword") keyword?: string, + @Query("keyword") keyword: string = "", ) { - const [profile, total] = await this.profileRepo.findAndCount({ - select: [ - "id", - "prefix", - "firstName", - "lastName", - "citizenId", - "position", - "posLevelId", - "posTypeId", + const [record, total] = await this.profileRepo.findAndCount({ + relations: { + posLevel: true, + posType: true, + gender: true, + relationship: true, + bloodGroup: true, + }, + where: [ + { citizenId: Like(`%${keyword}%`) }, + { position: Like(`%${keyword}%`) }, + { prefix: Like(`%${keyword}%`) }, + { firstName: Like(`%${keyword}%`) }, + { lastName: Like(`%${keyword}%`) }, + { email: Like(`%${keyword}%`) }, + { telephoneNumber: Like(`%${keyword}%`) }, ], order: { createdAt: "ASC" }, skip: (page - 1) * pageSize, take: pageSize, }); - if (keyword != undefined && keyword !== "") { - const formattedKeyword = keyword.toLowerCase().replace(/\s+/g, ""); - const filteredProfile = profile.filter( - (x) => - (x.prefix + x.firstName + x.lastName).replace(/\s+/g, "").includes(formattedKeyword) || - x.citizenId?.toString().includes(keyword) || - x.position?.toString().includes(keyword), - ); + return new HttpSuccess({ data: record, total }); + } - const formattedData = filteredProfile.map((item) => ({ - id: item.id, - prefix: item.prefix, - firstName: item.firstName, - lastName: item.lastName, - citizenId: item.citizenId, - position: item.position, - posLevelId: item.posLevelId, - posTypeId: item.posTypeId, - })); + @Get("history/{id}") + async getProfileHistory(@Path() id: string) { + const profile = await this.profileHistoryRepo.find({ + relations: { + posLevel: true, + posType: true, + gender: true, + relationship: true, + bloodGroup: true, + }, + where: { profileEmployeeId: id }, + }); - return new HttpSuccess({ data: formattedData, total: formattedData.length }); - } + if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); - const formattedData = profile.map((item) => ({ - id: item.id, - prefix: item.prefix, - firstName: item.firstName, - lastName: item.lastName, - citizenId: item.citizenId, - position: item.position, - posLevelId: item.posLevelId, - posTypeId: item.posTypeId, - })); - return new HttpSuccess({ data: formattedData, total }); + return new HttpSuccess(profile); } /** @@ -310,7 +262,7 @@ export class ProfileEmployeeController extends Controller { relations: ["posMasters"], }); if (!orgRevision) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); } const [profiles, total] = await this.profileRepo .createQueryBuilder("profileEmployee") @@ -417,7 +369,7 @@ export class ProfileEmployeeController extends Controller { relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], }); if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } const orgRevisionPublish = await this.orgRevisionRepo @@ -426,7 +378,7 @@ export class ProfileEmployeeController extends Controller { .andWhere("orgRevision.orgRevisionIsCurrent = true") .getOne(); if (!orgRevisionPublish) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง"); } const _profile = { @@ -780,7 +732,7 @@ export class ProfileEmployeeController extends Controller { }); if (profile) { throw new HttpError( - HttpStatusCode.INTERNAL_SERVER_ERROR, + HttpStatus.INTERNAL_SERVER_ERROR, "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว", ); } @@ -916,7 +868,7 @@ export class ProfileEmployeeController extends Controller { where: { orgRevisionIsCurrent: true }, }); if (!findRevision) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. OrgRevision"); + throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision"); } const [findPosMaster, total] = await AppDataSource.getRepository(EmployeePosMaster) @@ -1007,7 +959,7 @@ export class ProfileEmployeeController extends Controller { .take(body.pageSize) .getManyAndCount(); if (!findPosMaster) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. PosMaster"); + throw new HttpError(HttpStatus.NOT_FOUND, "not found. PosMaster"); } const formattedData = findPosMaster.map((item) => { @@ -1119,7 +1071,7 @@ export class ProfileEmployeeController extends Controller { relations: ["posLevel", "posType", "current_holders", "current_holders.orgRoot"], }); if (!profile) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } const _profile = {