diff --git a/src/controllers/ProfileCertificateController.ts b/src/controllers/ProfileCertificateController.ts new file mode 100644 index 00000000..18ed3f3e --- /dev/null +++ b/src/controllers/ProfileCertificateController.ts @@ -0,0 +1,189 @@ +import { + Body, + Controller, + Delete, + Example, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileCertificate, + ProfileCertificate, + UpdateProfileCertificate, +} from "../entities/ProfileCertificate"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileCertificateHistory } from "../entities/ProfileCertificateHistory"; +import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; + +@Route("api/v1/org/profile/certificate") +@Tags("ProfileCertificate") +@Security("bearerAuth") +export class ProfileCertificateController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); + private certificateRepo = AppDataSource.getRepository(ProfileCertificate); + private certificateHistoryRepo = AppDataSource.getRepository(ProfileCertificateHistory); + + @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "e1ef9c3d-079a-40d8-8332-664c3e9a5a70", + createdAt: "2024-03-12T03:02:27.532Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:02:27.532Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + expireDate: "2024-03-12T10:01:48.000Z", + isActive: true, + issueDate: "2024-03-12T10:01:48.000Z", + certificateNo: "string", + certificateType: "string", + issuer: "string", + }, + ], + }) + public async getCertificate(@Path() profileId: string) { + const record = await this.certificateRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{certificateId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "c0ecf986-b290-44ca-b45e-f4448cdd34dd", + createdAt: "2024-03-12T03:03:30.169Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T03:03:30.169Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + expireDate: "2024-03-12T10:03:05.000Z", + isActive: true, + issueDate: "2024-03-12T10:03:05.000Z", + certificateNo: "no", + certificateType: "type", + issuer: "issuer", + profileCertificateId: "e1ef9c3d-079a-40d8-8332-664c3e9a5a70", + }, + { + id: "dc4c2800-5fc5-4ec3-b19a-c4a27beac35f", + createdAt: "2024-03-12T03:02:27.583Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:02:27.583Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + expireDate: "2024-03-12T10:01:48.000Z", + isActive: true, + issueDate: "2024-03-12T10:01:48.000Z", + certificateNo: "string", + certificateType: "string", + issuer: "string", + profileCertificateId: "e1ef9c3d-079a-40d8-8332-664c3e9a5a70", + }, + ], + }) + public async certificateHistory(@Path() certificateId: string) { + const record = await this.certificateHistoryRepo.findBy({ + profileCertificateId: certificateId, + }); + return new HttpSuccess(record); + } + + @Post() + public async newCertificate( + @Request() req: RequestWithUser, + @Body() body: CreateProfileCertificate, + ) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + + const data = new ProfileCertificate(); + const history = new ProfileCertificateHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.certificateRepo.save(data); + + history.profileCertificateId = result.id; + + await this.certificateHistoryRepo.save(history); + + return new HttpSuccess(); + } + + @Patch("{certificateId}") + public async editCertificate( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileCertificate, + @Path() certificateId: string, + ) { + const record = await this.certificateRepo.findOneBy({ id: certificateId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileCertificateHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileCertificateId = certificateId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([ + this.certificateRepo.save(record), + this.certificateHistoryRepo.save(history), + ]); + + return new HttpSuccess(); + } + + @Delete("{certificateId}") + public async deleteCertificate(@Path() certificateId: string) { + await this.certificateHistoryRepo.delete({ + profileCertificateId: certificateId, + }); + + const certificateResult = await this.certificateRepo.delete({ + id: certificateId, + }); + + if (certificateResult.affected && certificateResult.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileHonorController.ts b/src/controllers/ProfileHonorController.ts new file mode 100644 index 00000000..1cf305b2 --- /dev/null +++ b/src/controllers/ProfileHonorController.ts @@ -0,0 +1,178 @@ +import { + Body, + Controller, + Delete, + Example, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { CreateProfileHonor, ProfileHonor, UpdateProfileHonor } from "../entities/ProfileHonor"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileHonorHistory } from "../entities/ProfileHonorHistory"; +import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; + +@Route("api/v1/org/profile/honor") +@Tags("ProfileHonor") +@Security("bearerAuth") +export class ProfileHonorController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); + private honorRepo = AppDataSource.getRepository(ProfileHonor); + private honorHistoryRepo = AppDataSource.getRepository(ProfileHonorHistory); + + @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "debfa8a7-83fb-4801-a940-8ae74e7638d3", + createdAt: "2024-03-12T03:10:05.594Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:10:05.594Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + isActive: true, + detail: "string", + issueDate: "2024-03-12T10:09:47.000Z", + issuer: "string", + refCommandDate: "2024-03-12T10:09:47.000Z", + refCommandNo: "string", + isDate: true, + }, + ], + }) + public async getHonor(@Path() profileId: string) { + const record = await this.honorRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{honorId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "3bedb365-4a41-4df5-8f47-b6e143221d2c", + createdAt: "2024-03-12T03:11:01.395Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T03:11:01.395Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + detail: "detail", + issueDate: "2024-03-12T10:10:31.000Z", + issuer: "issuer", + refCommandDate: "2024-03-12T10:10:31.000Z", + refCommandNo: "refCommandNo", + profileHonorId: "debfa8a7-83fb-4801-a940-8ae74e7638d3", + }, + { + id: "ba0e2f82-014e-46c6-8b82-a7c28eb5325f", + createdAt: "2024-03-12T03:10:05.657Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:10:05.657Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + detail: "string", + issueDate: "2024-03-12T10:09:47.000Z", + issuer: "string", + refCommandDate: "2024-03-12T10:09:47.000Z", + refCommandNo: "string", + profileHonorId: "debfa8a7-83fb-4801-a940-8ae74e7638d3", + }, + ], + }) + public async honorHistory(@Path() honorId: string) { + const record = await this.honorHistoryRepo.findBy({ + profileHonorId: honorId, + }); + return new HttpSuccess(record); + } + + @Post() + public async newHonor(@Request() req: RequestWithUser, @Body() body: CreateProfileHonor) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + + const data = new ProfileHonor(); + const history = new ProfileHonorHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.honorRepo.save(data); + + history.profileHonorId = result.id; + + await this.honorHistoryRepo.save(history); + + return new HttpSuccess(); + } + + @Patch("{honorId}") + public async editHonor( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileHonor, + @Path() honorId: string, + ) { + const record = await this.honorRepo.findOneBy({ id: honorId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileHonorHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileHonorId = honorId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([this.honorRepo.save(record), this.honorHistoryRepo.save(history)]); + + return new HttpSuccess(); + } + + @Delete("{honorId}") + public async deleteTraning(@Path() honorId: string) { + await this.honorHistoryRepo.delete({ + profileHonorId: honorId, + }); + + const result = await this.honorRepo.delete({ id: honorId }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileInsigniaController.ts b/src/controllers/ProfileInsigniaController.ts new file mode 100644 index 00000000..d05ef9f7 --- /dev/null +++ b/src/controllers/ProfileInsigniaController.ts @@ -0,0 +1,205 @@ +import { + Body, + Controller, + Delete, + Example, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileInsignia, + ProfileInsignia, + UpdateProfileInsignia, +} from "../entities/ProfileInsignia"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileInsigniaHistory } from "../entities/ProfileInsigniaHistory"; +import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; + +@Route("api/v1/org/profile/insignia") +@Tags("ProfileInsignia") +@Security("bearerAuth") +export class ProfileInsigniaController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); + private insigniaRepo = AppDataSource.getRepository(ProfileInsignia); + private insigniaHistoryRepo = AppDataSource.getRepository(ProfileInsigniaHistory); + + @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + createdAt: "2024-03-12T03:05:09.393Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:05:09.393Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + isActive: true, + year: 0, + no: "string", + volume: "string", + section: "string", + page: "string", + receiveDate: "2024-03-12T10:05:02.000Z", + insigniaId: "string", + insigniaType: "string", + dateAnnounce: "2024-03-12T10:05:02.000Z", + issue: "string", + volumeNo: "string", + refCommandDate: "2024-03-12T10:05:02.000Z", + refCommandNo: "string", + }, + ], + }) + public async getInsignia(@Path() profileId: string) { + const record = await this.insigniaRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{InsigniaId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "c363d13c-88bd-4954-adf5-70d3f5ca9c30", + createdAt: "2024-03-12T03:06:31.062Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T03:06:31.062Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + year: 0, + no: "no", + volume: "volume", + section: "section", + page: "page", + receiveDate: "2024-03-12T10:05:44.000Z", + insigniaId: "insigniaId", + insigniaType: "insigniaType", + dateAnnounce: "2024-03-12T10:05:44.000Z", + issue: "string", + volumeNo: "volumeNo", + refCommandDate: "2024-03-12T10:05:44.000Z", + refCommandNo: "refCommandNo", + profileInsigniaId: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + }, + { + id: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + createdAt: "2024-03-12T03:05:09.393Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T03:09:04.905Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + year: 0, + no: "string", + volume: "string", + section: "string", + page: "string", + receiveDate: "2024-03-12T10:05:02.000Z", + insigniaId: "string", + insigniaType: "string", + dateAnnounce: "2024-03-12T10:05:02.000Z", + issue: "string", + volumeNo: "string", + refCommandDate: "2024-03-12T10:05:02.000Z", + refCommandNo: "string", + profileInsigniaId: "c9d4dd52-25f5-491a-852d-28bfe00d66cb", + }, + ], + }) + public async getInsigniaHistory(@Path() InsigniaId: string) { + const record = await this.insigniaHistoryRepo.findBy({ + profileInsigniaId: InsigniaId, + }); + return new HttpSuccess(record); + } + + @Post() + public async newInsignia(@Request() req: RequestWithUser, @Body() body: CreateProfileInsignia) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + + const data = new ProfileInsignia(); + const history = new ProfileInsigniaHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.insigniaRepo.save(data); + + history.profileInsigniaId = result.id; + + await this.insigniaHistoryRepo.save(history); + + return new HttpSuccess(); + } + + @Patch("{insigniaId}") + public async editInsignia( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileInsignia, + @Path() insigniaId: string, + ) { + const record = await this.insigniaRepo.findOneBy({ id: insigniaId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileInsigniaHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileInsigniaId = insigniaId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([this.insigniaRepo.save(record), this.insigniaHistoryRepo.save(history)]); + + return new HttpSuccess(); + } + + @Delete("{insigniaId}") + public async deleteInsignia(@Path() insigniaId: string) { + await this.insigniaHistoryRepo.delete({ + profileInsigniaId: insigniaId, + }); + + const result = await this.insigniaRepo.delete({ id: insigniaId }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/controllers/ProfileTrainingController.ts b/src/controllers/ProfileTrainingController.ts new file mode 100644 index 00000000..32a1a123 --- /dev/null +++ b/src/controllers/ProfileTrainingController.ts @@ -0,0 +1,197 @@ +import { + Body, + Controller, + Delete, + Example, + Get, + Patch, + Path, + Post, + Request, + Route, + Security, + Tags, +} from "tsoa"; +import { AppDataSource } from "../database/data-source"; +import { + CreateProfileTraining, + ProfileTraining, + UpdateProfileTraining, +} from "../entities/ProfileTraining"; +import HttpSuccess from "../interfaces/http-success"; +import HttpStatus from "../interfaces/http-status"; +import HttpError from "../interfaces/http-error"; +import { ProfileTrainingHistory } from "../entities/ProfileTrainingHistory"; +import { RequestWithUser } from "../middlewares/user"; +import { Profile } from "../entities/Profile"; + +@Route("api/v1/org/profile/training") +@Tags("ProfileTraining") +@Security("bearerAuth") +export class ProfileTrainingController extends Controller { + private profileRepo = AppDataSource.getRepository(Profile); + private trainingRepo = AppDataSource.getRepository(ProfileTraining); + private trainingHistoryRepo = AppDataSource.getRepository(ProfileTrainingHistory); + + @Get("{profileId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "3cf02fb7-2f0c-471b-b641-51d557375c0a", + createdAt: "2024-03-12T02:55:56.915Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T02:55:56.915Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + profileId: "1526d9d3-d8b1-43ab-81b5-a84dfbe99201", + isActive: true, + startDate: "2024-03-12T09:55:23.000Z", + endDate: "2024-03-12T09:55:23.000Z", + numberOrder: "string", + topic: "string", + place: "string", + dateOrder: "2024-03-12T09:55:23.000Z", + department: "string", + duration: "string", + name: "string", + yearly: 0, + isDate: true, + }, + ], + }) + public async getTraining(@Path() profileId: string) { + const record = await this.trainingRepo.findBy({ profileId }); + return new HttpSuccess(record); + } + + @Get("history/{trainingId}") + @Example({ + status: 200, + message: "สำเร็จ", + result: [ + { + id: "6d4e9dbe-8697-4546-9651-0a1c3ea0a82d", + createdAt: "2024-03-12T02:55:56.971Z", + createdUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + lastUpdatedAt: "2024-03-12T02:55:56.971Z", + lastUpdateUserId: "59134ef9-9e62-41d0-aac5-339be727f2b0", + createdFullName: "สาวิตรี ศรีสมัย", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + startDate: "2024-03-12T09:55:23.000Z", + endDate: "2024-03-12T09:55:23.000Z", + numberOrder: "string", + topic: "string", + place: "string", + dateOrder: "2024-03-12T09:55:23.000Z", + department: "string", + duration: "string", + name: "string", + yearly: 0, + profileTrainingId: "3cf02fb7-2f0c-471b-b641-51d557375c0a", + }, + { + id: "a251c176-3dac-4d09-9813-38c8db1127e3", + createdAt: "2024-03-12T02:58:17.917Z", + createdUserId: "00000000-0000-0000-0000-000000000000", + lastUpdatedAt: "2024-03-12T02:58:17.917Z", + lastUpdateUserId: "00000000-0000-0000-0000-000000000000", + createdFullName: "string", + lastUpdateFullName: "สาวิตรี ศรีสมัย", + isActive: true, + startDate: "2024-03-12T09:57:44.000Z", + endDate: "2024-03-12T09:57:44.000Z", + numberOrder: "string", + topic: "topic", + place: "place", + dateOrder: "2024-03-12T09:57:44.000Z", + department: "department", + duration: "string", + name: "name", + yearly: 0, + profileTrainingId: "3cf02fb7-2f0c-471b-b641-51d557375c0a", + }, + ], + }) + public async trainingHistory(@Path() trainingId: string) { + const record = await this.trainingHistoryRepo.findBy({ + profileTrainingId: trainingId, + }); + return new HttpSuccess(record); + } + + @Post() + public async newTraining(@Request() req: RequestWithUser, @Body() body: CreateProfileTraining) { + if (!body.profileId) { + throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); + } + + const profile = await this.profileRepo.findOneBy({ id: body.profileId }); + + if (!profile) { + throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); + } + + const data = new ProfileTraining(); + const history = new ProfileTrainingHistory(); + + const meta = { + createdUserId: req.user.sub, + createdFullName: req.user.name, + lastUpdateUserId: req.user.sub, + lastUpdateFullName: req.user.name, + }; + + Object.assign(data, { ...body, ...meta }); + Object.assign(history, { ...body, ...meta }); + + const result = await this.trainingRepo.save(data); + + history.profileTrainingId = result.id; + + await this.trainingHistoryRepo.save(history); + + return new HttpSuccess(); + } + + @Patch("{trainingId}") + public async editTraining( + @Request() req: RequestWithUser, + @Body() body: UpdateProfileTraining, + @Path() trainingId: string, + ) { + const record = await this.trainingRepo.findOneBy({ id: trainingId }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + + const history = new ProfileTrainingHistory(); + + Object.assign(record, body); + Object.assign(history, { ...body, id: undefined }); + history.profileTrainingId = trainingId; + record.lastUpdateFullName = req.user.name; + history.lastUpdateFullName = req.user.name; + + await Promise.all([this.trainingRepo.save(record), this.trainingHistoryRepo.save(history)]); + + return new HttpSuccess(); + } + + @Delete("{trainingId}") + public async deleteTraining(@Path() trainingId: string) { + await this.trainingHistoryRepo.delete({ + profileTrainingId: trainingId, + }); + + const result = await this.trainingRepo.delete({ id: trainingId }); + + if (result.affected && result.affected <= 0) { + throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); + } + + return new HttpSuccess(); + } +} diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index ef23c9b1..d9edd9d9 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -5,8 +5,10 @@ export function calculateAge(start: Date, end = new Date()) { let month = end.getMonth() - start.getMonth(); let day = end.getDate() - start.getDate(); - if (month < 0) year -= 1; - if (month < 0) month += 12; + if (month < 0) { + month += 12; + year -= 1; + } if (day < 0) { month -= 1; day = diff --git a/src/middlewares/role.ts b/src/middlewares/role.ts index fef95919..681dc99b 100644 --- a/src/middlewares/role.ts +++ b/src/middlewares/role.ts @@ -5,7 +5,7 @@ import { RequestWithUser } from "./user"; export function authRole( role: string | string[], - errorMessage = "คุณไม่มีสิทธิในการเข้าถึงทรัพยากรดังกล่าว", + errorMessage: string = "คุณไม่มีสิทธิในการเข้าถึงทรัพยากรดังกล่าว", ) { return (req: RequestWithUser, _res: express.Response, next: express.NextFunction) => { if ((Array.isArray(role) && role.includes("*")) || role === "*") return next(); diff --git a/src/middlewares/user.ts b/src/middlewares/user.ts index 12c5d597..a35cdc4a 100644 --- a/src/middlewares/user.ts +++ b/src/middlewares/user.ts @@ -2,6 +2,7 @@ import type { Request } from "express"; export type RequestWithUser = Request & { user: { + sub: string; name: string; given_name: string; familiy_name: string; diff --git a/tsoa.json b/tsoa.json index 588162ec..87fa35f9 100644 --- a/tsoa.json +++ b/tsoa.json @@ -1,7 +1,7 @@ { "entryFile": "src/app.ts", "noImplicitAdditionalProperties": "throw-on-extras", - "controllerPathGlobs": ["src/controllers/*Controller.ts"], + "controllerPathGlobs": ["src/controllers/**/*Controller.ts"], "spec": { "outputDirectory": "src", "specVersion": 3,