private FacultyCourse getCourse(ModelMap model, SearchFacultyCourseTO searchFacultyCourseTO) { if (searchFacultyCourseTO.hasCourseIdentification()) { FacultyCourse course = null; try { course = facultyCourseService.getCourseBySearchFacultyCourseTO(searchFacultyCourseTO); } catch (ObjectNotFoundException e) { throw new EarlyAlertPortletControllerRuntimeException( buildErrorMesssage( "Course not found or user not listed as faculty for course.", searchFacultyCourseTO.getFacultySchoolId(), null, null, searchFacultyCourseTO.getFormattedCourse(), searchFacultyCourseTO.getTermCode(), searchFacultyCourseTO.getSectionCode())); } if (course == null) { throw new EarlyAlertPortletControllerRuntimeException( buildErrorMesssage( "Course not found or user not listed as faculty for course.", searchFacultyCourseTO.getFacultySchoolId(), null, null, searchFacultyCourseTO.getFormattedCourse(), searchFacultyCourseTO.getTermCode(), searchFacultyCourseTO.getSectionCode())); } return course; } return null; }
@RenderMapping(params = "action=enterAlert") public ModelAndView showForm( final PortletRequest req, @RequestParam(required = false) final String schoolId, @RequestParam(required = false) final String formattedCourse, @RequestParam(required = false) final String studentUserName, @RequestParam(required = false) final String sectionCode, @RequestParam(required = false) final String termCode, ModelMap model) { // Do not use a @ModelAttribute-annotated argument to get the user // out of the model b/c Spring will attempt to set properties on it // by matching up request param names. This will overwrite user.schoolId // with the method param of that name, effectively copying the student's // school ID into the faculty user's record. if (!StringUtils.isNotBlank(schoolId) && !StringUtils.isNotBlank(studentUserName)) { throw new EarlyAlertPortletControllerRuntimeException("Missing student identifier."); } if (!StringUtils.isNotBlank(formattedCourse) && !StringUtils.isNotBlank(sectionCode)) { throw new EarlyAlertPortletControllerRuntimeException("Missing course identifier/s."); } Person user = (Person) model.get("user"); if (user == null) { throw new EarlyAlertPortletControllerRuntimeException( "Missing or deactivated account for current user."); } FacultyCourse course = null; Person student = null; ExternalFacultyCourseRoster enrollment = null; try { // Should really always have a term code (see deprecation notes for // getCourseByFacultySchoolIdAndFormattedCourse) but we know at // least one real-world deployment (SPC) cannot/does not send term // codes when deep linking to the EA form *and* this just happens to // work b/c their formattedCourse values are globally unique. So // we preserve the option of not filtering by term code. course = facultyCourseService.getCourseBySearchFacultyCourseTO( new SearchFacultyCourseTO( user.getSchoolId(), termCode, sectionCode, formattedCourse)); if (course == null) { throw new EarlyAlertPortletControllerRuntimeException( buildErrorMesssage( "Course not found or current user is not listed as the instructor of record:", user.getSchoolId(), schoolId, studentUserName, formattedCourse, termCode, sectionCode)); } /* * NB: It's on us to translate from schoolId <-> studentId (SSP * UUID) at this point in the Early Alert process. Previous APIs * user the former where following APIs use the later. */ if (StringUtils.isNotBlank(schoolId)) { try { student = personService.getBySchoolId(schoolId, true); // TODO: Handle error better?? if (student == null) { throw new EarlyAlertPortletControllerRuntimeException( "Student not found by school ID: " + schoolId); } } catch (ObjectNotFoundException e) { throw new EarlyAlertPortletControllerRuntimeException( "Student not found by school ID: " + schoolId, e); } } else { try { student = personService.getByUsername(studentUserName, true); if (student == null) { throw new EarlyAlertPortletControllerRuntimeException( "Student not found by username: "******"Student not found by username: "******"Selected student has no school ID. Username: "******"Enrollment not found for: ", user.getSchoolId(), student.getSchoolId(), student.getUsername(), formattedCourse, termCode, sectionCode)); } } catch (EarlyAlertPortletControllerRuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException( buildErrorMesssage( "System error looking up course or enrollment for: ", user.getSchoolId(), student == null ? schoolId : student.getSchoolId(), student == null ? studentUserName : student.getUsername(), formattedCourse, termCode, sectionCode), e); } /* * SANITY CHECK (is this even necessary? wanted?) * - Confirm that the logged in user is the faculty of record on the * course */ if (!course.getFacultySchoolId().equals(user.getSchoolId())) { throw new EarlyAlertPortletControllerRuntimeException( buildErrorMesssage( "Current user is not listed as the instructor of record on the specified course: ", user.getSchoolId(), student.getSchoolId(), student.getUsername(), formattedCourse, termCode, sectionCode)); } EarlyAlertSearchForm form = new EarlyAlertSearchForm(); form.setAuthor(user); form.setStudent(student); form.setSortAndPage(buildSortAndPage(-1, 0)); PagedResponse<EarlyAlertSearchResultTO> results = earlyAlertService.searchEarlyAlert(form); model.put(KEY_STUDENT_ID, student.getId()); // Student UUID model.put(KEY_COURSE, course); model.put(KEY_ENROLLMENT, enrollment); model.put(KEY_EARLY_ALERT_RESULTS, results.getRows()); try { Term term = termService.getByCode(course.getTermCode()); model.put(KEY_COURSE_TERM_NAME, term.getName()); } catch (Exception exp) { model.put(KEY_COURSE_TERM_NAME, course.getTermCode()); } return new ModelAndView("ea-form", model); }
@Override public Map<String, Object> fillTemplateParameters(@NotNull final EarlyAlert earlyAlert) { if (earlyAlert == null) { throw new IllegalArgumentException("EarlyAlert was missing."); } if (earlyAlert.getPerson() == null) { throw new IllegalArgumentException("EarlyAlert.Person is missing."); } if (earlyAlert.getCreatedBy() == null) { throw new IllegalArgumentException("EarlyAlert.CreatedBy is missing."); } if (earlyAlert.getCampus() == null) { throw new IllegalArgumentException("EarlyAlert.Campus is missing."); } // ensure earlyAlert.createdBy is populated if ((earlyAlert.getCreatedBy().getFirstName() == null) || (earlyAlert.getCreatedBy().getLastName() == null)) { if (earlyAlert.getCreatedBy().getId() == null) { throw new IllegalArgumentException("EarlyAlert.CreatedBy.Id is missing."); } try { earlyAlert.setCreatedBy(personService.get(earlyAlert.getCreatedBy().getId())); } catch (final ObjectNotFoundException e) { throw new IllegalArgumentException("EarlyAlert.CreatedBy.Id could not be loaded.", e); } } final Map<String, Object> templateParameters = Maps.newHashMap(); final String courseName = earlyAlert.getCourseName(); if (StringUtils.isNotBlank(courseName)) { final String facultySchoolId = earlyAlert.getCreatedBy().getSchoolId(); if ((StringUtils.isNotBlank(facultySchoolId))) { String termCode = earlyAlert.getCourseTermCode(); FacultyCourse course = null; try { if (StringUtils.isBlank(termCode)) { course = facultyCourseService.getCourseByFacultySchoolIdAndFormattedCourse( facultySchoolId, courseName); } else { course = facultyCourseService.getCourseByFacultySchoolIdAndFormattedCourseAndTermCode( facultySchoolId, courseName, termCode); } } catch (ObjectNotFoundException e) { // Trace irrelevant. see below for logging. prefer to // do it there, after the null check b/c not all service // methods implement ObjectNotFoundException reliably. } if (course != null) { templateParameters.put("course", course); if (StringUtils.isBlank(termCode)) { termCode = course.getTermCode(); } if (StringUtils.isNotBlank(termCode)) { Term term = null; try { term = termService.getByCode(termCode); } catch (ObjectNotFoundException e) { // Trace irrelevant. See below for logging. } if (term != null) { templateParameters.put("term", term); } else { LOGGER.info( "Not adding term to message template" + " params or early alert {} because" + " the term code {} did not resolve to" + " an external term record", earlyAlert.getId(), termCode); } } } else { LOGGER.info( "Not adding course nor term to message template" + " params for early alert {} because the associated" + " course {} and faculty school id {} did not" + " resolve to an external course record.", new Object[] {earlyAlert.getId(), courseName, facultySchoolId}); } } } templateParameters.put("earlyAlert", earlyAlert); templateParameters.put( "termToRepresentEarlyAlert", configService.getByNameEmpty("term_to_represent_early_alert")); templateParameters.put("linkToSSP", configService.getByNameEmpty("serverExternalPath")); templateParameters.put("applicationTitle", configService.getByNameEmpty("app_title")); templateParameters.put("institutionName", configService.getByNameEmpty("inst_name")); return templateParameters; }