diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index 83413486..79cd5d93 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -18,7 +18,7 @@ import HttpStatus from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; import { RequestWithUser } from "../middlewares/user"; import { Profile } from "../entities/Profile"; -import { Brackets, IsNull, Not } from "typeorm"; +import { Brackets, In, IsNull, Not } from "typeorm"; import { OrgRevision } from "../entities/OrgRevision"; import { OrgRoot } from "../entities/OrgRoot"; import { ProfileEmployee } from "../entities/ProfileEmployee"; @@ -2353,6 +2353,154 @@ export class OrganizationDotnetController extends Controller { return new HttpSuccess(mapProfile); } + /** + * 3. API Get Profile จาก keycloak id + * + * @summary 3. API Get Profile จาก keycloak id + * + * @param {string} keycloakId Id keycloak + */ + @Post("find/employee/position") + async GetProfileByPositionEmpAsync( + @Request() req: RequestWithUser, + @Body() + body: { + empPosId: string[]; + }, + ) { + const findRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true }, + }); + + const profiles = await this.profileEmpRepo.find({ + relations: [ + "posLevel", + "posType", + "profileSalary", + "profileInsignias", + "profileInsignias.insignia", + "current_holders", + "current_holders.orgRevision", + "current_holders.orgRoot", + "current_holders.orgChild1", + "current_holders.orgChild2", + "current_holders.orgChild3", + "current_holders.orgChild4", + ], + where: { + current_holders: { + positions: { id: In(body.empPosId), positionIsSelected: true }, + orgRevisionId: findRevision?.id, + }, + }, + order: { + profileSalary: { + date: "DESC", + }, + profileInsignias: { + receiveDate: "DESC", + }, + }, + }); + + const mapProfile = profiles.map((profile) => { + const shortName = + profile.current_holders.length == 0 + ? null + : profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgChild4 != + null + ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgChild4.orgChild4ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) + ?.orgChild3 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgChild3.orgChild3ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) + ?.orgChild2 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgChild2.orgChild2ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) + ?.orgChild1 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgChild1.orgChild1ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id) + ?.orgRoot != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgRoot.orgRootShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.posMasterNo}` + : null; + return { + id: profile.id, + avatar: profile.avatar, + avatarName: profile.avatarName, + rank: profile.rank ?? "", + prefix: profile.prefix ?? "", + firstName: profile.firstName ?? "", + lastName: profile.lastName ?? "", + citizenId: profile.citizenId ?? "", + position: profile.position ?? "", + posLevelId: profile.posLevelId, + email: profile.email, + phone: profile.phone, + keycloak: profile.keycloak, + isProbation: profile.isProbation, + isLeave: profile.isLeave, + leaveReason: profile.leaveReason, + dateRetire: profile.dateRetire, + dateAppoint: profile.dateAppoint, + dateRetireLaw: profile.dateRetireLaw, + dateStart: profile.dateStart, + govAgeAbsent: profile.govAgeAbsent, + govAgePlus: profile.govAgePlus, + birthDate: profile.birthDate ?? new Date(), + reasonSameDate: profile.reasonSameDate, + telephoneNumber: profile.telephoneNumber, + nationality: profile.nationality, + gender: profile.gender ?? "", + relationship: profile.relationship ?? "", + religion: profile.religion ?? "", + bloodGroup: profile.bloodGroup ?? "", + registrationAddress: profile.registrationAddress, + registrationProvinceId: profile.registrationProvinceId, + registrationDistrictId: profile.registrationDistrictId, + registrationSubDistrictId: profile.registrationSubDistrictId, + registrationZipCode: profile.registrationZipCode, + currentAddress: profile.currentAddress, + currentProvinceId: profile.currentProvinceId, + currentSubDistrictId: profile.currentSubDistrictId, + currentZipCode: profile.currentZipCode, + // dutyTimeId: profile.dutyTimeId, + // dutyTimeEffectiveDate: profile.dutyTimeEffectiveDate, + posLevel: profile.posLevel?.posLevelName ?? "", + posType: profile.posType?.posTypeName ?? "", + profileSalary: profile.profileSalary, + profileInsignia: profile.profileInsignias.map((x) => { + return { ...x, insignia: x.insignia.name }; + }), + amount: profile.amount, + positionSalaryAmount: profile.positionSalaryAmount, + mouthSalaryAmount: profile.mouthSalaryAmount, + profileType: "EMPLOYEE", + root: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRoot?.orgRootName ?? null, + rootId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRootId ?? null, + posNo: shortName ?? "", + }; + }); + + return new HttpSuccess(mapProfile); + } + /** * 7.1 Get ข้อมูล GetUserFullName * diff --git a/src/controllers/ProfileActpositionController.ts b/src/controllers/ProfileActpositionController.ts new file mode 100644 index 00000000..fd9f44b1 --- /dev/null +++ b/src/controllers/ProfileActpositionController.ts @@ -0,0 +1,204 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { Profile } from "../entities/Profile"; +import { + CreateProfileActposition, + ProfileActposition, + UpdateProfileActposition, +} from "../entities/ProfileActposition"; +import { ProfileActpositionHistory } from "../entities/ProfileActpositionHistory"; +import { RequestWithUser } from "../middlewares/user"; +import HttpError from "../interfaces/http-error"; +import HttpStatus from "../interfaces/http-status"; +import HttpSuccess from "../interfaces/http-success"; +import permission from "../interfaces/permission"; +import { setLogDataDiff } from "../interfaces/utils"; +@Route("api/v1/org/profile/actposition") +@Tags("ProfileActposition") +@Security("bearerAuth") +export class ProfileActpositionController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); + private profileActpositionRepo = AppDataSource.getRepository(ProfileActposition); + private profileActpositionHistoryRepo = AppDataSource.getRepository(ProfileActpositionHistory); + + @Get("user") + public async detailProfileActpositionUser(@Request() request: { user: Record }) { + const profile = await this.profileRepo.findOneBy({ keycloak: request.user.sub }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const getProfileActpositionId = await this.profileActpositionRepo.find({ + where: { profileId: profile.id }, + order: { createdAt: "ASC" }, + }); + if (!getProfileActpositionId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileActpositionId); + } + + @Get("{profileId}") + public async detailProfileActposition( + @Path() profileId: string, + @Request() req: RequestWithUser, + ) { + let _workflow = await new permission().Workflow(req, profileId, "SYS_REGISTRY_OFFICER"); + if (_workflow == false) + await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", profileId); + const getProfileActpositionId = await this.profileActpositionRepo.find({ + where: { profileId: profileId }, + order: { createdAt: "ASC" }, + }); + if (!getProfileActpositionId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileActpositionId); + } + + @Get("admin/history/{actpositionId}") + public async getProfileActpositionAdminHistory( + @Path() actpositionId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (_record) { + let _workflow = await new permission().Workflow(req, actpositionId, "SYS_REGISTRY_OFFICER"); + if (_workflow == false) + await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", _record.profileId); + } + + const record = await this.profileActpositionHistoryRepo.find({ + where: { profileActpositionId: actpositionId }, + order: { createdAt: "DESC" }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Get("history/{actpositionId}") + public async getProfileActpositionHistory(@Path() actpositionId: string) { + const record = await this.profileActpositionHistoryRepo.find({ + where: { profileActpositionId: actpositionId }, + order: { createdAt: "DESC" }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Post() + public async newProfileActposition( + @Request() req: RequestWithUser, + @Body() body: CreateProfileActposition, + ) { + 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 ดังกล่าว"); + } + await new permission().PermissionOrgUserUpdate(req, "SYS_REGISTRY_OFFICER", profile.id); + const before = null; + const data = new ProfileActposition(); + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + createdAt: new Date(), + lastUpdatedAt: new Date(), + }; + + Object.assign(data, { ...body, ...meta }); + const history = new ProfileActpositionHistory(); + Object.assign(history, { ...data, id: undefined }); + + await this.profileActpositionRepo.save(data, { data: req }); + setLogDataDiff(req, { before, after: data }); + history.profileActpositionId = data.id; + await this.profileActpositionHistoryRepo.save(history, { data: req }); + //setLogDataDiff(req, { before, after: history }); + return new HttpSuccess(); + } + + @Patch("{actpositionId}") + public async editProfileActposition( + @Body() body: UpdateProfileActposition, + @Request() req: RequestWithUser, + @Path() actpositionId: string, + ) { + const record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + await new permission().PermissionOrgUserUpdate(req, "SYS_REGISTRY_OFFICER", record.profileId); + + const history = new ProfileActpositionHistory(); + const before = structuredClone(record); + // const before_null = null; + Object.assign(record, body); + Object.assign(history, { ...record, id: undefined }); + + history.profileActpositionId = actpositionId; + record.lastUpdateUserId = req.user.sub; + record.lastUpdateFullName = req.user.name; + record.lastUpdatedAt = new Date(); + history.lastUpdateUserId = req.user.sub; + history.lastUpdateFullName = req.user.name; + history.createdUserId = req.user.sub; + history.createdFullName = req.user.name; + history.createdAt = new Date(); + history.lastUpdatedAt = new Date(); + + await Promise.all([ + this.profileActpositionRepo.save(record, { data: req }), + setLogDataDiff(req, { before, after: record }), + this.profileActpositionHistoryRepo.save(history, { data: req }), + // setLogDataDiff(req, { before: before_null, after: history }), + ]); + + return new HttpSuccess(); + } + + @Delete("{actpositionId}") + public async deleteProfileActposition( + @Path() actpositionId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (_record) { + await new permission().PermissionOrgUserDelete( + req, + "SYS_REGISTRY_OFFICER", + _record.profileId, + ); + } + await this.profileActpositionHistoryRepo.delete({ + profileActpositionId: actpositionId, + }); + + const result = await this.profileActpositionRepo.delete({ id: actpositionId }); + + if (result.affected == undefined || result.affected <= 0) + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileActpositionEmployeeController.ts b/src/controllers/ProfileActpositionEmployeeController.ts new file mode 100644 index 00000000..667b5e25 --- /dev/null +++ b/src/controllers/ProfileActpositionEmployeeController.ts @@ -0,0 +1,211 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileActpositionEmployee, + ProfileActposition, + UpdateProfileActposition, +} from "../entities/ProfileActposition"; +import { ProfileActpositionHistory } from "../entities/ProfileActpositionHistory"; +import { RequestWithUser } from "../middlewares/user"; +import HttpError from "../interfaces/http-error"; +import HttpStatus from "../interfaces/http-status"; +import HttpSuccess from "../interfaces/http-success"; +import { ProfileEmployee } from "../entities/ProfileEmployee"; +import permission from "../interfaces/permission"; +import { setLogDataDiff } from "../interfaces/utils"; +@Route("api/v1/org/profile-employee/actposition") +@Tags("ProfileActpositionEmployee") +@Security("bearerAuth") +export class ProfileActpositionEmployeeController extends Controller { + private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); + private profileActpositionRepo = AppDataSource.getRepository(ProfileActposition); + private profileActpositionHistoryRepo = AppDataSource.getRepository(ProfileActpositionHistory); + + @Get("user") + public async detailProfileActpositionUser(@Request() request: { user: Record }) { + const profile = await this.profileEmployeeRepo.findOneBy({ keycloak: request.user.sub }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const getProfileActpositionId = await this.profileActpositionRepo.find({ + where: { profileEmployeeId: profile.id }, + order: { createdAt: "ASC" }, + }); + if (!getProfileActpositionId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileActpositionId); + } + + @Get("{profileEmployeeId}") + public async detailProfileActposition( + @Path() profileEmployeeId: string, + @Request() req: RequestWithUser, + ) { + let _workflow = await new permission().Workflow(req, profileEmployeeId, "SYS_REGISTRY_EMP"); + if (_workflow == false) + await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileEmployeeId); + const getProfileActpositionId = await this.profileActpositionRepo.find({ + where: { profileEmployeeId: profileEmployeeId }, + order: { createdAt: "ASC" }, + }); + if (!getProfileActpositionId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileActpositionId); + } + + @Get("admin/history/{actpositionId}") + public async getProfileAdminActpositionHistory( + @Path() actpositionId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (_record) { + let _workflow = await new permission().Workflow(req, actpositionId, "SYS_REGISTRY_EMP"); + if (_workflow == false) + await new permission().PermissionOrgUserGet( + req, + "SYS_REGISTRY_EMP", + _record.profileEmployeeId, + ); + } + const record = await this.profileActpositionHistoryRepo.find({ + where: { profileActpositionId: actpositionId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Get("history/{actpositionId}") + public async getProfileActpositionHistory(@Path() actpositionId: string) { + const record = await this.profileActpositionHistoryRepo.find({ + where: { profileActpositionId: actpositionId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Post() + public async newProfileActposition( + @Request() req: RequestWithUser, + @Body() body: CreateProfileActpositionEmployee, + ) { + if (!body.profileEmployeeId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileEmployeeId"); + } + + const profile = await this.profileEmployeeRepo.findOneBy({ id: body.profileEmployeeId }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + await new permission().PermissionOrgUserUpdate(req, "SYS_REGISTRY_EMP", profile.id); + const before = null; + const data = new ProfileActposition(); + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + createdAt: new Date(), + lastUpdatedAt: new Date(), + }; + + Object.assign(data, { ...body, ...meta }); + const history = new ProfileActpositionHistory(); + Object.assign(history, { ...data, id: undefined }); + + await this.profileActpositionRepo.save(data, { data: req }); + setLogDataDiff(req, { before, after: data }); + history.profileActpositionId = data.id; + await this.profileActpositionHistoryRepo.save(history, { data: req }); + //setLogDataDiff(req, { before, after: history }); + + return new HttpSuccess(); + } + + @Patch("{actpositionId}") + public async editProfileActposition( + @Body() body: UpdateProfileActposition, + @Request() req: RequestWithUser, + @Path() actpositionId: string, + ) { + const record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + await new permission().PermissionOrgUserUpdate( + req, + "SYS_REGISTRY_EMP", + record.profileEmployeeId, + ); + const before = structuredClone(record); + // const before_null = null; + const history = new ProfileActpositionHistory(); + + Object.assign(record, body); + Object.assign(history, { ...record, id: undefined }); + + history.profileActpositionId = actpositionId; + record.lastUpdateUserId = req.user.sub; + record.lastUpdateFullName = req.user.name; + record.lastUpdatedAt = new Date(); + history.lastUpdateUserId = req.user.sub; + history.lastUpdateFullName = req.user.name; + history.createdUserId = req.user.sub; + history.createdFullName = req.user.name; + history.createdAt = new Date(); + history.lastUpdatedAt = new Date(); + + await Promise.all([ + this.profileActpositionRepo.save(record, { data: req }), + setLogDataDiff(req, { before, after: record }), + this.profileActpositionHistoryRepo.save(history, { data: req }), + // setLogDataDiff(req, { before: before_null, after: history }), + ]); + + return new HttpSuccess(); + } + + @Delete("{actpositionId}") + public async deleteProfileActposition( + @Path() actpositionId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (_record) { + await new permission().PermissionOrgUserDelete( + req, + "SYS_REGISTRY_EMP", + _record.profileEmployeeId, + ); + } + await this.profileActpositionHistoryRepo.delete({ + profileActpositionId: actpositionId, + }); + + const result = await this.profileActpositionRepo.delete({ id: actpositionId }); + + if (result.affected == undefined || result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileActpositionEmployeeTempController.ts b/src/controllers/ProfileActpositionEmployeeTempController.ts new file mode 100644 index 00000000..fb2603c1 --- /dev/null +++ b/src/controllers/ProfileActpositionEmployeeTempController.ts @@ -0,0 +1,198 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileActpositionEmployee, + ProfileActposition, + UpdateProfileActposition, +} from "../entities/ProfileActposition"; +import { ProfileActpositionHistory } from "../entities/ProfileActpositionHistory"; +import { RequestWithUser } from "../middlewares/user"; +import HttpError from "../interfaces/http-error"; +import HttpStatus from "../interfaces/http-status"; +import HttpSuccess from "../interfaces/http-success"; +import { ProfileEmployee } from "../entities/ProfileEmployee"; +import permission from "../interfaces/permission"; +import { setLogDataDiff } from "../interfaces/utils"; +@Route("api/v1/org/profile-temp/actposition") +@Tags("ProfileActpositionEmployee") +@Security("bearerAuth") +export class ProfileActpositionEmployeeTempController extends Controller { + private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); + private profileActpositionRepo = AppDataSource.getRepository(ProfileActposition); + private profileActpositionHistoryRepo = AppDataSource.getRepository(ProfileActpositionHistory); + + @Get("user") + public async detailProfileActpositionUser(@Request() request: { user: Record }) { + const profile = await this.profileEmployeeRepo.findOneBy({ keycloak: request.user.sub }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const getProfileActpositionId = await this.profileActpositionRepo.find({ + where: { profileEmployeeId: profile.id }, + order: { createdAt: "ASC" }, + }); + if (!getProfileActpositionId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileActpositionId); + } + + @Get("{profileEmployeeId}") + public async detailProfileActposition( + @Path() profileEmployeeId: string, + @Request() req: RequestWithUser, + ) { + let _workflow = await new permission().Workflow(req, profileEmployeeId, "SYS_REGISTRY_TEMP"); + if (_workflow == false) await new permission().PermissionGet(req, "SYS_REGISTRY_TEMP"); + const getProfileActpositionId = await this.profileActpositionRepo.find({ + where: { profileEmployeeId: profileEmployeeId }, + order: { createdAt: "ASC" }, + }); + if (!getProfileActpositionId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileActpositionId); + } + + @Get("admin/history/{actpositionId}") + public async getProfileAdminActpositionHistory( + @Path() actpositionId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (_record) { + let _workflow = await new permission().Workflow(req, actpositionId, "SYS_REGISTRY_TEMP"); + if (_workflow == false) await new permission().PermissionGet(req, "SYS_REGISTRY_TEMP"); + } + const record = await this.profileActpositionHistoryRepo.find({ + where: { profileActpositionId: actpositionId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Get("history/{actpositionId}") + public async getProfileActpositionHistory(@Path() actpositionId: string) { + const record = await this.profileActpositionHistoryRepo.find({ + where: { profileActpositionId: actpositionId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Post() + public async newProfileActposition( + @Request() req: RequestWithUser, + @Body() body: CreateProfileActpositionEmployee, + ) { + if (!body.profileEmployeeId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileEmployeeId"); + } + + const profile = await this.profileEmployeeRepo.findOneBy({ id: body.profileEmployeeId }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + await new permission().PermissionUpdate(req, "SYS_REGISTRY_TEMP"); + const before = null; + const data = new ProfileActposition(); + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + createdAt: new Date(), + lastUpdatedAt: new Date(), + }; + + Object.assign(data, { ...body, ...meta }); + const history = new ProfileActpositionHistory(); + Object.assign(history, { ...data, id: undefined }); + + await this.profileActpositionRepo.save(data, { data: req }); + setLogDataDiff(req, { before, after: data }); + history.profileActpositionId = data.id; + await this.profileActpositionHistoryRepo.save(history, { data: req }); + //setLogDataDiff(req, { before, after: history }); + + return new HttpSuccess(); + } + + @Patch("{actpositionId}") + public async editProfileActposition( + @Body() body: UpdateProfileActposition, + @Request() req: RequestWithUser, + @Path() actpositionId: string, + ) { + const record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + await new permission().PermissionUpdate(req, "SYS_REGISTRY_TEMP"); + const before = structuredClone(record); + // const before_null = null; + const history = new ProfileActpositionHistory(); + + Object.assign(record, body); + Object.assign(history, { ...record, id: undefined }); + + history.profileActpositionId = actpositionId; + record.lastUpdateUserId = req.user.sub; + record.lastUpdateFullName = req.user.name; + record.lastUpdatedAt = new Date(); + history.lastUpdateUserId = req.user.sub; + history.lastUpdateFullName = req.user.name; + history.createdUserId = req.user.sub; + history.createdFullName = req.user.name; + history.createdAt = new Date(); + history.lastUpdatedAt = new Date(); + + await Promise.all([ + this.profileActpositionRepo.save(record, { data: req }), + setLogDataDiff(req, { before, after: record }), + this.profileActpositionHistoryRepo.save(history, { data: req }), + // setLogDataDiff(req, { before: before_null, after: history }), + ]); + + return new HttpSuccess(); + } + + @Delete("{actpositionId}") + public async deleteProfileActposition( + @Path() actpositionId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileActpositionRepo.findOneBy({ id: actpositionId }); + if (_record) { + await new permission().PermissionDelete(req, "SYS_REGISTRY_TEMP"); + } + + await this.profileActpositionHistoryRepo.delete({ + profileActpositionId: actpositionId, + }); + + const result = await this.profileActpositionRepo.delete({ id: actpositionId }); + + if (result.affected == undefined || result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileAssistanceController.ts b/src/controllers/ProfileAssistanceController.ts new file mode 100644 index 00000000..59cb4323 --- /dev/null +++ b/src/controllers/ProfileAssistanceController.ts @@ -0,0 +1,201 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { Profile } from "../entities/Profile"; +import { + CreateProfileAssistance, + ProfileAssistance, + UpdateProfileAssistance, +} from "../entities/ProfileAssistance"; +import { ProfileAssistanceHistory } from "../entities/ProfileAssistanceHistory"; +import { RequestWithUser } from "../middlewares/user"; +import HttpError from "../interfaces/http-error"; +import HttpStatus from "../interfaces/http-status"; +import HttpSuccess from "../interfaces/http-success"; +import permission from "../interfaces/permission"; +import { setLogDataDiff } from "../interfaces/utils"; +@Route("api/v1/org/profile/assistance") +@Tags("ProfileAssistance") +@Security("bearerAuth") +export class ProfileAssistanceController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); + private profileAssistanceRepo = AppDataSource.getRepository(ProfileAssistance); + private profileAssistanceHistoryRepo = AppDataSource.getRepository(ProfileAssistanceHistory); + + @Get("user") + public async detailProfileAssistanceUser(@Request() request: { user: Record }) { + const profile = await this.profileRepo.findOneBy({ keycloak: request.user.sub }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const getProfileAssistanceId = await this.profileAssistanceRepo.find({ + where: { profileId: profile.id }, + order: { createdAt: "ASC" }, + }); + if (!getProfileAssistanceId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileAssistanceId); + } + + @Get("{profileId}") + public async detailProfileAssistance(@Path() profileId: string, @Request() req: RequestWithUser) { + let _workflow = await new permission().Workflow(req, profileId, "SYS_REGISTRY_OFFICER"); + if (_workflow == false) + await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", profileId); + const getProfileAssistanceId = await this.profileAssistanceRepo.find({ + where: { profileId: profileId }, + order: { createdAt: "ASC" }, + }); + if (!getProfileAssistanceId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileAssistanceId); + } + + @Get("admin/history/{assistanceId}") + public async getProfileAssistanceAdminHistory( + @Path() assistanceId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (_record) { + let _workflow = await new permission().Workflow(req, assistanceId, "SYS_REGISTRY_OFFICER"); + if (_workflow == false) + await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_OFFICER", _record.profileId); + } + + const record = await this.profileAssistanceHistoryRepo.find({ + where: { profileAssistanceId: assistanceId }, + order: { createdAt: "DESC" }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Get("history/{assistanceId}") + public async getProfileAssistanceHistory(@Path() assistanceId: string) { + const record = await this.profileAssistanceHistoryRepo.find({ + where: { profileAssistanceId: assistanceId }, + order: { createdAt: "DESC" }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Post() + public async newProfileAssistance( + @Request() req: RequestWithUser, + @Body() body: CreateProfileAssistance, + ) { + 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 ดังกล่าว"); + } + await new permission().PermissionOrgUserUpdate(req, "SYS_REGISTRY_OFFICER", profile.id); + const before = null; + const data = new ProfileAssistance(); + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + createdAt: new Date(), + lastUpdatedAt: new Date(), + }; + + Object.assign(data, { ...body, ...meta }); + const history = new ProfileAssistanceHistory(); + Object.assign(history, { ...data, id: undefined }); + + await this.profileAssistanceRepo.save(data, { data: req }); + setLogDataDiff(req, { before, after: data }); + history.profileAssistanceId = data.id; + await this.profileAssistanceHistoryRepo.save(history, { data: req }); + //setLogDataDiff(req, { before, after: history }); + return new HttpSuccess(); + } + + @Patch("{assistanceId}") + public async editProfileAssistance( + @Body() body: UpdateProfileAssistance, + @Request() req: RequestWithUser, + @Path() assistanceId: string, + ) { + const record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + await new permission().PermissionOrgUserUpdate(req, "SYS_REGISTRY_OFFICER", record.profileId); + + const history = new ProfileAssistanceHistory(); + const before = structuredClone(record); + // const before_null = null; + Object.assign(record, body); + Object.assign(history, { ...record, id: undefined }); + + history.profileAssistanceId = assistanceId; + record.lastUpdateUserId = req.user.sub; + record.lastUpdateFullName = req.user.name; + record.lastUpdatedAt = new Date(); + history.lastUpdateUserId = req.user.sub; + history.lastUpdateFullName = req.user.name; + history.createdUserId = req.user.sub; + history.createdFullName = req.user.name; + history.createdAt = new Date(); + history.lastUpdatedAt = new Date(); + + await Promise.all([ + this.profileAssistanceRepo.save(record, { data: req }), + setLogDataDiff(req, { before, after: record }), + this.profileAssistanceHistoryRepo.save(history, { data: req }), + // setLogDataDiff(req, { before: before_null, after: history }), + ]); + + return new HttpSuccess(); + } + + @Delete("{assistanceId}") + public async deleteProfileAssistance( + @Path() assistanceId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (_record) { + await new permission().PermissionOrgUserDelete( + req, + "SYS_REGISTRY_OFFICER", + _record.profileId, + ); + } + await this.profileAssistanceHistoryRepo.delete({ + profileAssistanceId: assistanceId, + }); + + const result = await this.profileAssistanceRepo.delete({ id: assistanceId }); + + if (result.affected == undefined || result.affected <= 0) + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileAssistanceEmployeeController.ts b/src/controllers/ProfileAssistanceEmployeeController.ts new file mode 100644 index 00000000..4bb592e3 --- /dev/null +++ b/src/controllers/ProfileAssistanceEmployeeController.ts @@ -0,0 +1,211 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileAssistanceEmployee, + ProfileAssistance, + UpdateProfileAssistance, +} from "../entities/ProfileAssistance"; +import { ProfileAssistanceHistory } from "../entities/ProfileAssistanceHistory"; +import { RequestWithUser } from "../middlewares/user"; +import HttpError from "../interfaces/http-error"; +import HttpStatus from "../interfaces/http-status"; +import HttpSuccess from "../interfaces/http-success"; +import { ProfileEmployee } from "../entities/ProfileEmployee"; +import permission from "../interfaces/permission"; +import { setLogDataDiff } from "../interfaces/utils"; +@Route("api/v1/org/profile-employee/assistance") +@Tags("ProfileAssistanceEmployee") +@Security("bearerAuth") +export class ProfileAssistanceEmployeeController extends Controller { + private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); + private profileAssistanceRepo = AppDataSource.getRepository(ProfileAssistance); + private profileAssistanceHistoryRepo = AppDataSource.getRepository(ProfileAssistanceHistory); + + @Get("user") + public async detailProfileAssistanceUser(@Request() request: { user: Record }) { + const profile = await this.profileEmployeeRepo.findOneBy({ keycloak: request.user.sub }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const getProfileAssistanceId = await this.profileAssistanceRepo.find({ + where: { profileEmployeeId: profile.id }, + order: { createdAt: "ASC" }, + }); + if (!getProfileAssistanceId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileAssistanceId); + } + + @Get("{profileEmployeeId}") + public async detailProfileAssistance( + @Path() profileEmployeeId: string, + @Request() req: RequestWithUser, + ) { + let _workflow = await new permission().Workflow(req, profileEmployeeId, "SYS_REGISTRY_EMP"); + if (_workflow == false) + await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileEmployeeId); + const getProfileAssistanceId = await this.profileAssistanceRepo.find({ + where: { profileEmployeeId: profileEmployeeId }, + order: { createdAt: "ASC" }, + }); + if (!getProfileAssistanceId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileAssistanceId); + } + + @Get("admin/history/{assistanceId}") + public async getProfileAdminAssistanceHistory( + @Path() assistanceId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (_record) { + let _workflow = await new permission().Workflow(req, assistanceId, "SYS_REGISTRY_EMP"); + if (_workflow == false) + await new permission().PermissionOrgUserGet( + req, + "SYS_REGISTRY_EMP", + _record.profileEmployeeId, + ); + } + const record = await this.profileAssistanceHistoryRepo.find({ + where: { profileAssistanceId: assistanceId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Get("history/{assistanceId}") + public async getProfileAssistanceHistory(@Path() assistanceId: string) { + const record = await this.profileAssistanceHistoryRepo.find({ + where: { profileAssistanceId: assistanceId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Post() + public async newProfileAssistance( + @Request() req: RequestWithUser, + @Body() body: CreateProfileAssistanceEmployee, + ) { + if (!body.profileEmployeeId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileEmployeeId"); + } + + const profile = await this.profileEmployeeRepo.findOneBy({ id: body.profileEmployeeId }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + await new permission().PermissionOrgUserUpdate(req, "SYS_REGISTRY_EMP", profile.id); + const before = null; + const data = new ProfileAssistance(); + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + createdAt: new Date(), + lastUpdatedAt: new Date(), + }; + + Object.assign(data, { ...body, ...meta }); + const history = new ProfileAssistanceHistory(); + Object.assign(history, { ...data, id: undefined }); + + await this.profileAssistanceRepo.save(data, { data: req }); + setLogDataDiff(req, { before, after: data }); + history.profileAssistanceId = data.id; + await this.profileAssistanceHistoryRepo.save(history, { data: req }); + //setLogDataDiff(req, { before, after: history }); + + return new HttpSuccess(); + } + + @Patch("{assistanceId}") + public async editProfileAssistance( + @Body() body: UpdateProfileAssistance, + @Request() req: RequestWithUser, + @Path() assistanceId: string, + ) { + const record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + await new permission().PermissionOrgUserUpdate( + req, + "SYS_REGISTRY_EMP", + record.profileEmployeeId, + ); + const before = structuredClone(record); + // const before_null = null; + const history = new ProfileAssistanceHistory(); + + Object.assign(record, body); + Object.assign(history, { ...record, id: undefined }); + + history.profileAssistanceId = assistanceId; + record.lastUpdateUserId = req.user.sub; + record.lastUpdateFullName = req.user.name; + record.lastUpdatedAt = new Date(); + history.lastUpdateUserId = req.user.sub; + history.lastUpdateFullName = req.user.name; + history.createdUserId = req.user.sub; + history.createdFullName = req.user.name; + history.createdAt = new Date(); + history.lastUpdatedAt = new Date(); + + await Promise.all([ + this.profileAssistanceRepo.save(record, { data: req }), + setLogDataDiff(req, { before, after: record }), + this.profileAssistanceHistoryRepo.save(history, { data: req }), + // setLogDataDiff(req, { before: before_null, after: history }), + ]); + + return new HttpSuccess(); + } + + @Delete("{assistanceId}") + public async deleteProfileAssistance( + @Path() assistanceId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (_record) { + await new permission().PermissionOrgUserDelete( + req, + "SYS_REGISTRY_EMP", + _record.profileEmployeeId, + ); + } + await this.profileAssistanceHistoryRepo.delete({ + profileAssistanceId: assistanceId, + }); + + const result = await this.profileAssistanceRepo.delete({ id: assistanceId }); + + if (result.affected == undefined || result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileAssistanceEmployeeTempController.ts b/src/controllers/ProfileAssistanceEmployeeTempController.ts new file mode 100644 index 00000000..79c02f2a --- /dev/null +++ b/src/controllers/ProfileAssistanceEmployeeTempController.ts @@ -0,0 +1,198 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileAssistanceEmployee, + ProfileAssistance, + UpdateProfileAssistance, +} from "../entities/ProfileAssistance"; +import { ProfileAssistanceHistory } from "../entities/ProfileAssistanceHistory"; +import { RequestWithUser } from "../middlewares/user"; +import HttpError from "../interfaces/http-error"; +import HttpStatus from "../interfaces/http-status"; +import HttpSuccess from "../interfaces/http-success"; +import { ProfileEmployee } from "../entities/ProfileEmployee"; +import permission from "../interfaces/permission"; +import { setLogDataDiff } from "../interfaces/utils"; +@Route("api/v1/org/profile-temp/assistance") +@Tags("ProfileAssistanceEmployee") +@Security("bearerAuth") +export class ProfileAssistanceEmployeeTempController extends Controller { + private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); + private profileAssistanceRepo = AppDataSource.getRepository(ProfileAssistance); + private profileAssistanceHistoryRepo = AppDataSource.getRepository(ProfileAssistanceHistory); + + @Get("user") + public async detailProfileAssistanceUser(@Request() request: { user: Record }) { + const profile = await this.profileEmployeeRepo.findOneBy({ keycloak: request.user.sub }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + const getProfileAssistanceId = await this.profileAssistanceRepo.find({ + where: { profileEmployeeId: profile.id }, + order: { createdAt: "ASC" }, + }); + if (!getProfileAssistanceId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileAssistanceId); + } + + @Get("{profileEmployeeId}") + public async detailProfileAssistance( + @Path() profileEmployeeId: string, + @Request() req: RequestWithUser, + ) { + let _workflow = await new permission().Workflow(req, profileEmployeeId, "SYS_REGISTRY_TEMP"); + if (_workflow == false) await new permission().PermissionGet(req, "SYS_REGISTRY_TEMP"); + const getProfileAssistanceId = await this.profileAssistanceRepo.find({ + where: { profileEmployeeId: profileEmployeeId }, + order: { createdAt: "ASC" }, + }); + if (!getProfileAssistanceId) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(getProfileAssistanceId); + } + + @Get("admin/history/{assistanceId}") + public async getProfileAdminAssistanceHistory( + @Path() assistanceId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (_record) { + let _workflow = await new permission().Workflow(req, assistanceId, "SYS_REGISTRY_TEMP"); + if (_workflow == false) await new permission().PermissionGet(req, "SYS_REGISTRY_TEMP"); + } + const record = await this.profileAssistanceHistoryRepo.find({ + where: { profileAssistanceId: assistanceId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Get("history/{assistanceId}") + public async getProfileAssistanceHistory(@Path() assistanceId: string) { + const record = await this.profileAssistanceHistoryRepo.find({ + where: { profileAssistanceId: assistanceId }, + order: { createdAt: "DESC" }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + return new HttpSuccess(record); + } + + @Post() + public async newProfileAssistance( + @Request() req: RequestWithUser, + @Body() body: CreateProfileAssistanceEmployee, + ) { + if (!body.profileEmployeeId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileEmployeeId"); + } + + const profile = await this.profileEmployeeRepo.findOneBy({ id: body.profileEmployeeId }); + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + await new permission().PermissionUpdate(req, "SYS_REGISTRY_TEMP"); + const before = null; + const data = new ProfileAssistance(); + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + createdAt: new Date(), + lastUpdatedAt: new Date(), + }; + + Object.assign(data, { ...body, ...meta }); + const history = new ProfileAssistanceHistory(); + Object.assign(history, { ...data, id: undefined }); + + await this.profileAssistanceRepo.save(data, { data: req }); + setLogDataDiff(req, { before, after: data }); + history.profileAssistanceId = data.id; + await this.profileAssistanceHistoryRepo.save(history, { data: req }); + //setLogDataDiff(req, { before, after: history }); + + return new HttpSuccess(); + } + + @Patch("{assistanceId}") + public async editProfileAssistance( + @Body() body: UpdateProfileAssistance, + @Request() req: RequestWithUser, + @Path() assistanceId: string, + ) { + const record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + await new permission().PermissionUpdate(req, "SYS_REGISTRY_TEMP"); + const before = structuredClone(record); + // const before_null = null; + const history = new ProfileAssistanceHistory(); + + Object.assign(record, body); + Object.assign(history, { ...record, id: undefined }); + + history.profileAssistanceId = assistanceId; + record.lastUpdateUserId = req.user.sub; + record.lastUpdateFullName = req.user.name; + record.lastUpdatedAt = new Date(); + history.lastUpdateUserId = req.user.sub; + history.lastUpdateFullName = req.user.name; + history.createdUserId = req.user.sub; + history.createdFullName = req.user.name; + history.createdAt = new Date(); + history.lastUpdatedAt = new Date(); + + await Promise.all([ + this.profileAssistanceRepo.save(record, { data: req }), + setLogDataDiff(req, { before, after: record }), + this.profileAssistanceHistoryRepo.save(history, { data: req }), + // setLogDataDiff(req, { before: before_null, after: history }), + ]); + + return new HttpSuccess(); + } + + @Delete("{assistanceId}") + public async deleteProfileAssistance( + @Path() assistanceId: string, + @Request() req: RequestWithUser, + ) { + const _record = await this.profileAssistanceRepo.findOneBy({ id: assistanceId }); + if (_record) { + await new permission().PermissionDelete(req, "SYS_REGISTRY_TEMP"); + } + + await this.profileAssistanceHistoryRepo.delete({ + profileAssistanceId: assistanceId, + }); + + const result = await this.profileAssistanceRepo.delete({ id: assistanceId }); + + if (result.affected == undefined || result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/entities/Profile.ts b/src/entities/Profile.ts index 24d9f8ba..39d17905 100644 --- a/src/entities/Profile.ts +++ b/src/entities/Profile.ts @@ -45,6 +45,8 @@ import { StateOperatorUser } from "./StateOperatorUser"; import { StateUserComment } from "./StateUserComment"; import { CommandSign } from "./CommandSign"; import { RoleKeycloak } from "./RoleKeycloak"; +import { ProfileActposition } from "./ProfileActposition"; +import { ProfileAssistance } from "./ProfileAssistance"; @Entity("profile") export class Profile extends EntityBase { @@ -393,6 +395,12 @@ export class Profile extends EntityBase { @OneToMany(() => ProfileAssessment, (profileAssessment) => profileAssessment.profile) profileAssessments: ProfileAssessment[]; + @OneToMany(() => ProfileActposition, (profileActposition) => profileActposition.profile) + profileActpositions: ProfileActposition[]; + + @OneToMany(() => ProfileAssistance, (profileAssistance) => profileAssistance.profile) + profileAssistances: ProfileAssistance[]; + @OneToMany(() => ProfileLeave, (profileLeave) => profileLeave.profile) profileLeaves: ProfileLeave[]; diff --git a/src/entities/ProfileActposition.ts b/src/entities/ProfileActposition.ts new file mode 100644 index 00000000..740c8b44 --- /dev/null +++ b/src/entities/ProfileActposition.ts @@ -0,0 +1,101 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Profile } from "./Profile"; +import { ProfileActpositionHistory } from "./ProfileActpositionHistory"; +import { ProfileEmployee } from "./ProfileEmployee"; + +@Entity("profileActposition") +export class ProfileActposition extends EntityBase { + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง Profile", + default: null, + }) + profileId: string; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันที่เริ่มต้น", + default: null, + }) + dateStart: Date; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันที่สิ้นสุด", + default: null, + }) + dateEnd: Date; + + @Column({ + nullable: true, + comment: "ตำแหน่งเลขที่", + default: null, + }) + posNo: string; + + @Column({ + nullable: true, + comment: "ตำแหน่ง", + default: null, + }) + position: string; + + @Column({ + nullable: true, + comment: "สถานะ", + default: null, + }) + status: string; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง ProfileEmployee", + default: null, + }) + profileEmployeeId: string; + + @OneToMany( + () => ProfileActpositionHistory, + (profileActpositionHistory) => profileActpositionHistory.histories, + ) + profileActpositionHistorys: ProfileActpositionHistory[]; + + @ManyToOne(() => Profile, (profile) => profile.profileAbilities) + @JoinColumn({ name: "profileId" }) + profile: Profile; + + @ManyToOne(() => ProfileEmployee, (ProfileEmployee) => ProfileEmployee.profileAbilities) + @JoinColumn({ name: "profileEmployeeId" }) + profileEmployee: ProfileEmployee; +} + +export class CreateProfileActposition { + profileId: string | null; + dateStart: Date | null; + dateEnd: Date | null; + posNo: string | null; + position: string | null; + status: string | null; +} + +export class CreateProfileActpositionEmployee { + profileEmployeeId: string | null; + dateStart: Date | null; + dateEnd: Date | null; + posNo: string | null; + position: string | null; + status: string | null; +} + +export type UpdateProfileActposition = { + dateStart?: Date | null; + dateEnd?: Date | null; + posNo?: string | null; + position?: string | null; + status?: string | null; +}; diff --git a/src/entities/ProfileActpositionHistory.ts b/src/entities/ProfileActpositionHistory.ts new file mode 100644 index 00000000..64582dcb --- /dev/null +++ b/src/entities/ProfileActpositionHistory.ts @@ -0,0 +1,58 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { ProfileActposition } from "./ProfileActposition"; + +@Entity("profileActpositionHistory") +export class ProfileActpositionHistory extends EntityBase { + @Column({ + nullable: true, + type: "datetime", + comment: "วันที่เริ่มต้น", + default: null, + }) + dateStart: Date; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันที่สิ้นสุด", + default: null, + }) + dateEnd: Date; + + @Column({ + nullable: true, + comment: "ตำแหน่งเลขที่", + default: null, + }) + posNo: string; + + @Column({ + nullable: true, + comment: "ตำแหน่ง", + default: null, + }) + position: string; + + @Column({ + nullable: true, + comment: "สถานะ", + default: null, + }) + status: string; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง ProfileActposition", + default: null, + }) + profileActpositionId: string; + + @ManyToOne( + () => ProfileActposition, + (profileActposition) => profileActposition.profileActpositionHistorys, + ) + @JoinColumn({ name: "profileActpositionId" }) + histories: ProfileActposition; +} diff --git a/src/entities/ProfileAssistance.ts b/src/entities/ProfileAssistance.ts new file mode 100644 index 00000000..83f7b8c8 --- /dev/null +++ b/src/entities/ProfileAssistance.ts @@ -0,0 +1,110 @@ +import { Entity, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { Profile } from "./Profile"; +import { ProfileAssistanceHistory } from "./ProfileAssistanceHistory"; +import { ProfileEmployee } from "./ProfileEmployee"; + +@Entity("profileAssistance") +export class ProfileAssistance extends EntityBase { + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง Profile", + default: null, + }) + profileId: string; + + @Column({ + nullable: true, + comment: "หน่วยงานที่ให้ช่วยราชการ", + default: null, + }) + agency: string; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันเริ่มช่วยราชการ", + default: null, + }) + dateStart: Date; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันสิ้นสุดการช่วยราชการ", + default: null, + }) + dateEnd: Date; + + @Column({ + nullable: true, + comment: "เลขที่คำสั่ง", + default: null, + }) + commandNo: string; + + @Column({ + nullable: true, + comment: "เอกสารอ้างอิง", + default: null, + }) + document: string; + + @Column({ + comment: "แนบไฟล์เอกสาร", + default: false, + }) + isUpload: boolean; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง ProfileEmployee", + default: null, + }) + profileEmployeeId: string; + + @OneToMany( + () => ProfileAssistanceHistory, + (profileAssistanceHistory) => profileAssistanceHistory.histories, + ) + profileAssistanceHistorys: ProfileAssistanceHistory[]; + + @ManyToOne(() => Profile, (profile) => profile.profileAbilities) + @JoinColumn({ name: "profileId" }) + profile: Profile; + + @ManyToOne(() => ProfileEmployee, (ProfileEmployee) => ProfileEmployee.profileAbilities) + @JoinColumn({ name: "profileEmployeeId" }) + profileEmployee: ProfileEmployee; +} + +export class CreateProfileAssistance { + profileId: string | null; + agency: string | null; + dateStart: Date | null; + dateEnd: Date | null; + commandNo: string | null; + document: string | null; + isUpload: boolean; +} + +export class CreateProfileAssistanceEmployee { + profileEmployeeId: string | null; + agency: string | null; + dateStart: Date | null; + dateEnd: Date | null; + commandNo: string | null; + document: string | null; + isUpload: boolean; +} + +export type UpdateProfileAssistance = { + agency?: string | null; + dateStart?: Date | null; + dateEnd?: Date | null; + commandNo?: string | null; + document?: string | null; + isUpload: boolean; +}; diff --git a/src/entities/ProfileAssistanceHistory.ts b/src/entities/ProfileAssistanceHistory.ts new file mode 100644 index 00000000..3acea1a5 --- /dev/null +++ b/src/entities/ProfileAssistanceHistory.ts @@ -0,0 +1,64 @@ +import { Entity, Column, ManyToOne, JoinColumn } from "typeorm"; +import { EntityBase } from "./base/Base"; +import { ProfileAssistance } from "./ProfileAssistance"; + +@Entity("profileAssistanceHistory") +export class ProfileAssistanceHistory extends EntityBase { + @Column({ + nullable: true, + comment: "หน่วยงานที่ให้ช่วยราชการ", + default: null, + }) + agency: string; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันเริ่มช่วยราชการ", + default: null, + }) + dateStart: Date; + + @Column({ + nullable: true, + type: "datetime", + comment: "วันสิ้นสุดการช่วยราชการ", + default: null, + }) + dateEnd: Date; + + @Column({ + nullable: true, + comment: "เลขที่คำสั่ง", + default: null, + }) + commandNo: string; + + @Column({ + nullable: true, + comment: "เอกสารอ้างอิง", + default: null, + }) + document: string; + + @Column({ + comment: "แนบไฟล์เอกสาร", + default: false, + }) + isUpload: boolean; + + @Column({ + nullable: true, + length: 40, + comment: "คีย์นอก(FK)ของตาราง ProfileAssistance", + default: null, + }) + profileAssistanceId: string; + + @ManyToOne( + () => ProfileAssistance, + (profileAssistance) => profileAssistance.profileAssistanceHistorys, + ) + @JoinColumn({ name: "profileAssistanceId" }) + histories: ProfileAssistance; +} diff --git a/src/migration/1737737577863-addtableprofileAssistance.ts b/src/migration/1737737577863-addtableprofileAssistance.ts new file mode 100644 index 00000000..5397c0e3 --- /dev/null +++ b/src/migration/1737737577863-addtableprofileAssistance.ts @@ -0,0 +1,32 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddtableprofileAssistance1737737577863 implements MigrationInterface { + name = 'AddtableprofileAssistance1737737577863' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE \`profileActpositionHistory\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`dateStart\` datetime NULL COMMENT 'วันที่เริ่มต้น', \`dateEnd\` datetime NULL COMMENT 'วันที่สิ้นสุด', \`posNo\` varchar(255) NULL COMMENT 'ตำแหน่งเลขที่', \`position\` varchar(255) NULL COMMENT 'ตำแหน่ง', \`status\` varchar(255) NULL COMMENT 'สถานะ', \`profileActpositionId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง ProfileActposition', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`profileActposition\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`profileId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง Profile', \`dateStart\` datetime NULL COMMENT 'วันที่เริ่มต้น', \`dateEnd\` datetime NULL COMMENT 'วันที่สิ้นสุด', \`posNo\` varchar(255) NULL COMMENT 'ตำแหน่งเลขที่', \`position\` varchar(255) NULL COMMENT 'ตำแหน่ง', \`status\` varchar(255) NULL COMMENT 'สถานะ', \`profileEmployeeId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง ProfileEmployee', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`profileAssistanceHistory\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`agency\` varchar(255) NULL COMMENT 'หน่วยงานที่ให้ช่วยราชการ', \`dateStart\` datetime NULL COMMENT 'วันเริ่มช่วยราชการ', \`dateEnd\` datetime NULL COMMENT 'วันสิ้นสุดการช่วยราชการ', \`commandNo\` varchar(255) NULL COMMENT 'เลขที่คำสั่ง', \`document\` varchar(255) NULL COMMENT 'เอกสารอ้างอิง', \`isUpload\` tinyint NOT NULL COMMENT 'แนบไฟล์เอกสาร' DEFAULT 0, \`profileAssistanceId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง ProfileAssistance', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`CREATE TABLE \`profileAssistance\` (\`id\` varchar(36) NOT NULL, \`createdAt\` datetime(6) NOT NULL COMMENT 'สร้างข้อมูลเมื่อ' DEFAULT CURRENT_TIMESTAMP(6), \`createdUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่สร้างข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`lastUpdatedAt\` datetime(6) NOT NULL COMMENT 'แก้ไขข้อมูลล่าสุดเมื่อ' DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`lastUpdateUserId\` varchar(40) NOT NULL COMMENT 'User Id ที่แก้ไขข้อมูล' DEFAULT '00000000-0000-0000-0000-000000000000', \`createdFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่สร้างข้อมูล' DEFAULT 'string', \`lastUpdateFullName\` varchar(200) NOT NULL COMMENT 'ชื่อ User ที่แก้ไขข้อมูลล่าสุด' DEFAULT 'string', \`profileId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง Profile', \`agency\` varchar(255) NULL COMMENT 'หน่วยงานที่ให้ช่วยราชการ', \`dateStart\` datetime NULL COMMENT 'วันเริ่มช่วยราชการ', \`dateEnd\` datetime NULL COMMENT 'วันสิ้นสุดการช่วยราชการ', \`commandNo\` varchar(255) NULL COMMENT 'เลขที่คำสั่ง', \`document\` varchar(255) NULL COMMENT 'เอกสารอ้างอิง', \`isUpload\` tinyint NOT NULL COMMENT 'แนบไฟล์เอกสาร' DEFAULT 0, \`profileEmployeeId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง ProfileEmployee', PRIMARY KEY (\`id\`)) ENGINE=InnoDB`); + await queryRunner.query(`ALTER TABLE \`profileActpositionHistory\` ADD CONSTRAINT \`FK_3237d7abfbea9831a55541af88e\` FOREIGN KEY (\`profileActpositionId\`) REFERENCES \`profileActposition\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`profileActposition\` ADD CONSTRAINT \`FK_23b27027d87eeb4434a0fd180b9\` FOREIGN KEY (\`profileId\`) REFERENCES \`profile\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`profileActposition\` ADD CONSTRAINT \`FK_9a1370a44ec70ab52dacbfa59c7\` FOREIGN KEY (\`profileEmployeeId\`) REFERENCES \`profileEmployee\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`profileAssistanceHistory\` ADD CONSTRAINT \`FK_800ad6a522e1d5570282421a254\` FOREIGN KEY (\`profileAssistanceId\`) REFERENCES \`profileAssistance\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`profileAssistance\` ADD CONSTRAINT \`FK_40921096fc4283edf837ac7dd0d\` FOREIGN KEY (\`profileId\`) REFERENCES \`profile\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE \`profileAssistance\` ADD CONSTRAINT \`FK_5d287abdf47e8fba3e700537ed8\` FOREIGN KEY (\`profileEmployeeId\`) REFERENCES \`profileEmployee\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`profileAssistance\` DROP FOREIGN KEY \`FK_5d287abdf47e8fba3e700537ed8\``); + await queryRunner.query(`ALTER TABLE \`profileAssistance\` DROP FOREIGN KEY \`FK_40921096fc4283edf837ac7dd0d\``); + await queryRunner.query(`ALTER TABLE \`profileAssistanceHistory\` DROP FOREIGN KEY \`FK_800ad6a522e1d5570282421a254\``); + await queryRunner.query(`ALTER TABLE \`profileActposition\` DROP FOREIGN KEY \`FK_9a1370a44ec70ab52dacbfa59c7\``); + await queryRunner.query(`ALTER TABLE \`profileActposition\` DROP FOREIGN KEY \`FK_23b27027d87eeb4434a0fd180b9\``); + await queryRunner.query(`ALTER TABLE \`profileActpositionHistory\` DROP FOREIGN KEY \`FK_3237d7abfbea9831a55541af88e\``); + await queryRunner.query(`DROP TABLE \`profileAssistance\``); + await queryRunner.query(`DROP TABLE \`profileAssistanceHistory\``); + await queryRunner.query(`DROP TABLE \`profileActposition\``); + await queryRunner.query(`DROP TABLE \`profileActpositionHistory\``); + } + +}