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",