Website : rimsha.abasa.com
backdoor
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
canvas
/
app
/
models
/
Filename :
student_enrollment.rb
back
Copy
# frozen_string_literal: true # # Copyright (C) 2011 - 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/>. # class StudentEnrollment < Enrollment belongs_to :student, foreign_key: :user_id, class_name: "User" has_many :course_paces, through: :student after_save :evaluate_modules, if: proc { |e| # if enrollment switches sections or is created e.saved_change_to_course_section_id? || e.saved_change_to_course_id? || # or if an enrollment is deleted and they are in another section of the course (e.saved_change_to_workflow_state? && e.workflow_state == "deleted" && e.user.enrollments.where.not(id: e.id).active.where(course_id: e.course_id).exists?) } after_save :restore_submissions_and_scores after_save :republish_course_pace_if_needed after_save :republish_base_pace_if_needed def student? true end def evaluate_modules ContextModuleProgression.for_user(user_id).for_course(course_id).each(&:mark_as_outdated!) end def update_override_score(override_score:, grading_period_id: nil, updating_user:, record_grade_change: true) score_params = { grading_period_id: } if grading_period_id.present? score = find_score(score_params) raise ActiveRecord::RecordNotFound if score.blank? old_score = score[:override_score] old_grade = score.override_grade score.update!(override_score:) return score unless score.saved_change_to_override_score? Canvas::LiveEvents.grade_override(score, old_score, self, course) if record_grade_change && updating_user.present? override_grade_change = Auditors::GradeChange::OverrideGradeChange.new( grader: updating_user, old_grade:, old_score:, score: ) Auditors::GradeChange.record(override_grade_change:) end score end def update_override_status(custom_grade_status:, grading_period_id: nil) score_params = { grading_period_id: } if grading_period_id.present? score = find_score(score_params) score.update!(custom_grade_status:) end class << self def restore_submissions_and_scores_for_enrollments(enrollments) raise ArgumentError, "Cannot call with more than 1000 enrollments" if enrollments.count > 1_000 restore_deleted_submissions_for_enrollments(enrollments) restore_deleted_scores_for_enrollments(enrollments) end def restore_deleted_submissions_for_enrollments(student_enrollments) raise ArgumentError, "Cannot call with more than 1000 enrollments" if student_enrollments.count > 1_000 student_enrollments.group_by(&:course_id).each do |course_id, students| Submission .joins(:assignment) .where(user_id: students.map(&:user_id), workflow_state: "deleted", assignments: { context_id: course_id }) .merge(Assignment.active) .in_batches .update_all("workflow_state = #{SubmissionLifecycleManager.infer_submission_workflow_state_sql}") end end def restore_deleted_scores_for_enrollments(student_enrollments) raise ArgumentError, "Cannot call with more than 1000 enrollments" if student_enrollments.count > 1_000 student_enrollments.group_by(&:course_id).each_value do |students| course = students.first.course assignment_groups = course.assignment_groups.active.except(:order) grading_periods = GradingPeriod.for(course) Score.where(course_score: true).or( Score.where(assignment_group: assignment_groups) ).or( Score.where(grading_period: grading_periods) ).where(enrollment_id: students.map(&:id), workflow_state: "deleted") .update_all(workflow_state: "active") end end end private def restore_submissions_and_scores return unless being_restored?(to_state: "completed") # running in an n_strand to handle situations where a SIS import could # update a ton of enrollments from "deleted" to "completed". delay_if_production(n_strand: "Enrollment#restore_submissions_and_scores#{root_account.global_id}", priority: Delayed::LOW_PRIORITY) .restore_submissions_and_scores_now end def restore_submissions_and_scores_now restore_deleted_submissions restore_deleted_scores end def restore_deleted_submissions StudentEnrollment.restore_deleted_submissions_for_enrollments([self]) end def restore_deleted_scores StudentEnrollment.restore_deleted_scores_for_enrollments([self]) end def republish_course_pace_if_needed return unless saved_change_to_id? || saved_change_to_start_at? || (saved_change_to_workflow_state? && workflow_state != "deleted") return unless course.enable_course_paces? pace = course.course_paces.published.where(course_section_id:).last pace ||= course.course_paces.published.for_user(user).take || course.course_paces.published.primary.take pace&.create_publish_progress track_multiple_section_paces end def republish_base_pace_if_needed return unless course.enable_course_paces? && course_section_id && workflow_state == "deleted" student_section_ids = user.enrollments.where(course:).where.not(workflow_state: "deleted").pluck(:course_section_id) pace = course.course_paces.published.where(course_section_id: student_section_ids).last pace ||= course.course_paces.published.primary.take pace&.create_publish_progress end def track_multiple_section_paces section_ids_the_student_is_enrolled_in = user.student_enrollments.where.not(workflow_state: "deleted") .where(course_section: course.course_sections.pluck(:id)) .pluck(:course_section_id) if section_ids_the_student_is_enrolled_in.count > 1 && course.course_paces.published.for_section(section_ids_the_student_is_enrolled_in).size > 1 InstStatsd::Statsd.increment("course_pacing.student_with_multiple_sections_with_paces") end end end