-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of https://github.com/bcgov/EDUC-STUDENT-DATA-C…
- Loading branch information
Showing
24 changed files
with
2,921 additions
and
126 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
...in/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/MinistryReportTypeCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package ca.bc.gov.educ.studentdatacollection.api.constants.v1; | ||
|
||
import lombok.Getter; | ||
|
||
import java.util.Arrays; | ||
import java.util.Optional; | ||
|
||
@Getter | ||
public enum MinistryReportTypeCode { | ||
SCHOOL_ENROLLMENT_HEADCOUNTS("school-enrollment-headcounts"); | ||
|
||
private final String code; | ||
MinistryReportTypeCode(String code) { this.code = code; } | ||
|
||
public static Optional<MinistryReportTypeCode> findByValue(String value) { | ||
return Arrays.stream(values()).filter(e -> Arrays.asList(e.code).contains(value)).findFirst(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
...ov/educ/studentdatacollection/api/constants/v1/ministryreports/SchoolEnrolmentHeader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package ca.bc.gov.educ.studentdatacollection.api.constants.v1.ministryreports; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public enum SchoolEnrolmentHeader { | ||
|
||
SCHOOL_ENROLMENT_COLLECTION("School Enrolment Collection"), | ||
SCHOOL_YEAR("School Year"), | ||
DISTRICT_NUMBER("District Number"), | ||
SCHOOL_NUMBER("School Number"), | ||
SCHOOL_NAME("School Name"), | ||
FACILITY_TYPE("Facility Type"), | ||
SCHOOL_CATEGORY("School Category"), | ||
GRADE_RANGE("Grade Range"), | ||
REPORT_DATE("Report Date"), | ||
KIND_HT_COUNT("Kind(H/T) Count"), | ||
KIND_FT_COUNT("Kind(F/T) Count"), | ||
GRADE_01_COUNT("Grade 1 Count"), | ||
GRADE_02_COUNT("Grade 2 Count"), | ||
GRADE_03_COUNT("Grade 3 Count"), | ||
GRADE_04_COUNT("Grade 4 Count"), | ||
GRADE_05_COUNT("Grade 5 Count"), | ||
GRADE_06_COUNT("Grade 6 Count"), | ||
GRADE_07_COUNT("Grade 7 Count"), | ||
GRADE_08_COUNT("Grade 8 Count"), | ||
GRADE_09_COUNT("Grade 9 Count"), | ||
GRADE_10_COUNT("Grade 10 Count"), | ||
GRADE_11_COUNT("Grade 11 Count"), | ||
GRADE_12_COUNT("Grade 12 Count"); | ||
|
||
private final String code; | ||
SchoolEnrolmentHeader(String code) { this.code = code; } | ||
} |
40 changes: 40 additions & 0 deletions
40
.../gov/educ/studentdatacollection/api/controller/v1/MinistryHeadcountReportsController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package ca.bc.gov.educ.studentdatacollection.api.controller.v1; | ||
|
||
import ca.bc.gov.educ.studentdatacollection.api.constants.v1.MinistryReportTypeCode; | ||
import ca.bc.gov.educ.studentdatacollection.api.endpoint.v1.MinistryHeadcountReports; | ||
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.service.v1.MinistryHeadcountService; | ||
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.headcounts.HeadcountResultsTable; | ||
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 MinistryHeadcountReportsController implements MinistryHeadcountReports { | ||
|
||
private final MinistryHeadcountService ministryHeadcountService; | ||
|
||
@Override | ||
public HeadcountResultsTable getMinistryHeadcounts(UUID collectionID, String type) { | ||
Optional<MinistryReportTypeCode> code = MinistryReportTypeCode.findByValue(type); | ||
|
||
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); | ||
} | ||
|
||
return switch(code.get()) { | ||
case SCHOOL_ENROLLMENT_HEADCOUNTS -> ministryHeadcountService.getAllSchoolEnrollmentHeadcounts(collectionID); | ||
default -> new HeadcountResultsTable(); | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
...n/java/ca/bc/gov/educ/studentdatacollection/api/endpoint/v1/MinistryHeadcountReports.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package ca.bc.gov.educ.studentdatacollection.api.endpoint.v1; | ||
|
||
import ca.bc.gov.educ.studentdatacollection.api.constants.v1.URL; | ||
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.headcounts.HeadcountResultsTable; | ||
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_MINISTRY_HEADCOUNTS) | ||
public interface MinistryHeadcountReports { | ||
|
||
@GetMapping("/{collectionID}/{type}") | ||
@PreAuthorize("hasAuthority('SCOPE_READ_SDC_MINISTRY_REPORTS')") | ||
@Transactional(readOnly = true) | ||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "BAD REQUEST")}) | ||
HeadcountResultsTable getMinistryHeadcounts(@PathVariable UUID collectionID, @PathVariable(name = "type") String type); | ||
} |
143 changes: 143 additions & 0 deletions
143
.../ca/bc/gov/educ/studentdatacollection/api/reports/EllHeadcountPerSchoolReportService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package ca.bc.gov.educ.studentdatacollection.api.reports; | ||
|
||
import ca.bc.gov.educ.studentdatacollection.api.constants.v1.ReportTypeCode; | ||
import ca.bc.gov.educ.studentdatacollection.api.constants.v1.SchoolGradeCodes; | ||
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.model.v1.SdcDistrictCollectionEntity; | ||
import ca.bc.gov.educ.studentdatacollection.api.properties.ApplicationProperties; | ||
import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcDistrictCollectionRepository; | ||
import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcSchoolCollectionRepository; | ||
import ca.bc.gov.educ.studentdatacollection.api.repository.v1.SdcSchoolCollectionStudentRepository; | ||
import ca.bc.gov.educ.studentdatacollection.api.rest.RestUtils; | ||
import ca.bc.gov.educ.studentdatacollection.api.struct.external.institute.v1.SchoolTombstone; | ||
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.headcounts.EllHeadcountResult; | ||
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.reports.DownloadableReportResponse; | ||
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.reports.HeadcountChildNode; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import jakarta.annotation.PostConstruct; | ||
import lombok.extern.slf4j.Slf4j; | ||
import net.sf.jasperreports.engine.JRException; | ||
import net.sf.jasperreports.engine.JasperCompileManager; | ||
import net.sf.jasperreports.engine.JasperReport; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.io.InputStream; | ||
import java.util.*; | ||
|
||
@Service | ||
@Slf4j | ||
public class EllHeadcountPerSchoolReportService extends BaseReportGenerationService<EllHeadcountResult> { | ||
protected static final String ALLELL = "allEll"; | ||
private final SdcDistrictCollectionRepository sdcDistrictCollectionRepository; | ||
private final SdcSchoolCollectionStudentRepository sdcSchoolCollectionStudentRepository; | ||
private JasperReport ellHeadcountPerSchoolReport; | ||
private final RestUtils restUtils; | ||
private List<EllHeadcountResult> ellHeadcounts = new ArrayList<>(); | ||
private List<SchoolTombstone> allSchoolsTombstones; | ||
|
||
public EllHeadcountPerSchoolReportService(SdcDistrictCollectionRepository sdcDistrictCollectionRepository, SdcSchoolCollectionStudentRepository sdcSchoolCollectionStudentRepository, RestUtils restUtils, SdcSchoolCollectionRepository sdcSchoolCollectionRepository, RestUtils restUtils1) { | ||
super(restUtils, sdcSchoolCollectionRepository); | ||
|
||
this.sdcDistrictCollectionRepository = sdcDistrictCollectionRepository; | ||
this.sdcSchoolCollectionStudentRepository = sdcSchoolCollectionStudentRepository; | ||
this.restUtils = restUtils1; | ||
} | ||
|
||
@PostConstruct | ||
public void init() { | ||
ApplicationProperties.bgTask.execute(this::initialize); | ||
} | ||
|
||
private void initialize() { | ||
this.compileJasperReports(); | ||
} | ||
|
||
private void compileJasperReports() { | ||
try { | ||
InputStream inputSpecialEdHeadcount = getClass().getResourceAsStream("/reports/specialEdHeadcountsPerSchool.jrxml"); | ||
ellHeadcountPerSchoolReport = JasperCompileManager.compileReport(inputSpecialEdHeadcount); | ||
} catch (JRException e) { | ||
throw new StudentDataCollectionAPIRuntimeException("Compiling Jasper reports has failed :: " + e.getMessage()); | ||
} | ||
} | ||
|
||
public DownloadableReportResponse generateEllHeadcountPerSchoolReport(UUID collectionID) { | ||
try { | ||
Optional<SdcDistrictCollectionEntity> sdcDistrictCollectionEntityOptional = sdcDistrictCollectionRepository.findById(collectionID); | ||
SdcDistrictCollectionEntity sdcDistrictCollectionEntity = sdcDistrictCollectionEntityOptional.orElseThrow(() -> | ||
new EntityNotFoundException(SdcDistrictCollectionEntity.class, "CollectionId", collectionID.toString())); | ||
|
||
ellHeadcounts = sdcSchoolCollectionStudentRepository.getEllHeadcountsByBySchoolIdAndSdcDistrictCollectionId(sdcDistrictCollectionEntity.getSdcDistrictCollectionID()); | ||
this.allSchoolsTombstones = getAllSchoolTombstones(collectionID); | ||
return generateJasperReport(convertToReportJSONStringDistrict(ellHeadcounts, sdcDistrictCollectionEntity), ellHeadcountPerSchoolReport, ReportTypeCode.DIS_ELL_HEADCOUNT_PER_SCHOOL); | ||
} catch (JsonProcessingException e) { | ||
log.error("Exception occurred while writing PDF report for ell dis per school :: " + e.getMessage()); | ||
throw new StudentDataCollectionAPIRuntimeException("Exception occurred while writing PDF report for ell dis per school :: " + e.getMessage()); | ||
} | ||
} | ||
|
||
public HashMap<String, HeadcountChildNode> generateNodeMap(boolean includeKH) { | ||
HashMap<String, HeadcountChildNode> nodeMap = new HashMap<>(); | ||
Set<String> includedSchoolIDs = new HashSet<>(); | ||
addValuesForSectionToMap(nodeMap, ALLELL, "All English Language Learners Headcount for All Schools", "00"); | ||
|
||
int sequencePrefix = 10; | ||
if (!ellHeadcounts.isEmpty()) { | ||
for (EllHeadcountResult result : ellHeadcounts) { | ||
String schoolID = result.getSchoolID(); | ||
Optional<SchoolTombstone> schoolOptional = restUtils.getSchoolBySchoolID(schoolID); | ||
int finalSequencePrefix = sequencePrefix; | ||
schoolOptional.ifPresent(school -> { | ||
includedSchoolIDs.add(school.getSchoolId()); | ||
String schoolTitle = school.getMincode() + " - " + school.getDisplayName(); | ||
addValuesForSectionToMap(nodeMap, schoolID, schoolTitle, String.valueOf(finalSequencePrefix)); | ||
}); | ||
sequencePrefix += 10; | ||
} | ||
} | ||
|
||
for (SchoolTombstone school : allSchoolsTombstones) { | ||
if (!includedSchoolIDs.contains(school.getSchoolId())) { | ||
String schoolTitle = school.getMincode() + " - " + school.getDisplayName(); | ||
addValuesForSectionToMap(nodeMap, school.getSchoolId(), schoolTitle, String.valueOf(sequencePrefix)); | ||
sequencePrefix += 10; | ||
} | ||
} | ||
|
||
return nodeMap; | ||
} | ||
|
||
private void addValuesForSectionToMap(HashMap<String, HeadcountChildNode> nodeMap, String sectionPrefix, String sectionTitle, String sequencePrefix) { | ||
if (Objects.equals(sectionPrefix, ALLELL)) { | ||
nodeMap.put(sectionPrefix, new HeadcountChildNode(sectionTitle, "true", sequencePrefix + "0", false, false, false, false)); | ||
} else { | ||
nodeMap.put(sectionPrefix + "Heading", new HeadcountChildNode(sectionTitle, "true", sequencePrefix + "0", false)); | ||
nodeMap.put(sectionPrefix + "all", new HeadcountChildNode("All English Language Learners", FALSE, sequencePrefix + "1", false)); | ||
} | ||
} | ||
|
||
public void setValueForGrade(HashMap<String, HeadcountChildNode> nodeMap, EllHeadcountResult gradeResult) { | ||
Optional<SchoolGradeCodes> optionalCode = SchoolGradeCodes.findByValue(gradeResult.getEnrolledGradeCode()); | ||
var code = optionalCode.orElseThrow(() -> | ||
new EntityNotFoundException(SchoolGradeCodes.class, "Grade Value", gradeResult.getEnrolledGradeCode())); | ||
String schoolID = gradeResult.getSchoolID(); | ||
|
||
HeadcountChildNode allEllNode = nodeMap.get(ALLELL); | ||
if (allEllNode.getValueForGrade(code) == null) { | ||
allEllNode.setValueForGrade(code, "0"); | ||
} | ||
|
||
if (nodeMap.containsKey(schoolID + "all")) { | ||
nodeMap.get(schoolID + "all").setValueForGrade(code, gradeResult.getTotalEllStudents()); | ||
} | ||
|
||
if (nodeMap.containsKey(schoolID + "Heading")) { | ||
nodeMap.get(schoolID + "Heading").setAllValuesToNull(); | ||
} | ||
|
||
int currentTotal = Integer.parseInt(gradeResult.getTotalEllStudents()); | ||
int accumulatedTotal = Integer.parseInt(allEllNode.getValueForGrade(code)); | ||
allEllNode.setValueForGrade(code, String.valueOf(accumulatedTotal + currentTotal)); | ||
} | ||
} |
Oops, something went wrong.