--- loncom/interface/slotrequest.pm 2015/09/07 17:44:11 1.124 +++ loncom/interface/slotrequest.pm 2019/06/24 03:23:36 1.125.2.3.4.1 @@ -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.124 2015/09/07 17:44:11 raeburn Exp $ +# $Id: slotrequest.pm,v 1.125.2.3.4.1 2019/06/24 03:23:36 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -162,9 +162,24 @@ $js var startdate = startm+"/"+startd+"/"+starty; var starttime = new Date(startdate).getTime(); starttime = starttime/1000; + var starth = form.start_hour.options[form.start_hour.selectedIndex].value; + if (numberRegExp.test(starth)) { + starth = parseInt(starth); + if (starth > 0 && starth <= 23) { + starttime += 3600 * starth; + } + } var enddate = endm+"/"+endd+"/"+endy; var endtime = new Date(enddate).getTime(); endtime = endtime/1000; + var endh = form.end_hour.options[form.end_hour.selectedIndex].value; + if (numberRegExp.test(endh)) { + endh = parseInt(endh); + if (endh > 0 && endh <= 23) { + endtime += 3600 * endh; + } + } + var shown = 0; for (var i=0; i<$i; i++) { if ((slotstart[i] >= starttime) && (slotend[i] <= endtime)) { @@ -237,7 +252,7 @@ function uncheckSlotRadio() { if (document.getElementsByClassName) { slotpicks = document.getElementsByClassName('LC_slotpick_radio'); } else { - sloctpicks = getElementsByClassName(document.body,'LC_slotpick_radio'); + slotpicks = getElementsByClassName(document.body,'LC_slotpick_radio'); } if (slotpicks.length) { for (var i=0; i<slotpicks.length; i++) { @@ -714,13 +729,39 @@ sub release_reservation { } my $new_param = join(':',@new_slots); + # Get value of useslots parameter in effect for this user. + # If value is map or map_map, then the parm level is 2 (i.e., + # non-recursive enclosing map/folder level for specific user) + # and the symb for this reservation in slot_reservations.db + # will be the symb of the map itself. + + my $use_slots = &Apache::lonnet::EXT("resource.0.useslots", + $symb,$udom,$uname); + &Apache::lonxml::debug("use_slots is $use_slots<br />"); + + if (&Apache::lonnet::error($use_slots)) { + return (0,'error: Unable to determine current status'); + } + + my $parm_level = 1; + my $parm_symb = $passed_resource->symb(); + if ($use_slots eq 'map' || $use_slots eq 'map_map') { + $parm_level = 2; + unless ($passed_resource->is_map()) { + my ($map) = &Apache::lonnet::decode_symb($parm_symb); + $parm_symb = &Apache::lonnet::symbread($map); + } + } + my ($cnum,$cdom)=&get_course(); - # get slot reservations, check if user has one, if so remove reservation + # get slot reservations, check if user has one for the + # correct symb, and if so, remove the 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) && + ($consumed{$entry}->{'symb'} eq $parm_symb)) { &Apache::lonnet::del('slot_reservations',[$entry], $cdom,$cnum); my %storehash = ( @@ -729,25 +770,13 @@ sub release_reservation { action => 'release', context => $env{'form.context'}, ); - &Apache::lonnet::write_log('slotreservationslog',\%storehash, - 1,$uname,$udom,$cnum,$cdom); - &Apache::lonnet::write_log($cdom.'_'.$cnum.'_slotlog',\%storehash, - 1,$uname,$udom,$uname,$udom); + &Apache::lonnet::write_log('course','slotreservationslog', + \%storehash,1,$uname,$udom,$cnum,$cdom); + &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog', + \%storehash,1,$uname,$udom,$uname,$udom); } } - my $use_slots = &Apache::lonnet::EXT("resource.0.useslots", - $symb,$udom,$uname); - &Apache::lonxml::debug("use_slots is $use_slots<br />"); - - if (&Apache::lonnet::error($use_slots)) { - return (0,'error: Unable to determine current status'); - } - - my $parm_level = 1; - if ($use_slots eq 'map' || $use_slots eq 'map_map') { - $parm_level = 2; - } # store new parameter string my $result=&Apache::lonparmset::storeparm_by_symb($symb, '0_availablestudent', @@ -826,9 +855,15 @@ sub get_slot { if ($slot_name && $slot_name ne $conflictable_slot) { my %slot=&Apache::lonnet::get_slot($slot_name); my $description1=&get_description($slot_name,\%slot); + my $slottype1=$slot{'type'}; %slot=&Apache::lonnet::get_slot($env{'form.slotname'}); my $description2=&get_description($env{'form.slotname'},\%slot); - if ($slot_name ne $env{'form.slotname'}) { + if ($slottype1 eq 'preassigned') { + $r->print('<p>'.&mt('You already have a reservation: "[_1]", assigned by your instructor.', + $description1).'</p>'. + '<p>'.&mt('Your instructor must unassign it before you can make a new reservation.'). + '</p>'); + } elsif ($slot_name ne $env{'form.slotname'}) { $r->print(<<STUFF); <form method="post" action="/adm/slotrequest"> <input type="hidden" name="symb" value="$env{'form.symb'}" /> @@ -1461,15 +1496,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&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 { @@ -1618,30 +1654,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&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&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. @@ -1710,7 +1755,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; } @@ -2066,14 +2116,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[ @@ -2277,14 +2329,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) { @@ -2424,8 +2478,9 @@ sub display_filter { } $output .= '</select></td>'; } - $output .= '<td> </td><td valign="middle"><input type="submit" value="'. - &mt('Update Display').'" /></tr></table>'. + $output .= '<td> </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'); @@ -2740,8 +2795,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'}) { @@ -2750,8 +2809,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'}) { @@ -2811,12 +2874,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; @@ -2979,7 +3044,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'});