--- loncom/homework/grades.pm	2003/12/04 23:23:16	1.166
+++ loncom/homework/grades.pm	2004/03/12 18:03:38	1.180
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.166 2003/12/04 23:23:16 albertel Exp $
+# $Id: grades.pm,v 1.180 2004/03/12 18:03:38 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -48,6 +48,7 @@ use Apache::lonhomework;
 use Apache::loncoursedata;
 use Apache::lonmsg qw(:user_normal_msg);
 use Apache::Constants qw(:common);
+use Apache::lonlocal;
 use String::Similarity;
 
 my %oldessays=();
@@ -88,10 +89,15 @@ sub getpartlist {
 
 # --- Get the symbolic name of a problem and the url
 sub get_symb_and_url {
-    my ($request) = @_;
+    my ($request,$silent) = @_;
     (my $url=$ENV{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
     my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
-    if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
+    if ($symb eq '') { 
+	if (!$silent) {
+	    $request->print("Unable to handle ambiguous references:$url:.");
+	    return ();
+	}
+    }
     return ($symb,$url);
 }
 
@@ -168,7 +174,7 @@ sub showResourceInfo {
     my $col=3;
     if ($checkboxes) { $col=4; }
     my $result ='<table border="0">'.
-	'<tr><td colspan="'.$col.'"><font size="+1"><b>Current Resource: </b>'.
+	'<tr><td colspan="'.$col.'"><font size="+1"><b>'.&mt('Current Resource').': </b>'.
 	$probTitle.'</font></td></tr>'."\n";
     my ($partlist,$handgrade,$responseType) = &response_type($url);
     my %resptype = ();
@@ -520,18 +526,27 @@ sub verifyreceipt {
 
     my ($string,$contents,$matches) = ('','',0);
     my (undef,undef,$fullname) = &getclasslist('all','0');
-
+    
+    my $receiptparts=0;
+    if ($ENV{"course.$courseid.receiptalg"} eq 'receipt2') { $receiptparts=1; }
+    my $parts=['0'];
+    if ($receiptparts) { ($parts)=&response_type($url,$symb); }
     foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
 	my ($uname,$udom)=split(/\:/);
-	if ($receipt eq 
-	    &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb)) {
-	    $contents.='<tr bgcolor="#ffffe6"><td>&nbsp;'."\n".
-		'<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
-		'\')"; TARGET=_self>'.$$fullname{$_}.'</a>&nbsp;</td>'."\n".
-		'<td>&nbsp;'.$uname.'&nbsp;</td>'.
-		'<td>&nbsp;'.$udom.'&nbsp;</td></tr>'."\n";
-	    
-	    $matches++;
+	foreach my $part (@$parts) {
+	    if ($receipt eq &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb,$part)) {
+		$contents.='<tr bgcolor="#ffffe6"><td>&nbsp;'."\n".
+		    '<a href="javascript:viewOneStudent(\''.$uname.'\',\''.$udom.
+		    '\')"; TARGET=_self>'.$$fullname{$_}.'</a>&nbsp;</td>'."\n".
+		    '<td>&nbsp;'.$uname.'&nbsp;</td>'.
+		    '<td>&nbsp;'.$udom.'&nbsp;</td>';
+		if ($receiptparts) {
+		    $contents.='<td>&nbsp;'.$part.'&nbsp;</td>';
+		}
+		$contents.='</tr>'."\n";
+		
+		$matches++;
+	    }
 	}
     }
     if ($matches == 0) {
@@ -544,8 +559,11 @@ sub verifyreceipt {
 	    '<table border="0"><tr bgcolor="#e6ffff">'."\n".
 	    '<td><b>&nbsp;Fullname&nbsp;</b></td>'."\n".
 	    '<td><b>&nbsp;Username&nbsp;</b></td>'."\n".
-	    '<td><b>&nbsp;Domain&nbsp;</b></td></tr>'."\n".
-	    $contents.
+	    '<td><b>&nbsp;Domain&nbsp;</b></td>';
+	if ($receiptparts) {
+	    $string.='<td>&nbsp;Problem Part&nbsp;</td>';
+	}
+	$string.='</tr>'."\n".$contents.
 	    '</table></td></tr></table>'."\n";
     }
     return $string.&show_grading_menu_form($symb,$url);
@@ -737,9 +755,12 @@ LISTJAVASCRIPT
 	if ($num_students eq 0) {
 	    $gradeTable='<br />&nbsp;<font color="red">There are no students currently enrolled.</font>';
 	} else {
+	    my $submissions='submissions';
+	    if ($submitonly eq 'incorrect') { $submissions = 'incorrect submissions'; }
+	    if ($submitonly eq 'graded'   ) { $submissions = 'ungraded submissions'; }
 	    $gradeTable='<br />&nbsp;<font color="red">'.
-		'No submissions found for this resource for any students. ('.$num_students.
-		' checked for submissions)</font><br />';
+		'No '.$submissions.' found for this resource for any students. ('.$num_students.
+		' students checked for '.$submissions.')</font><br />';
 	}
     } elsif ($ctr == 1) {
 	$gradeTable =~ s/type=checkbox/type=checkbox checked/;
@@ -1274,10 +1295,10 @@ sub gradeBox {
     my $ctr = 0;
     $result.='<table border="0"><tr>'."\n";  # display radio buttons in a nice table 10 across
     while ($ctr<=$wgt) {
-	$result.= '<td><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
+	$result.= '<td><nobr><input type="radio" name="RADVAL'.$counter.'_'.$partid.'" '.
 	    'onclick="javascript:writeBox(this.form,\''.$counter.'_'.$partid.'\','.
 	    $ctr.')" value="'.$ctr.'" '.
-	    ($score eq $ctr ? 'checked':'').' /> '.$ctr."</td>\n";
+	    ($score eq $ctr ? 'checked':'').' /> '.$ctr."</nobr></td>\n";
 	$result.=(($ctr+1)%10 == 0 ? '</tr><tr>' : '');
 	$ctr++;
     }
@@ -1678,12 +1699,15 @@ KEYWORDS
 	my $toGrade.='<input type="button" value="Grade Student" '.
 	    'onClick="javascript:checksubmit(this.form,\'Grade Student\',\''
 	    .$counter.'\');" TARGET=_self> &nbsp;'."\n" if (&canmodify($usec));
-	$toGrade.='</td></tr></table></td></tr></table></form>'."\n";
-	$toGrade.=&show_grading_menu_form($symb,$url) 
-	    if (($ENV{'form.command'} eq 'submission') || 
-		($ENV{'form.command'} eq 'processGroup' && $counter == $total));
-	$request = print($toGrade);
+	$toGrade.='</td></tr></table></td></tr></table>'."\n";
+	if (($ENV{'form.command'} eq 'submission') || 
+	    ($ENV{'form.command'} eq 'processGroup' && $counter == $total)) {
+	    $toGrade.='</form>'.&show_grading_menu_form($symb,$url) 
+	}
+	$request->print($toGrade);
 	return;
+    } else {
+	$request->print('</td></tr></table></td></tr></table>'."\n");
     }
 
     # essay grading message center
@@ -2247,8 +2271,14 @@ sub viewgrades {
     &viewgrades_js($request);
 
     my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'}); 
-    my $result='<h3><font color="#339933">Manual Grading</font></h3>';
+    #need to make sure we have the correct data for later EXT calls, 
+    #thus invalidate the cache
+    &Apache::lonnet::devalidatecourseresdata(
+                 $ENV{'course.'.$ENV{'request.course.id'}.'.num'},
+                 $ENV{'course.'.$ENV{'request.course.id'}.'.domain'});
+    &Apache::lonnet::clear_EXT_cache_status();
 
+    my $result='<h3><font color="#339933">'.&mt('Manual Grading').'</font></h3>';
     $result.='<font size=+1><b>Current Resource: </b>'.$ENV{'form.probTitle'}.'</font>'."\n";
 
     #view individual student submission form - called using Javascript viewOneStudent
@@ -3031,6 +3061,14 @@ sub displayPage {
     my ($classlist,undef,$fullname) = &getclasslist($getsec,'1');
     my ($uname,$udom) = split(/:/,$ENV{'form.student'});
     my $usec=$classlist->{$ENV{'form.student'}}[5];
+
+    #need to make sure we have the correct data for later EXT calls, 
+    #thus invalidate the cache
+    &Apache::lonnet::devalidatecourseresdata(
+                 $ENV{'course.'.$ENV{'request.course.id'}.'.num'},
+                 $ENV{'course.'.$ENV{'request.course.id'}.'.domain'});
+    &Apache::lonnet::clear_EXT_cache_status();
+
     if (!&canview($usec)) {
 	$request->print('<font color="red">Unable to view requested student.('.$ENV{'form.student'}.')</font>');
 	$request->print(&show_grading_menu_form($symb,$url));
@@ -3202,7 +3240,7 @@ sub displaySubByDates {
 	    }
 	    if (exists $$record{"$version:resource.$partid.regrader"}) {
 		$displaySub[2].=$$record{"$version:resource.$partid.regrader"}.
-		    ' (<b>Part:</b> '.$partid.')';
+		    ' (<b>'.&mt('Part').':</b> '.$partid.')';
 	    }
 	}
 	# needed because old essay regrader has not parts info
@@ -3428,34 +3466,28 @@ sub scantron_selectphase {
         $default_form_data
         <table width="100%" border="0">
           <tr bgcolor="#e6ffff">
-            <td>
-              &nbsp;<b>Specify file location and which Folder/Sequence to grade</b>
+            <td colspan="2">
+              &nbsp;<b>Specify file and which Folder/Sequence to grade</b>
             </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
-               Sequence to grade: $sequence_selector
-	    </td>
+            <td> Sequence to grade: </td><td> $sequence_selector </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
-		Filename of scoring office file: $file_selector
-	    </td>
+            <td> Filename of scoring office file: </td><td> $file_selector </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
-              Format of data file: $format_selector
-	    </td>
+            <td> Format of data file: </td><td> $format_selector </td>
           </tr>
           <tr bgcolor="#ffffe6">
             <td>
 <!-- FIXME this is lazy, a single parse of the set should let me know what this is -->
-              Last line to expect an answer on: 
+              Last line to expect an answer on: </td><td>
                 <input type="text" name="scantron_maxbubble" />
 	    </td>
           </tr>
           <tr bgcolor="#ffffe6">
-            <td>
+            <td colspan="2">
               <input type="submit" value="Validate Scantron Records" />
             </td>
           </tr>
@@ -3476,13 +3508,36 @@ SCANTRONFORM
         <table width="100%" border="0">
           <tr bgcolor="#e6ffff">
             <td>
-              Specify a Scantron data file to upload.
+              &nbsp;<b>Specify a Scantron data file to upload.</b>
             </td>
           </tr>
           <tr bgcolor="#ffffe6">
             <td>
 SCANTRONFORM
-        &scantron_upload_scantron_data($r);
+    my $default_form_data=&defaultFormData(&get_symb_and_url($r,1));
+    my $cdom= $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+    my $cnum= $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
+    $r->print(<<UPLOAD);
+              <script type="text/javascript" language="javascript">
+    function checkUpload(formname) {
+	if (formname.upfile.value == "") {
+	    alert("Please use the browse button to select a file from your local directory.");
+	    return false;
+	}
+	formname.submit();
+    }
+              </script>
+
+              <form enctype='multipart/form-data' action='/adm/grades' name='rules' method='post'>
+                $default_form_data
+                <input name='courseid' type='hidden' value='$cnum' />
+                <input name='domainid' type='hidden' value='$cdom' />
+                <input name='command' value='scantronupload_save' type='hidden' />
+                File to upload:<input type="file" name="upfile" size="50" />
+                <br />
+                <input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Scantron Data" />
+              </form>
+UPLOAD
 
         $r->print(<<SCANTRONFORM);
             </td>
@@ -3802,7 +3857,7 @@ sub scantron_getfile {
     } else {
 	$scanlines{'skipped'}=[(split("\n",$lines,-1))];
     }
-    my @tmp=&Apache::lonnet::dump('scantrondata',$cdom,$cname);
+    my @tmp=&Apache::lonnet::dump('nohist_scantrondata',$cdom,$cname);
     if ($tmp[0] =~ /^(error:|no_such_host)/) { @tmp=(); }
     my %scan_data = @tmp;
     return (\%scanlines,\%scan_data);
@@ -3834,7 +3889,7 @@ sub scantron_putfile {
     &lonnet_putfile(join("\n",@{$scanlines->{'skipped'}}),
 		    $prefix.'skipped_'.
 		    $ENV{'form.scantron_selectfile'});
-    &Apache::lonnet::put('scantrondata',$scan_data,$cdom,$cname);
+    &Apache::lonnet::put('nohist_scantrondata',$scan_data,$cdom,$cname);
 }
 
 sub scantron_get_line {
@@ -3951,7 +4006,7 @@ sub scantron_get_correction {
 				       'scantron_username','scantron_domain'));
 	$r->print(": <input type='text' name='scantron_username' value='' />");
 	$r->print("\n@".
-		 &Apache::loncommon::select_dom_form(undef,'scantron_domain'));
+		 &Apache::loncommon::select_dom_form($ENV{'request.role..domain'},'scantron_domain'));
 
 	$r->print('</li>');
     } elsif ($error eq 'doublebubble') {
@@ -4136,11 +4191,11 @@ SCANTRONFORM
 						 'last student');
     }
     &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
-    my $lasttime = &Time::HiRes::time()-$start;
-    $r->print("<p>took $lasttime</p>");
+#    my $lasttime = &Time::HiRes::time()-$start;
+#    $r->print("<p>took $lasttime</p>");
 
     $navmap->untieHashes();
-    $r->print("<p>Done</p>");
+    $r->print("</form><p>Done</p>");
     $r->print(&show_grading_menu_form($symb,$url));
     return '';
 }
@@ -4152,7 +4207,7 @@ sub scantron_upload_scantron_data {
 							  'domainid');
     my $domsel=&Apache::loncommon::select_dom_form($ENV{'request.role.domain'},
 						   'domainid');
-    my $default_form_data=&defaultFormData(&get_symb_and_url($r));
+    my $default_form_data=&defaultFormData(&get_symb_and_url($r,1));
     $r->print(<<UPLOAD);
 <script type="text/javascript" language="javascript">
     function checkUpload(formname) {
@@ -4208,7 +4263,15 @@ sub scantron_upload_scantron_data_save {
     $r->print(&Apache::lonnet::finishuserfileupload($ENV{'form.courseid'},
 						    $ENV{'form.domainid'},
 						    $home,'upfile',$fname));
-    $r->print(&show_grading_menu_form(&get_symb_and_url($r)));
+    my ($symb,$url)=&get_symb_and_url($r);
+    if ($symb) {
+	$r->print(&show_grading_menu_form(&get_symb_and_url($r)));
+    } else {
+	$r->print('<br /><form action="/adm/grades" method="post">'."\n".
+		  '<input type="hidden" name="command" value="scantronupload" />'."\n".
+		  '<input type="submit" name="submit" value="Do Another Upload" />'."\n".
+		  '</form>'."\n");
+    }
     return '';
 }
 
@@ -4315,7 +4378,7 @@ GRADINGMENUJS
 
     $result.='<table width="100%" border=0>';
     $result.='<tr bgcolor="#ffffe6" valign="top"><td>'."\n".
-	'&nbsp;Select Section: <select name="section">'."\n";
+	'&nbsp;'.&mt('Select Section').': <select name="section">'."\n";
     if (ref($sections)) {
 	foreach (sort (@$sections)) {
 	    $result.='<option value="'.$_.'" '.
@@ -4324,7 +4387,7 @@ GRADINGMENUJS
     }
     $result.= '<option value="all" '.($saveSec eq 'all' ? 'selected="on"' : ''). '>all</select> &nbsp; ';
 
-    $result.='Student Status:</b>'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef);
+    $result.=&mt('Student Status').':</b>'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef);
 
     if (ref($sections) && (grep /no/,@$sections)) {
 	$result.='&nbsp;(Section "no" implies the students were not assigned a section.)<br />';
@@ -4333,8 +4396,8 @@ GRADINGMENUJS
 
     $result.='<tr bgcolor="#ffffe6"valign="top"><td>'.
 	'<input type="radio" name="radioChoice" value="submission" '.
-	($saveCmd eq 'submission' ? 'checked' : '').'> '.'<b>Current Resource:</b> For one or more students '.
-	'<select name="submitonly">'.
+	($saveCmd eq 'submission' ? 'checked' : '').'> '.'<b>'.&mt('Current Resource').':</b> '.&mt('For one or more students').
+	' <select name="submitonly">'.
 	'<option value="yes" '.
 	($saveSub eq 'yes' ? 'selected="on"' : '').'>with submissions</option>'.
 	'<option value="graded" '.