|
1 | | -import { Request, Response, NextFunction } from 'express'; |
2 | | -import { ResponseError, EmploymentHistory, validateEmploymentHistory } from '../../models'; |
| 1 | +import { Request, Response, RequestHandler } from 'express'; |
| 2 | +import { EmploymentHistorySchema, Trainee, EmploymentHistory } from '../../models'; |
3 | 3 | import { TraineesRepository } from '../../repositories'; |
| 4 | +import { BadRequestError, NotFoundError } from '../../utils/httpErrors'; |
| 5 | +import { TraineeHelper } from './TraineeHelper'; |
4 | 6 |
|
5 | 7 | export interface EmploymentHistoryControllerType { |
6 | | - getEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void>; |
7 | | - addEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void>; |
8 | | - updateEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void>; |
9 | | - deleteEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void>; |
| 8 | + getEmploymentHistory: RequestHandler; |
| 9 | + addEmploymentHistory: RequestHandler; |
| 10 | + updateEmploymentHistory: RequestHandler; |
| 11 | + deleteEmploymentHistory: RequestHandler; |
10 | 12 | } |
11 | 13 |
|
12 | 14 | export class EmploymentHistoryController implements EmploymentHistoryControllerType { |
13 | | - constructor(private readonly traineesRepository: TraineesRepository) {} |
14 | | - |
15 | | - async getEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void> { |
16 | | - try { |
17 | | - const traineeID = req.params.id; |
18 | | - const employmentHistory = await this.traineesRepository.getEmploymentHistory(traineeID); |
19 | | - res.json(employmentHistory); |
20 | | - } catch (error: any) { |
21 | | - next(error); |
22 | | - } |
| 15 | + constructor( |
| 16 | + private readonly traineesRepository: TraineesRepository, |
| 17 | + private readonly traineeHelper: TraineeHelper |
| 18 | + ) {} |
| 19 | + |
| 20 | + async getEmploymentHistory(req: Request, res: Response): Promise<void> { |
| 21 | + // input |
| 22 | + const traineeID = req.params.id; |
| 23 | + |
| 24 | + // check if trainee exists |
| 25 | + await this.traineeHelper.getTraineeOrThrow(traineeID); |
| 26 | + |
| 27 | + // get |
| 28 | + const employmentHistory = await this.traineesRepository.getEmploymentHistory(traineeID); |
| 29 | + res.json(employmentHistory); |
23 | 30 | } |
24 | 31 |
|
25 | | - async addEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void> { |
| 32 | + async addEmploymentHistory(req: Request, res: Response): Promise<void> { |
| 33 | + // input |
26 | 34 | const traineeID = req.params.id; |
27 | | - const employmentHistoryData: EmploymentHistory = req.body; |
28 | | - try { |
29 | | - validateEmploymentHistory(employmentHistoryData); |
30 | | - } catch (error: any) { |
31 | | - res.status(400).send(new ResponseError(error.message)); |
32 | | - return; |
33 | | - } |
34 | | - |
35 | | - try { |
36 | | - const newEmploymentHistory = await this.traineesRepository.addEmploymentHistory(traineeID, employmentHistoryData); |
37 | | - res.status(201).json(newEmploymentHistory); |
38 | | - } catch (error: any) { |
39 | | - next(error); |
40 | | - } |
| 35 | + |
| 36 | + // validate |
| 37 | + const parsed = EmploymentHistorySchema.safeParse(req.body); |
| 38 | + if (!parsed.success) throw new BadRequestError(parsed.error, 'stringify'); |
| 39 | + const historyToAdd = parsed.data; |
| 40 | + |
| 41 | + // check if trainee exists |
| 42 | + await this.traineeHelper.getTraineeOrThrow(traineeID); |
| 43 | + |
| 44 | + // add |
| 45 | + const addedEmploymentHistory = await this.traineesRepository.addEmploymentHistory(traineeID, historyToAdd); |
| 46 | + res.status(201).json(addedEmploymentHistory); |
41 | 47 | } |
42 | 48 |
|
43 | | - async updateEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void> { |
44 | | - const trainee = await this.traineesRepository.getTrainee(req.params.id); |
45 | | - if (!trainee) { |
46 | | - res.status(404).send(new ResponseError('Trainee not found')); |
47 | | - return; |
48 | | - } |
| 49 | + async updateEmploymentHistory(req: Request, res: Response): Promise<void> { |
| 50 | + // input |
| 51 | + const traineeID = req.params.id; |
| 52 | + const employmentHistoryID = req.params.employmentHistoryID; |
49 | 53 |
|
50 | | - const employmentHistoryData = trainee.employmentInfo.employmentHistory.find( |
51 | | - (history) => history.id === req.params.employmentHistoryID |
52 | | - ); |
53 | | - if (!employmentHistoryData) { |
54 | | - res.status(404).send(new ResponseError('Employment history was not found')); |
55 | | - return; |
56 | | - } |
57 | | - |
58 | | - const historyToUpdate: EmploymentHistory = { |
59 | | - id: employmentHistoryData.id, |
60 | | - type: req.body.type, |
61 | | - companyName: req.body.companyName, |
62 | | - role: req.body.role, |
63 | | - startDate: new Date(req.body.startDate), |
64 | | - endDate: req.body.endDate ? new Date(req.body.endDate) : undefined, |
65 | | - feeCollected: req.body.feeCollected, |
66 | | - feeAmount: req.body.feeAmount, |
67 | | - comments: req.body.comments, |
68 | | - }; |
69 | | - |
70 | | - try { |
71 | | - validateEmploymentHistory(historyToUpdate); |
72 | | - } catch (error: any) { |
73 | | - res.status(400).send(new ResponseError(error.message)); |
74 | | - return; |
75 | | - } |
76 | | - |
77 | | - try { |
78 | | - const updatedEmploymentHistory = await this.traineesRepository.updateEmploymentHistory( |
79 | | - trainee.id, |
80 | | - historyToUpdate |
81 | | - ); |
82 | | - |
83 | | - res.json(updatedEmploymentHistory); |
84 | | - } catch (error: any) { |
85 | | - next(error); |
86 | | - } |
| 54 | + // validate |
| 55 | + const parsed = EmploymentHistorySchema.safeParse(req.body); |
| 56 | + if (!parsed.success) throw new BadRequestError(parsed.error, 'stringify'); |
| 57 | + const historyToUpdate = parsed.data; |
| 58 | + |
| 59 | + // check if trainee and employment history exists |
| 60 | + const trainee = await this.traineeHelper.getTraineeOrThrow(traineeID); |
| 61 | + this.getEmploymentHistoryOrThrow(trainee, employmentHistoryID); |
| 62 | + |
| 63 | + // update |
| 64 | + const updatedEmploymentHistory = await this.traineesRepository.updateEmploymentHistory(traineeID, historyToUpdate); |
| 65 | + res.json(updatedEmploymentHistory); |
87 | 66 | } |
88 | 67 |
|
89 | | - async deleteEmploymentHistory(req: Request, res: Response, next: NextFunction): Promise<void> { |
90 | | - try { |
91 | | - const trainee = await this.traineesRepository.getTrainee(req.params.id); |
92 | | - if (!trainee) { |
93 | | - res.status(404).send(new ResponseError('Trainee not found')); |
94 | | - return; |
95 | | - } |
96 | | - |
97 | | - const employmentHistoryID = req.params.employmentHistoryID; |
98 | | - if (!trainee.employmentInfo.employmentHistory.find((history) => history.id === employmentHistoryID)) { |
99 | | - res.status(404).send(new ResponseError('Employment history not found')); |
100 | | - return; |
101 | | - } |
102 | | - |
103 | | - await this.traineesRepository.deleteEmploymentHistory(trainee.id, employmentHistoryID); |
104 | | - res.status(204).send(); |
105 | | - } catch (error: any) { |
106 | | - next(error); |
107 | | - } |
| 68 | + async deleteEmploymentHistory(req: Request, res: Response): Promise<void> { |
| 69 | + // input |
| 70 | + const traineeID = req.params.id; |
| 71 | + const employmentHistoryID = req.params.employmentHistoryID; |
| 72 | + |
| 73 | + // check if trainee and employment history exists |
| 74 | + const trainee = await this.traineeHelper.getTraineeOrThrow(traineeID); |
| 75 | + this.getEmploymentHistoryOrThrow(trainee, employmentHistoryID); |
| 76 | + |
| 77 | + // delete |
| 78 | + await this.traineesRepository.deleteEmploymentHistory(traineeID, employmentHistoryID); |
| 79 | + res.status(204).send(); |
| 80 | + } |
| 81 | + |
| 82 | + /** |
| 83 | + * Helper method to get employment history or throw NotFoundError |
| 84 | + */ |
| 85 | + private getEmploymentHistoryOrThrow(trainee: Trainee, employmentHistoryID: string): EmploymentHistory { |
| 86 | + const employmentHistory = trainee.employmentInfo.employmentHistory.find( |
| 87 | + (history) => history.id === employmentHistoryID |
| 88 | + ); |
| 89 | + |
| 90 | + if (!employmentHistory) throw new NotFoundError('Employment history not found'); |
| 91 | + return employmentHistory; |
108 | 92 | } |
109 | 93 | } |
0 commit comments