From 1780878f86be71bddcdb7d4077403fd5f8cd2f98 Mon Sep 17 00:00:00 2001 From: Jinil Sung Date: Tue, 28 Nov 2023 16:10:17 -0800 Subject: [PATCH 1/5] GRAD2-2389 & 2390 & 2412: task is complete. GRAD2-2389 & 2390 & 2412: task is complete. --- .../gradstudent/constant/TraxEventType.java | 18 ++ .../controller/DataConversionController.java | 4 +- .../service/DataConversionService.java | 158 ++++++++++++------ .../DataConversionControllerTest.java | 7 +- .../service/DataConversionServiceTest.java | 60 ++++++- 5 files changed, 183 insertions(+), 64 deletions(-) create mode 100644 api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/TraxEventType.java diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/TraxEventType.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/TraxEventType.java new file mode 100644 index 00000000..81724cc4 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/TraxEventType.java @@ -0,0 +1,18 @@ +package ca.bc.gov.educ.api.gradstudent.constant; + +public enum TraxEventType { + /* =========================================================== + Incremental updates from Trax to Grad + =============================================================*/ + /** + * Trax update type + */ + NEWSTUDENT, + UPD_DEMOG, + UPD_GRAD, + UPD_STD_STATUS, + XPROGRAM, + ASSESSMENT, + COURSE, + FI10ADD +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java index 6df8f1f1..50fc1be9 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java @@ -1,5 +1,6 @@ package ca.bc.gov.educ.api.gradstudent.controller; +import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.model.dto.*; import ca.bc.gov.educ.api.gradstudent.service.DataConversionService; import ca.bc.gov.educ.api.gradstudent.util.EducGradStudentApiConstants; @@ -45,10 +46,11 @@ public class DataConversionController { @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) public ResponseEntity saveStudentGradStatus(@PathVariable String studentID, @RequestParam(value = "ongoingUpdate", required = false, defaultValue = "false") boolean ongoingUpdate, + @RequestParam(value = "eventType", required = false) TraxEventType eventType, @RequestBody GraduationStudentRecord graduationStatus, @RequestHeader(name="Authorization") String accessToken) { logger.debug("Save Graduation Student Record for Student ID"); - var result = dataConversionService.saveGraduationStudentRecord(UUID.fromString(studentID),graduationStatus, ongoingUpdate, accessToken.replace(BEARER, "")); + var result = dataConversionService.saveGraduationStudentRecord(UUID.fromString(studentID),graduationStatus, ongoingUpdate, eventType, accessToken.replace(BEARER, "")); return response.GET(result); } diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java index c58bd69c..2c5eda2c 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java @@ -1,5 +1,6 @@ package ca.bc.gov.educ.api.gradstudent.service; +import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.model.dto.*; import ca.bc.gov.educ.api.gradstudent.model.entity.*; import ca.bc.gov.educ.api.gradstudent.model.transformer.GradStudentCareerProgramTransformer; @@ -88,42 +89,15 @@ public DataConversionService(WebClient webClient, * @return */ @Transactional - public GraduationStudentRecord saveGraduationStudentRecord(UUID studentID, GraduationStudentRecord graduationStatus, boolean ongoingUpdate, String accessToken) { + public GraduationStudentRecord saveGraduationStudentRecord(UUID studentID, GraduationStudentRecord graduationStatus, boolean ongoingUpdate, TraxEventType eventType, String accessToken) { Optional gradStatusOptional = graduationStatusRepository.findById(studentID); GraduationStudentRecordEntity sourceObject = graduationStatusTransformer.transformToEntity(graduationStatus); if (gradStatusOptional.isPresent()) { GraduationStudentRecordEntity gradEntity = gradStatusOptional.get(); - - if (!sourceObject.getProgram().equalsIgnoreCase(gradEntity.getProgram())) { - if(gradEntity.getProgram().equalsIgnoreCase("SCCP")) { - sourceObject.setProgramCompletionDate(null); - graduationStatusService.archiveStudentAchievements(sourceObject.getStudentID(),accessToken); - } else { - graduationStatusService.deleteStudentAchievements(sourceObject.getStudentID(), accessToken); - } - } - - BeanUtils.copyProperties(sourceObject, gradEntity, CREATE_USER, CREATE_DATE); - gradEntity.setUpdateDate(null); - gradEntity.setUpdateUser(null); - gradEntity = graduationStatusRepository.saveAndFlush(gradEntity); - if (ongoingUpdate) { - historyService.createStudentHistory(gradEntity, UPDATE_ONGOING_HISTORY_ACTIVITY_CODE); - } - if (constants.isStudentGuidPenXrefEnabled() && StringUtils.isNotBlank(graduationStatus.getPen())) { - saveStudentGuidPenXref(gradEntity.getStudentID(), graduationStatus.getPen()); - } + gradEntity = handleExistingGraduationStatus(sourceObject, gradEntity, graduationStatus.getPen(), true, eventType, accessToken); return graduationStatusTransformer.transformToDTO(gradEntity); } else { - sourceObject = graduationStatusRepository.saveAndFlush(sourceObject); - if (ongoingUpdate) { - historyService.createStudentHistory(sourceObject, ADD_ONGOING_HISTORY_ACTIVITY_CODE); - } else { - historyService.createStudentHistory(sourceObject, DATA_CONVERSION_HISTORY_ACTIVITY_CODE); - } - if (constants.isStudentGuidPenXrefEnabled()) { - saveStudentGuidPenXref(sourceObject.getStudentID(), graduationStatus.getPen()); - } + sourceObject = handleNewGraduationStatus(sourceObject, graduationStatus.getPen(), ongoingUpdate); return graduationStatusTransformer.transformToDTO(sourceObject); } } @@ -142,37 +116,14 @@ public StudentOptionalProgram saveStudentOptionalProgram(StudentOptionalProgramR if (gradStudentOptionalOptional.isPresent()) { // if it exists, just touch the entity in data conversion StudentOptionalProgramEntity gradEntity = gradStudentOptionalOptional.get(); - if (studentOptionalProgramReq.getStudentOptionalProgramData() != null) { - gradEntity.setStudentOptionalProgramData(studentOptionalProgramReq.getStudentOptionalProgramData()); - } - if (studentOptionalProgramReq.getOptionalProgramCompletionDate() != null) { - if (studentOptionalProgramReq.getOptionalProgramCompletionDate().length() > 7) { - gradEntity.setOptionalProgramCompletionDate(Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); - } else { - gradEntity.setOptionalProgramCompletionDate(EducGradStudentApiUtils.parsingProgramCompletionDate(studentOptionalProgramReq.getOptionalProgramCompletionDate())); - } - } - gradEntity.setUpdateDate(null); - gradEntity.setUpdateUser(null); - gradEntity = gradStudentOptionalProgramRepository.save(gradEntity); + gradEntity = handleExistingOptionalProgram(studentOptionalProgramReq, gradEntity); return gradStudentOptionalProgramTransformer.transformToDTO(gradEntity); } else { StudentOptionalProgramEntity sourceObject = new StudentOptionalProgramEntity(); sourceObject.setId(studentOptionalProgramReq.getId()); sourceObject.setStudentID(studentOptionalProgramReq.getStudentID()); sourceObject.setOptionalProgramID(studentOptionalProgramReq.getOptionalProgramID()); - if (studentOptionalProgramReq.getOptionalProgramCompletionDate() != null) { - if (studentOptionalProgramReq.getOptionalProgramCompletionDate().length() > 7) { - sourceObject.setOptionalProgramCompletionDate(Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); - } else { - sourceObject.setOptionalProgramCompletionDate(EducGradStudentApiUtils.parsingProgramCompletionDate(studentOptionalProgramReq.getOptionalProgramCompletionDate())); - } - } - if (sourceObject.getId() == null) { - sourceObject.setId(UUID.randomUUID()); - } - sourceObject = gradStudentOptionalProgramRepository.save(sourceObject); - historyService.createStudentOptionalProgramHistory(sourceObject, DATA_CONVERSION_HISTORY_ACTIVITY_CODE); + sourceObject = handleNewOptionalProgram(studentOptionalProgramReq, sourceObject); return gradStudentOptionalProgramTransformer.transformToDTO(sourceObject); } } @@ -264,4 +215,101 @@ public void deleteAllDependencies(UUID studentID) { gradStudentRecordHistoryRepository.deleteByStudentID(studentID); } + private GraduationStudentRecordEntity handleExistingGraduationStatus(GraduationStudentRecordEntity sourceObject, GraduationStudentRecordEntity targetObject, String pen, boolean ongoingUpdate, TraxEventType eventType, String accessToken) { + if (ongoingUpdate && !sourceObject.getProgram().equalsIgnoreCase(targetObject.getProgram())) { + if(targetObject.getProgram().equalsIgnoreCase("SCCP")) { + sourceObject.setProgramCompletionDate(null); + graduationStatusService.archiveStudentAchievements(sourceObject.getStudentID(),accessToken); + } else { + graduationStatusService.deleteStudentAchievements(sourceObject.getStudentID(), accessToken); + } + } + + if (ongoingUpdate && eventType != null) { + populateOngoingUpdateFields(sourceObject, targetObject, eventType); + } else { + BeanUtils.copyProperties(sourceObject, targetObject, CREATE_USER, CREATE_DATE); + } + targetObject.setUpdateDate(null); + targetObject.setUpdateUser(null); + targetObject = graduationStatusRepository.saveAndFlush(targetObject); + if (ongoingUpdate) { + historyService.createStudentHistory(targetObject, UPDATE_ONGOING_HISTORY_ACTIVITY_CODE); + } + if (constants.isStudentGuidPenXrefEnabled() && StringUtils.isNotBlank(pen)) { + saveStudentGuidPenXref(targetObject.getStudentID(), pen); + } + return targetObject; + } + + private GraduationStudentRecordEntity handleNewGraduationStatus(GraduationStudentRecordEntity newObject, String pen, boolean ongoingUpdate) { + newObject = graduationStatusRepository.saveAndFlush(newObject); + if (ongoingUpdate) { + historyService.createStudentHistory(newObject, ADD_ONGOING_HISTORY_ACTIVITY_CODE); + } else { + historyService.createStudentHistory(newObject, DATA_CONVERSION_HISTORY_ACTIVITY_CODE); + } + if (constants.isStudentGuidPenXrefEnabled() && StringUtils.isNotBlank(pen)) { + saveStudentGuidPenXref(newObject.getStudentID(), pen); + } + return newObject; + } + + private void populateOngoingUpdateFields(GraduationStudentRecordEntity sourceObject, GraduationStudentRecordEntity targetObject, TraxEventType eventType) { + if (eventType == TraxEventType.UPD_GRAD) { + // School of Record + targetObject.setSchoolOfRecord(sourceObject.getSchoolOfRecord()); + // GRAD Program + targetObject.setProgram(sourceObject.getProgram()); + // Adult Start Date + targetObject.setAdultStartDate(sourceObject.getAdultStartDate()); + // SLP Date + targetObject.setProgramCompletionDate(sourceObject.getProgramCompletionDate()); + // Student Grade + targetObject.setStudentGrade(sourceObject.getStudentGrade()); + // Citizenship + targetObject.setStudentCitizenship(sourceObject.getStudentCitizenship()); + } + if (eventType == TraxEventType.UPD_STD_STATUS) { + // Student Status + targetObject.setStudentStatus(sourceObject.getStudentStatus()); + } + // Others - common batch flags + targetObject.setRecalculateGradStatus(sourceObject.getRecalculateGradStatus()); + targetObject.setRecalculateProjectedGrad(sourceObject.getRecalculateProjectedGrad()); + } + + private StudentOptionalProgramEntity handleExistingOptionalProgram(StudentOptionalProgramRequestDTO studentOptionalProgramReq, StudentOptionalProgramEntity gradEntity) { + if (studentOptionalProgramReq.getStudentOptionalProgramData() != null) { + gradEntity.setStudentOptionalProgramData(studentOptionalProgramReq.getStudentOptionalProgramData()); + } + if (studentOptionalProgramReq.getOptionalProgramCompletionDate() != null) { + if (studentOptionalProgramReq.getOptionalProgramCompletionDate().length() > 7) { + gradEntity.setOptionalProgramCompletionDate(Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); + } else { + gradEntity.setOptionalProgramCompletionDate(EducGradStudentApiUtils.parsingProgramCompletionDate(studentOptionalProgramReq.getOptionalProgramCompletionDate())); + } + } + gradEntity.setUpdateDate(null); + gradEntity.setUpdateUser(null); + gradEntity = gradStudentOptionalProgramRepository.save(gradEntity); + return gradEntity; + } + + private StudentOptionalProgramEntity handleNewOptionalProgram(StudentOptionalProgramRequestDTO studentOptionalProgramReq, StudentOptionalProgramEntity sourceObject) { + if (studentOptionalProgramReq.getOptionalProgramCompletionDate() != null) { + if (studentOptionalProgramReq.getOptionalProgramCompletionDate().length() > 7) { + sourceObject.setOptionalProgramCompletionDate(Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); + } else { + sourceObject.setOptionalProgramCompletionDate(EducGradStudentApiUtils.parsingProgramCompletionDate(studentOptionalProgramReq.getOptionalProgramCompletionDate())); + } + } + if (sourceObject.getId() == null) { + sourceObject.setId(UUID.randomUUID()); + } + sourceObject = gradStudentOptionalProgramRepository.save(sourceObject); + historyService.createStudentOptionalProgramHistory(sourceObject, DATA_CONVERSION_HISTORY_ACTIVITY_CODE); + return sourceObject; + } + } diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java index 21c244e1..3ed38da0 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java @@ -1,5 +1,6 @@ package ca.bc.gov.educ.api.gradstudent.controller; +import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.messaging.jetstream.Publisher; import ca.bc.gov.educ.api.gradstudent.model.dto.GraduationStudentRecord; import ca.bc.gov.educ.api.gradstudent.model.dto.StudentCareerProgram; @@ -65,11 +66,11 @@ public void testSaveStudentGradStatus() { graduationStatus.setGpa("4"); graduationStatus.setProgramCompletionDate(EducGradStudentApiUtils.formatDate(new Date(System.currentTimeMillis()), "yyyy/MM")); - Mockito.when(dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus,false, "accessToken")).thenReturn(graduationStatus); + Mockito.when(dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus,false, null, "accessToken")).thenReturn(graduationStatus); Mockito.when(responseHelper.GET(graduationStatus)).thenReturn(ResponseEntity.ok().body(graduationStatus)); var result = dataConversionController - .saveStudentGradStatus(studentID.toString(), false, graduationStatus, "accessToken"); - Mockito.verify(dataConversionService).saveGraduationStudentRecord(studentID, graduationStatus,false, "accessToken"); + .saveStudentGradStatus(studentID.toString(), false, null, graduationStatus, "accessToken"); + Mockito.verify(dataConversionService).saveGraduationStudentRecord(studentID, graduationStatus,false, null, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); } diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java index bd94d58f..771bb94f 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java @@ -1,5 +1,6 @@ package ca.bc.gov.educ.api.gradstudent.service; +import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.messaging.NatsConnection; import ca.bc.gov.educ.api.gradstudent.messaging.jetstream.FetchGradStatusSubscriber; import ca.bc.gov.educ.api.gradstudent.messaging.jetstream.Publisher; @@ -105,7 +106,7 @@ public void testGraduationStudentRecordAsNew() { when(graduationStatusRepository.findById(studentID)).thenReturn(Optional.empty()); when(graduationStatusRepository.saveAndFlush(any(GraduationStudentRecordEntity.class))).thenReturn(graduationStatusEntity); - var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, false, "accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, false, null,"accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -149,7 +150,7 @@ public void testGraduationStudentRecordAsUpdate() { when(graduationStatusRepository.saveAndFlush(graduationStatusEntity)).thenReturn(savedGraduationStatus); when(graduationStatusRepository.countStudentGuidPenXrefRecord(studentID)).thenReturn(1L); - var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, "accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, input,false, null, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -202,7 +203,7 @@ public void testGraduationStudentRecordAsOngoingUpdate() { when(this.requestBodyMock.retrieve()).thenReturn(this.responseMock); when(this.responseMock.bodyToMono(Integer.class)).thenReturn(Mono.just(0)); - var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, "accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, TraxEventType.UPD_GRAD, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -216,6 +217,55 @@ public void testGraduationStudentRecordAsOngoingUpdate() { assertThat(result.getProgramCompletionDate()).isEqualTo(input.getProgramCompletionDate()); } + @Test + public void testGraduationStudentRecordAsOngoingUpdateForStudentStatus() { + // ID + UUID studentID = UUID.randomUUID(); + String mincode = "12345678"; + String oldStatus = "ARC"; + String newStatus = "CUR"; + + GraduationStudentRecordEntity graduationStatusEntity = new GraduationStudentRecordEntity(); + graduationStatusEntity.setStudentID(studentID); + graduationStatusEntity.setPen("123456789"); + graduationStatusEntity.setStudentStatus(oldStatus); + graduationStatusEntity.setRecalculateGradStatus("Y"); + graduationStatusEntity.setProgram("2018-EN"); + graduationStatusEntity.setSchoolOfRecord(mincode); + graduationStatusEntity.setSchoolAtGrad(mincode); + graduationStatusEntity.setGpa("4"); + graduationStatusEntity.setProgramCompletionDate(new Date(System.currentTimeMillis())); + + GraduationStudentRecord input = new GraduationStudentRecord(); + BeanUtils.copyProperties(graduationStatusEntity, input); + input.setStudentStatus(newStatus); + + GraduationStudentRecordEntity savedGraduationStatus = new GraduationStudentRecordEntity(); + BeanUtils.copyProperties(graduationStatusEntity, savedGraduationStatus); + savedGraduationStatus.setRecalculateGradStatus(null); + savedGraduationStatus.setStudentStatus(newStatus); + + when(graduationStatusRepository.findById(studentID)).thenReturn(Optional.of(graduationStatusEntity)); + when(graduationStatusRepository.saveAndFlush(graduationStatusEntity)).thenReturn(savedGraduationStatus); + + when(this.webClient.delete()).thenReturn(this.requestHeadersUriMock); + when(this.requestHeadersUriMock.uri(String.format(constants.getDeleteStudentAchievements(),studentID))).thenReturn(this.requestHeadersMock); + when(this.requestHeadersMock.headers(any(Consumer.class))).thenReturn(this.requestBodyMock); + when(this.requestBodyMock.retrieve()).thenReturn(this.responseMock); + when(this.responseMock.bodyToMono(Integer.class)).thenReturn(Mono.just(0)); + + var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, TraxEventType.UPD_STD_STATUS, "accessToken"); + + assertThat(result).isNotNull(); + assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); + assertThat(result.getPen()).isEqualTo(graduationStatusEntity.getPen()); + assertThat(result.getStudentStatus()).isEqualTo(newStatus); + assertThat(result.getSchoolOfRecord()).isEqualTo(graduationStatusEntity.getSchoolOfRecord()); + assertThat(result.getGpa()).isEqualTo(graduationStatusEntity.getGpa()); + + assertThat(result.getRecalculateGradStatus()).isNull(); + } + @Test public void testGraduationStudentRecordAsOngoingUpdateWhenSCCPStudent_isChangedTo_2018EN() { // ID @@ -255,7 +305,7 @@ public void testGraduationStudentRecordAsOngoingUpdateWhenSCCPStudent_isChangedT when(this.requestBodyMock.retrieve()).thenReturn(this.responseMock); when(this.responseMock.bodyToMono(Integer.class)).thenReturn(Mono.just(0)); - var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, "accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, TraxEventType.UPD_GRAD, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -292,7 +342,7 @@ public void testGraduationStudentRecordAsNewForOngoingUpdate() { when(graduationStatusRepository.findById(studentID)).thenReturn(Optional.empty()); when(graduationStatusRepository.saveAndFlush(any(GraduationStudentRecordEntity.class))).thenReturn(graduationStatusEntity); - var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, true, "accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, true, TraxEventType.NEWSTUDENT, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); From 75f673163a128446a071261709b5452f0d8e311f Mon Sep 17 00:00:00 2001 From: Jinil Sung Date: Wed, 29 Nov 2023 09:31:02 -0800 Subject: [PATCH 2/5] GRAD2-2389: Ongoing updates at field level is supported. GRAD2-2389: Ongoing updates at field level is supported. --- .../api/gradstudent/constant/FieldName.java | 15 ++ .../api/gradstudent/constant/FieldType.java | 6 + .../controller/DataConversionController.java | 18 ++- .../model/dto/OngoingUpdateFieldDTO.java | 38 +++++ .../model/dto/OngoingUpdateRequestDTO.java | 17 ++ .../service/DataConversionService.java | 147 ++++++++++++------ .../util/EducGradStudentApiConstants.java | 1 + .../DataConversionControllerTest.java | 50 +++++- .../service/DataConversionServiceTest.java | 75 ++++++--- 9 files changed, 286 insertions(+), 81 deletions(-) create mode 100644 api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldName.java create mode 100644 api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldType.java create mode 100644 api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateFieldDTO.java create mode 100644 api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateRequestDTO.java diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldName.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldName.java new file mode 100644 index 00000000..e72a2f41 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldName.java @@ -0,0 +1,15 @@ +package ca.bc.gov.educ.api.gradstudent.constant; + +public enum FieldName { + SCHOOL_OF_RECORD, + GRAD_PROGRAM, + ADULT_START_DATE, + SLP_DATE, + STUDENT_GRADE, + CITIZENSHIP, + STUDENT_STATUS, + + RECALC_GRAD_ALG, + RECALC_TVR + +} \ No newline at end of file diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldType.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldType.java new file mode 100644 index 00000000..0bfb7815 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/constant/FieldType.java @@ -0,0 +1,6 @@ +package ca.bc.gov.educ.api.gradstudent.constant; + +public enum FieldType { + STRING, + DATE +} \ No newline at end of file diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java index 50fc1be9..7c3b7e27 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionController.java @@ -1,6 +1,5 @@ package ca.bc.gov.educ.api.gradstudent.controller; -import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.model.dto.*; import ca.bc.gov.educ.api.gradstudent.service.DataConversionService; import ca.bc.gov.educ.api.gradstudent.util.EducGradStudentApiConstants; @@ -46,11 +45,20 @@ public class DataConversionController { @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) public ResponseEntity saveStudentGradStatus(@PathVariable String studentID, @RequestParam(value = "ongoingUpdate", required = false, defaultValue = "false") boolean ongoingUpdate, - @RequestParam(value = "eventType", required = false) TraxEventType eventType, - @RequestBody GraduationStudentRecord graduationStatus, - @RequestHeader(name="Authorization") String accessToken) { + @RequestBody GraduationStudentRecord graduationStatus) { logger.debug("Save Graduation Student Record for Student ID"); - var result = dataConversionService.saveGraduationStudentRecord(UUID.fromString(studentID),graduationStatus, ongoingUpdate, eventType, accessToken.replace(BEARER, "")); + var result = dataConversionService.saveGraduationStudentRecord(UUID.fromString(studentID),graduationStatus, ongoingUpdate); + return response.GET(result); + } + + @PostMapping(EducGradStudentApiConstants.CONV_GRADUATION_STATUS_FOR_ONGOING_UPDATES) + @PreAuthorize(PermissionsConstants.UPDATE_GRADUATION_STUDENT) + @Operation(summary = "Update Graduation Status At Field Level for Ongoing Updates", description = "Update Graduation Status At Field Level for Ongoing Updates", tags = { "Data Conversion" }) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) + public ResponseEntity updateGraduationStatusForOngoingUpdates(@RequestBody OngoingUpdateRequestDTO requestDTO, + @RequestHeader(name="Authorization") String accessToken) { + logger.debug("Save Graduation Student Record for Student ID"); + var result = dataConversionService.updateGraduationStatusByFields(requestDTO, accessToken.replace(BEARER, "")); return response.GET(result); } diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateFieldDTO.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateFieldDTO.java new file mode 100644 index 00000000..5673467b --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateFieldDTO.java @@ -0,0 +1,38 @@ +package ca.bc.gov.educ.api.gradstudent.model.dto; + +import ca.bc.gov.educ.api.gradstudent.constant.FieldName; +import ca.bc.gov.educ.api.gradstudent.constant.FieldType; +import lombok.Builder; +import lombok.Data; + +import java.util.Objects; + +@Builder +@Data +public class OngoingUpdateFieldDTO { + private FieldType type; + private FieldName name; + private Object value; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OngoingUpdateFieldDTO that = (OngoingUpdateFieldDTO) o; + return getName() == that.getName(); + } + + @Override + public int hashCode() { + return Objects.hash(getName()); + } + + @Override + public String toString() { + return "OngoingUpdateFieldDTO{" + + "type=" + type + + ", name=" + name + + ", value=" + value + + '}'; + } +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateRequestDTO.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateRequestDTO.java new file mode 100644 index 00000000..28413d12 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/model/dto/OngoingUpdateRequestDTO.java @@ -0,0 +1,17 @@ +package ca.bc.gov.educ.api.gradstudent.model.dto; + +import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@NoArgsConstructor +@Data +public class OngoingUpdateRequestDTO { + private String studentID; + private String pen; + private TraxEventType eventType; + private List updateFields = new ArrayList<>(); +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java index 2c5eda2c..6f5add0a 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java @@ -1,5 +1,6 @@ package ca.bc.gov.educ.api.gradstudent.service; +import ca.bc.gov.educ.api.gradstudent.constant.FieldName; import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.model.dto.*; import ca.bc.gov.educ.api.gradstudent.model.entity.*; @@ -20,7 +21,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.reactive.function.client.WebClient; -import java.sql.Date; import java.time.LocalDateTime; import java.util.*; @@ -40,8 +40,7 @@ public class DataConversionService { private static final String ADD_ONGOING_HISTORY_ACTIVITY_CODE = "TRAXADD"; private static final String UPDATE_ONGOING_HISTORY_ACTIVITY_CODE = "TRAXUPDATE"; private static final String DELETE_ONGOING_HISTORY_ACTIVITY_CODE = "TRAXDELETE"; - public static final String STUDENT_STATUS_MERGED = "MER"; - + private static final String ONGOING_UPDATE_FIELD_STR = " ==> {} for old value = {}"; final WebClient webClient; final GraduationStudentRecordRepository graduationStatusRepository; final GraduationStatusTransformer graduationStatusTransformer; @@ -83,18 +82,14 @@ public DataConversionService(WebClient webClient, /** * Create or Update a GraduationStudentRecord - * - * @param studentID - * @param graduationStatus - * @return */ @Transactional - public GraduationStudentRecord saveGraduationStudentRecord(UUID studentID, GraduationStudentRecord graduationStatus, boolean ongoingUpdate, TraxEventType eventType, String accessToken) { + public GraduationStudentRecord saveGraduationStudentRecord(UUID studentID, GraduationStudentRecord graduationStatus, boolean ongoingUpdate) { Optional gradStatusOptional = graduationStatusRepository.findById(studentID); GraduationStudentRecordEntity sourceObject = graduationStatusTransformer.transformToEntity(graduationStatus); if (gradStatusOptional.isPresent()) { GraduationStudentRecordEntity gradEntity = gradStatusOptional.get(); - gradEntity = handleExistingGraduationStatus(sourceObject, gradEntity, graduationStatus.getPen(), true, eventType, accessToken); + gradEntity = handleExistingGraduationStatus(sourceObject, gradEntity, graduationStatus.getPen(), ongoingUpdate); return graduationStatusTransformer.transformToDTO(gradEntity); } else { sourceObject = handleNewGraduationStatus(sourceObject, graduationStatus.getPen(), ongoingUpdate); @@ -102,6 +97,30 @@ public GraduationStudentRecord saveGraduationStudentRecord(UUID studentID, Gradu } } + /** + * Update Graduation Status at field level for Ongoing Updates + */ + @Transactional + public GraduationStudentRecord updateGraduationStatusByFields(OngoingUpdateRequestDTO requestDTO, String accessToken) { + UUID studentID = UUID.fromString(requestDTO.getStudentID()); + TraxEventType eventType = requestDTO.getEventType(); + log.info("Perform ongoing update event [{}] for studentID = {}", eventType, studentID); + Optional gradStatusOptional = graduationStatusRepository.findById(studentID); + if (gradStatusOptional.isPresent()) { + GraduationStudentRecordEntity gradEntity = gradStatusOptional.get(); + populateOngoingUpdateFields(requestDTO.getUpdateFields(), gradEntity, accessToken); + gradEntity.setUpdateDate(null); + gradEntity.setUpdateUser(null); + gradEntity = graduationStatusRepository.saveAndFlush(gradEntity); + historyService.createStudentHistory(gradEntity, UPDATE_ONGOING_HISTORY_ACTIVITY_CODE); + if (constants.isStudentGuidPenXrefEnabled() && StringUtils.isNotBlank(requestDTO.getPen())) { + saveStudentGuidPenXref(gradEntity.getStudentID(), requestDTO.getPen()); + } + return graduationStatusTransformer.transformToDTO(gradEntity); + } + return null; + } + @Transactional @Retry(name = "generalpostcall") public StudentOptionalProgram saveStudentOptionalProgram(StudentOptionalProgramRequestDTO studentOptionalProgramReq, String accessToken) { @@ -215,21 +234,8 @@ public void deleteAllDependencies(UUID studentID) { gradStudentRecordHistoryRepository.deleteByStudentID(studentID); } - private GraduationStudentRecordEntity handleExistingGraduationStatus(GraduationStudentRecordEntity sourceObject, GraduationStudentRecordEntity targetObject, String pen, boolean ongoingUpdate, TraxEventType eventType, String accessToken) { - if (ongoingUpdate && !sourceObject.getProgram().equalsIgnoreCase(targetObject.getProgram())) { - if(targetObject.getProgram().equalsIgnoreCase("SCCP")) { - sourceObject.setProgramCompletionDate(null); - graduationStatusService.archiveStudentAchievements(sourceObject.getStudentID(),accessToken); - } else { - graduationStatusService.deleteStudentAchievements(sourceObject.getStudentID(), accessToken); - } - } - - if (ongoingUpdate && eventType != null) { - populateOngoingUpdateFields(sourceObject, targetObject, eventType); - } else { - BeanUtils.copyProperties(sourceObject, targetObject, CREATE_USER, CREATE_DATE); - } + private GraduationStudentRecordEntity handleExistingGraduationStatus(GraduationStudentRecordEntity sourceObject, GraduationStudentRecordEntity targetObject, String pen, boolean ongoingUpdate) { + BeanUtils.copyProperties(sourceObject, targetObject, CREATE_USER, CREATE_DATE); targetObject.setUpdateDate(null); targetObject.setUpdateUser(null); targetObject = graduationStatusRepository.saveAndFlush(targetObject); @@ -255,28 +261,75 @@ private GraduationStudentRecordEntity handleNewGraduationStatus(GraduationStuden return newObject; } - private void populateOngoingUpdateFields(GraduationStudentRecordEntity sourceObject, GraduationStudentRecordEntity targetObject, TraxEventType eventType) { - if (eventType == TraxEventType.UPD_GRAD) { - // School of Record - targetObject.setSchoolOfRecord(sourceObject.getSchoolOfRecord()); - // GRAD Program - targetObject.setProgram(sourceObject.getProgram()); - // Adult Start Date - targetObject.setAdultStartDate(sourceObject.getAdultStartDate()); - // SLP Date - targetObject.setProgramCompletionDate(sourceObject.getProgramCompletionDate()); - // Student Grade - targetObject.setStudentGrade(sourceObject.getStudentGrade()); - // Citizenship - targetObject.setStudentCitizenship(sourceObject.getStudentCitizenship()); - } - if (eventType == TraxEventType.UPD_STD_STATUS) { - // Student Status - targetObject.setStudentStatus(sourceObject.getStudentStatus()); + private void populateOngoingUpdateFields(List fields, GraduationStudentRecordEntity targetObject, String accessToken) { + fields.forEach(f -> { + if (f.getName() == FieldName.GRAD_PROGRAM) { + String newProgram = (String) f.getValue(); + String currentProgram = targetObject.getProgram(); + if (!StringUtils.equalsIgnoreCase(currentProgram, newProgram)) { + if("SCCP".equalsIgnoreCase(currentProgram)) { + log.info(" {} ==> {}: Archive Student Achievements and SLP_DATE is set to null.", currentProgram, newProgram); + targetObject.setProgramCompletionDate(null); + graduationStatusService.archiveStudentAchievements(targetObject.getStudentID(),accessToken); + } else { + log.info(" {} ==> {}: Delete Student Achievements.", currentProgram, newProgram); + graduationStatusService.deleteStudentAchievements(targetObject.getStudentID(), accessToken); + } + } + } + populate(f, targetObject); + }); + } + + private void populate(OngoingUpdateFieldDTO field, GraduationStudentRecordEntity targetObject) { + switch (field.getName()) { + case SCHOOL_OF_RECORD -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, targetObject.getSchoolOfRecord()); + targetObject.setSchoolOfRecord(getStringValue(field.getValue())); + } + case GRAD_PROGRAM -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, targetObject.getProgram()); + targetObject.setProgram(getStringValue(field.getValue())); + } + case ADULT_START_DATE -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, EducGradStudentApiUtils.formatDate(targetObject.getAdultStartDate(), EducGradStudentApiConstants.DEFAULT_DATE_FORMAT)); + // date format: yyyy-MM-dd + Date adultStartDate = EducGradStudentApiUtils.parseDate((String) field.getValue()); + targetObject.setAdultStartDate(adultStartDate); + } + case SLP_DATE -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, EducGradStudentApiUtils.formatDate(targetObject.getProgramCompletionDate(), EducGradStudentApiConstants.PROGRAM_COMPLETION_DATE_FORMAT)); + // date format: yyyy/MM + Date programCompletionDate = EducGradStudentApiUtils.parsingProgramCompletionDate((String) field.getValue()); + targetObject.setProgramCompletionDate(programCompletionDate); + } + case STUDENT_GRADE -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, targetObject.getStudentGrade()); + targetObject.setStudentGrade(getStringValue(field.getValue())); + } + case CITIZENSHIP -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, targetObject.getStudentCitizenship()); + targetObject.setStudentCitizenship(getStringValue(field.getValue())); + } + case STUDENT_STATUS -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, targetObject.getStudentStatus()); + targetObject.setStudentStatus(getStringValue(field.getValue())); + } + case RECALC_GRAD_ALG -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, targetObject.getRecalculateGradStatus()); + targetObject.setRecalculateGradStatus(getStringValue(field.getValue())); + } + case RECALC_TVR -> { + log.info(ONGOING_UPDATE_FIELD_STR, field, targetObject.getRecalculateProjectedGrad()); + targetObject.setRecalculateProjectedGrad(getStringValue(field.getValue())); + } } - // Others - common batch flags - targetObject.setRecalculateGradStatus(sourceObject.getRecalculateGradStatus()); - targetObject.setRecalculateProjectedGrad(sourceObject.getRecalculateProjectedGrad()); + } + + private String getStringValue(Object value) { + if (value == null) + return null; + return (String) value; } private StudentOptionalProgramEntity handleExistingOptionalProgram(StudentOptionalProgramRequestDTO studentOptionalProgramReq, StudentOptionalProgramEntity gradEntity) { @@ -285,7 +338,7 @@ private StudentOptionalProgramEntity handleExistingOptionalProgram(StudentOption } if (studentOptionalProgramReq.getOptionalProgramCompletionDate() != null) { if (studentOptionalProgramReq.getOptionalProgramCompletionDate().length() > 7) { - gradEntity.setOptionalProgramCompletionDate(Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); + gradEntity.setOptionalProgramCompletionDate(java.sql.Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); } else { gradEntity.setOptionalProgramCompletionDate(EducGradStudentApiUtils.parsingProgramCompletionDate(studentOptionalProgramReq.getOptionalProgramCompletionDate())); } @@ -299,7 +352,7 @@ private StudentOptionalProgramEntity handleExistingOptionalProgram(StudentOption private StudentOptionalProgramEntity handleNewOptionalProgram(StudentOptionalProgramRequestDTO studentOptionalProgramReq, StudentOptionalProgramEntity sourceObject) { if (studentOptionalProgramReq.getOptionalProgramCompletionDate() != null) { if (studentOptionalProgramReq.getOptionalProgramCompletionDate().length() > 7) { - sourceObject.setOptionalProgramCompletionDate(Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); + sourceObject.setOptionalProgramCompletionDate(java.sql.Date.valueOf(studentOptionalProgramReq.getOptionalProgramCompletionDate())); } else { sourceObject.setOptionalProgramCompletionDate(EducGradStudentApiUtils.parsingProgramCompletionDate(studentOptionalProgramReq.getOptionalProgramCompletionDate())); } diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/util/EducGradStudentApiConstants.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/util/EducGradStudentApiConstants.java index 39f6117c..521be844 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/util/EducGradStudentApiConstants.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/util/EducGradStudentApiConstants.java @@ -100,6 +100,7 @@ public class EducGradStudentApiConstants { public static final String CONV_GRADUATION_STATUS_BY_STUDENT_ID = "/conv/studentid/{studentID}"; public static final String CONV_STUDENT_OPTIONAL_PROGRAM = "/conv/studentoptionalprogram"; public static final String CONV_STUDENT_CAREER_PROGRAM = "/conv/studentcareerprogram"; + public static final String CONV_GRADUATION_STATUS_FOR_ONGOING_UPDATES = "/conv/ongoingupdate/gradstatus"; public static final String CONV_STUDENT_OPTIONAL_PROGRAM_BY_STUDENT_ID = "/conv/studentoptionalprogram/{optionalProgramID}/{studentID}"; public static final String CONV_STUDENT_CAREER_PROGRAM_BY_STUDENT_ID = "/conv/studentcareerprogram/{careerProgramCode}/{studentID}"; diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java index 3ed38da0..774235c7 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/controller/DataConversionControllerTest.java @@ -1,11 +1,10 @@ package ca.bc.gov.educ.api.gradstudent.controller; +import ca.bc.gov.educ.api.gradstudent.constant.FieldName; +import ca.bc.gov.educ.api.gradstudent.constant.FieldType; import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.messaging.jetstream.Publisher; -import ca.bc.gov.educ.api.gradstudent.model.dto.GraduationStudentRecord; -import ca.bc.gov.educ.api.gradstudent.model.dto.StudentCareerProgram; -import ca.bc.gov.educ.api.gradstudent.model.dto.StudentOptionalProgram; -import ca.bc.gov.educ.api.gradstudent.model.dto.StudentOptionalProgramRequestDTO; +import ca.bc.gov.educ.api.gradstudent.model.dto.*; import ca.bc.gov.educ.api.gradstudent.service.DataConversionService; import ca.bc.gov.educ.api.gradstudent.service.HistoryService; import ca.bc.gov.educ.api.gradstudent.util.EducGradStudentApiUtils; @@ -66,11 +65,48 @@ public void testSaveStudentGradStatus() { graduationStatus.setGpa("4"); graduationStatus.setProgramCompletionDate(EducGradStudentApiUtils.formatDate(new Date(System.currentTimeMillis()), "yyyy/MM")); - Mockito.when(dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus,false, null, "accessToken")).thenReturn(graduationStatus); + Mockito.when(dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus,false)).thenReturn(graduationStatus); Mockito.when(responseHelper.GET(graduationStatus)).thenReturn(ResponseEntity.ok().body(graduationStatus)); var result = dataConversionController - .saveStudentGradStatus(studentID.toString(), false, null, graduationStatus, "accessToken"); - Mockito.verify(dataConversionService).saveGraduationStudentRecord(studentID, graduationStatus,false, null, "accessToken"); + .saveStudentGradStatus(studentID.toString(), false, graduationStatus); + Mockito.verify(dataConversionService).saveGraduationStudentRecord(studentID, graduationStatus,false); + assertThat(result).isNotNull(); + assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + public void testSaveStudentGradStatusByFields() { + // ID + UUID studentID = UUID.randomUUID(); + String pen = "123456789"; + String mincode = "12345678"; + + GraduationStudentRecord graduationStatus = new GraduationStudentRecord(); + graduationStatus.setStudentID(studentID); + graduationStatus.setPen(pen); + graduationStatus.setStudentStatus("A"); + graduationStatus.setRecalculateGradStatus("Y"); + graduationStatus.setProgram("2018-PF"); + graduationStatus.setSchoolOfRecord(mincode); + graduationStatus.setSchoolAtGrad(mincode); + graduationStatus.setGpa("4"); + graduationStatus.setProgramCompletionDate(EducGradStudentApiUtils.formatDate(new Date(System.currentTimeMillis()), "yyyy/MM")); + + OngoingUpdateRequestDTO requestDTO = new OngoingUpdateRequestDTO(); + requestDTO.setPen(pen); + requestDTO.setStudentID(studentID.toString()); + requestDTO.setEventType(TraxEventType.UPD_GRAD); + + OngoingUpdateFieldDTO field = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.GRAD_PROGRAM).value("2018-EN") + .build(); + requestDTO.getUpdateFields().add(field); + + Mockito.when(dataConversionService.updateGraduationStatusByFields(requestDTO, "accessToken")).thenReturn(graduationStatus); + Mockito.when(responseHelper.GET(graduationStatus)).thenReturn(ResponseEntity.ok().body(graduationStatus)); + var result = dataConversionController + .updateGraduationStatusForOngoingUpdates(requestDTO, "accessToken"); + Mockito.verify(dataConversionService).updateGraduationStatusByFields(requestDTO, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); } diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java index 771bb94f..c3a69077 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java @@ -1,5 +1,7 @@ package ca.bc.gov.educ.api.gradstudent.service; +import ca.bc.gov.educ.api.gradstudent.constant.FieldName; +import ca.bc.gov.educ.api.gradstudent.constant.FieldType; import ca.bc.gov.educ.api.gradstudent.constant.TraxEventType; import ca.bc.gov.educ.api.gradstudent.messaging.NatsConnection; import ca.bc.gov.educ.api.gradstudent.messaging.jetstream.FetchGradStatusSubscriber; @@ -106,7 +108,7 @@ public void testGraduationStudentRecordAsNew() { when(graduationStatusRepository.findById(studentID)).thenReturn(Optional.empty()); when(graduationStatusRepository.saveAndFlush(any(GraduationStudentRecordEntity.class))).thenReturn(graduationStatusEntity); - var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, false, null,"accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, false); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -150,7 +152,7 @@ public void testGraduationStudentRecordAsUpdate() { when(graduationStatusRepository.saveAndFlush(graduationStatusEntity)).thenReturn(savedGraduationStatus); when(graduationStatusRepository.countStudentGuidPenXrefRecord(studentID)).thenReturn(1L); - var result = dataConversionService.saveGraduationStudentRecord(studentID, input,false, null, "accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, input, false); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -168,13 +170,14 @@ public void testGraduationStudentRecordAsUpdate() { public void testGraduationStudentRecordAsOngoingUpdate() { // ID UUID studentID = UUID.randomUUID(); + String pen = "123456789"; String mincode = "12345678"; String oldProgram = "2018-EN"; String newProgram = "2018-PF"; GraduationStudentRecordEntity graduationStatusEntity = new GraduationStudentRecordEntity(); graduationStatusEntity.setStudentID(studentID); - graduationStatusEntity.setPen("123456789"); + graduationStatusEntity.setPen(pen); graduationStatusEntity.setStudentStatus("A"); graduationStatusEntity.setRecalculateGradStatus("Y"); graduationStatusEntity.setProgram(oldProgram); @@ -183,10 +186,20 @@ public void testGraduationStudentRecordAsOngoingUpdate() { graduationStatusEntity.setGpa("4"); graduationStatusEntity.setProgramCompletionDate(new Date(System.currentTimeMillis())); - GraduationStudentRecord input = new GraduationStudentRecord(); - BeanUtils.copyProperties(graduationStatusEntity, input); - input.setProgramCompletionDate(EducGradStudentApiUtils.formatDate(graduationStatusEntity.getProgramCompletionDate(), "yyyy/MM" )); - input.setProgram(newProgram); + OngoingUpdateRequestDTO requestDTO = new OngoingUpdateRequestDTO(); + requestDTO.setPen(pen); + requestDTO.setStudentID(studentID.toString()); + requestDTO.setEventType(TraxEventType.UPD_GRAD); + + OngoingUpdateFieldDTO field1 = OngoingUpdateFieldDTO.builder() + .type(FieldType.DATE).name(FieldName.SLP_DATE).value(EducGradStudentApiUtils.formatDate(graduationStatusEntity.getProgramCompletionDate(), "yyyy/MM")) + .build(); + requestDTO.getUpdateFields().add(field1); + + OngoingUpdateFieldDTO field2 = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.GRAD_PROGRAM).value(newProgram) + .build(); + requestDTO.getUpdateFields().add(field2); GraduationStudentRecordEntity savedGraduationStatus = new GraduationStudentRecordEntity(); BeanUtils.copyProperties(graduationStatusEntity, savedGraduationStatus); @@ -203,7 +216,7 @@ public void testGraduationStudentRecordAsOngoingUpdate() { when(this.requestBodyMock.retrieve()).thenReturn(this.responseMock); when(this.responseMock.bodyToMono(Integer.class)).thenReturn(Mono.just(0)); - var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, TraxEventType.UPD_GRAD, "accessToken"); + var result = dataConversionService.updateGraduationStatusByFields(requestDTO, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -214,20 +227,21 @@ public void testGraduationStudentRecordAsOngoingUpdate() { assertThat(result.getGpa()).isEqualTo(graduationStatusEntity.getGpa()); assertThat(result.getRecalculateGradStatus()).isNull(); - assertThat(result.getProgramCompletionDate()).isEqualTo(input.getProgramCompletionDate()); + assertThat(result.getProgramCompletionDate()).isEqualTo(field1.getValue()); } @Test public void testGraduationStudentRecordAsOngoingUpdateForStudentStatus() { // ID UUID studentID = UUID.randomUUID(); + String pen = "123456789"; String mincode = "12345678"; String oldStatus = "ARC"; String newStatus = "CUR"; GraduationStudentRecordEntity graduationStatusEntity = new GraduationStudentRecordEntity(); graduationStatusEntity.setStudentID(studentID); - graduationStatusEntity.setPen("123456789"); + graduationStatusEntity.setPen(pen); graduationStatusEntity.setStudentStatus(oldStatus); graduationStatusEntity.setRecalculateGradStatus("Y"); graduationStatusEntity.setProgram("2018-EN"); @@ -236,9 +250,15 @@ public void testGraduationStudentRecordAsOngoingUpdateForStudentStatus() { graduationStatusEntity.setGpa("4"); graduationStatusEntity.setProgramCompletionDate(new Date(System.currentTimeMillis())); - GraduationStudentRecord input = new GraduationStudentRecord(); - BeanUtils.copyProperties(graduationStatusEntity, input); - input.setStudentStatus(newStatus); + OngoingUpdateRequestDTO requestDTO = new OngoingUpdateRequestDTO(); + requestDTO.setPen(pen); + requestDTO.setStudentID(studentID.toString()); + requestDTO.setEventType(TraxEventType.UPD_STD_STATUS); + + OngoingUpdateFieldDTO field = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.STUDENT_STATUS).value(newStatus) + .build(); + requestDTO.getUpdateFields().add(field); GraduationStudentRecordEntity savedGraduationStatus = new GraduationStudentRecordEntity(); BeanUtils.copyProperties(graduationStatusEntity, savedGraduationStatus); @@ -254,7 +274,7 @@ public void testGraduationStudentRecordAsOngoingUpdateForStudentStatus() { when(this.requestBodyMock.retrieve()).thenReturn(this.responseMock); when(this.responseMock.bodyToMono(Integer.class)).thenReturn(Mono.just(0)); - var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, TraxEventType.UPD_STD_STATUS, "accessToken"); + var result = dataConversionService.updateGraduationStatusByFields(requestDTO, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -270,13 +290,14 @@ public void testGraduationStudentRecordAsOngoingUpdateForStudentStatus() { public void testGraduationStudentRecordAsOngoingUpdateWhenSCCPStudent_isChangedTo_2018EN() { // ID UUID studentID = UUID.randomUUID(); + String pen = "123456789"; String mincode = "12345678"; String oldProgram = "SCCP"; String newProgram = "2018-EN"; GraduationStudentRecordEntity graduationStatusEntity = new GraduationStudentRecordEntity(); graduationStatusEntity.setStudentID(studentID); - graduationStatusEntity.setPen("123456789"); + graduationStatusEntity.setPen(pen); graduationStatusEntity.setStudentStatus("A"); graduationStatusEntity.setRecalculateGradStatus("Y"); graduationStatusEntity.setProgram(oldProgram); @@ -285,10 +306,20 @@ public void testGraduationStudentRecordAsOngoingUpdateWhenSCCPStudent_isChangedT graduationStatusEntity.setGpa("4"); graduationStatusEntity.setProgramCompletionDate(new Date(System.currentTimeMillis())); - GraduationStudentRecord input = new GraduationStudentRecord(); - BeanUtils.copyProperties(graduationStatusEntity, input); - input.setProgramCompletionDate(EducGradStudentApiUtils.formatDate(graduationStatusEntity.getProgramCompletionDate(), "yyyy/MM" )); - input.setProgram(newProgram); + OngoingUpdateRequestDTO requestDTO = new OngoingUpdateRequestDTO(); + requestDTO.setPen(pen); + requestDTO.setStudentID(studentID.toString()); + requestDTO.setEventType(TraxEventType.UPD_GRAD); + + OngoingUpdateFieldDTO field1 = OngoingUpdateFieldDTO.builder() + .type(FieldType.DATE).name(FieldName.SLP_DATE).value(EducGradStudentApiUtils.formatDate(graduationStatusEntity.getProgramCompletionDate(), "yyyy/MM")) + .build(); + requestDTO.getUpdateFields().add(field1); + + OngoingUpdateFieldDTO field2 = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.GRAD_PROGRAM).value(newProgram) + .build(); + requestDTO.getUpdateFields().add(field2); GraduationStudentRecordEntity savedGraduationStatus = new GraduationStudentRecordEntity(); BeanUtils.copyProperties(graduationStatusEntity, savedGraduationStatus); @@ -305,7 +336,7 @@ public void testGraduationStudentRecordAsOngoingUpdateWhenSCCPStudent_isChangedT when(this.requestBodyMock.retrieve()).thenReturn(this.responseMock); when(this.responseMock.bodyToMono(Integer.class)).thenReturn(Mono.just(0)); - var result = dataConversionService.saveGraduationStudentRecord(studentID, input,true, TraxEventType.UPD_GRAD, "accessToken"); + var result = dataConversionService.updateGraduationStatusByFields(requestDTO, "accessToken"); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); @@ -316,7 +347,7 @@ public void testGraduationStudentRecordAsOngoingUpdateWhenSCCPStudent_isChangedT assertThat(result.getGpa()).isEqualTo(graduationStatusEntity.getGpa()); assertThat(result.getRecalculateGradStatus()).isNull(); - assertThat(result.getProgramCompletionDate()).isEqualTo(input.getProgramCompletionDate()); + assertThat(result.getProgramCompletionDate()).isEqualTo(field1.getValue()); } @Test @@ -342,7 +373,7 @@ public void testGraduationStudentRecordAsNewForOngoingUpdate() { when(graduationStatusRepository.findById(studentID)).thenReturn(Optional.empty()); when(graduationStatusRepository.saveAndFlush(any(GraduationStudentRecordEntity.class))).thenReturn(graduationStatusEntity); - var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, true, TraxEventType.NEWSTUDENT, "accessToken"); + var result = dataConversionService.saveGraduationStudentRecord(studentID, graduationStatus, true); assertThat(result).isNotNull(); assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); From c2ce3b45061dd2042800ac4918dc5aef574cb5e8 Mon Sep 17 00:00:00 2001 From: Jinil Sung Date: Wed, 29 Nov 2023 15:05:40 -0800 Subject: [PATCH 3/5] Clean up the message. Clean up the message. --- .../gov/educ/api/gradstudent/service/DataConversionService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java index 6f5add0a..bd307665 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionService.java @@ -40,7 +40,7 @@ public class DataConversionService { private static final String ADD_ONGOING_HISTORY_ACTIVITY_CODE = "TRAXADD"; private static final String UPDATE_ONGOING_HISTORY_ACTIVITY_CODE = "TRAXUPDATE"; private static final String DELETE_ONGOING_HISTORY_ACTIVITY_CODE = "TRAXDELETE"; - private static final String ONGOING_UPDATE_FIELD_STR = " ==> {} for old value = {}"; + private static final String ONGOING_UPDATE_FIELD_STR = " ==> {} for old value={}"; final WebClient webClient; final GraduationStudentRecordRepository graduationStatusRepository; final GraduationStatusTransformer graduationStatusTransformer; From 1422c68c5b5037d9f12768c5ffff83b980e28be5 Mon Sep 17 00:00:00 2001 From: Jinil Sung Date: Thu, 30 Nov 2023 09:12:08 -0800 Subject: [PATCH 4/5] More coverage on the new codes. More coverage on the new codes. --- .../service/DataConversionServiceTest.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java index c3a69077..1ec6ae96 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java @@ -171,18 +171,22 @@ public void testGraduationStudentRecordAsOngoingUpdate() { // ID UUID studentID = UUID.randomUUID(); String pen = "123456789"; - String mincode = "12345678"; + String oldMincode = "12312312"; + String newMincode = "12345678"; String oldProgram = "2018-EN"; String newProgram = "2018-PF"; + String oldGrade = "12"; + String newGrade = "11"; GraduationStudentRecordEntity graduationStatusEntity = new GraduationStudentRecordEntity(); graduationStatusEntity.setStudentID(studentID); graduationStatusEntity.setPen(pen); graduationStatusEntity.setStudentStatus("A"); + graduationStatusEntity.setStudentGrade(oldGrade); graduationStatusEntity.setRecalculateGradStatus("Y"); graduationStatusEntity.setProgram(oldProgram); - graduationStatusEntity.setSchoolOfRecord(mincode); - graduationStatusEntity.setSchoolAtGrad(mincode); + graduationStatusEntity.setSchoolOfRecord(oldMincode); + graduationStatusEntity.setSchoolAtGrad(oldMincode); graduationStatusEntity.setGpa("4"); graduationStatusEntity.setProgramCompletionDate(new Date(System.currentTimeMillis())); @@ -201,11 +205,40 @@ public void testGraduationStudentRecordAsOngoingUpdate() { .build(); requestDTO.getUpdateFields().add(field2); + OngoingUpdateFieldDTO field3 = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.STUDENT_GRADE).value(newGrade) + .build(); + requestDTO.getUpdateFields().add(field3); + + OngoingUpdateFieldDTO field4 = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.CITIZENSHIP).value("C") + .build(); + requestDTO.getUpdateFields().add(field4); + + OngoingUpdateFieldDTO field5 = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.SCHOOL_OF_RECORD).value(newMincode) + .build(); + requestDTO.getUpdateFields().add(field5); + + OngoingUpdateFieldDTO field6 = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.RECALC_GRAD_ALG).value(null) + .build(); + requestDTO.getUpdateFields().add(field6); + + OngoingUpdateFieldDTO field7 = OngoingUpdateFieldDTO.builder() + .type(FieldType.STRING).name(FieldName.RECALC_TVR).value("Y") + .build(); + requestDTO.getUpdateFields().add(field7); + GraduationStudentRecordEntity savedGraduationStatus = new GraduationStudentRecordEntity(); BeanUtils.copyProperties(graduationStatusEntity, savedGraduationStatus); savedGraduationStatus.setRecalculateGradStatus(null); + savedGraduationStatus.setRecalculateProjectedGrad("Y"); savedGraduationStatus.setProgramCompletionDate(graduationStatusEntity.getProgramCompletionDate()); savedGraduationStatus.setProgram(newProgram); + savedGraduationStatus.setStudentGrade(newGrade); + savedGraduationStatus.setStudentCitizenship("C"); + savedGraduationStatus.setSchoolOfRecord(newMincode); when(graduationStatusRepository.findById(studentID)).thenReturn(Optional.of(graduationStatusEntity)); when(graduationStatusRepository.saveAndFlush(graduationStatusEntity)).thenReturn(savedGraduationStatus); From 170090f3cfef81c74a7820c9af7044d79be97d73 Mon Sep 17 00:00:00 2001 From: Jinil Sung Date: Thu, 30 Nov 2023 09:19:58 -0800 Subject: [PATCH 5/5] Improved asserts in ongoing updates unit tests. Improved asserts in ongoing updates unit tests. --- .../gradstudent/service/DataConversionServiceTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java index 1ec6ae96..6e4b7677 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradstudent/service/DataConversionServiceTest.java @@ -255,12 +255,15 @@ public void testGraduationStudentRecordAsOngoingUpdate() { assertThat(result.getStudentID()).isEqualTo(graduationStatusEntity.getStudentID()); assertThat(result.getPen()).isEqualTo(graduationStatusEntity.getPen()); assertThat(result.getStudentStatus()).isEqualTo(graduationStatusEntity.getStudentStatus()); - assertThat(result.getProgram()).isEqualTo(newProgram); - assertThat(result.getSchoolOfRecord()).isEqualTo(graduationStatusEntity.getSchoolOfRecord()); assertThat(result.getGpa()).isEqualTo(graduationStatusEntity.getGpa()); - assertThat(result.getRecalculateGradStatus()).isNull(); assertThat(result.getProgramCompletionDate()).isEqualTo(field1.getValue()); + assertThat(result.getProgram()).isEqualTo(field2.getValue()); + assertThat(result.getStudentGrade()).isEqualTo(field3.getValue()); + assertThat(result.getStudentCitizenship()).isEqualTo(field4.getValue()); + assertThat(result.getSchoolOfRecord()).isEqualTo(field5.getValue()); + assertThat(result.getRecalculateGradStatus()).isNull(); + assertThat(result.getRecalculateProjectedGrad()).isEqualTo("Y"); } @Test