Skip to content

Commit

Permalink
Merge branch 'grad-release'
Browse files Browse the repository at this point in the history
  • Loading branch information
Harry0589 committed Oct 26, 2023
2 parents 1c281be + 4bf576d commit d6c1b13
Show file tree
Hide file tree
Showing 15 changed files with 614 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ca.bc.gov.educ.api.graduation.controller;

import ca.bc.gov.educ.api.graduation.model.dto.EdwGraduationSnapshot;
import ca.bc.gov.educ.api.graduation.service.EdwSnapshotService;
import ca.bc.gov.educ.api.graduation.util.EducGraduationApiConstants;
import ca.bc.gov.educ.api.graduation.util.GradValidation;
import ca.bc.gov.educ.api.graduation.util.PermissionsContants;
import ca.bc.gov.educ.api.graduation.util.ResponseHelper;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

@CrossOrigin
@RestController
@RequestMapping(EducGraduationApiConstants.GRADUATION_API_ROOT_MAPPING)
@OpenAPIDefinition(info = @Info(title = "API for EDW Snapshot of Graduation Status", description = "This API is for EDW Snapshot of Graduation Status.", version = "1"), security = {@SecurityRequirement(name = "OAUTH2", scopes = {"GRAD_GRADUATE_STUDENT"})})
public class EdwSnapshotController {

private static final Logger LOGGER = LoggerFactory.getLogger(EdwSnapshotController.class);
private static final String BEARER = "Bearer ";

@Autowired
EdwSnapshotService edwSnapshotService;

@Autowired
GradValidation validation;

@Autowired
ResponseHelper response;

@PostMapping(EducGraduationApiConstants.EDW_GRADUATION_SNAPSHOT)
@PreAuthorize(PermissionsContants.GRADUATE_STUDENT)
@Operation(summary = "Run a Graduation snapshot for EDW", description = "Run a Graduation snapshot for EDW", tags = { "EDW Snapshot" })
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
public ResponseEntity<EdwGraduationSnapshot> snapshotGraduationStatus(@RequestBody EdwGraduationSnapshot snapshotRequest, @RequestHeader(name="Authorization") String accessToken) {
LOGGER.debug("Snapshot Graduation Status for Student - pen# {}", snapshotRequest.getPen());
return response.GET(edwSnapshotService.processSnapshot(snapshotRequest, accessToken.replace(BEARER, "")));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ca.bc.gov.educ.api.graduation.model.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.UUID;

import static ca.bc.gov.educ.api.graduation.util.EducGraduationApiConstants.DEFAULT_DATE_FORMAT;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class EdwGraduationSnapshot {
private UUID studentID;

private Integer gradYear;
private String pen;
private String graduationFlag;
private String honoursStanding;
private BigDecimal gpa;
private String graduatedDate;

@JsonFormat(pattern=DEFAULT_DATE_FORMAT)
private LocalDate runDate;
@JsonFormat(pattern=DEFAULT_DATE_FORMAT)
private LocalDate sessionDate;

private String schoolOfRecord;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package ca.bc.gov.educ.api.graduation.model.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.UUID;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class StudentNonGradReason {

private UUID graduationStudentRecordId;
private String pen;

private String transcriptRule1;
private String description1;
private String gradRule1;
private String projected1;

private String transcriptRule2;
private String description2;
private String gradRule2;
private String projected2;

private String transcriptRule3;
private String description3;
private String gradRule3;
private String projected3;

private String transcriptRule4;
private String description4;
private String gradRule4;
private String projected4;

private String transcriptRule5;
private String description5;
private String gradRule5;
private String projected5;

private String transcriptRule6;
private String description6;
private String gradRule6;
private String projected6;

private String transcriptRule7;
private String description7;
private String gradRule7;
private String projected7;

private String transcriptRule8;
private String description8;
private String gradRule8;
private String projected8;

private String transcriptRule9;
private String description9;
private String gradRule9;
private String projected9;

private String transcriptRule10;
private String description10;
private String gradRule10;
private String projected10;

private String transcriptRule11;
private String description11;
private String gradRule11;
private String projected11;

private String transcriptRule12;
private String description12;
private String gradRule12;
private String projected12;

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,32 @@ public class AlgorithmProcessFactory {

@Autowired
GraduateStudentProcess graduateStudentProcess;

private static final Logger logger = LoggerFactory.getLogger(AlgorithmProcessFactory.class);

public AlgorithmProcess createProcess(AlgorithmProcessType processImplementation) {
AlgorithmProcess pcs = null;
switch(processImplementation.name()) {
case "REGFM":
logger.debug("\n************* PROJECTED (REGFM): Graduating Student START ************");
pcs = projectedGradFinalMarksRegistrationsProcess;
break;
case "FM":
logger.debug("\n************* PROJECTED (FM): Graduating Student START ************");
pcs = projectedGradFinalMarksProcess;
break;
case "FMR":
logger.debug("\n************* PROJECTED (FMR): Graduating Student START ************");
pcs = projectedGradFinalMarksReportsProcess;
break;
case "GS":
logger.debug("\n************* Graduating Student START ************");
pcs = graduateStudentProcess;
break;
default:
break;
}
switch (processImplementation.name()) {
case "REGFM" -> {
logger.debug("\n************* PROJECTED (REGFM): Graduating Student START ************");
pcs = projectedGradFinalMarksRegistrationsProcess;
}
case "FM" -> {
logger.debug("\n************* PROJECTED (FM): Graduating Student START ************");
pcs = projectedGradFinalMarksProcess;
}
case "FMR" -> {
logger.debug("\n************* PROJECTED (FMR): Graduating Student START ************");
pcs = projectedGradFinalMarksReportsProcess;
}
case "GS" -> {
logger.debug("\n************* Graduating Student START ************");
pcs = graduateStudentProcess;
}
default -> {
logger.debug("\n************ No matched Algorithm Process is found for {} ************", processImplementation.name());
}
}
return pcs;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package ca.bc.gov.educ.api.graduation.service;

import ca.bc.gov.educ.api.graduation.model.dto.*;
import ca.bc.gov.educ.api.graduation.util.EducGraduationApiConstants;
import ca.bc.gov.educ.api.graduation.util.JsonTransformer;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class EdwSnapshotService {

final GradAlgorithmService gradAlgorithmService;

final GradStatusService gradStatusService;

final ReportService reportService;

final EducGraduationApiConstants constants;

final RESTService restService;

final JsonTransformer jsonTransformer;

@Autowired
public EdwSnapshotService(EducGraduationApiConstants constants,
GradAlgorithmService gradAlgorithmService,
GradStatusService gradStatusService,
ReportService reportService,
RESTService restService,
JsonTransformer jsonTransformer) {
this.constants = constants;
this.gradAlgorithmService = gradAlgorithmService;
this.gradStatusService = gradStatusService;
this.reportService = reportService;
this.restService = restService;
this.jsonTransformer = jsonTransformer;
}

public EdwGraduationSnapshot processSnapshot(EdwGraduationSnapshot snapshotRequest, String accessToken) {
Integer gradYear = snapshotRequest.getGradYear(); // yyyy
String pen = snapshotRequest.getPen();
String graduatedDate = snapshotRequest.getGraduatedDate(); // yyyyMM
String schoolOfRecord = snapshotRequest.getSchoolOfRecord();

EdwGraduationSnapshot snapshot;
boolean isGraduated = StringUtils.isNotBlank(graduatedDate);
if (isGraduated) {
// retrieve honour_flag, gpa
snapshot = populateSnapshot(gradYear, pen, graduatedDate, "Y", snapshotRequest.getHonoursStanding(), snapshotRequest.getGpa(), schoolOfRecord);
} else {
snapshot = runHypotheticalGradAlgorithm(pen, gradYear, schoolOfRecord, accessToken);
}
log.debug("Save EdwSnapshot for Student pen# {}", snapshotRequest.getPen());
saveEdwSnapshotOfGraduationStatus(accessToken, snapshot);
return snapshot;
}

private EdwGraduationSnapshot runHypotheticalGradAlgorithm(String pen, Integer gradYear, String schoolOfRecord, String accessToken) {
UUID studentID = getStudentID(pen, accessToken);
if (studentID == null) {
return null;
}

EdwGraduationSnapshot snapshot;
log.debug("Hypothetical Grad Algorithm run for Student ID: {}", studentID);
GraduationStudentRecord gradResponse = gradStatusService.getGradStatus(studentID.toString(), accessToken, new ExceptionMessage());
String gradProgramCode = null;
if (gradResponse != null && !gradResponse.getStudentStatus().equals("MER")) {
gradProgramCode = gradResponse.getProgram();
}
boolean isHypotheticalPass = false;
GraduationData graduationData = null;
if (StringUtils.isNotBlank(gradProgramCode)) {
// run hypothetical grad algorithm
graduationData = gradAlgorithmService.runHypotheticalGraduatedAlgorithm(studentID, gradProgramCode, gradYear.toString(), accessToken);
if (graduationData != null) {
isHypotheticalPass = graduationData.isGraduated();
}
}
if (isHypotheticalPass) {
log.debug(" ==> Hypothetical Graduated!");
String gpaStr = graduationData.getGradStatus().getGpa();
BigDecimal gpa = NumberUtils.isCreatable(gpaStr)? new BigDecimal(gpaStr) : null;
String honoursStanding = graduationData.getGradStatus().getHonoursStanding();
snapshot = populateSnapshot(gradYear, pen, null, "Y", honoursStanding, gpa, schoolOfRecord);
} else {
// non-graduated student
log.debug(" ==> Not Graduated!");
snapshot = populateSnapshot(gradYear, pen, null, "N", null, BigDecimal.ZERO, schoolOfRecord);
}
return snapshot;
}

public void saveEdwSnapshotOfGraduationStatus(String accessToken, EdwGraduationSnapshot requestObj) {
this.restService.post(constants.getEdwSnapshotOfGraduationStatus(),
requestObj,
EdwGraduationSnapshot.class,
accessToken);
}

public UUID getStudentID(String pen, String accessToken) {
GradSearchStudent penStudent = getStudentByPenFromStudentApi(pen, accessToken);
if (penStudent != null) {
return UUID.fromString(penStudent.getStudentID());
} else {
return null;
}
}

@SuppressWarnings("rawtypes")
public GradSearchStudent getStudentByPenFromStudentApi(String pen, String accessToken) {
List response = this.restService.get(String.format(constants.getPenStudentApiByPenUrl(), pen),
List.class, accessToken);
if (response != null && !response.isEmpty()) {
List<GradSearchStudent> studentList = jsonTransformer.convertValue(response.get(0), new TypeReference<>(){});
return studentList.get(0);
}
return null;
}

private EdwGraduationSnapshot populateSnapshot(Integer gradYear, String pen, String graduatedDate, String gradFlag, String honourFlag, BigDecimal gpa, String schoolOfRecord) {
EdwGraduationSnapshot obj = new EdwGraduationSnapshot();
obj.setGradYear(gradYear);
obj.setPen(pen);
obj.setGpa(gpa);
obj.setHonoursStanding(honourFlag);
obj.setGraduationFlag(gradFlag);
obj.setGraduatedDate(graduatedDate);
obj.setSchoolOfRecord(schoolOfRecord);
return obj;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,12 @@ public GraduationData runProjectedAlgorithm(UUID studentID, String program,Strin
h.set(EducGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID());
}).retrieve().bodyToMono(GraduationData.class).block();
}

public GraduationData runHypotheticalGraduatedAlgorithm(UUID studentID, String program, String hypothenticalGradYear, String accessToken) {
return webClient.get().uri(String.format(educGraduationApiConstants.getGradHypotheticalAlgorithmEndpoint(), studentID, program, hypothenticalGradYear))
.headers(h -> {
h.setBearerAuth(accessToken);
h.set(EducGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID());
}).retrieve().bodyToMono(GraduationData.class).block();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ private void createCourseListForTranscript(List<StudentCourse> studentCourseList
String sDate = EducGraduationApiUtils.formatDate(sessionDate, EducGraduationApiConstants.DEFAULT_DATE_FORMAT);
int diff = EducGraduationApiUtils.getDifferenceInMonths(sDate, today);
boolean notCompletedCourse = xml && diff <= 0;
if (!sc.isDuplicate() && !sc.isFailed() && !sc.isNotCompleted() && ((notCompletedCourse) || !sc.isProjected()) && !sc.isValidationCourse()) {
if (!sc.isDuplicate() && !sc.isFailed() && !sc.isNotCompleted() && !sc.isCutOffCourse() && ((notCompletedCourse) || !sc.isProjected()) && !sc.isValidationCourse()) {
TranscriptResult result = new TranscriptResult();
String equivOrChallenge = "";
if (sc.getEquivOrChallenge() != null) {
Expand Down
Loading

0 comments on commit d6c1b13

Please sign in to comment.