canvas-lms/lib/gradebook_importer.rb

668 lines
22 KiB
Ruby
Raw Normal View History

2011-02-01 09:57:29 +08:00
#
# Copyright (C) 2011 - present Instructure, Inc.
2011-02-01 09:57:29 +08:00
#
# 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/>.
#
require 'csv'
2011-02-01 09:57:29 +08:00
class GradebookImporter
prevent grading if submission is due in closed grading period closes CNVS-32229 closes CNVS-32232 test plan: * Create a course with MGP enabled and two grading periods in the default term * Create two assignments for this course, one in a closed GP and one in an open GP * To test overrides, create the following as well: * For one of the students, make the open assignment due in the closed grading period * For another student, make the closed assignment due in the open grading period * Ensure the following steps work for all assignment/student combos due in a closed grading period. ** CNVS-32229 ** * Login as a teacher * Go to speedgrader for the assignment in the closed GP * Notice that the grade input is locked down * Right click on the locked-down input and select 'Inspect' * Remove the 'ui-state-disabled' class and remove readonly="readonly" from the input field's HTML * Notice the input is no longer grayed out and you can enter a grade * Enter a grade and tab out of the input * You should see an error message that says something went wrong and notice in the Network tab of your dev tools that the AJAX post failed, meaning the submission was not gradeable * Refresh the page and notice the grade is not there. * Verify it isn't there in Gradebook either * Login as an admin * Go to speedgrader for the assignment in the closed GP * Notice that the grade input is *not* locked down * Enter a grade and tab out of the input * You should *not* see an error message that says something went wrong meaning the submission was graded successfully * Refresh the page and notice the grade is there. * Verify it is also present in Gradebook ** CNVS-32232 ** * Login as a teacher * Go into a gradebook that has an assignment that is locked down because it is in a closed grading period * Notice that the grade cells for the assignment are locked down (because the submissions fall in a closed grading period) * Right-click on one of the locked-down cells and select 'Inspect' * Remove the 'grayed-out' and 'cannot_edit_in_closed_grading_period' classes * Notice the cell is no longer grayed out and you can enter a grade. * Enter a grade * Click on another cell. * You should see an error message that says something went wrong and in the Network tab of your dev tools verify the AJAX post failed, meaning the submission was not gradeable * Refresh the page and notice the grade is not there * Login as an admin * Login as a teacher * Go into a gradebook that has an assignment that is in a closed grading period * Enter a grade in a cell that should be due in a closed grading period * Click on another cell * You should *not* see an error message that says something went wrong meaning the submission was graded successfully * Refresh the page and notice the grade is there. * Verify it is also present in Gradebook Change-Id: Ia80e4de626616309c5e9dffb78ed0f9671ad1076 Reviewed-on: https://gerrit.instructure.com/95687 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Spencer Olson <solson@instructure.com> Tested-by: Jenkins QA-Review: Anju Reddy <areddy@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-11-15 05:36:56 +08:00
ASSIGNMENT_PRELOADED_FIELDS = %i/
id title points_possible grading_type updated_at context_id context_type group_category_id
created_at due_at only_visible_to_overrides moderated_grading grades_published_at final_grader_id
prevent grading if submission is due in closed grading period closes CNVS-32229 closes CNVS-32232 test plan: * Create a course with MGP enabled and two grading periods in the default term * Create two assignments for this course, one in a closed GP and one in an open GP * To test overrides, create the following as well: * For one of the students, make the open assignment due in the closed grading period * For another student, make the closed assignment due in the open grading period * Ensure the following steps work for all assignment/student combos due in a closed grading period. ** CNVS-32229 ** * Login as a teacher * Go to speedgrader for the assignment in the closed GP * Notice that the grade input is locked down * Right click on the locked-down input and select 'Inspect' * Remove the 'ui-state-disabled' class and remove readonly="readonly" from the input field's HTML * Notice the input is no longer grayed out and you can enter a grade * Enter a grade and tab out of the input * You should see an error message that says something went wrong and notice in the Network tab of your dev tools that the AJAX post failed, meaning the submission was not gradeable * Refresh the page and notice the grade is not there. * Verify it isn't there in Gradebook either * Login as an admin * Go to speedgrader for the assignment in the closed GP * Notice that the grade input is *not* locked down * Enter a grade and tab out of the input * You should *not* see an error message that says something went wrong meaning the submission was graded successfully * Refresh the page and notice the grade is there. * Verify it is also present in Gradebook ** CNVS-32232 ** * Login as a teacher * Go into a gradebook that has an assignment that is locked down because it is in a closed grading period * Notice that the grade cells for the assignment are locked down (because the submissions fall in a closed grading period) * Right-click on one of the locked-down cells and select 'Inspect' * Remove the 'grayed-out' and 'cannot_edit_in_closed_grading_period' classes * Notice the cell is no longer grayed out and you can enter a grade. * Enter a grade * Click on another cell. * You should see an error message that says something went wrong and in the Network tab of your dev tools verify the AJAX post failed, meaning the submission was not gradeable * Refresh the page and notice the grade is not there * Login as an admin * Login as a teacher * Go into a gradebook that has an assignment that is in a closed grading period * Enter a grade in a cell that should be due in a closed grading period * Click on another cell * You should *not* see an error message that says something went wrong meaning the submission was graded successfully * Refresh the page and notice the grade is there. * Verify it is also present in Gradebook Change-Id: Ia80e4de626616309c5e9dffb78ed0f9671ad1076 Reviewed-on: https://gerrit.instructure.com/95687 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Spencer Olson <solson@instructure.com> Tested-by: Jenkins QA-Review: Anju Reddy <areddy@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-11-15 05:36:56 +08:00
/.freeze
2011-02-01 09:57:29 +08:00
class NegativeId
class << self
def generate
instance.next
end
2011-02-01 09:57:29 +08:00
def instance
@@inst ||= new
end
end
def next
@i ||= 0
@i -= 1
end
end
class InvalidHeaderRow < StandardError; end
attr_reader :context, :contents, :attachment, :assignments, :students,
:submissions, :missing_assignments, :missing_students, :upload
def self.create_from(progress, gradebook_upload, user, attachment)
self.new(gradebook_upload, attachment, user, progress).parse!
end
def initialize(upload=nil, attachment=nil, user=nil, progress=nil)
@upload = upload
@context = upload.course
raise ArgumentError, "Must provide a valid context for this gradebook." unless valid_context?(@context)
raise ArgumentError, "Must provide attachment." unless attachment
@user = user
@attachment = attachment
@progress = progress
@visible_assignments = AssignmentStudentVisibility.visible_assignment_ids_in_course_by_user(
course_id: @context.id, user_id: @context.all_students.pluck(:id)
)
2011-02-01 09:57:29 +08:00
end
CSV::Converters[:nil] = lambda do |e|
begin
e.nil? ? e : raise
rescue
e
end
end
gradebook export and import localized CSV fixes GRADE-271 Test Plan: 1. Modify a local copy of config/locales/is.yml, adding the following translation key: csv: column_delimiter: ";" 2. Change Canvas settings to Íslenska (Icelandic): - root account settings - user profile - course settings 3. Create at least two students and at least two assignments for a course. - name at least one assignment with non-ASCII Icelandic characters such as "ð" - name at least one assignment with multi-byte Unicode characters, such as "文章" 4. Grade the assignments, covering the following: - decimal grade (with comma as decimal separator) - integer grade - empty grade 5. Go to (old) gradebook, export grades and download it 6. Configure Microsoft Excel for Icelandic language 7. Open the download in Excel. Verify that rows and columns are interpreted correctly, and that non- ASCII characters are displayed correctly. 8. Import the download in Google Sheets, specifying semicolon as the custom delmiter. Repeat the verification from (7) 9. Repeat steps 3-8 using new gradebook. 10. Repeat steps 3-8 using US English for all language settings. 11. Copy the Icelandic and English grade exports and modify some student grades 12. Import the modified Icelandic export file, while configured for US English. Verify that student grades are updated. 13. Import the modified English export file. Verify that student grades are updated. Change-Id: Icf7fcdadae5b22fad524a224d956fd93c2438b57 Reviewed-on: https://gerrit.instructure.com/128786 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Tested-by: Jenkins QA-Review: Indira Pai <ipai@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2017-10-04 22:51:38 +08:00
CSV::Converters[:decimal_comma_to_period] = -> (field) do
if field =~ /^-?[0-9.,]+%?$/
# This field is a pure number or percentage => let's normalize it
number_parts = field.split(/[,.]/)
last_number_part = number_parts.pop
if number_parts.empty?
last_number_part
else
[number_parts.join(), last_number_part].join('.')
end
else
field
end
end
def parse!
# preload a ton of data that presumably we'll be querying
@context.preload_user_roles!
@all_assignments = @context.assignments
.preload({ context: :account })
.published
.gradeable
prevent grading if submission is due in closed grading period closes CNVS-32229 closes CNVS-32232 test plan: * Create a course with MGP enabled and two grading periods in the default term * Create two assignments for this course, one in a closed GP and one in an open GP * To test overrides, create the following as well: * For one of the students, make the open assignment due in the closed grading period * For another student, make the closed assignment due in the open grading period * Ensure the following steps work for all assignment/student combos due in a closed grading period. ** CNVS-32229 ** * Login as a teacher * Go to speedgrader for the assignment in the closed GP * Notice that the grade input is locked down * Right click on the locked-down input and select 'Inspect' * Remove the 'ui-state-disabled' class and remove readonly="readonly" from the input field's HTML * Notice the input is no longer grayed out and you can enter a grade * Enter a grade and tab out of the input * You should see an error message that says something went wrong and notice in the Network tab of your dev tools that the AJAX post failed, meaning the submission was not gradeable * Refresh the page and notice the grade is not there. * Verify it isn't there in Gradebook either * Login as an admin * Go to speedgrader for the assignment in the closed GP * Notice that the grade input is *not* locked down * Enter a grade and tab out of the input * You should *not* see an error message that says something went wrong meaning the submission was graded successfully * Refresh the page and notice the grade is there. * Verify it is also present in Gradebook ** CNVS-32232 ** * Login as a teacher * Go into a gradebook that has an assignment that is locked down because it is in a closed grading period * Notice that the grade cells for the assignment are locked down (because the submissions fall in a closed grading period) * Right-click on one of the locked-down cells and select 'Inspect' * Remove the 'grayed-out' and 'cannot_edit_in_closed_grading_period' classes * Notice the cell is no longer grayed out and you can enter a grade. * Enter a grade * Click on another cell. * You should see an error message that says something went wrong and in the Network tab of your dev tools verify the AJAX post failed, meaning the submission was not gradeable * Refresh the page and notice the grade is not there * Login as an admin * Login as a teacher * Go into a gradebook that has an assignment that is in a closed grading period * Enter a grade in a cell that should be due in a closed grading period * Click on another cell * You should *not* see an error message that says something went wrong meaning the submission was graded successfully * Refresh the page and notice the grade is there. * Verify it is also present in Gradebook Change-Id: Ia80e4de626616309c5e9dffb78ed0f9671ad1076 Reviewed-on: https://gerrit.instructure.com/95687 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Spencer Olson <solson@instructure.com> Tested-by: Jenkins QA-Review: Anju Reddy <areddy@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-11-15 05:36:56 +08:00
.select(ASSIGNMENT_PRELOADED_FIELDS)
.index_by(&:id)
@all_students = @context.all_students
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
.select(['users.id', :name, :sortable_name, 'users.updated_at'])
.index_by(&:id)
@assignments = nil
@root_accounts = {}
@pseudonyms_by_sis_id = {}
@pseudonyms_by_login_id = {}
@students = []
@pp_row = []
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@warning_messages = {
prevented_new_assignment_creation_in_closed_period: false,
prevented_grading_ungradeable_submission: false,
prevented_changing_read_only_column: false
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
}
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
@parsed_custom_column_data = {}
@gradebook_importer_assignments = {}
@gradebook_importer_custom_columns = {}
begin
csv_stream do |row|
already_processed = check_for_non_student_row(row)
unless already_processed
@students << process_student(row)
process_submissions(row, @students.last)
end
end
rescue InvalidHeaderRow
@progress.message = "Invalid header row"
@progress.workflow_state = "failed"
@progress.save
return
2011-02-01 09:57:29 +08:00
end
@missing_assignments = []
@missing_assignments = @all_assignments.values - @assignments if @missing_assignment
@missing_students = []
@missing_students = @all_students.values - @students if @missing_student
# look up existing score for everything that was provided
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
assignment_ids = @missing_assignment ? @all_assignments.values : @assignments
user_ids = @missing_student ? @all_students.values : @students
# preload periods to avoid N+1s
periods = GradingPeriod.for(@context)
# preload is_admin to avoid N+1
is_admin = @context.account_membership_allows(@user)
# Preload effective due dates to avoid N+1s
effective_due_dates = EffectiveDueDates.for_course(@context, @all_assignments.values)
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@original_submissions = @context.submissions
.preload(:grading_period, assignment: { context: :account })
.select(['submissions.id', :assignment_id, :user_id, :grading_period_id, :score, :excused, :cached_due_date, 'submissions.updated_at'])
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
.where(assignment_id: assignment_ids, user_id: user_ids)
.map do |submission|
is_gradeable = gradeable?(submission: submission, is_admin: is_admin)
score = submission.excused? ? "EX" : submission.score.to_s
{
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
user_id: submission.user_id,
assignment_id: submission.assignment_id,
score: score,
gradeable: is_gradeable
}
end
# cache the score on the existing object
original_submissions_by_student = @original_submissions.inject({}) do |r, s|
r[s[:user_id]] ||= {}
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
r[s[:user_id]][s[:assignment_id]] ||= {}
r[s[:user_id]][s[:assignment_id]][:score] = s[:score]
r[s[:user_id]][s[:assignment_id]][:gradeable] = s[:gradeable]
r
end
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@students.each do |student|
@gradebook_importer_assignments[student.id].each do |submission|
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
submission_assignment_id = submission.fetch('assignment_id').to_i
assignment = original_submissions_by_student.
fetch(student.id, {}).
fetch(submission_assignment_id, {})
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
submission['original_grade'] = assignment.fetch(:score, nil)
submission['gradeable'] = assignment.fetch(:gradable, nil)
if submission.fetch('gradeable').nil?
assignment = @all_assignments[submission['assignment_id']] || @context.assignments.build
new_submission = Submission.new
new_submission.user = student
new_submission.assignment = assignment
edd = effective_due_dates.find_effective_due_date(student.id, assignment.id)
new_submission.cached_due_date = edd.fetch(:due_at, nil)
new_submission.grading_period_id = edd.fetch(:grading_period_id, nil)
submission['gradeable'] = !edd.fetch(:in_closed_grading_period, false) && gradeable?(
submission: new_submission,
is_admin: is_admin
)
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
end
end
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
@gradebook_importer_custom_columns[student.id].each do |column_id, student_custom_column_cell|
custom_column = custom_gradebook_columns.detect {|custom_col| custom_col.id == column_id}
datum = custom_column.custom_gradebook_column_data.detect {|custom_column_datum| custom_column_datum.user_id == student.id}
student_custom_column_cell['current_content'] = datum&.content
end
end
translate_pass_fail(@assignments, @students, @gradebook_importer_assignments)
during gradebook import pass_fail partial scores passes, 0 fails During Gradebook imports with pass_fail scores, points possible as well as partial points in the CSV are considered passing. 0 will be considered as failing. (The words "complete" and "incomplete" can still be passed.) Furthermore, the confirmation screen now reports "complete" or "incomplete" instead of the points being imported For the canvas user, this will result in a clearer understanding of the grade changes happening as a result of the import. fixes CNVS-21255 fixes gh-624 test plan: - Create a course with a student and 5 pass_fail assignments with 4 points possible - In the gradebook: - Leave three assignment as null - Set one assignment to complete - Set one assignment to incomplete - Export the current gradebook to CSV - Edit the CSV to: - Set the first null assignment to 4 points - Set the second null assignment to 1 point - Set the third null assignment to 0 points - Set the complete assignment to 0 points - Set the incomplete assignment to 1 point - Import the CSV back into the gradebook - Observe: - On the confirmation screen the words "complete" and "incomplete" are used - The first null assignment shows as complete - The second null assignment shows as complete - The third null assignment shows as incomplete - The complete assignment now shows as incomplete - The incomplete assignment now shows as complete Change-Id: I92921a3d88ad64f069573a2b27c41936151cec3c Reviewed-on: https://gerrit.instructure.com/62206 Reviewed-by: Cody Poll <cpoll@instructure.com> QA-Review: Jason Carter <jcarter@instructure.com> Tested-by: Jenkins Product-Review: Keith T. Garner <kgarner@instructure.com>
2015-09-01 05:37:09 +08:00
unless @missing_student
# weed out assignments with no changes
indexes_to_delete = []
@assignments.each_with_index do |assignment, idx|
next if assignment.changed? && !readonly_assignment?(idx)
indexes_to_delete << idx if readonly_assignment?(idx) || @students.all? do |student|
submission = @gradebook_importer_assignments[student.id][idx]
# Have potentially mixed case excused in grade match case
# expectations for the compare so it doesn't look changed
submission['grade'] = 'EX' if submission['grade'].to_s.casecmp('EX') == 0
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
no_change = submission['grade'] == submission['original_grade'] ||
(submission['original_grade'].present? && submission['grade'].present? && submission['original_grade'].to_f == submission['grade'].to_f) ||
(submission['original_grade'].blank? && submission['grade'].blank?)
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@warning_messages[:prevented_grading_ungradeable_submission] = true if !submission['gradeable'] && !no_change
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
no_change || !submission['gradeable']
end
end
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
custom_column_ids_to_skip_on_import = []
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
custom_gradebook_columns.each do |custom_column|
no_change = true
if @parsed_custom_column_data.include?(custom_column.id) && !custom_column.deleted?
no_change = no_change_to_column_values?(column_id: custom_column.id)
@warning_messages[:prevented_changing_read_only_column] = true if !no_change && custom_column.read_only
end
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
if no_change || exclude_custom_column_on_import(column: custom_column)
custom_column_ids_to_skip_on_import << custom_column.id
end
end
indexes_to_delete.reverse_each do |index|
@assignments.delete_at(index)
@students.each do |student|
@gradebook_importer_assignments[student.id].delete_at(index)
end
end
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@custom_gradebook_columns = @custom_gradebook_columns.reject { |custom_col| custom_column_ids_to_skip_on_import.include?(custom_col.id) }
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@students.each do |student|
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
@gradebook_importer_custom_columns[student.id].reject! do |column_id, _custom_col|
custom_column_ids_to_skip_on_import.include?(column_id)
end
end
@students.each do |student|
@gradebook_importer_assignments[student.id].select! { |sub| sub['gradeable'] }
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
end
@unchanged_assignments = !indexes_to_delete.empty?
@students = [] if @assignments.empty? && @custom_gradebook_columns.empty?
end
# remove concluded enrollments
prior_enrollment_ids = (
@all_students.keys - @context.gradable_students.pluck(:user_id).map(&:to_i)
).to_set
@students.delete_if { |s| prior_enrollment_ids.include? s.id }
@original_submissions = [] unless @missing_student || @missing_assignment
if prevent_new_assignment_creation?(periods, is_admin)
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@assignments.delete_if do |assignment|
new_assignment = assignment.new_record?
if new_assignment
@warning_messages[:prevented_new_assignment_creation_in_closed_period] = true
end
new_assignment
end
end
@upload.gradebook = self.as_json
@upload.save!
2011-02-01 09:57:29 +08:00
end
def translate_pass_fail(assignments, students, gradebook_importer_assignments)
during gradebook import pass_fail partial scores passes, 0 fails During Gradebook imports with pass_fail scores, points possible as well as partial points in the CSV are considered passing. 0 will be considered as failing. (The words "complete" and "incomplete" can still be passed.) Furthermore, the confirmation screen now reports "complete" or "incomplete" instead of the points being imported For the canvas user, this will result in a clearer understanding of the grade changes happening as a result of the import. fixes CNVS-21255 fixes gh-624 test plan: - Create a course with a student and 5 pass_fail assignments with 4 points possible - In the gradebook: - Leave three assignment as null - Set one assignment to complete - Set one assignment to incomplete - Export the current gradebook to CSV - Edit the CSV to: - Set the first null assignment to 4 points - Set the second null assignment to 1 point - Set the third null assignment to 0 points - Set the complete assignment to 0 points - Set the incomplete assignment to 1 point - Import the CSV back into the gradebook - Observe: - On the confirmation screen the words "complete" and "incomplete" are used - The first null assignment shows as complete - The second null assignment shows as complete - The third null assignment shows as incomplete - The complete assignment now shows as incomplete - The incomplete assignment now shows as complete Change-Id: I92921a3d88ad64f069573a2b27c41936151cec3c Reviewed-on: https://gerrit.instructure.com/62206 Reviewed-by: Cody Poll <cpoll@instructure.com> QA-Review: Jason Carter <jcarter@instructure.com> Tested-by: Jenkins Product-Review: Keith T. Garner <kgarner@instructure.com>
2015-09-01 05:37:09 +08:00
assignments.each_with_index do |assignment, idx|
next unless assignment.grading_type == "pass_fail"
students.each do |student|
submission = gradebook_importer_assignments.fetch(student.id)[idx]
during gradebook import pass_fail partial scores passes, 0 fails During Gradebook imports with pass_fail scores, points possible as well as partial points in the CSV are considered passing. 0 will be considered as failing. (The words "complete" and "incomplete" can still be passed.) Furthermore, the confirmation screen now reports "complete" or "incomplete" instead of the points being imported For the canvas user, this will result in a clearer understanding of the grade changes happening as a result of the import. fixes CNVS-21255 fixes gh-624 test plan: - Create a course with a student and 5 pass_fail assignments with 4 points possible - In the gradebook: - Leave three assignment as null - Set one assignment to complete - Set one assignment to incomplete - Export the current gradebook to CSV - Edit the CSV to: - Set the first null assignment to 4 points - Set the second null assignment to 1 point - Set the third null assignment to 0 points - Set the complete assignment to 0 points - Set the incomplete assignment to 1 point - Import the CSV back into the gradebook - Observe: - On the confirmation screen the words "complete" and "incomplete" are used - The first null assignment shows as complete - The second null assignment shows as complete - The third null assignment shows as incomplete - The complete assignment now shows as incomplete - The incomplete assignment now shows as complete Change-Id: I92921a3d88ad64f069573a2b27c41936151cec3c Reviewed-on: https://gerrit.instructure.com/62206 Reviewed-by: Cody Poll <cpoll@instructure.com> QA-Review: Jason Carter <jcarter@instructure.com> Tested-by: Jenkins Product-Review: Keith T. Garner <kgarner@instructure.com>
2015-09-01 05:37:09 +08:00
if submission['grade'].present?
gradebook_importer_assignments.fetch(student.id)[idx]['grade'] = assignment.score_to_grade(submission['grade'], \
submission['grade'])
during gradebook import pass_fail partial scores passes, 0 fails During Gradebook imports with pass_fail scores, points possible as well as partial points in the CSV are considered passing. 0 will be considered as failing. (The words "complete" and "incomplete" can still be passed.) Furthermore, the confirmation screen now reports "complete" or "incomplete" instead of the points being imported For the canvas user, this will result in a clearer understanding of the grade changes happening as a result of the import. fixes CNVS-21255 fixes gh-624 test plan: - Create a course with a student and 5 pass_fail assignments with 4 points possible - In the gradebook: - Leave three assignment as null - Set one assignment to complete - Set one assignment to incomplete - Export the current gradebook to CSV - Edit the CSV to: - Set the first null assignment to 4 points - Set the second null assignment to 1 point - Set the third null assignment to 0 points - Set the complete assignment to 0 points - Set the incomplete assignment to 1 point - Import the CSV back into the gradebook - Observe: - On the confirmation screen the words "complete" and "incomplete" are used - The first null assignment shows as complete - The second null assignment shows as complete - The third null assignment shows as incomplete - The complete assignment now shows as incomplete - The incomplete assignment now shows as complete Change-Id: I92921a3d88ad64f069573a2b27c41936151cec3c Reviewed-on: https://gerrit.instructure.com/62206 Reviewed-by: Cody Poll <cpoll@instructure.com> QA-Review: Jason Carter <jcarter@instructure.com> Tested-by: Jenkins Product-Review: Keith T. Garner <kgarner@instructure.com>
2015-09-01 05:37:09 +08:00
end
if submission['original_grade'].present?
gradebook_importer_assignments.fetch(student.id)[idx]['original_grade'] = assignment.score_to_grade(submission['original_grade'],
submission['original_grade'])
during gradebook import pass_fail partial scores passes, 0 fails During Gradebook imports with pass_fail scores, points possible as well as partial points in the CSV are considered passing. 0 will be considered as failing. (The words "complete" and "incomplete" can still be passed.) Furthermore, the confirmation screen now reports "complete" or "incomplete" instead of the points being imported For the canvas user, this will result in a clearer understanding of the grade changes happening as a result of the import. fixes CNVS-21255 fixes gh-624 test plan: - Create a course with a student and 5 pass_fail assignments with 4 points possible - In the gradebook: - Leave three assignment as null - Set one assignment to complete - Set one assignment to incomplete - Export the current gradebook to CSV - Edit the CSV to: - Set the first null assignment to 4 points - Set the second null assignment to 1 point - Set the third null assignment to 0 points - Set the complete assignment to 0 points - Set the incomplete assignment to 1 point - Import the CSV back into the gradebook - Observe: - On the confirmation screen the words "complete" and "incomplete" are used - The first null assignment shows as complete - The second null assignment shows as complete - The third null assignment shows as incomplete - The complete assignment now shows as incomplete - The incomplete assignment now shows as complete Change-Id: I92921a3d88ad64f069573a2b27c41936151cec3c Reviewed-on: https://gerrit.instructure.com/62206 Reviewed-by: Cody Poll <cpoll@instructure.com> QA-Review: Jason Carter <jcarter@instructure.com> Tested-by: Jenkins Product-Review: Keith T. Garner <kgarner@instructure.com>
2015-09-01 05:37:09 +08:00
end
end
end
end
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
def process_custom_column_headers(row)
row.each_with_index do |header_column, index|
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
gradebook_column = custom_gradebook_columns.detect { |column| column.title == header_column }
next if gradebook_column.blank?
@parsed_custom_column_data[gradebook_column.id] = {
title: header_column,
index: index,
read_only: gradebook_column.read_only
}
end
end
def strip_custom_columns(stripped_row)
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
@parsed_custom_column_data.each_value do |column|
stripped_row.delete(column[:title])
end
stripped_row
end
def process_header(row)
raise InvalidHeaderRow unless header?(row)
row = strip_non_assignment_columns(row)
row = strip_custom_columns(row)
parse_assignments(row) # requires non-assignment columns to be stripped
end
def header?(row)
return false unless row_has_student_headers? row
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
# this is here instead of in process_header() because @parsed_custom_column_data needs to be updated before update_column_count()
process_custom_column_headers(row)
update_column_count row
return false if last_student_info_column(row) !~ /Section/
true
end
def last_student_info_column(row)
# Custom Columns are between section and assignments
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
row[@student_columns - (1 + @parsed_custom_column_data.length)]
end
def row_has_student_headers?(row)
row.length > 3 && row[0] =~ /Student/ && row[1] =~ /ID/
end
def update_column_count(row)
# A side effect that's necessary to finish validation, but needs to come
# after the row.length check above.
@student_columns = 3 # name, user id, section
if row[2] =~ /SIS\s+Login\s+ID/
@sis_login_id_column = 2
@student_columns += 1
elsif row[2] =~ /SIS\s+User\s+ID/ && row[3] =~ /SIS\s+Login\s+ID/
@sis_user_id_column = 2
@sis_login_id_column = 3
@student_columns += 2
if row[4] =~ /Root\s+Account/
@student_columns +=1
@root_account_column = 4
end
end
# For Custom Columns
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
@student_columns += @parsed_custom_column_data.length
end
def strip_non_assignment_columns(stripped_row)
drop_student_information_columns(stripped_row)
# This regex will also include columns for unposted scores, which
# will be one of these values with "Unposted" prepended.
while stripped_row.last =~ /Current Score|Current Points|Current Grade|Final Score|Final Points|Final Grade/
stripped_row.pop
end
stripped_row
end
def drop_student_information_columns(row)
row.shift(@student_columns)
end
# this method requires non-assignment columns to be stripped from the row
def parse_assignments(stripped_row)
stripped_row.map do |name_and_id|
title, id = Assignment.title_and_id(name_and_id)
assignment = @all_assignments[id.to_i] if id.present?
# backward compat
assignment ||= @all_assignments.find { |_id, a| a.title == name_and_id }
.try(:last)
assignment ||= Assignment.new(:title => title || name_and_id)
assignment.previous_id = assignment.id
2011-02-01 09:57:29 +08:00
assignment.id ||= NegativeId.generate
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
@missing_assignment ||= assignment.new_record?
assignment
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
end.compact
end
def prevent_new_assignment_creation?(periods, is_admin)
return false unless @context.grading_periods?
return false if is_admin
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
GradingPeriod.date_in_closed_grading_period?(
course: @context,
date: nil,
periods: periods
)
2011-02-01 09:57:29 +08:00
end
def process_pp(row)
@pp_row = row
@assignments.each_with_index do |assignment, idx|
assignment.points_possible = row[idx] if row[idx]
end
end
def process_student(row)
student_id = row[1] # the second column in the csv should have the student_id for each row
student = @all_students[student_id.to_i] if student_id.present?
unless student
ra_sis_id = row[@root_account_column].presence if @root_account_column
unless @root_accounts.key?(ra_sis_id)
ra = ra_sis_id.nil? ? @context.root_account : Account.find_by_domain(ra_sis_id)
add_root_account_to_pseudonym_cache(ra) if ra
@root_accounts[ra_sis_id] = ra
end
ra = @root_accounts[ra_sis_id]
if ra && @sis_user_id_column && row[@sis_user_id_column].present?
sis_user_id = [ra.id, row[@sis_user_id_column]]
end
if ra && @sis_login_id_column && row[@sis_login_id_column].present?
sis_login_id = [ra.id, row[@sis_login_id_column]]
end
pseudonym = @pseudonyms_by_sis_id[sis_user_id] if sis_user_id
pseudonym ||= @pseudonyms_by_login_id[sis_login_id] if sis_login_id
student = @all_students[pseudonym.user_id] if pseudonym
end
if row[0].present?
student ||= @all_students.find do |_id, s|
s.name == row[0] || s.sortable_name == row[0]
end.try(:last)
end
student ||= User.new(:name => row[0])
student.previous_id = student.id
student.id ||= NegativeId.generate
@missing_student ||= student.new_record?
student
end
def process_submissions(row, student)
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
importer_submissions = []
@assignments.each_with_index do |assignment, idx|
assignment_id = assignment.new_record? ? assignment.id : assignment.previous_id
grade = row[idx + @student_columns]
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
if !assignment_visible_to_student(student, assignment, assignment_id, @visible_assignments)
grade = ''
end
new_submission = {
'grade' => grade,
'assignment_id' => assignment_id,
}
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
importer_submissions << new_submission
2011-02-01 09:57:29 +08:00
end
# custom columns
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
importer_custom_columns = {}
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
@parsed_custom_column_data.each do |id, custom_column|
column_index = custom_column[:index]
new_custom_column_data = {
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
'new_content' => row[column_index],
'column_id' => id
}
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
importer_custom_columns[id] = new_custom_column_data
end
@gradebook_importer_custom_columns[student.id] = importer_custom_columns
@gradebook_importer_assignments[student.id] = importer_submissions
2011-02-01 09:57:29 +08:00
end
def assignment_visible_to_student(student, assignment, assignment_id, visible_assignments)
return true unless visible_assignments # wont be set if DA is off
return true if assignment.new_record? || student.new_record?
assignments_visible_to_student = visible_assignments[student.id].to_set
assignments_visible_to_student.try(:include?, assignment_id)
end
def as_json(_options={})
2011-02-01 09:57:29 +08:00
{
:students => @students.map { |s| student_to_hash(s) },
:assignments => @assignments.map { |a| assignment_to_hash(a) },
:missing_objects => {
:assignments => @missing_assignments.map { |a| assignment_to_hash(a) },
:students => @missing_students.map { |s| student_to_hash(s) }
},
:original_submissions => @original_submissions,
:unchanged_assignments => @unchanged_assignments,
:warning_messages => @warning_messages,
:custom_columns => custom_gradebook_columns.map { |cc| custom_columns_to_hash(cc) },
}
2011-02-01 09:57:29 +08:00
end
2011-02-01 09:57:29 +08:00
protected
def custom_gradebook_columns
@custom_gradebook_columns ||= @context.custom_gradebook_columns.to_a
end
gradebook export and import localized CSV fixes GRADE-271 Test Plan: 1. Modify a local copy of config/locales/is.yml, adding the following translation key: csv: column_delimiter: ";" 2. Change Canvas settings to Íslenska (Icelandic): - root account settings - user profile - course settings 3. Create at least two students and at least two assignments for a course. - name at least one assignment with non-ASCII Icelandic characters such as "ð" - name at least one assignment with multi-byte Unicode characters, such as "文章" 4. Grade the assignments, covering the following: - decimal grade (with comma as decimal separator) - integer grade - empty grade 5. Go to (old) gradebook, export grades and download it 6. Configure Microsoft Excel for Icelandic language 7. Open the download in Excel. Verify that rows and columns are interpreted correctly, and that non- ASCII characters are displayed correctly. 8. Import the download in Google Sheets, specifying semicolon as the custom delmiter. Repeat the verification from (7) 9. Repeat steps 3-8 using new gradebook. 10. Repeat steps 3-8 using US English for all language settings. 11. Copy the Icelandic and English grade exports and modify some student grades 12. Import the modified Icelandic export file, while configured for US English. Verify that student grades are updated. 13. Import the modified English export file. Verify that student grades are updated. Change-Id: Icf7fcdadae5b22fad524a224d956fd93c2438b57 Reviewed-on: https://gerrit.instructure.com/128786 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Tested-by: Jenkins QA-Review: Indira Pai <ipai@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2017-10-04 22:51:38 +08:00
def identify_delimiter(rows)
field_counts = {}
%w[; ,].each do |separator|
begin
field_counts[separator] = 0
gradebook export and import localized CSV fixes GRADE-271 Test Plan: 1. Modify a local copy of config/locales/is.yml, adding the following translation key: csv: column_delimiter: ";" 2. Change Canvas settings to Íslenska (Icelandic): - root account settings - user profile - course settings 3. Create at least two students and at least two assignments for a course. - name at least one assignment with non-ASCII Icelandic characters such as "ð" - name at least one assignment with multi-byte Unicode characters, such as "文章" 4. Grade the assignments, covering the following: - decimal grade (with comma as decimal separator) - integer grade - empty grade 5. Go to (old) gradebook, export grades and download it 6. Configure Microsoft Excel for Icelandic language 7. Open the download in Excel. Verify that rows and columns are interpreted correctly, and that non- ASCII characters are displayed correctly. 8. Import the download in Google Sheets, specifying semicolon as the custom delmiter. Repeat the verification from (7) 9. Repeat steps 3-8 using new gradebook. 10. Repeat steps 3-8 using US English for all language settings. 11. Copy the Icelandic and English grade exports and modify some student grades 12. Import the modified Icelandic export file, while configured for US English. Verify that student grades are updated. 13. Import the modified English export file. Verify that student grades are updated. Change-Id: Icf7fcdadae5b22fad524a224d956fd93c2438b57 Reviewed-on: https://gerrit.instructure.com/128786 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Tested-by: Jenkins QA-Review: Indira Pai <ipai@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2017-10-04 22:51:38 +08:00
field_count_by_row = rows.map { |line| CSV.parse_line(line, col_sep: separator).size }
# If the number of fields generated by this separator is consistent for all lines,
# we should be able to assume it's a valid delimiter for this file
field_counts[separator] = field_count_by_row.first if field_count_by_row.uniq.size == 1
rescue CSV::MalformedCSVError => e
end
end
field_counts[';'] > field_counts[','] ? :semicolon : :comma
gradebook export and import localized CSV fixes GRADE-271 Test Plan: 1. Modify a local copy of config/locales/is.yml, adding the following translation key: csv: column_delimiter: ";" 2. Change Canvas settings to Íslenska (Icelandic): - root account settings - user profile - course settings 3. Create at least two students and at least two assignments for a course. - name at least one assignment with non-ASCII Icelandic characters such as "ð" - name at least one assignment with multi-byte Unicode characters, such as "文章" 4. Grade the assignments, covering the following: - decimal grade (with comma as decimal separator) - integer grade - empty grade 5. Go to (old) gradebook, export grades and download it 6. Configure Microsoft Excel for Icelandic language 7. Open the download in Excel. Verify that rows and columns are interpreted correctly, and that non- ASCII characters are displayed correctly. 8. Import the download in Google Sheets, specifying semicolon as the custom delmiter. Repeat the verification from (7) 9. Repeat steps 3-8 using new gradebook. 10. Repeat steps 3-8 using US English for all language settings. 11. Copy the Icelandic and English grade exports and modify some student grades 12. Import the modified Icelandic export file, while configured for US English. Verify that student grades are updated. 13. Import the modified English export file. Verify that student grades are updated. Change-Id: Icf7fcdadae5b22fad524a224d956fd93c2438b57 Reviewed-on: https://gerrit.instructure.com/128786 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Tested-by: Jenkins QA-Review: Indira Pai <ipai@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2017-10-04 22:51:38 +08:00
end
def semicolon_delimited?(csv_file)
first_lines = []
File.open(csv_file.path) do |csv|
while !csv.eof? && first_lines.size < 3
first_lines << csv.readline
end
end
return false if first_lines.blank?
identify_delimiter(first_lines) == :semicolon
end
def check_for_non_student_row(row)
# check if this is the first row, a header row
if @assignments.nil?
@assignments = process_header(row)
return true
end
if row[0] =~ /Points Possible/
# this row is describing the assignment, has no student data
row.shift(@student_columns)
process_pp(row)
return true
end
if row.compact.all? { |c| c.strip =~ /^(Muted|)$/i }
# this row is muted or empty and should not be processed at all
return true
end
false # nothing unusual, signal to process as a student row
end
def csv_stream
csv_file = attachment.open(need_local_file: true)
gradebook export and import localized CSV fixes GRADE-271 Test Plan: 1. Modify a local copy of config/locales/is.yml, adding the following translation key: csv: column_delimiter: ";" 2. Change Canvas settings to Íslenska (Icelandic): - root account settings - user profile - course settings 3. Create at least two students and at least two assignments for a course. - name at least one assignment with non-ASCII Icelandic characters such as "ð" - name at least one assignment with multi-byte Unicode characters, such as "文章" 4. Grade the assignments, covering the following: - decimal grade (with comma as decimal separator) - integer grade - empty grade 5. Go to (old) gradebook, export grades and download it 6. Configure Microsoft Excel for Icelandic language 7. Open the download in Excel. Verify that rows and columns are interpreted correctly, and that non- ASCII characters are displayed correctly. 8. Import the download in Google Sheets, specifying semicolon as the custom delmiter. Repeat the verification from (7) 9. Repeat steps 3-8 using new gradebook. 10. Repeat steps 3-8 using US English for all language settings. 11. Copy the Icelandic and English grade exports and modify some student grades 12. Import the modified Icelandic export file, while configured for US English. Verify that student grades are updated. 13. Import the modified English export file. Verify that student grades are updated. Change-Id: Icf7fcdadae5b22fad524a224d956fd93c2438b57 Reviewed-on: https://gerrit.instructure.com/128786 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Tested-by: Jenkins QA-Review: Indira Pai <ipai@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2017-10-04 22:51:38 +08:00
is_semicolon_delimited = semicolon_delimited?(csv_file)
csv_parse_options = {
converters: %i(nil),
skip_lines: /^[;, ]*$/,
col_sep: is_semicolon_delimited ? ";" : ","
}
if is_semicolon_delimited
csv_parse_options[:converters] << :decimal_comma_to_period
end
# using "foreach" rather than "parse" processes a chunk of the
# file at a time rather than loading the whole file into memory
# at once, a boon for memory consumption
gradebook export and import localized CSV fixes GRADE-271 Test Plan: 1. Modify a local copy of config/locales/is.yml, adding the following translation key: csv: column_delimiter: ";" 2. Change Canvas settings to Íslenska (Icelandic): - root account settings - user profile - course settings 3. Create at least two students and at least two assignments for a course. - name at least one assignment with non-ASCII Icelandic characters such as "ð" - name at least one assignment with multi-byte Unicode characters, such as "文章" 4. Grade the assignments, covering the following: - decimal grade (with comma as decimal separator) - integer grade - empty grade 5. Go to (old) gradebook, export grades and download it 6. Configure Microsoft Excel for Icelandic language 7. Open the download in Excel. Verify that rows and columns are interpreted correctly, and that non- ASCII characters are displayed correctly. 8. Import the download in Google Sheets, specifying semicolon as the custom delmiter. Repeat the verification from (7) 9. Repeat steps 3-8 using new gradebook. 10. Repeat steps 3-8 using US English for all language settings. 11. Copy the Icelandic and English grade exports and modify some student grades 12. Import the modified Icelandic export file, while configured for US English. Verify that student grades are updated. 13. Import the modified English export file. Verify that student grades are updated. Change-Id: Icf7fcdadae5b22fad524a224d956fd93c2438b57 Reviewed-on: https://gerrit.instructure.com/128786 Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Tested-by: Jenkins QA-Review: Indira Pai <ipai@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2017-10-04 22:51:38 +08:00
CSV.foreach(csv_file.path, csv_parse_options) do |row|
yield row
end
end
def add_root_account_to_pseudonym_cache(root_account)
pseudonyms = root_account.shard.activate do
root_account.pseudonyms
.active
.select([:id, :unique_id, :sis_user_id, :user_id])
.where(:user_id => @all_students.values).to_a
2011-02-01 09:57:29 +08:00
end
pseudonyms.each do |pseudonym|
@pseudonyms_by_sis_id[[root_account.id, pseudonym.sis_user_id]] = pseudonym
@pseudonyms_by_login_id[[root_account.id, pseudonym.unique_id]] = pseudonym
2011-02-01 09:57:29 +08:00
end
end
def custom_columns_to_hash(cc)
{
id: cc.id,
title: cc.title,
read_only: cc.read_only,
}
end
def student_to_hash(student)
{
:last_name_first => student.last_name_first,
:name => student.name,
:previous_id => student.previous_id,
:id => student.id,
:submissions => @gradebook_importer_assignments[student.id],
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
:custom_column_data => @gradebook_importer_custom_columns[student.id]&.values
}
end
2011-02-01 09:57:29 +08:00
def assignment_to_hash(assignment)
{
:id => assignment.id,
:previous_id => assignment.previous_id,
:title => assignment.title,
:points_possible => assignment.points_possible,
gradebook upload respects close date close date will now be respected when uploading a gradebook CSV. this means a) grades cannot be changed if they fall in a closed grading period, and b) assignments cannot be created via upload if they would fall in a closed grading period. closes CNVS-26720 test plan: 1. turn multiple grading periods on for a course, go to the gradebook and click 'import'. 2. log in as a non-admin teacher and verify via CSV upload: a) trying to change the grade for a submission that falls in a closed grading period does not change the grade and displays a message before uploading that says some submissions were skipped because they were not gradeable. b) changing the grade for a submission with a due date that does not fall in a closed grading period is allowed. c) trying to create a new assignment (by adding a new assignment column in the CSV) does not succeed if the last grading period in the course is closed. also verify a message is displayed saying new assignments could not be created because they would fall in a closed grading period. d) creating a new assignment (by adding a new assignment column in the CSV) succeeds if the last grading period in the course is not closed. 3. log in as a root account admin and verify step 2a allows the user to change a submission's grade and step 2c allows the user to create a new assignment. 4. turn off multiple grading periods and verify gradebook upload behaves normally. Change-Id: Ic4e9e1b08d7910cf99b5c4cff57d921e80af9e19 Reviewed-on: https://gerrit.instructure.com/88540 Tested-by: Jenkins Reviewed-by: Jeremy Neander <jneander@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Keith T. Garner <kgarner@instructure.com>
2016-08-22 22:25:51 +08:00
:grading_type => assignment.grading_type
}
end
def valid_context?(context=nil)
context && [
:students,
:assignments,
:submissions,
:students=,
:assignments=,
:submissions=
].all?{ |m| context.respond_to?(m) }
end
def readonly_assignment?(index)
@pp_row[index] =~ /read\s+only/
end
private
def gradeable?(submission:, is_admin: false)
# `submission#grants_right?` will check if the user
# is an admin, but if we've pre-loaded that value already
# to avoid an N+1, check that first.
is_admin || submission.grants_right?(@user, :grade)
end
[ci no-cached-dist] Handle custom columns properly when importing When importing a gradebook CSV and and analyzing what changes have been made, map changes to custom columns properly and do not attempt to include deleted or hidden columns. fixes GRADE-1616 Test plan: - In a course with some students, set up four custom columns (referred to as C1 through C4); for now, don't change any settings on them - In new Gradebook, set some values for the columns - Adjust them as follows: - C1: deleted - C2: hidden - C3: read-only - C4: [leave as is] - Export a CSV - The CSV should contain C3 and C4 but not the other two columns (this behavior has not changed) - Twiddle some assignment scores and custom-column values in the CSV - Import the edited CSV and check the following on the proposed changes screen: - Changes to C4 are shown as expected - Any changes to assignment scores are shown as expected - Changes to C3 are *not* shown, and the warning message about preventing changing read-only columns is shown at the bottom - Otherwise, everything is as you'd expect: the importer isn't attempting to replace a custom column with the section name or perpetrate any similar skulduggery Change-Id: Ib1ebcec6820120288e67c1652cb5496a8b8240a7 Reviewed-on: https://gerrit.instructure.com/167149 Reviewed-by: Keith Garner <kgarner@instructure.com> Reviewed-by: Gary Mei <gmei@instructure.com> Reviewed-by: Derek Bender <djbender@instructure.com> QA-Review: Gary Mei <gmei@instructure.com> Product-Review: Keith Garner <kgarner@instructure.com> Tested-by: Jenkins
2018-10-05 03:20:09 +08:00
def no_change_to_column_values?(column_id:)
@students.all? do |student|
custom_column_datum = @gradebook_importer_custom_columns[student.id][column_id]
return true if custom_column_datum['current_content'].blank? && custom_column_datum['new_content'].blank?
custom_column_datum['current_content'] == custom_column_datum['new_content']
end
end
def exclude_custom_column_on_import(column:)
column.deleted? || column.read_only
end
2011-02-01 09:57:29 +08:00
end