--- loncom/interface/slotrequest.pm 2009/03/27 11:39:07 1.92 +++ loncom/interface/slotrequest.pm 2012/08/23 14:17:13 1.115 @@ -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.92 2009/03/27 11:39:07 bisitz Exp $ +# $Id: slotrequest.pm,v 1.115 2012/08/23 14:17:13 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -137,16 +137,20 @@ sub check_for_reservation { return 'error: Unable to determine current status'; } my @got; - my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots); + my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots,'starttime'); foreach my $slot_name (@sorted_slots) { next if (!defined($slots{$slot_name}) || !ref($slots{$slot_name})); &Apache::lonxml::debug(time." $slot_name ". $slots{$slot_name}->{'starttime'}." -- ". - $slots{$slot_name}->{'startreserve'}); - if ($slots{$slot_name}->{'endtime'} > time && - $slots{$slot_name}->{'startreserve'} < time) { - # between start of reservation times and end of slot + $slots{$slot_name}->{'startreserve'}." -- ". + $slots{$slot_name}->{'endreserve'}); + if (($slots{$slot_name}->{'endtime'} > time) && + ($slots{$slot_name}->{'startreserve'} < time) && + ((!$slots{$slot_name}->{'endreserve'}) || + ($slots{$slot_name}->{'endreserve'} > time))) { + # between start of reservation time and end of reservation time + # and before end of slot if ($mode eq 'allslots') { push(@got,$slot_name); } else { @@ -335,12 +339,12 @@ sub store_slot_parm { context => $env{'form.context'}, ); - &Apache::lonnet::instructor_log('slotreservationslog',\%storehash, - '',$env{'user.name'},$env{'user.domain'}, - $cnum,$cdom); - &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash, - 1,$env{'user.name'},$env{'user.domain'}, - $env{'user.name'},$env{'user.domain'}); + &Apache::lonnet::write_log('slotreservationslog',\%storehash, + '',$env{'user.name'},$env{'user.domain'}, + $cnum,$cdom); + &Apache::lonnet::write_log($cdom.'_'.$cnum.'_slotlog',\%storehash, + 1,$env{'user.name'},$env{'user.domain'}, + $env{'user.name'},$env{'user.domain'}); return; } @@ -534,10 +538,10 @@ sub release_reservation { action => 'release', context => $env{'form.context'}, ); - &Apache::lonnet::instructor_log('slotreservationslog',\%storehash, - 1,$uname,$udom,$cnum,$cdom); - &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash, - 1,$uname,$udom,$uname,$udom); + &Apache::lonnet::write_log('slotreservationslog',\%storehash, + 1,$uname,$udom,$cnum,$cdom); + &Apache::lonnet::write_log($cdom.'_'.$cnum.'_slotlog',\%storehash, + 1,$uname,$udom,$uname,$udom); } } @@ -562,7 +566,11 @@ sub release_reservation { if ($mgr eq 'F') { $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom"); } else { - $msg = &mt('Released Reservation: [_1]',$description); + $msg = '<span style="font-weight: bold;">'.&mt('Released reservation: [_1]',$description).'</span><br /><br />'; + my $person = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}); + my $subject = &mt('Reservation change: [_1]',$description); + my $msgbody = &mt('Reservation released by [_1] for [_2].',$person,$description); + $msg .= &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'release'); } return (1,$msg); } @@ -629,7 +637,6 @@ sub get_slot { my $description1=&get_description($slot_name,\%slot); %slot=&Apache::lonnet::get_slot($env{'form.slotname'}); my $description2=&get_description($env{'form.slotname'},\%slot); - $r->print('<p>'.&mt('Already have a reservation: [_1].',$description1).'</p>'); if ($slot_name ne $env{'form.slotname'}) { $r->print(<<STUFF); <form method="post" action="/adm/slotrequest"> @@ -638,19 +645,24 @@ sub get_slot { <input type="hidden" name="releaseslot" value="$slot_name" /> <input type="hidden" name="command" value="change" /> STUFF - $r->print('<p>' - .&mt('You can either [_1]Change[_2] your reservation from [_3] to [_4] or' - ,'<input type="submit" name="change" value="' - ,'" />' - ,'<b>'.$description1.'</b>' - ,'<b>'.$description2.'</b>') - .'<br /></p>' - ); - &return_link($r); + $r->print('<p class="LC_error">'.&mt('Reservation currently unchanged').'</p>'); + if ($slot_name ne '') { + $r->print('<p>'.&mt('To complete the transaction you [_1]must confirm[_2] you want to [_3]process the change[_4] to [_5].' + ,'<b>','</b>','<i>','</i>','<b>'.$description2.'</b>') + .'<br />' + .&mt('Or you can choose to [_1]make no change[_2] and continue[_2] with the reservation you already had: [_3].' + ,'<i>','</i>','<b>'.$description1.'</b>') + .'</p><p><span class="LC_nobreak">' + .'<input type="submit" name="change" value="'.&mt('Process the change').'" />' + .(' 'x3) + .'<input type="submit" name="nochange" value="'.&mt('Make no change').'" />' + .'</span></p>'); + } $r->print(<<STUFF); </form> STUFF } else { + $r->print('<p>'.&mt('Already have a reservation: [_1].',$description1).'</p>'); &return_link($r); } return 0; @@ -667,8 +679,15 @@ STUFF .&mt('An error occurred while attempting to make a reservation. ([_1])',$1) .'</span></p>'); } elsif ($reserved > -1) { - $r->print('<p>'.&mt('Success: [_1]',$description).'</p>'); + $r->print('<p style="font-weight: bold;">'.&mt('Successfully signed up: [_1]',$description).'</p>'); $retvalue = 1; + my $person = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}); + my $subject = &mt('Reservation change: [_1]',$description); + my $msgbody = &mt('Successful reservation by [_1] for [_2].',$person,$description); + my $msg = &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'reserve'); + if ($msg) { + $r->print($msg); + } } elsif ($reserved < 0) { $r->print('<p>'.&mt('Already reserved: [_1]',$description).'</p>'); } @@ -707,7 +726,8 @@ $lt{'or'} STUFF if (!$inhibit_return_link) { - $r->print(&mt('or').'</p>').&return_link($r); + $r->print(&mt('or').'</p>'); + &return_link($r); } else { $r->print('</p>'); } @@ -740,6 +760,11 @@ sub allowed_slot { if ($slot->{'startreserve'} > time) { return 0; } + # reserve time ended + if (($slot->{'endreserve'}) && + ($slot->{'endreserve'} < time)) { + return 0; + } &Apache::lonxml::debug("$slot_name reserve good"); my $userallowed=0; @@ -817,7 +842,7 @@ sub show_choices { my ($r,$symb,$formname)=@_; my ($cnum,$cdom)=&get_course(); - my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); + my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom); my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots); if (ref($consumed_uniqueperiods) eq 'HASH') { if (&Apache::lonnet::error(%$consumed_uniqueperiods)) { @@ -846,17 +871,18 @@ sub show_choices { (keys(%slots))) { &Apache::lonxml::debug("Checking Slot $slot"); - next if (!&allowed_slot($slot,$slots{$slot},undef,\%slots, + next if (!&allowed_slot($slot,$slots{$slot},$symb,\%slots, $consumed_uniqueperiods)); push(@available,$slot); } if (!@available) { - $output = &mt('No available times.'); + $output = '<div class="LC_info">'.&mt('No available times.'); if ($env{'form.command'} ne 'manageresv') { $output .= ' <a href="/adm/flip?postdata=return:">'. &mt('Return to last resource').'</a>'; } + $output .= '</div>'; $r->print($output); return; } @@ -1025,6 +1051,7 @@ sub show_table { my ($r,$mgr)=@_; my ($cnum,$cdom)=&get_course(); + my $crstype=&Apache::loncommon::course_type($cdom.'_'.$cnum); my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); if ( (keys(%slots))[0] =~ /^error: 2 /) { undef(%slots); @@ -1048,7 +1075,11 @@ sub show_table { } if (!keys(%slots)) { - $r->print('<div>'.&mt('No slots have been created in this course.').'</div>'); + if ($crstype eq 'Community') { + $r->print('<div>'.&mt('No slots have been created in this community.').'</div>'); + } else { + $r->print('<div>'.&mt('No slots have been created in this course.').'</div>'); + } return; } @@ -1075,6 +1106,8 @@ sub show_table { 'starttime' => 'Start time', 'endtime' => 'End Time', 'startreserve' => 'Time students can start reserving', + 'endreserve' => 'Time students can no longer reserve', + 'reservationmsg' => 'Message triggered by reservation', 'secret' => 'Secret Word', 'space' => '# of students/max', 'ip' => 'IP or DNS restrictions', @@ -1084,9 +1117,14 @@ sub show_table { 'uniqueperiod' => 'Period of time slot is unique', 'scheduled' => 'Scheduled Students', 'proctor' => 'List of proctors'); + if ($crstype eq 'Community') { + $show_fields{'startreserve'} = &mt('Time members can start reserving'); + $show_fields{'endreserve'} = &mt('Time members can no longer reserve'); + $show_fields{'scheduled'} = &mt('Scheduled Members'); + } my @show_order=('name','description','type','starttime','endtime', - 'startreserve','secret','space','ip','symb', - 'allowedsections','allowedusers','uniqueperiod', + 'startreserve','endreserve','reservationmsg','secret','space', + 'ip','symb','allowedsections','allowedusers','uniqueperiod', 'scheduled','proctor'); my @show = (exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show') @@ -1159,11 +1197,11 @@ sub show_table { 6,\%stu_display_fields, \@stu_display_order).' </td> - <td valign="top">'.&Apache::loncommon::select_form($when,'when',%when_fields). + <td valign="top">'.&Apache::loncommon::select_form($when,'when',\%when_fields). '</td> <td valign="top">'.&Apache::loncommon::select_form($name_filter_type, 'name_filter_type', - %name_filter_type_fields). + \%name_filter_type_fields). '<br />'. &Apache::lonhtmlcommon::textbox('name_filter_value', $env{'form.name_filter_value'}, @@ -1197,7 +1235,7 @@ sub show_table { my %name_cache; my $slotsort = sub { - if ($env{'form.order'}=~/^(type|description|endtime|startreserve|ip|symb|allowedsections|allowedusers)$/) { + if ($env{'form.order'}=~/^(type|description|endtime|startreserve|endreserve|ip|symb|allowedsections|allowedusers|reservationmsg)$/) { if (lc($slots{$a}->{$env{'form.order'}}) ne lc($slots{$b}->{$env{'form.order'}})) { return (lc($slots{$a}->{$env{'form.order'}}) @@ -1234,12 +1272,15 @@ sub show_table { if ($tmp =~ /^error: /) { undef(%consumed); } } + my %msgops = &slot_reservationmsg_options(); + foreach my $slot (sort $slotsort (keys(%slots))) { if (!&to_show($slot,$slots{$slot},$when, $env{'form.deleted'},$name_filter)) { next; } + my $reservemsg; if (defined($slots{$slot}->{'type'}) - && $slots{$slot}->{'type'} ne 'schedulable_student') { - #next; + && $slots{$slot}->{'type'} eq 'schedulable_student') { + $reservemsg = $msgops{$slots{$slot}->{'reservationmsg'}}; } my $description=&get_description($slot,$slots{$slot}); my ($id_count,$ids); @@ -1276,6 +1317,8 @@ sub show_table { &Apache::lonlocal::locallocaltime($slots{$slot}->{'endtime'}):''); my $start_reserve=($slots{$slot}->{'startreserve'}? &Apache::lonlocal::locallocaltime($slots{$slot}->{'startreserve'}):''); + my $end_reserve=($slots{$slot}->{'endreserve'}? + &Apache::lonlocal::locallocaltime($slots{$slot}->{'endreserve'}):''); my $unique; if (ref($slots{$slot}{'uniqueperiod'})) { @@ -1351,9 +1394,13 @@ LOGLINK my $remove_all=&remove_link($slot,'remove all').'<br />'; - if ($ids ne '') { undef($delete); } - if ($slots{$slot}{'type'} ne 'schedulable_student' - || $ids eq '') { + if ($ids eq '') { + undef($remove_all); + } else { + undef($delete); + } + if ($slots{$slot}{'type'} ne 'schedulable_student') { + undef($showlog); undef($remove_all); } @@ -1379,6 +1426,12 @@ LOGLINK if (exists($show{'startreserve'})) { $colspan++;$r->print("<td>$start_reserve</td>\n"); } + if (exists($show{'endreserve'})) { + $colspan++;$r->print("<td>$end_reserve</td>\n"); + } + if (exists($show{'reservationmsg'})) { + $colspan++;$r->print("<td>$reservemsg</td>\n"); + } if (exists($show{'secret'})) { $colspan++;$r->print("<td>$slots{$slot}{'secret'}</td>\n"); } @@ -1424,21 +1477,23 @@ STUFF } sub manage_reservations { - my ($r,$type) = @_; + my ($r,$crstype) = @_; my $navmap = Apache::lonnavmaps::navmap->new(); $r->print('<p>' .&mt('Instructors may use a reservation system to place restrictions on when and where assignments can be worked on.') .'<br />' .&mt('One example is for management of laboratory space, which is only available at certain times, and has a limited number of seats.') - .'</p><p>' - .&mt('Your reservation status for any such assignments is listed below:') .'</p>' ); if (!defined($navmap)) { - $r->print('<div class="LC_error">'. - &mt('Unable to retrieve information about course contents'). - '</div>'); - &Apache::lonnet::logthis('Manage Reservations - could not create navmap object in '.lc($type).':'.$env{'request.course.id'}); + $r->print('<div class="LC_error">'); + if ($crstype eq 'Community') { + $r->print(&mt('Unable to retrieve information about community contents')); + } else { + $r->print(&mt('Unable to retrieve information about course contents')); + } + $r->print('</div>'); + &Apache::lonnet::logthis('Manage Reservations - could not create navmap object in '.lc($crstype).':'.$env{'request.course.id'}); return; } my (%parent,%shownparent,%container,%container_title,%contents); @@ -1446,7 +1501,11 @@ sub manage_reservations { my @backgrounds = ("LC_odd_row","LC_even_row"); my $numcolors = scalar(@backgrounds); my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif"); - $r->print('<table class="LC_data_table LC_tableOfContent">'."\n"); + my $slotheader = '<p>'. + &mt('Your reservation status for any such assignments is listed below:'). + '</p>'. + '<table class="LC_data_table LC_tableOfContent">'."\n"; + my $shownheader = 0; my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef); while (my $resource = $it->next()) { if ($resource == $it->BEGIN_MAP()) { @@ -1508,6 +1567,8 @@ sub manage_reservations { } elsif ($slot_status == $resource->RESERVABLE) { $msg=&mt('Reservation needed'); $get_choices = 1; + } elsif ($slot_status == $resource->RESERVABLE_LATER) { + $msg=&mt('Reservation needed: will be reservable later.'); } elsif ($slot_status == $resource->NOTRESERVABLE) { $msg=&mt('Reservation needed: none available.'); } elsif ($slot_status == $resource->UNKNOWN) { @@ -1541,11 +1602,19 @@ sub manage_reservations { foreach my $item (@maprows) { $rownum ++; my $bgcolor = $backgrounds[$rownum % $numcolors]; + if (!$shownheader) { + $r->print($slotheader); + $shownheader = 1; + } $r->print('<tr class="'.$bgcolor.'">'.$item.'</tr>'."\n"); } } $rownum ++; my $bgcolor = $backgrounds[$rownum % $numcolors]; + if (!$shownheader) { + $r->print($slotheader); + $shownheader = 1; + } $r->print('<tr class="'.$bgcolor.'"><td>'."\n"); for (my $i=0; $i<$depth; $i++) { $r->print('<img src="'.$location.'" alt="" />'); @@ -1580,11 +1649,19 @@ sub manage_reservations { } } } + if ($shownheader) { + $r->print('</table>'); + } if (!$reservable) { - $r->print('<span class="LC_info">'.&mt('No course items currently require a reservation to gain access.').'</span>'); + $r->print('<span class="LC_info">'); + if ($crstype eq 'Community') { + $r->print(&mt('No community items currently require a reservation to gain access.')); + } else { + $r->print(&mt('No course items currently require a reservation to gain access.')); + } + $r->print('</span>'); } - $r->print('</table>'. - '<p><a href="/adm/slotrequest?command=showresv">'. + $r->print('<p><a href="/adm/slotrequest?command=showresv">'. &mt('Reservation History').'</a></p>'); } @@ -1595,9 +1672,9 @@ sub show_map_row { $output .= '<img src="'.$location.'" alt="" />'; } if ($type eq 'page') { - $output .= '<img src="/adm/lonIcons/navmap.page.open.gif"> '."\n"; + $output .= '<img src="/adm/lonIcons/navmap.page.open.gif" alt="" /> '."\n"; } else { - $output .= '<img src="/adm/lonIcons/navmap.folder.open.gif"> '."\n"; + $output .= '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" /> '."\n"; } $output .= $title.'</td><td colspan="2"> </td>'."\n"; unshift (@{$maprows},$output); @@ -1615,12 +1692,21 @@ sub show_reservations { my $formname = 'slotlog'; my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $crstype = &Apache::loncommon::course_type(); my %log=&Apache::lonnet::dump('nohist_'.$cdom.'_'.$cnum.'_slotlog',$udom,$uname); if ($env{'form.origin'} eq 'aboutme') { - $r->print('<div class="LC_fontsize_large">'. - &mt('History of student-schedulable slots for: [_1]', - &Apache::loncommon::plainname($env{'form.uname'},$env{'form.udom'}, - 'firstname')).'</div>'); + $r->print('<div class="LC_fontsize_large">'); + my $name = &Apache::loncommon::plainname($env{'form.uname'},$env{'form.udom'}, + 'firstname'); + if ($crstype eq 'Community') { + $r->print(&mt('History of member-reservable slots for: [_1]', + $name)); + } else { + $r->print(&mt('History of student-reservable slots for: [_1]', + $name)); + + } + $r->print('</div>'); } $r->print('<form action="/adm/slotrequest" method="post" name="'.$formname.'">'); # set defaults @@ -1669,7 +1755,7 @@ sub show_reservations { } } my (%titles,%maptitles); - my %lt = &reservationlog_contexts(); + my %lt = &reservationlog_contexts($crstype); foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) { next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) || ($log{$id}{'exe_time'} > $curr{'log_end_date'})); @@ -1731,7 +1817,7 @@ ENDSCRIPT } } else { $r->print('<span class="LC_info">' - .&mt('There are no transactions to display') + .&mt('There are no transactions to display.') .'</span>' ); } @@ -1748,6 +1834,33 @@ ENDSCRIPT sub show_reservations_log { my ($r) = @_; + my $badslot; + my $crstype = &Apache::loncommon::course_type(); + if ($env{'form.slotname'} eq '') { + $r->print('<div class="LC_warning">'.&mt('No slot name provided').'</div>'); + $badslot = 1; + } else { + my %slot=&Apache::lonnet::get_slot($env{'form.slotname'}); + if (keys(%slot) == 0) { + $r->print('<div class="LC_warning">'.&mt('Invalid slot name: [_1]',$env{'form.slotname'}).'</div>'); + $badslot = 1; + } elsif ($slot{type} ne 'schedulable_student') { + my $description = &get_description($env{'form.slotname'},\%slot); + $r->print('<div class="LC_warning">'); + if ($crstype eq 'Community') { + $r->print(&mt('Reservation history unavailable for non-member-reservable slot: [_1].',$description)); + } else { + $r->print(&mt('Reservation history unavailable for non-student-reservable slot: [_1].',$description)); + } + $r->print('</div>'); + $badslot = 1; + } + } + if ($badslot) { + $r->print('<p><a href="/adm/slotrequest?command=showslots">'. + &mt('Return to slot list').'</a></p>'); + return; + } my $formname = 'reservationslog'; my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; @@ -1810,9 +1923,13 @@ sub show_reservations_log { my %slot=&Apache::lonnet::get_slot($env{'form.slotname'}); my $description = $slot{'description'}; - $r->print('<div class="LC_fontsize_large">'. - &mt('Reservation changes for slot: [_1]',$description).'</div>'); - + $r->print('<span class="LC_fontsize_large">'); + if ($crstype eq 'Community') { + $r->print(&mt('Reservation changes for member-reservable slot: [_1]',$description)); + } else { + $r->print(&mt('Reservation changes for student-reservable slot: [_1]',$description)); + } + $r->print('</span><br />'); $r->print(&display_filter($formname,$cdom,$cnum,\%curr,$version,\@allsymbs)); my $showntablehdr = 0; my $tablehdr = &Apache::loncommon::start_data_table(). @@ -1830,7 +1947,7 @@ sub show_reservations_log { $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'}; } } - my %lt = &reservationlog_contexts(); + my %lt = &reservationlog_contexts($crstype); my (%titles,%maptitles); foreach my $id (sort { $log{$b}{'exe_time'}<=>$log{$a}{'exe_time'} } (keys(%log))) { next if (($log{$id}{'exe_time'} < $curr{'log_start_date'}) || @@ -1908,11 +2025,13 @@ function chgPage(caller) { ENDSCRIPT } } else { - $r->print(&mt('There are no records to display')); + $r->print(&mt('There are no records to display.')); } $r->print('<input type="hidden" name="page" value="'.$curr{'page'}.'" />'. '<input type="hidden" name="slotname" value="'.$env{'form.slotname'}.'" />'. - '<input type="hidden" name="command" value="slotlog" /></form>'); + '<input type="hidden" name="command" value="slotlog" /></form>'. + '<p><a href="/adm/slotrequest?command=showslots">'. + &mt('Return to slot list').'</a></p>'); return; } @@ -1948,6 +2067,7 @@ sub get_resource_title { } sub reservationlog_contexts { + my ($crstype) = @_; my %lt = &Apache::lonlocal::texthash ( any => 'Any', user => 'By student', @@ -1957,6 +2077,10 @@ sub reservationlog_contexts { release => 'Dropped reservation', usermanage => 'By student', ); + if ($crstype eq 'Community') { + $lt{'user'} = &mt('By member'); + $lt{'usermanage'} = $lt{'user'}; + } return %lt; } @@ -1964,7 +2088,7 @@ sub display_filter { my ($formname,$cdom,$cnum,$curr,$version,$allsymbs) = @_; my $nolink = 1; my (%titles,%maptitles); - my $output = '<table><tr><td valign="top">'. + my $output = '<br /><table><tr><td valign="top">'. '<span class="LC_nobreak"><b>'.&mt('Changes/page:').'</b><br />'. &Apache::lonmeta::selectbox('show',$curr->{'show'},undef, (&mt('all'),5,10,20,50,100,1000,10000)). @@ -1977,7 +2101,8 @@ sub display_filter { &Apache::lonhtmlcommon::date_setter($formname,'log_end_date', $curr->{'log_end_date'},undef, undef,undef,undef,undef,undef,undef,$nolink); - my %lt = &reservationlog_contexts(); + my $crstype = &Apache::loncommon::course_type(); + my %lt = &reservationlog_contexts($crstype); $output .= '<td valign="top"><b>'.&mt('Window during which changes occurred:'). '</b><br /><table><tr><td>'.&mt('After:'). '</td><td>'.$startform.'</td></tr><tr><td>'.&mt('Before:').'</td><td>'. @@ -2025,36 +2150,77 @@ sub display_filter { } $output .= '<td> </td><td valign="middle"><input type="submit" value="'. &mt('Update Display').'" /></tr></table>'. - '<span class="LC_roleslog_note">'. - &mt('[_1]Note:[_2] Only changes made from servers running LON-CAPA 2.8.99.0 or later are displayed.'); + '<p class="LC_info">'. + &mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.' + ,'2.9.0'); if ($version) { - $output .= ' '.&mt('This server is version [_3].','<b>','</b>',$version); + $output .= ' '.&mt('This LON-CAPA server is version [_1]',$version); } - $output .= '</span><hr noshade><br />'; + $output .= '</p><hr /><br />'; return $output; } +sub slot_change_messaging { + my ($setting,$subject,$msg,$action) = @_; + my $user = $env{'user.name'}; + my $domain = $env{'user.domain'}; + my ($message_status,$comment_status); + if ($setting eq 'only_student' + || $setting eq 'student_and_user_notes_screen') { + $message_status = + &Apache::lonmsg::user_normal_msg($user,$domain,$subject,$msg); + $message_status = '<li>'.&mt('Sent to you: [_1]', + $message_status).' </li>'; + } + if ($setting eq 'student_and_user_notes_screen') { + $comment_status = + &Apache::lonmsg::store_instructor_comment($subject.'<br />'. + $msg,$user,$domain); + $comment_status = '<li>'.&mt('Entry added to course record (viewable by instructor): [_1]', + $comment_status).'</li>'; + } + if ($message_status || $comment_status) { + my $msgtitle; + if ($action eq 'reserve') { + $msgtitle = &mt('Status of messages about saved reservation'); + } elsif ($action eq 'release') { + $msgtitle = &mt('Status of messages about dropped reservation'); + } elsif ($action eq 'nochange') { + $msgtitle = &mt('Status of messages about unchanged existing reservation'); + } + return '<span class="LC_info">'.$msgtitle.'</span>' + .'<ul>' + .$message_status + .$comment_status + .'</ul><hr />'; + } +} + sub upload_start { my ($r)=@_; - $r->print(&Apache::grades::checkforfile_js()); - my $result.='<table width=100% border=0><tr bgcolor="#e6ffff"><td>'."\n"; - $result.=' <b>'. - &mt('Specify a file containing the slot definitions.'). - '</b></td></tr>'."\n"; - $result.='<tr bgcolor="#ffffe6"><td>'."\n"; - my $upfile_select=&Apache::loncommon::upfile_select_html(); - my $ignore=&mt('Ignore First Line'); - $result.=<<ENDUPFORM; -<form method="post" enctype="multipart/form-data" action="/adm/slotrequest" name="slotupload"> -<input type="hidden" name="command" value="csvuploadmap" /> -$upfile_select -<br /><input type="button" onClick="javascript:checkUpload(this.form);" value="Upload Data" /> -<label><input type="checkbox" name="noFirstLine" />$ignore</label> -</form> -ENDUPFORM - $result.='</td></tr></table>'."\n"; - $result.='</td></tr></table>'."\n"; - $r->print($result); + $r->print( + &Apache::grades::checkforfile_js() + .'<h3>'.&mt('Specify a file containing the slot definitions.').'</h3>' + .'<form method="post" enctype="multipart/form-data"' + .' action="/adm/slotrequest" name="slotupload">' + .'<input type="hidden" name="command" value="csvuploadmap" />' + .&Apache::lonhtmlcommon::start_pick_box() + .&Apache::lonhtmlcommon::row_title(&mt('File')) + .&Apache::loncommon::upfile_select_html() + .&Apache::lonhtmlcommon::row_closure() + .&Apache::lonhtmlcommon::row_title( + '<label for="noFirstLine">' + .&mt('Ignore First Line') + .'</label>') + .'<input type="checkbox" name="noFirstLine" id="noFirstLine" />' + .&Apache::lonhtmlcommon::row_closure(1) + .&Apache::lonhtmlcommon::end_pick_box() + .'<p>' + .'<input type="button" onclick="javascript:checkUpload(this.form);"' + .' value="'.&mt('Next').'" />' + .'</p>' + .'</form>' + ); } sub csvuploadmap_header { @@ -2076,8 +2242,8 @@ sub csvuploadmap_header { Total number of records found in file: $distotal <hr /> Enter as many fields as you can. The system will inform you and bring you back to this page if the data selected is insufficient to create the slots.<hr /> -<input type="button" value="Reverse Association" onClick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" /> -<label><input type="checkbox" name="noFirstLine" $checked />$ignore</label> +<input type="button" value="Reverse Association" onclick="javascript:this.form.associate.value='Reverse Association';submit(this.form);" /> +<label><input type="checkbox" name="noFirstLine"$checked />$ignore</label> <input type="hidden" name="associate" value="" /> <input type="hidden" name="datatoken" value="$datatoken" /> <input type="hidden" name="fileupload" value="$env{'form.fileupload'}" /> @@ -2101,7 +2267,7 @@ sub csvuploadmap_footer { </table> <input type="hidden" name="nfields" value="$i" /> <input type="hidden" name="keyfields" value="$keyfields" /> -<input type="button" onClick="javascript:verify(this.form)" value="$buttontext" /><br /> +<input type="button" onclick="javascript:verify(this.form)" value="$buttontext" /><br /> </form> ENDPICK } @@ -2200,6 +2366,8 @@ sub csvupload_fields { ['starttime','Start Time of slot'], ['endtime','End Time of slot'], ['startreserve','Reservation Start Time'], + ['endreserve','Reservation End Time'], + ['reservationmsg','Message when reservation changed'], ['ip','IP or DNS restriction'], ['proctor','List of proctor ids'], ['description','Slot Description'], @@ -2281,6 +2449,30 @@ sub csv_upload_assign { next; } + if ($entries{$fields{'endreserve'}}) { + $slot{'endreserve'}= + &UnixDate($entries{$fields{'endreserve'}},"%s"); + } + if (defined($slot{'endreserve'}) + && $slot{'endreserve'} > $slot{'starttime'}) { + push(@errors,"$name not created -- Slot's reservation end time is after the slot's start time."); + next; + } + + if ($slot{'type'} eq 'schedulable_student') { + if ($entries{$fields{'reservationmsg'}}) { + if (($entries{$fields{'reservationmsg'}} eq 'only_student') || + ($entries{$fields{'reservationmsg'}} eq 'student_and_user_notes_screen')) { + $slot{'reservationmsg'}=$entries{$fields{'reservationmsg'}}; + } else { + unless (($entries{$fields{'reservationmsg'}} eq 'none') || + ($entries{$fields{'reservationmsg'}} eq '')) { + push(@errors,"$name -- Slot's reservationmsg setting ignored - not one of: 'only_student', 'student_and_user_notes_screen', 'none' or ''"); + } + } + } + } + foreach my $key ('ip','proctor','description','maxspace', 'secret','symb') { if ($entries{$fields{$key}}) { @@ -2305,6 +2497,9 @@ sub csv_upload_assign { $r->rflush(); $countdone++; } + if ($countdone) { + &Apache::lonnet::devalidate_slots_cache($cname,$cdom); + } $r->print('<p>'.&mt('Created [quant,_1,slot]',$countdone)."\n".'</p>'); foreach my $error (@errors) { $r->print('<p><span class="LC_warning">'.$error.'</span></p>'."\n"); @@ -2330,6 +2525,15 @@ sub slot_command_titles { return %titles; } +sub slot_reservationmsg_options { + my %options = &Apache::lonlocal::texthash ( + only_student => 'Sent to student', + student_and_user_notes_screen => 'Sent to student and added to user notes', + none => 'None sent and no record in user notes', + ); + return %options; +} + sub handler { my $r=shift; @@ -2389,8 +2593,9 @@ sub handler { if (ref($brcrum) eq 'ARRAY') { push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}}); } - } + } else { + $brcrum =[]; } &start_page($r,$title,$brcrum); @@ -2459,7 +2664,26 @@ sub handler { } elsif ($env{'form.command'} eq 'get') { &get_slot($r,$symb); } elsif ($env{'form.command'} eq 'change') { - if (&get_slot($r,$symb,$env{'form.releaseslot'},1)) { + if ($env{'form.nochange'}) { + my $slot_name = $env{'form.releaseslot'}; + my @slots = &check_for_reservation($symb,'allslots'); + my $msg; + if (($slot_name ne '') && (grep(/^\Q$slot_name\E/,@slots))) { + my %slot=&Apache::lonnet::get_slot($env{'form.releaseslot'}); + my $description=&get_description($slot_name,\%slot); + $msg = '<span style="font-weight: bold;">'. + &mt('Unchanged reservation: [_1]',$description).'</span><br /><br />'; + my $person = + &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}); + my $subject = &mt('Reservation unchanged: [_1]',$description); + my $msgbody = &mt('No change to existing registration by [_1] for [_2].',$person,$description); + $msg .= &slot_change_messaging($slot{'reservationmsg'},$subject,$msgbody,'nochange'); + } else { + $msg = '<span class="LC_warning">'.&mt('Reservation no longer reported as available.').'</span>'; + } + $r->print($msg); + &return_link($r); + } elsif (&get_slot($r,$symb,$env{'form.releaseslot'},1)) { &release_slot($r,$symb,$env{'form.releaseslot'}); } } else {