--- loncom/interface/slotrequest.pm	2006/03/30 04:35:58	1.55
+++ loncom/interface/slotrequest.pm	2006/06/16 19:49:00	1.64
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler for requesting to have slots added to a students record
 #
-# $Id: slotrequest.pm,v 1.55 2006/03/30 04:35:58 albertel Exp $
+# $Id: slotrequest.pm,v 1.64 2006/06/16 19:49:00 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -36,12 +36,15 @@ use Apache::lonlocal;
 use Apache::lonnet;
 use Apache::lonnavmaps();
 use Date::Manip;
+use lib '/home/httpd/lib/perl/';
+use LONCAPA;
 
 sub fail {
     my ($r,$code)=@_;
     if ($code eq 'not_valid') {
 	$r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>');
-
+    } elsif ($code eq 'not_available') {
+	$r->print('<p>'.&mt('No slots are available.').'</p>');
     } elsif ($code eq 'not_allowed') {
 	$r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>');
     } else {
@@ -243,10 +246,22 @@ sub make_reservation {
     my $value=&Apache::lonnet::EXT("resource.0.availablestudent",$symb,
 				   $env{'user.domain'},$env{'user.name'});
     &Apache::lonxml::debug("value is  $value<br />");
-    if (&network_error($value)) { 
+
+    my $use_slots = &Apache::lonnet::EXT("resource.0.useslots");
+    &Apache::lonxml::debug("use_slots is  $use_slots<br />");
+
+    if (&network_error($value) || &network_error($use_slots)) { 
 	return 'error: Unable to determine current status';
     }
 
+    my $parm_symb  = $symb;
+    my $parm_level = 1;
+    if ($use_slots eq 'map') {
+	my ($map) = &Apache::lonnet::decode_symb($symb);
+	$parm_symb = &Apache::lonnet::symbread($map);
+	$parm_level = 2;
+    }
+
     foreach my $other_slot (split(/:/, $value)) {
 	if ($other_slot eq $slot_name) {
 	    my %consumed=&Apache::lonnet::dump('slot_reservations', $cdom,
@@ -254,7 +269,7 @@ sub make_reservation {
 	    if (&network_error($value)) { 
 		return 'error: Unable to determine current status';
 	    }
-	    my $me=$env{'user.name'}.'@'.$env{'user.domain'};
+	    my $me=$env{'user.name'}.':'.$env{'user.domain'};
 	    foreach my $key (keys(%consumed)) {
 		if ($consumed{$key}->{'name'} eq $me) {
 		    my $num=(split('\0',$key))[1];
@@ -284,9 +299,9 @@ sub make_reservation {
 	return undef;
     }
     
-    my %reservation=('name'      => $env{'user.name'}.'@'.$env{'user.domain'},
+    my %reservation=('name'      => $env{'user.name'}.':'.$env{'user.domain'},
 		     'timestamp' => time,
-		     'symb'      => $symb);
+		     'symb'      => $parm_symb);
 
     my $success=&Apache::lonnet::newput('slot_reservations',
 					{"$slot_name\0$wanted" =>
@@ -300,7 +315,8 @@ sub make_reservation {
 	}
 	my $result=&Apache::lonparmset::storeparm_by_symb($symb,
 						      '0_availablestudent',
-						       1, $new_value, 'string',
+						       $parm_level, $new_value,
+						       'string',
 						       $env{'user.name'},
 					               $env{'user.domain'});
 	&Apache::lonxml::debug("hrrm $result");
@@ -369,13 +385,13 @@ sub remove_registration_confirmation {
 					 'no'  => 'No',);
     $r->print(<<"END_CONFIRM");
 <p> $msg </p>
-<form action="/adm/slotrequest" method="POST">
+<form action="/adm/slotrequest" method="post">
     <input type="hidden" name="command" value="release" />
     <input type="hidden" name="button" value="yes" />
     $hidden_input
     <input type="submit" value="$lt{'yes'}" />
 </form>
-<form action="/adm/slotrequest" method="POST">
+<form action="/adm/slotrequest" method="post">
     <input type="hidden" name="command" value="showslots" />
     <input type="submit" value="$lt{'no'}" />
 </form>
@@ -397,7 +413,7 @@ sub release_all_slot {
 
     foreach my $entry (sort { $consumed{$a}{'name'} cmp 
 				  $consumed{$b}{'name'} } (keys(%consumed))) {
-	my ($uname,$udom) = split('@',$consumed{$entry}{'name'});
+	my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
 	my ($result,$msg) =
 	    &release_reservation($slot_name,$uname,$udom,
 				 $consumed{$entry}{'symb'},$mgr);
@@ -465,17 +481,28 @@ sub release_reservation {
     my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum,
 				       "^$slot_name\0");
     foreach my $entry (keys(%consumed)) {
-	if ( $consumed{$entry}->{'name'} eq ($uname.'@'.$udom) ) {
+	if ( $consumed{$entry}->{'name'} eq ($uname.':'.$udom) ) {
 	    &Apache::lonnet::del('slot_reservations',[$entry],
 				 $cdom,$cnum);
 	}
     }
 
+    my $use_slots = &Apache::lonnet::EXT("resource.0.useslots");
+    &Apache::lonxml::debug("use_slots is  $use_slots<br />");
+
+    if (&network_error($use_slots)) { 
+	return (0,'error: Unable to determine current status');
+    }
+
+    my $parm_level = 1;
+    if ($use_slots eq 'map') {
+	$parm_level = 2;
+    }
     # store new parameter string
     my $result=&Apache::lonparmset::storeparm_by_symb($symb,
 						      '0_availablestudent',
-						      1, $new_param, 'string',
-						      $uname,$udom);
+						      $parm_level, $new_param,
+						      'string', $uname, $udom);
 
     my $msg;
     if ($mgr eq 'F') {
@@ -544,7 +571,7 @@ sub get_slot {
 	$r->print("<p>Already have a reservation: $description1</p>");
 	if ($slot_name ne $env{'form.slotname'}) {
 	    $r->print(<<STUFF);
-<form method="POST" action="/adm/slotrequest">
+<form method="post" action="/adm/slotrequest">
    <input type="hidden" name="symb" value="$env{'form.symb'}" />
    <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
    <input type="hidden" name="releaseslot" value="$slot_name" />
@@ -589,7 +616,7 @@ STUFF
     $r->print(<<STUFF);
 <p> <font color="red">Failed</font> to reserve a spot for $description. </p>
 <p>
-<form method="POST" action="/adm/slotrequest">
+<form method="post" action="/adm/slotrequest">
    <input type="submit" name="Try Again" value="$lt{'try'}" />
    <input type="hidden" name="symb" value="$env{'form.symb'}" />
    <input type="hidden" name="slotname" value="$env{'form.slotname'}" />
@@ -599,7 +626,7 @@ STUFF
 </p>
 <p>
 or
-<form method="POST" action="/adm/slotrequest">
+<form method="post" action="/adm/slotrequest">
     <input type="hidden" name="symb" value="$env{'form.symb'}" />
     <input type="submit" name="requestattempt" value="$lt{'request'}" />
 </form>
@@ -738,9 +765,9 @@ sub show_choices {
 		    $command='get';
 		}
 	    }
-	    my $escsymb=&Apache::lonnet::escape($symb);
+	    my $escsymb=&escape($symb);
 	    $form=<<STUFF;
-   <form method="POST" action="/adm/slotrequest">
+   <form method="post" action="/adm/slotrequest">
      <input type="submit" name="Select" value="$text" />
      <input type="hidden" name="symb" value="$escsymb" />
      <input type="hidden" name="slotname" value="$slot" />
@@ -837,14 +864,14 @@ sub remove_link {
 	undef($udom);
     }
 
-    $slotname  = &Apache::lonnet::escape($slotname);
-    $entry     = &Apache::lonnet::escape($entry);
-    $uname     = &Apache::lonnet::escape($uname);
-    $udom      = &Apache::lonnet::escape($udom);
-    $symb      = &Apache::lonnet::escape($symb);
+    $slotname  = &escape($slotname);
+    $entry     = &escape($entry);
+    $uname     = &escape($uname);
+    $udom      = &escape($udom);
+    $symb      = &escape($symb);
 
     return <<"END_LINK";
- <a href="/adm/slotrequest?command=remove_registration&slotname=$slotname&entry=$entry&uname=$uname&udom=$udom&symb=$symb"
+ <a href="/adm/slotrequest?command=remove_registration&amp;slotname=$slotname&amp;entry=$entry&amp;uname=$uname&amp;udom=$udom&amp;symb=$symb"
    >($remove)</a>
 END_LINK
 
@@ -861,11 +888,11 @@ sub show_table {
     my $available;
     if ($mgr eq 'F') {
 	$r->print('<div>');
-	$r->print('<form method="POST" action="/adm/slotrequest">
+	$r->print('<form method="post" action="/adm/slotrequest">
 <input type="hidden" name="command" value="uploadstart" />
 <input type="submit" name="start" value="'.&mt('Upload Slot List').'" />
 </form>');
-	$r->print('<form method="POST" action="/adm/helper/newslot.helper">
+	$r->print('<form method="post" action="/adm/helper/newslot.helper">
 <input type="submit" name="newslot" value="'.&mt('Create a New Slot').'" />
 </form>');
 	$r->print('</div>');
@@ -952,13 +979,16 @@ sub show_table {
     my $name_filter = {'type'  => $name_filter_type,
 		       'value' => $env{'form.name_filter_value'},};
 
+    
     #deleted slot filtering
+    #default to hide if no value
+    $env{'form.deleted'} ||= 'hide';
     my $hide_radio = 
 	&Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'hide');
     my $show_radio = 
 	&Apache::lonhtmlcommon::radio('deleted',$env{'form.deleted'},'show');
 	
-    $r->print('<form method="POST" action="/adm/slotrequest">
+    $r->print('<form method="post" action="/adm/slotrequest">
 <input type="hidden" name="command" value="showslots" />');
     $r->print('<div>');
     $r->print('<table class="inline">
@@ -1055,14 +1085,14 @@ sub show_table {
 					      $consumed{$b}{name} }
 				   (keys(%consumed))) {
 		    my (undef,$id)=split("\0",$entry);
-		    my ($uname,$udom) = split('@',$consumed{$entry}{'name'});
+		    my ($uname,$udom) = split(':',$consumed{$entry}{'name'});
 		    $ids.= '<nobr>';
 		    foreach my $item (@stu_display_order) {
 			if ($stu_display{$item}) {
 			    if ($item eq 'fullname') {
 				$ids.=$fullname->{"$uname:$udom"}.' ';
 			    } elsif ($item eq 'username') {
-				$ids.="<tt>$uname\@$udom</tt> ";
+				$ids.="<tt>$uname:$udom</tt> ";
 			    }
 			}
 		    }
@@ -1081,7 +1111,7 @@ sub show_table {
 	
 	my $unique;
 	if (ref($slots{$slot}{'uniqueperiod'})) {
-	    $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).','.
+	    $unique=localtime($slots{$slot}{'uniqueperiod'}[0]).', '.
 		localtime($slots{$slot}{'uniqueperiod'}[1]);
 	}
 
@@ -1122,7 +1152,7 @@ sub show_table {
 	if (exists($show{'proctor'})) {
 	    $rowspan=2;
 	    @proctors= map {
-		my ($uname,$udom)=split(/@/,$_);
+		my ($uname,$udom)=split(/:/,$_);
 		my $fullname=$name_cache{$_};
 		if (!defined($fullname)) {
 		    $fullname = &Apache::loncommon::plainname($uname,$udom);
@@ -1139,17 +1169,18 @@ sub show_table {
 EDITLINK
 
 	my $delete=(<<"DELETELINK");
-<a href="/adm/slotrequest?command=delete&slotname=$slot">Delete</a>
+<a href="/adm/slotrequest?command=delete&amp;slotname=$slot">Delete</a>
 DELETELINK
 
-        my $remove_all=&remove_link($slot,'remove all');
+        my $remove_all=&remove_link($slot,'remove all').'<br />';
 
         if ($ids ne '') { undef($delete); }
-	if ($slots{$slot}{'type'} ne 'schedulable_student') { 
+	if ($slots{$slot}{'type'} ne 'schedulable_student' 
+	    || $ids eq '') { 
 	    undef($remove_all);
 	}
 
-        $r->print("<tr>\n<td rowspan=\"$rowspan\">$edit $delete $remove_all</td>\n");
+        $r->print("<tr>\n<td rowspan=\"$rowspan\">$edit $delete</td>\n");
 	if (exists($show{'name'})) {
 	    $colspan++;$r->print("<td>$slot</td>");
 	}
@@ -1186,9 +1217,13 @@ DELETELINK
 	if (exists($show{'allowedusers'})) {
 	    $colspan++;$r->print("<td>$allowedusers</td>\n");
 	}
+	if (exists($show{'uniqueperiod'})) {
+	    $colspan++;$r->print("<td>$unique</td>\n");
+	}
 	if (exists($show{'scheduled'})) {
-	    $colspan++;$r->print("<td>$ids</td>\n</tr>\n");
+	    $colspan++;$r->print("<td>$remove_all $ids</td>\n");
 	}
+	$r->print("</tr>\n");
 	if (exists($show{'proctor'})) {
 	    $r->print(<<STUFF);
 <tr>
@@ -1197,7 +1232,7 @@ DELETELINK
 STUFF
         }
     }
-    $r->print('</table>');
+    $r->print('</table></form>');
 }
 
 sub upload_start {
@@ -1419,22 +1454,49 @@ sub csv_upload_assign {
 	if ($entries{$fields{'endtime'}}) {
 	    $slot{'endtime'}=&UnixDate($entries{$fields{'endtime'}},"%s");
 	}
+
+	# start/endtime must be defined and greater than zero
+	if (!$slot{'starttime'}) {
+	    push(@errors,"$name not created -- Invalid start time");
+	    next;
+	}
+	if (!$slot{'endtime'}) {
+	    push(@errors,"$name not created -- Invalid end time");
+	    next;
+	}
+	if ($slot{'starttime'} > $slot{'endtime'}) {
+	    push(@errors,"$name not created -- Slot starts after it ends");
+	    next;
+	}
+
 	if ($entries{$fields{'startreserve'}}) {
 	    $slot{'startreserve'}=
 		&UnixDate($entries{$fields{'startreserve'}},"%s");
 	}
+	if (defined($slot{'startreserve'})
+	    && $slot{'startreserve'} > $slot{'starttime'}) {
+	    push(@errors,"$name not created -- Slot's reservation start time is after the slot's start time.");
+	    next;
+	}
+
 	foreach my $key ('ip','proctor','description','maxspace',
 			 'secret','symb') {
 	    if ($entries{$fields{$key}}) {
 		$slot{$key}=$entries{$fields{$key}};
 	    }
 	}
+
 	if ($entries{$fields{'uniqueperiod'}}) {
 	    my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});
 	    my @times=(&UnixDate($start,"%s"),
 		       &UnixDate($end,"%s"));
 	    $slot{'uniqueperiod'}=\@times;
 	}
+	if (defined($slot{'uniqueperiod'})
+	    && $slot{'uniqueperiod'}[0] > $slot{'uniqueperiod'}[1]) {
+	    push(@errors,"$name not created -- Slot's unique period start time is later than the unique period's end time.");
+	    next;
+	}
 
 	&Apache::lonnet::cput('slots',{$name=>\%slot},$cdom,$cname);
 	$r->print('.');
@@ -1497,11 +1559,15 @@ sub handler {
 	    &csv_upload_map($r);
 	}
     } else {
-	my $symb=&Apache::lonnet::unescape($env{'form.symb'});
+	my $symb=&unescape($env{'form.symb'});
+	if (!defined($symb)) {
+	    &fail($r,'not_valid');
+	    return OK;
+	}
 	my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb);
 	my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb);
-	if ($useslots ne 'resource') {
-	    &fail($r,'not_valid');
+	if ($useslots ne 'resource' && $useslots ne 'map') {
+	    &fail($r,'not_available');
 	    return OK;
 	}
 	$env{'request.symb'}=$symb;