--- loncom/interface/slotrequest.pm	2015/09/27 22:35:39	1.130
+++ loncom/interface/slotrequest.pm	2016/10/27 21:02:02	1.134
@@ -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.130 2015/09/27 22:35:39 raeburn Exp $
+# $Id: slotrequest.pm,v 1.134 2016/10/27 21:02:02 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1494,7 +1494,8 @@ sub show_table {
 	     'allowedusers'    => 'Users slot is restricted to.',
 	     'uniqueperiod'    => 'Period of time slot is unique',
 	     'scheduled'       => 'Scheduled Students',
-	     'proctor'         => 'List of proctors');
+	     'proctor'         => 'List of proctors',
+	     'iptied'          => 'Unique IP each student',);
     if ($crstype eq 'Community') {
         $show_fields{'startreserve'} = &mt('Time members can start reserving');
         $show_fields{'endreserve'} = &mt('Time members can no longer reserve');
@@ -1502,7 +1503,7 @@ sub show_table {
     }
     my @show_order=('name','description','type','starttime','endtime',
 		    'startreserve','endreserve','reservationmsg','secret','space',
-		    'ip','symb','allowedsections','allowedusers','uniqueperiod',
+		    'ip','iptied','symb','allowedsections','allowedusers','uniqueperiod',
 		    'scheduled','proctor');
     my @show = 
 	(exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show')
@@ -1601,15 +1602,16 @@ sub show_table {
     $r->print('</div>');
     $r->print('<p><input type="submit" name="start" value="'.&mt('Update Display').'" /></p>');
     my $linkstart='<a href="/adm/slotrequest?command=showslots&amp;order=';
-    $r->print(&Apache::loncommon::start_data_table().
-	      &Apache::loncommon::start_data_table_header_row().'
-	       <th></th>');
+    my $tableheader = &Apache::loncommon::start_data_table().
+	              &Apache::loncommon::start_data_table_header_row().'
+	              <th></th>';
     foreach my $which (@show_order) {
 	if ($which ne 'proctor' && exists($show{$which})) {
-	    $r->print('<th>'.$linkstart.$which.'">'.$show_fields{$which}.'</a></th>');
+	    $tableheader .= '<th>'.$linkstart.$which.'">'.$show_fields{$which}.'</a></th>';
 	}
     }
-    $r->print(&Apache::loncommon::end_data_table_header_row());
+    $tableheader .= &Apache::loncommon::end_data_table_header_row();
+    my $shownheader = 0;
 
     my %name_cache;
     my $slotsort = sub {
@@ -1766,30 +1768,39 @@ sub show_table {
                                                delete => 'Delete',
                                                slotlog => 'History',
         );
-	my $edit=(<<"EDITLINK");
+        my ($edit,$delete,$showlog,$remove_all);
+        if ($mgr) {
+	    $edit=(<<"EDITLINK");
 <a href="/adm/helper/newslot.helper?name=$slot">$lt{'edit'}</a>
 EDITLINK
 
-	my $delete=(<<"DELETELINK");
+	    $delete=(<<"DELETELINK");
 <a href="/adm/slotrequest?command=delete&amp;slotname=$slot">$lt{'delete'}</a>
 DELETELINK
 
-        my $showlog=(<<"LOGLINK");
+            $remove_all=&remove_link($slot,'remove all').'<br />';
+
+            if ($ids eq '') {
+                undef($remove_all);
+            } else {
+                undef($delete);
+            }
+        }
+
+        $showlog=(<<"LOGLINK");
 <a href="/adm/slotrequest?command=slotlog&amp;slotname=$slot">$lt{'slotlog'}</a>
 LOGLINK
 
-        my $remove_all=&remove_link($slot,'remove all').'<br />';
-
-        if ($ids eq '') {
-            undef($remove_all);
-        } else {
-            undef($delete);
-        }
 	if ($slots{$slot}{'type'} ne 'schedulable_student') {
             undef($showlog); 
 	    undef($remove_all);
 	}
 
+        unless ($shownheader) {
+            $r->print($tableheader);
+            $shownheader = 1;
+        }
+
 	my $row_start=&Apache::loncommon::start_data_table_row();
 	my $row_end=&Apache::loncommon::end_data_table_row();
         $r->print($row_start.
@@ -1834,6 +1845,16 @@ LOGLINK
 	if (exists($show{'ip'})) {
 	    $colspan++;$r->print("<td>$slots{$slot}{'ip'}</td>\n");
 	}
+        if (exists($show{'iptied'})) {
+            $colspan++;
+            if ($slots{$slot}{'iptied'} eq 'yes') {
+                $r->print('<td>'.&mt('Yes')."</td>\n");
+            } elsif ($slots{$slot}{'iptied'} eq 'answer') {
+                $r->print('<td>'.&mt('Yes, including post-answer date')."</td>\n");
+            } else {
+                $r->print('<td>'.&mt('No')."</td>\n");
+            }
+        }
 	if (exists($show{'symb'})) {
 	    $colspan++;$r->print("<td>".join('<br />',@titles)."</td>\n");
 	}
@@ -1858,7 +1879,12 @@ $row_end
 STUFF
         }
     }
-    $r->print(&Apache::loncommon::end_data_table().'</form>');
+    if ($shownheader) {
+        $r->print(&Apache::loncommon::end_data_table());
+    } else {
+        $r->print('<p>'.&mt('No slots meet the criteria for display').'</p>');
+    }
+    $r->print('</form>');
     return;
 }
 
@@ -2349,14 +2375,16 @@ sub show_reservations {
     if ($showntablehdr) {
         $r->print(&Apache::loncommon::end_data_table().'<br />');
         if (($curr{'page'} > 1) || ($more_records)) {
-            $r->print('<table><tr>');
+            $r->print('<p>');
             if ($curr{'page'} > 1) {
-                $r->print('<td><a href="javascript:chgPage('."'previous'".');">'.&mt('Previous [_1] changes',$curr{'show'}).'</a></td>');
+                $r->print('<input type="button" onclick="javascript:chgPage('."'previous'".');" value="'.
+                          &mt('Previous [_1] changes',$curr{'show'}).'" />');
             }
             if ($more_records) {
-                $r->print('<td><a href="javascript:chgPage('."'next'".');">'.&mt('Next [_1] changes',$curr{'show'}).'</a></td>');
+                $r->print('<input type="button" onclick="javascript:chgPage('."'next'".');" value="'.
+                          &mt('Next [_1] changes',$curr{'show'}).'" />');
             }
-            $r->print('</tr></table>');
+            $r->print('</p>');
             $r->print(<<"ENDSCRIPT");
 <script type="text/javascript">
 // <![CDATA[
@@ -2560,14 +2588,16 @@ sub show_reservations_log {
     if ($showntablehdr) {
         $r->print(&Apache::loncommon::end_data_table().'<br />');
         if (($curr{'page'} > 1) || ($more_records)) {
-            $r->print('<table><tr>');
+            $r->print('<p>');
             if ($curr{'page'} > 1) {
-                $r->print('<td><a href="javascript:chgPage('."'previous'".');">'.&mt('Previous [_1] changes',$curr{'show'}).'</a></td>');
+                $r->print('<input type="button" onclick="javascript:chgPage('."'previous'".');" value="'.
+                          &mt('Previous [_1] changes',$curr{'show'}).'" />');
             }
             if ($more_records) {
-                $r->print('<td><a href="javascript:chgPage('."'next'".');">'.&mt('Next [_1] changes',$curr{'show'}).'</a></td>');
+                $r->print('<input type="button" onclick="javascript:chgPage('."'next'".');" value="'.
+                          &mt('Next [_1] changes',$curr{'show'}).'" />');
             }
-            $r->print('</tr></table>');
+            $r->print('</p>');
             $r->print(<<"ENDSCRIPT");
 <script type="text/javascript">
 function chgPage(caller) {
@@ -2707,8 +2737,9 @@ sub display_filter {
         }
         $output .= '</select></td>';
     }
-    $output .= '<td>&nbsp;&nbsp;</td><td valign="middle"><input type="submit" value="'.
-               &mt('Update Display').'" /></tr></table>'.
+    $output .= '<td>&nbsp;&nbsp;</td></tr></table>'.
+               '<p><input type="submit" value="'.
+               &mt('Update Display').'" /></p>'.
                '<p class="LC_info">'.
                &mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.'
                   ,'2.9.0');
@@ -2952,6 +2983,7 @@ sub csvupload_fields {
             ['endreserve','Reservation End Time'],
             ['reservationmsg','Message when reservation changed'],
 	    ['ip','IP or DNS restriction'],
+            ['iptied','Unique IP each student'],
 	    ['proctor','List of proctor ids'],
 	    ['description','Slot Description'],
 	    ['maxspace','Maximum number of reservations'],
@@ -3023,8 +3055,12 @@ sub csv_upload_assign {
 	}
 
 	if ($entries{$fields{'startreserve'}}) {
-	    $slot{'startreserve'}=
-		&UnixDate($entries{$fields{'startreserve'}},"%s");
+            my $date = &UnixDate($entries{$fields{'startreserve'}},"%s");
+            if ($date eq '') {
+                push(@errors,"$name -- No reservation start time set for slot -- value provided had invalid format");
+            } else {
+                $slot{'startreserve'} = $date;
+            }
 	}
 	if (defined($slot{'startreserve'})
 	    && $slot{'startreserve'} > $slot{'starttime'}) {
@@ -3033,8 +3069,12 @@ sub csv_upload_assign {
 	}
 
         if ($entries{$fields{'endreserve'}}) {
-            $slot{'endreserve'}=
-                &UnixDate($entries{$fields{'endreserve'}},"%s");
+            my $date = &UnixDate($entries{$fields{'endreserve'}},"%s");
+            if ($date eq '') {
+                push(@errors,"$name -- No reservation end time set for slot -- value provided had invalid format");
+            } else {
+                $slot{'endreserve'} = $date;
+            }
         }
         if (defined($slot{'endreserve'})
             && $slot{'endreserve'} > $slot{'starttime'}) {
@@ -3062,6 +3102,11 @@ sub csv_upload_assign {
 		$slot{$key}=$entries{$fields{$key}};
 	    }
 	}
+        if ($entries{$fields{'iptied'}} =~ /^\s*(yes|1)\s*$/i) {
+            $slot{'iptied'}='yes'; 
+        } elsif ($entries{$fields{'iptied'}} =~ /^\s*answer\s*$/i) {
+            $slot{'iptied'}='answer';
+        }
         if ($entries{$fields{'allowedusers'}}) {
             $entries{$fields{'allowedusers'}} =~ s/^\s+//;
             $entries{$fields{'allowedusers'}} =~ s/\s+$//;
@@ -3094,12 +3139,14 @@ sub csv_upload_assign {
             }
         }
 	if ($entries{$fields{'uniqueperiod'}}) {
-	    my ($start,$end)=split(',',$entries{$fields{'uniqueperiod'}});
-	    my @times=(&UnixDate($start,"%s"),
-		       &UnixDate($end,"%s"));
-	    $slot{'uniqueperiod'}=\@times;
+            my ($start,$end)= map { &UnixDate($_,"%s"); } split(',',$entries{$fields{'uniqueperiod'}});
+            if (($start ne '') && ($end ne '')) {
+                $slot{'uniqueperiod'}=[$start,$end];
+            } else {
+                push(@errors,"$name -- Slot's unique period ignored -- one or both of the comma separated values for start and end had an invalid format");
+            }
 	}
-	if (defined($slot{'uniqueperiod'})
+	if (ref($slot{'uniqueperiod'}) eq 'ARRAY' 
 	    && $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;
@@ -3262,7 +3309,7 @@ sub handler {
 	    }
 	    &csv_upload_map($r);
 	}
-    } elsif ($env{'form.command'} eq 'slotlog' && $mgr eq 'F') {
+    } elsif (($env{'form.command'} eq 'slotlog') && ($vgr eq 'F')) {
         &show_reservations_log($r);
     } else {
 	my $symb=&unescape($env{'form.symb'});
@@ -3284,7 +3331,8 @@ sub handler {
 	my ($status) = &Apache::lonhomework::check_slot_access('0',$type);
 	if ($status eq 'CAN_ANSWER' ||
 	    $status eq 'NEEDS_CHECKIN' ||
-	    $status eq 'WAITING_FOR_GRADE') {
+	    $status eq 'WAITING_FOR_GRADE' ||
+            $status eq 'NEED_DIFFERENT_IP') {
 	    &fail($r,'not_allowed');
 	    return OK;
 	}