Esempio n. 1
0
def create_course():
    params = request.get_json()
    accent_color = normalize_accent_color(get_param(params, 'accentColor'))
    degree_check_id = get_param(params, 'degreeCheckId')
    grade = get_param(params, 'grade')
    name = get_param(params, 'name')
    note = get_param(params, 'note')
    sid = get_param(params, 'sid')
    value = get_param(request.get_json(), 'unitRequirementIds')
    unit_requirement_ids = list(filter(None, value.split(','))) if isinstance(
        value, str) else value
    units = get_param(params, 'units')

    if 0 in map(lambda v: len(str(v).strip()) if v else 0, (name, sid)):
        raise BadRequestError('Missing one or more required parameters')
    course = DegreeProgressCourse.create(
        accent_color=accent_color,
        degree_check_id=degree_check_id,
        display_name=name,
        grade=grade,
        manually_created_at=datetime.now(),
        manually_created_by=current_user.get_id(),
        note=note,
        section_id=None,
        sid=sid,
        term_id=None,
        unit_requirement_ids=unit_requirement_ids or (),
        units=units,
    )
    # Update updated_at date of top-level record
    DegreeProgressTemplate.refresh_updated_at(course.degree_check_id,
                                              current_user.get_id())
    return tolerant_jsonify(course.to_api_json())
Esempio n. 2
0
def update_course(course_id):
    course = DegreeProgressCourse.find_by_id(course_id)
    if course:
        params = request.get_json()
        accent_color = normalize_accent_color(get_param(params, 'accentColor'))

        grade = get_param(params, 'grade')
        grade = course.grade if grade is None else grade
        name = get_param(params, 'name')
        name = course.display_name if name is None else name
        if name is None:
            raise BadRequestError('name is required.')

        note = get_param(params, 'note')
        # Courses are mapped to degree_progress_unit_requirements
        value = get_param(request.get_json(), 'unitRequirementIds')
        unit_requirement_ids = list(filter(
            None, value.split(','))) if isinstance(value, str) else value
        units = get_param(params, 'units') or None

        course = DegreeProgressCourse.update(
            accent_color=accent_color,
            course_id=course_id,
            grade=grade,
            name=name,
            note=note,
            unit_requirement_ids=unit_requirement_ids,
            units=units,
        )
        # Update updated_at date of top-level record
        DegreeProgressTemplate.refresh_updated_at(course.degree_check_id,
                                                  current_user.get_id())
        return tolerant_jsonify(course.to_api_json())
    else:
        raise ResourceNotFoundError('Course not found.')
Esempio n. 3
0
def update_category(category_id):
    params = request.get_json()
    units_lower = get_param(params, 'unitsLower')
    units_upper = get_param(params, 'unitsUpper')
    description = get_param(params, 'description')
    name = get_param(params, 'name')
    parent_category_id = get_param(params, 'parentCategoryId')
    # Courses can be mapped to degree_progress_unit_requirements
    value = get_param(request.get_json(), 'unitRequirementIds')
    unit_requirement_ids = list(filter(None, value.split(','))) if isinstance(
        value, str) else value

    category = DegreeProgressCategory.update(
        category_id=category_id,
        course_units_lower=units_lower,
        course_units_upper=units_upper,
        description=description,
        parent_category_id=parent_category_id,
        name=name,
        unit_requirement_ids=unit_requirement_ids,
    )
    # Update updated_at date of top-level record
    DegreeProgressTemplate.refresh_updated_at(category.template_id,
                                              current_user.get_id())
    return tolerant_jsonify(category.to_api_json())
Esempio n. 4
0
def toggle_campus_requirement(category_id):
    params = request.get_json()
    is_satisfied = get_param(params, 'isSatisfied')
    if is_satisfied is None:
        raise BadRequestError('Parameter \'isSatisfied\' is required')
    category = _get_degree_category(category_id)
    if category.category_type not in [
            'Campus Requirement, Satisfied', 'Campus Requirement, Unsatisfied'
    ]:
        raise BadRequestError('Category must be a \'Campus Requirement\' type')
    if ((category.category_type == 'Campus Requirement, Satisfied'
         and is_satisfied is True)
            or (category.category_type == 'Campus Requirement, Unsatisfied'
                and is_satisfied is False)):
        app.logger.info(
            f'Request ignored: set is_satisfied={is_satisfied} on {category.category_type}'
        )
    else:
        category = DegreeProgressCategory.set_campus_requirement_satisfied(
            category_id=category_id,
            is_satisfied=is_satisfied,
        )
        # Update updated_at date of top-level record
        DegreeProgressTemplate.refresh_updated_at(category.template_id,
                                                  current_user.get_id())
    return tolerant_jsonify(category.to_api_json())
Esempio n. 5
0
def recommend_category(category_id):
    params = request.get_json()
    is_recommended = get_param(params, 'isRecommended')
    if is_recommended is None:
        raise BadRequestError('Parameter \'isRecommended\' is required')

    accent_color = normalize_accent_color(get_param(params, 'accentColor'))
    grade = get_param(params, 'grade')
    note = get_param(params, 'note')
    units_lower = get_param(params, 'unitsLower')
    units_upper = get_param(params, 'unitsUpper')

    category = DegreeProgressCategory.recommend(
        accent_color=accent_color,
        category_id=category_id,
        course_units_lower=units_lower,
        course_units_upper=units_upper,
        grade=grade,
        is_recommended=is_recommended,
        note=(note or '').strip() or None,
    )
    # Update updated_at date of top-level record
    DegreeProgressTemplate.refresh_updated_at(category.template_id,
                                              current_user.get_id())
    return tolerant_jsonify(category.to_api_json())
Esempio n. 6
0
def delete_degree_category(category_id):
    category = _get_degree_category(category_id)
    DegreeProgressCategory.delete(category.id)
    # Update updated_at date of top-level record
    DegreeProgressTemplate.refresh_updated_at(category.template_id,
                                              current_user.get_id())
    return tolerant_jsonify({'message':
                             f'Template {category_id} deleted'}), 200
Esempio n. 7
0
def assign_course(course_id):
    params = request.get_json()
    course = DegreeProgressCourse.find_by_id(course_id)
    if course:
        # Get existing category assignment. If it's a placeholder then delete it at end of transaction.
        previous_category = DegreeProgressCategory.find_by_id(
            course.category_id) if course.category_id else None
        category_id = get_param(params, 'categoryId')
        category = DegreeProgressCategory.find_by_id(
            category_id) if category_id else None
        if category:
            if category.template_id != course.degree_check_id:
                raise BadRequestError(
                    'The category and course do not belong to the same degree_check instance.'
                )
            children = DegreeProgressCategory.find_by_parent_category_id(
                parent_category_id=category_id)
            if next((c for c in children if c.category_type == 'Subcategory'),
                    None):
                raise BadRequestError(
                    'A course cannot be assigned to a category with a subcategory.'
                )
            course = DegreeProgressCourse.assign(category_id=category_id,
                                                 course_id=course.id)

        else:
            # When user un-assigns a course we delete all copies of that course,.
            for copy_of_course in DegreeProgressCourse.get_courses(
                    degree_check_id=course.degree_check_id,
                    manually_created_at=course.manually_created_at,
                    manually_created_by=course.manually_created_by,
                    section_id=course.section_id,
                    sid=course.sid,
                    term_id=course.term_id,
            ):
                if copy_of_course.id != course.id:
                    DegreeProgressCourseUnitRequirement.delete(
                        copy_of_course.id)
                    category = DegreeProgressCategory.find_by_id(
                        copy_of_course.category_id)
                    if category and 'Placeholder' in category.category_type:
                        DegreeProgressCategory.delete(category.id)
                    DegreeProgressCourse.delete(copy_of_course)
            ignore = to_bool_or_none(get_param(params, 'ignore'))
            course = DegreeProgressCourse.unassign(course_id=course.id,
                                                   ignore=ignore)

        # If previous assignment was a "placeholder" category then delete it.
        if previous_category and 'Placeholder' in previous_category.category_type:
            DegreeProgressCategory.delete(previous_category.id)

        # Update updated_at date of top-level record
        DegreeProgressTemplate.refresh_updated_at(course.degree_check_id,
                                                  current_user.get_id())
        return tolerant_jsonify(course.to_api_json())
    else:
        raise ResourceNotFoundError('Course not found.')
Esempio n. 8
0
def create_category():
    params = request.get_json()
    category_type = get_param(params, 'categoryType')
    course_units_lower = get_param(params, 'unitsLower')
    course_units_upper = get_param(params, 'unitsUpper')
    description = get_param(params, 'description')
    name = get_param(params, 'name')
    parent_category_id = get_param(params, 'parentCategoryId')
    position = get_param(params, 'position')
    template_id = get_param(params, 'templateId')
    # Categories are mapped to degree_progress_unit_requirements
    value = get_param(request.get_json(), 'unitRequirementIds')
    unit_requirement_ids = list(filter(None, value.split(','))) if isinstance(
        value, str) else value

    if not category_type or not name or not _is_valid_position(
            position) or not template_id:
        raise BadRequestError(
            "Insufficient data: categoryType, name, position and templateId are required.'"
        )
    if category_type in ['Category', 'Campus Requirements'
                         ] and parent_category_id:
        raise BadRequestError(f'{category_type} cannot have a parent.')
    if category_type in ('Course Requirement',
                         'Subcategory') and not parent_category_id:
        raise BadRequestError(
            f"The parentCategoryId param is required when categoryType equals '{category_type}'."
        )
    if parent_category_id:
        parent = _get_degree_category(parent_category_id)
        parent_type = parent.category_type
        if parent_type == 'Course Requirement' or (
                parent_type == 'Subcategory' and category_type == 'Category'):
            raise BadRequestError(
                f'Type {category_type} not allowed, based on parent type: {parent_type}.'
            )
        if position != parent.position:
            raise BadRequestError(
                f'Category position ({position}) must match its parent ({parent.position}).'
            )

    category = _create_category(
        category_type=category_type,
        course_units_lower=course_units_lower,
        course_units_upper=course_units_upper,
        description=description,
        name=name,
        parent_category_id=parent_category_id,
        position=position,
        template_id=template_id,
        unit_requirement_ids=unit_requirement_ids,
    )
    # Update updated_at date of top-level record
    DegreeProgressTemplate.refresh_updated_at(template_id,
                                              current_user.get_id())
    return tolerant_jsonify(category.to_api_json())
def delete_unit_requirement(unit_requirement_id):
    unit_requirement = DegreeProgressUnitRequirement.find_by_id(unit_requirement_id)
    if unit_requirement:
        DegreeProgressUnitRequirement.delete(unit_requirement_id)
        # Update updated_at date of top-level record
        DegreeProgressTemplate.refresh_updated_at(unit_requirement.template_id, current_user.get_id())

        return tolerant_jsonify({'message': f'Unit requirement {unit_requirement_id} deleted'}), 200
    else:
        raise ResourceNotFoundError(f'No unit_requirement found with id={unit_requirement_id}.')
Esempio n. 10
0
def update_degree_note(degree_check_id):
    params = request.get_json()
    body = get_param(params, 'body')
    note = DegreeProgressNote.upsert(
        body=body,
        template_id=degree_check_id,
        updated_by=current_user.get_id(),
    )
    # Update updated_at date of top-level record
    DegreeProgressTemplate.refresh_updated_at(degree_check_id,
                                              current_user.get_id())
    return tolerant_jsonify(note.to_api_json())
def update_unit_requirement(unit_requirement_id):
    params = request.get_json()
    name = params.get('name')
    min_units = params.get('minUnits')
    if not name or not min_units:
        raise BadRequestError('Unit requirement \'name\' and \'minUnits\' must be provided.')
    unit_requirement = DegreeProgressUnitRequirement.update(
        id_=unit_requirement_id,
        min_units=min_units,
        name=name,
        updated_by=current_user.get_id(),
    )
    # Update updated_at date of top-level record
    DegreeProgressTemplate.refresh_updated_at(unit_requirement.template_id, current_user.get_id())
    return tolerant_jsonify(unit_requirement.to_api_json())
Esempio n. 12
0
def delete_course(course_id):
    course = DegreeProgressCourse.find_by_id(course_id)
    if course:
        # Verify that course is a copy
        matches = DegreeProgressCourse.get_courses(
            degree_check_id=course.degree_check_id,
            manually_created_at=course.manually_created_at,
            manually_created_by=course.manually_created_by,
            section_id=course.section_id,
            sid=course.sid,
            term_id=course.term_id,
        )

        def _delete_course(c):
            category = DegreeProgressCategory.find_by_id(c.category_id)
            DegreeProgressCourseUnitRequirement.delete(c.id)
            DegreeProgressCourse.delete(c)
            if category and 'Placeholder' in category.category_type:
                DegreeProgressCategory.delete(category_id=category.id)

        matches = sorted(matches, key=lambda c: c.created_at)
        if matches[0].id == course.id:
            if course.manually_created_by:
                for match in matches:
                    _delete_course(match)
            else:
                raise BadRequestError('Only copied courses can be deleted.')
        else:
            _delete_course(course)

        # Update updated_at date of top-level record
        DegreeProgressTemplate.refresh_updated_at(course.degree_check_id,
                                                  current_user.get_id())
        return tolerant_jsonify({'message':
                                 f'Course {course_id} deleted'}), 200
    else:
        raise ResourceNotFoundError('Course not found.')