diff --git a/JavaSource/org/unitime/timetable/api/AbstractApiHelper.java b/JavaSource/org/unitime/timetable/api/AbstractApiHelper.java index 1cd483e9cd..5eff008b6d 100644 --- a/JavaSource/org/unitime/timetable/api/AbstractApiHelper.java +++ b/JavaSource/org/unitime/timetable/api/AbstractApiHelper.java @@ -124,4 +124,85 @@ public org.hibernate.Session getHibSession() { @Override public void close() {} + + @Override + public String getOptinalParameter(String name, String defaultValue) { + String ret = getParameter(name); + return (ret != null ? ret : defaultValue); + } + + @Override + public String getRequiredParameter(String name) { + String ret = getParameter(name); + if (ret == null) + throw new IllegalArgumentException("Parameter '" + name + "' was not provided."); + return ret; + } + + @Override + public Integer getOptinalParameterInteger(String name, Integer defaultValue) { + String ret = getParameter(name); + if (ret != null) { + try { + return Integer.valueOf(ret); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Parameter '" + name + "' must be an integer."); + } + } + return defaultValue; + } + + @Override + public Integer getRequiredParameterInteger(String name) { + String ret = getParameter(name); + if (ret == null) + throw new IllegalArgumentException("Parameter '" + name + "' was not provided."); + try { + return Integer.valueOf(ret); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Parameter '" + name + "' must be an integer."); + } + } + + @Override + public Long getOptinalParameterLong(String name, Long defaultValue) { + String ret = getParameter(name); + if (ret != null) { + try { + return Long.valueOf(ret); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Parameter '" + name + "' must be a long."); + } + } + return defaultValue; + } + + @Override + public Long getRequiredParameterLong(String name) { + String ret = getParameter(name); + if (ret == null) + throw new IllegalArgumentException("Parameter '" + name + "' was not provided."); + try { + return Long.valueOf(ret); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Parameter '" + name + "' must be a long."); + } + } + + @Override + public Boolean getOptinalParameterBoolean(String name, Boolean defaultValue) { + String ret = getParameter(name); + if (ret != null) { + return "true".equalsIgnoreCase(ret) || "1".equalsIgnoreCase(ret); + } + return defaultValue; + } + + @Override + public Boolean getRequiredParameterBoolean(String name) { + String ret = getParameter(name); + if (ret == null) + throw new IllegalArgumentException("Parameter '" + name + "' was not provided."); + return "true".equalsIgnoreCase(ret) || "1".equalsIgnoreCase(ret); + } } diff --git a/JavaSource/org/unitime/timetable/api/ApiHelper.java b/JavaSource/org/unitime/timetable/api/ApiHelper.java index 90bad677f3..6c1eaecd8a 100644 --- a/JavaSource/org/unitime/timetable/api/ApiHelper.java +++ b/JavaSource/org/unitime/timetable/api/ApiHelper.java @@ -50,4 +50,20 @@ public interface ApiHelper { public org.hibernate.Session getHibSession(); public void close(); + + public String getOptinalParameter(String name, String defaultValue); + + public String getRequiredParameter(String name); + + public Integer getOptinalParameterInteger(String name, Integer defaultValue); + + public Integer getRequiredParameterInteger(String name); + + public Long getOptinalParameterLong(String name, Long defaultValue); + + public Long getRequiredParameterLong(String name); + + public Boolean getOptinalParameterBoolean(String name, Boolean defaultValue); + + public Boolean getRequiredParameterBoolean(String name); } diff --git a/JavaSource/org/unitime/timetable/api/connectors/OnlineStudentSchedulingConnector.java b/JavaSource/org/unitime/timetable/api/connectors/OnlineStudentSchedulingConnector.java new file mode 100644 index 0000000000..1ff7c60c3a --- /dev/null +++ b/JavaSource/org/unitime/timetable/api/connectors/OnlineStudentSchedulingConnector.java @@ -0,0 +1,511 @@ +/* + * Licensed to The Apereo Foundation under one or more contributor license + * agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * The Apereo Foundation licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ +package org.unitime.timetable.api.connectors; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; +import org.unitime.timetable.api.ApiConnector; +import org.unitime.timetable.api.ApiHelper; +import org.unitime.timetable.gwt.client.sectioning.SectioningStatusFilterBox; +import org.unitime.timetable.gwt.server.UniTimePrincipal; +import org.unitime.timetable.gwt.services.SectioningService; +import org.unitime.timetable.gwt.shared.AcademicSessionProvider; +import org.unitime.timetable.gwt.shared.ClassAssignmentInterface; +import org.unitime.timetable.gwt.shared.CourseRequestInterface; +import org.unitime.timetable.gwt.shared.OnlineSectioningInterface; +import org.unitime.timetable.model.Student; +import org.unitime.timetable.model.dao.StudentDAO; +import org.unitime.timetable.security.UserAuthority; +import org.unitime.timetable.security.UserContext; +import org.unitime.timetable.security.rights.Right; +import org.unitime.timetable.util.NameFormat; + +/** + * @author Tomas Muller + */ +@Service("/api/sectioning") +public class OnlineStudentSchedulingConnector extends ApiConnector { + + protected @Autowired ApplicationContext applicationContext; + + protected SectioningService getSectioningService() { + return applicationContext.getBean("sectioning.gwt", SectioningService.class); + } + + protected void execute(ApiHelper helper, Flag type) throws IOException { + String operation = helper.getParameter("operation"); + if (operation == null) + throw new IllegalArgumentException("Parameter 'operation' was not provided."); + + Operation op = null; + try { + op = Operation.valueOf(operation); + } catch (Exception e) { + new IllegalArgumentException("Operation '" + operation + "' is not a valid " + type.name() + " operation."); + } + if (op == null || !op.hasFlag(type)) + new IllegalArgumentException("Operation '" + operation + "' is not a valid " + type.name() + " operation."); + + if (op.hasFlag(Flag.NO_SESSION)) { + helper.getSessionContext().checkPermissionAnyAuthority(Right.ApiOnlineStudentScheduliung); + op.execute(getSectioningService(), helper, type, null, null); + return; + } + + Long sessionId = helper.getAcademicSessionId(); + if (sessionId == null && helper.getSessionContext().getUser() != null) + sessionId = helper.getSessionContext().getUser().getCurrentAcademicSessionId(); + if (sessionId == null) + throw new IllegalArgumentException("Academic session not provided, please set the term parameter."); + + helper.getSessionContext().checkPermissionAnyAuthority(sessionId, "Session", Right.ApiOnlineStudentScheduliung); + + for (UserAuthority authority: helper.getSessionContext().getUser().getAuthorities()) + if (authority.getAcademicSession() != null && sessionId.equals(authority.getAcademicSession().getQualifierId()) && authority.hasRight(Right.ApiOnlineStudentScheduliung)) { + helper.getSessionContext().getUser().setCurrentAuthority(authority); + if (helper.getSessionContext().hasPermission(Right.StudentSchedulingAdvisor)) + break; + } + + helper.getSessionContext().setAttribute("sessionId", sessionId); + + String studentId = helper.getParameter("studentId"); + UniTimePrincipal principal = null; + if (studentId != null && helper.getSessionContext().hasPermission(Right.StudentSchedulingAdvisor)) { + org.hibernate.Session hibSession = StudentDAO.getInstance().createNewSession(); + try { + List student = hibSession.createQuery("select m from Student m where m.externalUniqueId = :uid").setString("uid", studentId).setCacheable(true).list(); + if (!student.isEmpty()) { + UserContext user = helper.getSessionContext().getUser(); + principal = new UniTimePrincipal(user.getExternalUserId(), user.getName()); + for (Student s: student) { + principal.addStudentId(s.getSession().getUniqueId(), s.getUniqueId()); + principal.setName(NameFormat.defaultFormat().format(s)); + } + helper.getSessionContext().setAttribute("user", principal); + } + } finally { + hibSession.close(); + } + } + + String pin = helper.getParameter("pin"); + if (pin != null) + helper.getSessionContext().setAttribute("pin", pin); + + op.execute(getSectioningService(), helper, type, sessionId, principal == null ? null : principal.getStudentId(sessionId)); + } + + @Override + public void doGet(ApiHelper helper) throws IOException { + execute(helper, Flag.GET); + } + + @Override + public void doPost(ApiHelper helper) throws IOException { + execute(helper, Flag.POST); + } + + public static enum Flag { + GET, + POST, + NO_SESSION, + ; + + public int toInt() { return 1 << ordinal(); } + public boolean has(int flags) { return (flags & toInt()) == toInt(); } + } + + public static interface OpExecution { + public R execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException; + } + + public static enum Operation { + listCourseOfferings(new OpExecution>() { + @Override + public Collection execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.listCourseOfferings(sessionId, helper.getOptinalParameter("query", ""), helper.getOptinalParameterInteger("limit", null)); + } + }, Flag.GET), + listAcademicSessions(new OpExecution>() { + @Override + public Collection execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.listAcademicSessions(helper.getOptinalParameterBoolean("sectioning", true)); + } + }, Flag.GET, Flag.NO_SESSION), + retrieveCourseDetails(new OpExecution() { + @Override + public String execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.retrieveCourseDetails(sessionId, helper.getRequiredParameter("course")); + } + }, Flag.GET), + listClasses(new OpExecution>() { + @Override + public Collection execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.listClasses(sessionId, helper.getRequiredParameter("course")); + } + }, Flag.GET), + retrieveCourseOfferingId(new OpExecution() { + @Override + public Long execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.retrieveCourseOfferingId(sessionId, helper.getRequiredParameter("course")); + } + }, Flag.GET), + checkCourses(new OpExecution>() { + @Override + public Collection execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + CourseRequestInterface request = helper.getRequest(CourseRequestInterface.class); + request.setAcademicSessionId(sessionId); + if (request.getStudentId() == null && studentId != null) + request.setStudentId(studentId); + return service.checkCourses(helper.getOptinalParameterBoolean("online", true), request); + } + }, Flag.POST), + section(new OpExecution() { + @Override + public ClassAssignmentInterface execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + SectionRequest request = helper.getRequest(SectionRequest.class); + if (request.request != null) { + request.request.setAcademicSessionId(sessionId); + if (request.request.getStudentId() == null && studentId != null) + request.request.setStudentId(studentId); + } + return service.section( + helper.getOptinalParameterBoolean("online", request.online == null ? true : request.online), + request.request, + request.currentAssignment); + } + }, Flag.POST), + computeSuggestions(new OpExecution>() { + @Override + public Collection execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + SectionRequest request = helper.getRequest(SectionRequest.class); + if (request.request != null) { + request.request.setAcademicSessionId(sessionId); + if (request.request.getStudentId() == null && studentId != null) + request.request.setStudentId(studentId); + } + return service.computeSuggestions( + helper.getOptinalParameterBoolean("online", request.online == null ? true : request.online), + request.request, + request.currentAssignment, + helper.getOptinalParameterInteger("selectedAssignment", request.selectedAssignment == null ? 0 : request.selectedAssignment), + helper.getOptinalParameter("filter", request.filter)); + } + }, Flag.POST), + checkEligibility(new OpExecution() { + @Override + public OnlineSectioningInterface.EligibilityCheck execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.checkEligibility( + helper.getOptinalParameterBoolean("online", true), + sessionId, + studentId, + helper.getOptinalParameter("pin", null)); + } + }, Flag.GET), + saveRequest(new OpExecution() { + @Override + public Boolean execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + CourseRequestInterface request = helper.getRequest(CourseRequestInterface.class); + request.setAcademicSessionId(sessionId); + if (request.getStudentId() == null && studentId != null) + request.setStudentId(studentId); + return service.saveRequest(request); + } + }, Flag.POST), + enroll(new OpExecution() { + @Override + public ClassAssignmentInterface execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + SectionRequest request = helper.getRequest(SectionRequest.class); + if (request.request != null) { + request.request.setAcademicSessionId(sessionId); + if (request.request.getStudentId() == null && studentId != null) + request.request.setStudentId(studentId); + } + return service.enroll( + helper.getOptinalParameterBoolean("online", request.online == null ? true : request.online), + request.request, + request.currentAssignment); + } + }, Flag.POST), + getProperties(new OpExecution() { + @Override + public OnlineSectioningInterface.SectioningProperties execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.getProperties(sessionId); + } + }, Flag.GET), + listEnrollments(new OpExecution>() { + @Override + public List execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.listEnrollments(helper.getRequiredParameterLong("offeringId")); + } + }, Flag.GET), + getEnrollment(new OpExecution() { + @Override + public ClassAssignmentInterface execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.getEnrollment(helper.getOptinalParameterBoolean("online", true), studentId); + } + }, Flag.GET), + canApprove(new OpExecution>() { + @Override + public List execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.canApprove(helper.getRequiredParameterLong("classOrOfferingId")); + } + }, Flag.GET), + approveEnrollments(new OpExecution() { + @Override + public String execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + ApproveEnrollmentsRequest request = null; + if (Flag.POST == type) + request = helper.getRequest(ApproveEnrollmentsRequest.class); + if (request == null) + request = new ApproveEnrollmentsRequest(); + if (request.studentIds == null) { + request.studentIds = new ArrayList(); + } + if (request.studentIds.isEmpty() && studentId != null) + request.studentIds.add(studentId); + return service.approveEnrollments( + helper.getOptinalParameterLong("classOrOfferingId", request.classOrOfferingId), + request.studentIds); + } + }, Flag.GET, Flag.POST), + rejectEnrollments(new OpExecution() { + @Override + public Boolean execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + ApproveEnrollmentsRequest request = null; + if (Flag.POST == type) + request = helper.getRequest(ApproveEnrollmentsRequest.class); + if (request == null) + request = new ApproveEnrollmentsRequest(); + if (request.studentIds == null) { + request.studentIds = new ArrayList(); + } + if (request.studentIds.isEmpty() && studentId != null) + request.studentIds.add(studentId); + return service.rejectEnrollments( + helper.getOptinalParameterLong("classOrOfferingId", request.classOrOfferingId), + request.studentIds); + } + }, Flag.GET, Flag.POST), + findEnrollmentInfos(new OpExecution>() { + @Override + public List execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + FindInfosRequest request = null; + if (type == Flag.POST) + request = helper.getRequest(FindInfosRequest.class); + if (request == null) + request = new FindInfosRequest(); + return service.findEnrollmentInfos( + helper.getOptinalParameterBoolean("online", (request.online == null ? true : request.online)), + helper.getOptinalParameter("query", (request.query == null ? "" : request.query)), + request.filter, + helper.getOptinalParameterLong("courseId", request.courseId)); + } + }, Flag.GET, Flag.POST), + findStudentInfos(new OpExecution>() { + @Override + public List execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + FindInfosRequest request = null; + if (type == Flag.POST) + request = helper.getRequest(FindInfosRequest.class); + if (request == null) + request = new FindInfosRequest(); + return service.findStudentInfos( + helper.getOptinalParameterBoolean("online", (request.online == null ? true : request.online)), + helper.getOptinalParameter("query", (request.query == null ? "" : request.query)), + request.filter); + } + }, Flag.GET, Flag.POST), + findEnrollments(new OpExecution>() { + @Override + public List execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + FindInfosRequest request = null; + if (type == Flag.POST) + request = helper.getRequest(FindInfosRequest.class); + if (request == null) + request = new FindInfosRequest(); + return service.findEnrollments( + helper.getOptinalParameterBoolean("online", (request.online == null ? true : request.online)), + helper.getOptinalParameter("query", (request.query == null ? "" : request.query)), + request.filter, + helper.getOptinalParameterLong("courseId", request.courseId), + helper.getOptinalParameterLong("classId", request.classId)); + } + }, Flag.GET, Flag.POST), + querySuggestions(new OpExecution>() { + @Override + public List execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.querySuggestions(helper.getOptinalParameterBoolean("online", true), helper.getOptinalParameter("query", ""), helper.getOptinalParameterInteger("limit", null)); + } + }, Flag.GET), + canEnroll(new OpExecution() { + @Override + public Long execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.canEnroll(helper.getOptinalParameterBoolean("online", true), studentId); + } + }, Flag.GET), + savedRequest(new OpExecution() { + @Override + public CourseRequestInterface execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.savedRequest(helper.getOptinalParameterBoolean("online", true), sessionId, studentId); + } + }, Flag.GET), + savedResult(new OpExecution() { + @Override + public ClassAssignmentInterface execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.savedResult(helper.getOptinalParameterBoolean("online", true), sessionId, studentId); + } + }, Flag.GET), + lookupStudentSectioningStates(new OpExecution>() { + @Override + public Map execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.lookupStudentSectioningStates(); + } + }, Flag.GET), + sendEmail(new OpExecution() { + @Override + public Boolean execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + return service.sendEmail(studentId, helper.getOptinalParameter("subject", null), helper.getOptinalParameter("message", null), helper.getOptinalParameter("cc", null)); + } + }, Flag.GET, Flag.POST), + changeStatus(new OpExecution() { + @Override + public Boolean execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + ChangeStatusRequest request = helper.getRequest(ChangeStatusRequest.class); + if (request == null) + request = new ChangeStatusRequest(); + if (request.studentIds == null) + request.studentIds = new ArrayList(); + if (request.studentIds.isEmpty() && studentId != null) + request.studentIds.add(studentId); + return service.changeStatus(request.studentIds, helper.getOptinalParameter("status", request.status)); + } + }, Flag.GET, Flag.POST), + changeLog(new OpExecution>() { + @Override + public List execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + String sid = helper.getOptinalParameter("studentId", null); + return service.changeLog(helper.getOptinalParameter("query", (sid == null ? "" : "id:" + sid))); + } + }, Flag.GET), + massCancel(new OpExecution() { + @Override + public Boolean execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + MassCancelRequest request = null; + if (type == Flag.POST) + request = helper.getRequest(MassCancelRequest.class); + if (request == null) + request = new MassCancelRequest(); + if (request.studentIds == null) + request.studentIds = new ArrayList(); + if (request.studentIds.isEmpty() && studentId != null) + request.studentIds.add(studentId); + return service.massCancel( + request.studentIds, + helper.getOptinalParameter("status", request.status), + helper.getOptinalParameter("subject", request.subject), + helper.getOptinalParameter("message", request.message), + helper.getOptinalParameter("cc", request.cc)); + } + }, Flag.GET, Flag.POST), + requestStudentUpdate(new OpExecution() { + @Override + public Boolean execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + StudentIdsRequest request = null; + if (type == Flag.POST) + request = helper.getRequest(StudentIdsRequest.class); + if (request == null) + request = new StudentIdsRequest(); + if (request.studentIds == null) + request.studentIds = new ArrayList(); + if (request.studentIds.isEmpty() && studentId != null) + request.studentIds.add(studentId); + return service.requestStudentUpdate(request.studentIds); + } + }, Flag.GET, Flag.POST), + ; + + int iFlags = 0; + OpExecution iExecution = null; + + Operation(OpExecution execution, Flag... flags) { + iExecution = execution; + for (Flag f: flags) { + iFlags |= f.toInt(); + } + } + + public boolean hasFlag(Flag f) { + return f.has(iFlags); + } + + public void execute(SectioningService service, ApiHelper helper, Flag type, Long sessionId, Long studentId) throws IOException { + helper.setResponse(iExecution.execute(service, helper, type, sessionId, studentId)); + } + } + + @Override + protected String getName() { + return "sectioning"; + } + + public static class SectionRequest { + Boolean online; + CourseRequestInterface request; + ArrayList currentAssignment; + Integer selectedAssignment; + String filter; + } + + public static class StudentIdsRequest { + List studentIds; + } + + public static class ApproveEnrollmentsRequest extends StudentIdsRequest { + Long classOrOfferingId; + } + + public static class ChangeStatusRequest extends StudentIdsRequest { + String status; + } + + public static class MassCancelRequest extends StudentIdsRequest { + String status; + String subject; + String message; + String cc; + } + + public static class FindInfosRequest { + Boolean online; + String query; + SectioningStatusFilterBox.SectioningStatusFilterRpcRequest filter; + Long courseId; + Long classId; + } +} diff --git a/JavaSource/org/unitime/timetable/onlinesectioning/OnlineSectioningHelper.java b/JavaSource/org/unitime/timetable/onlinesectioning/OnlineSectioningHelper.java index 2a080411f9..416735a461 100644 --- a/JavaSource/org/unitime/timetable/onlinesectioning/OnlineSectioningHelper.java +++ b/JavaSource/org/unitime/timetable/onlinesectioning/OnlineSectioningHelper.java @@ -409,23 +409,27 @@ public OnlineSectioningLog.Log getLog() { public static OnlineSectioningLog.Section toProto(ClassAssignmentInterface.ClassAssignment assignment) { OnlineSectioningLog.Section.Builder section = OnlineSectioningLog.Section.newBuilder(); if (assignment.getClassId() != null) { - section.setClazz( - OnlineSectioningLog.Entity.newBuilder() - .setUniqueId(assignment.getClassId()) - .setExternalId(assignment.getSection()) - .setName(assignment.getClassNumber())); + OnlineSectioningLog.Entity.Builder e = OnlineSectioningLog.Entity.newBuilder(); + e.setUniqueId(assignment.getClassId()); + if (assignment.getSection() != null) + e.setExternalId(assignment.getSection()); + if (assignment.getClassNumber() != null) + e.setName(assignment.getClassNumber()); + section.setClazz(e); } if (assignment.getSubpartId() != null) { - section.setSubpart( - OnlineSectioningLog.Entity.newBuilder() - .setUniqueId(assignment.getSubpartId()) - .setName(assignment.getSubpart())); + OnlineSectioningLog.Entity.Builder e = OnlineSectioningLog.Entity.newBuilder(); + e.setUniqueId(assignment.getSubpartId()); + if (assignment.getSubpart() != null) + e.setName(assignment.getSubpart()); + section.setSubpart(e); } if (assignment.getCourseId() != null) { - section.setCourse( - OnlineSectioningLog.Entity.newBuilder() - .setUniqueId(assignment.getCourseId()) - .setName(assignment.getSubject() + " " + assignment.getCourseNbr())); + OnlineSectioningLog.Entity.Builder e = OnlineSectioningLog.Entity.newBuilder(); + e.setUniqueId(assignment.getCourseId()); + if (assignment.getSubject() != null && assignment.getCourseNbr() != null) + e.setName(assignment.getSubject() + " " + assignment.getCourseNbr()); + section.setCourse(e); } if (assignment.isAssigned()) { OnlineSectioningLog.Time.Builder time = OnlineSectioningLog.Time.newBuilder(); diff --git a/JavaSource/org/unitime/timetable/security/rights/Right.java b/JavaSource/org/unitime/timetable/security/rights/Right.java index 2edef1af3d..48e53225b6 100644 --- a/JavaSource/org/unitime/timetable/security/rights/Right.java +++ b/JavaSource/org/unitime/timetable/security/rights/Right.java @@ -578,6 +578,7 @@ public enum Right { ApiRetrieveClassInfo(Session.class), ApiJsonConnector, ApiDataExchangeConnector, + ApiOnlineStudentScheduliung(Session.class), /** People Lookup limitations */ CanLookupStudents,