Search in sources :

Example 1 with DuplicateCourseStudentException

use of fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException in project pyramus by otavanopisto.

the class EditStudentProjectJSONRequestController method process.

public void process(JSONRequestContext jsonRequestContext) {
    StaffMemberDAO staffMemberDAO = DAOFactory.getInstance().getStaffMemberDAO();
    ModuleDAO moduleDAO = DAOFactory.getInstance().getModuleDAO();
    CourseDAO courseDAO = DAOFactory.getInstance().getCourseDAO();
    StudentDAO studentDAO = DAOFactory.getInstance().getStudentDAO();
    CourseStudentDAO courseStudentDAO = DAOFactory.getInstance().getCourseStudentDAO();
    StudentProjectDAO studentProjectDAO = DAOFactory.getInstance().getStudentProjectDAO();
    StudentProjectModuleDAO studentProjectModuleDAO = DAOFactory.getInstance().getStudentProjectModuleDAO();
    GradeDAO gradeDAO = DAOFactory.getInstance().getGradeDAO();
    ProjectAssessmentDAO projectAssessmentDAO = DAOFactory.getInstance().getProjectAssessmentDAO();
    EducationalTimeUnitDAO educationalTimeUnitDAO = DAOFactory.getInstance().getEducationalTimeUnitDAO();
    AcademicTermDAO academicTermDAO = DAOFactory.getInstance().getAcademicTermDAO();
    TagDAO tagDAO = DAOFactory.getInstance().getTagDAO();
    DefaultsDAO defaultsDAO = DAOFactory.getInstance().getDefaultsDAO();
    Defaults defaults = defaultsDAO.getDefaults();
    // Project
    Long studentProjectId = jsonRequestContext.getLong("studentProject");
    StudentProject studentProject = studentProjectDAO.findById(studentProjectId);
    // Version check
    Long version = jsonRequestContext.getLong("version");
    if (!studentProject.getVersion().equals(version))
        throw new StaleObjectStateException(StudentProject.class.getName(), studentProject.getId());
    String name = jsonRequestContext.getString("name");
    String description = jsonRequestContext.getString("description");
    StaffMember staffMember = staffMemberDAO.findById(jsonRequestContext.getLoggedUserId());
    Long optionalStudiesLengthTimeUnitId = jsonRequestContext.getLong("optionalStudiesLengthTimeUnit");
    EducationalTimeUnit optionalStudiesLengthTimeUnit = educationalTimeUnitDAO.findById(optionalStudiesLengthTimeUnitId);
    Double optionalStudiesLength = jsonRequestContext.getDouble("optionalStudiesLength");
    String tagsText = jsonRequestContext.getString("tags");
    Long studentId = jsonRequestContext.getLong("student");
    CourseOptionality projectOptionality = (CourseOptionality) jsonRequestContext.getEnum("projectOptionality", CourseOptionality.class);
    Set<Tag> tagEntities = new HashSet<>();
    if (!StringUtils.isBlank(tagsText)) {
        List<String> tags = Arrays.asList(tagsText.split("[\\ ,]"));
        for (String tag : tags) {
            if (!StringUtils.isBlank(tag)) {
                Tag tagEntity = tagDAO.findByText(tag.trim());
                if (tagEntity == null)
                    tagEntity = tagDAO.create(tag);
                tagEntities.add(tagEntity);
            }
        }
    }
    Student student = studentDAO.findById(studentId);
    if (!studentProject.getStudent().equals(student)) {
        studentProjectDAO.updateStudent(studentProject, student, staffMember);
    }
    studentProjectDAO.update(studentProject, name, description, optionalStudiesLength, optionalStudiesLengthTimeUnit, projectOptionality, staffMember);
    // Tags
    studentProjectDAO.updateTags(studentProject, tagEntities);
    // ProjectAssessments
    int rowCount = jsonRequestContext.getInteger("assessmentsTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "assessmentsTable." + i;
        Long assessmentModified = jsonRequestContext.getLong(colPrefix + ".modified");
        if ((assessmentModified != null) && (assessmentModified.intValue() == 1)) {
            Long assessmentId = jsonRequestContext.getLong(colPrefix + ".assessmentId");
            ProjectAssessment projectAssessment = ((assessmentId != null) && (assessmentId.intValue() != -1)) ? projectAssessmentDAO.findById(assessmentId) : null;
            Long assessmentArchived = jsonRequestContext.getLong(colPrefix + ".deleted");
            if ((assessmentArchived != null) && (assessmentArchived.intValue() == 1)) {
                if (projectAssessment != null)
                    projectAssessmentDAO.archive(projectAssessment);
                else
                    throw new SmvcRuntimeException(PyramusStatusCode.OK, "Assessment marked for delete does not exist.");
            } else {
                Date assessmentDate = jsonRequestContext.getDate(colPrefix + ".date");
                Long assessmentGradeId = jsonRequestContext.getLong(colPrefix + ".grade");
                Grade grade = assessmentGradeId != null ? gradeDAO.findById(assessmentGradeId) : null;
                String verbalAssessment = projectAssessment != null ? projectAssessment.getVerbalAssessment() : null;
                Long verbalAssessmentModified = jsonRequestContext.getLong(colPrefix + ".verbalModified");
                if ((verbalAssessmentModified != null) && (verbalAssessmentModified.intValue() == 1))
                    verbalAssessment = jsonRequestContext.getString(colPrefix + ".verbalAssessment");
                if (projectAssessment == null) {
                    projectAssessmentDAO.create(studentProject, staffMember, grade, assessmentDate, verbalAssessment);
                } else {
                    projectAssessmentDAO.update(projectAssessment, staffMember, grade, assessmentDate, verbalAssessment);
                }
            }
        }
    }
    // Student project modules
    Set<Long> existingModuleIds = new HashSet<>();
    rowCount = jsonRequestContext.getInteger("modulesTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "modulesTable." + i;
        Long studentProjectModuleId = jsonRequestContext.getLong(colPrefix + ".studentProjectModuleId");
        CourseOptionality optionality = (CourseOptionality) jsonRequestContext.getEnum(colPrefix + ".optionality", CourseOptionality.class);
        Long studyTermId = jsonRequestContext.getLong(colPrefix + ".academicTerm");
        AcademicTerm academicTerm = studyTermId == null ? null : academicTermDAO.findById(studyTermId);
        if (studentProjectModuleId == -1) {
            Long moduleId = jsonRequestContext.getLong(colPrefix + ".moduleId");
            Module module = moduleDAO.findById(moduleId);
            studentProjectModuleId = studentProjectModuleDAO.create(studentProject, module, academicTerm, optionality).getId();
        } else {
            studentProjectModuleDAO.update(studentProjectModuleDAO.findById(studentProjectModuleId), academicTerm, optionality);
        }
        existingModuleIds.add(studentProjectModuleId);
    }
    // Removed Student project modules
    List<StudentProjectModule> studentProjectModules = studentProjectModuleDAO.listByStudentProject(studentProject);
    for (StudentProjectModule studentProjectModule : studentProjectModules) {
        if (!existingModuleIds.contains(studentProjectModule.getId())) {
            studentProjectModuleDAO.delete(studentProjectModule);
        }
    }
    // Student project courses
    rowCount = jsonRequestContext.getInteger("coursesTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "coursesTable." + i;
        Long courseId = jsonRequestContext.getLong(colPrefix + ".courseId");
        CourseOptionality optionality = (CourseOptionality) jsonRequestContext.getEnum(colPrefix + ".optionality", CourseOptionality.class);
        Course course = courseId == -1 ? null : courseDAO.findById(courseId);
        CourseStudent courseStudent = courseStudentDAO.findByCourseAndStudent(course, studentProject.getStudent());
        if (courseStudent == null) {
            CourseEnrolmentType courseEnrolmentType = defaults.getInitialCourseEnrolmentType();
            CourseParticipationType participationType = defaults.getInitialCourseParticipationType();
            Date enrolmentDate = new Date(System.currentTimeMillis());
            Boolean lodging = Boolean.FALSE;
            String organization = null;
            String additionalInfo = null;
            Room room = null;
            BigDecimal lodgingFee = null;
            Currency lodgingFeeCurrency = null;
            BigDecimal reservationFee = null;
            Currency reservationFeeCurrency = null;
            try {
                courseStudent = courseStudentDAO.create(course, studentProject.getStudent(), courseEnrolmentType, participationType, enrolmentDate, lodging, optionality, null, organization, additionalInfo, room, lodgingFee, lodgingFeeCurrency, reservationFee, reservationFeeCurrency, Boolean.FALSE);
            } catch (DuplicateCourseStudentException dcse) {
                Locale locale = jsonRequestContext.getRequest().getLocale();
                throw new SmvcRuntimeException(PyramusStatusCode.UNDEFINED, Messages.getInstance().getText(locale, "generic.errors.duplicateCourseStudent", new Object[] { student.getFullName() }));
            }
        } else {
            courseStudentDAO.updateOptionality(courseStudent, optionality);
        }
    }
    jsonRequestContext.setRedirectURL(jsonRequestContext.getReferer(true));
}
Also used : Locale(java.util.Locale) DuplicateCourseStudentException(fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException) CourseOptionality(fi.otavanopisto.pyramus.domainmodel.base.CourseOptionality) CourseDAO(fi.otavanopisto.pyramus.dao.courses.CourseDAO) StudentProjectModuleDAO(fi.otavanopisto.pyramus.dao.projects.StudentProjectModuleDAO) ModuleDAO(fi.otavanopisto.pyramus.dao.modules.ModuleDAO) StudentProjectModuleDAO(fi.otavanopisto.pyramus.dao.projects.StudentProjectModuleDAO) SmvcRuntimeException(fi.internetix.smvc.SmvcRuntimeException) StaffMember(fi.otavanopisto.pyramus.domainmodel.users.StaffMember) StaffMemberDAO(fi.otavanopisto.pyramus.dao.users.StaffMemberDAO) StudentProjectDAO(fi.otavanopisto.pyramus.dao.projects.StudentProjectDAO) AcademicTermDAO(fi.otavanopisto.pyramus.dao.base.AcademicTermDAO) CourseStudent(fi.otavanopisto.pyramus.domainmodel.courses.CourseStudent) Currency(java.util.Currency) Course(fi.otavanopisto.pyramus.domainmodel.courses.Course) CourseParticipationType(fi.otavanopisto.pyramus.domainmodel.courses.CourseParticipationType) Room(fi.otavanopisto.pyramus.domainmodel.accommodation.Room) EducationalTimeUnit(fi.otavanopisto.pyramus.domainmodel.base.EducationalTimeUnit) HashSet(java.util.HashSet) TagDAO(fi.otavanopisto.pyramus.dao.base.TagDAO) EducationalTimeUnitDAO(fi.otavanopisto.pyramus.dao.base.EducationalTimeUnitDAO) CourseStudentDAO(fi.otavanopisto.pyramus.dao.courses.CourseStudentDAO) CourseEnrolmentType(fi.otavanopisto.pyramus.domainmodel.courses.CourseEnrolmentType) Grade(fi.otavanopisto.pyramus.domainmodel.grading.Grade) GradeDAO(fi.otavanopisto.pyramus.dao.grading.GradeDAO) DefaultsDAO(fi.otavanopisto.pyramus.dao.base.DefaultsDAO) Student(fi.otavanopisto.pyramus.domainmodel.students.Student) CourseStudent(fi.otavanopisto.pyramus.domainmodel.courses.CourseStudent) Date(java.util.Date) BigDecimal(java.math.BigDecimal) CourseStudentDAO(fi.otavanopisto.pyramus.dao.courses.CourseStudentDAO) StudentDAO(fi.otavanopisto.pyramus.dao.students.StudentDAO) Defaults(fi.otavanopisto.pyramus.domainmodel.base.Defaults) AcademicTerm(fi.otavanopisto.pyramus.domainmodel.base.AcademicTerm) StudentProjectModule(fi.otavanopisto.pyramus.domainmodel.projects.StudentProjectModule) ProjectAssessment(fi.otavanopisto.pyramus.domainmodel.grading.ProjectAssessment) ProjectAssessmentDAO(fi.otavanopisto.pyramus.dao.grading.ProjectAssessmentDAO) Tag(fi.otavanopisto.pyramus.domainmodel.base.Tag) StudentProjectModule(fi.otavanopisto.pyramus.domainmodel.projects.StudentProjectModule) Module(fi.otavanopisto.pyramus.domainmodel.modules.Module) StaleObjectStateException(org.hibernate.StaleObjectStateException) StudentProject(fi.otavanopisto.pyramus.domainmodel.projects.StudentProject)

Example 2 with DuplicateCourseStudentException

use of fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException in project pyramus by otavanopisto.

the class CourseStudentDAO method create.

/**
 * Adds a course student to the database.
 *
 * @param course The course
 * @param student The student
 * @param courseEnrolmentType Student enrolment type
 * @param participationType Student participation type
 * @param enrolmentDate The enrolment date
 * @param optionality
 * @param billingDetails
 * @param archived
 * @param room
 *
 * @return The created course student
 * @throws DuplicateCourseStudentException
 */
public CourseStudent create(Course course, Student student, CourseEnrolmentType courseEnrolmentType, CourseParticipationType participationType, Date enrolmentDate, Boolean lodging, CourseOptionality optionality, BillingDetails billingDetails, String organization, String additionalInfo, Room room, BigDecimal lodgingFee, Currency lodgingFeeCurrency, BigDecimal reservationFee, Currency reservationFeeCurrency, Boolean archived) throws DuplicateCourseStudentException {
    List<CourseStudent> courseStudents = listByCourseAndStudent(course, student);
    if (!courseStudents.isEmpty())
        throw new DuplicateCourseStudentException();
    CourseStudent courseStudent = new CourseStudent();
    courseStudent.setCourse(course);
    courseStudent.setArchived(archived);
    courseStudent.setBillingDetails(billingDetails);
    courseStudent.setCourseEnrolmentType(courseEnrolmentType);
    courseStudent.setEnrolmentTime(enrolmentDate);
    courseStudent.setParticipationType(participationType);
    courseStudent.setLodging(lodging);
    courseStudent.setOptionality(optionality);
    courseStudent.setStudent(student);
    courseStudent.setRoom(room);
    courseStudent.setLodgingFee(lodgingFee);
    courseStudent.setLodgingFeeCurrency(lodgingFeeCurrency);
    courseStudent.setReservationFee(reservationFee);
    courseStudent.setReservationFeeCurrency(reservationFeeCurrency);
    courseStudent.setOrganization(organization);
    courseStudent.setAdditionalInfo(additionalInfo);
    persist(courseStudent);
    courseStudentCreatedEvent.fire(new CourseStudentCreatedEvent(courseStudent.getId(), courseStudent.getCourse().getId(), courseStudent.getStudent().getId()));
    return courseStudent;
}
Also used : DuplicateCourseStudentException(fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException) CourseStudent(fi.otavanopisto.pyramus.domainmodel.courses.CourseStudent) CourseStudentCreatedEvent(fi.otavanopisto.pyramus.events.CourseStudentCreatedEvent)

Example 3 with DuplicateCourseStudentException

use of fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException in project pyramus by otavanopisto.

the class CourseRESTService method createCourseStudent.

@Path("/courses/{COURSEID:[0-9]*}/students")
@POST
@RESTPermit(handling = Handling.INLINE)
public // @RESTPermit (CoursePermissions.CREATE_COURSESTUDENT)
Response createCourseStudent(@PathParam("COURSEID") Long courseId, fi.otavanopisto.pyramus.rest.model.CourseStudent entity) {
    if (entity == null) {
        return Response.status(Status.BAD_REQUEST).entity("Request payload missing").build();
    }
    if (entity.getStudentId() == null) {
        return Response.status(Status.BAD_REQUEST).entity("studentId is missing").build();
    }
    if (entity.getLodging() == null) {
        return Response.status(Status.BAD_REQUEST).entity("lodging is missing").build();
    }
    if (entity.getEnrolmentTime() == null) {
        return Response.status(Status.BAD_REQUEST).entity("enrolmentTime is missing").build();
    }
    if (!restSecurity.hasPermission(new String[] { CoursePermissions.CREATE_COURSESTUDENT, UserPermissions.USER_OWNER }, entity, Style.OR)) {
        return Response.status(Status.FORBIDDEN).build();
    }
    Course course = courseController.findCourseById(courseId);
    if (course == null) {
        return Response.status(Status.NOT_FOUND).build();
    }
    if (course.isCourseTemplate()) {
        return Response.status(Status.BAD_REQUEST).entity("Cannot add student to a course template").build();
    }
    Student student = studentController.findStudentById(entity.getStudentId());
    if (student == null) {
        return Response.status(Status.BAD_REQUEST).entity("could not find the student #" + entity.getStudentId()).build();
    }
    if (courseController.findCourseStudentByCourseAndStudent(course, student) != null) {
        return Response.status(Status.BAD_REQUEST).entity("student #" + entity.getStudentId() + " is already on course #" + courseId).build();
    }
    BillingDetails billingDetails = null;
    if (entity.getBillingDetailsId() != null) {
        billingDetails = commonController.findBillingDetailsById(entity.getBillingDetailsId());
        if (billingDetails == null) {
            return Response.status(Status.BAD_REQUEST).entity("could not find billingDetails #" + entity.getBillingDetailsId()).build();
        }
    }
    fi.otavanopisto.pyramus.domainmodel.courses.CourseEnrolmentType enrolmentType;
    if (entity.getEnrolmentTypeId() != null) {
        enrolmentType = courseController.findCourseEnrolmentTypeById(entity.getEnrolmentTypeId());
        if (enrolmentType == null) {
            return Response.status(Status.BAD_REQUEST).entity("could not find enrolmentType #" + entity.getEnrolmentTypeId()).build();
        }
    } else {
        enrolmentType = courseController.getDefaultCourseEnrolmentType();
    }
    fi.otavanopisto.pyramus.domainmodel.base.CourseOptionality optionality = entity.getOptionality() != null ? fi.otavanopisto.pyramus.domainmodel.base.CourseOptionality.valueOf(entity.getOptionality().name()) : null;
    fi.otavanopisto.pyramus.domainmodel.courses.CourseParticipationType participantionType;
    if (entity.getParticipationTypeId() != null) {
        participantionType = courseController.findCourseParticipationTypeById(entity.getParticipationTypeId());
        if (participantionType == null) {
            return Response.status(Status.BAD_REQUEST).entity("could not find participationType #" + entity.getParticipationTypeId()).build();
        }
    } else {
        participantionType = courseController.getDefaultCourseParticipationType();
    }
    // TODO: Add support for room, organization, additionalInfo and lodging fee
    String organization = null;
    String additionalInfo = null;
    Room room = null;
    BigDecimal lodgingFee = null;
    Currency lodgingFeeCurrency = null;
    BigDecimal reservationFee = null;
    Currency reservationFeeCurrency = null;
    try {
        return Response.status(Status.OK).entity(objectFactory.createModel(courseController.createCourseStudent(course, student, enrolmentType, participantionType, toDate(entity.getEnrolmentTime()), entity.getLodging(), optionality, billingDetails, lodgingFee, lodgingFeeCurrency, reservationFee, reservationFeeCurrency, organization, additionalInfo, room))).build();
    } catch (DuplicateCourseStudentException dcse) {
        logger.log(Level.SEVERE, "Attempt to add CourseStudent when it already exists (student=" + entity.getStudentId() + ", course=" + courseId + ".", dcse);
        return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Student is already member of the course.").build();
    }
}
Also used : DuplicateCourseStudentException(fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException) CourseStudent(fi.otavanopisto.pyramus.domainmodel.courses.CourseStudent) Student(fi.otavanopisto.pyramus.domainmodel.students.Student) BillingDetails(fi.otavanopisto.pyramus.domainmodel.base.BillingDetails) BigDecimal(java.math.BigDecimal) CourseParticipationType(fi.otavanopisto.pyramus.domainmodel.courses.CourseParticipationType) Currency(java.util.Currency) Course(fi.otavanopisto.pyramus.domainmodel.courses.Course) Room(fi.otavanopisto.pyramus.domainmodel.accommodation.Room) Path(javax.ws.rs.Path) RESTPermit(fi.otavanopisto.pyramus.rest.annotation.RESTPermit) POST(javax.ws.rs.POST)

Example 4 with DuplicateCourseStudentException

use of fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException in project pyramus by otavanopisto.

the class EditCourseJSONRequestController method process.

/**
 * Processes the request to edit a course.
 * The request should contain the following parameters:
 * <dl>
 *   <dt><code>name</code></dt>
 *   <dd>The name of the course.</dd>
 *   <dt><code>nameExtension</code></dt>
 *   <dd>The name extension of the course.</dd>
 *   <dt><code>state</code></dt>
 *   <dd>The ID of the initial course state.</dd>
 *   <dt><code>description</code></dt>
 *   <dd>The description of the course, in HTML.</dd>
 *   <dt><code>module</code></dt>
 *   <dd>The ID of the module the course is associated with.</dd>
 *   <dt><code>subject</code></dt>
 *   <dd>The ID of the subject of the course.</dd>
 *   <dt><code>courseNumber</code></dt>
 *   <dd>The course number of the course.</dd>
 *   <dt><code>beginDate</code></dt>
 *   <dd>The beginning date of the course, as a timestamp in ms.</dd>
 *   <dt><code>endDate</code></dt>
 *   <dd>The end date of the course, as a timestamp in ms.</dd>
 *   <dt><code>enrolmentTimeEnd</code></dt>
 *   <dd>The time when enrollment for the course ends, as a timestamp in ms.</dd>
 *   <dt><code>courseLength</code></dt>
 *   <dd>The length of the course, in units specified in <code>courseLengthTimeUnit</code>.</dd>
 *   <dt><code>courseLengthTimeUnit</code></dt>
 *   <dd>The ID of the time unit for the courses.</dd>
 *   <dt><code>maxParticipantCount</code></dt>
 *   <dd>The maximum number of participants for this course.</dd>
 *   <dt><code>distanceTeachingDays</code></dt>
 *   <dd>The number of days of distance teaching.</dd>
 *   <dt><code>localTeachingDays</code></dt>
 *   <dd>The number of days of local teaching.</dd>
 *   <dt><code>teachingHours</code></dt>
 *   <dd>The total number of teaching hours.</dd>
 *   <dt><code>planningHours</code></dt>
 *   <dd>The total number of hours used for planning.
 *   <dt><code>assessingHours</code></dt>
 *   <dd>The total number of hours used for assessing.
 *   <dt><code>tags</code></dt>
 *   <dd>The tags associated with the course, separated by spaces.</dd>
 * </dl>
 * The following are not single but multiple parameters, arranged
 * as collections of objects. Each parameter is defined by the
 * following scheme (zero indexed):<br/>
 * <code>
 * <i>collection name</i>.<i>property name</i>
 * </code>
 * or<br/>
 * <code>
 * <i>collection name</i>.<i>object index</i>.<i>property name</i>
 * </code>
 * <dl>
 *   <dt><code>courseDescription.*.catId</code></dt>
 *   <dd>The course description category ID to add the description to.
 *   <dt><code>courseDescription.*.text</code></dt>
 *   <dd>The description of the course.</dd>
 *   <dt><code>personnelTable.rowCount</code></dt>
 *   <dd>The number of personnel in the course.</dd>
 *   <dt><code>personnelTable.*.userId</code></dt>
 *   <dd>The ID of the user in the personnel table.</dd>
 *   <dt><code>personnelTable.*.roleId</code></dt>
 *   <dd>The role ID of the user in the personnel table.</dd>
 *   <dt><code>components.componentCount</code></dt>
 *   <dd>The number of course components in this course.</dd>
 *   <dt><code>components.*.0.name</code></dt>
 *   <dd>The name of the course component.</dd>
 *   <dt><code>components.*.0.length</code></dt>
 *   <dd>The length of the course component, in default time units.</dd>
 *   <dt><code>components.*.0.description</code></dt>
 *   <dd>The description of the course component.</dd>
 *   <dt><code>components.*.resourceCategoryCount</code></dt>
 *   <dd>The number of resource categories in the course component.</dd>
 *   <dt><code>components.*.*.resources.rowCount</code></dt>
 *   <dd>The number of resources in the resource category.</dd>
 *   <dt><code>components.*.*.resources.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>components.*.*.resources.*.quantity</code></dt>
 *   <dd>The quantity of the resource.</dd>
 *   <dt><code>components.*.*.resources.*.usage</code></dt>
 *   <dd>The usage of the resource.</dd>
 *   <dt><code>educationType.*.*</code></dt>
 *   <dd>The education types and subtypes (as numerical IDs) of the course.</dd>
 *   <dt><code>basicResourcesTable.rowCount</code></dt>
 *   <dd>The number of basic resources associated with the course.</dd>
 *   <dt><code>basicResourcesTable.*.hours</code></dt>
 *   <dd>The number of hours the resource is used.</dd>
 *   <dt><code>basicResourcesTable.*.hourlyCost</code></dt>
 *   <dd>The hourly cost of the resource.</dd>
 *   <dt><code>basicResourcesTable.*.units</code></dt>
 *   <dd>The number of units of the resource used.</dd>
 *   <dt><code>basicResourcesTable.*.unitCost</code></dt>
 *   <dd>The cost of a single unit of the resource.</dd>
 *   <dt><code>basicResourcesTable.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>studentResourcesTable.rowCount</code></dt>
 *   <dd>The number of student resources associated with the course.</dd>
 *   <dt><code>studentResourcesTable.*.hours</code></dt>
 *   <dd>The number of hours the resource is used.</dd>
 *   <dt><code>studentResourcesTable.*.hourlyCost</code></dt>
 *   <dd>The hourly cost of the resource.</dd>
 *   <dt><code>studentResourcesTable.*.unitCost</code></dt>
 *   <dd>The cost of a single unit of the resource.</dd>
 *   <dt><code>studentResourcesTable.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>gradeResourcesTable.rowCount</code></dt>
 *   <dd>The number of grade resources associated with the course.</dd>
 *   <dt><code>gradeResourcesTable.*.hours</code></dt>
 *   <dd>The number of hours the resource is used.</dd>
 *   <dt><code>gradeResourcesTable.*.hourlyCost</code></dt>
 *   <dd>The hourly cost of the resource.</dd>
 *   <dt><code>gradeResourcesTable.*.unitCost</code></dt>
 *   <dd>The cost of a single unit of the resource.</dd>
 *   <dt><code>gradeResourcesTable.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>otherCostsTable.rowCount</code></dt>
 *   <dd>The number of other costs associated with this course.</dd>
 *   <dt><code>otherCostsTable.*.name</code></dt>
 *   <dd>The name of the cost.</dd>
 *   <dt><code>otherCostsTable.*.count</code></dt>
 *   <dd>The amount of the cost.</dd>
 *   <dt><code>studentsTable.rowCount</code></dt>
 *   <dd>The number of students attending this course.</dd>
 *   <dt><code>studentsTable.*.studentId</code></dt>
 *   <dd>The ID of the student.</dd>
 *   <dt><code>studentsTable.*.enrolmentDate</code></dt>
 *   <dd>The enrollment date of the student, as a timestamp in ms.</dd>
 *   <dt><code>studentsTable.*.enrolmentType</code></dt>
 *   <dd>The ID of the enrollment type of the student.</dd>
 *   <dt><code>studentsTable.*.participationType</code></dt>
 *   <dd>The ID of the participation type of the student.</dd>
 *   <dt><code>studentsTable.*.lodging</code></dt>
 *   <dd><code>true</code> if the student is lodging on campus.</dd>
 *   <dt><code>studentsTable.*.optionality</code></dt>
 *   <dd>The optionality of the course for the student:
 *   <code>MANDATORY</code> or <code>OPTIONAL</code></dd>
 * </dl>
 *
 * @param requestContext The JSON request context
 */
public void process(JSONRequestContext requestContext) {
    StaffMemberDAO userDAO = DAOFactory.getInstance().getStaffMemberDAO();
    StudentDAO studentDAO = DAOFactory.getInstance().getStudentDAO();
    CourseDAO courseDAO = DAOFactory.getInstance().getCourseDAO();
    ResourceDAO resourceDAO = DAOFactory.getInstance().getResourceDAO();
    CourseDescriptionDAO courseDescriptionDAO = DAOFactory.getInstance().getCourseDescriptionDAO();
    CourseStudentDAO courseStudentDAO = DAOFactory.getInstance().getCourseStudentDAO();
    CourseStateDAO courseStateDAO = DAOFactory.getInstance().getCourseStateDAO();
    CourseParticipationTypeDAO participationTypeDAO = DAOFactory.getInstance().getCourseParticipationTypeDAO();
    CourseComponentResourceDAO componentResourceDAO = DAOFactory.getInstance().getCourseComponentResourceDAO();
    CourseEnrolmentTypeDAO enrolmentTypeDAO = DAOFactory.getInstance().getCourseEnrolmentTypeDAO();
    CourseComponentDAO componentDAO = DAOFactory.getInstance().getCourseComponentDAO();
    CourseStaffMemberDAO courseStaffMemberDAO = DAOFactory.getInstance().getCourseStaffMemberDAO();
    CourseStaffMemberRoleDAO courseStaffMemberRoleDAO = DAOFactory.getInstance().getCourseStaffMemberRoleDAO();
    CourseDescriptionDAO descriptionDAO = DAOFactory.getInstance().getCourseDescriptionDAO();
    CourseDescriptionCategoryDAO descriptionCategoryDAO = DAOFactory.getInstance().getCourseDescriptionCategoryDAO();
    OtherCostDAO otherCostDAO = DAOFactory.getInstance().getOtherCostDAO();
    BasicCourseResourceDAO basicCourseResourceDAO = DAOFactory.getInstance().getBasicCourseResourceDAO();
    StudentCourseResourceDAO studentCourseResourceDAO = DAOFactory.getInstance().getStudentCourseResourceDAO();
    GradeCourseResourceDAO gradeCourseResourceDAO = DAOFactory.getInstance().getGradeCourseResourceDAO();
    CourseEducationTypeDAO courseEducationTypeDAO = DAOFactory.getInstance().getCourseEducationTypeDAO();
    CourseEducationSubtypeDAO courseEducationSubtypeDAO = DAOFactory.getInstance().getCourseEducationSubtypeDAO();
    EducationalTimeUnitDAO educationalTimeUnitDAO = DAOFactory.getInstance().getEducationalTimeUnitDAO();
    EducationTypeDAO educationTypeDAO = DAOFactory.getInstance().getEducationTypeDAO();
    EducationSubtypeDAO educationSubtypeDAO = DAOFactory.getInstance().getEducationSubtypeDAO();
    SubjectDAO subjectDAO = DAOFactory.getInstance().getSubjectDAO();
    TagDAO tagDAO = DAOFactory.getInstance().getTagDAO();
    DefaultsDAO defaultsDAO = DAOFactory.getInstance().getDefaultsDAO();
    CourseTypeDAO courseTypeDAO = DAOFactory.getInstance().getCourseTypeDAO();
    CurriculumDAO curriculumDAO = DAOFactory.getInstance().getCurriculumDAO();
    ModuleDAO moduleDAO = DAOFactory.getInstance().getModuleDAO();
    OrganizationDAO organizationDAO = DAOFactory.getInstance().getOrganizationDAO();
    StaffMemberDAO staffMemberDAO = DAOFactory.getInstance().getStaffMemberDAO();
    Locale locale = requestContext.getRequest().getLocale();
    StaffMember loggedUser = staffMemberDAO.findById(requestContext.getLoggedUserId());
    Organization organization = organizationDAO.findById(requestContext.getLong("organizationId"));
    if (!UserUtils.canAccessOrganization(loggedUser, organization)) {
        throw new SmvcRuntimeException(PyramusStatusCode.UNAUTHORIZED, "Invalid organization.");
    }
    // Course basic information
    Long courseId = requestContext.getLong("course");
    Course course = courseDAO.findById(courseId);
    String name = requestContext.getString("name");
    String nameExtension = requestContext.getString("nameExtension");
    Long courseStateId = requestContext.getLong("state");
    Long courseTypeId = requestContext.getLong("type");
    Long maxParticipantCount = requestContext.getLong("maxParticipantCount");
    Date enrolmentTimeEnd = requestContext.getDate("enrolmentTimeEnd");
    CourseState courseState = courseStateId == null ? course.getState() : courseStateDAO.findById(courseStateId);
    CourseType courseType = courseTypeId != null ? courseTypeDAO.findById(courseTypeId) : null;
    String description = requestContext.getString("description");
    Subject subject = subjectDAO.findById(requestContext.getLong("subject"));
    Integer courseNumber = requestContext.getInteger("courseNumber");
    Date beginDate = requestContext.getDate("beginDate");
    Date endDate = requestContext.getDate("endDate");
    Double courseLength = requestContext.getDouble("courseLength");
    EducationalTimeUnit courseLengthTimeUnit = educationalTimeUnitDAO.findById(requestContext.getLong("courseLengthTimeUnit"));
    Double distanceTeachingDays = requestContext.getDouble("distanceTeachingDays");
    Double localTeachingDays = requestContext.getDouble("localTeachingDays");
    Double teachingHours = requestContext.getDouble("teachingHours");
    Double distanceTeachingHours = requestContext.getDouble("distanceTeachingHours");
    Double planningHours = requestContext.getDouble("planningHours");
    Double assessingHours = requestContext.getDouble("assessingHours");
    String tagsText = requestContext.getString("tags");
    BigDecimal courseFee = requestContext.getBigDecimal("courseFee");
    Currency courseFeeCurrency = requestContext.getCurrency("courseFeeCurrency");
    Long version = requestContext.getLong("version");
    if (!course.getVersion().equals(version))
        throw new StaleObjectStateException(Course.class.getName(), course.getId());
    List<Curriculum> allCurriculums = curriculumDAO.listUnarchived();
    Set<Curriculum> curriculums = new HashSet<>();
    for (Curriculum curriculum : allCurriculums) {
        if ("1".equals(requestContext.getString("curriculum." + curriculum.getId()))) {
            curriculums.add(curriculum);
        }
    }
    Set<Tag> tagEntities = new HashSet<>();
    if (!StringUtils.isBlank(tagsText)) {
        List<String> tags = Arrays.asList(tagsText.split("[\\ ,]"));
        for (String tag : tags) {
            if (!StringUtils.isBlank(tag)) {
                Tag tagEntity = tagDAO.findByText(tag.trim());
                if (tagEntity == null)
                    tagEntity = tagDAO.create(tag);
                tagEntities.add(tagEntity);
            }
        }
    }
    StaffMember staffMember = userDAO.findById(requestContext.getLoggedUserId());
    courseDAO.update(course, organization, name, nameExtension, courseState, courseType, subject, courseNumber, beginDate, endDate, courseLength, courseLengthTimeUnit, distanceTeachingDays, localTeachingDays, teachingHours, distanceTeachingHours, planningHours, assessingHours, description, maxParticipantCount, enrolmentTimeEnd, staffMember);
    courseDAO.updateCurriculums(course, curriculums);
    if (Role.ADMINISTRATOR.equals(loggedUser.getRole())) {
        Boolean isCourseTemplate = requestContext.getBoolean("isCourseTemplate");
        courseDAO.updateCourseTemplate(course, Boolean.TRUE.equals(isCourseTemplate));
    }
    Long moduleId = requestContext.getLong("moduleId");
    Long currentModuleId = course.getModule() != null ? course.getModule().getId() : null;
    if ((moduleId != null) && (!moduleId.equals(currentModuleId))) {
        Module module = moduleDAO.findById(moduleId);
        courseDAO.updateModule(course, module);
    }
    courseDAO.updateCourseFee(course, courseFee, courseFeeCurrency, staffMember);
    // Tags
    courseDAO.setCourseTags(course, tagEntities);
    // Education types and subtypes submitted from the web page
    Map<Long, Vector<Long>> chosenEducationTypes = new HashMap<>();
    Enumeration<String> parameterNames = requestContext.getRequest().getParameterNames();
    while (parameterNames.hasMoreElements()) {
        name = (String) parameterNames.nextElement();
        if (name.startsWith("educationType.")) {
            String[] nameElements = name.split("\\.");
            Long educationTypeId = new Long(nameElements[1]);
            Long educationSubtypeId = new Long(nameElements[2]);
            Vector<Long> v = chosenEducationTypes.containsKey(educationTypeId) ? chosenEducationTypes.get(educationTypeId) : new Vector<Long>();
            v.add(educationSubtypeId);
            if (!chosenEducationTypes.containsKey(educationTypeId)) {
                chosenEducationTypes.put(educationTypeId, v);
            }
        }
    }
    // Remove education types and subtypes
    List<CourseEducationType> courseEducationTypes = course.getCourseEducationTypes();
    for (int i = courseEducationTypes.size() - 1; i >= 0; i--) {
        CourseEducationType courseEducationType = courseEducationTypes.get(i);
        if (!chosenEducationTypes.containsKey(courseEducationType.getEducationType().getId())) {
            courseEducationTypeDAO.delete(courseEducationType);
        } else {
            Vector<Long> v = chosenEducationTypes.get(courseEducationType.getEducationType().getId());
            List<CourseEducationSubtype> courseEducationSubtypes = courseEducationType.getCourseEducationSubtypes();
            for (int j = courseEducationSubtypes.size() - 1; j >= 0; j--) {
                CourseEducationSubtype courseEducationSubtype = courseEducationSubtypes.get(j);
                if (!v.contains(courseEducationSubtype.getEducationSubtype().getId())) {
                    courseEducationType.removeSubtype(courseEducationSubtype);
                }
            }
        }
    }
    for (Map.Entry<Long, Vector<Long>> entry : chosenEducationTypes.entrySet()) {
        EducationType educationType = educationTypeDAO.findById(entry.getKey());
        CourseEducationType courseEducationType;
        if (!course.contains(educationType)) {
            courseEducationType = courseEducationTypeDAO.create(course, educationType);
        } else {
            courseEducationType = course.getCourseEducationTypeByEducationTypeId(entry.getKey());
        }
        for (Long educationSubtypeId : entry.getValue()) {
            EducationSubtype educationSubtype = educationSubtypeDAO.findById(educationSubtypeId);
            if (!courseEducationType.contains(educationSubtype)) {
                courseEducationSubtypeDAO.create(courseEducationType, educationSubtype);
            }
        }
    }
    // Course Descriptions
    List<CourseDescriptionCategory> descriptionCategories = descriptionCategoryDAO.listUnarchived();
    Set<CourseDescription> nonExistingDescriptions = new HashSet<>();
    for (CourseDescriptionCategory cat : descriptionCategories) {
        String varName = "courseDescription." + cat.getId().toString();
        Long descriptionCatId = requestContext.getLong(varName + ".catId");
        String descriptionText = requestContext.getString(varName + ".text");
        CourseDescription oldDesc = descriptionDAO.findByCourseAndCategory(course, cat);
        if (descriptionCatId != null && descriptionCatId.intValue() != -1) {
            // Description has been submitted from form
            if (oldDesc != null)
                descriptionDAO.update(oldDesc, course, cat, descriptionText);
            else
                descriptionDAO.create(course, cat, descriptionText);
        } else {
            // Description wasn't submitted from form, if it exists, it's marked for deletion
            if (oldDesc != null)
                nonExistingDescriptions.add(oldDesc);
        }
    }
    // Delete non existing descriptions
    for (CourseDescription desc : nonExistingDescriptions) {
        courseDescriptionDAO.delete(desc);
    }
    // Personnel
    Set<Long> existingIds = new HashSet<>();
    int rowCount = requestContext.getInteger("personnelTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "personnelTable." + i;
        Long courseUserId = requestContext.getLong(colPrefix + ".courseUserId");
        Long userId = requestContext.getLong(colPrefix + ".userId");
        Long roleId = requestContext.getLong(colPrefix + ".roleId");
        staffMember = userDAO.findById(userId);
        CourseStaffMemberRole role = courseStaffMemberRoleDAO.findById(roleId);
        if (courseUserId == -1) {
            courseUserId = courseStaffMemberDAO.create(course, staffMember, role).getId();
        } else {
            courseStaffMemberDAO.updateRole(courseStaffMemberDAO.findById(courseUserId), role);
        }
        existingIds.add(courseUserId);
    }
    List<CourseStaffMember> courseUsers = courseStaffMemberDAO.listByCourse(courseDAO.findById(courseId));
    for (CourseStaffMember courseUser : courseUsers) {
        if (!existingIds.contains(courseUser.getId())) {
            courseStaffMemberDAO.delete(courseUser);
        }
    }
    // Course components
    rowCount = requestContext.getInteger("components.componentCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "components.component." + i;
        Long componentId = requestContext.getLong(colPrefix + ".0.componentId");
        String componentName = requestContext.getString(colPrefix + ".0.name");
        Double componentLength = requestContext.getDouble(colPrefix + ".0.length");
        String componentDescription = requestContext.getString(colPrefix + ".0.description");
        // TODO Component length; should be just hours but it currently depends on the default time unit - ok?
        EducationalTimeUnit componentTimeUnit = defaultsDAO.getDefaults().getBaseTimeUnit();
        CourseComponent courseComponent;
        if (componentId == -1) {
            courseComponent = componentDAO.create(course, componentLength, componentTimeUnit, componentName, componentDescription);
        } else {
            courseComponent = componentDAO.update(componentDAO.findById(componentId), componentLength, componentTimeUnit, componentName, componentDescription);
        }
        Long resourceCategoryCount = requestContext.getLong(colPrefix + ".resourceCategoryCount");
        for (int categoryIndex = 0; categoryIndex < resourceCategoryCount; categoryIndex++) {
            String resourcesPrefix = colPrefix + "." + categoryIndex + ".resources";
            Long resourcesCount = requestContext.getLong(resourcesPrefix + ".rowCount");
            for (int j = 0; j < resourcesCount; j++) {
                String resourcePrefix = resourcesPrefix + "." + j;
                Long id = requestContext.getLong(resourcePrefix + ".id");
                Long resourceId = requestContext.getLong(resourcePrefix + ".resourceId");
                Resource resource = resourceDAO.findById(resourceId);
                Double usagePercent;
                if (resource.getResourceType() == ResourceType.MATERIAL_RESOURCE) {
                    usagePercent = requestContext.getDouble(resourcePrefix + ".quantity") * 100;
                } else {
                    usagePercent = requestContext.getDouble(resourcePrefix + ".usage");
                }
                if (id == -1) {
                    componentResourceDAO.create(courseComponent, resource, usagePercent);
                } else {
                    CourseComponentResource courseComponentResource = componentResourceDAO.findById(id);
                    componentResourceDAO.updateUsagePercent(courseComponentResource, usagePercent);
                }
            }
        }
    }
    // Basic course resources
    existingIds = new HashSet<>();
    rowCount = requestContext.getInteger("basicResourcesTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "basicResourcesTable." + i;
        Double hours = requestContext.getDouble(colPrefix + ".hours");
        if (hours == null) {
            hours = 0.0;
        }
        MonetaryAmount hourlyCost = new MonetaryAmount();
        hourlyCost.setAmount(requestContext.getDouble(colPrefix + ".hourlyCost"));
        Integer units = requestContext.getInteger(colPrefix + ".units");
        MonetaryAmount unitCost = new MonetaryAmount();
        unitCost.setAmount(requestContext.getDouble(colPrefix + ".unitCost"));
        Long resourceId = requestContext.getLong(colPrefix + ".resourceId");
        Resource resource = resourceDAO.findById(resourceId);
        Long basicResourceId = requestContext.getLong(colPrefix + ".basicResourceId");
        if (basicResourceId == -1) {
            basicResourceId = basicCourseResourceDAO.create(course, resource, hours, hourlyCost, units, unitCost).getId();
        } else {
            basicCourseResourceDAO.update(basicCourseResourceDAO.findById(basicResourceId), hours, hourlyCost, units, unitCost);
        }
        existingIds.add(basicResourceId);
    }
    List<BasicCourseResource> basicCourseResources = basicCourseResourceDAO.listByCourse(course);
    for (BasicCourseResource basicCourseResource : basicCourseResources) {
        if (!existingIds.contains(basicCourseResource.getId())) {
            basicCourseResourceDAO.delete(basicCourseResource);
        }
    }
    // Student course resources
    existingIds = new HashSet<>();
    rowCount = requestContext.getInteger("studentResourcesTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "studentResourcesTable." + i;
        Double hours = requestContext.getDouble(colPrefix + ".hours");
        if (hours == null) {
            hours = 0.0;
        }
        MonetaryAmount hourlyCost = new MonetaryAmount();
        hourlyCost.setAmount(requestContext.getDouble(colPrefix + ".hourlyCost"));
        MonetaryAmount unitCost = new MonetaryAmount();
        hourlyCost.setAmount(requestContext.getDouble(colPrefix + ".unitCost"));
        Long resourceId = requestContext.getLong(colPrefix + ".resourceId");
        Resource resource = resourceDAO.findById(resourceId);
        Long studentResourceId = requestContext.getLong(colPrefix + ".studentResourceId");
        if (studentResourceId == -1) {
            studentResourceId = studentCourseResourceDAO.create(course, resource, hours, hourlyCost, unitCost).getId();
        } else {
            studentCourseResourceDAO.update(studentCourseResourceDAO.findById(studentResourceId), hours, hourlyCost, unitCost);
        }
        existingIds.add(studentResourceId);
    }
    List<StudentCourseResource> studentCourseResources = studentCourseResourceDAO.listByCourse(course);
    for (StudentCourseResource studentCourseResource : studentCourseResources) {
        if (!existingIds.contains(studentCourseResource.getId())) {
            studentCourseResourceDAO.delete(studentCourseResource);
        }
    }
    // Grade course resources
    existingIds = new HashSet<>();
    rowCount = requestContext.getInteger("gradeResourcesTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "gradeResourcesTable." + i;
        Double hours = requestContext.getDouble(colPrefix + ".hours");
        if (hours == null) {
            hours = 0.0;
        }
        MonetaryAmount hourlyCost = new MonetaryAmount();
        hourlyCost.setAmount(requestContext.getDouble(colPrefix + ".hourlyCost"));
        MonetaryAmount unitCost = new MonetaryAmount();
        unitCost.setAmount(requestContext.getDouble(colPrefix + ".unitCost"));
        Long resourceId = requestContext.getLong(colPrefix + ".resourceId");
        Resource resource = resourceDAO.findById(resourceId);
        Long gradeResourceId = requestContext.getLong(colPrefix + ".gradeResourceId");
        if (gradeResourceId == -1) {
            gradeResourceId = gradeCourseResourceDAO.create(course, resource, hours, hourlyCost, unitCost).getId();
        } else {
            gradeCourseResourceDAO.update(gradeCourseResourceDAO.findById(gradeResourceId), hours, hourlyCost, unitCost);
        }
        existingIds.add(gradeResourceId);
    }
    List<GradeCourseResource> gradeCourseResources = gradeCourseResourceDAO.listByCourse(course);
    for (GradeCourseResource gradeCourseResource : gradeCourseResources) {
        if (!existingIds.contains(gradeCourseResource.getId())) {
            gradeCourseResourceDAO.delete(gradeCourseResource);
        }
    }
    // Other costs
    existingIds = new HashSet<>();
    rowCount = requestContext.getInteger("otherCostsTable.rowCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "otherCostsTable." + i;
        name = requestContext.getString(colPrefix + ".name");
        MonetaryAmount cost = new MonetaryAmount();
        cost.setAmount(requestContext.getDouble(colPrefix + ".cost"));
        Long otherCostId = requestContext.getLong(colPrefix + ".otherCostId");
        if (otherCostId == -1) {
            otherCostId = otherCostDAO.create(course, name, cost).getId();
        } else {
            otherCostDAO.update(otherCostDAO.findById(otherCostId), name, cost);
        }
        existingIds.add(otherCostId);
    }
    List<OtherCost> otherCosts = otherCostDAO.listByCourse(course);
    for (OtherCost otherCost : otherCosts) {
        if (!existingIds.contains(otherCost.getId())) {
            otherCostDAO.delete(otherCost);
        }
    }
    // Students
    existingIds = new HashSet<>();
    rowCount = requestContext.getInteger("studentsTable.rowCount");
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "studentsTable." + i;
        Long studentId = requestContext.getLong(colPrefix + ".studentId");
        Long courseStudentId = requestContext.getLong(colPrefix + ".courseStudentId");
        Date enrolmentDate = requestContext.getDate(colPrefix + ".enrolmentDate");
        Long enrolmentTypeId = requestContext.getLong(colPrefix + ".enrolmentType");
        Long participationTypeId = requestContext.getLong(colPrefix + ".participationType");
        Boolean lodging = requestContext.getBoolean(colPrefix + ".lodging");
        CourseEnrolmentType enrolmentType = enrolmentTypeId != null ? enrolmentTypeDAO.findById(enrolmentTypeId) : null;
        CourseParticipationType participationType = participationTypeId != null ? participationTypeDAO.findById(participationTypeId) : null;
        CourseStudent courseStudent;
        CourseOptionality optionality = (CourseOptionality) requestContext.getEnum(colPrefix + ".optionality", CourseOptionality.class);
        if (courseStudentId == -1) {
            /* New student */
            Student student = studentDAO.findById(studentId);
            String organizationName = null;
            String additionalInfo = null;
            Room room = null;
            BigDecimal lodgingFee = null;
            Currency lodgingFeeCurrency = null;
            BigDecimal reservationFee = null;
            Currency reservationFeeCurrency = null;
            if (course.isCourseTemplate()) {
                throw new SmvcRuntimeException(PyramusStatusCode.UNDEFINED, Messages.getInstance().getText(locale, "generic.errors.cannotAddStudentsToCourseTemplate"));
            }
            try {
                courseStudent = courseStudentDAO.create(course, student, enrolmentType, participationType, enrolmentDate, lodging, optionality, null, organizationName, additionalInfo, room, lodgingFee, lodgingFeeCurrency, reservationFee, reservationFeeCurrency, Boolean.FALSE);
            } catch (DuplicateCourseStudentException dcse) {
                throw new SmvcRuntimeException(PyramusStatusCode.UNDEFINED, Messages.getInstance().getText(locale, "generic.errors.duplicateCourseStudent", new Object[] { student.getFullName() }));
            }
        } else {
            boolean modified = new Integer(1).equals(requestContext.getInteger(colPrefix + ".modified"));
            if (modified) {
                /* Existing student */
                Student student = studentDAO.findById(studentId);
                courseStudent = courseStudentDAO.findById(courseStudentId);
                try {
                    courseStudentDAO.update(courseStudent, student, enrolmentType, participationType, enrolmentDate, lodging, optionality);
                } catch (DuplicateCourseStudentException dcse) {
                    throw new SmvcRuntimeException(PyramusStatusCode.UNDEFINED, Messages.getInstance().getText(locale, "generic.errors.duplicateCourseStudent", new Object[] { student.getFullName() }));
                }
            }
        }
    }
    processSignupStudyProgrammes(requestContext, course, loggedUser);
    processSignupStudentGroups(requestContext, course, loggedUser);
    requestContext.setRedirectURL(requestContext.getReferer(true));
}
Also used : BasicCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.BasicCourseResourceDAO) StudentCourseResource(fi.otavanopisto.pyramus.domainmodel.courses.StudentCourseResource) Currency(java.util.Currency) StudentCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.StudentCourseResourceDAO) Vector(java.util.Vector) MonetaryAmount(fi.otavanopisto.pyramus.persistence.usertypes.MonetaryAmount) EducationalTimeUnitDAO(fi.otavanopisto.pyramus.dao.base.EducationalTimeUnitDAO) CourseEducationSubtype(fi.otavanopisto.pyramus.domainmodel.base.CourseEducationSubtype) CourseEducationTypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationTypeDAO) CourseStudent(fi.otavanopisto.pyramus.domainmodel.courses.CourseStudent) Student(fi.otavanopisto.pyramus.domainmodel.students.Student) CourseStaffMemberRoleDAO(fi.otavanopisto.pyramus.dao.courses.CourseStaffMemberRoleDAO) CourseStudentDAO(fi.otavanopisto.pyramus.dao.courses.CourseStudentDAO) StudentDAO(fi.otavanopisto.pyramus.dao.students.StudentDAO) CourseEnrolmentTypeDAO(fi.otavanopisto.pyramus.dao.courses.CourseEnrolmentTypeDAO) Module(fi.otavanopisto.pyramus.domainmodel.modules.Module) Map(java.util.Map) HashMap(java.util.HashMap) CourseTypeDAO(fi.otavanopisto.pyramus.dao.courses.CourseTypeDAO) Organization(fi.otavanopisto.pyramus.domainmodel.base.Organization) CourseEducationType(fi.otavanopisto.pyramus.domainmodel.base.CourseEducationType) EducationType(fi.otavanopisto.pyramus.domainmodel.base.EducationType) DuplicateCourseStudentException(fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException) SubjectDAO(fi.otavanopisto.pyramus.dao.base.SubjectDAO) CourseDescriptionCategoryDAO(fi.otavanopisto.pyramus.dao.courses.CourseDescriptionCategoryDAO) CourseComponent(fi.otavanopisto.pyramus.domainmodel.courses.CourseComponent) CourseType(fi.otavanopisto.pyramus.domainmodel.courses.CourseType) CurriculumDAO(fi.otavanopisto.pyramus.dao.base.CurriculumDAO) TagDAO(fi.otavanopisto.pyramus.dao.base.TagDAO) GradeCourseResource(fi.otavanopisto.pyramus.domainmodel.courses.GradeCourseResource) CourseEnrolmentType(fi.otavanopisto.pyramus.domainmodel.courses.CourseEnrolmentType) CourseEducationSubtypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationSubtypeDAO) EducationSubtypeDAO(fi.otavanopisto.pyramus.dao.base.EducationSubtypeDAO) CourseEducationSubtypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationSubtypeDAO) BasicCourseResource(fi.otavanopisto.pyramus.domainmodel.courses.BasicCourseResource) Curriculum(fi.otavanopisto.pyramus.domainmodel.base.Curriculum) CourseComponentResourceDAO(fi.otavanopisto.pyramus.dao.courses.CourseComponentResourceDAO) GradeCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.GradeCourseResourceDAO) StudentCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.StudentCourseResourceDAO) BasicCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.BasicCourseResourceDAO) ResourceDAO(fi.otavanopisto.pyramus.dao.resources.ResourceDAO) Tag(fi.otavanopisto.pyramus.domainmodel.base.Tag) Locale(java.util.Locale) CourseStaffMemberRole(fi.otavanopisto.pyramus.domainmodel.courses.CourseStaffMemberRole) HashMap(java.util.HashMap) CourseDAO(fi.otavanopisto.pyramus.dao.courses.CourseDAO) CourseDescriptionDAO(fi.otavanopisto.pyramus.dao.courses.CourseDescriptionDAO) ModuleDAO(fi.otavanopisto.pyramus.dao.modules.ModuleDAO) SmvcRuntimeException(fi.internetix.smvc.SmvcRuntimeException) CourseStaffMember(fi.otavanopisto.pyramus.domainmodel.courses.CourseStaffMember) StaffMember(fi.otavanopisto.pyramus.domainmodel.users.StaffMember) CourseDescription(fi.otavanopisto.pyramus.domainmodel.courses.CourseDescription) CourseComponentResource(fi.otavanopisto.pyramus.domainmodel.courses.CourseComponentResource) Course(fi.otavanopisto.pyramus.domainmodel.courses.Course) OrganizationDAO(fi.otavanopisto.pyramus.dao.base.OrganizationDAO) EducationalTimeUnit(fi.otavanopisto.pyramus.domainmodel.base.EducationalTimeUnit) HashSet(java.util.HashSet) CourseEducationType(fi.otavanopisto.pyramus.domainmodel.base.CourseEducationType) CourseParticipationTypeDAO(fi.otavanopisto.pyramus.dao.courses.CourseParticipationTypeDAO) CourseComponentDAO(fi.otavanopisto.pyramus.dao.courses.CourseComponentDAO) CourseEducationSubtype(fi.otavanopisto.pyramus.domainmodel.base.CourseEducationSubtype) EducationSubtype(fi.otavanopisto.pyramus.domainmodel.base.EducationSubtype) CourseStudentDAO(fi.otavanopisto.pyramus.dao.courses.CourseStudentDAO) BasicCourseResource(fi.otavanopisto.pyramus.domainmodel.courses.BasicCourseResource) GradeCourseResource(fi.otavanopisto.pyramus.domainmodel.courses.GradeCourseResource) Resource(fi.otavanopisto.pyramus.domainmodel.resources.Resource) StudentCourseResource(fi.otavanopisto.pyramus.domainmodel.courses.StudentCourseResource) CourseComponentResource(fi.otavanopisto.pyramus.domainmodel.courses.CourseComponentResource) DefaultsDAO(fi.otavanopisto.pyramus.dao.base.DefaultsDAO) OtherCostDAO(fi.otavanopisto.pyramus.dao.courses.OtherCostDAO) OtherCost(fi.otavanopisto.pyramus.domainmodel.courses.OtherCost) CourseEducationTypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationTypeDAO) EducationTypeDAO(fi.otavanopisto.pyramus.dao.base.EducationTypeDAO) CourseStaffMemberDAO(fi.otavanopisto.pyramus.dao.courses.CourseStaffMemberDAO) StaleObjectStateException(org.hibernate.StaleObjectStateException) GradeCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.GradeCourseResourceDAO) CourseComponentResourceDAO(fi.otavanopisto.pyramus.dao.courses.CourseComponentResourceDAO) CourseOptionality(fi.otavanopisto.pyramus.domainmodel.base.CourseOptionality) CourseStateDAO(fi.otavanopisto.pyramus.dao.courses.CourseStateDAO) StaffMemberDAO(fi.otavanopisto.pyramus.dao.users.StaffMemberDAO) CourseStaffMemberDAO(fi.otavanopisto.pyramus.dao.courses.CourseStaffMemberDAO) CourseDescriptionCategory(fi.otavanopisto.pyramus.domainmodel.courses.CourseDescriptionCategory) CourseStudent(fi.otavanopisto.pyramus.domainmodel.courses.CourseStudent) CourseState(fi.otavanopisto.pyramus.domainmodel.courses.CourseState) CourseParticipationType(fi.otavanopisto.pyramus.domainmodel.courses.CourseParticipationType) Room(fi.otavanopisto.pyramus.domainmodel.accommodation.Room) Date(java.util.Date) Subject(fi.otavanopisto.pyramus.domainmodel.base.Subject) BigDecimal(java.math.BigDecimal) CourseStaffMember(fi.otavanopisto.pyramus.domainmodel.courses.CourseStaffMember)

Example 5 with DuplicateCourseStudentException

use of fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException in project pyramus by otavanopisto.

the class CreateCourseJSONRequestController method process.

/**
 * Processes a JSON request.
 * The request should contain the following parameters:
 * <dl>
 *   <dt><code>name</code></dt>
 *   <dd>The name of the course.</dd>
 *   <dt><code>nameExtension</code></dt>
 *   <dd>The name extension of the course.</dd>
 *   <dt><code>state</code></dt>
 *   <dd>The ID of the initial course state.</dd>
 *   <dt><code>description</code></dt>
 *   <dd>The description of the course, in HTML.</dd>
 *   <dt><code>module</code></dt>
 *   <dd>The ID of the module the course is associated with.</dd>
 *   <dt><code>subject</code></dt>
 *   <dd>The ID of the subject of the course.</dd>
 *   <dt><code>courseNumber</code></dt>
 *   <dd>The course number of the course.</dd>
 *   <dt><code>beginDate</code></dt>
 *   <dd>The beginning date of the course, as a timestamp in ms.</dd>
 *   <dt><code>endDate</code></dt>
 *   <dd>The end date of the course, as a timestamp in ms.</dd>
 *   <dt><code>enrolmentTimeEnd</code></dt>
 *   <dd>The time when enrollment for the course ends, as a timestamp in ms.</dd>
 *   <dt><code>courseLength</code></dt>
 *   <dd>The length of the course, in units specified in <code>courseLengthTimeUnit</code>.</dd>
 *   <dt><code>courseLengthTimeUnit</code></dt>
 *   <dd>The ID of the time unit for the courses.</dd>
 *   <dt><code>maxParticipantCount</code></dt>
 *   <dd>The maximum number of participants for this course.</dd>
 *   <dt><code>distanceTeachingDays</code></dt>
 *   <dd>The number of days of distance teaching.</dd>
 *   <dt><code>localTeachingDays</code></dt>
 *   <dd>The number of days of local teaching.</dd>
 *   <dt><code>teachingHours</code></dt>
 *   <dd>The total number of teaching hours.</dd>
 *   <dt><code>planningHours</code></dt>
 *   <dd>The total number of hours used for planning.
 *   <dt><code>assessingHours</code></dt>
 *   <dd>The total number of hours used for assessing.
 *   <dt><code>tags</code></dt>
 *   <dd>The tags associated with the course, separated by spaces.</dd>
 * </dl>
 * The following are not single but multiple parameters, arranged
 * as collections of objects. Each parameter is defined by the
 * following scheme (zero indexed):<br/>
 * <code>
 * <i>collection name</i>.<i>property name</i>
 * </code>
 * or<br/>
 * <code>
 * <i>collection name</i>.<i>object index</i>.<i>property name</i>
 * </code>
 * <dl>
 *   <dt><code>courseDescription.*.catId</code></dt>
 *   <dd>The course description category ID to add the description to.
 *   <dt><code>courseDescription.*.text</code></dt>
 *   <dd>The description of the course.</dd>
 *   <dt><code>personnelTable.rowCount</code></dt>
 *   <dd>The number of personnel in the course.</dd>
 *   <dt><code>personnelTable.*.userId</code></dt>
 *   <dd>The ID of the user in the personnel table.</dd>
 *   <dt><code>personnelTable.*.roleId</code></dt>
 *   <dd>The role ID of the user in the personnel table.</dd>
 *   <dt><code>components.componentCount</code></dt>
 *   <dd>The number of course components in this course.</dd>
 *   <dt><code>components.*.0.name</code></dt>
 *   <dd>The name of the course component.</dd>
 *   <dt><code>components.*.0.length</code></dt>
 *   <dd>The length of the course component, in default time units.</dd>
 *   <dt><code>components.*.0.description</code></dt>
 *   <dd>The description of the course component.</dd>
 *   <dt><code>components.*.resourceCategoryCount</code></dt>
 *   <dd>The number of resource categories in the course component.</dd>
 *   <dt><code>components.*.*.resources.rowCount</code></dt>
 *   <dd>The number of resources in the resource category.</dd>
 *   <dt><code>components.*.*.resources.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>components.*.*.resources.*.quantity</code></dt>
 *   <dd>The quantity of the resource.</dd>
 *   <dt><code>components.*.*.resources.*.usage</code></dt>
 *   <dd>The usage of the resource.</dd>
 *   <dt><code>educationType.*.*</code></dt>
 *   <dd>The education types and subtypes (as numerical IDs) of the course.</dd>
 *   <dt><code>basicResourcesTable.rowCount</code></dt>
 *   <dd>The number of basic resources associated with the course.</dd>
 *   <dt><code>basicResourcesTable.*.hours</code></dt>
 *   <dd>The number of hours the resource is used.</dd>
 *   <dt><code>basicResourcesTable.*.hourlyCost</code></dt>
 *   <dd>The hourly cost of the resource.</dd>
 *   <dt><code>basicResourcesTable.*.units</code></dt>
 *   <dd>The number of units of the resource used.</dd>
 *   <dt><code>basicResourcesTable.*.unitCost</code></dt>
 *   <dd>The cost of a single unit of the resource.</dd>
 *   <dt><code>basicResourcesTable.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>studentResourcesTable.rowCount</code></dt>
 *   <dd>The number of student resources associated with the course.</dd>
 *   <dt><code>studentResourcesTable.*.hours</code></dt>
 *   <dd>The number of hours the resource is used.</dd>
 *   <dt><code>studentResourcesTable.*.hourlyCost</code></dt>
 *   <dd>The hourly cost of the resource.</dd>
 *   <dt><code>studentResourcesTable.*.unitCost</code></dt>
 *   <dd>The cost of a single unit of the resource.</dd>
 *   <dt><code>studentResourcesTable.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>gradeResourcesTable.rowCount</code></dt>
 *   <dd>The number of grade resources associated with the course.</dd>
 *   <dt><code>gradeResourcesTable.*.hours</code></dt>
 *   <dd>The number of hours the resource is used.</dd>
 *   <dt><code>gradeResourcesTable.*.hourlyCost</code></dt>
 *   <dd>The hourly cost of the resource.</dd>
 *   <dt><code>gradeResourcesTable.*.unitCost</code></dt>
 *   <dd>The cost of a single unit of the resource.</dd>
 *   <dt><code>gradeResourcesTable.*.resourceId</code></dt>
 *   <dd>The ID of the resource.</dd>
 *   <dt><code>otherCostsTable.rowCount</code></dt>
 *   <dd>The number of other costs associated with this course.</dd>
 *   <dt><code>otherCostsTable.*.name</code></dt>
 *   <dd>The name of the cost.</dd>
 *   <dt><code>otherCostsTable.*.count</code></dt>
 *   <dd>The amount of the cost.</dd>
 *   <dt><code>studentsTable.rowCount</code></dt>
 *   <dd>The number of students attending this course.</dd>
 *   <dt><code>studentsTable.*.studentId</code></dt>
 *   <dd>The ID of the student.</dd>
 *   <dt><code>studentsTable.*.enrolmentDate</code></dt>
 *   <dd>The enrollment date of the student, as a timestamp in ms.</dd>
 *   <dt><code>studentsTable.*.enrolmentType</code></dt>
 *   <dd>The ID of the enrollment type of the student.</dd>
 *   <dt><code>studentsTable.*.participationType</code></dt>
 *   <dd>The ID of the participation type of the student.</dd>
 *   <dt><code>studentsTable.*.lodging</code></dt>
 *   <dd><code>true</code> if the student is lodging on campus.</dd>
 *   <dt><code>studentsTable.*.optionality</code></dt>
 *   <dd>The optionality of the course for the student:
 *   <code>MANDATORY</code> or <code>OPTIONAL</code></dd>
 * </dl>
 *
 * @param binaryRequestContext The context of the binary request.
 */
public void process(JSONRequestContext requestContext) {
    StaffMemberDAO userDAO = DAOFactory.getInstance().getStaffMemberDAO();
    StudentDAO studentDAO = DAOFactory.getInstance().getStudentDAO();
    CourseDAO courseDAO = DAOFactory.getInstance().getCourseDAO();
    ModuleDAO moduleDAO = DAOFactory.getInstance().getModuleDAO();
    ResourceDAO resourceDAO = DAOFactory.getInstance().getResourceDAO();
    CourseStateDAO courseStateDAO = DAOFactory.getInstance().getCourseStateDAO();
    CourseTypeDAO courseTypeDAO = DAOFactory.getInstance().getCourseTypeDAO();
    CourseParticipationTypeDAO participationTypeDAO = DAOFactory.getInstance().getCourseParticipationTypeDAO();
    CourseEnrolmentTypeDAO enrolmentTypeDAO = DAOFactory.getInstance().getCourseEnrolmentTypeDAO();
    CourseStudentDAO courseStudentDAO = DAOFactory.getInstance().getCourseStudentDAO();
    CourseStaffMemberDAO courseStaffMemberDAO = DAOFactory.getInstance().getCourseStaffMemberDAO();
    CourseDescriptionDAO descriptionDAO = DAOFactory.getInstance().getCourseDescriptionDAO();
    CourseDescriptionCategoryDAO descriptionCategoryDAO = DAOFactory.getInstance().getCourseDescriptionCategoryDAO();
    CourseComponentDAO componentDAO = DAOFactory.getInstance().getCourseComponentDAO();
    CourseComponentResourceDAO componentResourceDAO = DAOFactory.getInstance().getCourseComponentResourceDAO();
    OtherCostDAO otherCostDAO = DAOFactory.getInstance().getOtherCostDAO();
    BasicCourseResourceDAO basicCourseResourceDAO = DAOFactory.getInstance().getBasicCourseResourceDAO();
    StudentCourseResourceDAO studentCourseResourceDAO = DAOFactory.getInstance().getStudentCourseResourceDAO();
    GradeCourseResourceDAO gradeCourseResourceDAO = DAOFactory.getInstance().getGradeCourseResourceDAO();
    CourseEducationTypeDAO courseEducationTypeDAO = DAOFactory.getInstance().getCourseEducationTypeDAO();
    CourseEducationSubtypeDAO courseEducationSubtypeDAO = DAOFactory.getInstance().getCourseEducationSubtypeDAO();
    EducationalTimeUnitDAO educationalTimeUnitDAO = DAOFactory.getInstance().getEducationalTimeUnitDAO();
    EducationTypeDAO educationTypeDAO = DAOFactory.getInstance().getEducationTypeDAO();
    EducationSubtypeDAO educationSubtypeDAO = DAOFactory.getInstance().getEducationSubtypeDAO();
    SubjectDAO subjectDAO = DAOFactory.getInstance().getSubjectDAO();
    TagDAO tagDAO = DAOFactory.getInstance().getTagDAO();
    DefaultsDAO defaultsDAO = DAOFactory.getInstance().getDefaultsDAO();
    CourseStaffMemberRoleDAO courseStaffMemberRoleDAO = DAOFactory.getInstance().getCourseStaffMemberRoleDAO();
    CurriculumDAO curriculumDAO = DAOFactory.getInstance().getCurriculumDAO();
    OrganizationDAO organizationDAO = DAOFactory.getInstance().getOrganizationDAO();
    StaffMemberDAO staffMemberDAO = DAOFactory.getInstance().getStaffMemberDAO();
    User loggedUser = staffMemberDAO.findById(requestContext.getLoggedUserId());
    Organization organization = organizationDAO.findById(requestContext.getLong("organizationId"));
    if (!UserUtils.canAccessOrganization(loggedUser, organization)) {
        throw new SmvcRuntimeException(PyramusStatusCode.UNAUTHORIZED, "Invalid organization.");
    }
    // Course basic information
    String name = requestContext.getString("name");
    String nameExtension = requestContext.getString("nameExtension");
    Long courseStateId = requestContext.getLong("state");
    Long courseTypeId = requestContext.getLong("type");
    CourseState courseState = courseStateDAO.findById(courseStateId);
    CourseType courseType = courseTypeId != null ? courseTypeDAO.findById(courseTypeId) : null;
    String description = requestContext.getString("description");
    Module module = moduleDAO.findById(requestContext.getLong("module"));
    Subject subject = subjectDAO.findById(requestContext.getLong("subject"));
    Integer courseNumber = requestContext.getInteger("courseNumber");
    Date beginDate = requestContext.getDate("beginDate");
    Date endDate = requestContext.getDate("endDate");
    Date enrolmentTimeEnd = requestContext.getDate("enrolmentTimeEnd");
    Double courseLength = requestContext.getDouble("courseLength");
    Long courseLengthTimeUnitId = requestContext.getLong("courseLengthTimeUnit");
    Long maxParticipantCount = requestContext.getLong("maxParticipantCount");
    EducationalTimeUnit courseLengthTimeUnit = educationalTimeUnitDAO.findById(courseLengthTimeUnitId);
    Double distanceTeachingDays = requestContext.getDouble("distanceTeachingDays");
    Double localTeachingDays = requestContext.getDouble("localTeachingDays");
    Double teachingHours = requestContext.getDouble("teachingHours");
    Double distanceTeachingHours = requestContext.getDouble("distanceTeachingHours");
    Double planningHours = requestContext.getDouble("planningHours");
    Double assessingHours = requestContext.getDouble("assessingHours");
    String tagsText = requestContext.getString("tags");
    BigDecimal courseFee = requestContext.getBigDecimal("courseFee");
    Currency courseFeeCurrency = requestContext.getCurrency("courseFeeCurrency");
    List<Curriculum> allCurriculums = curriculumDAO.listUnarchived();
    Set<Curriculum> curriculums = new HashSet<>();
    for (Curriculum curriculum : allCurriculums) {
        if ("1".equals(requestContext.getString("curriculum." + curriculum.getId()))) {
            curriculums.add(curriculum);
        }
    }
    Set<Tag> tagEntities = new HashSet<>();
    if (!StringUtils.isBlank(tagsText)) {
        List<String> tags = Arrays.asList(tagsText.split("[\\ ,]"));
        for (String tag : tags) {
            if (!StringUtils.isBlank(tag)) {
                Tag tagEntity = tagDAO.findByText(tag.trim());
                if (tagEntity == null)
                    tagEntity = tagDAO.create(tag);
                tagEntities.add(tagEntity);
            }
        }
    }
    Course course = courseDAO.create(module, organization, name, nameExtension, courseState, courseType, subject, courseNumber, beginDate, endDate, courseLength, courseLengthTimeUnit, distanceTeachingDays, localTeachingDays, teachingHours, distanceTeachingHours, planningHours, assessingHours, description, maxParticipantCount, courseFee, courseFeeCurrency, enrolmentTimeEnd, loggedUser);
    // Curriculums
    courseDAO.updateCurriculums(course, curriculums);
    // Tags
    courseDAO.setCourseTags(course, tagEntities);
    // Course Descriptions
    List<CourseDescriptionCategory> descriptionCategories = descriptionCategoryDAO.listUnarchived();
    for (CourseDescriptionCategory cat : descriptionCategories) {
        String varName = "courseDescription." + cat.getId().toString();
        Long descriptionCatId = requestContext.getLong(varName + ".catId");
        String descriptionText = requestContext.getString(varName + ".text");
        if (descriptionCatId != null && descriptionCatId.intValue() != -1) {
            // Description has been submitted from form
            descriptionDAO.create(course, cat, descriptionText);
        }
    }
    // Personnel
    int rowCount = requestContext.getInteger("personnelTable.rowCount");
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "personnelTable." + i;
        Long userId = requestContext.getLong(colPrefix + ".userId");
        Long roleId = requestContext.getLong(colPrefix + ".roleId");
        StaffMember staffMember = userDAO.findById(userId);
        CourseStaffMemberRole role = courseStaffMemberRoleDAO.findById(roleId);
        courseStaffMemberDAO.create(course, staffMember, role);
    }
    // Course components
    rowCount = requestContext.getInteger("components.componentCount").intValue();
    for (int i = 0; i < rowCount; i++) {
        String colPrefix = "components.component." + i;
        String componentName = requestContext.getString(colPrefix + ".0.name");
        Double componentLength = requestContext.getDouble(colPrefix + ".0.length");
        String componentDescription = requestContext.getString(colPrefix + ".0.description");
        // TODO Component length; should be just hours but it currently depends on the default time unit - ok?
        EducationalTimeUnit componentTimeUnit = defaultsDAO.getDefaults().getBaseTimeUnit();
        CourseComponent courseComponent = componentDAO.create(course, componentLength, componentTimeUnit, componentName, componentDescription);
        Long resourceCategoryCount = requestContext.getLong(colPrefix + ".resourceCategoryCount");
        for (int categoryIndex = 0; categoryIndex < resourceCategoryCount; categoryIndex++) {
            String resourcesPrefix = colPrefix + "." + categoryIndex + ".resources";
            Long resourcesCount = requestContext.getLong(resourcesPrefix + ".rowCount");
            for (int j = 0; j < resourcesCount; j++) {
                String resourcePrefix = resourcesPrefix + "." + j;
                Long resourceId = requestContext.getLong(resourcePrefix + ".resourceId");
                Resource resource = resourceDAO.findById(resourceId);
                Double usagePercent;
                if (resource.getResourceType() == ResourceType.MATERIAL_RESOURCE) {
                    usagePercent = requestContext.getDouble(resourcePrefix + ".quantity") * 100;
                } else {
                    usagePercent = requestContext.getDouble(resourcePrefix + ".usage");
                }
                componentResourceDAO.create(courseComponent, resource, usagePercent);
            }
        }
    }
    // Education types and subtypes submitted from the web page
    Map<Long, Vector<Long>> chosenEducationTypes = new HashMap<>();
    Enumeration<String> parameterNames = requestContext.getRequest().getParameterNames();
    while (parameterNames.hasMoreElements()) {
        name = (String) parameterNames.nextElement();
        if (name.startsWith("educationType.")) {
            String[] nameElements = name.split("\\.");
            Long educationTypeId = new Long(nameElements[1]);
            Long educationSubtypeId = new Long(nameElements[2]);
            Vector<Long> v = chosenEducationTypes.containsKey(educationTypeId) ? chosenEducationTypes.get(educationTypeId) : new Vector<Long>();
            v.add(educationSubtypeId);
            if (!chosenEducationTypes.containsKey(educationTypeId)) {
                chosenEducationTypes.put(educationTypeId, v);
            }
        }
    }
    for (Map.Entry<Long, Vector<Long>> entry : chosenEducationTypes.entrySet()) {
        EducationType educationType = educationTypeDAO.findById(entry.getKey());
        CourseEducationType courseEducationType;
        if (!course.contains(educationType)) {
            courseEducationType = courseEducationTypeDAO.create(course, educationType);
        } else {
            courseEducationType = course.getCourseEducationTypeByEducationTypeId(entry.getKey());
        }
        for (Long educationSubtypeId : entry.getValue()) {
            EducationSubtype educationSubtype = educationSubtypeDAO.findById(educationSubtypeId);
            if (!courseEducationType.contains(educationSubtype)) {
                courseEducationSubtypeDAO.create(courseEducationType, educationSubtype);
            }
        }
    }
    // Basic course resources
    int basicResourcesTableRowCount = requestContext.getInteger("basicResourcesTable.rowCount");
    for (int i = 0; i < basicResourcesTableRowCount; i++) {
        String colPrefix = "basicResourcesTable." + i;
        Double hours = requestContext.getDouble(colPrefix + ".hours");
        if (hours == null) {
            hours = 0.0;
        }
        MonetaryAmount hourlyCost = new MonetaryAmount();
        hourlyCost.setAmount(requestContext.getDouble(colPrefix + ".hourlyCost"));
        Integer units = requestContext.getInteger(colPrefix + ".units");
        if (units == null) {
            units = 0;
        }
        MonetaryAmount unitCost = new MonetaryAmount();
        unitCost.setAmount(requestContext.getDouble(colPrefix + ".unitCost"));
        Long resourceId = requestContext.getLong(colPrefix + ".resourceId");
        Resource resource = resourceDAO.findById(resourceId);
        basicCourseResourceDAO.create(course, resource, hours, hourlyCost, units, unitCost);
    }
    // Student course resources
    int studentResourcesTableRowCount = requestContext.getInteger("studentResourcesTable.rowCount");
    for (int i = 0; i < studentResourcesTableRowCount; i++) {
        String colPrefix = "studentResourcesTable." + i;
        Double hours = requestContext.getDouble(colPrefix + ".hours");
        if (hours == null) {
            hours = 0.0;
        }
        MonetaryAmount hourlyCost = new MonetaryAmount();
        hourlyCost.setAmount(requestContext.getDouble(colPrefix + ".hourlyCost"));
        MonetaryAmount unitCost = new MonetaryAmount();
        unitCost.setAmount(requestContext.getDouble(colPrefix + ".unitCost"));
        Long resourceId = NumberUtils.createLong(requestContext.getRequest().getParameter(colPrefix + ".resourceId"));
        Resource resource = resourceDAO.findById(resourceId);
        studentCourseResourceDAO.create(course, resource, hours, hourlyCost, unitCost);
    }
    // Grade course resources
    int gradeResourcesTableRowCount = requestContext.getInteger("gradeResourcesTable.rowCount");
    for (int i = 0; i < gradeResourcesTableRowCount; i++) {
        String colPrefix = "gradeResourcesTable." + i;
        Double hours = requestContext.getDouble(colPrefix + ".hours");
        if (hours == null) {
            hours = 0.0;
        }
        MonetaryAmount hourlyCost = new MonetaryAmount();
        hourlyCost.setAmount(requestContext.getDouble(colPrefix + ".hourlyCost"));
        MonetaryAmount unitCost = new MonetaryAmount();
        unitCost.setAmount(requestContext.getDouble(colPrefix + ".unitCost"));
        Long resourceId = requestContext.getLong(colPrefix + ".resourceId");
        Resource resource = resourceDAO.findById(resourceId);
        gradeCourseResourceDAO.create(course, resource, hours, hourlyCost, unitCost);
    }
    // Other costs
    int otherCostsTableRowCount = requestContext.getInteger("otherCostsTable.rowCount");
    for (int i = 0; i < otherCostsTableRowCount; i++) {
        String colPrefix = "otherCostsTable." + i;
        name = requestContext.getString(colPrefix + ".name");
        MonetaryAmount cost = new MonetaryAmount();
        cost.setAmount(requestContext.getDouble(colPrefix + ".cost"));
        otherCostDAO.create(course, name, cost);
    }
    // Students
    int studentsTableRowCount = requestContext.getInteger("studentsTable.rowCount");
    for (int i = 0; i < studentsTableRowCount; i++) {
        String colPrefix = "studentsTable." + i;
        Long studentId = requestContext.getLong(colPrefix + ".studentId");
        Date enrolmentDate = requestContext.getDate(colPrefix + ".enrolmentDate");
        Long enrolmentTypeId = requestContext.getLong(colPrefix + ".enrolmentType");
        Long participationTypeId = requestContext.getLong(colPrefix + ".participationType");
        Boolean lodging = requestContext.getBoolean(colPrefix + ".lodging");
        String organizationName = null;
        String additionalInfo = null;
        Room room = null;
        BigDecimal lodgingFee = null;
        Currency lodgingFeeCurrency = null;
        BigDecimal reservationFee = null;
        Currency reservationFeeCurrency = null;
        Student student = studentDAO.findById(studentId);
        CourseEnrolmentType enrolmentType = enrolmentTypeId != null ? enrolmentTypeDAO.findById(enrolmentTypeId) : null;
        CourseParticipationType participationType = participationTypeId != null ? participationTypeDAO.findById(participationTypeId) : null;
        CourseOptionality optionality = (CourseOptionality) requestContext.getEnum(colPrefix + ".optionality", CourseOptionality.class);
        try {
            courseStudentDAO.create(course, student, enrolmentType, participationType, enrolmentDate, lodging, optionality, null, organizationName, additionalInfo, room, lodgingFee, lodgingFeeCurrency, reservationFee, reservationFeeCurrency, Boolean.FALSE);
        } catch (DuplicateCourseStudentException dcse) {
            Locale locale = requestContext.getRequest().getLocale();
            throw new SmvcRuntimeException(PyramusStatusCode.UNDEFINED, Messages.getInstance().getText(locale, "generic.errors.duplicateCourseStudent", new Object[] { student.getFullName() }));
        }
    }
    String redirectURL = requestContext.getRequest().getContextPath() + "/courses/editcourse.page?course=" + course.getId();
    String refererAnchor = requestContext.getRefererAnchor();
    if (!StringUtils.isBlank(refererAnchor))
        redirectURL += "#" + refererAnchor;
    requestContext.setRedirectURL(redirectURL);
}
Also used : Locale(java.util.Locale) CourseStaffMemberRole(fi.otavanopisto.pyramus.domainmodel.courses.CourseStaffMemberRole) BasicCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.BasicCourseResourceDAO) HashMap(java.util.HashMap) CourseDAO(fi.otavanopisto.pyramus.dao.courses.CourseDAO) CourseDescriptionDAO(fi.otavanopisto.pyramus.dao.courses.CourseDescriptionDAO) ModuleDAO(fi.otavanopisto.pyramus.dao.modules.ModuleDAO) SmvcRuntimeException(fi.internetix.smvc.SmvcRuntimeException) StaffMember(fi.otavanopisto.pyramus.domainmodel.users.StaffMember) Currency(java.util.Currency) Course(fi.otavanopisto.pyramus.domainmodel.courses.Course) StudentCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.StudentCourseResourceDAO) OrganizationDAO(fi.otavanopisto.pyramus.dao.base.OrganizationDAO) Vector(java.util.Vector) EducationalTimeUnit(fi.otavanopisto.pyramus.domainmodel.base.EducationalTimeUnit) HashSet(java.util.HashSet) CourseEducationType(fi.otavanopisto.pyramus.domainmodel.base.CourseEducationType) CourseParticipationTypeDAO(fi.otavanopisto.pyramus.dao.courses.CourseParticipationTypeDAO) CourseComponentDAO(fi.otavanopisto.pyramus.dao.courses.CourseComponentDAO) MonetaryAmount(fi.otavanopisto.pyramus.persistence.usertypes.MonetaryAmount) EducationalTimeUnitDAO(fi.otavanopisto.pyramus.dao.base.EducationalTimeUnitDAO) EducationSubtype(fi.otavanopisto.pyramus.domainmodel.base.EducationSubtype) CourseStudentDAO(fi.otavanopisto.pyramus.dao.courses.CourseStudentDAO) Resource(fi.otavanopisto.pyramus.domainmodel.resources.Resource) CourseEducationTypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationTypeDAO) DefaultsDAO(fi.otavanopisto.pyramus.dao.base.DefaultsDAO) Student(fi.otavanopisto.pyramus.domainmodel.students.Student) CourseStaffMemberRoleDAO(fi.otavanopisto.pyramus.dao.courses.CourseStaffMemberRoleDAO) CourseStudentDAO(fi.otavanopisto.pyramus.dao.courses.CourseStudentDAO) StudentDAO(fi.otavanopisto.pyramus.dao.students.StudentDAO) OtherCostDAO(fi.otavanopisto.pyramus.dao.courses.OtherCostDAO) CourseEnrolmentTypeDAO(fi.otavanopisto.pyramus.dao.courses.CourseEnrolmentTypeDAO) CourseEducationTypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationTypeDAO) EducationTypeDAO(fi.otavanopisto.pyramus.dao.base.EducationTypeDAO) CourseStaffMemberDAO(fi.otavanopisto.pyramus.dao.courses.CourseStaffMemberDAO) Module(fi.otavanopisto.pyramus.domainmodel.modules.Module) Map(java.util.Map) HashMap(java.util.HashMap) GradeCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.GradeCourseResourceDAO) CourseTypeDAO(fi.otavanopisto.pyramus.dao.courses.CourseTypeDAO) User(fi.otavanopisto.pyramus.domainmodel.users.User) Organization(fi.otavanopisto.pyramus.domainmodel.base.Organization) CourseComponentResourceDAO(fi.otavanopisto.pyramus.dao.courses.CourseComponentResourceDAO) CourseEducationType(fi.otavanopisto.pyramus.domainmodel.base.CourseEducationType) EducationType(fi.otavanopisto.pyramus.domainmodel.base.EducationType) DuplicateCourseStudentException(fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException) CourseOptionality(fi.otavanopisto.pyramus.domainmodel.base.CourseOptionality) SubjectDAO(fi.otavanopisto.pyramus.dao.base.SubjectDAO) CourseDescriptionCategoryDAO(fi.otavanopisto.pyramus.dao.courses.CourseDescriptionCategoryDAO) CourseComponent(fi.otavanopisto.pyramus.domainmodel.courses.CourseComponent) CourseStateDAO(fi.otavanopisto.pyramus.dao.courses.CourseStateDAO) StaffMemberDAO(fi.otavanopisto.pyramus.dao.users.StaffMemberDAO) CourseStaffMemberDAO(fi.otavanopisto.pyramus.dao.courses.CourseStaffMemberDAO) CourseDescriptionCategory(fi.otavanopisto.pyramus.domainmodel.courses.CourseDescriptionCategory) CourseState(fi.otavanopisto.pyramus.domainmodel.courses.CourseState) CourseType(fi.otavanopisto.pyramus.domainmodel.courses.CourseType) CourseParticipationType(fi.otavanopisto.pyramus.domainmodel.courses.CourseParticipationType) Room(fi.otavanopisto.pyramus.domainmodel.accommodation.Room) CurriculumDAO(fi.otavanopisto.pyramus.dao.base.CurriculumDAO) TagDAO(fi.otavanopisto.pyramus.dao.base.TagDAO) CourseEnrolmentType(fi.otavanopisto.pyramus.domainmodel.courses.CourseEnrolmentType) CourseEducationSubtypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationSubtypeDAO) Subject(fi.otavanopisto.pyramus.domainmodel.base.Subject) Date(java.util.Date) BigDecimal(java.math.BigDecimal) EducationSubtypeDAO(fi.otavanopisto.pyramus.dao.base.EducationSubtypeDAO) CourseEducationSubtypeDAO(fi.otavanopisto.pyramus.dao.base.CourseEducationSubtypeDAO) Curriculum(fi.otavanopisto.pyramus.domainmodel.base.Curriculum) CourseComponentResourceDAO(fi.otavanopisto.pyramus.dao.courses.CourseComponentResourceDAO) GradeCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.GradeCourseResourceDAO) StudentCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.StudentCourseResourceDAO) BasicCourseResourceDAO(fi.otavanopisto.pyramus.dao.courses.BasicCourseResourceDAO) ResourceDAO(fi.otavanopisto.pyramus.dao.resources.ResourceDAO) Tag(fi.otavanopisto.pyramus.domainmodel.base.Tag)

Aggregations

DuplicateCourseStudentException (fi.otavanopisto.pyramus.exception.DuplicateCourseStudentException)7 CourseStudent (fi.otavanopisto.pyramus.domainmodel.courses.CourseStudent)6 Room (fi.otavanopisto.pyramus.domainmodel.accommodation.Room)5 Course (fi.otavanopisto.pyramus.domainmodel.courses.Course)5 Student (fi.otavanopisto.pyramus.domainmodel.students.Student)5 BigDecimal (java.math.BigDecimal)5 Currency (java.util.Currency)5 CourseDAO (fi.otavanopisto.pyramus.dao.courses.CourseDAO)4 CourseStudentDAO (fi.otavanopisto.pyramus.dao.courses.CourseStudentDAO)4 StudentDAO (fi.otavanopisto.pyramus.dao.students.StudentDAO)4 Date (java.util.Date)4 SmvcRuntimeException (fi.internetix.smvc.SmvcRuntimeException)3 DefaultsDAO (fi.otavanopisto.pyramus.dao.base.DefaultsDAO)3 EducationalTimeUnitDAO (fi.otavanopisto.pyramus.dao.base.EducationalTimeUnitDAO)3 TagDAO (fi.otavanopisto.pyramus.dao.base.TagDAO)3 ModuleDAO (fi.otavanopisto.pyramus.dao.modules.ModuleDAO)3 StaffMemberDAO (fi.otavanopisto.pyramus.dao.users.StaffMemberDAO)3 CourseEducationSubtypeDAO (fi.otavanopisto.pyramus.dao.base.CourseEducationSubtypeDAO)2 CourseEducationTypeDAO (fi.otavanopisto.pyramus.dao.base.CourseEducationTypeDAO)2 CurriculumDAO (fi.otavanopisto.pyramus.dao.base.CurriculumDAO)2