Skip to content

Commit

Permalink
Control when sets with score 0 are included in LTI grade passback
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex-Jordan committed Nov 5, 2024
1 parent dd844c7 commit 9760e68
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 19 deletions.
7 changes: 7 additions & 0 deletions conf/authen_LTI.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ $LTIGradeMode = '';
#$LTIGradeMode = 'course';
#$LTIGradeMode = 'homework';

# This can be set to 'open', 'reduced', 'close', 'answer', or 'never'. It controls when a set
# with score 0 will be included in grades that are passed back to the LMS. For example, setting
# this to 'close' means that a set with score 0 is only included in grades sent to the LMS once
# it is past the set's close date.
$LTISendZeroScores = 'open';

# When set this variable sends grades back to the LMS every time a user submits an answer. This
# keeps students grades up to date but can be a drain on the server.
$LTIGradeOnSubmit = 1;
Expand Down Expand Up @@ -170,6 +176,7 @@ $LTIMassUpdateInterval = 86400; #in seconds
#'LTI{v1p3}{LMS_url}',
#'external_auth',
#'LTIGradeMode',
#'LTISendZeroScores',
#'LTIGradeOnSubmit',
#'LTIMassUpdateInterval',
#'LMSManageUserData',
Expand Down
24 changes: 17 additions & 7 deletions lib/WeBWorK/Authen/LTIAdvanced/SubmitGrade.pm
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ async sub submit_course_grade ($self, $userID) {
$self->warning("lis_source_did is not available for user: $userID")
if !$user->lis_source_did && ($ce->{debug_lti_grade_passback} || $self->{post_processing_mode});

return await $self->submit_grade($user->lis_source_did, scalar(grade_all_sets($db, $userID)));
return await $self->submit_grade($user->lis_source_did,
scalar(grade_all_sets($db, $userID, $ce->{LTISendZeroScores})));
}

# Computes and submits the set grade for $userID and $setID to the LMS. For gateways the best score is used.
Expand All @@ -147,14 +148,23 @@ async sub submit_set_grade ($self, $userID, $setID) {
$self->warning('lis_source_did is not available for this set.')
if !$userSet->lis_source_did && ($ce->{debug_lti_grade_passback} || $self->{post_processing_mode});

return await $self->submit_grade(
$userSet->lis_source_did,
scalar(
$userSet->assignment_type =~ /gateway/
my $score =
scalar($userSet->assignment_type =~ /gateway/
? grade_gateway($db, $userSet, $userSet->set_id, $userID)
: grade_set($db, $userSet, $userID, 0)
)
: grade_set($db, $userSet, $userID, 0));

my %dates = (
open => $userSet->open_date(),
reduced => $userSet->reduced_scoring_date(),
close => $userSet->close_date(),
answer => $userSet->answer_date()
);

if ($score == 0) {
return if ($ce->{LTISendZeroScores} eq 'never' || before($dates{ $ce->{LTISendZeroScores} }));
}

return await $self->submit_grade($userSet->lis_source_did, $score);
}

# Submits a score of $score to the lms with $sourcedid as the identifier.
Expand Down
18 changes: 16 additions & 2 deletions lib/WeBWorK/Authen/LTIAdvantage/SubmitGrade.pm
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ async sub submit_course_grade ($self, $userID) {
$self->warning('LMS user id is not available for this user.') unless $user->lis_source_did;
$self->warning('LMS lineitem is not available for the course.') unless $lineitem;

return await $self->submit_grade($user->lis_source_did, $lineitem, grade_all_sets($db, $userID));
return await $self->submit_grade($user->lis_source_did, $lineitem,
grade_all_sets($db, $userID, $ce->{LTISendZeroScores}));
}

# Computes and submits the set grade for $userID and $setID to the LMS. For gateways the best score is used.
Expand All @@ -225,10 +226,23 @@ async sub submit_set_grade ($self, $userID, $setID) {
$self->warning('LMS user id is not available for this user.') unless $user->lis_source_did;
$self->warning('LMS lineitem is not available for this set.') unless $userSet->lis_source_did;

my ($totalRight, $total) = (grade_set($db, $userSet, $userID, 0))[ 0, 1 ];

my %dates = (
open => $userSet->open_date(),
reduced => $userSet->reduced_scoring_date(),
close => $userSet->close_date(),
answer => $userSet->answer_date()
);

if ($totalRight == 0) {
return if ($ce->{LTISendZeroScores} eq 'never' || before($dates{ $ce->{LTISendZeroScores} }));
}

return await $self->submit_grade($user->lis_source_did, $userSet->lis_source_did,
$userSet->assignment_type =~ /gateway/
? grade_gateway($db, $userSet, $userSet->set_id, $userID)
: (grade_set($db, $userSet, $userID, 0))[ 0, 1 ]);
: ($totalRight, $total));
}

# Submits scoreGiven and scoreMaximum to the lms with $sourcedid as the identifier.
Expand Down
19 changes: 19 additions & 0 deletions lib/WeBWorK/ConfigValues.pm
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,25 @@ sub getConfigValues ($ce) {
labels => { '' => 'None', 'course' => 'Course', 'homework' => 'Homework' },
type => 'popuplist'
},
LTISendZeroScores => {
var => 'LTISendZeroScores',
doc => x('When to send zero scores to the LMS'),
doc2 => x(
'If the grade passback mode is "homework", this controls when a set with score 0 will have '
. 'that score sent to the LMS, as opposed to leaving the score null in the LMS. If the grade '
. 'passback mode is "course", this controls when a set with score 0 will be included in the '
. 'overall grade calculation that is sent to the LMS.'
),
values => [qw(open reduced close answer never)],
labels => {
open => 'After Open Date',
reduced => 'After Reduced Scoring Date',
close => 'After Close Date',
answer => 'After Answer Date',
never => 'Never'
},
type => 'popuplist'
},
LTIGradeOnSubmit => {
var => 'LTIGradeOnSubmit',
doc => x('Update LMS Grade Each Submit'),
Expand Down
27 changes: 17 additions & 10 deletions lib/WeBWorK/Utils/Sets.pm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use Carp;

use PGrandom;
use WeBWorK::Utils qw(wwRound);
use WeBWorK::Utils::DateTime qw(after);
use WeBWorK::Utils::DateTime qw(after before);
use WeBWorK::Utils::JITAR qw(jitar_id_to_seq jitar_problem_adjusted_status);

our @EXPORT_OK = qw(
Expand Down Expand Up @@ -146,7 +146,7 @@ sub grade_gateway ($db, $set, $setName, $studentName) {
}
}

sub grade_all_sets ($db, $studentName) {
sub grade_all_sets ($db, $studentName, $LTISendZeroScores) {
my @setIDs = $db->listUserSets($studentName);
my @userSetIDs = map { [ $studentName, $_ ] } @setIDs;
my @userSets = $db->getMergedSets(@userSetIDs);
Expand All @@ -156,17 +156,24 @@ sub grade_all_sets ($db, $studentName) {

for my $userSet (@userSets) {
next unless (after($userSet->open_date()));
my $totalRight;
my $total;
my %dates = (
open => $userSet->open_date(),
reduced => $userSet->reduced_scoring_date(),
close => $userSet->close_date(),
answer => $userSet->answer_date()
);
if ($userSet->assignment_type() =~ /gateway/) {

my ($totalRight, $total) = grade_gateway($db, $userSet, $userSet->set_id, $studentName);
$courseTotalRight += $totalRight;
$courseTotal += $total;
($totalRight, $total) = grade_gateway($db, $userSet, $userSet->set_id, $studentName);
} else {
my ($totalRight, $total) = grade_set($db, $userSet, $studentName, 0);

$courseTotalRight += $totalRight;
$courseTotal += $total;
($totalRight, $total) = grade_set($db, $userSet, $studentName, 0);
}
if ($totalRight == 0) {
next if ($LTISendZeroScores eq 'never' || before($dates{$LTISendZeroScores}));
}
$courseTotalRight += $totalRight;
$courseTotal += $total;
}

if (wantarray) {
Expand Down

0 comments on commit 9760e68

Please sign in to comment.