@Override public List<EnrollmentRequest> execute( OnlineSectioningServer server, OnlineSectioningHelper helper) { Lock readLock = server.readLock(); try { Set<Long> offeringIds = new HashSet<Long>(); for (ClassAssignmentInterface.ClassAssignment ca : getAssignment()) if (ca != null && !ca.isFreeTime()) { XCourse course = server.getCourse(ca.getCourseId()); if (course != null) offeringIds.add(course.getOfferingId()); } Lock lock = server.lockStudent(getStudentId(), offeringIds, name()); try { return check(server, helper); } finally { lock.release(); } } finally { readLock.release(); } }
public static GwtRpcResponseList<ClassAssignmentInterface.Enrollment> convert( Collection<StudentClassEnrollment> enrollments, Map<Long, List<Meeting>> conflicts, boolean canShowExtId, boolean canRegister, boolean canUseAssistant) { GwtRpcResponseList<ClassAssignmentInterface.Enrollment> converted = new GwtRpcResponseList<ClassAssignmentInterface.Enrollment>(); Map<String, String> approvedBy2name = new Hashtable<String, String>(); Hashtable<Long, ClassAssignmentInterface.Enrollment> student2enrollment = new Hashtable<Long, ClassAssignmentInterface.Enrollment>(); for (StudentClassEnrollment enrollment : enrollments) { ClassAssignmentInterface.Enrollment enrl = student2enrollment.get(enrollment.getStudent().getUniqueId()); if (enrl == null) { ClassAssignmentInterface.Student st = new ClassAssignmentInterface.Student(); st.setId(enrollment.getStudent().getUniqueId()); st.setExternalId(enrollment.getStudent().getExternalUniqueId()); st.setCanShowExternalId(canShowExtId); st.setCanRegister(canRegister); st.setCanUseAssistant(canUseAssistant); st.setName( enrollment .getStudent() .getName(ApplicationProperty.OnlineSchedulingStudentNameFormat.value())); for (AcademicAreaClassification ac : enrollment.getStudent().getAcademicAreaClassifications()) { st.addArea(ac.getAcademicArea().getAcademicAreaAbbreviation()); st.addClassification(ac.getAcademicClassification().getCode()); } for (PosMajor m : enrollment.getStudent().getPosMajors()) { st.addMajor(m.getCode()); } for (StudentGroup g : enrollment.getStudent().getGroups()) { st.addGroup(g.getGroupAbbreviation()); } for (StudentAccomodation a : enrollment.getStudent().getAccomodations()) { st.addAccommodation(a.getAbbreviation()); } enrl = new ClassAssignmentInterface.Enrollment(); enrl.setStudent(st); enrl.setEnrolledDate(enrollment.getTimestamp()); CourseAssignment c = new CourseAssignment(); c.setCourseId(enrollment.getCourseOffering().getUniqueId()); c.setSubject(enrollment.getCourseOffering().getSubjectAreaAbbv()); c.setCourseNbr(enrollment.getCourseOffering().getCourseNbr()); enrl.setCourse(c); student2enrollment.put(enrollment.getStudent().getUniqueId(), enrl); if (enrollment.getCourseRequest() != null) { enrl.setPriority(1 + enrollment.getCourseRequest().getCourseDemand().getPriority()); if (enrollment.getCourseRequest().getCourseDemand().getCourseRequests().size() > 1) { CourseRequest first = null; for (CourseRequest r : enrollment.getCourseRequest().getCourseDemand().getCourseRequests()) { if (first == null || r.getOrder().compareTo(first.getOrder()) < 0) first = r; } if (!first.equals(enrollment.getCourseRequest())) enrl.setAlternative(first.getCourseOffering().getCourseName()); } if (enrollment.getCourseRequest().getCourseDemand().isAlternative()) { CourseDemand first = enrollment.getCourseRequest().getCourseDemand(); demands: for (CourseDemand cd : enrollment.getStudent().getCourseDemands()) { if (!cd.isAlternative() && cd.getPriority().compareTo(first.getPriority()) < 0 && !cd.getCourseRequests().isEmpty()) { for (CourseRequest cr : cd.getCourseRequests()) if (cr.getClassEnrollments().isEmpty()) continue demands; first = cd; } } CourseRequest alt = null; for (CourseRequest r : first.getCourseRequests()) { if (alt == null || r.getOrder().compareTo(alt.getOrder()) < 0) alt = r; } enrl.setAlternative(alt.getCourseOffering().getCourseName()); } enrl.setRequestedDate(enrollment.getCourseRequest().getCourseDemand().getTimestamp()); enrl.setApprovedDate(enrollment.getApprovedDate()); if (enrollment.getApprovedBy() != null) { String name = approvedBy2name.get(enrollment.getApprovedBy()); if (name == null) { TimetableManager mgr = (TimetableManager) EventDAO.getInstance() .getSession() .createQuery("from TimetableManager where externalUniqueId = :externalId") .setString("externalId", enrollment.getApprovedBy()) .setMaxResults(1) .uniqueResult(); if (mgr != null) { name = mgr.getName(); } else { DepartmentalInstructor instr = (DepartmentalInstructor) EventDAO.getInstance() .getSession() .createQuery( "from DepartmentalInstructor where externalUniqueId = :externalId and department.session.uniqueId = :sessionId") .setString("externalId", enrollment.getApprovedBy()) .setLong( "sessionId", enrollment.getStudent().getSession().getUniqueId()) .setMaxResults(1) .uniqueResult(); if (instr != null) name = instr.nameLastNameFirst(); } if (name != null) approvedBy2name.put(enrollment.getApprovedBy(), name); } enrl.setApprovedBy(name == null ? enrollment.getApprovedBy() : name); } } else { enrl.setPriority(-1); } List<Meeting> conf = (conflicts == null ? null : conflicts.get(enrollment.getStudent().getUniqueId())); if (conf != null) { Map<Event, TreeSet<Meeting>> events = new HashMap<Event, TreeSet<Meeting>>(); for (Meeting m : conf) { TreeSet<Meeting> ms = events.get(m.getEvent()); if (ms == null) { ms = new TreeSet<Meeting>(); events.put(m.getEvent(), ms); } ms.add(m); } for (Event confEvent : new TreeSet<Event>(events.keySet())) { Conflict conflict = new Conflict(); conflict.setName(confEvent.getEventName()); conflict.setType(confEvent.getEventTypeAbbv()); String lastDate = null, lastTime = null, lastRoom = null; for (MultiMeeting mm : Event.getMultiMeetings(events.get(confEvent))) { String date = getDateFormat().format(mm.getMeetings().first().getMeetingDate()) + (mm.getMeetings().size() == 1 ? "" : " - " + getDateFormat().format(mm.getMeetings().last().getMeetingDate())); if (lastDate == null) { conflict.setDate(date); } else if (lastDate.equals(date)) { conflict.setDate(conflict.getDate() + "<br>"); } else { conflict.setDate(conflict.getDate() + "<br>" + date); } lastDate = date; String time = mm.getDays(CONSTANTS.days(), CONSTANTS.shortDays()) + " " + (mm.getMeetings().first().isAllDay() ? "All Day" : mm.getMeetings().first().startTime() + " - " + mm.getMeetings().first().stopTime()); if (lastTime == null) { conflict.setTime(time); } else if (lastTime.equals(time)) { conflict.setTime(conflict.getTime() + "<br>"); } else { conflict.setTime(conflict.getTime() + "<br>" + time); } lastTime = time; String room = (mm.getMeetings().first().getLocation() == null ? "" : mm.getMeetings().first().getLocation().getLabel()); if (lastRoom == null) { conflict.setRoom(room); } else if (lastRoom.equals(room)) { conflict.setRoom(conflict.getRoom() + "<br>"); } else { conflict.setRoom(conflict.getRoom() + "<br>" + room); } lastRoom = room; } enrl.addConflict(conflict); } } converted.add(enrl); } ClassAssignmentInterface.ClassAssignment c = enrl.getCourse().addClassAssignment(); c.setClassId(enrollment.getClazz().getUniqueId()); c.setSection(enrollment.getClazz().getClassSuffix(enrollment.getCourseOffering())); if (c.getSection() == null) c.setSection(enrollment.getClazz().getSectionNumberString()); c.setClassNumber(enrollment.getClazz().getSectionNumberString()); c.setSubpart(enrollment.getClazz().getSchedulingSubpart().getItypeDesc()); } return converted; }
public List<EnrollmentRequest> check( OnlineSectioningServer server, OnlineSectioningHelper helper) { XStudent student = server.getStudent(getStudentId()); if (student == null) throw new SectioningException(MSG.exceptionBadStudentId()); List<EnrollmentRequest> requests = new ArrayList<EnrollmentRequest>(); Hashtable<Long, EnrollmentRequest> courseId2request = new Hashtable<Long, EnrollmentRequest>(); Hashtable<Long, XOffering> courseId2offering = new Hashtable<Long, XOffering>(); for (ClassAssignmentInterface.ClassAssignment ca : getAssignment()) { // Skip free times and dummy sections if (ca == null || ca.isFreeTime() || ca.getClassId() == null || ca.isDummy()) continue; XCourse course = server.getCourse(ca.getCourseId()); if (course == null) throw new SectioningException( MSG.exceptionCourseDoesNotExist(MSG.courseName(ca.getSubject(), ca.getClassNumber()))); XOffering offering = server.getOffering(course.getOfferingId()); if (offering == null) throw new SectioningException( MSG.exceptionCourseDoesNotExist(MSG.courseName(ca.getSubject(), ca.getClassNumber()))); // Check section limits XSection section = offering.getSection(ca.getClassId()); if (section == null) throw new SectioningException( MSG.exceptionEnrollNotAvailable( MSG.clazz(ca.getSubject(), ca.getCourseNbr(), ca.getSubpart(), ca.getSection()))); // Check cancelled flag if (section.isCancelled()) { if (server.getConfig().getPropertyBoolean("Enrollment.CanKeepCancelledClass", false)) { boolean contains = false; for (XRequest r : student.getRequests()) if (r instanceof XCourseRequest) { XCourseRequest cr = (XCourseRequest) r; if (cr.getEnrollment() != null && cr.getEnrollment().getSectionIds().contains(section.getSectionId())) { contains = true; break; } } if (!contains) throw new SectioningException( MSG.exceptionEnrollCancelled( MSG.clazz( ca.getSubject(), ca.getCourseNbr(), ca.getSubpart(), ca.getSection()))); } else { throw new SectioningException( MSG.exceptionEnrollCancelled( MSG.clazz(ca.getSubject(), ca.getCourseNbr(), ca.getSubpart(), ca.getSection()))); } } EnrollmentRequest request = courseId2request.get(ca.getCourseId()); if (request == null) { request = new EnrollmentRequest(course, new ArrayList<XSection>()); courseId2request.put(ca.getCourseId(), request); requests.add(request); } request.getSections().add(section); courseId2offering.put(course.getCourseId(), offering); } // Check for NEW and CHANGE deadlines check: for (EnrollmentRequest request : requests) { XCourse course = request.getCourse(); List<XSection> sections = request.getSections(); for (XRequest r : student.getRequests()) { if (r instanceof XCourseRequest) { XEnrollment enrollment = ((XCourseRequest) r).getEnrollment(); if (enrollment != null && enrollment.getCourseId().equals(course.getCourseId())) { // course change for (XSection s : sections) if (!enrollment.getSectionIds().contains(s.getSectionId()) && !server.checkDeadline( course.getCourseId(), s.getTime(), OnlineSectioningServer.Deadline.CHANGE)) throw new SectioningException( MSG.exceptionEnrollDeadlineChange( MSG.clazz( course.getSubjectArea(), course.getCourseNumber(), s.getSubpartName(), s.getName(course.getCourseId())))); continue check; } } } // new course for (XSection section : sections) { if (!server.checkDeadline( course.getOfferingId(), section.getTime(), OnlineSectioningServer.Deadline.NEW)) throw new SectioningException( MSG.exceptionEnrollDeadlineNew( MSG.clazz( course.getSubjectArea(), course.getCourseNumber(), section.getSubpartName(), section.getName(course.getCourseId())))); } } // Check for DROP deadlines for (XRequest r : student.getRequests()) { if (r instanceof XCourseRequest) { XEnrollment enrollment = ((XCourseRequest) r).getEnrollment(); if (enrollment != null && !courseId2offering.containsKey(enrollment.getCourseId())) { XOffering offering = server.getOffering(enrollment.getOfferingId()); if (offering != null) for (XSection section : offering.getSections(enrollment)) { if (!server.checkDeadline( offering.getOfferingId(), section.getTime(), OnlineSectioningServer.Deadline.DROP)) throw new SectioningException( MSG.exceptionEnrollDeadlineDrop(enrollment.getCourseName())); } } } } Hashtable<Long, XConfig> courseId2config = new Hashtable<Long, XConfig>(); for (EnrollmentRequest request : requests) { XCourse course = request.getCourse(); XOffering offering = courseId2offering.get(course.getCourseId()); XEnrollments enrollments = server.getEnrollments(course.getOfferingId()); List<XSection> sections = request.getSections(); XSubpart subpart = offering.getSubpart(sections.get(0).getSubpartId()); XConfig config = offering.getConfig(subpart.getConfigId()); courseId2config.put(course.getCourseId(), config); XReservation reservation = null; reservations: for (XReservation r : offering.getReservations()) { if (!r.isApplicable(student)) continue; if (r.getLimit() >= 0 && r.getLimit() <= enrollments.countEnrollmentsForReservation(r.getReservationId())) { boolean contain = false; for (XEnrollment e : enrollments.getEnrollmentsForReservation(r.getReservationId())) if (e.getStudentId().equals(student.getStudentId())) { contain = true; break; } if (!contain) continue; } if (!r.getConfigsIds().isEmpty() && !r.getConfigsIds().contains(config.getConfigId())) continue; for (XSection section : sections) if (r.getSectionIds(section.getSubpartId()) != null && !r.getSectionIds(section.getSubpartId()).contains(section.getSectionId())) continue reservations; if (reservation == null || r.compareTo(reservation) < 0) reservation = r; } if (reservation == null || !reservation.canAssignOverLimit()) { for (XSection section : sections) { if (section.getLimit() >= 0 && section.getLimit() <= enrollments.countEnrollmentsForSection(section.getSectionId())) { boolean contain = false; for (XEnrollment e : enrollments.getEnrollmentsForSection(section.getSectionId())) if (e.getStudentId().equals(student.getStudentId())) { contain = true; break; } if (!contain) throw new SectioningException( MSG.exceptionEnrollNotAvailable( MSG.clazz( course.getSubjectArea(), course.getCourseNumber(), section.getSubpartName(), section.getName()))); } if ((reservation == null || !offering.getSectionReservations(section.getSectionId()).contains(reservation)) && offering.getUnreservedSectionSpace(section.getSectionId(), enrollments) <= 0) { boolean contain = false; for (XEnrollment e : enrollments.getEnrollmentsForSection(section.getSectionId())) if (e.getStudentId().equals(student.getStudentId())) { contain = true; break; } if (!contain) throw new SectioningException( MSG.exceptionEnrollNotAvailable( MSG.clazz( course.getSubjectArea(), course.getCourseNumber(), section.getSubpartName(), section.getName()))); } } if (config.getLimit() >= 0 && config.getLimit() <= enrollments.countEnrollmentsForConfig(config.getConfigId())) { boolean contain = false; for (XEnrollment e : enrollments.getEnrollmentsForConfig(config.getConfigId())) if (e.getStudentId().equals(student.getStudentId())) { contain = true; break; } if (!contain) throw new SectioningException( MSG.exceptionEnrollNotAvailable( MSG.courseName(course.getSubjectArea(), course.getCourseNumber())) + " " + config.getName()); } if ((reservation == null || !offering.getConfigReservations(config.getConfigId()).contains(reservation)) && offering.getUnreservedConfigSpace(config.getConfigId(), enrollments) <= 0) { boolean contain = false; for (XEnrollment e : enrollments.getEnrollmentsForConfig(config.getConfigId())) if (e.getStudentId().equals(student.getStudentId())) { contain = true; break; } if (!contain) throw new SectioningException( MSG.exceptionEnrollNotAvailable( MSG.courseName(course.getSubjectArea(), course.getCourseNumber())) + " " + config.getName()); } if (course.getLimit() >= 0 && course.getLimit() <= enrollments.countEnrollmentsForCourse(course.getCourseId())) { boolean contain = false; for (XEnrollment e : enrollments.getEnrollmentsForCourse(course.getCourseId())) if (e.getStudentId().equals(student.getStudentId())) { contain = true; break; } if (!contain) throw new SectioningException( MSG.exceptionEnrollNotAvailable( MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))); } } } for (EnrollmentRequest request : requests) { XCourse course = request.getCourse(); XOffering offering = courseId2offering.get(course.getCourseId()); List<XSection> sections = request.getSections(); XSubpart subpart = offering.getSubpart(sections.get(0).getSubpartId()); XConfig config = offering.getConfig(subpart.getConfigId()); if (sections.size() < config.getSubparts().size()) { throw new SectioningException( MSG.exceptionEnrollmentIncomplete( MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))); } else if (sections.size() > config.getSubparts().size()) { throw new SectioningException( MSG.exceptionEnrollmentInvalid( MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))); } for (XSection s1 : sections) { for (XSection s2 : sections) { if (s1.getSectionId() < s2.getSectionId() && s1.isOverlapping(offering.getDistributions(), s2)) { throw new SectioningException( MSG.exceptionEnrollmentOverlapping( MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))); } if (!s1.getSectionId().equals(s2.getSectionId()) && s1.getSubpartId().equals(s2.getSubpartId())) { throw new SectioningException( MSG.exceptionEnrollmentInvalid( MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))); } } if (!offering.getSubpart(s1.getSubpartId()).getConfigId().equals(config.getConfigId())) { throw new SectioningException( MSG.exceptionEnrollmentInvalid( MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))); } } if (!offering.isAllowOverlap(student, config.getConfigId(), sections)) for (EnrollmentRequest otherRequest : requests) { XOffering other = courseId2offering.get(otherRequest.getCourse().getCourseId()); XConfig otherConfig = courseId2config.get(otherRequest.getCourse().getCourseId()); if (!other.equals(offering) && !other.isAllowOverlap( student, otherConfig.getConfigId(), otherRequest.getSections())) { List<XSection> assignment = otherRequest.getSections(); for (XSection section : sections) if (section.isOverlapping(offering.getDistributions(), assignment)) throw new SectioningException( MSG.exceptionEnrollmentConflicting( MSG.courseName(course.getSubjectArea(), course.getCourseNumber()))); } } } return requests; }