diff --git a/backend/src/components/cache-service.js b/backend/src/components/cache-service.js index afd9e2db5..14cfa9ca9 100644 --- a/backend/src/components/cache-service.js +++ b/backend/src/components/cache-service.js @@ -20,6 +20,11 @@ let activeDistricts = []; let activeAuthorities = []; let authorities = []; let authoritiesMap = new Map(); +let bandCodesMap = new Map(); +let enrolledProgramCodesMap = new Map(); +let careerProgramCodesMap = new Map(); +let schoolFundingCodesMap = new Map(); +let specialEducationCodesMap = new Map(); let rolePermissionsMap = new Map(); let documentTypeCodesMap = new Map(); let documentTypeCodes = []; @@ -192,9 +197,6 @@ const cacheService = { retries: 50 }); }, - getAllDocumentTypeCodesJSON() { - return documentTypeCodes; - }, getDocumentTypeCodeLabelByCode(code) { return documentTypeCodesMap.get(code); }, @@ -232,19 +234,75 @@ const cacheService = { getCachedData(){ return cachedData; }, + getAllActiveBandCodesMap() { + let bandCodesRaw = cachedData[constants.CACHE_KEYS.SDC_BAND_CODES].activeRecords; + let bandCodes = bandCodesRaw.map(item => { + return {...item, dropdownText: `${item.description} (${item.bandCode})`}; + }); + + bandCodes.unshift({'bandCode': '', 'dropdownText': 'No Band Code'}); + bandCodes.forEach(bandCode => { + bandCodesMap.set(bandCode.bandCode, bandCode); + }); + return bandCodesMap; + }, + getActiveCareerProgramCodesMap() { + let careerProgramCodesRaw = cachedData[constants.CACHE_KEYS.SDC_CAREER_PROGRAM_CODES].activeRecords; + let careerProgramCodes = careerProgramCodesRaw.map(item => { + return {...item, dropdownText: `${item.description} (${item.careerProgramCode})`}; + }); + careerProgramCodes.unshift({'careerProgramCode': '', 'dropdownText': 'No Career Code'}); + careerProgramCodes.forEach(careerProgramCode => { + careerProgramCodesMap.set(careerProgramCode.careerProgramCode, careerProgramCode); + }); + return careerProgramCodesMap; + }, + getEnrolledProgramCodesMap() { + let enrolledProgramCodesRaw = cachedData[constants.CACHE_KEYS.SDC_ENROLLED_GRADE_CODES].activeRecords; + let enrolledProgramCodes = enrolledProgramCodesRaw.map(item => { + return {...item, dropdownText: `${item.description} (${item.enrolledProgramCode})`}; + }); + enrolledProgramCodes.forEach(enrolledProgramCode => { + enrolledProgramCodesMap.set(enrolledProgramCode.enrolledProgramCode, enrolledProgramCode); + }); + return enrolledProgramCodesMap; + }, + getActiveSchoolFundingCodesMap() { + let schoolFundingCodesRaw = cachedData[constants.CACHE_KEYS.SDC_SCHOOL_FUNDING_CODES].activeRecords; + let schoolFundingCodes = schoolFundingCodesRaw.map(item => { + return {...item, dropdownText: `${item.description} (${item.schoolFundingCode})`}; + }); + schoolFundingCodes.unshift({'schoolFundingCode': '', 'dropdownText': 'No Funding Code'}); + schoolFundingCodes.forEach(schoolFundingCode => { + schoolFundingCodesMap.set(schoolFundingCode.schoolFundingCode, schoolFundingCode); + }); + return schoolFundingCodesMap; + }, + getActiveSpecialEducationCodesMap() { + let specialEducationCodesRaw = cachedData[constants.CACHE_KEYS.SDC_SPECIAL_ED_CODES].activeRecords; + let specialEducationCodes = specialEducationCodesRaw.map(item => { + return {...item, dropdownText: `${item.description} (${item.specialEducationCategoryCode})`}; + }); + specialEducationCodesMap = new Map(); + specialEducationCodes.unshift({'specialEducationCategoryCode': '', 'dropdownText': 'No Special Ed Category Code'}); + specialEducationCodes.forEach(specialEducationCategoryCode => { + specialEducationCodesMap.set(specialEducationCategoryCode.specialEducationCategoryCode, specialEducationCategoryCode); + }); + return specialEducationCodesMap; + }, getActiveEnrolledGradeCodes() { return cachedData[constants.CACHE_KEYS.SDC_ENROLLED_GRADE_CODES].activeRecords; }, - getActiveFundingCodes() { + getActiveSchoolFundingCodes() { return cachedData[constants.CACHE_KEYS.SDC_SCHOOL_FUNDING_CODES].activeRecords; }, - getActiveCareerCodes() { + getActiveCareerProgramCodes() { return cachedData[constants.CACHE_KEYS.SDC_CAREER_PROGRAM_CODES].activeRecords; }, - getActiveEnrolledPrograms() { + getActiveEnrolledProgramCodes() { return cachedData[constants.CACHE_KEYS.SDC_ENROLLED_PROGRAM_CODES].activeRecords; }, - getActiveSpedCodes() { + getActiveSpecialEducationCodes() { return cachedData[constants.CACHE_KEYS.SDC_SPECIAL_ED_CODES].activeRecords; } }; diff --git a/backend/src/components/sdc.js b/backend/src/components/sdc.js index a33daff07..c7344f988 100644 --- a/backend/src/components/sdc.js +++ b/backend/src/components/sdc.js @@ -3,9 +3,10 @@ const { getAccessToken, handleExceptionResponse, getData, postData, putData, get const HttpStatus = require('http-status-codes'); const log = require('./logger'); const config = require('../config'); -const { FILTER_OPERATION, VALUE_TYPE, CONDITION } = require('../util/constants'); +const { FILTER_OPERATION, VALUE_TYPE, CONDITION, ENROLLED_PROGRAM_TYPE_CODE_MAP} = require('../util/constants'); const {createMoreFiltersSearchCriteria} = require('./studentFilters'); const {REPORT_TYPE_CODE_MAP} = require('../util/constants'); +const cacheService = require('./cache-service'); async function getCollectionBySchoolId(req, res) { try { @@ -160,6 +161,10 @@ async function getSDCSchoolCollectionStudentPaginated(req, res) { return res.status(HttpStatus.OK).json(result); } + if(req?.query?.tableFormat){ + data.content = data?.content.map(toTableRow); + } + return res.status(HttpStatus.OK).json(data); } catch (e) { if (e?.status === 404) { @@ -201,6 +206,20 @@ async function getSDCSchoolCollectionStudentDetail(req, res) { } } +async function markSdcSchoolCollectionStudentAsDifferent(req, res) { + try { + const payload = req.body; + payload.assignedPen = null; + payload.assignedStudentId = null; + payload.penMatchResult = 'MRKED_DIFF'; + + return updateAndValidateSdcSchoolCollectionStudent(req, res); + } catch (e) { + log.error('Error updating sdc school collection student detail', e.stack); + return handleExceptionResponse(e, res); + } +} + async function updateAndValidateSdcSchoolCollectionStudent(req, res) { try { const payload = req.body; @@ -253,6 +272,78 @@ async function removeSDCSchoolCollectionStudents(req, res) { } } +async function getSchoolStudentDuplicates(req, res) { + try { + const token = getAccessToken(req); + let studentDuplicates = await getData(token, `${config.get('sdc:schoolCollectionURL')}/${req.params.sdcSchoolCollectionID}/duplicates`, req.session?.correlationID); + + let dupsMap = new Map(); + studentDuplicates.forEach((dup) => { + if(dupsMap.has(dup.assignedPen)){ + dupsMap.get(dup.assignedPen).push(toTableRow(dup)); + }else{ + dupsMap.set(dup.assignedPen, [toTableRow(dup)]); + } + }); + + let resultArray = []; + + dupsMap.forEach(function(items,key){ + resultArray.push({assignedPen: key, items}); + }); + + return res.status(HttpStatus.OK).json(resultArray); + } catch (e) { + log.error('Error getting Student duplicates.', e.stack); + return handleExceptionResponse(e, res); + } +} + +function toTableRow(student) { + let bandCodesMap = cacheService.getAllActiveBandCodesMap(); + let careerProgramCodesMap = cacheService.getActiveCareerProgramCodesMap(); + let schoolFundingCodesMap = cacheService.getActiveSchoolFundingCodesMap(); + let specialEducationCodesMap = cacheService.getActiveSpecialEducationCodesMap(); + + student.mappedSpedCode = specialEducationCodesMap.get(student.specialEducationCategoryCode) !== undefined ? `${specialEducationCodesMap.get(student.specialEducationCategoryCode)?.description} (${specialEducationCodesMap.get(student.specialEducationCategoryCode)?.specialEducationCategoryCode})` : null; + student.mappedAncestryIndicator = student.nativeAncestryInd === null ? null : nativeAncestryInd(student); + student.mappedFrenchEnrolledProgram = enrolledProgramMapping(student, ENROLLED_PROGRAM_TYPE_CODE_MAP.FRENCH_ENROLLED_PROGRAM_CODES); + student.mappedEllEnrolledProgram = enrolledProgramMapping(student, ENROLLED_PROGRAM_TYPE_CODE_MAP.ENGLISH_ENROLLED_PROGRAM_CODES); + student.mappedLanguageEnrolledProgram = enrolledProgramMapping(student, [...ENROLLED_PROGRAM_TYPE_CODE_MAP.ENGLISH_ENROLLED_PROGRAM_CODES, ...ENROLLED_PROGRAM_TYPE_CODE_MAP.FRENCH_ENROLLED_PROGRAM_CODES]); + student.careerProgram = enrolledProgramMapping(student, ENROLLED_PROGRAM_TYPE_CODE_MAP.CAREER_ENROLLED_PROGRAM_CODES); + student.mappedIndigenousEnrolledProgram = enrolledProgramMapping(student, ENROLLED_PROGRAM_TYPE_CODE_MAP.INDIGENOUS_ENROLLED_PROGRAM_CODES); + student.mappedBandCode = bandCodesMap.get(student.bandCode) !== undefined ? `${bandCodesMap.get(student.bandCode)?.description} (${bandCodesMap.get(student.bandCode)?.bandCode})` : null; + student.careerProgramCode = careerProgramCodesMap.get(student.careerProgramCode) !== undefined ? `${careerProgramCodesMap.get(student.careerProgramCode)?.description} (${careerProgramCodesMap.get(student.careerProgramCode)?.careerProgramCode})` : null; + student.mappedSchoolFunding = schoolFundingCodesMap.get(student.schoolFundingCode) !== undefined ? `${schoolFundingCodesMap.get(student.schoolFundingCode)?.description} (${schoolFundingCodesMap.get(student.schoolFundingCode)?.schoolFundingCode})` : null; + student.indProgramEligible = student.indigenousSupportProgramNonEligReasonCode !== null ? 'No' : 'Yes'; + student.frenchProgramEligible = student.frenchProgramNonEligReasonCode !== null ? 'No' : 'Yes'; + student.ellProgramEligible = student.ellNonEligReasonCode !== null ? 'No' : 'Yes'; + student.careerProgramEligible = student.careerProgramNonEligReasonCode !== null ? 'No' : 'Yes'; + student.spedProgramEligible = student.specialEducationNonEligReasonCode !== null ? 'No' : 'Yes'; + student.yearsInEll = student.sdcStudentEll ? student.sdcStudentEll.yearsInEll : ''; + student.mappedNoOfCourses = student.numberOfCoursesDec !== null ? student.numberOfCoursesDec.toFixed(2) : '0'; + return student; +} + +function enrolledProgramMapping(student, enrolledProgramFilter) { + let enrolledProgramCodesMap = cacheService.getActiveSpecialEducationCodesMap(); + if(!student.enrolledProgramCodes) { + return ''; + } + return student.enrolledProgramCodes + .match(/.{1,2}/g) + .filter(programCode => enrolledProgramFilter.includes(programCode)) + .map(programCode => { + const enrolledProgram = enrolledProgramCodesMap.get(programCode); + return enrolledProgram ? `${enrolledProgram.description} (${programCode})` : programCode; + }) + .join(','); +} + +function nativeAncestryInd(student) { + return student.nativeAncestryInd === 'Y' ? 'Yes' : 'No'; +} + async function getStudentHeadcounts(req, res) { try { const params = { @@ -454,6 +545,7 @@ module.exports = { getCollectionBySchoolId, uploadFile, getSdcFileProgress, + getSchoolStudentDuplicates, removeSDCSchoolCollectionStudents, updateSchoolCollection, getDistrictCollectionById, @@ -465,5 +557,6 @@ module.exports = { getSDCSchoolCollectionStudentDetail, updateAndValidateSdcSchoolCollectionStudent, deleteSDCSchoolCollectionStudent, + markSdcSchoolCollectionStudentAsDifferent, getStudentHeadcounts }; diff --git a/backend/src/components/studentFilters.js b/backend/src/components/studentFilters.js index a9311cc0c..1eb54402f 100644 --- a/backend/src/components/studentFilters.js +++ b/backend/src/components/studentFilters.js @@ -268,7 +268,7 @@ function validateGradeFilter(filterGrades = []) { } function validateFundingTypeFilter(filterFunding = []) { - const activeFundingCodes = cacheService.getActiveFundingCodes(); + const activeFundingCodes = cacheService.getActiveSchoolFundingCodes(); if (filterFunding.length > 0) { if (filterFunding.every(value => activeFundingCodes.includes(code => code !== 'No Funding' && value === code.schoolFundingCode))) { log.error('Invalid funding code filter.'); @@ -278,7 +278,7 @@ function validateFundingTypeFilter(filterFunding = []) { } function validateCareerCodeFilter(filterCareerCodes = []) { - const activeFundingCodes = cacheService.getActiveCareerCodes(); + const activeFundingCodes = cacheService.getActiveCareerProgramCodes(); if (filterCareerCodes.length > 0) { if (filterCareerCodes.every(value => activeFundingCodes.includes(code => value === code.careerProgramCode))) { log.error('Invalid career code filter.'); @@ -288,7 +288,7 @@ function validateCareerCodeFilter(filterCareerCodes = []) { } function validateEnrolledProgramFilter(filterGrades = []) { - const activeFundingCodes = cacheService.getActiveEnrolledPrograms(); + const activeFundingCodes = cacheService.getActiveEnrolledProgramCodes(); if (filterGrades.length > 0) { if (filterGrades.every(value => activeFundingCodes.includes(code => value === code.enrolledProgramCode))) { log.error('Invalid enrolled program filter.'); @@ -311,7 +311,7 @@ function validateWarningFilter(filters = []) { } function validateSpedCodes(filters = []) { - const activeSpedCodes = cacheService.getActiveSpedCodes(); + const activeSpedCodes = cacheService.getActiveSpecialEducationCodes(); if (filters.length > 0) { if (filters.every(value => activeSpedCodes.includes(code => value === code.specialEducationCategoryCode))) { log.error('Invalid special education filter.'); @@ -391,7 +391,7 @@ function createSpedFilter(pValue) { let spedCodeList = []; validateSpedCodes(pValue); if (pValue.includes('noSpedCode')) { - const notInValues = cacheService.getActiveSpedCodes().map(x=>x.specialEducationCategoryCode).filter(value => !pValue.includes(value) && pValue!=='noSpedCode'); + const notInValues = cacheService.getActiveSpecialEducationCodes().map(x=>x.specialEducationCategoryCode).filter(value => !pValue.includes(value) && pValue!=='noSpedCode'); if(notInValues?.length > 0) { //if all filters are selected then it is equivalent to no filters being selected spedCodeList.push({ key: 'specialEducationCategoryCode', value: notInValues.toString(), operation: FILTER_OPERATION.NOT_IN, valueType: VALUE_TYPE.STRING, condition: CONDITION.OR }); } @@ -511,7 +511,7 @@ function careerCodeFilter(pValue) { validateCareerCodeFilter(pValue); if (pValue.includes('noCareerCodes')) { - const notInValues = cacheService.getActiveCareerCodes().map(x=>x.careerProgramCode).filter(value => !pValue.includes(value) && pValue!=='noCareerCodes'); + const notInValues = cacheService.getActiveCareerProgramCodes().map(x=>x.careerProgramCode).filter(value => !pValue.includes(value) && pValue!=='noCareerCodes'); if(notInValues?.length > 0) { //if all filters are selected then it is equivalent to no filters being selected careerCodeList.push({ key: 'careerProgramCode', value: notInValues.toString(), operation: FILTER_OPERATION.NOT_IN, valueType: VALUE_TYPE.STRING, condition: CONDITION.OR }); } diff --git a/backend/src/routes/sdc.js b/backend/src/routes/sdc.js index fe2eb755f..ecc29439c 100644 --- a/backend/src/routes/sdc.js +++ b/backend/src/routes/sdc.js @@ -4,7 +4,10 @@ const router = express.Router(); const { getCollectionBySchoolId, getCollectionByDistrictId, uploadFile, getSdcFileProgress, updateSchoolCollection, getSchoolCollectionById, getDistrictCollectionById, getSDCSchoolCollectionStudentPaginated, getSDCSchoolCollectionStudentSummaryCounts, getSDCSchoolCollectionStudentDetail, updateAndValidateSdcSchoolCollectionStudent, deleteSDCSchoolCollectionStudent, removeSDCSchoolCollectionStudents, - getStudentHeadcounts, downloadSdcReport} = require('../components/sdc'); + getStudentHeadcounts, downloadSdcReport, + getSchoolStudentDuplicates, + markSdcSchoolCollectionStudentAsDifferent +} = require('../components/sdc'); const {getCachedSDCData} = require('../components/sdc-cache'); const auth = require('../components/auth'); const constants = require('../util/constants'); @@ -30,6 +33,7 @@ router.get('/zero-fte-reason-codes', passport.authenticate('jwt', {session: fals router.get('/getCollectionBySchoolId/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, getCollectionBySchoolId); router.get('/getCollectionByDistrictId/:districtID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, getCollectionByDistrictId); +router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolStudentDuplicates); router.get('/sdcSchoolCollection/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolCollectionById); router.get('/sdcDistrictCollection/:sdcDistrictCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getDistrictCollectionById); router.post('/:sdcSchoolCollectionID/file', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, scanFilePayload, uploadFile); @@ -39,6 +43,7 @@ router.get('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/paginated', passp router.get('/sdcSchoolCollectionStudent/stats/error-warning-count/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentSummaryCounts); router.get('/sdcSchoolCollectionStudent/:sdcSchoolCollectionStudentID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionStudentID_params, loadSdcSchoolCollectionStudent, findSdcSchoolCollectionID_fromRequestedSdcSchoolCollectionStudent, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentDetail); router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, updateAndValidateSdcSchoolCollectionStudent); +router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/markDiff', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, markSdcSchoolCollectionStudentAsDifferent); router.delete('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/student/:sdcSchoolCollectionStudentID', passport.authenticate('jwt', {session: false}, undefined), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, deleteSDCSchoolCollectionStudent); router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/students/remove', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, removeSDCSchoolCollectionStudents); diff --git a/frontend/src/components/common/CustomTable.vue b/frontend/src/components/common/CustomTable.vue index 3889bef17..82375801b 100644 --- a/frontend/src/components/common/CustomTable.vue +++ b/frontend/src/components/common/CustomTable.vue @@ -142,6 +142,8 @@ diff --git a/frontend/src/components/common/EditStudent.vue b/frontend/src/components/common/EditStudent.vue index 7fc177c39..97a00e635 100644 --- a/frontend/src/components/common/EditStudent.vue +++ b/frontend/src/components/common/EditStudent.vue @@ -434,7 +434,7 @@ - - - + + + + /> @@ -163,6 +174,7 @@ import {SDC_STEPS_SCHOOL} from '../../../utils/institute/SdcSteps'; import StepOneUploadData from './stepOneUploadData/StepOneUploadData.vue'; import StepTwoViewDataIssues from './stepTwoValidateData/StepTwoViewDataIssues.vue'; +import StepThreeDuplicatesProcessing from './stepThreeSchoolDuplicates/StepThreeDuplicatesProcessing.vue'; import StepThreeVerifyData from './stepThreeVerifyData/StepThreeVerifyData.vue'; import StepFourSchoolDetails from './StepFourSchoolDetails.vue'; import StepFiveSchoolContacts from './StepFiveSchoolContacts.vue'; @@ -172,6 +184,7 @@ export default { name: 'SDCCollectionView', components: { StepFiveSchoolContacts, + StepThreeDuplicatesProcessing, StepFourSchoolDetails, StepThreeVerifyData, StepTwoViewDataIssues, diff --git a/frontend/src/components/sdcCollection/sdcSchoolCollection/stepThreeSchoolDuplicates/StepThreeDuplicatesProcessing.vue b/frontend/src/components/sdcCollection/sdcSchoolCollection/stepThreeSchoolDuplicates/StepThreeDuplicatesProcessing.vue new file mode 100644 index 000000000..cae488307 --- /dev/null +++ b/frontend/src/components/sdcCollection/sdcSchoolCollection/stepThreeSchoolDuplicates/StepThreeDuplicatesProcessing.vue @@ -0,0 +1,385 @@ + + + + + diff --git a/frontend/src/components/sdcCollection/sdcSchoolCollection/stepThreeVerifyData/DetailComponent.vue b/frontend/src/components/sdcCollection/sdcSchoolCollection/stepThreeVerifyData/DetailComponent.vue index 717fe7b8b..d7408931b 100644 --- a/frontend/src/components/sdcCollection/sdcSchoolCollection/stepThreeVerifyData/DetailComponent.vue +++ b/frontend/src/components/sdcCollection/sdcSchoolCollection/stepThreeVerifyData/DetailComponent.vue @@ -153,7 +153,6 @@ import {ApiRoutes} from '../../../../utils/constants'; import {cloneDeep, isEmpty, omitBy} from 'lodash'; import {mapState} from 'pinia'; import {sdcCollectionStore} from '../../../../store/modules/sdcCollection'; -import {enrolledProgram} from '../../../../utils/sdc/enrolledProgram'; import Filters from '../../../common/Filters.vue'; import {setFailureAlert, setSuccessAlert} from '../../../composable/alertComposable'; import ConfirmationDialog from '../../../util/ConfirmationDialog.vue'; @@ -265,7 +264,7 @@ export default { }, loadStudents() { this.isLoading= true; - ApiService.apiAxios.get(`${ApiRoutes.sdc.SDC_SCHOOL_COLLECTION_STUDENT}/${this.$route.params.schoolCollectionID}/paginated`, { + ApiService.apiAxios.get(`${ApiRoutes.sdc.SDC_SCHOOL_COLLECTION_STUDENT}/${this.$route.params.schoolCollectionID}/paginated?tableFormat=true`, { params: { pageNumber: this.pageNumber - 1, pageSize: this.pageSize, @@ -275,7 +274,7 @@ export default { }, } }).then(response => { - this.studentList = response.data.content.map(this.toTableRow); + this.studentList = response.data.content; this.totalElements = response.data.totalElements; }).catch(error => { console.error(error); @@ -287,45 +286,6 @@ export default { toggleFilters() { this.showFilters= !this.showFilters; }, - enrolledProgramMapping(student, enrolledProgramFilter) { - if(!student.enrolledProgramCodes) { - return ''; - } - return student.enrolledProgramCodes - .match(/.{1,2}/g) - .filter(programCode => enrolledProgramFilter.includes(programCode)) - .map(programCode => { - const enrolledProgram = this.enrolledProgramCodesMap.get(programCode); - return enrolledProgram ? `${enrolledProgram.description} (${programCode})` : programCode; - }) - .join(','); - }, - toTableRow(student) { - student.mappedSpedCode = this.specialEducationCodesMap.get(student.specialEducationCategoryCode) !== undefined ? `${this.specialEducationCodesMap.get(student.specialEducationCategoryCode)?.description} (${this.specialEducationCodesMap.get(student.specialEducationCategoryCode)?.specialEducationCategoryCode})` : null; - student.mappedAncestryIndicator = student.nativeAncestryInd === null ? null : this.nativeAncestryInd(student); - student.mappedFrenchEnrolledProgram = this.enrolledProgramMapping(student, enrolledProgram.FRENCH_ENROLLED_PROGRAM_CODES); - student.mappedEllEnrolledProgram = this.enrolledProgramMapping(student, enrolledProgram.ENGLISH_ENROLLED_PROGRAM_CODES); - student.mappedLanguageEnrolledProgram = this.enrolledProgramMapping(student, [...enrolledProgram.ENGLISH_ENROLLED_PROGRAM_CODES, ...enrolledProgram.FRENCH_ENROLLED_PROGRAM_CODES]); - student.careerProgram = this.enrolledProgramMapping(student, enrolledProgram.CAREER_ENROLLED_PROGRAM_CODES); - student.mappedIndigenousEnrolledProgram = this.enrolledProgramMapping(student, enrolledProgram.INDIGENOUS_ENROLLED_PROGRAM_CODES); - student.mappedBandCode = this.bandCodesMap.get(student.bandCode) !== undefined ? `${this.bandCodesMap.get(student.bandCode)?.description} (${this.bandCodesMap.get(student.bandCode)?.bandCode})` : null; - student.careerProgramCode = this.careerProgramCodesMap.get(student.careerProgramCode) !== undefined ? `${this.careerProgramCodesMap.get(student.careerProgramCode)?.description} (${this.careerProgramCodesMap.get(student.careerProgramCode)?.careerProgramCode})` : null; - student.mappedSchoolFunding = this.schoolFundingCodesMap.get(student.schoolFundingCode) !== undefined ? `${this.schoolFundingCodesMap.get(student.schoolFundingCode)?.description} (${this.schoolFundingCodesMap.get(student.schoolFundingCode)?.schoolFundingCode})` : null; - student.indProgramEligible = student.indigenousSupportProgramNonEligReasonCode !== null ? 'No' : 'Yes'; - student.frenchProgramEligible = student.frenchProgramNonEligReasonCode !== null ? 'No' : 'Yes'; - student.ellProgramEligible = student.ellNonEligReasonCode !== null ? 'No' : 'Yes'; - student.careerProgramEligible = student.careerProgramNonEligReasonCode !== null ? 'No' : 'Yes'; - student.spedProgramEligible = student.specialEducationNonEligReasonCode !== null ? 'No' : 'Yes'; - student.yearsInEll = student.sdcStudentEll ? student.sdcStudentEll.yearsInEll : ''; - let noOfCourses = student.numberOfCourses; - if(noOfCourses && noOfCourses.length === 4) { - student.mappedNoOfCourses = (Number.parseInt(noOfCourses) / 100).toFixed(2); - } - return student; - }, - nativeAncestryInd(student) { - return student.nativeAncestryInd === 'Y' ? 'Yes' : 'No'; - }, reload(value) { if(value?.pageSize) { this.pageSize = value?.pageSize; diff --git a/frontend/src/utils/format.js b/frontend/src/utils/format.js index eadf2d56f..ceb637dea 100644 --- a/frontend/src/utils/format.js +++ b/frontend/src/utils/format.js @@ -22,6 +22,27 @@ export function formatDateTime(datetime, from='uuuuMMdd', to='uuuu/MM/dd', hasTi return result; } +export function displayName(first, middle, last) { + let name = ''; + if (last) { + name += last; + } + + if (first && last) { + name += `, ${first}` ; + } else if (first) { + name += first; + } + + if ((first && middle) || (last && middle)) { + name += ` (${middle})`; + } else if (middle) { + name += `(${middle})`; + } + + return name; +} + export function formatPhoneNumber(phoneNumberString) { let cleaned = ('' + phoneNumberString).replace(/\D/g, ''); let match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/); diff --git a/frontend/src/utils/institute/SdcSteps.js b/frontend/src/utils/institute/SdcSteps.js index 526db2f32..af26401b4 100644 --- a/frontend/src/utils/institute/SdcSteps.js +++ b/frontend/src/utils/institute/SdcSteps.js @@ -18,26 +18,32 @@ export const SDC_STEPS_SCHOOL = Object.freeze([ }, { id: 'step-3', - title: 'Edit/Verify Data Issues', + title: 'Review & Fix Duplicates', step: 3, - sdcSchoolCollectionStatusCode: 'REVIEWED' + sdcSchoolCollectionStatusCode: 'SCH_DUPLI' }, { id: 'step-4', - title: 'Verify School Details (1601)', + title: 'Edit/Verify Data Issues', step: 4, - sdcSchoolCollectionStatusCode: 'SCH_D_VRFD' + sdcSchoolCollectionStatusCode: 'REVIEWED' }, { id: 'step-5', - title: 'Verify School Contacts (1601)', + title: 'Verify School Details (1601)', step: 5, - sdcSchoolCollectionStatusCode: 'SCH_C_VRFD' + sdcSchoolCollectionStatusCode: 'SCH_D_VRFD' }, { id: 'step-6', - title: 'Submit Data', + title: 'Verify School Contacts (1601)', step: 6, + sdcSchoolCollectionStatusCode: 'SCH_C_VRFD' + }, + { + id: 'step-7', + title: 'Submit Data', + step: 7, sdcSchoolCollectionStatusCode: 'SUBMITTED' }, ]); diff --git a/frontend/src/utils/sdc/TableConfiguration.js b/frontend/src/utils/sdc/TableConfiguration.js index 81765cc04..7612dc629 100644 --- a/frontend/src/utils/sdc/TableConfiguration.js +++ b/frontend/src/utils/sdc/TableConfiguration.js @@ -946,3 +946,21 @@ export const REFUGEE = Object.freeze( } } ); + +export const SCH_DUPLICATES = Object.freeze( + { + tableHeaders: [ + { title: 'FTE', key: 'fte', align: 'start' }, + { title: 'PEN', key: 'studentPen', subHeader: { title: 'Local ID', key: 'localID' } }, + { title: 'Legal Names', key: 'legalName', subHeader: { title: 'Usual Names', key: 'usualName' } }, + { title: 'Adult', key: 'isAdult', subHeader: { title: 'Grad', key: 'isGraduated' } }, + { title: 'Grade', key: 'enrolledGradeCode', subHeader: { title: 'Funding Code', key: 'mappedSchoolFunding' } }, + { title: 'Courses For Grad', key: 'mappedNoOfCourses', subHeader: { title: 'Support Blocks', key: 'supportBlocks' } }, + { title: 'Language Program', key: 'mappedLanguageEnrolledProgram', subHeader: { title: 'Years in ELL', key: 'yearsInEll' } }, + { title: 'Career Program', key: 'careerProgram', subHeader: { title: 'Career Code', key: 'careerProgramCode' } }, + { title: 'Indigenous Ancestry', key: 'mappedAncestryIndicator', subHeader: { title: 'Band Code', key: 'mappedBandCode' } }, + { title: 'Indigenous Support Program', key: 'mappedIndigenousEnrolledProgram', subHeader: { title: 'Special Education Category', key: 'mappedSpedCode' } }, + { title: ' ', key: 'action' }, + ], + } +);