Website : rimsha.abasa.com
backdoor
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
canvas
/
lib
/
gradebook
/
Filename :
apply_score_to_ungraded_submissions.rb
back
Copy
# frozen_string_literal: true # # Copyright (C) 2021 - 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 Gradebook class ApplyScoreToUngradedSubmissions MAX_ERROR_COUNT = 100 Options = Struct.new( :excused, :mark_as_missing, :only_apply_to_past_due, :percent, :assignment_ids, :student_ids, keyword_init: true ) def self.queue_apply_score(course:, grader:, options:) progress = Progress.create!(context: course, tag: "apply_score_to_ungraded_assignments") progress.process_job(self, :process_apply_score, {}, course, grader, options) progress end def self.process_apply_score(progress, course, grader, options) Delayed::Batch.serial_batch( priority: Delayed::LOW_PRIORITY, n_strand: ["apply_score_to_ungraded_assignments", course.root_account.global_id] ) do errors = [] affected_user_ids = Set.new matching_submissions_scope(course, grader, options).find_each do |submission| # A batch update is a possibility here, but we follow the lead of # similar processes like the submissions bulk update in issuing # individual updates to each submission so that the appropriate # callbacks happen. process_submission(submission, grader, options) affected_user_ids.add(submission.user_id) rescue if errors.count < MAX_ERROR_COUNT errors << { assignment_id: submission.assignment_id, error: :failed_to_update, student_id: submission.user_id } end end progress&.complete! ensure course.recompute_student_scores(affected_user_ids) if affected_user_ids.any? progress&.set_results({ errors: }) end end def self.matching_submissions_scope(course, grader, options) students = course.students_visible_to(grader).where(id: options.student_ids) assignments = course.assignments.where(id: options.assignment_ids).where.not(submission_types: "not_graded") submissions = Submission.active .joins(:assignment) .preload(:assignment, :user) .where(assignment: assignments) .where.not("assignments.moderated_grading IS TRUE AND assignments.grades_published_at IS NULL") .where.not(["assignments.moderated_grading IS TRUE AND assignments.final_grader_id != ?", grader.id]) .where(user: students) .ungraded .where("submissions.excused IS NOT TRUE") submissions = submissions.where(cached_due_date: ...Time.zone.now) if options.only_apply_to_past_due submissions end private_class_method :matching_submissions_scope def self.process_submission(submission, grader, options) assignment = submission.assignment # call assignment.points_possible.to_f because points_possible could be nil percent_score = options.percent.to_f * assignment.points_possible.to_f / 100 if options.percent.present? Submission.suspend_callbacks(:apply_late_policy) do assignment.grade_student( submission.user, grader:, excused: options.excused, score: percent_score, skip_grade_calc: true ) end # If mark_as_missing is true, we need to surreptitiously update the late policy # status, since calling grade_student will clear it. There may be a less clunky # way to do this. submission.update_column(:late_policy_status, "missing") if options.mark_as_missing end private_class_method :process_submission end end