11import { sequelize } from "../../models" ;
22import ReviewedApplicantRecord from "../../models/reviewedApplicantRecord.model" ;
3+ import ApplicantRecord from "../../models/applicantRecord.model" ;
34import {
45 ReviewedApplicantRecordDTO ,
56 CreateReviewedApplicantRecordDTO ,
67 DeleteReviewedApplicantRecordDTO ,
8+ UpdateReviewedApplicantRecordDTO ,
9+ Review ,
710} from "../../types" ;
811import { getErrorMessage } from "../../utilities/errorUtils" ;
912import logger from "../../utilities/logger" ;
1013import IReviewApplicantRecordService from "../interfaces/IReviewedApplicantRecordService" ;
1114
1215const Logger = logger ( __filename ) ;
1316
17+ function validateReviewScores ( review : Review | undefined ) : void {
18+ if ( ! review ) return ;
19+
20+ const scores = {
21+ passionFSG : review . passionFSG ,
22+ teamPlayer : review . teamPlayer ,
23+ desireToLearn : review . desireToLearn ,
24+ skill : review . skill ,
25+ } ;
26+
27+ Object . entries ( scores ) . forEach ( ( [ field , value ] ) => {
28+ if ( value !== undefined && ( value < 1 || value > 5 ) ) {
29+ throw new Error (
30+ `Invalid score for ${ field } : ${ value } . Scores must be between 1 and 5.` ,
31+ ) ;
32+ }
33+ } ) ;
34+ }
35+
1436class ReviewedApplicantRecordService implements IReviewApplicantRecordService {
1537 /* eslint-disable class-methods-use-this */
1638 async createReviewedApplicantRecord (
1739 dto : CreateReviewedApplicantRecordDTO ,
1840 ) : Promise < ReviewedApplicantRecordDTO > {
1941 try {
42+ validateReviewScores ( dto . review ) ;
2043 const record = await ReviewedApplicantRecord . create ( dto ) ;
2144 return record . toJSON ( ) as ReviewedApplicantRecordDTO ;
2245 } catch ( error : unknown ) {
@@ -33,6 +56,10 @@ class ReviewedApplicantRecordService implements IReviewApplicantRecordService {
3356 createReviewedApplicantRecordDTOs : CreateReviewedApplicantRecordDTO [ ] ,
3457 ) : Promise < ReviewedApplicantRecordDTO [ ] > {
3558 try {
59+ createReviewedApplicantRecordDTOs . forEach ( ( dto ) => {
60+ validateReviewScores ( dto . review ) ;
61+ } ) ;
62+
3663 const reviewedApplicantRecords = await sequelize . transaction (
3764 async ( t ) => {
3865 const records = await ReviewedApplicantRecord . bulkCreate (
@@ -121,6 +148,90 @@ class ReviewedApplicantRecordService implements IReviewApplicantRecordService {
121148 throw error ;
122149 }
123150 }
151+
152+ /* eslint-disable class-methods-use-this */
153+ async updateReviewedApplicantRecord ( {
154+ applicantRecordId,
155+ reviewerId,
156+ review,
157+ status,
158+ } : UpdateReviewedApplicantRecordDTO ) : Promise < ReviewedApplicantRecordDTO > {
159+ try {
160+ const updatedRecord = await sequelize . transaction ( async ( t ) => {
161+ const reviewedRecord = await ReviewedApplicantRecord . findOne ( {
162+ where : { applicantRecordId, reviewerId } ,
163+ transaction : t ,
164+ } ) ;
165+
166+ if ( ! reviewedRecord ) {
167+ throw new Error (
168+ `ReviewedApplicantRecord not found for applicantRecordId: ${ applicantRecordId } and reviewerId: ${ reviewerId } ` ,
169+ ) ;
170+ }
171+
172+ const oldReviewedScore = reviewedRecord . score || 0 ;
173+
174+ if ( review !== undefined ) {
175+ validateReviewScores ( review ) ;
176+
177+ reviewedRecord . review = {
178+ ...reviewedRecord . review ,
179+ ...review ,
180+ } ;
181+
182+ const { passionFSG, teamPlayer, desireToLearn, skill } =
183+ reviewedRecord . review ;
184+
185+ let calculatedScore = 0 ;
186+ if ( passionFSG !== undefined ) calculatedScore += passionFSG ;
187+ if ( teamPlayer !== undefined ) calculatedScore += teamPlayer ;
188+ if ( desireToLearn !== undefined ) calculatedScore += desireToLearn ;
189+ if ( skill !== undefined ) calculatedScore += skill ;
190+ reviewedRecord . score = calculatedScore ;
191+
192+ if ( review . skillCategory !== undefined ) {
193+ reviewedRecord . skillCategory = review . skillCategory ;
194+ }
195+ }
196+
197+ if ( status !== undefined ) {
198+ reviewedRecord . status = status ;
199+ }
200+
201+ await reviewedRecord . save ( { transaction : t } ) ;
202+
203+ const newReviewedScore = reviewedRecord . score || 0 ;
204+
205+ const applicantRecord = await ApplicantRecord . findOne ( {
206+ where : { id : applicantRecordId } ,
207+ transaction : t ,
208+ } ) ;
209+
210+ if ( ! applicantRecord ) {
211+ throw new Error (
212+ `ApplicantRecord not found for applicantRecordId: ${ applicantRecordId } ` ,
213+ ) ;
214+ }
215+
216+ const oldCombinedScore = applicantRecord . combined_score || 0 ;
217+ applicantRecord . combined_score =
218+ oldCombinedScore - oldReviewedScore + newReviewedScore ;
219+
220+ await applicantRecord . save ( { transaction : t } ) ;
221+
222+ return reviewedRecord ;
223+ } ) ;
224+
225+ return updatedRecord . toJSON ( ) as ReviewedApplicantRecordDTO ;
226+ } catch ( error : unknown ) {
227+ Logger . error (
228+ `Failed to update reviewed applicant record. Reason = ${ getErrorMessage (
229+ error ,
230+ ) } `,
231+ ) ;
232+ throw error ;
233+ }
234+ }
124235}
125236
126237export default ReviewedApplicantRecordService ;
0 commit comments