diff --git a/backend/src/components/institute/institute.js b/backend/src/components/institute/institute.js index 3252bc435..0b921bd6a 100644 --- a/backend/src/components/institute/institute.js +++ b/backend/src/components/institute/institute.js @@ -863,6 +863,105 @@ async function getSchoolByID(req, res) { } } +async function getSchoolByMincode(req, res) { + const token = getBackendToken(req); + try { + let school = cacheService.getSchoolJSONByMincode(req.params.mincode); + const url = `${config.get('server:institute:rootURL')}/school/${school.schoolID}`; + const data = await getData(token, url); + return res.status(200).json(data); + } catch (e) { + logApiError(e, 'getSchoolByMincode', 'Error occurred while attempting to GET school entity by mincode.'); + return errorResponse(res); + } +} + + +async function getStudentRegistrationContacts(req, res) { + const token = getBackendToken(req); + let contactsList = []; + try { + const schoolContactURL = `${config.get('server:institute:instituteSchoolURL')}/contact/paginated?pageNumber=0&pageSize=10000&searchCriteriaList=[{"searchCriteriaList":[{"key":"schoolContactTypeCode","operation":"eq","value":"STUDREGIS","valueType":"STRING","condition":"AND"}]}]`; + const districtContactURL = `${config.get('server:institute:instituteDistrictURL')}/contact/paginated?pageNumber=0&pageSize=10000&searchCriteriaList=[{"searchCriteriaList":[{"key":"districtContactTypeCode","operation":"eq","value":"STUDREGIS","valueType":"STRING","condition":"AND"}]}]`; + Promise.all([ + getData(token, schoolContactURL), + getData(token, districtContactURL), + ]) + .then(async ([schoolContactResponse, districtContactResponse]) => { + if (schoolContactResponse && districtContactResponse) { + schoolContactResponse.content.forEach((element) => { + let school = cacheService.getSchoolBySchoolID(element.schoolId); + let schoolRegistrationContact = {}; + schoolRegistrationContact.name = (element.firstName ? element.firstName + ' ' + element.lastName : element.lastName).trim(); + schoolRegistrationContact.email = element.email; + schoolRegistrationContact.instituteName = school.schoolName; + schoolRegistrationContact.instituteIdentifier = school.mincode; + schoolRegistrationContact.instituteGUID = school.schoolID; + schoolRegistrationContact.instituteType = 'SCHOOL'; + contactsList.push(schoolRegistrationContact); + }); + districtContactResponse.content.forEach((element) => { + let district = cacheService.getDistrictJSONByDistrictId(element.districtId); + let schoolRegistrationContact = {}; + schoolRegistrationContact.name = (element.firstName ? element.firstName + ' ' + element.lastName : element.lastName).trim(); + schoolRegistrationContact.email = element.email; + schoolRegistrationContact.instituteName = district.name; + schoolRegistrationContact.instituteGUID = district.districtId; + schoolRegistrationContact.instituteIdentifier = district.districtNumber; + schoolRegistrationContact.instituteType = 'DISTRICT'; + contactsList.push(schoolRegistrationContact); + }); + return res.status(200).json(contactsList); + } + }); + } catch (e) { + logApiError(e, 'getStudentRegistrationContacts', 'Error occurred while attempting to GET student registration contacts.'); + return errorResponse(res); + } +} + +async function getStudentRegistrationContactByMincode(req, res) { + const accessToken = getBackendToken(req); + try { + let school = cacheService.getSchoolJSONByMincode(req.params.mincode); + let searchCriteriaList = []; + searchCriteriaList.push({key: 'schoolContactTypeCode', operation: FILTER_OPERATION.EQUAL, value: 'STUDREGIS', valueType: VALUE_TYPE.STRING, condition: CONDITION.AND}); + searchCriteriaList.push({key: 'schoolID', operation: FILTER_OPERATION.EQUAL, value: school.schoolID, valueType: VALUE_TYPE.UUID, condition: CONDITION.AND}); + + const schoolSearchCriteria = [{ + condition: null, + searchCriteriaList: searchCriteriaList, + }]; + + const schoolSearchParam = { + params: { + pageNumber: req.query.pageNumber, + pageSize: req.query.pageSize, + sort: req.query.sort, + searchCriteriaList: JSON.stringify(schoolSearchCriteria) + } + }; + + let response = await getData(accessToken, config.get('server:institute:rootURL') + '/school/contact/paginated', schoolSearchParam); + let schoolRegistrationContact = {}; + if(response?.content && response.content[0]){ + let firstStudRegContact = response.content[0]; + schoolRegistrationContact.name = (firstStudRegContact.firstName ? firstStudRegContact.firstName + ' ' + firstStudRegContact.lastName : firstStudRegContact.lastName).trim(); + schoolRegistrationContact.email = firstStudRegContact.email; + schoolRegistrationContact.instituteName = school.schoolName; + schoolRegistrationContact.instituteIdentifier = school.mincode; + schoolRegistrationContact.instituteGUID = school.schoolID; + schoolRegistrationContact.instituteType = 'SCHOOL'; + } + + return res.status(200).json(schoolRegistrationContact); + } catch (e) { + logApiError(e, 'getStudentRegistrationContactByMincode', 'Error occurred while attempting to GET student registration contact entity.'); + return errorResponse(res); + } +} + + async function updateSchool(req, res) { try { const token = getBackendToken(req); @@ -1356,5 +1455,8 @@ module.exports = { addDistrictContact, deleteDistrictContact, getSchoolHistoryPaginated, - moveSchool + moveSchool, + getStudentRegistrationContacts, + getStudentRegistrationContactByMincode, + getSchoolByMincode }; diff --git a/backend/src/components/school-api-cache-service.js b/backend/src/components/school-api-cache-service.js deleted file mode 100644 index 3995c6212..000000000 --- a/backend/src/components/school-api-cache-service.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; -const config = require('../config/index'); -const log = require('../components/logger'); -const {getApiCredentials} = require('../components/auth'); -const {getData} = require('../components/utils'); -const retry = require('async-retry'); - -let mincodeSchoolMap = new Map(); -let mincodeSchools = []; - -const schoolApiCacheService = { - - async loadAllSchoolsToMap() { - log.debug('loading all schools during start up'); - await retry(async () => { - // if anything throws, we retry - const data = await getApiCredentials(); // get the tokens first to make api calls. - const schools = await getData(data.accessToken, `${config.get('server:schoolAPIURL')}/schools`); - mincodeSchools = []; // reset the value. - mincodeSchoolMap.clear();// reset the value. - if (schools && schools.length > 0) { - for (const school of schools) { - const mincodeSchool = { - mincode: `${school.distNo}${school.schlNo}`, - schoolName: school.schoolName, - effectiveDate: school.dateOpened, - expiryDate: school.dateClosed, - }; - mincodeSchoolMap.set(`${school.distNo}${school.schlNo}`, mincodeSchool); - mincodeSchools.push(mincodeSchool); - } - } - log.info(`loaded ${mincodeSchoolMap.size} schools to school-api-cache.`); - }, { - retries: 50 - }); - - }, - getAllSchoolsJSON() { - return mincodeSchools; - }, - getSchoolNameJSONByMincode(mincode) { - return mincodeSchoolMap.get(mincode); - }, - -}; - -module.exports = schoolApiCacheService; diff --git a/backend/src/components/school.js b/backend/src/components/school.js deleted file mode 100644 index dbd738936..000000000 --- a/backend/src/components/school.js +++ /dev/null @@ -1,107 +0,0 @@ -'use strict'; -const config = require('../config/index'); -const {getBackendToken, getData, putData, getUser, logApiError, errorResponse} = require('./utils'); -const HttpStatus = require('http-status-codes'); -const schoolApiCacheService = require('./school-api-cache-service'); -const lodash = require('lodash'); -const retry = require('async-retry'); -const {LocalDate, DateTimeFormatter} = require('@js-joda/core'); - -async function getSchoolByMincode(req, res) { - try { - if(req.query?.mincode){ - const data = schoolApiCacheService.getSchoolNameJSONByMincode(req.query.mincode); - if(data){ - return res.status(200).json(data); - } - }else { - let data = schoolApiCacheService.getAllSchoolsJSON(); - if(data){ - data = data.filter(school => { - return isSchoolExpired(school); - }); - return res.status(200).json(data); - }else { - return res.status(200).json([]); - } - } - return res.status(200).json(); - } catch (e) { - logApiError(e, 'getSchoolByMincode', 'Error occurred while attempting to GET school entity.'); - return errorResponse(res); - } -} - -async function getPenCoordinatorByMincode(req, res) { - const token = getBackendToken(req); - try { - const url = `${config.get('server:schoolAPIURL')}/schools/${req.params.mincode}/pen-coordinator`; - const data = await getData(token, url); - return res.status(200).json(data); - } catch (e) { - logApiError(e, 'getPenCoordinatorByMincode', 'Error occurred while attempting to GET pen coordinator entity.'); - return errorResponse(res); - } -} - -async function updatePenCoordinatorByMincode(req, res) { - try { - const token = getBackendToken(req); - const url = `${config.get('server:schoolAPIURL')}/schools/${req.params.mincode}/pen-coordinator`; - - await retry(async () => { - const result = await putData(token, url, req.body, getUser(req).idir_username); - return res.status(HttpStatus.OK).json(result); - }, - { - retries: 3 - }); - } catch (e) { - logApiError(e, 'updatePenCoordinatorByMincode', 'Error occurred while attempting to update a PEN Coordinator.'); - return errorResponse(res); - } - -} - -async function getPenCoordinators(req, res) { - const token = getBackendToken(req); - try { - const url = `${config.get('server:schoolAPIURL')}/schools/pen-coordinator`; - const data = await getData(token, url); - const coords = lodash.sortBy(data, ['mincode', 'penCoordinatorName']); - const filteredCords = coords.filter(coord=> { - const school = schoolApiCacheService.getSchoolNameJSONByMincode(coord.mincode); - if(!school){ - return true; - } - return isSchoolExpired(school); - }).map(coord=> { - coord.schoolName = schoolApiCacheService.getSchoolNameJSONByMincode(coord.mincode)?.schoolName; - if(!coord.schoolName){ - coord.schoolName = 'District'; - } - return coord; - }); - return res.status(200).json(filteredCords); - } catch (e) { - logApiError(e, 'getPenCoordinators', 'Error occurred while attempting to GET pen coordinator entities.'); - return errorResponse(res); - } -} - -function isSchoolExpired(school) { - if(school === null){ - return false; - } - - const openedDate = school?.effectiveDate; - const closedDate = school?.expiryDate; - return !(!school || !school.schoolName || !openedDate || LocalDate.parse(openedDate, DateTimeFormatter.ISO_LOCAL_DATE_TIME).isAfter(LocalDate.now()) || (closedDate && LocalDate.parse(closedDate, DateTimeFormatter.ISO_LOCAL_DATE_TIME).isBefore(LocalDate.now()))); -} - -module.exports = { - getSchoolByMincode, - getPenCoordinatorByMincode, - updatePenCoordinatorByMincode, - getPenCoordinators, -}; diff --git a/backend/src/routes/institute.js b/backend/src/routes/institute.js index 8aa97946e..25aae081a 100644 --- a/backend/src/routes/institute.js +++ b/backend/src/routes/institute.js @@ -4,7 +4,9 @@ const router = express.Router(); const { getDistricts, getSchools, getSchoolsPaginated, getAuthoritiesPaginated, getAuthorityByID, getSchoolByID, getDistrictByDistrictID, addNewSchoolNote, updateSchoolNote, deleteSchoolNote, updateSchoolContact, updateAuthority, addAuthorityContact, updateAuthorityContact, deleteAuthorityContact, addNewAuthorityNote, updateAuthorityNote, deleteAuthorityNote, updateSchool, addSchool, addSchoolContact, deleteSchoolContact, updateDistrict, updateDistrictContact, deleteDistrictContact, addAuthority, - addDistrictContact, addNewDistrictNote, updateDistrictNote, deleteDistrictNote, moveSchool, getSchoolHistoryPaginated + addDistrictContact, addNewDistrictNote, updateDistrictNote, deleteDistrictNote, moveSchool, getSchoolHistoryPaginated, + getStudentRegistrationContacts, + getStudentRegistrationContactByMincode, getSchoolByMincode } = require('../components/institute/institute'); const utils = require('../components/utils'); const auth = require('../components/auth'); @@ -12,12 +14,17 @@ const extendSession = utils.extendSession(); const {getCodes} = require('../components/utils'); const {CACHE_KEYS} = require('../util/constants'); + router.get('/district', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getDistricts); router.get('/district/:districtId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getDistrictByDistrictID); router.put('/district/:districtId', passport.authenticate('jwt', {session: false}, undefined), auth.isValidDistrictAdmin, extendSession, updateDistrict); +router.get('/studentRegistrationContacts', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getStudentRegistrationContacts); + +router.get('/studentRegistrationContact/:mincode', passport.authenticate('jwt', {session: false}, undefined), extendSession, getStudentRegistrationContactByMincode); + router.put('/district/contact/:contactId', passport.authenticate('jwt', {session: false}, undefined), auth.isValidDistrictAdmin, extendSession, updateDistrictContact); router.delete('/district/contact/:districtId/:contactId', passport.authenticate('jwt', {session: false}, undefined), auth.isValidDistrictAdmin, extendSession, deleteDistrictContact); @@ -56,6 +63,8 @@ router.post('/school/contact', passport.authenticate('jwt', {session: false}, un router.get('/school/:id', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getSchoolByID); +router.get('/school/mincode/:mincode', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getSchoolByMincode); + router.put('/school/:id', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, updateSchool); router.get('/schoolsPaginated', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getSchoolsPaginated); diff --git a/backend/src/routes/schools.js b/backend/src/routes/schools.js index 1daeb1737..adb8452ad 100644 --- a/backend/src/routes/schools.js +++ b/backend/src/routes/schools.js @@ -1,33 +1,8 @@ const passport = require('passport'); const express = require('express'); const router = express.Router(); -const { getSchoolByMincode, getPenCoordinatorByMincode, getPenCoordinators, updatePenCoordinatorByMincode } = require('../components/school'); const utils = require('../components/utils'); -const auth = require('../components/auth'); const extendSession = utils.extendSession(); -const roles = require('../components/roles'); - -const isValidUiTokenWithEditRoles = auth.isValidUiTokenWithRoles('StaffAdministration & NominalRoll', [roles.Admin.StaffAdministration, roles.Admin.NominalRoll, roles.Admin.EDX]); - -/* - * Get a school entity by mincode - */ -router.get('/', passport.authenticate('jwt', {session: false}, undefined), extendSession, getSchoolByMincode); - -/* - * Get a pen coordinator entity by mincode - */ -router.get('/:mincode/penCoordinator', passport.authenticate('jwt', {session: false}, undefined), extendSession, getPenCoordinatorByMincode); - -/* - * Update a pen coordinator entity by mincode - */ -router.put('/:mincode/penCoordinator', passport.authenticate('jwt', {session: false}, undefined), isValidUiTokenWithEditRoles, extendSession, updatePenCoordinatorByMincode); - -/* - * Get all pen coordinator entities - */ -router.get('/penCoordinators', passport.authenticate('jwt', {session: false}, undefined), extendSession, getPenCoordinators); router.get('/fedProvSchoolCodes', passport.authenticate('jwt', {session: false}, undefined), extendSession, utils.getCodes('server:schoolAPIURL', 'fedProvSchoolCodes', '/schools/federal-province-codes', false)); diff --git a/backend/src/schedulers/school-api-cache-service-scheduler.js b/backend/src/schedulers/school-api-cache-service-scheduler.js deleted file mode 100644 index af5ead6ea..000000000 --- a/backend/src/schedulers/school-api-cache-service-scheduler.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; -const CronJob = require('cron').CronJob; -const log = require('../components/logger'); -const schoolApiCacheService = require('../components/school-api-cache-service'); - -try { - // reload the cache every midnight at 12.15 AM as the api reloads cache at 12 AM. - const reloadCache = new CronJob('0 15 0 * * *', async () => { - log.debug('Starting reload cache'); - try { - await schoolApiCacheService.loadAllSchoolsToMap(); - } catch (e) { - log.error(e); - } - }); - reloadCache.start(); -} catch (e) { - log.error(e); -} - diff --git a/backend/src/server.js b/backend/src/server.js index e20a1e378..97ddf1ba4 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -29,7 +29,6 @@ const server = http.createServer(app); const WS = require('./socket/web-socket'); const NATS = require('./messaging/message-pub-sub'); const cacheService = require('./components/cache-service'); -const schoolApiCacheServicce = require('./components/school-api-cache-service'); const constants = require('./util/constants'); cacheService.loadAllSchoolsToMap().then(() => { @@ -125,11 +124,6 @@ cacheService.loadAllDocumentTypeCodesToMap().then(() => { }).catch((e) => { log.error('Error loading document type codes during boot .', e); }); -schoolApiCacheServicce.loadAllSchoolsToMap().then(() => { - log.info('Loaded school data to memory school-api-cache'); -}).catch((e) => { - log.error('Error loading schools during boot school-api-cache .', e); -}); WS.init(app, server); /** diff --git a/backend/tests/unit/components/school.spec.js b/backend/tests/unit/components/school.spec.js deleted file mode 100644 index 82142c079..000000000 --- a/backend/tests/unit/components/school.spec.js +++ /dev/null @@ -1,60 +0,0 @@ -const HttpStatus = require('http-status-codes'); -jest.mock('../../../src/components/utils', () => { - const originalModule = jest.requireActual('../../../src/components/utils'); - return { - __esModule: true, // Use it when dealing with esModules - ...originalModule, - getBackendToken: jest.fn(), - getData: jest.fn(), - putData: jest.fn(), - postData: jest.fn(), - getUser: jest.fn().mockReturnValue({idir_username: 'User'}) - }; -}); -jest.mock('../../../src/components/school-api-cache-service'); -const cacheService = require('../../../src/components/school-api-cache-service'); -const { mockRequest, mockResponse } = require('../helpers'); -const utils = require('../../../src/components/utils'); -const { ApiError } = require('../../../src/components/error'); -const school = require('../../../src/components/school'); -const {LocalDateTime} = require('@js-joda/core'); - - -describe('getPenCoordinators', () => { - let req; - let res; - const coords = [ - {mincode: '00200001', penCoordinatorName: 'coord A'}, - {mincode: '00100001', penCoordinatorName: 'coord B'}, - ]; - - const formattedResponse = [ - {mincode: '00100001', penCoordinatorName: 'coord B', schoolName: 'School A'}, - {mincode: '00200001', penCoordinatorName: 'coord A', schoolName: 'School A'}, - ]; - - - beforeEach(() => { - utils.getBackendToken.mockReturnValue('token'); - req = mockRequest(); - res = mockResponse(); - }); - afterEach(() => { - jest.clearAllMocks(); - }); - - it('should return all coords correctly', async () => { - utils.getData.mockResolvedValue(coords); - cacheService.getSchoolNameJSONByMincode.mockReturnValue({schoolName: 'School A', effectiveDate: LocalDateTime.now().minusMinutes(2).toJSON()}); - await school.getPenCoordinators(req,res); - expect(res.status).toHaveBeenCalledWith(HttpStatus.OK); - expect(res.json).toHaveBeenCalledWith(formattedResponse); - }); - it('should return 500 if getData fails', async () => { - utils.getData.mockRejectedValue(new ApiError()); - - await school.getPenCoordinators(req,res); - expect(res.status).toHaveBeenCalledWith(HttpStatus.INTERNAL_SERVER_ERROR); - expect(res.json).toHaveBeenCalledWith({code: HttpStatus.INTERNAL_SERVER_ERROR, message: 'INTERNAL SERVER ERROR'}); - }); -}); diff --git a/frontend/src/common/apiService.js b/frontend/src/common/apiService.js index 8e86ce15e..70b1da2b8 100644 --- a/frontend/src/common/apiService.js +++ b/frontend/src/common/apiService.js @@ -82,7 +82,7 @@ export default { getPrbValidationFieldCodes: getCodes(Routes.penRequestBatch.PRB_VALIDATION_FIELD_CODE_URL), getPrbValidationIssueSeverityCodes: getCodes(Routes.penRequestBatch.PRB_VALIDATION_ISSUE_SEVERITY_CODE_URL), getPrbValidationIssueTypeCodes: getCodes(Routes.penRequestBatch.PRB_VALIDATION_ISSUE_TYPE_CODE_URL), - getMincodeSchoolNames: getCodes(Routes.cache.SCHOOL_DATA_URL), + getAllSchools: getCodes(Routes.cache.SCHOOL_DATA_URL), getActiveSchools: getCodes(`${Routes.cache.SCHOOL_DATA_URL}?active=true`), getActiveDistricts: getCodes(`${Routes.cache.DISTRICT_DATA_URL}?active=true`), getSchools:getCodes(Routes.cache.SCHOOL_DATA_URL), @@ -107,7 +107,6 @@ export default { getInstituteGradeCodes: getCodes(Routes.cache.GRADE_TYPES_URL), getInstituteProvinceCodes: getCodes(Routes.cache.PROVINCES_URL), getInstituteCountryCodes: getCodes(Routes.cache.COUNTRIES_URL), - getSchoolApiMincodeSchoolNames: getCodes(Routes.SCHOOL_DATA_URL), getSchoolCategoryFacilityTypes: getCodes(Routes.cache.SCHOOL_CATEGORY_FACILITY_TYPE_URL), getAllActiveFacilityTypeCodes: getCodes(`${Routes.cache.FACILITY_TYPES_URL}?active=true`), getAllActiveSchoolCategoryTypeCodes: getCodes(`${Routes.cache.SCHOOL_CATEGORY_TYPES_URL}?active=true`), diff --git a/frontend/src/components/Home.vue b/frontend/src/components/Home.vue index e71c649c8..2add190b7 100644 --- a/frontend/src/components/Home.vue +++ b/frontend/src/components/Home.vue @@ -408,7 +408,7 @@ export default { } }, computed: { - ...mapState(appStore, ['schoolApiMincodeSchoolNames', 'schoolApiDistrictCodes']), + ...mapState(appStore, ['mincodeSchoolNames', 'districtCodes']), ...mapState(authStore, ['VIEW_GMP_REQUESTS_ROLE', 'VIEW_UMP_REQUESTS_ROLE', 'ADVANCED_SEARCH_ROLE', 'VIEW_EDIT_PEN_REQUEST_BATCH_FILES_ROLE', 'HAS_STATS_ROLE', 'STUDENT_ANALYTICS_STUDENT_PROFILE', 'STUDENT_ANALYTICS_BATCH', 'EXCHANGE_ROLE', 'PEN_TEAM_ROLE']), requestTypes() { return REQUEST_TYPES; @@ -461,9 +461,9 @@ export default { isValidDistrictOrMincode(v) { if (isValidMincode(v) && (v.length === 3 || v.length === 8)) { if (v.length === 3) { - return this.schoolApiDistrictCodes.size === 0 || this.schoolApiDistrictCodes.has(v); + return this.districtCodes.size === 0 || this.districtCodes.has(v); } else { - return this.schoolApiMincodeSchoolNames.size === 0 || this.schoolApiMincodeSchoolNames.has(v); + return this.mincodeSchoolNames.size === 0 || this.mincodeSchoolNames.has(v); } } return false; diff --git a/frontend/src/components/institute/authority/AuthorityContact.vue b/frontend/src/components/institute/authority/AuthorityContact.vue index f0f5c3972..34ed86237 100644 --- a/frontend/src/components/institute/authority/AuthorityContact.vue +++ b/frontend/src/components/institute/authority/AuthorityContact.vue @@ -70,7 +70,7 @@ class="pt-1" >

mdi-alert Missing contact details

diff --git a/frontend/src/components/institute/common/SchoolContact.vue b/frontend/src/components/institute/common/SchoolContact.vue index bb28de091..34590383f 100644 --- a/frontend/src/components/institute/common/SchoolContact.vue +++ b/frontend/src/components/institute/common/SchoolContact.vue @@ -82,7 +82,7 @@ class="pt-1" >

mdi-alert Missing contact details

diff --git a/frontend/src/components/institute/district/DistrictContact.vue b/frontend/src/components/institute/district/DistrictContact.vue index a9f91bd4b..eea5ff416 100644 --- a/frontend/src/components/institute/district/DistrictContact.vue +++ b/frontend/src/components/institute/district/DistrictContact.vue @@ -79,7 +79,7 @@ class="pt-1" >

mdi-alert Missing contact details

diff --git a/frontend/src/components/nominal-roll/MapSchoolCodeModal.vue b/frontend/src/components/nominal-roll/MapSchoolCodeModal.vue index 535a72336..3777470e5 100644 --- a/frontend/src/components/nominal-roll/MapSchoolCodeModal.vue +++ b/frontend/src/components/nominal-roll/MapSchoolCodeModal.vue @@ -162,10 +162,10 @@ export default { }; }, computed: { - ...mapState(appStore, ['schoolApiMincodeSchoolNames']), + ...mapState(appStore, ['mincodeSchoolNames']), ...mapState(nominalRollStore, ['fedProvSchoolCodes']), schools() { - return _.sortBy(Array.from(this.schoolApiMincodeSchoolNames.entries()).map(school => ({ + return _.sortBy(Array.from(this.mincodeSchoolNames.entries()).map(school => ({ text: `${school[0]} - ${school[1]}`, value: school[0] })), ['value']); diff --git a/frontend/src/components/nominal-roll/NomRollStudentSearchResults.vue b/frontend/src/components/nominal-roll/NomRollStudentSearchResults.vue index 4b3081504..117760fec 100644 --- a/frontend/src/components/nominal-roll/NomRollStudentSearchResults.vue +++ b/frontend/src/components/nominal-roll/NomRollStudentSearchResults.vue @@ -205,7 +205,7 @@ density="compact" name="1" label="School District" - :items="schoolApiDistrictCodesObjectSorted" + :items="districtCodesObjectSorted" :rules="[!validationErrors['School District'] || validationErrors['School District']]" /> @@ -252,7 +252,7 @@ density="compact" name="3" label="School Name" - :items="schoolApiMincodeSchoolNamesObjectSorted" + :items="mincodeSchoolNamesObjectSorted" :rules="[!validationErrors['School Name'] || validationErrors['School Name']]" /> @@ -500,7 +500,7 @@ export default { computed: { ...mapState(nominalRollStudentSearchStore, ['nomRollStudentSearchResponse', 'nomRollStudentSearchCriteria', 'currentNomRollStudentSearchParams']), ...mapState(studentStore, ['genders', 'gradeCodeObjects']), - ...mapState(appStore, ['schoolApiMincodeSchoolNames', 'schoolApiDistrictCodes', 'schoolApiMincodeSchoolNamesObjectSorted', 'schoolApiDistrictCodesObjectSorted']), + ...mapState(appStore, ['mincodeSchoolNamesObjectSorted', 'districtCodesObjectSorted']), ...mapState(authStore, ['EDIT_NOMINAL_ROLL_ROLE', 'NOMINAL_ROLL_READ_ONLY_ROLE']), ...mapState(nominalRollStore, ['fedProvSchoolCodes']), ...mapState(notificationsStore, ['notification']), @@ -563,7 +563,7 @@ export default { return (format && column) ? format(column) : (column || ' '); }, getSchoolName(request) { - return appStore().schoolApiMincodeSchoolNames.get(request?.mincode?.replace(' ', '')); + return appStore().mincodeSchoolNames.get(request?.mincode?.replace(' ', '')); }, hasNoEditRoleAccess() { return this.EDIT_NOMINAL_ROLL_ROLE === false || this.hasReadOnlyRoleAccess(); diff --git a/frontend/src/components/penreg/coordinator/PenCoordinatorsDisplay.vue b/frontend/src/components/penreg/coordinator/PenCoordinatorsDisplay.vue deleted file mode 100644 index 37abe9c4a..000000000 --- a/frontend/src/components/penreg/coordinator/PenCoordinatorsDisplay.vue +++ /dev/null @@ -1,381 +0,0 @@ - - - - - diff --git a/frontend/src/components/penreg/penrequest-batch/PenRequestBatchDisplay.vue b/frontend/src/components/penreg/penrequest-batch/PenRequestBatchDisplay.vue index 116b2e927..0178dfef9 100644 --- a/frontend/src/components/penreg/penrequest-batch/PenRequestBatchDisplay.vue +++ b/frontend/src/components/penreg/penrequest-batch/PenRequestBatchDisplay.vue @@ -244,7 +244,7 @@ export default { }, computed: { ...mapState(penRequestBatchStore, ['selectedFiles', 'prbStudentStatusFilters', 'currentBatchFileSearchParams']), - ...mapState(appStore, ['schoolApiMincodeSchoolNames']), + ...mapState(appStore, ['mincodeSchoolNames']), selectedSchoolGroup: { get() { return penRequestBatchStore().selectedSchoolGroup; @@ -487,7 +487,7 @@ export default { formatArchivePayload(file) { return { penRequestBatchID: file.penRequestBatchID, - schoolName: this.schoolApiMincodeSchoolNames.get(file?.mincode?.replace(' ', '')) + schoolName: this.mincodeSchoolNames.get(file?.mincode?.replace(' ', '')) }; }, setSagaErrorMessage(error) { diff --git a/frontend/src/components/penreg/penrequest-batch/PenRequestBatchHistoryModal.vue b/frontend/src/components/penreg/penrequest-batch/PenRequestBatchHistoryModal.vue index ae924307a..e63ee3b26 100644 --- a/frontend/src/components/penreg/penrequest-batch/PenRequestBatchHistoryModal.vue +++ b/frontend/src/components/penreg/penrequest-batch/PenRequestBatchHistoryModal.vue @@ -16,6 +16,7 @@ v-for="(item, i) in fileItems" :key="item.name + i" :name="item.name" + label-span="2" :label="item.label" :value="item.value" :loading="loadingPenCoord && item.type === 'coord'" @@ -154,7 +155,7 @@ export default { }, {title: '', text: '', value: '', sortable: false}, ], - penCoordinator: {}, + studentRegistrationContact: {}, }; }, computed: { @@ -163,8 +164,8 @@ export default { return [ {name: 'district', label: this.districtFieldLabel, value: this.districtName}, {name: 'school', label: this.schoolFieldLabel, value: this.batchFile.schoolName}, - {name: 'coord', label: 'PEN Coord:', value: this.penCoordinator.penCoordinatorName, type: 'coord'}, - {name: 'email', label: 'Email:', value: this.penCoordinator.penCoordinatorEmail, type: 'coord'}, + {name: 'coord', label: 'Student Registration Contact:', value: this.studentRegistrationContact.name, type: 'coord'}, + {name: 'email', label: 'Email:', value: this.studentRegistrationContact.email, type: 'coord'}, {name: 'breakLine', label: '', value: ''}, {name: 'fileName', label: 'File Name:', value: this.batchFile.fileName}, {name: 'submission', label: 'Submission #:', value: this.batchFile.submissionNumber}, @@ -220,7 +221,7 @@ export default { }, created() { this.modalOpen = this.value; - this.loadPenCoord(); + this.loadStudentRegistrationContact(); this.loadPenWebBlobs(); }, methods: { @@ -245,13 +246,13 @@ export default { }) .finally(() => (this.loadingTable = false)); }, - loadPenCoord() { + loadStudentRegistrationContact() { this.loadingPenCoord = true; ApiService.apiAxios - .get(`${Routes.SCHOOL_DATA_URL}/${this.batchFile.mincode}/penCoordinator`) + .get(`${Routes.institute.STUDENT_REGISTRATION_CONTACT}/${this.batchFile.mincode}`) .then(response => { if (response.data) { - this.penCoordinator = response.data; + this.studentRegistrationContact = response.data; } }) .catch(error => { diff --git a/frontend/src/components/penreg/penrequest-batch/PrbStudentSearchResults.vue b/frontend/src/components/penreg/penrequest-batch/PrbStudentSearchResults.vue index 220be591d..2817dd3a0 100644 --- a/frontend/src/components/penreg/penrequest-batch/PrbStudentSearchResults.vue +++ b/frontend/src/components/penreg/penrequest-batch/PrbStudentSearchResults.vue @@ -306,7 +306,7 @@ export default { ...mapActions(penRequestBatchStudentSearchStore, ['setPageNumber', 'setSelectedRecords', 'setPrbStudentSearchResponse']), ...mapActions(navigationStore, ['setSelectedIDs', 'setArchived']), getSchoolName(request) { - return appStore().schoolApiMincodeSchoolNames.get(request?.mincode?.replace(' ','')); + return appStore().mincodeSchoolNames.get(request?.mincode?.replace(' ','')); }, clickViewSelected() { if(this.selectedRecords?.length > 0) { diff --git a/frontend/src/components/penreg/student-registration/StudentRegistrationContactsDisplay.vue b/frontend/src/components/penreg/student-registration/StudentRegistrationContactsDisplay.vue new file mode 100644 index 000000000..70500121c --- /dev/null +++ b/frontend/src/components/penreg/student-registration/StudentRegistrationContactsDisplay.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/frontend/src/components/penreg/student/StudentAuditHistoryDetailCard.vue b/frontend/src/components/penreg/student/StudentAuditHistoryDetailCard.vue index 1fa94face..bb29f4eca 100644 --- a/frontend/src/components/penreg/student/StudentAuditHistoryDetailCard.vue +++ b/frontend/src/components/penreg/student/StudentAuditHistoryDetailCard.vue @@ -320,7 +320,7 @@ export default { return this.studentHistoryDetail.demogCode ? this.demogCodeObjects.filter(it => (it.demogCode === this.studentHistoryDetail.demogCode))[0].label : ''; }, getSchoolName(mincode) { - return appStore().schoolApiMincodeSchoolNames.get(mincode?.replace(' ', '')); + return appStore().mincodeSchoolNames.get(mincode?.replace(' ', '')); }, prefixFieldName(fieldName) { return this.idPrefix + fieldName.charAt(0).toUpperCase() + fieldName.slice(1); diff --git a/frontend/src/components/util/NavBar.vue b/frontend/src/components/util/NavBar.vue index c802d74ea..8c85d7444 100644 --- a/frontend/src/components/util/NavBar.vue +++ b/frontend/src/components/util/NavBar.vue @@ -216,7 +216,7 @@ export default { }, { title: PAGE_TITLES.PEN_COORDINATORS, - link: 'penCoordinators', + link: 'studentRegistrationContacts', newTab: true, authorized: this.VIEW_PEN_COORDINATOR_INFO_ROLE }, diff --git a/frontend/src/mixins/schoolMixin.js b/frontend/src/mixins/schoolMixin.js index bd6af0d77..b4a273fd1 100644 --- a/frontend/src/mixins/schoolMixin.js +++ b/frontend/src/mixins/schoolMixin.js @@ -17,8 +17,8 @@ export default { this.loadingSchoolData = true; try { const schoolData = await getSchoolData(mincode); - if (!!schoolData && !!schoolData.schoolName) { - this.schoolLabel = schoolData.schoolName; + if (!!schoolData && !!schoolData.displayName) { + this.schoolLabel = schoolData.displayName; this.mincodeError = false; this.mincodeErrors = []; } else { diff --git a/frontend/src/router.js b/frontend/src/router.js index c8c0b5384..84ddfe0e6 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -27,7 +27,7 @@ import RouterView from '@/components/RouterView.vue'; import BackendSessionExpired from '@/components/BackendSessionExpired.vue'; import UnAuthorizedPage from '@/components/UnAuthorizedPage.vue'; import CompareStudents from '@/components/CompareStudents.vue'; -import PenCoordinatorsDisplay from '@/components/penreg/coordinator/PenCoordinatorsDisplay.vue'; +import StudentRegistrationContactsDisplay from '@/components/penreg/student-registration/StudentRegistrationContactsDisplay.vue'; import MacrosDisplay from '@/components/admin/MacrosDisplay.vue'; import NominalRoll from '@/components/nominal-roll/NominalRoll.vue'; import NomRollStudentListDisplay from '@/components/nominal-roll/NomRollStudentListDisplay.vue'; @@ -261,9 +261,9 @@ const router = createRouter({ }, }, { - path: '/penCoordinators', - name: 'penCoordinators', - component: PenCoordinatorsDisplay, + path: '/studentRegistrationContacts', + name: 'studentRegistrationContacts', + component: StudentRegistrationContactsDisplay, meta: { pageTitle: PAGE_TITLES.PEN_COORDINATORS, requiresAuth: true, diff --git a/frontend/src/store/modules/app.js b/frontend/src/store/modules/app.js index 7b74dcde8..e33c40147 100644 --- a/frontend/src/store/modules/app.js +++ b/frontend/src/store/modules/app.js @@ -13,8 +13,6 @@ export const appStore = defineStore('app', { requestTypeLabel: REQUEST_TYPES.penRequest.label, pageTitle: null, stickyInfoPanelHeight: null, - schoolApiMincodeSchoolNames: new Map(), - schoolApiDistrictCodes: new Set(), mincodeSchoolNames: new Map(), schoolMap: new Map(), notClosedSchools: [], @@ -31,7 +29,9 @@ export const appStore = defineStore('app', { fundingGroups: [] }), getters: { - activeFundingGroups: state => state.fundingGroups.filter(group => group.expiryDate >= LocalDateTime.now().toString() && group.effectiveDate <= LocalDateTime.now().toString()) + activeFundingGroups: state => state.fundingGroups.filter(group => group.expiryDate >= LocalDateTime.now().toString() && group.effectiveDate <= LocalDateTime.now().toString()), + districtCodesObjectSorted: state => Array.from(state.districtCodes).sort(), + mincodeSchoolNamesObjectSorted: state => Object.values(Object.fromEntries(state.mincodeSchoolNames)).map(v => v.toUpperCase()).sort(), }, actions: { async setConfig(config){ @@ -105,13 +105,6 @@ export const appStore = defineStore('app', { this.alertNotification = true; } }, - async setSchoolApiMincodeSchoolNameAndDistrictCodes(schoolApiMincodeSchoolNameList) { - this.schoolApiMincodeSchoolNames = new Map(); - schoolApiMincodeSchoolNameList.forEach(element => { - this.schoolApiMincodeSchoolNames.set(element.mincode, element.schoolName); - this.schoolApiDistrictCodes.add(element.mincode?.substring(0, 3)); - }); - }, async setFundingGroups(fundingGroups) { this.fundingGroups = fundingGroups; this.fundingGroupsMap = new Map(); @@ -122,7 +115,7 @@ export const appStore = defineStore('app', { async getCodes() { if(localStorage.getItem('jwtToken')) { // DONT Call api if there is not token. if(this.mincodeSchoolNames.size === 0) { - const response = await ApiService.getMincodeSchoolNames(); + const response = await ApiService.getAllSchools(); await this.setMincodeSchoolNameAndDistrictCodes(response.data); } if (this.activeSchools.length === 0) { @@ -141,10 +134,6 @@ export const appStore = defineStore('app', { const response = await ApiService.getAuthorities(); await this.setIndependentAuthorities(response.data); } - if(this.schoolApiMincodeSchoolNames.size === 0) { - const response = await ApiService.getSchoolApiMincodeSchoolNames(); - await this.setSchoolApiMincodeSchoolNameAndDistrictCodes(response.data); - } if(this.fundingGroupsMap.size === 0 && !this.config.DISABLE_SDC_FUNCTIONALITY) { const response = await ApiService.getAllFundingGroups(); await this.setFundingGroups(response.data); @@ -157,7 +146,7 @@ export const appStore = defineStore('app', { }, async refreshEntities() { if(localStorage.getItem('jwtToken')) { // DONT Call api if there is not token. - const responseMinSchool = await ApiService.getMincodeSchoolNames(); + const responseMinSchool = await ApiService.getAllSchools(); await this.setMincodeSchoolNameAndDistrictCodes(responseMinSchool.data); const responseActiveSchools = await ApiService.getActiveSchools(); @@ -172,9 +161,6 @@ export const appStore = defineStore('app', { const response = await ApiService.getAuthorities(); await this.setIndependentAuthorities(response.data); - const responseSchoolApiMin = await ApiService.getSchoolApiMincodeSchoolNames(); - await this.setSchoolApiMincodeSchoolNameAndDistrictCodes(responseSchoolApiMin.data); - if(!this.config.DISABLE_SDC_FUNCTIONALITY) { const responseFunding = await ApiService.getAllFundingGroups(); await this.setFundingGroups(responseFunding.data); diff --git a/frontend/src/utils/common.js b/frontend/src/utils/common.js index 0b956759e..fcd501fea 100644 --- a/frontend/src/utils/common.js +++ b/frontend/src/utils/common.js @@ -198,15 +198,10 @@ export function updatePossibleMatchResultsBasedOnCurrentStatus(prbStudent, possi } export function getSchoolData(mincode) { - const params = { - params: { - mincode: mincode, - } - }; if (mincode) { return new Promise((resolve, reject) => { ApiService.apiAxios - .get(Routes.SCHOOL_DATA_URL, params) + .get(Routes.institute.SCHOOL_DATA_URL + '/mincode/' + mincode) .then(response => { resolve(response.data); }) diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 4d2650968..de41f9f25 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -97,6 +97,8 @@ let object = { institute: { ROOT_ENDPOINT: instituteRoot, SCHOOL_DATA_URL: instituteRoot + '/school', + STUDENT_REGISTRATION_CONTACTS: instituteRoot + '/studentRegistrationContacts', + STUDENT_REGISTRATION_CONTACT: instituteRoot + '/studentRegistrationContact', SCHOOL_NOTE_URL: instituteRoot + '/school/note', SCHOOL_CONTACT_URL: instituteRoot + '/school/contact', SCHOOL_PAGINATED_DATA_URL: instituteRoot + '/schoolsPaginated', @@ -424,7 +426,7 @@ export const PAGE_TITLES = Object.freeze( PEN_REQ_BATCH_STUDENT_DETAILS: 'PEN Request Details', CREATE_NEW_PEN: 'Create New PEN', ARCHIVED_REQ_FILES: 'Archived PEN Request Files', - PEN_COORDINATORS: 'PEN Contacts', + PEN_COORDINATORS: 'Student Registration Contacts', NEW_PENS: 'New PENs', MACRO_MANAGEMENT: 'Macro Management', NOMINAL_ROLL: 'Nominal Roll',