--- loncom/homework/grades.pm	2005/02/01 21:06:48	1.241
+++ loncom/homework/grades.pm	2005/02/12 03:14:44	1.244
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.241 2005/02/01 21:06:48 albertel Exp $
+# $Id: grades.pm,v 1.244 2005/02/12 03:14:44 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2655,15 +2655,17 @@ sub csvupload_javascript_reverse_associa
   function verify(vf) {
     var foundsomething=0;
     var founduname=0;
+    var foundID=0;
     var founddomain=0;
     for (i=0;i<=vf.nfields.value;i++) {
       tw=eval('vf.f'+i+'.selectedIndex');
-      if (i==0 && tw!=0) { founduname=1; }
-      if (i==1 && tw!=0) { founddomain=1; }
-      if (i!=0 && i!=1 && tw!=0) { foundsomething=1; }
+      if (i==0 && tw!=0) { foundID=1; }
+      if (i==1 && tw!=0) { founduname=1; }
+      if (i==2 && tw!=0) { founddomain=1; }
+      if (i!=0 && i!=1 && i!=2 && tw!=0) { foundsomething=1; }
     }
-    if (founduname==0 || founddomain==0) {
-      alert('You need to specify at both the username and domain');
+    if ((founduname==0 && foundID==0) || founddomain==0) {
+      alert('You need to specify the domain and either the username or ID');
       return;
     }
     if (foundsomething==0) {
@@ -2693,15 +2695,17 @@ sub csvupload_javascript_forward_associa
   function verify(vf) {
     var foundsomething=0;
     var founduname=0;
+    var foundID=0;
     var founddomain=0;
     for (i=0;i<=vf.nfields.value;i++) {
       tw=eval('vf.f'+i+'.selectedIndex');
-      if (tw==1) { founduname=1; }
-      if (tw==2) { founddomain=1; }
-      if (tw>2) { foundsomething=1; }
+      if (tw==1) { foundID=1; }
+      if (tw==2) { founduname=1; }
+      if (tw==3) { founddomain=1; }
+      if (tw>3) { foundsomething=1; }
     }
-    if (founduname==0 || founddomain==0) {
-      alert('You need to specify at both the username and domain');
+    if ((founduname==0 && foundID==0) || founddomain==0) {
+      alert('You need to specify the domain and either the username or ID');
       return;
     }
     if (foundsomething==0) {
@@ -2768,13 +2772,18 @@ ENDPICK
 sub csvupload_fields {
     my ($url,$symb) = @_;
     my (@parts) = &getpartlist($url,$symb);
-    my @fields=(['username','Student Username'],['domain','Student Domain']);
+    my @fields=(['ID','Student ID'],
+		['username','Student Username'],
+		['domain','Student Domain']);
     foreach my $part (sort(@parts)) {
 	my @datum;
 	my $display=&Apache::lonnet::metadata($url,$part.'.display');
 	my $name=$part;
 	if  (!$display) { $display = $name; }
 	@datum=($name,$display);
+	if ($name=~/^stores_(.*)_awarded/) {
+	    push(@fields,['stores_'.$1.'_points',"Points [Part: $1]"]);
+	}
 	push(@fields,\@datum);
     }
     return (@fields);
@@ -2899,10 +2908,15 @@ sub csvuploadassign {
     my $countdone=0;
     foreach my $grade (@gradedata) {
 	my %entries=&Apache::loncommon::record_sep($grade);
-	my $username=$entries{$fields{'username'}};
-	$username=~s/\s//g;
 	my $domain=$entries{$fields{'domain'}};
 	$domain=~s/\s//g;
+	my $username=$entries{$fields{'username'}};
+	$username=~s/\s//g;
+	if (!$username) {
+	    my $id=$entries{$fields{'ID'}};
+	    my %ids=&Apache::lonnet::idget($domain,$id);
+	    $username=$ids{$id};
+	}
 	if (!exists($$classlist{"$username:$domain"})) {
 	    push(@skipped,"$username:$domain");
 	    next;
@@ -2912,16 +2926,33 @@ sub csvuploadassign {
 	    push(@notallowed,"$username:$domain");
 	    next;
 	}
+	my %points;
 	my %grades;
 	foreach my $dest (keys(%fields)) {
-	    if ($dest eq 'username' || $dest eq 'domain') { next; }
-	    if ($entries{$fields{$dest}} eq '') { next; }
-	    my $store_key=$dest;
-	    $store_key=~s/^stores/resource/;
-	    $store_key=~s/_/\./g;
-	    $grades{$store_key}=$entries{$fields{$dest}};
+	    if ($dest eq 'ID' || $dest eq 'username' ||
+		$dest eq 'domain') { next; }
+	    if ($entries{$fields{$dest}} =~ /^\s*$/) { next; }
+	    if ($dest=~/stores_(.*)_points/) {
+		my $part=$1;
+		my $wgt =&Apache::lonnet::EXT('resource.'.$part.'.weight',
+					      $symb,$domain,$username);
+		my $pcr=$entries{$fields{$dest}} / $wgt;
+		my $award='correct_by_override';
+		$grades{"resource.$part.awarded"}=$pcr;
+		$grades{"resource.$part.solved"}=$award;
+		$points{$part}=1;
+	    } else {
+		if ($dest=~/stores_(.*)_awarded/) { if ($points{$1}) {next;} }
+		if ($dest=~/stores_(.*)_solved/)  { if ($points{$1}) {next;} }
+		my $store_key=$dest;
+		$store_key=~s/^stores/resource/;
+		$store_key=~s/_/\./g;
+		$grades{$store_key}=$entries{$fields{$dest}};
+	    }
 	}
+	if (! %grades) { push(@skipped,"$username:$domain no data to store"); }
 	$grades{"resource.regrader"}="$ENV{'user.name'}:$ENV{'user.domain'}";
+#	&Apache::lonnet::logthis(" storing ".(join('-',%grades)));
 	&Apache::lonnet::cstore(\%grades,$symb,$ENV{'request.course.id'},
 				$domain,$username);
 	$request->print('.');
@@ -4326,6 +4357,12 @@ sub scantron_get_correction {
 	$r->print(" in scanline $i <pre>".
 		  $line."</pre> \n");
     }
+    my $message="<p>The ID on the form is  <tt>".
+	$$scan_record{'scantron.ID'}."</tt><br />\n".
+	"The name on the paper is ".
+	$$scan_record{'scantron.LastName'}.",".
+	$$scan_record{'scantron.FirstName'}."</p>";
+
     $r->print('<input type="hidden" name="scantron_corrections" value="'.$error.'" />'."\n");
     $r->print('<input type="hidden" name="scantron_line" value="'.$i.'" />'."\n");
     if ($error =~ /ID$/) {
@@ -4334,11 +4371,7 @@ sub scantron_get_correction {
 	} elsif ($error eq 'duplicateID') {
 	    $r->print("The encoded ID has also been used by a previous paper $arg</p>\n");
 	}
-	$r->print("<p>The ID on the form is  <tt>".
-		  $$scan_record{'scantron.ID'}."</tt><br />\n");
-	$r->print("The name on the paper is ".
-		  $$scan_record{'scantron.LastName'}.",".
-		  $$scan_record{'scantron.FirstName'}."</p>");
+	$r->print($message);
 	$r->print("<p>How should I handle this? <br /> \n");
 	$r->print("\n<ul><li> ");
 	#FIXME it would be nice if this sent back the user ID and
@@ -4358,11 +4391,7 @@ sub scantron_get_correction {
 	}
 	$r->print("<p>The CODE on the form is  <tt>'".
 		  $$scan_record{'scantron.CODE'}."'</tt><br />\n");
-	$r->print("<p>The ID on the form is  <tt>".
-		  $$scan_record{'scantron.ID'}."</tt><br />\n");
-	$r->print("The name on the paper is ".
-		  $$scan_record{'scantron.LastName'}.",".
-		  $$scan_record{'scantron.FirstName'}."</p>");
+	$r->print($message);
 	$r->print("<p>How should I handle this? <br /> \n");
 	$r->print("\n<br /> ");
 	my $i=0;
@@ -4405,6 +4434,7 @@ ENDSCRIPT
 	$r->print("<p>There have been multiple bubbles scanned for a some question(s)</p>\n");
 	$r->print('<input type="hidden" name="scantron_questions" value="'.
 		  join(',',@{$arg}).'" />');
+	$r->print($message);
 	$r->print("<p>Please indicate which bubble should be used for grading</p>");
 	foreach my $question (@{$arg}) {
 	    my $selected=$$scan_record{"scantron.$question.answer"};
@@ -4412,6 +4442,7 @@ ENDSCRIPT
 	}
     } elsif ($error eq 'missingbubble') {
 	$r->print("<p>There have been <b>no</b> bubbles scanned for some question(s)</p>\n");
+	$r->print($message);
 	$r->print("<p>Please indicate which bubble should be used for grading</p>");
 	$r->print("Some questions have no scanned bubbles\n");
 	$r->print('<input type="hidden" name="scantron_questions" value="'.