182 lines
6.7 KiB
Ruby
182 lines
6.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2015 - present Instructure, Inc.
|
|
#
|
|
# This file is part of Canvas.
|
|
#
|
|
# Canvas is free software: you can redistribute it and/or modify it under
|
|
# the terms of the GNU Affero General Public License as published by the Free
|
|
# Software Foundation, version 3 of the License.
|
|
#
|
|
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License along
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
module Api::V1::SisAssignment
|
|
include Api::V1::Json
|
|
|
|
class UnloadedAssociationError < StandardError
|
|
end
|
|
|
|
API_SIS_ASSIGNMENT_JSON_OPTS = {
|
|
only: %i(id created_at due_at unlock_at lock_at points_possible sis_assignment_id integration_id integration_data include_in_final_grade).freeze,
|
|
methods: %i(name submission_types_array).freeze
|
|
}.freeze
|
|
|
|
API_SIS_ASSIGNMENT_GROUP_JSON_OPTS = {
|
|
only: %i(id name sis_source_id integration_data group_weight).freeze
|
|
}.freeze
|
|
|
|
API_SIS_ASSIGNMENT_COURSE_SECTION_JSON_OPTS = {
|
|
only: %i(id name sis_source_id integration_id).freeze
|
|
}.freeze
|
|
|
|
API_SIS_ASSIGNMENT_COURSE_JSON_OPTS = {
|
|
only: %i(id name sis_source_id integration_id).freeze
|
|
}.freeze
|
|
|
|
API_SIS_ASSIGNMENT_OVERRIDES_JSON_OPTS = {
|
|
only: %i(id title due_at unlock_at lock_at).freeze
|
|
}.freeze
|
|
|
|
API_SIS_ASSIGNMENT_STUDENT_OVERRIDES_JSON_OPTS = {
|
|
only: %i(user_id).freeze
|
|
}.freeze
|
|
|
|
def sis_assignments_json(assignments, includes = {})
|
|
assignments.map { |a| sis_assignment_json(a, includes) }
|
|
end
|
|
|
|
private
|
|
|
|
def sis_assignment_json(assignment, includes)
|
|
json = api_json(assignment, nil, nil, API_SIS_ASSIGNMENT_JSON_OPTS)
|
|
json[:due_at] = default_due_date(assignment)
|
|
json[:course_id] = assignment.context_id if assignment.context_type == 'Course'
|
|
json[:submission_types] = json.delete(:submission_types_array)
|
|
json[:include_in_final_grade] = include_in_final_grade(assignment)
|
|
add_sis_assignment_group_json(assignment, json)
|
|
add_sis_course_sections_json(assignment, json)
|
|
|
|
json[:user_overrides] = assignment_user_overrides_json(assignment) if includes[:student_overrides]
|
|
json
|
|
end
|
|
|
|
def default_due_date(assignment)
|
|
return assignment.due_at if assignment.due_at
|
|
|
|
overrides = active_assignment_overrides_for(assignment) || []
|
|
mastery_path_override = overrides.find(&:mastery_paths?)
|
|
mastery_path_override.try(:due_at)
|
|
end
|
|
|
|
def add_sis_assignment_group_json(assignment, json)
|
|
return unless assignment.association(:assignment_group).loaded? && assignment.assignment_group
|
|
|
|
json.merge!(assignment_group: sis_assignment_group_json(assignment.assignment_group))
|
|
end
|
|
|
|
def sis_assignment_group_json(assignment_group)
|
|
api_json(assignment_group, nil, nil, API_SIS_ASSIGNMENT_GROUP_JSON_OPTS)
|
|
end
|
|
|
|
def add_sis_course_sections_json(assignment, json)
|
|
return unless assignment.association(:context).loaded?
|
|
|
|
course_sections = active_course_sections_for(assignment.context)
|
|
return unless course_sections
|
|
|
|
json.merge!(sections: sis_assignment_course_sections_json(course_sections, assignment))
|
|
end
|
|
|
|
def assignment_user_overrides_json(assignment)
|
|
overrides = active_assignment_overrides_for(assignment)
|
|
raise UnloadedAssociationError if overrides.nil?
|
|
|
|
overrides.map { |o| assignment_user_override_json(o) }.compact
|
|
end
|
|
|
|
def assignment_user_override_json(override)
|
|
raise UnloadedAssociationError unless override.association(:assignment_override_students).loaded?
|
|
return nil if override.assignment_override_students.empty?
|
|
|
|
assignment_override_students_json = override.assignment_override_students.map do |student_override|
|
|
json = api_json(student_override, nil, nil, API_SIS_ASSIGNMENT_STUDENT_OVERRIDES_JSON_OPTS)
|
|
if student_override.association(:user).loaded?
|
|
pseudonym = SisPseudonym.for(student_override.user, override.assignment.context)
|
|
json[:sis_user_id] = pseudonym&.sis_user_id
|
|
end
|
|
|
|
json
|
|
end
|
|
|
|
api_json(override, nil, nil, API_SIS_ASSIGNMENT_OVERRIDES_JSON_OPTS)
|
|
.merge({ students: assignment_override_students_json })
|
|
end
|
|
|
|
def sis_assignment_course_sections_json(course_sections, assignment)
|
|
if assignment.only_visible_to_overrides
|
|
section_ids = active_assignment_overrides_for(assignment).map { |o| o.set_id if o.set_type == 'CourseSection' }
|
|
section_ids = Set.new(section_ids.compact)
|
|
course_sections = course_sections.select { |section| section_ids.include?(section.id) }
|
|
end
|
|
|
|
course_sections.map { |s| sis_assignment_course_section_json(s, assignment) }
|
|
end
|
|
|
|
def sis_assignment_course_section_json(course_section, assignment)
|
|
json = api_json(course_section, nil, nil, API_SIS_ASSIGNMENT_COURSE_SECTION_JSON_OPTS)
|
|
json[:sis_id] = json.delete(:sis_source_id)
|
|
json[:origin_course] = sis_assignment_course_json(course_section.nonxlist_course || course_section.course)
|
|
json[:xlist_course] = sis_assignment_course_json(course_section.course) if course_section.crosslisted?
|
|
add_sis_assignment_override_json(json, assignment, course_section)
|
|
json
|
|
end
|
|
|
|
def sis_assignment_course_json(course)
|
|
json = api_json(course, nil, nil, API_SIS_ASSIGNMENT_COURSE_JSON_OPTS)
|
|
json[:sis_id] = json.delete(:sis_source_id)
|
|
json
|
|
end
|
|
|
|
def add_sis_assignment_override_json(json, assignment, course_section)
|
|
assignment_overrides = active_assignment_overrides_for(assignment)
|
|
return unless assignment_overrides
|
|
|
|
override = assignment_overrides.detect do |assignment_override|
|
|
assignment_override.set_type == 'CourseSection' && assignment_override.set_id == course_section.id
|
|
end
|
|
return if override.nil?
|
|
|
|
override_json = api_json(override, nil, nil, API_SIS_ASSIGNMENT_OVERRIDES_JSON_OPTS)
|
|
override_json[:override_title] = override_json.delete(:title)
|
|
json[:override] = override_json
|
|
end
|
|
|
|
def include_in_final_grade(assignment)
|
|
!(assignment.omit_from_final_grade? || assignment.grading_type == 'not_graded')
|
|
end
|
|
|
|
def active_course_sections_for(context)
|
|
if context.respond_to?(:active_course_sections) && context.association(:active_course_sections).loaded?
|
|
context.active_course_sections
|
|
elsif context.respond_to?(:course_sections) && context.association(:course_sections).loaded?
|
|
context.course_sections.select(&:active?)
|
|
end
|
|
end
|
|
|
|
def active_assignment_overrides_for(assignment)
|
|
if assignment.association(:active_assignment_overrides).loaded?
|
|
assignment.active_assignment_overrides
|
|
elsif assignment.association(:assignment_overrides).loaded?
|
|
assignment.assignment_overrides.select(&:active?)
|
|
end
|
|
end
|
|
end
|