diff --git a/api/pom.xml b/api/pom.xml index 00c00d8d8..158b46b4c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -141,6 +141,16 @@ io.micrometer micrometer-registry-prometheus + + net.sf.jasperreports + jasperreports + 6.21.0 + + + net.sf.jasperreports + jasperreports-fonts + 6.21.0 + org.springframework.boot spring-boot-starter-actuator diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/ReportTypeCode.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/ReportTypeCode.java new file mode 100644 index 000000000..2153ec2f1 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/ReportTypeCode.java @@ -0,0 +1,25 @@ +package ca.bc.gov.educ.studentdatacollection.api.constants.v1; + +import lombok.Getter; + +import java.util.Arrays; +import java.util.Optional; + +/** + * The enum Event outcome. + */ +public enum ReportTypeCode { + + GRADE_ENROLLMENT_FTE("GRADE_ENROLLMENT_FTE"); + + @Getter + private final String code; + ReportTypeCode(String code) { + this.code = code; + } + + public static Optional findByValue(String value) { + return Arrays.stream(values()).filter(e -> Arrays.asList(e.code).contains(value)).findFirst(); + } + +} diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/URL.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/URL.java index afcd776a2..7a956eb69 100644 --- a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/URL.java +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/URL.java @@ -9,6 +9,7 @@ private URL(){ public static final String BASE_URL_COLLECTION="/api/v1/student-data-collection/collection"; public static final String BASE_URL_SCHOOL_COLLECTION="/api/v1/student-data-collection/sdcSchoolCollection"; public static final String BASE_URL_SCHOOL_COLLECTION_STUDENT="/api/v1/student-data-collection/sdcSchoolCollectionStudent"; + public static final String BASE_URL_REPORT_GENERATION="/api/v1/student-data-collection/reportGeneration"; public static final String BASE_URL_SCHOOL_FUNDING="/api/v1/student-data-collection/schoolFundingGroup"; public static final String ENROLLED_PROGRAM_CODES="/enrolled-program-codes"; public static final String CAREER_PROGRAM_CODES="/career-program-codes"; diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/controller/v1/ReportGenerationController.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/controller/v1/ReportGenerationController.java new file mode 100644 index 000000000..b57ed1ee7 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/controller/v1/ReportGenerationController.java @@ -0,0 +1,41 @@ +package ca.bc.gov.educ.studentdatacollection.api.controller.v1; + +import ca.bc.gov.educ.studentdatacollection.api.constants.v1.ReportTypeCode; +import ca.bc.gov.educ.studentdatacollection.api.endpoint.v1.ReportGenerationEndpoint; +import ca.bc.gov.educ.studentdatacollection.api.exception.InvalidPayloadException; +import ca.bc.gov.educ.studentdatacollection.api.exception.errors.ApiError; +import ca.bc.gov.educ.studentdatacollection.api.reports.ReportGenerationService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.Optional; +import java.util.UUID; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +@RestController +@Slf4j +@RequiredArgsConstructor +public class ReportGenerationController implements ReportGenerationEndpoint { + + private final ReportGenerationService reportGenerationService; + + @Override + public byte[] generateSDCReport(UUID collectionID, String reportTypeCode) { + Optional code = ReportTypeCode.findByValue(reportTypeCode); + + if(code.isEmpty()){ + ApiError error = ApiError.builder().timestamp(LocalDateTime.now()).message("Payload contains invalid report type code.").status(BAD_REQUEST).build(); + throw new InvalidPayloadException(error); + } + + switch(code.get()){ + case GRADE_ENROLLMENT_FTE: + return reportGenerationService.generateGradeEnrollementFTEReport(collectionID); + } + + return new byte[0]; + } +} diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/endpoint/v1/ReportGenerationEndpoint.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/endpoint/v1/ReportGenerationEndpoint.java new file mode 100644 index 000000000..5eeb822df --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/endpoint/v1/ReportGenerationEndpoint.java @@ -0,0 +1,23 @@ +package ca.bc.gov.educ.studentdatacollection.api.endpoint.v1; + +import ca.bc.gov.educ.studentdatacollection.api.constants.v1.URL; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.UUID; + +@RequestMapping(URL.BASE_URL_REPORT_GENERATION) +public interface ReportGenerationEndpoint { + + @GetMapping("/{sdcSchoolCollectionID}/{reportTypeCode}") + @PreAuthorize("hasAuthority('SCOPE_READ_SDC_SCHOOL_COLLECTION')") + @Transactional(readOnly = true) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "NOT FOUND")}) + byte[] generateSDCReport(@PathVariable("sdcSchoolCollectionID") UUID sdcSchoolCollectionID, @PathVariable("reportTypeCode") String reportTypeCode); + +} diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/reports/ReportGenerationService.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/reports/ReportGenerationService.java new file mode 100644 index 000000000..003100e48 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/reports/ReportGenerationService.java @@ -0,0 +1,76 @@ +package ca.bc.gov.educ.studentdatacollection.api.reports; + +import ca.bc.gov.educ.studentdatacollection.api.exception.EntityNotFoundException; +import ca.bc.gov.educ.studentdatacollection.api.exception.StudentDataCollectionAPIRuntimeException; +import ca.bc.gov.educ.studentdatacollection.api.mappers.v1.SdcSchoolCollectionMapper; +import ca.bc.gov.educ.studentdatacollection.api.model.v1.SdcSchoolCollectionEntity; +import ca.bc.gov.educ.studentdatacollection.api.properties.ApplicationProperties; +import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcSchoolCollectionRepository; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import net.sf.jasperreports.engine.*; +import net.sf.jasperreports.engine.query.JsonQueryExecuterFactory; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.*; + +@Service +@Slf4j +public class ReportGenerationService { + + private final SdcSchoolCollectionRepository sdcSchoolCollectionRepository; + private JasperReport gradeEnrollmentFTEReport; + private ObjectWriter objectWriter = new ObjectMapper().writer().withDefaultPrettyPrinter(); + + public ReportGenerationService(SdcSchoolCollectionRepository sdcSchoolCollectionRepository) { + this.sdcSchoolCollectionRepository = sdcSchoolCollectionRepository; + } + + @PostConstruct + public void init() { + ApplicationProperties.bgTask.execute(this::initialize); + } + + private void initialize() { + this.compileJasperReports(); + } + + private void compileJasperReports(){ + try { + InputStream input = getClass().getResourceAsStream("/gradeEnrollmentFTEReport.jrxml"); + gradeEnrollmentFTEReport = JasperCompileManager.compileReport(input); + } catch (JRException e) { + throw new StudentDataCollectionAPIRuntimeException("Compiling Jasper reports has failed :: " + e.getMessage()); + } + } + + public byte[] generateGradeEnrollementFTEReport(UUID collectionID){ + try { + Optional sdcSchoolCollectionEntityOptional = sdcSchoolCollectionRepository.findById(collectionID); + SdcSchoolCollectionEntity sdcSchoolCollectionEntity = sdcSchoolCollectionEntityOptional.orElseThrow(() -> + new EntityNotFoundException(SdcSchoolCollectionEntity.class, "Collection by Id", collectionID.toString())); + + Map params = new HashMap<>(); + params.put(JsonQueryExecuterFactory.JSON_DATE_PATTERN, "yyyy-MM-dd"); + params.put(JsonQueryExecuterFactory.JSON_NUMBER_PATTERN, "#,##0.##"); + params.put(JsonQueryExecuterFactory.JSON_LOCALE, Locale.ENGLISH); + params.put(JRParameter.REPORT_LOCALE, Locale.US); + var schoolColl = SdcSchoolCollectionMapper.mapper.toStructure(sdcSchoolCollectionEntity); + String json = "{\"report\": { \"collectionNameAndYear\": \"September 2023 Collection\", \"reportGeneratedDate\": \"Report Date: 2023-10-03\", \"districtNumberAndName\": \"085 - Vancouver Island\", \"schoolMincodeAndName\": \"08585023 - Eagle View Elementary School\", \"grades\": [{ \"code\": \"KF\", \"schoolAgedHeadcount\": \"100\", \"schoolAgedEligibleForFTE\": \"0\", \"schoolAgedFTETotal\": \"100.0000\", \"adultHeadcount\": \"100\", \"adultEligibleForFTE\": \"0\", \"adultFTETotal\": \"100.0000\", \"allStudentHeadcount\": \"90\", \"allStudentEligibleForFTE\": \"10\", \"allStudentFTETotal\": \"90.0000\"},{ \"code\": \"01\", \"schoolAgedHeadcount\": \"100\", \"schoolAgedEligibleForFTE\": \"50\", \"schoolAgedFTETotal\": \"100.0000\", \"adultHeadcount\": \"60\", \"adultEligibleForFTE\": \"5\", \"adultFTETotal\": \"150.0000\", \"allStudentHeadcount\": \"100\", \"allStudentEligibleForFTE\": \"0\", \"allStudentFTETotal\": \"100.0000\", \"totalCountsCode\": \"Total\", \"totalSchoolAgedHeadcount\": \"300\"} ] }}"; +// String json = objectWriter.writeValueAsString(schoolColl); + InputStream targetStream = new ByteArrayInputStream(json.getBytes()); + params.put(JsonQueryExecuterFactory.JSON_INPUT_STREAM, targetStream); + + JasperPrint jasperPrint = JasperFillManager.fillReport(gradeEnrollmentFTEReport, params); + return JasperExportManager.exportReportToPdf(jasperPrint); + } catch (Exception e) { + log.info("Exception occurred while writing PDF report for grade enrollment :: " + e.getMessage()); + throw new StudentDataCollectionAPIRuntimeException("Exception occurred while writing PDF report for grade enrollment :: " + e.getMessage()); + } + } + +} diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTENode.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTENode.java new file mode 100644 index 000000000..a0641b688 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTENode.java @@ -0,0 +1,20 @@ +package ca.bc.gov.educ.studentdatacollection.api.struct.v1.reports; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@SuppressWarnings("squid:S1700") +public class GradeEnrollementFTENode implements Serializable { + private static final long serialVersionUID = 6118916290604876032L; + + private GradeEnrollementFTEReportNode report; + +} diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTEReportGradesNode.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTEReportGradesNode.java new file mode 100644 index 000000000..a79d2a1e1 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTEReportGradesNode.java @@ -0,0 +1,38 @@ +package ca.bc.gov.educ.studentdatacollection.api.struct.v1.reports; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@SuppressWarnings("squid:S1700") +public class GradeEnrollementFTEReportGradesNode implements Serializable { + private static final long serialVersionUID = 6118916290604876032L; + + private String code; + + private String schoolAgedHeadcount; + + private String schoolAgedEligibleForFTE; + + private String schoolAgedFTETotal; + + private String adultHeadcount; + + private String adultEligibleForFTE; + + private String adultFTETotal; + + private String allStudentHeadcount; + + private String allStudentEligibleForFTE; + + private String allStudentFTETotal; + +} diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTEReportNode.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTEReportNode.java new file mode 100644 index 000000000..c3d4aa129 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/struct/v1/reports/GradeEnrollementFTEReportNode.java @@ -0,0 +1,29 @@ +package ca.bc.gov.educ.studentdatacollection.api.struct.v1.reports; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@SuppressWarnings("squid:S1700") +public class GradeEnrollementFTEReportNode implements Serializable { + private static final long serialVersionUID = 6118916290604876032L; + + private String collectionNameAndYear; + + private String reportGeneratedDate; + + private String districtNumberAndName; + + private String schoolMincodeAndName; + + private List grades; + +} diff --git a/api/src/main/resources/gradeEnrollmentFTEReport.jrxml b/api/src/main/resources/gradeEnrollmentFTEReport.jrxml new file mode 100644 index 000000000..e4b594685 --- /dev/null +++ b/api/src/main/resources/gradeEnrollmentFTEReport.jrxml @@ -0,0 +1,543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/BaseStudentDataCollectionAPITest.java b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/BaseStudentDataCollectionAPITest.java index 1994b63b2..3d739785d 100644 --- a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/BaseStudentDataCollectionAPITest.java +++ b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/BaseStudentDataCollectionAPITest.java @@ -10,7 +10,6 @@ import ca.bc.gov.educ.studentdatacollection.api.repository.v1.*; import ca.bc.gov.educ.studentdatacollection.api.struct.SdcStudentSagaData; import ca.bc.gov.educ.studentdatacollection.api.struct.StudentRuleData; -import ca.bc.gov.educ.studentdatacollection.api.struct.external.grad.v1.GradStatusPayload; import ca.bc.gov.educ.studentdatacollection.api.struct.external.grad.v1.GradStatusResult; import ca.bc.gov.educ.studentdatacollection.api.struct.external.penmatch.v1.PenMatchRecord; import ca.bc.gov.educ.studentdatacollection.api.struct.external.penmatch.v1.PenMatchResult; @@ -28,11 +27,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; +import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Arrays; -import java.util.Collection; -import java.util.Set; +import java.util.HashSet; import java.util.UUID; @SpringBootTest(classes = {StudentDataCollectionApiApplication.class}) @@ -175,6 +174,8 @@ public SdcSchoolCollectionEntity createMockSdcSchoolCollectionEntity(CollectionE sdcEntity.setCreateDate(LocalDateTime.now()); sdcEntity.setUpdateUser("ABC"); sdcEntity.setUpdateDate(LocalDateTime.now()); + sdcEntity.setSdcSchoolCollectionHistoryEntities(new HashSet<>()); + sdcEntity.setSdcSchoolStudentEntities(new HashSet<>()); return sdcEntity; } @@ -212,6 +213,59 @@ public SdcSchoolCollectionStudentEntity createMockSchoolStudentEntity(SdcSchoolC sdcEntity.setIsSchoolAged(true); sdcEntity.setIsAdult(false); sdcEntity.setIsGraduated(false); + sdcEntity.setSdcStudentEnrolledProgramEntities(new HashSet<>()); + sdcEntity.setSdcStudentValidationIssueEntities(new HashSet<>()); + return sdcEntity; + } + + public SdcSchoolCollectionStudentEntity createMockSchoolStudentForSagaEntity(SdcSchoolCollectionEntity sdcSchoolCollectionEntity){ + SdcSchoolCollectionStudentEntity sdcEntity = new SdcSchoolCollectionStudentEntity(); + sdcEntity.setSdcSchoolCollection(sdcSchoolCollectionEntity); + sdcEntity.setLocalID("LOCAL123"); + sdcEntity.setStudentPen("PEN123456"); + sdcEntity.setLegalFirstName("John"); + sdcEntity.setLegalMiddleNames("Michael"); + sdcEntity.setLegalLastName("Doe"); + sdcEntity.setUsualFirstName("John"); + sdcEntity.setUsualMiddleNames("Mike"); + sdcEntity.setUsualLastName("Doe"); + sdcEntity.setDob("20050515"); + sdcEntity.setGender("M"); + sdcEntity.setSpecialEducationCategoryCode("SPED01"); + sdcEntity.setSchoolFundingCode("FUND02"); + sdcEntity.setNativeAncestryInd("N"); + sdcEntity.setHomeLanguageSpokenCode("ENG"); + sdcEntity.setOtherCourses("0"); + sdcEntity.setSupportBlocks("1"); + sdcEntity.setEnrolledGradeCode("10"); + sdcEntity.setEnrolledProgramCodes("PROG001,PROG002"); + sdcEntity.setCareerProgramCode("CAREER001"); + sdcEntity.setNumberOfCourses("6"); + sdcEntity.setBandCode(""); + sdcEntity.setPostalCode("V6G 1A1"); + sdcEntity.setSdcSchoolCollectionStudentStatusCode("ACTIVE"); + sdcEntity.setIsAdult(false); + sdcEntity.setIsSchoolAged(true); + sdcEntity.setIsGraduated(false); + sdcEntity.setAssignedStudentId(UUID.randomUUID()); + sdcEntity.setAssignedPen("120164447"); + sdcEntity.setIsAdult(false); + sdcEntity.setFte(new BigDecimal(0.875)); + sdcEntity.setFteZeroReasonCode("REASON001"); + sdcEntity.setFrenchProgramNonEligReasonCode("REASON002"); + sdcEntity.setEllNonEligReasonCode("REASON003"); + sdcEntity.setIndigenousSupportProgramNonEligReasonCode("REASON004"); + sdcEntity.setCareerProgramNonEligReasonCode("REASON005"); + sdcEntity.setSpecialEducationNonEligReasonCode("REASON006"); + sdcEntity.setCreateUser("ABC"); + sdcEntity.setCreateDate(LocalDateTime.now()); + sdcEntity.setUpdateUser("ABC"); + sdcEntity.setUpdateDate(LocalDateTime.now()); + sdcEntity.setIsSchoolAged(true); + sdcEntity.setIsAdult(false); + sdcEntity.setIsGraduated(false); + sdcEntity.setSdcStudentEnrolledProgramEntities(new HashSet<>()); + sdcEntity.setSdcStudentValidationIssueEntities(new HashSet<>()); return sdcEntity; } diff --git a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/calculator/FteCalculatorChainProcessorIntegrationTest.java b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/calculator/FteCalculatorChainProcessorIntegrationTest.java index 5f13863ed..103f3f45c 100644 --- a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/calculator/FteCalculatorChainProcessorIntegrationTest.java +++ b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/calculator/FteCalculatorChainProcessorIntegrationTest.java @@ -5,6 +5,7 @@ import ca.bc.gov.educ.studentdatacollection.api.constants.v1.ZeroFteReasonCodes; import ca.bc.gov.educ.studentdatacollection.api.model.v1.CollectionEntity; import ca.bc.gov.educ.studentdatacollection.api.model.v1.SdcSchoolCollectionEntity; +import ca.bc.gov.educ.studentdatacollection.api.model.v1.SdcSchoolCollectionStudentEntity; import ca.bc.gov.educ.studentdatacollection.api.repository.v1.CollectionRepository; import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcSchoolCollectionRepository; import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcSchoolCollectionStudentRepository; @@ -186,35 +187,31 @@ void testProcessFteCalculator_DistrictDoubleReported() throws IOException { // Given this.studentData.getSchool().setSchoolCategoryCode("PUBLIC"); this.studentData.getSchool().setFacilityTypeCode("DIST_LEARN"); - this.studentData.getSdcSchoolCollectionStudentEntity().setEnrolledGradeCode("08"); - this.studentData.getSdcSchoolCollectionStudentEntity().setCreateDate(LocalDateTime.of(LocalDateTime.now().getYear(), Month.FEBRUARY, 5, 0, 0)); CollectionEntity collectionOrig = createMockCollectionEntity(); collectionOrig.setSnapshotDate(LocalDate.of(collectionOrig.getOpenDate().getYear(), 2, 15)); collectionOrig.setCollectionTypeCode(CollectionTypeCodes.FEBRUARY.getTypeCode()); + collectionOrig = collectionRepository.save(collectionOrig); SdcSchoolCollectionEntity sdcSchoolCollectionEntityOrig = createMockSdcSchoolCollectionEntity(collectionOrig, null, null); this.studentData.getSdcSchoolCollectionStudentEntity().setSdcSchoolCollection(sdcSchoolCollectionEntityOrig); + sdcSchoolCollectionEntityOrig = sdcSchoolCollectionRepository.save(sdcSchoolCollectionEntityOrig); - final File file = new File( - Objects.requireNonNull(getClass().getClassLoader().getResource("sdc-school-collection-entity.json")).getFile() - ); - - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - SdcSchoolCollectionEntity sdcSchoolCollection = objectMapper.readValue(file, SdcSchoolCollectionEntity.class); var lastCollectionDate = LocalDateTime.of(LocalDateTime.now().minusYears(1).getYear(), Month.SEPTEMBER, 5, 0, 0); - var collection = collectionRepository.save(sdcSchoolCollection.getCollectionEntity()); - sdcSchoolCollection.getCollectionEntity().setCollectionID(collection.getCollectionID()); - sdcSchoolCollection = sdcSchoolCollectionRepository.save(sdcSchoolCollection); - this.studentData.getSchool().setSchoolId(sdcSchoolCollection.getSchoolID().toString()); - this.studentData.getSchool().setDistrictId(String.valueOf(sdcSchoolCollection.getDistrictID())); + this.studentData.getSchool().setSchoolId(sdcSchoolCollectionEntityOrig.getSchoolID().toString()); + this.studentData.getSchool().setDistrictId(String.valueOf(sdcSchoolCollectionEntityOrig.getDistrictID())); + SdcSchoolCollectionStudentEntity sdcSchoolCollectionStudentEntity = createMockSchoolStudentForSagaEntity(sdcSchoolCollectionEntityOrig); + + sdcSchoolCollectionStudentEntity.setEnrolledGradeCode("08"); + sdcSchoolCollectionStudentEntity.setCreateDate(LocalDateTime.of(LocalDateTime.now().getYear(), Month.FEBRUARY, 5, 0, 0)); + sdcSchoolCollectionStudentRepository.save(sdcSchoolCollectionStudentEntity); + this.studentData.setSdcSchoolCollectionStudentEntity(sdcSchoolCollectionStudentEntity); var oldCollection = createMockCollectionEntity(); var oldSnapDate = LocalDate.of(LocalDateTime.now().minusYears(1).getYear(), Month.SEPTEMBER, 29); oldCollection.setSnapshotDate(oldSnapDate); var oldSdcCollection = createMockSdcSchoolCollectionEntity(oldCollection, null, null); collectionRepository.save(oldCollection); - oldSdcCollection.setDistrictID(sdcSchoolCollection.getDistrictID()); + oldSdcCollection.setDistrictID(sdcSchoolCollectionEntityOrig.getDistrictID()); sdcSchoolCollectionRepository.save(oldSdcCollection); var oneYearAgoCollectionStudent = createMockSchoolStudentEntity(oldSdcCollection); oneYearAgoCollectionStudent.setCreateDate(lastCollectionDate); @@ -238,35 +235,34 @@ void testProcessFteCalculator_IndAuthorityDoubleReported() throws IOException { // Given this.studentData.getSchool().setSchoolCategoryCode("INDEPEND"); this.studentData.getSchool().setFacilityTypeCode("DIST_LEARN"); - this.studentData.getSdcSchoolCollectionStudentEntity().setEnrolledGradeCode("08"); - this.studentData.getSdcSchoolCollectionStudentEntity().setCreateDate(LocalDateTime.of(LocalDateTime.now().getYear(), Month.FEBRUARY, 5, 0, 0)); - - final File file = new File( - Objects.requireNonNull(getClass().getClassLoader().getResource("sdc-school-collection-entity.json")).getFile() - ); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - SdcSchoolCollectionEntity sdcSchoolCollection = objectMapper.readValue(file, SdcSchoolCollectionEntity.class); + CollectionEntity collectionEntity = createMockCollectionEntity(); var snapDate = LocalDate.of(LocalDateTime.now().getYear(), Month.FEBRUARY, 15); - sdcSchoolCollection.getCollectionEntity().setSnapshotDate(snapDate); - sdcSchoolCollection.getCollectionEntity().setCollectionTypeCode(CollectionTypeCodes.FEBRUARY.getTypeCode()); - this.studentData.getSdcSchoolCollectionStudentEntity().setSdcSchoolCollection(sdcSchoolCollection); - - var collection = collectionRepository.save(sdcSchoolCollection.getCollectionEntity()); - sdcSchoolCollection.getCollectionEntity().setCollectionID(collection.getCollectionID()); + collectionEntity.setSnapshotDate(snapDate); + collectionEntity.setCollectionTypeCode(CollectionTypeCodes.FEBRUARY.getTypeCode()); + collectionEntity = collectionRepository.save(collectionEntity); + SdcSchoolCollectionEntity sdcSchoolCollection = createMockSdcSchoolCollectionEntity(collectionEntity, null, null); sdcSchoolCollection = sdcSchoolCollectionRepository.save(sdcSchoolCollection); + + SdcSchoolCollectionStudentEntity sdcSchoolCollectionStudentEntity = createMockSchoolStudentForSagaEntity(sdcSchoolCollection); + sdcSchoolCollectionStudentEntity.setEnrolledGradeCode("08"); + sdcSchoolCollectionStudentEntity.setCreateDate(LocalDateTime.of(LocalDateTime.now().getYear(), Month.FEBRUARY, 5, 0, 0)); + + sdcSchoolCollectionStudentRepository.save(sdcSchoolCollectionStudentEntity); + + this.studentData.setSdcSchoolCollectionStudentEntity(sdcSchoolCollectionStudentEntity); + this.studentData.getSchool().setSchoolId(sdcSchoolCollection.getSchoolID().toString()); this.studentData.getSchool().setDistrictId(String.valueOf(sdcSchoolCollection.getDistrictID())); var oldCollection = createMockCollectionEntity(); var oldSnapDate = LocalDate.of(LocalDateTime.now().minusYears(1).getYear(), Month.SEPTEMBER, 29); oldCollection.setSnapshotDate(oldSnapDate); + oldCollection = collectionRepository.save(oldCollection); var oldSdcCollection = createMockSdcSchoolCollectionEntity(oldCollection, null, null); - collectionRepository.save(oldCollection); oldSdcCollection.setSchoolID(sdcSchoolCollection.getSchoolID()); - sdcSchoolCollectionRepository.save(oldSdcCollection); - var oneYearAgoCollectionStudent = createMockSchoolStudentEntity(oldSdcCollection); + oldSdcCollection = sdcSchoolCollectionRepository.save(oldSdcCollection); + var oneYearAgoCollectionStudent = createMockSchoolStudentForSagaEntity(oldSdcCollection); oneYearAgoCollectionStudent.setAssignedStudentId(this.studentData.getSdcSchoolCollectionStudentEntity().getAssignedStudentId()); sdcSchoolCollectionStudentRepository.save(oneYearAgoCollectionStudent); @@ -335,8 +331,14 @@ void testProcessFteCalculator_NewOnlineStudent() { this.studentData.getSdcSchoolCollectionStudentEntity().setSdcSchoolCollection(sdcSchoolCollectionEntityOrig); this.studentData.getSchool().setFacilityTypeCode("DIST_LEARN"); this.studentData.getSchool().setSchoolId(sdcSchoolCollectionEntityOrig.getSchoolID().toString()); - this.studentData.getSdcSchoolCollectionStudentEntity().setEnrolledGradeCode("KH"); - this.studentData.getSdcSchoolCollectionStudentEntity().setCreateDate(LocalDateTime.of(LocalDateTime.now().getYear(), Month.FEBRUARY, 5, 0, 0)); + + SdcSchoolCollectionStudentEntity sdcSchoolCollectionStudentEntity = createMockSchoolStudentForSagaEntity(sdcSchoolCollectionEntityOrig); + sdcSchoolCollectionStudentEntity.setEnrolledGradeCode("KH"); + sdcSchoolCollectionStudentEntity.setCreateDate(LocalDateTime.of(LocalDateTime.now().getYear(), Month.FEBRUARY, 5, 0, 0)); + + sdcSchoolCollectionStudentRepository.save(sdcSchoolCollectionStudentEntity); + + this.studentData.setSdcSchoolCollectionStudentEntity(sdcSchoolCollectionStudentEntity); var lastCollectionDate = LocalDateTime.of(LocalDateTime.now().minusYears(1).getYear(), Month.SEPTEMBER, 5, 0, 0); diff --git a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/controller/v1/ReportGenerationControllerTest.java b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/controller/v1/ReportGenerationControllerTest.java new file mode 100644 index 000000000..160d58ccc --- /dev/null +++ b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/controller/v1/ReportGenerationControllerTest.java @@ -0,0 +1,93 @@ +package ca.bc.gov.educ.studentdatacollection.api.controller.v1; + +import ca.bc.gov.educ.studentdatacollection.api.BaseStudentDataCollectionAPITest; +import ca.bc.gov.educ.studentdatacollection.api.constants.v1.URL; +import ca.bc.gov.educ.studentdatacollection.api.model.v1.CollectionEntity; +import ca.bc.gov.educ.studentdatacollection.api.model.v1.SdcSchoolCollectionEntity; +import ca.bc.gov.educ.studentdatacollection.api.repository.v1.CollectionRepository; +import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcSchoolCollectionRepository; +import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcSchoolCollectionStudentEnrolledProgramRepository; +import ca.bc.gov.educ.studentdatacollection.api.struct.v1.School; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDateTime; +import java.util.UUID; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oidcLogin; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +class ReportGenerationControllerTest extends BaseStudentDataCollectionAPITest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + SdcSchoolCollectionController sdcSchoolCollectionController; + + @Autowired + CollectionRepository collectionRepository; + + @Autowired + SdcSchoolCollectionRepository sdcSchoolCollectionRepository; + + @Autowired + SdcSchoolCollectionStudentEnrolledProgramRepository sdcSchoolCollectionStudentEnrolledProgramRepository; + + @BeforeEach + public void before() { + } + + @AfterEach + public void after() { + this.collectionRepository.deleteAll(); + } + + @Test + void testGetCollectionByID_ShouldReturnCollection() throws Exception { + final GrantedAuthority grantedAuthority = () -> "SCOPE_READ_SDC_SCHOOL_COLLECTION"; + final SecurityMockMvcRequestPostProcessors.OidcLoginRequestPostProcessor mockAuthority = oidcLogin().authorities(grantedAuthority); + + CollectionEntity collection = createMockCollectionEntity(); + collection.setCloseDate(LocalDateTime.now().plusDays(2)); + collectionRepository.save(collection); + + School school = createMockSchool(); + SdcSchoolCollectionEntity sdcMockSchool = createMockSdcSchoolCollectionEntity(collection, UUID.fromString(school.getSchoolId()), UUID.fromString(school.getDistrictId())); + sdcMockSchool.setUploadDate(null); + sdcMockSchool.setUploadFileName(null); + sdcSchoolCollectionRepository.save(sdcMockSchool); + + this.mockMvc.perform( + get(URL.BASE_URL_REPORT_GENERATION + "/" + sdcMockSchool.getSdcSchoolCollectionID() + "/GRADE_ENROLLMENT_FTE").with(mockAuthority)) + .andDo(print()).andExpect(status().isOk()); + } + + @Test + void testGetCollectionByID_ShouldReturnBadRequest() throws Exception { + final GrantedAuthority grantedAuthority = () -> "SCOPE_READ_SDC_SCHOOL_COLLECTION"; + final SecurityMockMvcRequestPostProcessors.OidcLoginRequestPostProcessor mockAuthority = oidcLogin().authorities(grantedAuthority); + + CollectionEntity collection = createMockCollectionEntity(); + collection.setCloseDate(LocalDateTime.now().plusDays(2)); + collectionRepository.save(collection); + + School school = createMockSchool(); + SdcSchoolCollectionEntity sdcMockSchool = createMockSdcSchoolCollectionEntity(collection, UUID.fromString(school.getSchoolId()), UUID.fromString(school.getDistrictId())); + sdcMockSchool.setUploadDate(null); + sdcMockSchool.setUploadFileName(null); + sdcSchoolCollectionRepository.save(sdcMockSchool); + + this.mockMvc.perform( + get(URL.BASE_URL_REPORT_GENERATION + "/" + sdcMockSchool.getSdcSchoolCollectionID() + "/ABC").with(mockAuthority)) + .andDo(print()).andExpect(status().isBadRequest()); + } + +} diff --git a/api/src/test/resources/sdc-student-saga-data.json b/api/src/test/resources/sdc-student-saga-data.json index f4c6ae8ed..9da870073 100644 --- a/api/src/test/resources/sdc-student-saga-data.json +++ b/api/src/test/resources/sdc-student-saga-data.json @@ -1,7 +1,7 @@ { "sdcSchoolCollectionStudentEntity": { - "sdcSchoolCollectionStudentID": "20f024a9-43a1-4b4a-b2a7-1689cf6ad712", - "sdcSchoolCollectionID": "20f024b3-43a1-4b4a-b2a7-1689cf6ad712", + "sdcSchoolCollectionStudentID": null, + "sdcSchoolCollectionID": null, "localID": "LOCAL123", "studentPen": "PEN123456", "legalFirstName": "John",