diff --git a/backend/src/components/cache-service.js b/backend/src/components/cache-service.js index 23697859..36b303af 100644 --- a/backend/src/components/cache-service.js +++ b/backend/src/components/cache-service.js @@ -240,7 +240,7 @@ const cacheService = { if (assessmentTypeCodesResponse && assessmentTypeCodesResponse.length > 0) { assessmentTypeCodesMap.clear(); // reset the value. assessmentTypeCodesResponse.forEach(entry => { - assessmentTypeCodesMap.set(entry.assessmentTypeCode, entry.label); + assessmentTypeCodesMap.set(entry.assessmentTypeCode, {'label': entry.label, 'displayOrder': entry.displayOrder }); }); } log.info(`Loaded ${assessmentTypeCodesMap.size} assessmentTypeCodes.`); @@ -265,7 +265,7 @@ const cacheService = { }); }, - getAssessmentTypeLabelByCode(assessmentTypeCode) { + getAssessmentTypeByCode(assessmentTypeCode) { return assessmentTypeCodesMap.get(assessmentTypeCode); }, @@ -273,6 +273,10 @@ const cacheService = { return assessmentSpecialCaseTypeCodesMap.get(specialCaseTypeCode); }, + getAllAssessmentSpecialCases(){ + return assessmentSpecialCaseTypeCodesMap; + }, + async loadDataToCache(cacheKey,url){ log.debug(` loading all ${cacheKey} during start up`); await retry(async () => { diff --git a/backend/src/components/eas/eas.js b/backend/src/components/eas/eas.js index 3717fa45..b3109428 100644 --- a/backend/src/components/eas/eas.js +++ b/backend/src/components/eas/eas.js @@ -26,8 +26,11 @@ async function getAssessmentSessionsBySchoolYear(req, res) { const url = `${config.get('server:eas:assessmentSessionsURL')}/school-year/${req.params.schoolYear}`; let data = await getData(url); data.forEach(session => { + session.isOpen = new Date(session.activeFromDate) <= new Date() && new Date(session.activeUntilDate) >= new Date(); session.assessments.forEach(assessment => { - assessment.assessmentTypeName = cacheService.getAssessmentTypeLabelByCode(assessment.assessmentTypeCode)+' ('+assessment.assessmentTypeCode+')'; + let assessmentType = cacheService.getAssessmentTypeByCode(assessment.assessmentTypeCode); + assessment.assessmentTypeName = assessmentType.label+' ('+assessment.assessmentTypeCode+')'; + assessment.displayOrder = assessmentType.displayOrder; }); }); return res.status(200).json(data); @@ -59,17 +62,15 @@ async function updateAssessmentSession(req, res) { } } -async function getAssessmentStudentsPaginated(req, res) { +async function getAssessmentStudentsPaginated(req, res) { try { - const search = []; - + const search = []; if (req.query.searchParams?.['moreFilters']) { let criteriaArray = createMoreFiltersSearchCriteria(req.query.searchParams['moreFilters']); criteriaArray.forEach(criteria => { search.push(criteria); }); } - const params = { params: { pageNumber: req.query.pageNumber, @@ -78,30 +79,13 @@ async function getAssessmentStudentsPaginated(req, res) { searchCriteriaList: JSON.stringify(search), } }; - - let data = await getData(`${config.get('server:eas:assessmentStudentsURL')}/paginated`, params); - + let data = await getData(`${config.get('server:eas:assessmentStudentsURL')}/paginated`, params); if (req?.query?.returnKey) { let result = data?.content.map((student) => student[req?.query?.returnKey]); return res.status(HttpStatus.OK).json(result); } data?.content.forEach(value => { - let school = cacheService.getSchoolBySchoolID(value.schoolID); - let assessmentCenter = cacheService.getSchoolBySchoolID(value.assessmentCenterID); - let district = cacheService.getDistrictJSONByDistrictId(school.districtID); - - value.schoolNumber = school.mincode; - value.schoolName = getSchoolName(school); - value.districtID = school.districtID; - value.districtNumber = district.districtNumber; - value.districtName = getDistrictName(district); - value.assessmentCenterNumber = assessmentCenter.mincode; - value.assessmentCenterName = getSchoolName(assessmentCenter); - - value.assessmentTypeName = cacheService.getAssessmentTypeLabelByCode(value.assessmentTypeCode)+' ('+value.assessmentTypeCode+')'; - value.provincialSpecialCaseName = cacheService.getSpecialCaseTypeLabelByCode(value.provincialSpecialCaseCode); - value.sessionName = moment(value.courseMonth, 'MM').format('MMMM') +' '+value.courseYear; - + includeAssessmentStudentProps(value); }); return res.status(200).json(data); } catch (e) { @@ -114,6 +98,66 @@ async function getAssessmentStudentsPaginated(req, res) { } } +async function getAssessmentStudentByID(req, res) { + try { + + let data = await getData(`${config.get('server:eas:assessmentStudentsURL')}/${req.params.assessmentStudentID}`); + return res.status(200).json(includeAssessmentStudentProps(data)); + } catch (e) { + if (e?.status === 404) { + res.status(HttpStatus.OK).json(null); + } else { + await logApiError(e, 'Error getting eas assessment student'); + return errorResponse(res); + } + } +} + +async function updateAssessmentStudentByID(req, res) { + if (req.params.assessmentStudentID !== req.body.assessmentStudentID) { + return res.status(HttpStatus.BAD_REQUEST).json({ + message: 'The assessmentStudentID in the URL didn\'t match the assessmentStudentID in the request body.' + }); + } + try { + const userInfo = utils.getUser(req); + const payload = { + ...req.body, + updateUser: userInfo.idir_username, + updateDate: null, + createDate: null + }; + const result = await utils.putData(`${config.get('server:eas:assessmentStudentsURL')}/${req.params.assessmentStudentID}`, payload, utils.getUser(req).idir_username); + return res.status(HttpStatus.OK).json(result); + } catch (e) { + logApiError(e, 'updateAssessmentStudent', 'Error occurred while attempting to save the changes to the assessment student registration.'); + return errorResponse(res); + } +} + +function includeAssessmentStudentProps(assessmentStudent) { + if(assessmentStudent) { + let school = cacheService.getSchoolBySchoolID(assessmentStudent.schoolID); + let assessmentCenter = assessmentStudent.assessmentCenterID ? cacheService.getSchoolBySchoolID(assessmentStudent.assessmentCenterID) : null; + let district = cacheService.getDistrictJSONByDistrictId(school.districtID); + + if(school && district) { + assessmentStudent.schoolName_desc = getSchoolName(school); + assessmentStudent.districtID = school.districtID; + assessmentStudent.districtName_desc = getDistrictName(district); + } + + if(assessmentCenter) { + assessmentStudent.assessmentCenterName_desc = getSchoolName(assessmentCenter); + } + + assessmentStudent.assessmentTypeName_desc = cacheService.getAssessmentTypeByCode(assessmentStudent.assessmentTypeCode).label+' ('+assessmentStudent.assessmentTypeCode+')'; + assessmentStudent.provincialSpecialCaseName_desc = assessmentStudent.provincialSpecialCaseCode ? cacheService.getSpecialCaseTypeLabelByCode(assessmentStudent.provincialSpecialCaseCode) : null; + assessmentStudent.sessionName_desc = moment(assessmentStudent.courseMonth, 'MM').format('MMMM') +' '+assessmentStudent.courseYear; + } + return assessmentStudent; +} + function getSchoolName(school) { return school.mincode + ' - ' + school.schoolName; } @@ -122,9 +166,23 @@ function getDistrictName(district) { return district.districtNumber + ' - ' + district.name; } +function getAssessmentSpecialCases(req, res) { + try { + const codes = cacheService.getAllAssessmentSpecialCases(); + return res.status(HttpStatus.OK).json(Object.fromEntries(codes)); + } catch (e) { + logApiError(e, 'getAssessmentSpecialCases', 'Error occurred while attempting to get specialcase types.'); + return errorResponse(res); + } +} + + module.exports = { getAssessmentSessions, getAssessmentSessionsBySchoolYear, updateAssessmentSession, - getAssessmentStudentsPaginated + getAssessmentStudentsPaginated, + getAssessmentStudentByID, + updateAssessmentStudentByID, + getAssessmentSpecialCases }; diff --git a/backend/src/components/eas/studentFilters.js b/backend/src/components/eas/studentFilters.js index 7d2a879c..dd84ecb0 100644 --- a/backend/src/components/eas/studentFilters.js +++ b/backend/src/components/eas/studentFilters.js @@ -34,18 +34,15 @@ function createMoreFiltersSearchCriteria(searchFilter = []) { } if (key === 'districtNameNumber' && pValue) { - let districtNameNumberCriteria = createDistrictNameNumberSearchCriteria(pValue.toString()); - districtNameNumberFilter = [...districtNameNumberCriteria]; + searchCriteriaList.push({ key: 'districtID', value: pValue.toString(), operation: FILTER_OPERATION.EQUAL, valueType: VALUE_TYPE.UUID, condition: CONDITION.AND }); } if (key === 'schoolNameNumber' && pValue) { - let schoolNameNumberCriteria = createSchoolNameNumberSearchCriteria(pValue.toString()); - schoolNameNumberFilter = [...schoolNameNumberCriteria]; + searchCriteriaList.push({ key: 'schoolID', value: pValue.toString(), operation: FILTER_OPERATION.EQUAL, valueType: VALUE_TYPE.UUID, condition: CONDITION.AND }); } if (key === 'assessmentCenterNameNumber' && pValue) { - let schoolNameNumberCriteria = createAssessmentCenterNameNumberSearchCriteria(pValue.toString()); - assessmentCenterNameNumberFilter = [...schoolNameNumberCriteria]; + searchCriteriaList.push({ key: 'assessmentCenterID', value: pValue.toString(), operation: FILTER_OPERATION.EQUAL, valueType: VALUE_TYPE.UUID, condition: CONDITION.AND }); } if (key === 'session' && pValue) { @@ -101,48 +98,6 @@ function createMoreFiltersSearchCriteria(searchFilter = []) { return search; } -function createDistrictNameNumberSearchCriteria(value) { - const searchDistrictCriteriaList = []; - - searchDistrictCriteriaList.push({ - key: 'districtID', - operation: FILTER_OPERATION.EQUAL, - value: value, - valueType: VALUE_TYPE.UUID, - condition: CONDITION.AND - }); - - return searchDistrictCriteriaList; -} - -function createSchoolNameNumberSearchCriteria(value) { - const searchSchoolCriteriaList = []; - - searchSchoolCriteriaList.push({ - key: 'schoolID', - operation: FILTER_OPERATION.EQUAL, - value: value, - valueType: VALUE_TYPE.UUID, - condition: CONDITION.AND - }); - - return searchSchoolCriteriaList; -} - -function createAssessmentCenterNameNumberSearchCriteria(value) { - const searchAssessmentCenterCriteriaList = []; - - searchAssessmentCenterCriteriaList.push({ - key: 'assessmentCenterID', - operation: FILTER_OPERATION.EQUAL, - value: value, - valueType: VALUE_TYPE.UUID, - condition: CONDITION.AND - }); - - return searchAssessmentCenterCriteriaList; -} - module.exports = { createMoreFiltersSearchCriteria diff --git a/backend/src/routes/eas.js b/backend/src/routes/eas.js index 934a4edb..42750b0d 100644 --- a/backend/src/routes/eas.js +++ b/backend/src/routes/eas.js @@ -1,11 +1,13 @@ const passport = require('passport'); const express = require('express'); const router = express.Router(); -const { getAssessmentSessions, getAssessmentSessionsBySchoolYear, updateAssessmentSession, getAssessmentStudentsPaginated } = require('../components/eas/eas'); +const { getAssessmentSessions, getAssessmentSessionsBySchoolYear, updateAssessmentSession, getAssessmentStudentsPaginated, getAssessmentStudentByID, updateAssessmentStudentByID, getAssessmentSpecialCases } = require('../components/eas/eas'); const utils = require('../components/utils'); const extendSession = utils.extendSession(); const permUtils = require('../components/permissionUtils'); const perm = require('../util/Permission'); +const validate = require('../components/validator'); +const {putStudentAssessmentSchema} = require('../validations/eas'); const PERMISSION = perm.PERMISSION; @@ -14,7 +16,10 @@ router.get('/assessment-sessions', passport.authenticate('jwt', {session: false} router.get('/assessment-sessions/school-year/:schoolYear', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.MANAGE_EAS_SESSIONS_PERMISSION), extendSession, getAssessmentSessionsBySchoolYear); router.put('/assessment-sessions/:sessionID', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.MANAGE_EAS_SESSIONS_PERMISSION), extendSession, updateAssessmentSession); +router.get('/assessment-registrations/student/:assessmentStudentID', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.VIEW_EAS_STUDENT_PERMISSION), extendSession, getAssessmentStudentByID); +router.put('/assessment-registrations/student/:assessmentStudentID', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.EDIT_EAS_STUDENT_PERMISSION), extendSession, validate(putStudentAssessmentSchema), updateAssessmentStudentByID); router.get('/assessment-registrations/paginated', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.VIEW_EAS_STUDENT_PERMISSION), extendSession, getAssessmentStudentsPaginated); +router.get('/assessment-specialcase-types', passport.authenticate('jwt', {session: false}, undefined), permUtils.checkUserHasPermission(PERMISSION.MANAGE_EAS_SESSIONS_PERMISSION), extendSession, getAssessmentSpecialCases); module.exports = router; diff --git a/backend/src/util/Permission.js b/backend/src/util/Permission.js index 8de31e48..5d209527 100644 --- a/backend/src/util/Permission.js +++ b/backend/src/util/Permission.js @@ -18,7 +18,9 @@ const PERMISSION = Object.freeze( REPORTS_SDC_INDEPENDENT_SCHOOLS_PERMISSION: 'REPORTS_SDC_INDEPENDENT_SCHOOLS_PERMISSION', REPORTS_SDC_HEADCOUNTS_PERMISSION: 'REPORTS_SDC_HEADCOUNTS_PERMISSION', MANAGE_EAS_SESSIONS_PERMISSION:'MANAGE_EAS_SESSIONS_PERMISSION', - VIEW_EAS_STUDENT_PERMISSION: 'VIEW_EAS_STUDENT_PERMISSION' + VIEW_EAS_STUDENT_PERMISSION: 'VIEW_EAS_STUDENT_PERMISSION', + EDIT_EAS_STUDENT_PERMISSION: 'EDIT_EAS_STUDENT_PERMISSION' + } ); diff --git a/backend/src/validations/base.js b/backend/src/validations/base.js new file mode 100644 index 00000000..3f9628a5 --- /dev/null +++ b/backend/src/validations/base.js @@ -0,0 +1,12 @@ +const { object, string, date } = require('yup'); + +const baseRequestSchema = object({ + createDate: date().nullable().optional(), + createUser: string().nullable().max(100).optional(), + updateDate: date().nullable().optional(), + updateUser: string().nullable().max(100).optional(), +}).noUnknown(); + +module.exports = { + baseRequestSchema, +}; diff --git a/backend/src/validations/eas.js b/backend/src/validations/eas.js new file mode 100644 index 00000000..e2518a59 --- /dev/null +++ b/backend/src/validations/eas.js @@ -0,0 +1,34 @@ +const { object, string, boolean, number } = require('yup'); +const { baseRequestSchema } = require('./base'); + +const putStudentAssessmentSchema = object({ + body: object({ + assessmentStudentID: string().nonNullable(), + sessionID:string().nonNullable(), + districtID: string().nonNullable(), + schoolID: string().nonNullable(), + assessmentCenterID: string().nullable().optional(), + assessmentID:string().nonNullable(), + assessmentTypeCode: string().nonNullable(), + studentID: string().nonNullable(), + pen: string().max(9).nonNullable(), + localID: string().max(12).nonNullable(), + givenName: string().max(25).nonNullable(), + surName: string().max(25).nonNullable(), + isElectronicExam: boolean().nonNullable(), + proficiencyScore: number().nullable().optional(), + provincialSpecialCaseCode: string().max(1).nullable().optional(), + courseStatusCode: string().max(1).nullable().optional(), + numberOfAttempts: number().nullable().optional(), + courseMonth: number().optional(), + courseYear: number().optional(), + }).concat(baseRequestSchema).noUnknown(), + params: object({ + studentAssessmentID: string().nonNullable(), + }), + query: object().noUnknown(), +}).noUnknown(); + +module.exports = { + putStudentAssessmentSchema, +}; diff --git a/frontend/src/common/apiService.js b/frontend/src/common/apiService.js index ee207608..dca6f377 100644 --- a/frontend/src/common/apiService.js +++ b/frontend/src/common/apiService.js @@ -141,6 +141,9 @@ export default { getAllActiveHomeLanguageSpokenCodes:getCodes(`${Routes.sdc.SDC_HOME_LANGUAGE_SPOKEN_CODES}?active=true`), getAllActiveSchoolFundingCodes:getCodes(`${Routes.sdc.SDC_SCHOOL_FUNDING_CODES}?active=true`), getAllActiveSpecialEdCodes:getCodes(`${Routes.sdc.SDC_SPECIAL_ED_CODES}?active=true`), + + getAllEASSpecialCaseCodes:getCodes(`${Routes.eas.GET_ASSESSMENT_SPECIALCASE_TYPES}`), + async getConfig() { try { const response = await apiAxios.get(Routes.CONFIG); diff --git a/frontend/src/components/assessments/registrations/StudentRegistrationDetail.vue b/frontend/src/components/assessments/registrations/StudentRegistrationDetail.vue new file mode 100644 index 00000000..b4d8c312 --- /dev/null +++ b/frontend/src/components/assessments/registrations/StudentRegistrationDetail.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/frontend/src/components/assessments/registrations/StudentRegistrations.vue b/frontend/src/components/assessments/registrations/StudentRegistrations.vue index 0302f7da..a18f20aa 100644 --- a/frontend/src/components/assessments/registrations/StudentRegistrations.vue +++ b/frontend/src/components/assessments/registrations/StudentRegistrations.vue @@ -40,6 +40,8 @@ :reset="resetFlag" :can-load-next="canLoadNext" :can-load-previous="canLoadPrevious" + @reload-registrations="reload" + @editSelectedRow="editRegistration" @loadNext="loadNext" @loadPrevious="loadPrevious" /> @@ -67,6 +69,21 @@ /> + + + @@ -77,6 +94,8 @@ import ApiService from '@/common/apiService'; import { Routes } from '@/utils/constants'; import { cloneDeep, isEmpty, omitBy } from 'lodash'; import StudentRegistrationsFilter from './StudentRegistrationsFilter.vue'; +import StudentRegistrationDetail from './StudentRegistrationDetail.vue'; + import moment from 'moment'; export default { @@ -84,6 +103,7 @@ export default { components: { StudentRegistrationsCustomTable, StudentRegistrationsFilter, + StudentRegistrationDetail }, props: { schoolYear: { @@ -116,6 +136,9 @@ export default { canLoadNext: false, canLoadPrevious: false, resetFlag: false, + studentRegistrationForEdit: null, + reloadStudentRegistrationsFlag: false, + editStudentRegistrationSheet: false, }; }, computed: { @@ -128,6 +151,17 @@ export default { this.getAssessmentStudents(); }, methods: { + editRegistration($event) { + this.studentRegistrationForEdit = cloneDeep($event); + this.editStudentRegistrationSheet = true; + }, + closeEditAndLoadStudentRegistrations() { + this.editStudentRegistrationSheet = !this.editStudentRegistrationSheet; + if (this.reloadStudentRegistrationsFlag === true) { + this.getAssessmentStudents(); + } + this.reloadStudentRegistrationsFlag = false; + }, applydefaultFilers() { if (this.sessionID) { const activeSession = this.schoolYearSessions.find( @@ -195,6 +229,14 @@ export default { this.pageNumber -= 1; this.getAssessmentStudents(); } + }, + reload(value) { + if(value?.pageSize) { + this.pageSize = value?.pageSize; + } else if(value?.pageNumber) { + this.pageNumber = value?.pageNumber; + } + this.getAssessmentStudents(); } }, }; diff --git a/frontend/src/components/assessments/registrations/StudentRegistrationsCustomTable.vue b/frontend/src/components/assessments/registrations/StudentRegistrationsCustomTable.vue index 95c01761..bca7e590 100644 --- a/frontend/src/components/assessments/registrations/StudentRegistrationsCustomTable.vue +++ b/frontend/src/components/assessments/registrations/StudentRegistrationsCustomTable.vue @@ -152,7 +152,7 @@ export default { default: false, }, }, - emits: [ 'reload', 'openStudentDetails', 'selections', 'editSelectedRow', 'loadPrevious', 'loadNext'], + emits: [ 'reload-registrations', 'openStudentDetails', 'editSelectedRow', 'loadPrevious', 'loadNext'], data() { return { masterCheckbox: false, @@ -173,26 +173,9 @@ export default { if (val) { this.masterCheckbox = false; this.selected = []; - this.$emit('reload', { pageNumber: val }); + this.$emit('reload-registrations', { pageNumber: val }); } - }, - selected: { - handler(val) { - if (val) { - this.$emit('selections', this.selected); - } - }, - deep: true, - }, - reset: { - handler(val) { - if (val) { - this.masterCheckbox = false; - this.selected.splice(0); - } - }, - immediate: true, - }, + } }, created() { appStore() diff --git a/frontend/src/components/assessments/registrations/StudentRegistrationsFilter.vue b/frontend/src/components/assessments/registrations/StudentRegistrationsFilter.vue index a76d4a30..dd1094e7 100644 --- a/frontend/src/components/assessments/registrations/StudentRegistrationsFilter.vue +++ b/frontend/src/components/assessments/registrations/StudentRegistrationsFilter.vue @@ -211,7 +211,7 @@ {{ option?.title }} @@ -232,7 +232,22 @@ {{ option?.title }} - + +
+ + + {{ option?.title }} + + +
{ + this.setupSpecialCaseCodes(); + this.loading = false; + }); }); Object.keys(this.filters).forEach((key) => { this.selected[key] = []; @@ -337,6 +361,7 @@ export default { this.setupAssessmentSessions(); }, methods: { + close() { this.$emit('close-assessment-filter'); }, @@ -344,14 +369,29 @@ export default { this.sessionSearchNames = []; this.assessmentTypeSearchNames = []; this.schoolYearSessions.forEach(session => { - this.sessionSearchNames.push({title: this.formatMonth(session.courseMonth), id: session.sessionID, value: session.sessionID}); + this.sessionSearchNames.push({ + id: session.sessionID, + courseMonth: parseInt(session.courseMonth), + courseYear: parseInt(session.courseYear), + title: this.formatMonth(session.courseMonth), + value: session.sessionID + }); session.assessments.forEach(assessment => { let existingItem = this.assessmentTypeSearchNames.find(item => item.id === assessment.assessmentTypeCode); if (!existingItem) { - this.assessmentTypeSearchNames.push({title: assessment.assessmentTypeName, id: assessment.assessmentTypeCode, value: assessment.assessmentTypeCode}); + this.assessmentTypeSearchNames.push({title: assessment.assessmentTypeName, id: assessment.assessmentTypeCode, value: assessment.assessmentTypeCode, displayOrder: assessment.displayOrder}); } }); }); + this.sessionSearchNames = sortBy(this.sessionSearchNames, ['courseYear','courseMonth']); + this.assessmentTypeSearchNames = sortBy(this.assessmentTypeSearchNames, ['displayOrder']); + }, + setupSpecialCaseCodes() { + this.specialCaseSearchNames = []; + Object.keys(this.specialCaseCodes).forEach(key => { + this.specialCaseSearchNames.push({title: this.specialCaseCodes[key], id: key, value: key}); + }); + this.specialCaseSearchNames = sortBy(this.specialCaseSearchNames, ['title']); }, setupSchoolList() { this.schoolSearchNames = []; @@ -442,25 +482,7 @@ export default { delete this.selected[key]; this.apply(); } - }, - setScoreRangeFilter(key, $event){ - this.setPenLocalIdNameFilter($event, null); - if($event) { - let scoreFilterTitle; - if($event[0] === this.scoreRangeDefault[0]){ - scoreFilterTitle = + $event[1] + ' courses or less'; - } else if ($event[1] === this.scoreRangeDefault[1]) { - scoreFilterTitle = $event[0] + ' courses or more'; - } else { - scoreFilterTitle = 'Between ' + $event[0] + ' and ' + $event[1] + ' courses'; - } - this.selected[key] = [{title: scoreFilterTitle, value: $event}]; - this.apply(); - } else { - delete this.selected[key]; - this.apply(); - } - }, + }, clear() { this.selected = {}; this.penLocalIdNameFilter = null; @@ -505,6 +527,14 @@ export default { border: 1px solid #003366; } +.filter-button-active { +padding: 5px; +margin: 0 8px 8px 8px; +background-color: rgb(0, 51, 102); +color: rgb(255, 255, 255); +caret-color: rgb(255, 255, 255); +} + .filter-toggle { flex-wrap: wrap !important; overflow: visible !important; diff --git a/frontend/src/components/assessments/registrations/forms/EditStudentRegistration.vue b/frontend/src/components/assessments/registrations/forms/EditStudentRegistration.vue new file mode 100644 index 00000000..c44a34c8 --- /dev/null +++ b/frontend/src/components/assessments/registrations/forms/EditStudentRegistration.vue @@ -0,0 +1,549 @@ + + + + diff --git a/frontend/src/store/modules/eas.js b/frontend/src/store/modules/eas.js new file mode 100644 index 00000000..f2b4c0fe --- /dev/null +++ b/frontend/src/store/modules/eas.js @@ -0,0 +1,23 @@ +import ApiService from '@/common/apiService'; +import {defineStore} from 'pinia'; + +export const easStore = defineStore('EasStore', { + namespaced: true, + state: () => ({ + specialCaseCodes: {}, + }), + actions: { + async setSpecialCaseCodes(payload) { + this.specialCaseCodes = payload; + }, + async getSpecialCaseCodes() { + if(localStorage.getItem('jwtToken')) { // DONT Call api if there is not token. + if (Object.keys(this.specialCaseCodes).length === 0) { + const response = await ApiService.getAllEASSpecialCaseCodes(); + await this.setSpecialCaseCodes(response.data); + } + } + return this.specialCaseCodes; + }, + }, +}); diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 8d913f5e..d90c2ccf 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -208,6 +208,8 @@ let object = { BASE_URL: easRoot, GET_ASSESSMENT_SESSIONS: easRoot + '/assessment-sessions', GET_ASSESSMENT_TYPES: easRoot + '/assessment-types', + GET_ASSESSMENT_SPECIALCASE_TYPES: easRoot + '/assessment-specialcase-types', + ASSESSMENT_STUDENTS: easRoot + '/assessment-registrations/student', GET_ASSESSMENT_STUDENTS_PAGINATED: easRoot + '/assessment-registrations/paginated', } }; diff --git a/frontend/src/utils/constants/Permission.js b/frontend/src/utils/constants/Permission.js index ad50b3ef..63b7b402 100644 --- a/frontend/src/utils/constants/Permission.js +++ b/frontend/src/utils/constants/Permission.js @@ -40,7 +40,9 @@ export const PERMISSION = Object.freeze( REPORTS_SDC_HEADCOUNTS_PERMISSION: 'REPORTS_SDC_HEADCOUNTS_PERMISSION', - MANAGE_EAS_SESSIONS_PERMISSION: 'MANAGE_EAS_SESSIONS_PERMISSION' + MANAGE_EAS_SESSIONS_PERMISSION: 'MANAGE_EAS_SESSIONS_PERMISSION', + + EDIT_EAS_HISTORY_PERMISSION: 'EDIT_EAS_HISTORY_PERMISSION' } ); diff --git a/frontend/src/utils/eas/StudentRegistrationTableConfiguration.js b/frontend/src/utils/eas/StudentRegistrationTableConfiguration.js index 4602b444..ed798de9 100644 --- a/frontend/src/utils/eas/StudentRegistrationTableConfiguration.js +++ b/frontend/src/utils/eas/StudentRegistrationTableConfiguration.js @@ -31,22 +31,7 @@ export const SPECIAL_CASE_FILTER = Object.freeze( id: 'specialCaseCode', multiple: true, key: 'specialCaseCode', - filterOptions: [ - { - title: 'Aegrotat', - id: 'aegrotat', - value: 'A' - }, - { - title: 'Exemption', - id: 'exemption', - value: 'E' - }, - { - title: 'Disqualified', - id: 'disqualified', - value: 'D' - } + filterOptions: [ ] } ); @@ -106,16 +91,16 @@ export const PROFICIENCY_SCORE_RANGE_FILTER = Object.freeze( export const SCHOOL_YEAR_REGISTRATIONS_VIEW = Object.freeze( { tableHeaders: [ - { title: 'Session', key: 'sessionName'}, - { title: 'District', key: 'districtName' }, - { title: 'School', key: 'schoolName' }, - { title: 'Assessment Center', key: 'assessmentCenterName' }, + { title: 'Session', key: 'sessionName_desc'}, + { title: 'District', key: 'districtName_desc' }, + { title: 'School', key: 'schoolName_desc' }, + { title: 'Assessment Center', key: 'assessmentCenterName_desc' }, { title: 'PEN', key: 'pen' }, { title: 'Local ID', key: 'localID' }, { title: 'Given Name', key: 'givenName' }, { title: 'Surname', key: 'surName' }, - { title: 'Course Name (Code)', key: 'assessmentTypeName' }, - { title: 'Special Case', key: 'provincialSpecialCaseName' }, + { title: 'Course Name (Code)', key: 'assessmentTypeName_desc' }, + { title: 'Special Case', key: 'provincialSpecialCaseName_desc' }, { title: 'Proficiency Score', key: 'proficiencyScore' }, ], allowedFilters: { @@ -131,15 +116,15 @@ export const SCHOOL_YEAR_REGISTRATIONS_VIEW = Object.freeze( export const SESSION_REGISTRATIONS_VIEW = Object.freeze( { tableHeaders: [ - { title: 'District', key: 'districtName' }, - { title: 'School', key: 'schoolName' }, - { title: 'Assessment Center', key: 'assessmentCenterName' }, + { title: 'District', key: 'districtName_desc' }, + { title: 'School', key: 'schoolName_desc' }, + { title: 'Assessment Center', key: 'assessmentCenterName_desc' }, { title: 'PEN', key: 'pen' }, { title: 'Local ID', key: 'localID' }, { title: 'Surname', key: 'surName' }, { title: 'Given Name', key: 'givenName' }, - { title: 'Course Name (Code)', key: 'assessmentTypeName' }, - { title: 'Special Case', key: 'provincialSpecialCaseName' }, + { title: 'Course Name (Code)', key: 'assessmentTypeName_desc' }, + { title: 'Special Case', key: 'provincialSpecialCaseName_desc' }, { title: 'Proficiency Score', key: 'proficiencyScore' }, ], allowedFilters: { diff --git a/tools/config/update-configmap.sh b/tools/config/update-configmap.sh index f14aa0c2..e13eef0d 100644 --- a/tools/config/update-configmap.sh +++ b/tools/config/update-configmap.sh @@ -565,6 +565,32 @@ viewEasStudentsPermissionJson=$(curl -sX GET "https://$SOAM_KC/auth/admin/realms -H "Content-Type: application/json" \ -H "Authorization: Bearer $TKN") +echo +echo Creating EDIT_EAS_STUDENT_PERMISSION permission +curl -sX POST "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/roles" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TKN" \ + -d "{\"name\" : \"EDIT_EAS_STUDENT_PERMISSION\",\"description\" : \"Permission to edit EAS student\",\"composite\" : false,\"clientRole\" : false,\"containerId\" : \"$SOAM_KC_REALM_ID\"}" + +echo +echo Retrieving EDIT_EAS_STUDENT_PERMISSION permission +editEasStudentsPermissionJson=$(curl -sX GET "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/roles/EDIT_EAS_STUDENT_PERMISSION" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TKN") + +echo +echo Creating EDIT_EAS_HISTORY_PERMISSION permission +curl -sX POST "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/roles" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TKN" \ + -d "{\"name\" : \"EDIT_EAS_HISTORY_PERMISSION\",\"description\" : \"Permission to edit EAS historical registrations\",\"composite\" : false,\"clientRole\" : false,\"containerId\" : \"$SOAM_KC_REALM_ID\"}" + +echo +echo Retrieving EDIT_EAS_HISTORY_PERMISSION permission +editEasHistoryPermissionJson=$(curl -sX GET "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/roles/EDIT_EAS_HISTORY_PERMISSION" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TKN") + echo echo Creating EAS_ADMIN role curl -sX POST "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/roles" \ @@ -577,7 +603,7 @@ echo Assigning permissions to EAS_ADMIN role curl -sX POST "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/roles/EAS_ADMIN/composites" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TKN" \ - -d "[$manageSessionsPermissionJson, $viewEasStudentsPermissionJson]" + -d "[$manageSessionsPermissionJson, $viewEasStudentsPermissionJson, $editEasStudentsPermissionJson, $editEasHistoryPermissionJson]" echo echo Retrieving client ID for student-admin-soam @@ -639,14 +665,14 @@ if [[ ("$studentAdminServiceClientSecret" != "" && "$studentAdminServiceClientSe curl -sX POST "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/clients" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TKN" \ - -d "{ \"clientId\" : \"student-admin-service\",\"secret\" : \"$studentAdminServiceClientSecret\", \"name\" : \"Student Admin Service Client\", \"description\" : \"Student admin user which logs into SOAM\", \"surrogateAuthRequired\" : false, \"enabled\" : true, \"clientAuthenticatorType\" : \"client-secret\", \"redirectUris\" : [ ], \"webOrigins\" : [ ], \"notBefore\" : 0, \"bearerOnly\" : false, \"consentRequired\" : false, \"standardFlowEnabled\" : false, \"implicitFlowEnabled\" : false, \"directAccessGrantsEnabled\" : false, \"serviceAccountsEnabled\" : true, \"publicClient\" : false, \"frontchannelLogout\" : false, \"protocol\" : \"openid-connect\", \"attributes\" : { \"saml.assertion.signature\" : \"false\", \"saml.multivalued.roles\" : \"false\", \"saml.force.post.binding\" : \"false\", \"saml.encrypt\" : \"false\", \"saml.server.signature\" : \"false\", \"saml.server.signature.keyinfo.ext\" : \"false\", \"exclude.session.state.from.auth.response\" : \"false\", \"saml_force_name_id_format\" : \"false\", \"saml.client.signature\" : \"false\", \"tls.client.certificate.bound.access.tokens\" : \"false\", \"saml.authnstatement\" : \"false\", \"display.on.consent.screen\" : \"false\", \"saml.onetimeuse.condition\" : \"false\" }, \"authenticationFlowBindingOverrides\" : { }, \"fullScopeAllowed\" : true, \"nodeReRegistrationTimeout\" : -1, \"protocolMappers\" : [ ], \"defaultClientScopes\" : [ \"web-origins\", \"role_list\", \"SEND_PEN_REQUEST_EMAIL\", \"WRITE_PEN_REQUEST\", \"profile\", \"roles\", \"email\", \"READ_PEN_REQUEST\", \"READ_PEN_REQUEST_STATUSES\", \"READ_PEN_DEMOGRAPHICS\", \"WRITE_DIGITALID\", \"READ_DIGITALID\", \"WRITE_STUDENT\", \"READ_STUDENT\", \"READ_STUDENT_CODES\", \"READ_DIGITALID_CODETABLE\", \"READ_DOCUMENT\", \"READ_DOCUMENT_TYPES\", \"WRITE_DOCUMENT\", \"READ_SDC_MINISTRY_REPORTS\", \"READ_STUDENT_PROFILE\", \"WRITE_STUDENT_PROFILE\", \"READ_DOCUMENT_STUDENT_PROFILE\", \"WRITE_DOCUMENT_STUDENT_PROFILE\", \"READ_DOCUMENT_TYPES_STUDENT_PROFILE\", \"READ_STUDENT_PROFILE_STATUSES\", \"READ_STUDENT_PROFILE_CODES\", \"SEND_STUDENT_PROFILE_EMAIL\",\"PEN_REQUEST_UNLINK_SAGA\",\"PEN_REQUEST_REJECT_SAGA\",\"READ_SECURE_EXCHANGE_DOCUMENT_REQUIREMENTS\", \"PEN_REQUEST_RETURN_SAGA\",\"PEN_REQUEST_COMPLETE_SAGA\",\"STUDENT_PROFILE_COMPLETE_SAGA\",\"STUDENT_PROFILE_REJECT_SAGA\",\"STUDENT_PROFILE_RETURN_SAGA\", \"READ_PEN_REQUEST_BATCH\", \"READ_PEN_MATCH\", \"WRITE_PEN_REQUEST_BATCH\", \"STUDENT_PROFILE_READ_SAGA\", \"GET_NEXT_PEN_NUMBER\", \"VALIDATE_STUDENT_DEMOGRAPHICS\",\"PEN_REQUEST_BATCH_NEW_PEN_SAGA\",\"PEN_REQUEST_BATCH_USER_MATCH_SAGA\",\"PEN_REQUEST_BATCH_READ_SAGA\", \"READ_VALIDATION_CODES\", \"READ_STUDENT_HISTORY\", \"READ_NICKNAMES\", \"READ_SCHOOL_FUNDING_GROUP_SNAPSHOT\", \"READ_SCHOOL\", \"READ_PEN_TRAX\", \"READ_SLD_STUDENT\",\"WRITE_POSSIBLE_MATCH\",\"DELETE_POSSIBLE_MATCH\",\"READ_POSSIBLE_MATCH\",\"READ_STUDENT_MERGE\" ,\"WRITE_STUDENT_MERGE\",\"READ_STUDENT_MERGE_CODES\",\"STUDENT_MERGE_COMPLETE_SAGA\",\"STUDENT_DEMERGE_COMPLETE_SAGA\",\"PEN_SERVICES_READ_SAGA\",\"READ_PEN_REQUEST_BATCH_BLOB\",\"STUDENT_SPLIT_PEN_SAGA\", \"PEN_REQUEST_BATCH_ARCHIVE_SAGA\", \"PEN_REQUEST_BATCH_REPOST_SAGA\", \"READ_PEN_COORDINATOR\", \"WRITE_PEN_COORDINATOR\", \"READ_PEN_MACRO\", \"WRITE_PEN_MACRO\", \"MACRO_READ_SAGA\",\"READ_PEN_REQUEST_STATS\", \"READ_STUDENT_PROFILE_STATS\", \"STUDENT_MOVE_SLD_SAGA\", \"NOMINAL_ROLL_READ_STUDENT\", \"NOMINAL_ROLL_WRITE_STUDENT\", \"NOMINAL_ROLL_DELETE_STUDENT\", \"NOMINAL_ROLL_UPLOAD_FILE\", \"NOMINAL_ROLL_VALIDATE\", \"NOMINAL_ROLL_POST_DATA_SAGA\", \"NOMINAL_ROLL_READ_SAGA\", \"READ_FED_PROV_CODE\", \"WRITE_FED_PROV_CODE\", \"NOMINAL_ROLL_CREATE_FED_PROV\", \"READ_SECURE_EXCHANGE\", \"WRITE_SECURE_EXCHANGE\", \"READ_SECURE_EXCHANGE_DOCUMENT\", \"WRITE_SECURE_EXCHANGE_DOCUMENT\", \"DELETE_SECURE_EXCHANGE_DOCUMENT\", \"READ_SECURE_EXCHANGE_CODES\", \"READ_SECURE_EXCHANGE_DOCUMENT_TYPES\", \"READ_SECURE_EXCHANGE_STATUSES\", \"READ_MINISTRY_TEAMS\", \"READ_EDX_USER_SCHOOLS\", \"DELETE_SECURE_EXCHANGE\", \"READ_EDX_USERS\", \"READ_PRIMARY_ACTIVATION_CODE\", \"WRITE_EDX_USER_SCHOOL\", \"WRITE_PRIMARY_ACTIVATION_CODE\", \"SCHOOL_USER_ACTIVATION_INVITE_SAGA\", \"CREATE_SECURE_EXCHANGE_SAGA\" , \"DELETE_EDX_USER_SCHOOL\", \"WRITE_EDX_USER_DISTRICT\", \"DELETE_EDX_USER_DISTRICT\", \"CREATE_SECURE_EXCHANGE_COMMENT_SAGA\", \"READ_DISTRICT\", \"WRITE_DISTRICT_CONTACT\", \"DISTRICT_USER_ACTIVATION_INVITE_SAGA\", \"DISTRICT_USER_ACTIVATION_INVITE_SAGA\", \"DELETE_SECURE_EXCHANGE_NOTE\", \"WRITE_SECURE_EXCHANGE_NOTE\", \"READ_SECURE_EXCHANGE_NOTE\", \"DELETE_SECURE_EXCHANGE_COMMENT\", \"WRITE_SECURE_EXCHANGE_COMMENT\", \"READ_SECURE_EXCHANGE_COMMENT\", \"DELETE_SECURE_EXCHANGE_STUDENT\", \"WRITE_SECURE_EXCHANGE_STUDENT\", \"READ_SECURE_EXCHANGE_STUDENT\", \"READ_INSTITUTE_CODES\", \"READ_INDEPENDENT_AUTHORITY\", \"WRITE_INDEPENDENT_AUTHORITY\", \"READ_SCHOOL_NOTE\", \"WRITE_SCHOOL_NOTE\", \"DELETE_SCHOOL_NOTE\", \"WRITE_SCHOOL_CONTACT\", \"WRITE_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_INDEPENDENT_AUTHORITY_NOTE\", \"DELETE_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_SCHOOL\", \"WRITE_DISTRICT\", \"READ_DISTRICT_NOTE\", \"WRITE_DISTRICT_NOTE\", \"DELETE_DISTRICT_NOTE\", \"READ_SCHOOL_HISTORY\",\"MOVE_SCHOOL_SAGA\", \"CREATE_SCHOOL_SAGA\", \"READ_SCHOOL_CONTACT\", \"READ_DISTRICT_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_SCHOOL_FUNDING_GROUP\", \"WRITE_SCHOOL_FUNDING_GROUP\", \"DELETE_SCHOOL_FUNDING_GROUP\", \"READ_SDC_COLLECTION\", \"READ_SDC_DISTRICT_COLLECTION\", \"READ_COLLECTION_CODES\", \"WRITE_COLLECTION_CODES\", \"WRITE_ACTIVATION_CODE\", \"READ_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_DISTRICT_COLLECTION\", \"WRITE_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_COLLECTION\", \"READ_EAS_SESSIONS\", \"WRITE_EAS_SESSIONS\", \"READ_EAS_STUDENT\"], \"optionalClientScopes\" : [ \"address\", \"phone\" ], \"access\" : { \"view\" : true, \"configure\" : true, \"manage\" : true } }" + -d "{ \"clientId\" : \"student-admin-service\",\"secret\" : \"$studentAdminServiceClientSecret\", \"name\" : \"Student Admin Service Client\", \"description\" : \"Student admin user which logs into SOAM\", \"surrogateAuthRequired\" : false, \"enabled\" : true, \"clientAuthenticatorType\" : \"client-secret\", \"redirectUris\" : [ ], \"webOrigins\" : [ ], \"notBefore\" : 0, \"bearerOnly\" : false, \"consentRequired\" : false, \"standardFlowEnabled\" : false, \"implicitFlowEnabled\" : false, \"directAccessGrantsEnabled\" : false, \"serviceAccountsEnabled\" : true, \"publicClient\" : false, \"frontchannelLogout\" : false, \"protocol\" : \"openid-connect\", \"attributes\" : { \"saml.assertion.signature\" : \"false\", \"saml.multivalued.roles\" : \"false\", \"saml.force.post.binding\" : \"false\", \"saml.encrypt\" : \"false\", \"saml.server.signature\" : \"false\", \"saml.server.signature.keyinfo.ext\" : \"false\", \"exclude.session.state.from.auth.response\" : \"false\", \"saml_force_name_id_format\" : \"false\", \"saml.client.signature\" : \"false\", \"tls.client.certificate.bound.access.tokens\" : \"false\", \"saml.authnstatement\" : \"false\", \"display.on.consent.screen\" : \"false\", \"saml.onetimeuse.condition\" : \"false\" }, \"authenticationFlowBindingOverrides\" : { }, \"fullScopeAllowed\" : true, \"nodeReRegistrationTimeout\" : -1, \"protocolMappers\" : [ ], \"defaultClientScopes\" : [ \"web-origins\", \"role_list\", \"SEND_PEN_REQUEST_EMAIL\", \"WRITE_PEN_REQUEST\", \"profile\", \"roles\", \"email\", \"READ_PEN_REQUEST\", \"READ_PEN_REQUEST_STATUSES\", \"READ_PEN_DEMOGRAPHICS\", \"WRITE_DIGITALID\", \"READ_DIGITALID\", \"WRITE_STUDENT\", \"READ_STUDENT\", \"READ_STUDENT_CODES\", \"READ_DIGITALID_CODETABLE\", \"READ_DOCUMENT\", \"READ_DOCUMENT_TYPES\", \"WRITE_DOCUMENT\", \"READ_SDC_MINISTRY_REPORTS\", \"READ_STUDENT_PROFILE\", \"WRITE_STUDENT_PROFILE\", \"READ_DOCUMENT_STUDENT_PROFILE\", \"WRITE_DOCUMENT_STUDENT_PROFILE\", \"READ_DOCUMENT_TYPES_STUDENT_PROFILE\", \"READ_STUDENT_PROFILE_STATUSES\", \"READ_STUDENT_PROFILE_CODES\", \"SEND_STUDENT_PROFILE_EMAIL\",\"PEN_REQUEST_UNLINK_SAGA\",\"PEN_REQUEST_REJECT_SAGA\",\"READ_SECURE_EXCHANGE_DOCUMENT_REQUIREMENTS\", \"PEN_REQUEST_RETURN_SAGA\",\"PEN_REQUEST_COMPLETE_SAGA\",\"STUDENT_PROFILE_COMPLETE_SAGA\",\"STUDENT_PROFILE_REJECT_SAGA\",\"STUDENT_PROFILE_RETURN_SAGA\", \"READ_PEN_REQUEST_BATCH\", \"READ_PEN_MATCH\", \"WRITE_PEN_REQUEST_BATCH\", \"STUDENT_PROFILE_READ_SAGA\", \"GET_NEXT_PEN_NUMBER\", \"VALIDATE_STUDENT_DEMOGRAPHICS\",\"PEN_REQUEST_BATCH_NEW_PEN_SAGA\",\"PEN_REQUEST_BATCH_USER_MATCH_SAGA\",\"PEN_REQUEST_BATCH_READ_SAGA\", \"READ_VALIDATION_CODES\", \"READ_STUDENT_HISTORY\", \"READ_NICKNAMES\", \"READ_SCHOOL_FUNDING_GROUP_SNAPSHOT\", \"READ_SCHOOL\", \"READ_PEN_TRAX\", \"READ_SLD_STUDENT\",\"WRITE_POSSIBLE_MATCH\",\"DELETE_POSSIBLE_MATCH\",\"READ_POSSIBLE_MATCH\",\"READ_STUDENT_MERGE\" ,\"WRITE_STUDENT_MERGE\",\"READ_STUDENT_MERGE_CODES\",\"STUDENT_MERGE_COMPLETE_SAGA\",\"STUDENT_DEMERGE_COMPLETE_SAGA\",\"PEN_SERVICES_READ_SAGA\",\"READ_PEN_REQUEST_BATCH_BLOB\",\"STUDENT_SPLIT_PEN_SAGA\", \"PEN_REQUEST_BATCH_ARCHIVE_SAGA\", \"PEN_REQUEST_BATCH_REPOST_SAGA\", \"READ_PEN_COORDINATOR\", \"WRITE_PEN_COORDINATOR\", \"READ_PEN_MACRO\", \"WRITE_PEN_MACRO\", \"MACRO_READ_SAGA\",\"READ_PEN_REQUEST_STATS\", \"READ_STUDENT_PROFILE_STATS\", \"STUDENT_MOVE_SLD_SAGA\", \"NOMINAL_ROLL_READ_STUDENT\", \"NOMINAL_ROLL_WRITE_STUDENT\", \"NOMINAL_ROLL_DELETE_STUDENT\", \"NOMINAL_ROLL_UPLOAD_FILE\", \"NOMINAL_ROLL_VALIDATE\", \"NOMINAL_ROLL_POST_DATA_SAGA\", \"NOMINAL_ROLL_READ_SAGA\", \"READ_FED_PROV_CODE\", \"WRITE_FED_PROV_CODE\", \"NOMINAL_ROLL_CREATE_FED_PROV\", \"READ_SECURE_EXCHANGE\", \"WRITE_SECURE_EXCHANGE\", \"READ_SECURE_EXCHANGE_DOCUMENT\", \"WRITE_SECURE_EXCHANGE_DOCUMENT\", \"DELETE_SECURE_EXCHANGE_DOCUMENT\", \"READ_SECURE_EXCHANGE_CODES\", \"READ_SECURE_EXCHANGE_DOCUMENT_TYPES\", \"READ_SECURE_EXCHANGE_STATUSES\", \"READ_MINISTRY_TEAMS\", \"READ_EDX_USER_SCHOOLS\", \"DELETE_SECURE_EXCHANGE\", \"READ_EDX_USERS\", \"READ_PRIMARY_ACTIVATION_CODE\", \"WRITE_EDX_USER_SCHOOL\", \"WRITE_PRIMARY_ACTIVATION_CODE\", \"SCHOOL_USER_ACTIVATION_INVITE_SAGA\", \"CREATE_SECURE_EXCHANGE_SAGA\" , \"DELETE_EDX_USER_SCHOOL\", \"WRITE_EDX_USER_DISTRICT\", \"DELETE_EDX_USER_DISTRICT\", \"CREATE_SECURE_EXCHANGE_COMMENT_SAGA\", \"READ_DISTRICT\", \"WRITE_DISTRICT_CONTACT\", \"DISTRICT_USER_ACTIVATION_INVITE_SAGA\", \"DISTRICT_USER_ACTIVATION_INVITE_SAGA\", \"DELETE_SECURE_EXCHANGE_NOTE\", \"WRITE_SECURE_EXCHANGE_NOTE\", \"READ_SECURE_EXCHANGE_NOTE\", \"DELETE_SECURE_EXCHANGE_COMMENT\", \"WRITE_SECURE_EXCHANGE_COMMENT\", \"READ_SECURE_EXCHANGE_COMMENT\", \"DELETE_SECURE_EXCHANGE_STUDENT\", \"WRITE_SECURE_EXCHANGE_STUDENT\", \"READ_SECURE_EXCHANGE_STUDENT\", \"READ_INSTITUTE_CODES\", \"READ_INDEPENDENT_AUTHORITY\", \"WRITE_INDEPENDENT_AUTHORITY\", \"READ_SCHOOL_NOTE\", \"WRITE_SCHOOL_NOTE\", \"DELETE_SCHOOL_NOTE\", \"WRITE_SCHOOL_CONTACT\", \"WRITE_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_INDEPENDENT_AUTHORITY_NOTE\", \"DELETE_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_SCHOOL\", \"WRITE_DISTRICT\", \"READ_DISTRICT_NOTE\", \"WRITE_DISTRICT_NOTE\", \"DELETE_DISTRICT_NOTE\", \"READ_SCHOOL_HISTORY\",\"MOVE_SCHOOL_SAGA\", \"CREATE_SCHOOL_SAGA\", \"READ_SCHOOL_CONTACT\", \"READ_DISTRICT_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_SCHOOL_FUNDING_GROUP\", \"WRITE_SCHOOL_FUNDING_GROUP\", \"DELETE_SCHOOL_FUNDING_GROUP\", \"READ_SDC_COLLECTION\", \"READ_SDC_DISTRICT_COLLECTION\", \"READ_COLLECTION_CODES\", \"WRITE_COLLECTION_CODES\", \"WRITE_ACTIVATION_CODE\", \"READ_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_DISTRICT_COLLECTION\", \"WRITE_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_COLLECTION\", \"READ_EAS_SESSIONS\", \"WRITE_EAS_SESSIONS\", \"READ_EAS_STUDENT\", \"WRITE_EAS_STUDENT\"], \"optionalClientScopes\" : [ \"address\", \"phone\" ], \"access\" : { \"view\" : true, \"configure\" : true, \"manage\" : true } }" else echo echo Creating client student-admin-service without secret curl -sX POST "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/clients" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TKN" \ - -d "{ \"clientId\" : \"student-admin-service\", \"name\" : \"Student Admin Service Client\", \"description\" : \"Student admin user which logs into SOAM\", \"surrogateAuthRequired\" : false, \"enabled\" : true, \"clientAuthenticatorType\" : \"client-secret\", \"redirectUris\" : [ ], \"webOrigins\" : [ ], \"notBefore\" : 0, \"bearerOnly\" : false, \"consentRequired\" : false, \"standardFlowEnabled\" : false, \"implicitFlowEnabled\" : false, \"directAccessGrantsEnabled\" : false, \"serviceAccountsEnabled\" : true, \"publicClient\" : false, \"frontchannelLogout\" : false, \"protocol\" : \"openid-connect\", \"attributes\" : { \"saml.assertion.signature\" : \"false\", \"saml.multivalued.roles\" : \"false\", \"saml.force.post.binding\" : \"false\", \"saml.encrypt\" : \"false\", \"saml.server.signature\" : \"false\", \"saml.server.signature.keyinfo.ext\" : \"false\", \"exclude.session.state.from.auth.response\" : \"false\", \"saml_force_name_id_format\" : \"false\", \"saml.client.signature\" : \"false\", \"tls.client.certificate.bound.access.tokens\" : \"false\", \"saml.authnstatement\" : \"false\", \"display.on.consent.screen\" : \"false\", \"saml.onetimeuse.condition\" : \"false\" }, \"authenticationFlowBindingOverrides\" : { }, \"fullScopeAllowed\" : true, \"nodeReRegistrationTimeout\" : -1, \"protocolMappers\" : [ ], \"defaultClientScopes\" : [ \"web-origins\", \"role_list\", \"SEND_PEN_REQUEST_EMAIL\", \"WRITE_PEN_REQUEST\", \"profile\", \"roles\", \"email\", \"READ_PEN_REQUEST\", \"READ_PEN_REQUEST_STATUSES\", \"READ_PEN_DEMOGRAPHICS\", \"WRITE_DIGITALID\", \"READ_DIGITALID\", \"WRITE_STUDENT\", \"READ_STUDENT\", \"READ_STUDENT_CODES\", \"READ_DIGITALID_CODETABLE\", \"READ_DOCUMENT\", \"READ_DOCUMENT_TYPES\", \"WRITE_DOCUMENT\", \"READ_STUDENT_PROFILE\", \"WRITE_STUDENT_PROFILE\", \"READ_SDC_MINISTRY_REPORTS\", \"READ_DOCUMENT_STUDENT_PROFILE\", \"WRITE_DOCUMENT_STUDENT_PROFILE\", \"READ_DOCUMENT_TYPES_STUDENT_PROFILE\", \"READ_STUDENT_PROFILE_STATUSES\", \"READ_STUDENT_PROFILE_CODES\", \"SEND_STUDENT_PROFILE_EMAIL\",\"PEN_REQUEST_UNLINK_SAGA\",\"PEN_REQUEST_REJECT_SAGA\",\"PEN_REQUEST_RETURN_SAGA\",\"PEN_REQUEST_COMPLETE_SAGA\",\"STUDENT_PROFILE_COMPLETE_SAGA\",\"READ_SECURE_EXCHANGE_DOCUMENT_REQUIREMENTS\",\"STUDENT_PROFILE_REJECT_SAGA\",\"STUDENT_PROFILE_RETURN_SAGA\", \"READ_PEN_REQUEST_BATCH\", \"READ_PEN_MATCH\", \"WRITE_PEN_REQUEST_BATCH\", \"STUDENT_PROFILE_READ_SAGA\", \"GET_NEXT_PEN_NUMBER\", \"VALIDATE_STUDENT_DEMOGRAPHICS\",\"PEN_REQUEST_BATCH_NEW_PEN_SAGA\",\"PEN_REQUEST_BATCH_USER_MATCH_SAGA\",\"PEN_REQUEST_BATCH_READ_SAGA\", \"READ_VALIDATION_CODES\", \"READ_STUDENT_HISTORY\", \"READ_NICKNAMES\", \"READ_SCHOOL_FUNDING_GROUP_SNAPSHOT\", \"READ_SCHOOL\", \"READ_PEN_TRAX\", \"READ_SLD_STUDENT\",\"WRITE_POSSIBLE_MATCH\",\"DELETE_POSSIBLE_MATCH\",\"READ_POSSIBLE_MATCH\",\"READ_STUDENT_MERGE\" ,\"WRITE_STUDENT_MERGE\",\"READ_STUDENT_MERGE_CODES\",\"STUDENT_MERGE_COMPLETE_SAGA\",\"STUDENT_DEMERGE_COMPLETE_SAGA\",\"PEN_SERVICES_READ_SAGA\",\"READ_PEN_REQUEST_BATCH_BLOB\",\"STUDENT_SPLIT_PEN_SAGA\", \"PEN_REQUEST_BATCH_ARCHIVE_SAGA\", \"PEN_REQUEST_BATCH_REPOST_SAGA\", \"READ_PEN_COORDINATOR\", \"WRITE_PEN_COORDINATOR\", \"READ_PEN_MACRO\", \"WRITE_PEN_MACRO\", \"MACRO_READ_SAGA\",\"READ_PEN_REQUEST_STATS\", \"READ_STUDENT_PROFILE_STATS\", \"STUDENT_MOVE_SLD_SAGA\", \"NOMINAL_ROLL_READ_STUDENT\", \"NOMINAL_ROLL_WRITE_STUDENT\", \"NOMINAL_ROLL_DELETE_STUDENT\", \"NOMINAL_ROLL_UPLOAD_FILE\", \"NOMINAL_ROLL_VALIDATE\", \"NOMINAL_ROLL_POST_DATA_SAGA\", \"NOMINAL_ROLL_READ_SAGA\", \"READ_FED_PROV_CODE\", \"WRITE_FED_PROV_CODE\", \"NOMINAL_ROLL_CREATE_FED_PROV\", \"READ_SECURE_EXCHANGE\", \"WRITE_SECURE_EXCHANGE\", \"READ_SECURE_EXCHANGE_DOCUMENT\", \"WRITE_SECURE_EXCHANGE_DOCUMENT\", \"DELETE_SECURE_EXCHANGE_DOCUMENT\", \"READ_SECURE_EXCHANGE_CODES\", \"READ_SECURE_EXCHANGE_DOCUMENT_TYPES\", \"READ_SECURE_EXCHANGE_STATUSES\", \"READ_MINISTRY_TEAMS\", \"READ_EDX_USER_SCHOOLS\", \"DELETE_SECURE_EXCHANGE\", \"READ_EDX_USERS\", \"READ_PRIMARY_ACTIVATION_CODE\", \"WRITE_PRIMARY_ACTIVATION_CODE\", \"WRITE_EDX_USER_SCHOOL\", \"SCHOOL_USER_ACTIVATION_INVITE_SAGA\", \"CREATE_SECURE_EXCHANGE_SAGA\", \"DELETE_EDX_USER_SCHOOL\", \"WRITE_EDX_USER_DISTRICT\", \"DELETE_EDX_USER_DISTRICT\", \"CREATE_SECURE_EXCHANGE_COMMENT_SAGA\", \"READ_DISTRICT\", \"WRITE_DISTRICT_CONTACT\", \"DISTRICT_USER_ACTIVATION_INVITE_SAGA\", \"DELETE_SECURE_EXCHANGE_NOTE\", \"WRITE_SECURE_EXCHANGE_NOTE\", \"READ_SECURE_EXCHANGE_NOTE\", \"DELETE_SECURE_EXCHANGE_COMMENT\", \"WRITE_SECURE_EXCHANGE_COMMENT\", \"READ_SECURE_EXCHANGE_COMMENT\", \"DELETE_SECURE_EXCHANGE_STUDENT\", \"WRITE_SECURE_EXCHANGE_STUDENT\", \"READ_SECURE_EXCHANGE_STUDENT\", \"READ_INSTITUTE_CODES\", \"READ_INDEPENDENT_AUTHORITY\", \"WRITE_INDEPENDENT_AUTHORITY\", \"READ_SCHOOL_NOTE\", \"WRITE_SCHOOL_NOTE\", \"DELETE_SCHOOL_NOTE\", \"WRITE_SCHOOL_CONTACT\", \"WRITE_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_INDEPENDENT_AUTHORITY_NOTE\", \"DELETE_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_SCHOOL\", \"WRITE_DISTRICT\", \"READ_DISTRICT_NOTE\", \"WRITE_DISTRICT_NOTE\", \"DELETE_DISTRICT_NOTE\", \"READ_SCHOOL_HISTORY\", \"MOVE_SCHOOL_SAGA\", \"CREATE_SCHOOL_SAGA\", \"READ_SCHOOL_CONTACT\", \"READ_DISTRICT_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_SCHOOL_FUNDING_GROUP\", \"WRITE_SCHOOL_FUNDING_GROUP\", \"DELETE_SCHOOL_FUNDING_GROUP\", \"READ_SDC_COLLECTION\", \"READ_SDC_DISTRICT_COLLECTION\", \"READ_COLLECTION_CODES\", \"WRITE_COLLECTION_CODES\", \"WRITE_SDC_DISTRICT_COLLECTION\", \"WRITE_ACTIVATION_CODE\", \"READ_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_COLLECTION\", \"READ_EAS_SESSIONS\", \"WRITE_EAS_SESSIONS\", \"READ_EAS_STUDENT\"], \"optionalClientScopes\" : [ \"address\", \"phone\" ], \"access\" : { \"view\" : true, \"configure\" : true, \"manage\" : true } }" + -d "{ \"clientId\" : \"student-admin-service\", \"name\" : \"Student Admin Service Client\", \"description\" : \"Student admin user which logs into SOAM\", \"surrogateAuthRequired\" : false, \"enabled\" : true, \"clientAuthenticatorType\" : \"client-secret\", \"redirectUris\" : [ ], \"webOrigins\" : [ ], \"notBefore\" : 0, \"bearerOnly\" : false, \"consentRequired\" : false, \"standardFlowEnabled\" : false, \"implicitFlowEnabled\" : false, \"directAccessGrantsEnabled\" : false, \"serviceAccountsEnabled\" : true, \"publicClient\" : false, \"frontchannelLogout\" : false, \"protocol\" : \"openid-connect\", \"attributes\" : { \"saml.assertion.signature\" : \"false\", \"saml.multivalued.roles\" : \"false\", \"saml.force.post.binding\" : \"false\", \"saml.encrypt\" : \"false\", \"saml.server.signature\" : \"false\", \"saml.server.signature.keyinfo.ext\" : \"false\", \"exclude.session.state.from.auth.response\" : \"false\", \"saml_force_name_id_format\" : \"false\", \"saml.client.signature\" : \"false\", \"tls.client.certificate.bound.access.tokens\" : \"false\", \"saml.authnstatement\" : \"false\", \"display.on.consent.screen\" : \"false\", \"saml.onetimeuse.condition\" : \"false\" }, \"authenticationFlowBindingOverrides\" : { }, \"fullScopeAllowed\" : true, \"nodeReRegistrationTimeout\" : -1, \"protocolMappers\" : [ ], \"defaultClientScopes\" : [ \"web-origins\", \"role_list\", \"SEND_PEN_REQUEST_EMAIL\", \"WRITE_PEN_REQUEST\", \"profile\", \"roles\", \"email\", \"READ_PEN_REQUEST\", \"READ_PEN_REQUEST_STATUSES\", \"READ_PEN_DEMOGRAPHICS\", \"WRITE_DIGITALID\", \"READ_DIGITALID\", \"WRITE_STUDENT\", \"READ_STUDENT\", \"READ_STUDENT_CODES\", \"READ_DIGITALID_CODETABLE\", \"READ_DOCUMENT\", \"READ_DOCUMENT_TYPES\", \"WRITE_DOCUMENT\", \"READ_STUDENT_PROFILE\", \"WRITE_STUDENT_PROFILE\", \"READ_SDC_MINISTRY_REPORTS\", \"READ_DOCUMENT_STUDENT_PROFILE\", \"WRITE_DOCUMENT_STUDENT_PROFILE\", \"READ_DOCUMENT_TYPES_STUDENT_PROFILE\", \"READ_STUDENT_PROFILE_STATUSES\", \"READ_STUDENT_PROFILE_CODES\", \"SEND_STUDENT_PROFILE_EMAIL\",\"PEN_REQUEST_UNLINK_SAGA\",\"PEN_REQUEST_REJECT_SAGA\",\"PEN_REQUEST_RETURN_SAGA\",\"PEN_REQUEST_COMPLETE_SAGA\",\"STUDENT_PROFILE_COMPLETE_SAGA\",\"READ_SECURE_EXCHANGE_DOCUMENT_REQUIREMENTS\",\"STUDENT_PROFILE_REJECT_SAGA\",\"STUDENT_PROFILE_RETURN_SAGA\", \"READ_PEN_REQUEST_BATCH\", \"READ_PEN_MATCH\", \"WRITE_PEN_REQUEST_BATCH\", \"STUDENT_PROFILE_READ_SAGA\", \"GET_NEXT_PEN_NUMBER\", \"VALIDATE_STUDENT_DEMOGRAPHICS\",\"PEN_REQUEST_BATCH_NEW_PEN_SAGA\",\"PEN_REQUEST_BATCH_USER_MATCH_SAGA\",\"PEN_REQUEST_BATCH_READ_SAGA\", \"READ_VALIDATION_CODES\", \"READ_STUDENT_HISTORY\", \"READ_NICKNAMES\", \"READ_SCHOOL_FUNDING_GROUP_SNAPSHOT\", \"READ_SCHOOL\", \"READ_PEN_TRAX\", \"READ_SLD_STUDENT\",\"WRITE_POSSIBLE_MATCH\",\"DELETE_POSSIBLE_MATCH\",\"READ_POSSIBLE_MATCH\",\"READ_STUDENT_MERGE\" ,\"WRITE_STUDENT_MERGE\",\"READ_STUDENT_MERGE_CODES\",\"STUDENT_MERGE_COMPLETE_SAGA\",\"STUDENT_DEMERGE_COMPLETE_SAGA\",\"PEN_SERVICES_READ_SAGA\",\"READ_PEN_REQUEST_BATCH_BLOB\",\"STUDENT_SPLIT_PEN_SAGA\", \"PEN_REQUEST_BATCH_ARCHIVE_SAGA\", \"PEN_REQUEST_BATCH_REPOST_SAGA\", \"READ_PEN_COORDINATOR\", \"WRITE_PEN_COORDINATOR\", \"READ_PEN_MACRO\", \"WRITE_PEN_MACRO\", \"MACRO_READ_SAGA\",\"READ_PEN_REQUEST_STATS\", \"READ_STUDENT_PROFILE_STATS\", \"STUDENT_MOVE_SLD_SAGA\", \"NOMINAL_ROLL_READ_STUDENT\", \"NOMINAL_ROLL_WRITE_STUDENT\", \"NOMINAL_ROLL_DELETE_STUDENT\", \"NOMINAL_ROLL_UPLOAD_FILE\", \"NOMINAL_ROLL_VALIDATE\", \"NOMINAL_ROLL_POST_DATA_SAGA\", \"NOMINAL_ROLL_READ_SAGA\", \"READ_FED_PROV_CODE\", \"WRITE_FED_PROV_CODE\", \"NOMINAL_ROLL_CREATE_FED_PROV\", \"READ_SECURE_EXCHANGE\", \"WRITE_SECURE_EXCHANGE\", \"READ_SECURE_EXCHANGE_DOCUMENT\", \"WRITE_SECURE_EXCHANGE_DOCUMENT\", \"DELETE_SECURE_EXCHANGE_DOCUMENT\", \"READ_SECURE_EXCHANGE_CODES\", \"READ_SECURE_EXCHANGE_DOCUMENT_TYPES\", \"READ_SECURE_EXCHANGE_STATUSES\", \"READ_MINISTRY_TEAMS\", \"READ_EDX_USER_SCHOOLS\", \"DELETE_SECURE_EXCHANGE\", \"READ_EDX_USERS\", \"READ_PRIMARY_ACTIVATION_CODE\", \"WRITE_PRIMARY_ACTIVATION_CODE\", \"WRITE_EDX_USER_SCHOOL\", \"SCHOOL_USER_ACTIVATION_INVITE_SAGA\", \"CREATE_SECURE_EXCHANGE_SAGA\", \"DELETE_EDX_USER_SCHOOL\", \"WRITE_EDX_USER_DISTRICT\", \"DELETE_EDX_USER_DISTRICT\", \"CREATE_SECURE_EXCHANGE_COMMENT_SAGA\", \"READ_DISTRICT\", \"WRITE_DISTRICT_CONTACT\", \"DISTRICT_USER_ACTIVATION_INVITE_SAGA\", \"DELETE_SECURE_EXCHANGE_NOTE\", \"WRITE_SECURE_EXCHANGE_NOTE\", \"READ_SECURE_EXCHANGE_NOTE\", \"DELETE_SECURE_EXCHANGE_COMMENT\", \"WRITE_SECURE_EXCHANGE_COMMENT\", \"READ_SECURE_EXCHANGE_COMMENT\", \"DELETE_SECURE_EXCHANGE_STUDENT\", \"WRITE_SECURE_EXCHANGE_STUDENT\", \"READ_SECURE_EXCHANGE_STUDENT\", \"READ_INSTITUTE_CODES\", \"READ_INDEPENDENT_AUTHORITY\", \"WRITE_INDEPENDENT_AUTHORITY\", \"READ_SCHOOL_NOTE\", \"WRITE_SCHOOL_NOTE\", \"DELETE_SCHOOL_NOTE\", \"WRITE_SCHOOL_CONTACT\", \"WRITE_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_INDEPENDENT_AUTHORITY_NOTE\", \"DELETE_INDEPENDENT_AUTHORITY_NOTE\", \"WRITE_SCHOOL\", \"WRITE_DISTRICT\", \"READ_DISTRICT_NOTE\", \"WRITE_DISTRICT_NOTE\", \"DELETE_DISTRICT_NOTE\", \"READ_SCHOOL_HISTORY\", \"MOVE_SCHOOL_SAGA\", \"CREATE_SCHOOL_SAGA\", \"READ_SCHOOL_CONTACT\", \"READ_DISTRICT_CONTACT\", \"READ_INDEPENDENT_AUTHORITY_CONTACT\", \"READ_SCHOOL_FUNDING_GROUP\", \"WRITE_SCHOOL_FUNDING_GROUP\", \"DELETE_SCHOOL_FUNDING_GROUP\", \"READ_SDC_COLLECTION\", \"READ_SDC_DISTRICT_COLLECTION\", \"READ_COLLECTION_CODES\", \"WRITE_COLLECTION_CODES\", \"WRITE_SDC_DISTRICT_COLLECTION\", \"WRITE_ACTIVATION_CODE\", \"READ_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_SCHOOL_COLLECTION_STUDENT\", \"WRITE_SDC_COLLECTION\", \"READ_EAS_SESSIONS\", \"WRITE_EAS_SESSIONS\", \"READ_EAS_STUDENT\", \"WRITE_EAS_STUDENT\"], \"optionalClientScopes\" : [ \"address\", \"phone\" ], \"access\" : { \"view\" : true, \"configure\" : true, \"manage\" : true } }" fi echo Fetching public key from SOAM