From 72cbea3a0a3a21d98a2171f6ebf6d83d64d07cc9 Mon Sep 17 00:00:00 2001 From: alexmcdermid Date: Fri, 16 Feb 2024 14:40:31 -0800 Subject: [PATCH 1/3] feat: Add v79 - funding warning no funding for sped --- .../StudentValidationIssueTypeCode.java | 1 + .../v1/ValidationRulesDependencyMatrix.java | 3 +- .../impl/SchoolAgedSpedRule.java | 62 +++++++++++++++++++ .../api/rules/RulesProcessorTest.java | 18 ++++++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/StudentValidationIssueTypeCode.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/StudentValidationIssueTypeCode.java index 3a54c6f2d..7a4a01bc2 100644 --- a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/StudentValidationIssueTypeCode.java +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/StudentValidationIssueTypeCode.java @@ -90,6 +90,7 @@ public enum StudentValidationIssueTypeCode { SCHOOL_AGED_ZERO_COURSE_HISTORY("SCHOOLAGEDZEROCOURSEH", "Zero courses reported in last two years."), SCHOOL_AGED_INDIGENOUS_SUPPORT("SCHOOLAGEDINDIGENOUSSUPPORT", "Only school-aged students will receive funding for Indigenous Support Programs."), SCHOOL_AGED_ELL("SCHOOLAGEDELL", "Only school-aged students will receive funding for English Language Learning."), + SCHOOL_AGED_SPED("SCHOOLAGEDSPED", "Only school-aged students or non-graduated adults will receive funding for Special Education."), ; /** diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/ValidationRulesDependencyMatrix.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/ValidationRulesDependencyMatrix.java index f31a2c203..4bab09681 100644 --- a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/ValidationRulesDependencyMatrix.java +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/constants/v1/ValidationRulesDependencyMatrix.java @@ -60,7 +60,8 @@ public enum ValidationRulesDependencyMatrix { ENTRY53("V47", new String[]{NO_OF_COURSES_INVALID.getCode(), INVALID_GRADE_CODE.getCode(), DOB_INVALID_FORMAT.getCode()}), ENTRY54("V76", new String[]{SPED_ERR.getCode()}), ENTRY55("V77", new String[]{DOB_INVALID_FORMAT.getCode(), ENROLLED_CODE_PARSE_ERR.getCode(), ENROLLED_CODE_INVALID.getCode()}), - ENTRY56("V78", new String[]{DOB_INVALID_FORMAT.getCode(), ENROLLED_CODE_PARSE_ERR.getCode(), ENROLLED_CODE_INVALID.getCode()}); + ENTRY56("V78", new String[]{DOB_INVALID_FORMAT.getCode(), ENROLLED_CODE_PARSE_ERR.getCode(), ENROLLED_CODE_INVALID.getCode()}), + ENTRY57("V79", new String[]{DOB_INVALID_FORMAT.getCode(), SPED_ERR.getCode()}); @Getter private final String ruleID; diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java new file mode 100644 index 000000000..237138884 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java @@ -0,0 +1,62 @@ +package ca.bc.gov.educ.studentdatacollection.api.rules.validationrules.impl; + +import ca.bc.gov.educ.studentdatacollection.api.calculator.FteCalculatorUtils; +import ca.bc.gov.educ.studentdatacollection.api.constants.StudentValidationFieldCode; +import ca.bc.gov.educ.studentdatacollection.api.constants.StudentValidationIssueSeverityCode; +import ca.bc.gov.educ.studentdatacollection.api.constants.StudentValidationIssueTypeCode; +import ca.bc.gov.educ.studentdatacollection.api.rules.ValidationBaseRule; +import ca.bc.gov.educ.studentdatacollection.api.struct.StudentRuleData; +import ca.bc.gov.educ.studentdatacollection.api.struct.v1.SdcSchoolCollectionStudentValidationIssue; +import ca.bc.gov.educ.studentdatacollection.api.util.DOBUtil; +import lombok.extern.slf4j.Slf4j; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +/** + * | ID | Severity | Rule | Dependent On | + * |-----|----------|------------------------------------------------------------------------------|--------------| + * | V79 | WARNING | Only school-aged students or non-graduated students will receive funding | V04, V60 | + * for Special Education. + * + */ +@Component +@Slf4j +@Order(750) +public class SchoolAgedSpedRule implements ValidationBaseRule { + @Override + public boolean shouldExecute(StudentRuleData studentRuleData, List validationErrorsMap) { + log.debug("In shouldExecute of SchoolAgedSPEDRule-V78: for collectionType {} and sdcSchoolCollectionStudentID :: {}" , FteCalculatorUtils.getCollectionTypeCode(studentRuleData), + studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); + + var shouldExecute = isValidationDependencyResolved("V78", validationErrorsMap); + + log.debug("In shouldExecute of SchoolAgedSPEDRule-V78: Condition returned - {} for sdcSchoolCollectionStudentID :: {}" , + shouldExecute, + studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); + + return shouldExecute; + } + + @Override + public List executeValidation(StudentRuleData studentRuleData) { + log.debug("In executeValidation of SchoolAgedSpedRule-V78 for sdcSchoolCollectionStudentID ::" + studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); + + final List errors = new ArrayList<>(); + var student = studentRuleData.getSdcSchoolCollectionStudentEntity(); + + log.debug("SchoolAgedSpedRule-V78: Only school-aged students or non-graduated adults will receive funding for Special Education for sdcSchoolCollectionStudentID:: {}", studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); + if (StringUtils.isNotEmpty(student.getSpecialEducationCategoryCode()) + && DOBUtil.isAdult(student.getDob()) && BooleanUtils.isTrue(student.getIsGraduated())) { + errors.add(createValidationIssue(StudentValidationIssueSeverityCode.FUNDING_WARNING, StudentValidationFieldCode.SPECIAL_EDUCATION_CATEGORY_CODE, StudentValidationIssueTypeCode.SCHOOL_AGED_SPED)); + errors.add(createValidationIssue(StudentValidationIssueSeverityCode.FUNDING_WARNING, StudentValidationFieldCode.DOB, StudentValidationIssueTypeCode.SCHOOL_AGED_SPED)); + } + + return errors; + } +} \ No newline at end of file diff --git a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java index c5f39f925..7986998ae 100644 --- a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java +++ b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java @@ -887,6 +887,24 @@ void testSchoolAgedELLRule() { assertThat(error2).isTrue(); } + @Test + void testSchoolAgedSpedRule() { + var collection = collectionRepository.save(createMockCollectionEntity()); + var sdcSchoolCollectionEntity = sdcSchoolCollectionRepository.save(createMockSdcSchoolCollectionEntity(collection, null, null)); + val entity = this.createMockSchoolStudentEntity(sdcSchoolCollectionEntity); + entity.setSpecialEducationCategoryCode("A"); + entity.setDob("19890101"); + entity.setIsGraduated(true); + + val validationError = rulesProcessor.processRules(createMockStudentRuleData(entity, createMockSchool())); + val error1 = validationError.stream().anyMatch(val -> val.getValidationIssueCode().equals(StudentValidationIssueTypeCode.SCHOOL_AGED_SPED.getCode()) + && val.getValidationIssueFieldCode().equals(StudentValidationFieldCode.SPECIAL_EDUCATION_CATEGORY_CODE.getCode())); + val error2 = validationError.stream().anyMatch(val -> val.getValidationIssueCode().equals(StudentValidationIssueTypeCode.SCHOOL_AGED_SPED.getCode()) + && val.getValidationIssueFieldCode().equals(StudentValidationFieldCode.DOB.getCode())); + assertThat(error1).isTrue(); + assertThat(error2).isTrue(); + } + @Test void testAdultGraduatesRule() { var collection = collectionRepository.save(createMockCollectionEntity()); From 3ccb347efe2f10ebec81c3321f5fcb459b221040 Mon Sep 17 00:00:00 2001 From: alexmcdermid Date: Fri, 16 Feb 2024 14:41:27 -0800 Subject: [PATCH 2/3] fix: upate v number --- .../rules/validationrules/impl/SchoolAgedSpedRule.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java index 237138884..63dcf102a 100644 --- a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java @@ -31,12 +31,12 @@ public class SchoolAgedSpedRule implements ValidationBaseRule { @Override public boolean shouldExecute(StudentRuleData studentRuleData, List validationErrorsMap) { - log.debug("In shouldExecute of SchoolAgedSPEDRule-V78: for collectionType {} and sdcSchoolCollectionStudentID :: {}" , FteCalculatorUtils.getCollectionTypeCode(studentRuleData), + log.debug("In shouldExecute of SchoolAgedSPEDRule-V79: for collectionType {} and sdcSchoolCollectionStudentID :: {}" , FteCalculatorUtils.getCollectionTypeCode(studentRuleData), studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); - var shouldExecute = isValidationDependencyResolved("V78", validationErrorsMap); + var shouldExecute = isValidationDependencyResolved("V79", validationErrorsMap); - log.debug("In shouldExecute of SchoolAgedSPEDRule-V78: Condition returned - {} for sdcSchoolCollectionStudentID :: {}" , + log.debug("In shouldExecute of SchoolAgedSPEDRule-V79: Condition returned - {} for sdcSchoolCollectionStudentID :: {}" , shouldExecute, studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); @@ -45,12 +45,12 @@ public boolean shouldExecute(StudentRuleData studentRuleData, List executeValidation(StudentRuleData studentRuleData) { - log.debug("In executeValidation of SchoolAgedSpedRule-V78 for sdcSchoolCollectionStudentID ::" + studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); + log.debug("In executeValidation of SchoolAgedSpedRule-V79 for sdcSchoolCollectionStudentID ::" + studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); final List errors = new ArrayList<>(); var student = studentRuleData.getSdcSchoolCollectionStudentEntity(); - log.debug("SchoolAgedSpedRule-V78: Only school-aged students or non-graduated adults will receive funding for Special Education for sdcSchoolCollectionStudentID:: {}", studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); + log.debug("SchoolAgedSpedRule-V79: Only school-aged students or non-graduated adults will receive funding for Special Education for sdcSchoolCollectionStudentID:: {}", studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); if (StringUtils.isNotEmpty(student.getSpecialEducationCategoryCode()) && DOBUtil.isAdult(student.getDob()) && BooleanUtils.isTrue(student.getIsGraduated())) { errors.add(createValidationIssue(StudentValidationIssueSeverityCode.FUNDING_WARNING, StudentValidationFieldCode.SPECIAL_EDUCATION_CATEGORY_CODE, StudentValidationIssueTypeCode.SCHOOL_AGED_SPED)); From fe71bc8ef6b972f486d5acd5066b754512b32790 Mon Sep 17 00:00:00 2001 From: alexmcdermid Date: Fri, 16 Feb 2024 15:44:55 -0800 Subject: [PATCH 3/3] fix: check for sped codes on not adult and not school aged users --- .../validationrules/impl/SchoolAgedSpedRule.java | 4 ++-- .../api/rules/RulesProcessorTest.java | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java index 63dcf102a..fa4dec5ce 100644 --- a/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java +++ b/api/src/main/java/ca/bc/gov/educ/studentdatacollection/api/rules/validationrules/impl/SchoolAgedSpedRule.java @@ -51,8 +51,8 @@ public List executeValidation(Student var student = studentRuleData.getSdcSchoolCollectionStudentEntity(); log.debug("SchoolAgedSpedRule-V79: Only school-aged students or non-graduated adults will receive funding for Special Education for sdcSchoolCollectionStudentID:: {}", studentRuleData.getSdcSchoolCollectionStudentEntity().getSdcSchoolCollectionStudentID()); - if (StringUtils.isNotEmpty(student.getSpecialEducationCategoryCode()) - && DOBUtil.isAdult(student.getDob()) && BooleanUtils.isTrue(student.getIsGraduated())) { + if ((StringUtils.isNotEmpty(student.getSpecialEducationCategoryCode()) && DOBUtil.isAdult(student.getDob()) && BooleanUtils.isTrue(student.getIsGraduated())) + || (StringUtils.isNotEmpty(student.getSpecialEducationCategoryCode()) && !DOBUtil.isAdult(student.getDob()) && !DOBUtil.isSchoolAged(student.getDob()))) { errors.add(createValidationIssue(StudentValidationIssueSeverityCode.FUNDING_WARNING, StudentValidationFieldCode.SPECIAL_EDUCATION_CATEGORY_CODE, StudentValidationIssueTypeCode.SCHOOL_AGED_SPED)); errors.add(createValidationIssue(StudentValidationIssueSeverityCode.FUNDING_WARNING, StudentValidationFieldCode.DOB, StudentValidationIssueTypeCode.SCHOOL_AGED_SPED)); } diff --git a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java index 7986998ae..79de94de8 100644 --- a/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java +++ b/api/src/test/java/ca/bc/gov/educ/studentdatacollection/api/rules/RulesProcessorTest.java @@ -892,9 +892,12 @@ void testSchoolAgedSpedRule() { var collection = collectionRepository.save(createMockCollectionEntity()); var sdcSchoolCollectionEntity = sdcSchoolCollectionRepository.save(createMockSdcSchoolCollectionEntity(collection, null, null)); val entity = this.createMockSchoolStudentEntity(sdcSchoolCollectionEntity); + val entity2 = this.createMockSchoolStudentEntity(sdcSchoolCollectionEntity); entity.setSpecialEducationCategoryCode("A"); entity.setDob("19890101"); entity.setIsGraduated(true); + entity2.setSpecialEducationCategoryCode("A"); + entity2.setDob("20230101"); val validationError = rulesProcessor.processRules(createMockStudentRuleData(entity, createMockSchool())); val error1 = validationError.stream().anyMatch(val -> val.getValidationIssueCode().equals(StudentValidationIssueTypeCode.SCHOOL_AGED_SPED.getCode()) @@ -903,6 +906,15 @@ void testSchoolAgedSpedRule() { && val.getValidationIssueFieldCode().equals(StudentValidationFieldCode.DOB.getCode())); assertThat(error1).isTrue(); assertThat(error2).isTrue(); + + + val validationError2 = rulesProcessor.processRules(createMockStudentRuleData(entity2, createMockSchool())); + val error21 = validationError2.stream().anyMatch(val -> val.getValidationIssueCode().equals(StudentValidationIssueTypeCode.SCHOOL_AGED_SPED.getCode()) + && val.getValidationIssueFieldCode().equals(StudentValidationFieldCode.SPECIAL_EDUCATION_CATEGORY_CODE.getCode())); + val error22 = validationError2.stream().anyMatch(val -> val.getValidationIssueCode().equals(StudentValidationIssueTypeCode.SCHOOL_AGED_SPED.getCode()) + && val.getValidationIssueFieldCode().equals(StudentValidationFieldCode.DOB.getCode())); + assertThat(error21).isTrue(); + assertThat(error22).isTrue(); } @Test