Skip to content

Commit

Permalink
Merge pull request #1056 from bcgov/feature/sped
Browse files Browse the repository at this point in the history
Added first Ministry report
  • Loading branch information
arcshiftsolutions authored Aug 15, 2024
2 parents 5ce372b + c70cfe3 commit 8e5ca68
Show file tree
Hide file tree
Showing 11 changed files with 381 additions and 0 deletions.
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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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_DISTRICT_COLLECTION="/api/v1/student-data-collection/sdcDistrictCollection";
public static final String BASE_DISTRICT_HEADCOUNTS = "/api/v1/student-data-collection/headcounts";
public static final String BASE_MINISTRY_HEADCOUNTS = "/api/v1/student-data-collection/ministryHeadcounts";
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";
Expand Down
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; }
}
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();
};
}
}
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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ HAVING COUNT(assignedStudentId) > 1)

long countBySdcSchoolCollection_SdcSchoolCollectionIDAndSdcSchoolCollectionStudentStatusCode(UUID sdcSchoolCollectionID, String sdcSchoolCollectionStatusCode);

@Query("SELECT " +
" sscs.sdcSchoolCollection.schoolID as schoolID, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = 'KH' THEN 1 END) as kindHCount, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = 'KF' THEN 1 END) as kindFCount, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '01' THEN 1 END) as grade1Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '02' THEN 1 END) as grade2Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '03' THEN 1 END) as grade3Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '04' THEN 1 END) as grade4Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '05' THEN 1 END) as grade5Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '06' THEN 1 END) as grade6Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '07' THEN 1 END) as grade7Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '08' THEN 1 END) as grade8Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '09' THEN 1 END) as grade9Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '10' THEN 1 END) as grade10Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '11' THEN 1 END) as grade11Count, " +
" COUNT(CASE WHEN sscs.enrolledGradeCode = '12' THEN 1 END) as grade12Count " +
" FROM SdcSchoolCollectionStudentEntity sscs " +
" WHERE sscs.sdcSchoolCollectionStudentStatusCode NOT IN ('ERROR', 'DELETED') " +
" AND sscs.sdcSchoolCollection.collectionEntity.collectionID = :collectionID " +
" GROUP BY sscs.sdcSchoolCollection.sdcSchoolCollectionID ")
List<SchoolHeadcountResult> getAllEnrollmentHeadcountsByCollectionId(@Param("collectionID") UUID collectionID);

@Query(value = """
SELECT stud
FROM SdcSchoolCollectionStudentLightEntity stud, SdcSchoolCollectionEntity school, SdcDistrictCollectionEntity dist
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package ca.bc.gov.educ.studentdatacollection.api.service.v1;

import ca.bc.gov.educ.studentdatacollection.api.constants.v1.CollectionTypeCodes;
import ca.bc.gov.educ.studentdatacollection.api.constants.v1.ministryreports.SchoolEnrolmentHeader;
import ca.bc.gov.educ.studentdatacollection.api.exception.EntityNotFoundException;
import ca.bc.gov.educ.studentdatacollection.api.model.v1.CollectionEntity;
import ca.bc.gov.educ.studentdatacollection.api.repository.v1.CollectionRepository;
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.v1.Collection;
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.headcounts.HeadcountHeaderColumn;
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.headcounts.HeadcountResultsTable;
import ca.bc.gov.educ.studentdatacollection.api.struct.v1.headcounts.SchoolHeadcountResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

import static ca.bc.gov.educ.studentdatacollection.api.constants.v1.ministryreports.SchoolEnrolmentHeader.*;


@Service
@Slf4j
@RequiredArgsConstructor
public class MinistryHeadcountService {
private final CollectionRepository collectionRepository;
private final SdcSchoolCollectionStudentRepository sdcSchoolCollectionStudentRepository;
private final RestUtils restUtils;
private static final String COLLECTION_ID = "collectionID";

public HeadcountResultsTable getAllSchoolEnrollmentHeadcounts(UUID collectionID) {
List<SchoolHeadcountResult> collectionRawData = sdcSchoolCollectionStudentRepository.getAllEnrollmentHeadcountsByCollectionId(collectionID);
var collectionOpt = collectionRepository.findById(collectionID);
if(collectionOpt.isEmpty()){
throw new EntityNotFoundException(Collection.class, COLLECTION_ID, collectionID.toString());
}
var collection = collectionOpt.get();

HeadcountResultsTable resultsTable = new HeadcountResultsTable();
var headerList = new ArrayList<String>();
for (SchoolEnrolmentHeader header : SchoolEnrolmentHeader.values()) {
headerList.add(header.getCode());
}
resultsTable.setHeaders(headerList);
var rows = new ArrayList<Map<String, HeadcountHeaderColumn>>();
collectionRawData.stream().forEach(schoolHeadcountResult -> {
var school = restUtils.getSchoolBySchoolID(schoolHeadcountResult.getSchoolID()).get();

var rowMap = new HashMap<String, HeadcountHeaderColumn>();
rowMap.put(SCHOOL_YEAR.getCode(), getHeadcountColumn(getSchoolYearString(collection)));
rowMap.put(DISTRICT_NUMBER.getCode(), getHeadcountColumn(school.getMincode().substring(0,3)));
rowMap.put(SCHOOL_NUMBER.getCode(), getHeadcountColumn(school.getSchoolNumber()));
rowMap.put(SCHOOL_NAME.getCode(), getHeadcountColumn(school.getDisplayName()));
rowMap.put(FACILITY_TYPE.getCode(), getHeadcountColumn(school.getFacilityTypeCode()));
rowMap.put(SCHOOL_CATEGORY.getCode(), getHeadcountColumn(school.getSchoolCategoryCode()));
rowMap.put(REPORT_DATE.getCode(), getHeadcountColumn(collection.getSnapshotDate().toString()));
rowMap.put(KIND_HT_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getKindHCount()));
rowMap.put(KIND_FT_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getKindFCount()));
rowMap.put(GRADE_01_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade1Count()));
rowMap.put(GRADE_02_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade2Count()));
rowMap.put(GRADE_03_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade3Count()));
rowMap.put(GRADE_04_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade4Count()));
rowMap.put(GRADE_05_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade5Count()));
rowMap.put(GRADE_06_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade6Count()));
rowMap.put(GRADE_07_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade7Count()));
rowMap.put(GRADE_08_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade8Count()));
rowMap.put(GRADE_09_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade9Count()));
rowMap.put(GRADE_10_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade10Count()));
rowMap.put(GRADE_11_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade11Count()));
rowMap.put(GRADE_12_COUNT.getCode(), getHeadcountColumn(schoolHeadcountResult.getGrade12Count()));
rows.add(rowMap);
});
resultsTable.setRows(rows);
return resultsTable;
}

private HeadcountHeaderColumn getHeadcountColumn(String value){
HeadcountHeaderColumn column = new HeadcountHeaderColumn();
column.setCurrentValue(value);
return column;
}

private String getSchoolYearString(CollectionEntity collection){
var snapshotDateString = collection.getSnapshotDate();
if(!collection.getCollectionTypeCode().equals(CollectionTypeCodes.SEPTEMBER.getTypeCode())){
return snapshotDateString.minusYears(1).getYear() + "/" + snapshotDateString.getYear() + "SY";
}else{
return snapshotDateString.getYear() + "/" + snapshotDateString.plusYears(1).getYear() + "SY";
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ca.bc.gov.educ.studentdatacollection.api.struct.v1.headcounts;

public interface SchoolHeadcountResult extends HeadcountResult{
String getKindHCount();
String getKindFCount();
String getGrade1Count();
String getGrade2Count();
String getGrade3Count();
String getGrade4Count();
String getGrade5Count();
String getGrade6Count();
String getGrade7Count();
String getGrade8Count();
String getGrade9Count();
String getGrade10Count();
String getGrade11Count();
String getGrade12Count();
}
Loading

0 comments on commit 8e5ca68

Please sign in to comment.