diff --git a/src/controllers/AuthRoleController.ts b/src/controllers/AuthRoleController.ts index 0c83d910..3f222267 100644 --- a/src/controllers/AuthRoleController.ts +++ b/src/controllers/AuthRoleController.ts @@ -27,7 +27,9 @@ import { EmployeePosMaster } from "../entities/EmployeePosMaster"; @Security("bearerAuth") export class AuthRoleController extends Controller { private authRoleRepo = AppDataSource.getRepository(AuthRole); - private authRoleAttrRepo = AppDataSource.getRepository(AuthRoleAttr); + private authRoleAttrRepo = AppDataSource.getRepository(AuthRoleAttr); + private posMasterRepository = AppDataSource.getRepository(PosMaster); + private employeePosMasterRepository = AppDataSource.getRepository(EmployeePosMaster) @Get("list") public async listAuthRole() { @@ -74,9 +76,33 @@ export class AuthRoleController extends Controller { return new HttpSuccess(data.id); } - @Post("assign") - public async AddAuthRole(@Request() req: RequestWithUser, @Body() body: CreateAddAuthRole) { - // console pasMater = await this + @Post("govoment") + public async AddAuthRoleGovoment(@Request() req: RequestWithUser, @Body() body: CreateAddAuthRole) { + const getDetail = await this.authRoleRepo.findOneBy({ id: body.authRoleId }); + if (!getDetail) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์"); + + const posMaster = await this.posMasterRepository.findOneBy({ id : body.posMasterId }) + if (!posMaster) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลตำแหน่ง"); + + posMaster.lastUpdateUserId = req.user.sub; + posMaster.lastUpdateFullName = req.user.name; + posMaster.authRoleId = body.authRoleId + await this.posMasterRepository.save(posMaster); + return new HttpSuccess(); + } + + @Post("employee") + public async AddAuthRoleEmployee(@Request() req: RequestWithUser, @Body() body: CreateAddAuthRole) { + const getDetail = await this.authRoleRepo.findOneBy({ id: body.authRoleId }); + if (!getDetail) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์"); + + const posMaster = await this.employeePosMasterRepository.findOneBy({ id : body.posMasterId }) + if (!posMaster) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลตำแหน่ง"); + + posMaster.lastUpdateUserId = req.user.sub; + posMaster.lastUpdateFullName = req.user.name; + posMaster.authRoleId = body.authRoleId + await this.employeePosMasterRepository.save(posMaster); return new HttpSuccess(); } diff --git a/src/controllers/ChangePositionController.ts b/src/controllers/ChangePositionController.ts index 9cffa825..3e224b28 100644 --- a/src/controllers/ChangePositionController.ts +++ b/src/controllers/ChangePositionController.ts @@ -165,8 +165,8 @@ export class ChangePositionController extends Controller { .createQueryBuilder("changePosition") .leftJoinAndSelect("changePosition.profileChangePosition", "profileChangePosition") .where( - searchKeyword ? - "changePosition.name LIKE :keyword OR changePosition.date LIKE :keyword OR changePosition.status LIKE :keyword" + searchKeyword + ? "changePosition.name LIKE :keyword OR changePosition.date LIKE :keyword OR changePosition.status LIKE :keyword" : "1=1", { keyword: `%${searchKeyword}%` } ) @@ -262,33 +262,68 @@ export class ChangePositionController extends Controller { @Query() searchKeyword: string = "", ) { - const findData = await this.profileChangePositionRepository.find({ - where: { changePositionId: changePositionId } - }); - if (!findData) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรอบย้ายสับเปลี่ยนตำแหน่ง"); - const [profileChangePosition, total] = await AppDataSource.getRepository(ProfileChangePosition) .createQueryBuilder("profileChangePosition") - .where("profileChangePosition.changePositionId LIKE :id", { id: changePositionId }) + .where({ changePositionId: changePositionId }) .andWhere( - searchKeyword ? - "CONCAT(profileChangePosition.prefix, profileChangePosition.firstName, ' ', profileChangePosition.lastName) LIKE :keyword" - : "1=1", - { - keyword: `%${searchKeyword}%`, - }, - ) - .andWhere( - searchKeyword ? - "profileChangePosition.citizenId LIKE :keyword OR profileChangePosition.status LIKE :keyword" - : "1=1", - { keyword: `%${searchKeyword}%` } - ) - .andWhere( - searchKeyword ? - "profileChangePosition.birthDate LIKE :keyword OR profileChangePosition.lastUpdatedAt LIKE :keyword" - : "1=1", - { keyword: `%${searchKeyword}%` } + new Brackets((qb) => { + qb.where( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? "profileChangePosition.prefix LIKE :keyword" + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .orWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? "profileChangePosition.firstName LIKE :keyword" + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .orWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? "profileChangePosition.lastName LIKE :keyword" + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .orWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? "profileChangePosition.citizenId LIKE :keyword" + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .orWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? "profileChangePosition.birthDate LIKE :keyword" + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .orWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? "profileChangePosition.lastUpdatedAt LIKE :keyword" + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + .orWhere( + searchKeyword != undefined && searchKeyword != null && searchKeyword != "" + ? "profileChangePosition.status LIKE :keyword" + : "1=1", + { + keyword: `%${searchKeyword}%`, + }, + ) + }), ) .orderBy("profileChangePosition.createdAt", "ASC") .skip((page - 1) * pageSize) diff --git a/src/controllers/ProfileChangeNameController.ts b/src/controllers/ProfileChangeNameController.ts index a120052b..c9ca7158 100644 --- a/src/controllers/ProfileChangeNameController.ts +++ b/src/controllers/ProfileChangeNameController.ts @@ -24,6 +24,8 @@ import { ProfileChangeName, UpdateProfileChangeName, } from "../entities/ProfileChangeName"; +import CallAPI from "../interfaces/call-api"; +import { updateName } from "../keycloak"; @Route("api/v1/org/profile/changeName") @Tags("ProfileChangeName") @@ -145,6 +147,16 @@ export class ProfileChangeNameController extends Controller { profile.prefix = body.prefix ?? profile.prefix; await this.profileRepository.save(profile); + // if (profile != null) { + // const result = await updateName(profile.id, profile.firstName, profile.lastName,req); + + // const _mapData = { + // data: mappedData, + // total: total, + // }; + + // } + return new HttpSuccess(data.id); } diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 3ceb2734..92e48350 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -1934,6 +1934,8 @@ export class ProfileController extends Controller { */ @Post("search-personal") async getProfileBySearchKeyword( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, @Body() body: { fieldName: string; @@ -1941,9 +1943,12 @@ export class ProfileController extends Controller { }, ) { let findProfile: any; + let total: any; + const skip = (page - 1) * pageSize; + const take = pageSize; switch (body.fieldName) { - case "idcard": - findProfile = await this.profileRepo.find({ + case "citizenId": + [findProfile, total] = await this.profileRepo.find({ where: { citizenId: Like(`%${body.keyword}%`) }, relations: [ "posType", @@ -1956,11 +1961,13 @@ export class ProfileController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; case "firstname": - findProfile = await this.profileRepo.find({ + [findProfile, total] = await this.profileRepo.find({ where: { firstName: Like(`%${body.keyword}%`) }, relations: [ "posType", @@ -1973,11 +1980,13 @@ export class ProfileController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; case "lastname": - findProfile = await this.profileRepo.find({ + [findProfile, total] = await this.profileRepo.find({ where: { lastName: Like(`%${body.keyword}%`) }, relations: [ "posType", @@ -1990,11 +1999,13 @@ export class ProfileController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; default: - findProfile = await this.profileRepo.find({ + [findProfile, total] = await this.profileRepo.find({ relations: [ "posType", "posLevel", @@ -2006,6 +2017,8 @@ export class ProfileController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; } @@ -2095,7 +2108,7 @@ export class ProfileController extends Controller { firstName: item.firstName, lastName: item.lastName, position: item.position, - idcard: item.citizenId, + citizenId: item.citizenId, email: item.email, phone: item.phone, name: fullName, @@ -2127,7 +2140,10 @@ export class ProfileController extends Controller { posTypeName: item.posType?.posTypeName, posLevelId: item.posLevelId, posLevelName: item.posLevel?.posLevelName, - educationDegree: latestProfileEducation != null && latestProfileEducation.educationLevel != null ? latestProfileEducation.educationLevel : null, + educationDegree: + latestProfileEducation != null && latestProfileEducation.educationLevel != null + ? latestProfileEducation.educationLevel + : null, // ? { // id: latestProfileEducation.id, // degree: latestProfileEducation.degree, @@ -2154,7 +2170,7 @@ export class ProfileController extends Controller { }), ); - return new HttpSuccess(mapDataProfile); + return new HttpSuccess({ data: mapDataProfile, total }); } /** @@ -3122,4 +3138,171 @@ export class ProfileController extends Controller { await this.profileRepo.save(profile); return new HttpSuccess(); } + + /** + * API ค้นหาข้อมูลทะเบียนประวัติที่ยังไม่เชื่อม keycloak + * + * @summary ค้นหาข้อมูลทะเบียนประวัติที่ยังไม่เชื่อม keycloak + * + */ + @Post("search-personal-no-keycloak") + async getProfileBySearchKeywordNoKeyCloak( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, + @Body() + body: { + fieldName: string; + keyword?: string; + }, + ) { + let findProfile: any; + let total: any; + const skip = (page - 1) * pageSize; + const take = pageSize; + switch (body.fieldName) { + case "citizenId": + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + citizenId: Like(`%${body.keyword}%`), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalary"], + skip, + take, + }); + break; + + case "firstname": + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + firstName: Like(`%${body.keyword}%`), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalary"], + skip, + take, + }); + break; + + case "lastname": + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + lastName: Like(`%${body.keyword}%`), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalary"], + skip, + take, + }); + break; + + default: + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalary"], + skip, + take, + }); + break; + } + + const findRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true }, + }); + if (!findRevision) { + throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision"); + } + + const mapDataProfile = await Promise.all( + findProfile.map(async (item: Profile) => { + const fullName = `${item.prefix} ${item.firstName} ${item.lastName}`; + const shortName = + item.current_holders.length == 0 + ? null + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != + null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != + null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild2 != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild1 != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != + null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgRoot != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : null; + + const root = + item.current_holders.length == 0 || + (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) + ? null + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; + + let salary: any = ""; + if (item != null && item.profileSalary != null && item.profileSalary.length > 0) { + let _salary: any = item.profileSalary.sort( + (a, b) => + (b.date == null ? 0 : b.date.getTime()) - (a.date == null ? 0 : a.date.getTime()), + ); + if (_salary.length > 0) { + salary = _salary[0]; + } + } + + const posMasterNo = item.current_holders?.find( + (x) => x.orgRevisionId == findRevision.id, + )?.posMasterNo; + + const latestProfileEducation = await this.profileEducationRepository.findOne({ + where: { profileId: item.id }, + order: { endDate: "DESC" }, + }); + + return { + id: item.id, + prefix: item.prefix, + rank: item.rank, + firstName: item.firstName, + lastName: item.lastName, + position: item.position, + citizenId: item.citizenId, + email: item.email, + phone: item.phone, + name: fullName, + birthDate: item.birthDate, + positionLevel: item.posLevelId, + positionLevelName: item.posLevel?.posLevelName, + positionType: item.posTypeId, + positionTypeName: item.posType?.posTypeName, + posNo: shortName, + organization: root == null ? null : root.orgRootShortName, + salary: salary == "" ? "" : salary.amount, + posMasterNo: posMasterNo ?? null, + posTypeId: item.posTypeId, + posTypeName: item.posType?.posTypeName, + posLevelId: item.posLevelId, + posLevelName: item.posLevel?.posLevelName, + educationDegree: + latestProfileEducation != null && latestProfileEducation.educationLevel != null + ? latestProfileEducation.educationLevel + : null, + }; + }), + ); + + return new HttpSuccess({ data: mapDataProfile, total }); + } } diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index def15132..338f65c6 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -1356,6 +1356,8 @@ export class ProfileEmployeeController extends Controller { */ @Post("search-personal") async getProfileBySearchKeyword( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, @Body() body: { fieldName: string; @@ -1363,9 +1365,12 @@ export class ProfileEmployeeController extends Controller { }, ) { let findProfile: any; + let total: any; + const skip = (page - 1) * pageSize; + const take = pageSize; switch (body.fieldName) { - case "idcard": - findProfile = await this.profileRepo.find({ + case "citizenId": + [findProfile, total] = await this.profileRepo.find({ where: { citizenId: Like(`%${body.keyword}%`) }, relations: [ "posType", @@ -1378,11 +1383,13 @@ export class ProfileEmployeeController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; case "firstname": - findProfile = await this.profileRepo.find({ + [findProfile, total] = await this.profileRepo.find({ where: { firstName: Like(`%${body.keyword}%`) }, relations: [ "posType", @@ -1395,11 +1402,13 @@ export class ProfileEmployeeController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; case "lastname": - findProfile = await this.profileRepo.find({ + [findProfile, total] = await this.profileRepo.find({ where: { lastName: Like(`%${body.keyword}%`) }, relations: [ "posType", @@ -1412,11 +1421,13 @@ export class ProfileEmployeeController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; default: - findProfile = await this.profileRepo.find({ + [findProfile, total] = await this.profileRepo.find({ relations: [ "posType", "posLevel", @@ -1428,6 +1439,8 @@ export class ProfileEmployeeController extends Controller { "current_holders.orgChild3", "current_holders.orgChild4", ], + skip, + take, }); break; } @@ -1505,11 +1518,10 @@ export class ProfileEmployeeController extends Controller { (x) => x.orgRevisionId == findRevision.id, )?.posMasterNo; - const latestProfileEducation = await this.profileEducationRepository.findOne({ - where: { profileEmployeeId: item.id }, - order: { endDate: "DESC" }, - }); - + const latestProfileEducation = await this.profileEducationRepository.findOne({ + where: { profileEmployeeId: item.id }, + order: { endDate: "DESC" }, + }); return { id: item.id, @@ -1518,7 +1530,7 @@ export class ProfileEmployeeController extends Controller { firstName: item.firstName, lastName: item.lastName, position: item.position, - idcard: item.citizenId, + citizenId: item.citizenId, email: item.email, phone: item.phone, name: fullName, @@ -1580,7 +1592,7 @@ export class ProfileEmployeeController extends Controller { }), ); - return new HttpSuccess(mapDataProfile); + return new HttpSuccess({ data: mapDataProfile, total }); } /** @@ -2910,4 +2922,171 @@ export class ProfileEmployeeController extends Controller { ); return new HttpSuccess(); } + + /** + * API ค้นหาข้อมูลทะเบียนประวัติที่ยังไม่เชื่อม keycloak + * + * @summary ค้นหาข้อมูลทะเบียนประวัติที่ยังไม่เชื่อม keycloak + * + */ + @Post("search-personal-no-keycloak") + async getProfileBySearchKeywordNoKeyCloak( + @Query("page") page: number = 1, + @Query("pageSize") pageSize: number = 10, + @Body() + body: { + fieldName: string; + keyword?: string; + }, + ) { + let findProfile: any; + let total: any; + const skip = (page - 1) * pageSize; + const take = pageSize; + switch (body.fieldName) { + case "citizenId": + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + citizenId: Like(`%${body.keyword}%`), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalarys"], + skip, + take, + }); + break; + + case "firstname": + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + firstName: Like(`%${body.keyword}%`), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalarys"], + skip, + take, + }); + break; + + case "lastname": + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + lastName: Like(`%${body.keyword}%`), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalarys"], + skip, + take, + }); + break; + + default: + [findProfile, total] = await this.profileRepo.findAndCount({ + where: { + keycloak: IsNull(), + }, + relations: ["posType", "posLevel", "current_holders", "profileSalarys"], + skip, + take, + }); + break; + } + + const findRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true }, + }); + if (!findRevision) { + throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision"); + } + + const mapDataProfile = await Promise.all( + findProfile.map(async (item: ProfileEmployee) => { + const fullName = `${item.prefix} ${item.firstName} ${item.lastName}`; + const shortName = + item.current_holders.length == 0 + ? null + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != + null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != + null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild2 != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild1 != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != + null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgRoot != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : null; + + const root = + item.current_holders.length == 0 || + (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) + ? null + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; + + let salary: any = ""; + if (item != null && item.profileSalarys != null && item.profileSalarys.length > 0) { + let _salary: any = item.profileSalarys.sort( + (a, b) => + (b.date == null ? 0 : b.date.getTime()) - (a.date == null ? 0 : a.date.getTime()), + ); + if (_salary.length > 0) { + salary = _salary[0]; + } + } + + const posMasterNo = item.current_holders?.find( + (x) => x.orgRevisionId == findRevision.id, + )?.posMasterNo; + + const latestProfileEducation = await this.profileEducationRepository.findOne({ + where: { profileEmployeeId: item.id }, + order: { endDate: "DESC" }, + }); + + return { + id: item.id, + prefix: item.prefix, + rank: item.rank, + firstName: item.firstName, + lastName: item.lastName, + position: item.position, + citizenId: item.citizenId, + email: item.email, + phone: item.phone, + name: fullName, + birthDate: item.birthDate, + positionLevel: item.posLevelId, + positionLevelName: item.posLevel?.posLevelName, + positionType: item.posTypeId, + positionTypeName: item.posType?.posTypeName, + posNo: shortName, + organization: root == null ? null : root.orgRootShortName, + salary: salary == "" ? "" : salary.amount, + posMasterNo: posMasterNo ?? null, + posTypeId: item.posTypeId, + posTypeName: item.posType?.posTypeName, + posLevelId: item.posLevelId, + posLevelName: item.posLevel?.posLevelName, + educationDegree: + latestProfileEducation != null && latestProfileEducation.educationLevel != null + ? latestProfileEducation.educationLevel + : null, + }; + }), + ); + + return new HttpSuccess({ data: mapDataProfile, total }); + } } diff --git a/src/controllers/UserController.ts b/src/controllers/UserController.ts index 9e152c41..f496c054 100644 --- a/src/controllers/UserController.ts +++ b/src/controllers/UserController.ts @@ -30,6 +30,10 @@ import { getRoleMappings, getUserCount, } from "../keycloak"; +import { AppDataSource } from "../database/data-source"; +import { Profile } from "../entities/Profile"; +import { ProfileEmployee } from "../entities/ProfileEmployee"; +import { IsNull } from "typeorm"; // import * as io from "../lib/websocket"; // import elasticsearch from "../elasticsearch"; // import { StorageFolder } from "../interfaces/storage-fs"; @@ -38,7 +42,6 @@ import { // if (!process.env.ELASTICSEARCH_INDEX) throw Error("Default ElasticSearch index must be specified."); // const DEFAULT_INDEX = process.env.ELASTICSEARCH_INDEX; - function stripLeadingSlash(str: string) { return str.replace(/^\//, ""); } @@ -47,6 +50,10 @@ function stripLeadingSlash(str: string) { @Tags("Single-Sign On") @Security("bearerAuth") export class KeycloakController extends Controller { + + private profileRepo = AppDataSource.getRepository(Profile); + private profileEmpRepo = AppDataSource.getRepository(ProfileEmployee); + @Get("user/{id}") async getUser(@Path("id") id: string) { const userData = await getUser(id); @@ -80,6 +87,7 @@ export class KeycloakController extends Controller { lastName?: string; email?: string; roles?: string[]; + profileId?: string; }, ) { const userId = await createUser(body.username, body.password, { @@ -133,6 +141,17 @@ export class KeycloakController extends Controller { role: body.roles || [], }; const addRole = await this.addRole(userId, _roles); + + const profile = await this.profileRepo.findOne({ + where: { + id: body.profileId, + }, + }); + + if (profile) { + profile.keycloak = userId; + await this.profileRepo.save(profile); + } return userId; } @@ -166,6 +185,17 @@ export class KeycloakController extends Controller { async deleteUser(@Path() userId: string) { const result = await deleteUser(userId); if (!result) throw new Error("Failed. Cannot delete userId."); + + const profile = await this.profileRepo.findOne({ + where: { + id: userId, + }, + }); + + if (profile) { + profile.keycloak = ""; + await this.profileRepo.save(profile); + } } // @Security("bearerAuth", ["system", "admin"]) diff --git a/src/keycloak/index.ts b/src/keycloak/index.ts index b32eaf6e..240ff947 100644 --- a/src/keycloak/index.ts +++ b/src/keycloak/index.ts @@ -203,6 +203,45 @@ export async function editUser(userId: string, opts: Record) { const id = path?.split("/").at(-1); return id || true; } +/** + * Update keycloak user by uuid + * + * Client must have permission to manage realm's user + * + * @returns user uuid or true if success, false otherwise. + */ +export async function updateName( + userId: string, + firstName: string, + lastName: string, + opts: Record, +) { + const { password, ...rest } = opts; + + const res = await fetch(`${KC_URL}/admin/realms/${KC_REALM}/users/${userId}`, { + // prettier-ignore + headers: { + "authorization": `Bearer ${await getToken()}`, + "content-type": `application/json`, + }, + method: "PUT", + body: JSON.stringify({ + enabled: true, + credentials: (password && [{ type: "password", value: opts?.password }]) || undefined, + ...rest, + }), + }).catch((e) => console.log("Keycloak Error: ", e)); + + if (!res) return false; + if (!res.ok) { + // return Boolean(console.error("Keycloak Error Response: ", await res.json())); + return await res.json(); + } + + const path = res.headers.get("Location"); + const id = path?.split("/").at(-1); + return id || true; +} /** * Delete keycloak user by uuid @@ -588,4 +627,6 @@ export async function removeUserGroup(userId: string, groupId: string) { } return true; + + }