--- loncom/homework/grades.pm 2017/07/02 16:50:30 1.741 +++ loncom/homework/grades.pm 2017/12/31 14:00:41 1.749 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.741 2017/07/02 16:50:30 raeburn Exp $ +# $Id: grades.pm,v 1.749 2017/12/31 14:00:41 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -116,7 +116,11 @@ sub getpartlist { my $res = $navmap->getBySymb($symb); my $partlist = $res->parts(); my $url = $res->src(); - my @metakeys = split(/,/,&Apache::lonnet::metadata($url,'keys')); + my $toolsymb; + if ($url =~ /ext\.tool$/) { + $toolsymb = $symb; + } + my @metakeys = split(/,/,&Apache::lonnet::metadata($url,'keys',$toolsymb)); my @stores; foreach my $part (@{ $partlist }) { @@ -852,6 +856,7 @@ sub verifyreceipt { sub listStudents { my ($request,$symb,$submitonly) = @_; + my $is_tool = ($symb =~ /ext\.tool$/); my $cdom = $env{"course.$env{'request.course.id'}.domain"}; my $cnum = $env{"course.$env{'request.course.id'}.num"}; my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'}; @@ -907,38 +912,66 @@ LISTJAVASCRIPT "\n"; $gradeTable .= &Apache::lonhtmlcommon::start_pick_box(); - $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Problem Text')) - .'<label><input type="radio" name="vProb" value="no" checked="checked" /> '.&mt('no').' </label>'."\n" - .'<label><input type="radio" name="vProb" value="yes" /> '.&mt('one student').' </label>'."\n" - .'<label><input type="radio" name="vProb" value="all" /> '.&mt('all students').' </label><br />'."\n" - .&Apache::lonhtmlcommon::row_closure(); - $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Answer')) - .'<label><input type="radio" name="vAns" value="no" /> '.&mt('no').' </label>'."\n" - .'<label><input type="radio" name="vAns" value="yes" /> '.&mt('one student').' </label>'."\n" - .'<label><input type="radio" name="vAns" value="all" checked="checked" /> '.&mt('all students').' </label><br />'."\n" - .&Apache::lonhtmlcommon::row_closure(); + unless ($is_tool) { + $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Problem Text')) + .'<label><input type="radio" name="vProb" value="no" checked="checked" /> '.&mt('no').' </label>'."\n" + .'<label><input type="radio" name="vProb" value="yes" /> '.&mt('one student').' </label>'."\n" + .'<label><input type="radio" name="vProb" value="all" /> '.&mt('all students').' </label><br />'."\n" + .&Apache::lonhtmlcommon::row_closure(); + $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Answer')) + .'<label><input type="radio" name="vAns" value="no" /> '.&mt('no').' </label>'."\n" + .'<label><input type="radio" name="vAns" value="yes" /> '.&mt('one student').' </label>'."\n" + .'<label><input type="radio" name="vAns" value="all" checked="checked" /> '.&mt('all students').' </label><br />'."\n" + .&Apache::lonhtmlcommon::row_closure(); + } my $submission_options; my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); my $saveStatus = $stu_status eq '' ? 'Active' : $stu_status; $env{'form.Status'} = $saveStatus; + my %optiontext; + if ($is_tool) { + %optiontext = &Apache::lonlocal::texthash ( + lastonly => 'last transaction', + last => 'last transaction with details', + datesub => 'all transactions', + all => 'all transactions with details', + ); + } else { + %optiontext = &Apache::lonlocal::texthash ( + lastonly => 'last submission', + last => 'last submission with details', + datesub => 'all submissions', + all => 'all submissions with details', + ); + } $submission_options.= '<span class="LC_nobreak">'. '<label><input type="radio" name="lastSub" value="lastonly" /> '. - &mt('last submission').' </label></span>'."\n". + $optiontext{'lastonly'}.' </label></span>'."\n". '<span class="LC_nobreak">'. '<label><input type="radio" name="lastSub" value="last" /> '. - &mt('last submission with details').' </label></span>'."\n". + $optiontext{'last'}.' </label></span>'."\n". '<span class="LC_nobreak">'. '<label><input type="radio" name="lastSub" value="datesub" checked="checked" /> '. - &mt('all submissions').'</label></span>'."\n". + $optiontext{'datesub'}.'</label></span>'."\n". '<span class="LC_nobreak">'. '<label><input type="radio" name="lastSub" value="all" /> '. - &mt('all submissions with details').'</label></span>'; - $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('View Submissions')) + $optiontext{'all'}.'</label></span>'; + my $viewtitle; + if ($is_tool) { + $viewtitle = &mt('View Transactions'); + } else { + $viewtitle = &mt('View Submissions'); + } + $gradeTable .= &Apache::lonhtmlcommon::row_title($viewtitle) .$submission_options .&Apache::lonhtmlcommon::row_closure(); + my $closure; + if (($is_tool) && (exists($env{'form.Status'}))) { + $closure = 1; + } $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Grading Increments')) .'<select name="increment">' .'<option value="1">'.&mt('Whole Points').'</option>' @@ -946,7 +979,7 @@ LISTJAVASCRIPT .'<option value=".25">'.&mt('Quarter Points').'</option>' .'<option value=".1">'.&mt('Tenths of a Point').'</option>' .'</select>' - .&Apache::lonhtmlcommon::row_closure(); + .&Apache::lonhtmlcommon::row_closure($closure); $gradeTable .= &build_section_inputs(). @@ -957,19 +990,30 @@ LISTJAVASCRIPT if (exists($env{'form.Status'})) { $gradeTable .= '<input type="hidden" name="Status" value="'.$stu_status.'" />'."\n"; } else { + if ($is_tool) { + $closure = 1; + } $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Student Status')) .&Apache::lonhtmlcommon::StatusOptions( $saveStatus,undef,1,'javascript:reLoadList(this.form);') - .&Apache::lonhtmlcommon::row_closure(); + .&Apache::lonhtmlcommon::row_closure($closure); } - $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Check For Plagiarism')) - .'<input type="checkbox" name="checkPlag" checked="checked" />' - .&Apache::lonhtmlcommon::row_closure(1) - .&Apache::lonhtmlcommon::end_pick_box(); - + unless ($is_tool) { + $closure = 1; + $gradeTable .= &Apache::lonhtmlcommon::row_title(&mt('Check For Plagiarism')) + .'<input type="checkbox" name="checkPlag" checked="checked" />' + .&Apache::lonhtmlcommon::row_closure($closure); + } + $gradeTable .= &Apache::lonhtmlcommon::end_pick_box(); + my $regrademsg; + if ($is_tool) { + $regrademsg =&mt("To view/grade/regrade, click on the check box(es) next to the student's name(s). Then click on the Next button."); + } else { + $regrademsg = &mt("To view/grade/regrade a submission or a group of submissions, click on the check box(es) next to the student's name(s). Then click on the Next button."); + } $gradeTable .= '<p>' - .&mt("To view/grade/regrade a submission or a group of submissions, click on the check box(es) next to the student's name(s). Then click on the Next button.")."\n" + .$regrademsg."\n" .'<input type="hidden" name="command" value="processGroup" />' .'</p>'; @@ -1977,6 +2021,7 @@ sub submission { my $probtitle=&Apache::lonnet::gettitle($symb); if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; } + my $is_tool = ($symb =~ /ext\.tool$/); if (!&canview($usec)) { $request->print( @@ -1989,8 +2034,10 @@ sub submission { } if (!$env{'form.lastSub'}) { $env{'form.lastSub'} = 'datesub'; } - if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; } - if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; } + unless ($is_tool) { + if (!$env{'form.vProb'}) { $env{'form.vProb'} = 'yes'; } + if (!$env{'form.vAns'}) { $env{'form.vAns'} = 'yes'; } + } my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : ''); my $checkIcon = '<img alt="'.&mt('Check Mark'). '" src="'.$request->dir_config('lonIconsURL'). @@ -2078,7 +2125,7 @@ sub submission { $request->print($prnmsg); # if ($env{'form.handgrade'} eq 'yes') { - if (1) { + unless ($is_tool) { my %lt = &Apache::lonlocal::texthash( keyh => 'Keyword Highlighting for Essays', @@ -2163,12 +2210,16 @@ sub submission { # Display student info $request->print(($counter == 0 ? '' : '<br />')); + my $boxtitle = &mt('Submissions'); + if ($is_tool) { + $boxtitle = &mt('Transactions') + } my $result='<div class="LC_Box">' - .'<h3 class="LC_hcell">'.&mt('Submissions').'</h3>'; + .'<h3 class="LC_hcell">'.$boxtitle.'</h3>'; $result.='<input type="hidden" name="name'.$counter. '" value="'.$env{'form.fullname'}.'" />'."\n"; # if ($env{'form.handgrade'} eq 'no') { - if (1) { + unless ($is_tool) { $result.='<p class="LC_info">' .&mt('Part(s) graded correct by the computer is marked with a [_1] symbol.',$checkIcon) ."</p>\n"; @@ -2178,7 +2229,7 @@ sub submission { my $fullname; my $col_fullnames = []; # if ($env{'form.handgrade'} eq 'yes') { - if (1) { + unless ($is_tool) { (my $sub_result,$fullname,$col_fullnames)= &check_collaborators($symb,$uname,$udom,\%record,$handgrade, $counter); @@ -2193,12 +2244,16 @@ sub submission { # (3) Last submission plus the parts info # (4) The whole record for this student - my ($string,$timestamp)= &get_last_submission(\%record); + my ($string,$timestamp)= &get_last_submission(\%record,$is_tool); my $lastsubonly; if ($$timestamp eq '') { $lastsubonly.='<div class="LC_grade_submissions_body">'.$$string[0].'</div>'; + } elsif ($is_tool) { + $lastsubonly = + '<div class="LC_grade_submissions_body">' + .'<b>'.&mt('Date Grade Passed Back:').'</b> '.$$timestamp."</div>\n"; } else { $lastsubonly = '<div class="LC_grade_submissions_body">' @@ -2381,7 +2436,12 @@ sub submission { my %seen = (); my @partlist; my @gradePartRespid; - my @part_response_id = &flatten_responseType($responseType); + my @part_response_id; + if ($is_tool) { + @part_response_id = ([0,'']); + } else { + @part_response_id = &flatten_responseType($responseType); + } $request->print( '<div class="LC_Box">' .'<h3 class="LC_hcell">'.&mt('Assign Grades').'</h3>' @@ -2507,7 +2567,7 @@ sub check_collaborators { #--- Retrieve the last submission for all the parts sub get_last_submission { - my ($returnhash)=@_; + my ($returnhash,$is_tool)=@_; my (@string,$timestamp,%lasthidden); if ($$returnhash{'version'}) { my %lasthash=(); @@ -2573,8 +2633,14 @@ sub get_last_submission { } } if (!@string) { + my $msg; + if ($is_tool) { + $msg = &mt('No grade passed back.'); + } else { + $msg = &mt('Nothing submitted - no attempts.'); + } $string[0] = - '<span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span>'; + '<span class="LC_warning">'.$msg.'</span>'; } return (\@string,\$timestamp); } @@ -3561,6 +3627,11 @@ VIEWJAVASCRIPT #--- show scores for a section or whole class w/ option to change/update a score sub viewgrades { my ($request,$symb) = @_; + my ($is_tool,$toolsymb); + if ($symb =~ /ext\.tool$/) { + $is_tool = 1; + $toolsymb = $symb; + } &viewgrades_js($request); #need to make sure we have the correct data for later EXT calls, @@ -3641,7 +3712,13 @@ sub viewgrades { if ($env{'form.submitonly'} eq 'all') { $result.= '<h3>'.$common_header.'</h3>'; } else { - $result.= '<h3>'.$common_header.' '.&mt('(submission status: "[_1]")',$submission_status).'</h3>'; + my $text; + if ($is_tool) { + $text = &mt('(transaction status: "[_1]")',$submission_status); + } else { + $text = &mt('(submission status: "[_1]")',$submission_status); + } + $result.= '<h3>'.$common_header.' '.$text.'</h3>'; } $result .= &Apache::loncommon::start_data_table(); #radio buttons/text box for assigning points for a section or class. @@ -3654,13 +3731,18 @@ sub viewgrades { my %weight = (); my $ctsparts = 0; my %seen = (); - my @part_response_id = &flatten_responseType($responseType); + my @part_response_id; + if ($is_tool) { + @part_response_id = ([0,'']); + } else { + @part_response_id = &flatten_responseType($responseType); + } foreach my $part_response_id (@part_response_id) { my ($partid,$respid) = @{ $part_response_id }; my $part_resp = join('_',@{ $part_response_id }); next if $seen{$partid}; $seen{$partid}++; - my $handgrade=$$handgrade{$part_resp}; +# my $handgrade=$$handgrade{$part_resp}; my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb); $weight{$partid} = $wgt eq '' ? '1' : $wgt; @@ -3709,7 +3791,13 @@ sub viewgrades { if ($env{'form.submitonly'} eq 'all') { $result.= '<h3>'.$specific_header.'</h3>'; } else { - $result.= '<h3>'.$specific_header.' '.&mt('(submission status: "[_1]")',$submission_status).'</h3>'; + my $text; + if ($is_tool) { + $text = &mt('(transaction status: "[_1]")',$submission_status); + } else { + $text = &mt('(submission status: "[_1]")',$submission_status); + } + $result.= '<h3>'.$specific_header.' '.$text.'</h3>'; } $result.= &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). @@ -3723,10 +3811,10 @@ sub viewgrades { my (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); my @partids = (); foreach my $part (@parts) { - my $display=&Apache::lonnet::metadata($url,$part.'.display'); + my $display=&Apache::lonnet::metadata($url,$part.'.display',$toolsymb); my $narrowtext = &mt('Tries'); $display =~ s|^Number of Attempts|$narrowtext <br />|; # makes the column narrower - if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); } + if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name',$toolsymb); } my ($partid) = &split_part_type($part); push(@partids,$partid); # @@ -3767,7 +3855,7 @@ sub viewgrades { return $a cmp $b; } (keys(%$fullname))) { $result.=&viewstudentgrade($symb,$env{'request.course.id'}, - $_,$$fullname{$_},\@parts,\%weight,\$ctr,\%last_resets); + $_,$$fullname{$_},\@parts,\%weight,\$ctr,\%last_resets,$is_tool); } $result.=&Apache::loncommon::end_data_table(); $result.='<input type="hidden" name="total" value="'.$ctr.'" />'."\n"; @@ -3855,7 +3943,7 @@ sub viewgrades { #--- call by previous routine to display each student who satisfies submission filter. sub viewstudentgrade { - my ($symb,$courseid,$student,$fullname,$parts,$weight,$ctr,$last_resets) = @_; + my ($symb,$courseid,$student,$fullname,$parts,$weight,$ctr,$last_resets,$is_tool) = @_; my ($uname,$udom) = split(/:/,$student); my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname); my $submitonly = $env{'form.submitonly'}; @@ -3961,6 +4049,10 @@ sub viewstudentgrade { # record does not get update if unchanged sub editgrades { my ($request,$symb) = @_; + my $toolsymb; + if ($symb =~ /ext\.tool$/) { + $toolsymb = $symb; + } my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section')); my $title='<h2>'.&mt('Current Grade Status').'</h2>'; @@ -3998,6 +4090,7 @@ sub editgrades { $ctr++; } my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb); + my $totcolspan = 0; foreach my $partid (@partid) { $header .= '<th align="center">'.&mt('Old Score').'</th>'. '<th align="center">'.&mt('New Score').'</th>'; @@ -4006,7 +4099,7 @@ sub editgrades { my ($part,$type) = &split_part_type($stores); if ($part !~ m/^\Q$partid\E/) { next;} if ($type eq 'awarded' || $type eq 'solved') { next; } - my $display=&Apache::lonnet::metadata($url,$stores.'.display'); + my $display=&Apache::lonnet::metadata($url,$stores.'.display',$toolsymb); $display =~ s/\[Part: \Q$part\E\]//; my $narrowtext = &mt('Tries'); $display =~ s/Number of Attempts/$narrowtext/; @@ -4014,6 +4107,7 @@ sub editgrades { '<th align="center">'.&mt('New').' '.$display.'</th>'; $columns{$partid}+=2; } + $totcolspan += $columns{$partid}; } foreach my $partid (@partid) { my $display_part=&get_display_part($partid,$symb); @@ -4029,18 +4123,18 @@ sub editgrades { my @noupdate; my ($updateCtr,$noupdateCtr) = (1,1); for ($i=0; $i<$env{'form.total'}; $i++) { - my $line; my $user = $env{'form.ctr'.$i}; my ($uname,$udom)=split(/:/,$user); my %newrecord; my $updateflag = 0; - $line .= '<td>'.&nameUserString(undef,$$fullname{$user},$uname,$udom).'</td>'; my $usec=$classlist->{"$uname:$udom"}[5]; - if (!&canmodify($usec)) { - my $numcols=scalar(@partid)*4+2; + my $canmodify = &canmodify($usec); + my $line = '<td'.($canmodify?'':' colspan="2"').'>'. + &nameUserString(undef,$$fullname{$user},$uname,$udom).'</td>'; + if (!$canmodify) { push(@noupdate, - $line."<td colspan=\"$numcols\"><span class=\"LC_warning\">". - &mt('Not allowed to modify student')."</span></td></tr>"); + $line."<td colspan=\"$totcolspan\"><span class=\"LC_warning\">". + &mt('Not allowed to modify student')."</span></td>"); next; } my %aggregate = (); @@ -4157,8 +4251,7 @@ sub editgrades { } } if (@noupdate) { -# my $numcols=(scalar(@partid)*(scalar(@parts)-1)*2)+3; - my $numcols=scalar(@partid)*4+2; + my $numcols=$totcolspan+2; $result .= &Apache::loncommon::start_data_table_row('LC_empty_row'). '<td align="center" colspan="'.$numcols.'">'. &mt('No Changes Occurred For the Students Below'). @@ -4199,7 +4292,7 @@ sub split_part_type { # #--- Javascript to handle csv upload sub csvupload_javascript_reverse_associate { - my $error1=&mt('You need to specify the username or the student/employee ID'); + my $error1=&mt('You need to specify the username, the student/employee ID, or the clicker ID'); my $error2=&mt('You need to specify at least one grading field'); &js_escape(\$error1); &js_escape(\$error2); @@ -4208,13 +4301,15 @@ sub csvupload_javascript_reverse_associa var foundsomething=0; var founduname=0; var foundID=0; + var foundclicker=0; for (i=0;i<=vf.nfields.value;i++) { tw=eval('vf.f'+i+'.selectedIndex'); if (i==0 && tw!=0) { foundID=1; } if (i==1 && tw!=0) { founduname=1; } - if (i!=0 && i!=1 && i!=2 && tw!=0) { foundsomething=1; } + if (i==2 && tw!=0) { foundclicker=1; } + if (i!=0 && i!=1 && i!=2 && i!=3 && tw!=0) { foundsomething=1; } } - if (founduname==0 && foundID==0) { + if (founduname==0 && foundID==0 && foundclicker==0) { alert('$error1'); return; } @@ -4241,7 +4336,7 @@ ENDPICK } sub csvupload_javascript_forward_associate { - my $error1=&mt('You need to specify the username or the student/employee ID'); + my $error1=&mt('You need to specify the username, the student/employee ID, or the clicker ID'); my $error2=&mt('You need to specify at least one grading field'); &js_escape(\$error1); &js_escape(\$error2); @@ -4250,13 +4345,15 @@ sub csvupload_javascript_forward_associa var foundsomething=0; var founduname=0; var foundID=0; + var foundclicker=0; for (i=0;i<=vf.nfields.value;i++) { tw=eval('vf.f'+i+'.selectedIndex'); if (tw==1) { foundID=1; } if (tw==2) { founduname=1; } - if (tw>3) { foundsomething=1; } + if (tw==3) { foundclicker=1; } + if (tw>4) { foundsomething=1; } } - if (founduname==0 && foundID==0) { + if (founduname==0 && foundID==0 && Ć’oundclicker==0) { alert('$error1'); return; } @@ -4314,6 +4411,10 @@ ENDPICK sub csvupload_fields { my ($symb,$errorref) = @_; + my $toolsymb; + if ($symb =~ /ext\.tool$/) { + $toolsymb = $symb; + } my (@parts) = &getpartlist($symb,$errorref); if (ref($errorref)) { if ($$errorref) { @@ -4322,15 +4423,15 @@ sub csvupload_fields { } my @fields=(['ID','Student/Employee ID'], - ['clicker','Clicker ID'], ['username','Student Username'], + ['clicker','Clicker ID'], ['domain','Student Domain']); my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb); foreach my $part (sort(@parts)) { my @datum; - my $display=&Apache::lonnet::metadata($url,$part.'.display'); + my $display=&Apache::lonnet::metadata($url,$part.'.display',$toolsymb); my $name=$part; - if (!$display) { $display = $name; } + if (!$display) { $display = $name; } @datum=($name,$display); if ($name=~/^stores_(.*)_awarded/) { push(@fields,['stores_'.$1.'_points',"Points [Part: $1]"]); @@ -4405,8 +4506,10 @@ sub csvuploadmap { if (!$env{'form.datatoken'}) { $datatoken=&Apache::loncommon::upfile_store($request); } else { - $datatoken=$env{'form.datatoken'}; - &Apache::loncommon::load_tmp_file($request); + $datatoken=&Apache::loncommon::valid_datatoken($env{'form.datatoken'}); + if ($datatoken ne '') { + &Apache::loncommon::load_tmp_file($request,$datatoken); + } } my @records=&Apache::loncommon::upfile_record_sep(); &csvuploadmap_header($request,$symb,$datatoken,$#records+1); @@ -4495,7 +4598,10 @@ sub csvuploadassign { my ($request,$symb)= @_; if (!$symb) {return '';} my $error_msg = ''; - &Apache::loncommon::load_tmp_file($request); + my $datatoken = &Apache::loncommon::valid_datatoken($env{'form.datatoken'}); + if ($datatoken ne '') { + &Apache::loncommon::load_tmp_file($request,$datatoken); + } my @gradedata = &Apache::loncommon::upfile_record_sep(); my %fields=&get_fields(); my $courseid=$env{'request.course.id'}; @@ -4815,7 +4921,7 @@ sub getSymbMap { my @sequences = $navmap->retrieveResources(undef, sub { shift->is_map(); }, 1,0,1); for my $sequence ($navmap->getById('0.0'), @sequences) { - if ($navmap->hasResource($sequence, sub { shift->is_problem(); }, 0) ) { + if ($navmap->hasResource($sequence, sub { shift->is_gradable(); }, 0) ) { my $title = $minder.'.'. &HTML::Entities::encode($sequence->compTitle(),'"\'&'); push(@titles, $title); # minder in case two titles are identical @@ -4912,10 +5018,11 @@ sub displayPage { if($curRes == $iterator->BEGIN_MAP) { $depth++; } if($curRes == $iterator->END_MAP) { $depth--; } - if (ref($curRes) && $curRes->is_problem()) { + if (ref($curRes) && $curRes->is_gradable()) { my $parts = $curRes->parts(); my $title = $curRes->compTitle(); my $symbx = $curRes->symb(); + my $is_tool = ($symbx =~ /ext\.tool$/); $studentTable.= &Apache::loncommon::start_data_table_row(). '<td align="center" valign="top" >'.$prob. @@ -4926,26 +5033,34 @@ sub displayPage { '</td>'; $studentTable.='<td valign="top">'; my %form = ('CODE' => $env{'form.CODE'},); - if ($env{'form.vProb'} eq 'yes' ) { - $studentTable.=&show_problem($request,$symbx,$uname,$udom,1, - undef,'both',\%form); - } else { - my $companswer = &Apache::loncommon::get_student_answers($symbx,$uname,$udom,$env{'request.course.id'},%form); - $companswer =~ s|<form(.*?)>||g; - $companswer =~ s|</form>||g; -# while ($companswer =~ /(<a href\=\"javascript:newWindow.*?Script Vars<\/a>)/s) { #<a href="javascript:newWindow</a> -# $companswer =~ s/$1/ /ms; -# $request->print('match='.$1."<br />\n"); -# } -# $companswer =~ s|<table border=\"1\">|<table border=\"0\">|g; - $studentTable.=' <b>'.$title.'</b> <br /> <b>'.&mt('Correct answer').':</b><br />'.$companswer; + if ($is_tool) { + $studentTable.=' <b>'.$title.'</b><br />'; + } else { + if ($env{'form.vProb'} eq 'yes' ) { + $studentTable.=&show_problem($request,$symbx,$uname,$udom,1, + undef,'both',\%form); + } else { + my $companswer = &Apache::loncommon::get_student_answers($symbx,$uname,$udom,$env{'request.course.id'},%form); + $companswer =~ s|<form(.*?)>||g; + $companswer =~ s|</form>||g; +# while ($companswer =~ /(<a href\=\"javascript:newWindow.*?Script Vars<\/a>)/s) { #<a href="javascript:newWindow</a> +# $companswer =~ s/$1/ /ms; +# $request->print('match='.$1."<br />\n"); +# } +# $companswer =~ s|<table border=\"1\">|<table border=\"0\">|g; + $studentTable.=' <b>'.$title.'</b> <br /> <b>'.&mt('Correct answer').':</b><br />'.$companswer; + } } my %record = &Apache::lonnet::restore($symbx,$env{'request.course.id'},$udom,$uname); if ($env{'form.lastSub'} eq 'datesub') { if ($record{'version'} eq '') { - $studentTable.='<br /> <span class="LC_warning">'.&mt('No recorded submission for this problem.').'</span><br />'; + my $msg = &mt('No recorded submission for this problem.'); + if ($is_tool) { + $msg = &mt('No recorded transactions for this external tool'); + } + $studentTable.='<br /> <span class="LC_warning">'.$msg.'</span><br />'; } else { my %responseType = (); foreach my $partid (@{$parts}) { @@ -4958,7 +5073,6 @@ sub displayPage { $responseType{$partid} = \%responseIds; } $studentTable.= &displaySubByDates($symbx,\%record,$parts,\%responseType,$checkIcon,$uname,$udom); - } } elsif ($env{'form.lastSub'} eq 'all') { my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : ''); @@ -4999,13 +5113,14 @@ sub displaySubByDates { my ($symb,$record,$parts,$responseType,$checkIcon,$uname,$udom) = @_; my $isCODE=0; my $isTask = ($symb =~/\.task$/); + my $is_tool = ($symb =~/\.tool$/); if (exists($record->{'resource.CODE'})) { $isCODE=1; } my $studentTable=&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). '<th>'.&mt('Date/Time').'</th>'. ($isCODE?'<th>'.&mt('CODE').'</th>':''). ($isTask?'<th>'.&mt('Version').'</th>':''). - '<th>'.&mt('Submission').'</th>'. + '<th>'.($is_tool?&mt('Grade'):&mt('Submission')).'</th>'. '<th>'.&mt('Status').'</th>'. &Apache::loncommon::end_data_table_header_row(); my ($version); @@ -5013,7 +5128,11 @@ sub displaySubByDates { my %orders; $mark{'correct_by_student'} = $checkIcon; if (!exists($$record{'1:timestamp'})) { - return '<br /> <span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br />'; + if ($is_tool) { + return '<br /> <span class="LC_warning">'.&mt('No grade passed back.').'</span><br />'; + } else { + return '<br /> <span class="LC_warning">'.&mt('Nothing submitted - no attempts.').'</span><br />'; + } } my $interaction; @@ -5046,56 +5165,64 @@ sub displaySubByDates { if (($type eq 'anonsurvey') || ($type eq 'anonsurveycred')) { $hidden = 1; } - my @matchKey = ($isTask ? sort(grep /^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys) - : sort(grep /^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys)); - + my @matchKey; + if ($isTask) { + @matchKey = sort(grep /^resource\.\d+\.\Q$partid\E\.award$/,@versionKeys); + } elsif ($is_tool) { + @matchKey = sort(grep /^resource\.\Q$partid\E\.awarded$/,@versionKeys); + } else { + @matchKey = sort(grep /^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys); + } # next if ($$record{"$version:resource.$partid.solved"} eq ''); my $display_part=&get_display_part($partid,$symb); foreach my $matchKey (@matchKey) { if (exists($$record{$version.':'.$matchKey}) && $$record{$version.':'.$matchKey} ne '') { - - my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/) - : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/)); - $displaySub[0].='<span class="LC_nobreak">'; - $displaySub[0].='<b>'.&mt('Part: [_1]',$display_part).'</b>' - .' <span class="LC_internal_info">' - .'('.&mt('Response ID: [_1]',$responseId).')' - .'</span>' - .' <b>'; - if ($hidden) { - $displaySub[0].= &mt('Anonymous Survey').'</b>'; + if ($is_tool) { + $displaySub[0].=$$record{"$version:resource.$partid.awarded"}; } else { - my ($trial,$rndseed,$newvariation); - if ($type eq 'randomizetry') { - $trial = $$record{"$where.$partid.tries"}; - $rndseed = $$record{"$where.$partid.rndseed"}; - } - if ($$record{"$where.$partid.tries"} eq '') { - $displaySub[0].=&mt('Trial not counted'); - } else { - $displaySub[0].=&mt('Trial: [_1]', - $$record{"$where.$partid.tries"}); - if (($rndseed ne '') && ($lastrndseed{$partid} ne '')) { - if (($rndseed ne $lastrndseed{$partid}) && - (($type eq 'randomizetry') || ($lasttype{$partid} eq 'randomizetry'))) { - $newvariation = ' ('.&mt('New variation this try').')'; - } + my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/) + : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/)); + $displaySub[0].='<span class="LC_nobreak">'; + $displaySub[0].='<b>'.&mt('Part: [_1]',$display_part).'</b>' + .' <span class="LC_internal_info">' + .'('.&mt('Response ID: [_1]',$responseId).')' + .'</span>' + .' <b>'; + if ($hidden) { + $displaySub[0].= &mt('Anonymous Survey').'</b>'; + } else { + my ($trial,$rndseed,$newvariation); + if ($type eq 'randomizetry') { + $trial = $$record{"$where.$partid.tries"}; + $rndseed = $$record{"$where.$partid.rndseed"}; } - $lastrndseed{$partid} = $rndseed; - $lasttype{$partid} = $type; - } - my $responseType=($isTask ? 'Task' + if ($$record{"$where.$partid.tries"} eq '') { + $displaySub[0].=&mt('Trial not counted'); + } else { + $displaySub[0].=&mt('Trial: [_1]', + $$record{"$where.$partid.tries"}); + if (($rndseed ne '') && ($lastrndseed{$partid} ne '')) { + if (($rndseed ne $lastrndseed{$partid}) && + (($type eq 'randomizetry') || ($lasttype{$partid} eq 'randomizetry'))) { + $newvariation = ' ('.&mt('New variation this try').')'; + } + } + $lastrndseed{$partid} = $rndseed; + $lasttype{$partid} = $type; + } + my $responseType=($isTask ? 'Task' : $responseType->{$partid}->{$responseId}); - if (!exists($orders{$partid})) { $orders{$partid}={}; } - if ((!exists($orders{$partid}->{$responseId})) || ($trial)) { - $orders{$partid}->{$responseId}= - &get_order($partid,$responseId,$symb,$uname,$udom, - $no_increment,$type,$trial,$rndseed); - } - $displaySub[0].='</b>'.$newvariation.'</span>'; # /nobreak - $displaySub[0].=' '. - &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom,$type,$trial,$rndseed).'<br />'; + if (!exists($orders{$partid})) { $orders{$partid}={}; } + if ((!exists($orders{$partid}->{$responseId})) || ($trial)) { + $orders{$partid}->{$responseId}= + &get_order($partid,$responseId,$symb,$uname,$udom, + $no_increment,$type,$trial,$rndseed); + } + $displaySub[0].='</b>'.$newvariation.'</span>'; # /nobreak + $displaySub[0].=' '. + &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom,$type,$trial,$rndseed).'<br />'; + } } } } @@ -5110,14 +5237,22 @@ sub displaySubByDates { lc($$record{"$where.$partid.award"}).' '. $mark{$$record{"$where.$partid.solved"}}. '<br />'; + } elsif (($is_tool) && (exists($$record{"$version:resource.$partid.solved"}))) { + if ($$record{"$version:resource.$partid.solved"} =~ /^(in|)correct_by_passback$/) { + $displaySub[1].=&mt('Grade passed back by external tool'); + } } if (exists $$record{"$where.$partid.regrader"}) { - $displaySub[2].=$$record{"$where.$partid.regrader"}. - ' (<b>'.&mt('Part').':</b> '.$display_part.')'; + $displaySub[2].=$$record{"$where.$partid.regrader"}; + unless ($is_tool) { + $displaySub[2].=' (<b>'.&mt('Part').':</b> '.$display_part.')'; + } } elsif ($$record{"$version:resource.$partid.regrader"} =~ /\S/) { $displaySub[2].= - $$record{"$version:resource.$partid.regrader"}. - ' (<b>'.&mt('Part').':</b> '.$display_part.')'; + $$record{"$version:resource.$partid.regrader"}; + unless ($is_tool) { + $displaySub[2].=' (<b>'.&mt('Part').':</b> '.$display_part.')'; + } } } # needed because old essay regrader has not parts info @@ -9649,12 +9784,13 @@ sub submit_options_table { my ($request,$symb) = @_; if (!$symb) {return '';} &commonJSfunctions($request); + my $is_tool = ($symb =~ /ext\.tool$/); my $result; $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n"; - $result.=&selectfield(1). + $result.=&selectfield(1,$is_tool). '<input type="hidden" name="command" value="viewgrades" /> <div> <input type="submit" value="'.&mt('Next').' →" /> @@ -9668,6 +9804,7 @@ sub submit_options_download { my ($request,$symb) = @_; if (!$symb) {return '';} + my $is_tool = ($symb =~ /ext\.tool$/); &commonJSfunctions($request); my $result='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". @@ -9675,7 +9812,7 @@ sub submit_options_download { $result.=' <h2> '.&mt('Select Students for Which to Download Submissions').' -</h2>'.&selectfield(1).' +</h2>'.&selectfield(1,$is_tool).' <input type="hidden" name="command" value="downloadfileslink" /> <input type="submit" value="'.&mt('Next').' →" /> </div> @@ -9691,12 +9828,13 @@ sub submit_options { my ($request,$symb) = @_; if (!$symb) {return '';} + my $is_tool = ($symb =~ /ext\.tool$/); &commonJSfunctions($request); my $result; $result.='<form action="/adm/grades" method="post" name="gradingMenu">'."\n". '<input type="hidden" name="symb" value="'.&Apache::lonenc::check_encrypt($symb).'" />'."\n"; - $result.=&selectfield(1).' + $result.=&selectfield(1,$is_tool).' <input type="hidden" name="command" value="submission" /> <input type="submit" value="'.&mt('Next').' →" /> </div> @@ -9708,10 +9846,17 @@ sub submit_options { } sub selectfield { - my ($full)=@_; - my %options = - (&substatus_options, - 'select_form_order' => ['yes','queued','graded','incorrect','all']); + my ($full,$is_tool)=@_; + my %options; + if ($is_tool) { + %options = + (&transtatus_options, + 'select_form_order' => ['yes','incorrect','all']); + } else { + %options = + (&substatus_options, + 'select_form_order' => ['yes','queued','graded','incorrect','all']); + } my $result='<div class="LC_columnSection"> <fieldset> @@ -9735,10 +9880,14 @@ sub selectfield { '.&Apache::lonhtmlcommon::StatusOptions(undef,undef,5,undef,'mult').' </fieldset>'; if ($full) { - $result.=' + my $heading = &mt('Submission Status'); + if ($is_tool) { + $heading = &mt('Transaction Status'); + } + $result.=' <fieldset> <legend> - '.&mt('Submission Status').' + '.$heading.' </legend>'. &Apache::loncommon::select_form('all','submitonly',\%options). '</fieldset>'; @@ -9757,6 +9906,14 @@ sub substatus_options { ); } +sub transtatus_options { + return &Apache::lonlocal::texthash( + 'yes' => 'with score transactions', + 'incorrect' => 'with less than full credit', + 'all' => 'with any status', + ); +} + sub reset_perm { undef(%perm); } @@ -10387,7 +10544,7 @@ sub startpage { sub select_problem { my ($r)=@_; $r->print('<h3>'.&mt('Select the problem or one of the problems you want to grade').'</h3><form action="/adm/grades">'); - $r->print(&Apache::lonstathelpers::problem_selector('.',undef,1)); + $r->print(&Apache::lonstathelpers::problem_selector('.',undef,1,undef,undef,undef,undef,1)); $r->print('<input type="hidden" name="command" value="gradingmenu" />'); $r->print('<input type="submit" value="'.&mt('Next').' →" /></form>'); }