--- loncom/interface/slotrequest.pm 2009/03/20 10:05:08 1.90
+++ loncom/interface/slotrequest.pm 2018/07/02 20:34:52 1.139
@@ -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.90 2009/03/20 10:05:08 bisitz Exp $
+# $Id: slotrequest.pm,v 1.139 2018/07/02 20:34:52 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -37,7 +37,7 @@ use Apache::lonnet;
use Apache::lonnavmaps();
use Date::Manip;
use lib '/home/httpd/lib/perl/';
-use LONCAPA;
+use LONCAPA qw(:DEFAULT :match);
sub fail {
my ($r,$code)=@_;
@@ -56,8 +56,22 @@ sub fail {
}
sub start_page {
- my ($r,$title)=@_;
- $r->print(&Apache::loncommon::start_page($title));
+ my ($r,$title,$brcrum,$js)=@_;
+ my $args;
+ if (ref($brcrum) eq 'ARRAY') {
+ $args = {bread_crumbs => $brcrum};
+ }
+ if (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) {
+ my %loaditems = (
+ onload => 'javascript:uncheckSlotRadio();',
+ );
+ if (ref($args) eq 'HASH') {
+ $args->{'add_entries'} = \%loaditems;
+ } else {
+ $args = { 'add_entries' => \%loaditems };
+ }
+ }
+ $r->print(&Apache::loncommon::start_page($title,$js,$args));
}
sub end_page {
@@ -65,6 +79,291 @@ sub end_page {
$r->print(&Apache::loncommon::end_page());
}
+sub reservation_js {
+ my ($slots,$consumed_uniqueperiods,$available,$got_slots,$symb) = @_;
+ return unless ((ref($slots) eq 'HASH') && (ref($available) eq 'ARRAY'));
+ my $toskip;
+ if ($symb eq '') {
+ $toskip = { symb => 1, };
+ }
+ my ($i,$j) = (0,0);
+ my $js;
+ foreach my $slot (sort
+ { return $slots->{$a}->{'starttime'} <=> $slots->{$b}->{'starttime'} }
+ (keys(%{$slots}))) {
+
+ next if (!&allowed_slot($slot,$slots->{$slot},$symb,$slots,
+ $consumed_uniqueperiods,$toskip));
+ $js .= " slotstart[$i]='$slots->{$slot}->{'starttime'}';\n".
+ " slotend[$i]='$slots->{$slot}->{'endtime'}';\n".
+ " slotname[$i]='$slot';\n";
+ if (($symb) && (ref($got_slots) eq 'ARRAY')) {
+ if (grep(/^\Q$slot\E$/,@{$got_slots})) {
+ $js .= " currslot[$j]='$slot';\n";
+ $j++;
+ }
+ }
+ $i++;
+ push(@{$available},$slot);
+ }
+ if ($j) {
+ $js = " var currslot = new Array($j);\n\n$js";
+ }
+ my %alerts = &Apache::lonlocal::texthash (
+ none => 'No reservable time slots found',
+ invalid => 'Invalid date format',
+ );
+ return <<"ENDSCRIPT";
+
+ENDSCRIPT
+
+}
+
+
=pod
slot_reservations db
@@ -117,7 +416,6 @@ sub check_for_reservation {
my ($symb,$mode)=@_;
my $student = &Apache::lonnet::EXT("resource.0.availablestudent", $symb,
$env{'user.domain'}, $env{'user.name'});
-
my $course = &Apache::lonnet::EXT("resource.0.available", $symb,
$env{'user.domain'}, $env{'user.name'});
my @slots = (split(/:/,$student), split(/:/, $course));
@@ -133,22 +431,20 @@ sub check_for_reservation {
return 'error: Unable to determine current status';
}
my @got;
- foreach my $slot_name (sort {
- if (ref($slots{$a}) && ref($slots{$b})) {
- return $slots{$a}{'starttime'} <=> $slots{$b}{'starttime'}
- }
- if (ref($slots{$a})) { return -1;}
- if (ref($slots{$b})) { return 1;}
- return 0;
- } @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 {
@@ -169,7 +465,7 @@ sub get_consumed_uniqueperiods {
return 'error: Unable to determine current status';
}
my @problems = $navmap->retrieveResources(undef,
- sub { $_[0]->is_problem() },1,0);
+ sub { $_[0]->is_problem() || $_[0]->is_tool() },1,0);
my %used_slots;
foreach my $problem (@problems) {
my $symb = $problem->symb();
@@ -216,16 +512,19 @@ sub check_for_conflict {
if (!defined($new_slot->{'uniqueperiod'})) { return undef; }
if (!ref($consumed_uniqueperiods)) {
- $consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);
- if (ref($consumed_uniqueperiods) eq 'HASH') {
- if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
- return 'error: Unable to determine current status';
- }
+ if ($consumed_uniqueperiods =~ /^error: /) {
+ return $consumed_uniqueperiods;
} else {
- return 'error: Unable to determine current status';
+ $consumed_uniqueperiods = &get_consumed_uniqueperiods($slots);
+ if (ref($consumed_uniqueperiods) eq 'HASH') {
+ if (&Apache::lonnet::error(%$consumed_uniqueperiods)) {
+ return 'error: Unable to determine current status';
+ }
+ } else {
+ return 'error: Unable to determine current status';
+ }
}
- }
-
+ }
my ($new_uniq_start,$new_uniq_end) = @{$new_slot->{'uniqueperiod'}};
foreach my $slot_name (keys(%$consumed_uniqueperiods)) {
my ($start,$end)=@{$consumed_uniqueperiods->{$slot_name}};
@@ -337,9 +636,13 @@ sub store_slot_parm {
context => $env{'form.context'},
);
- &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,
- '',$env{'user.name'},$env{'user.domain'},
- $cnum,$cdom);
+ &Apache::lonnet::write_log('course','slotreservationslog',\%storehash,
+ '',$env{'user.name'},$env{'user.domain'},
+ $cnum,$cdom);
+ &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash,
+ 1,$env{'user.name'},$env{'user.domain'},
+ $env{'user.name'},$env{'user.domain'});
+
return;
}
@@ -498,14 +801,20 @@ sub release_reservation {
return (0,'error: Unable to determine current status');
}
my $passed_resource = $navmap->getBySymb($symb);
- if ($passed_resource->is_map()) {
- my ($a_resource) =
- $navmap->retrieveResources($passed_resource,
- sub {$_[0]->is_problem()},0,1);
- $symb = $a_resource->symb();
+ if (ref($passed_resource)) {
+ if ($passed_resource->is_map()) {
+ my ($a_resource) =
+ $navmap->retrieveResources($passed_resource,
+ sub {$_[0]->is_problem() || $_[0]->is_tool() },0,1);
+ $symb = $a_resource->symb();
+ }
+ } else {
+ unless ($mgr eq 'F') {
+ return (0,'error: Unable to determine current status');
+ }
}
- # get parameter string, check for existance, rebuild string with the slot
+ # get parameter string, check for existence, rebuild string with the slot
my $student = &Apache::lonnet::EXT("resource.0.availablestudent",
$symb,$udom,$uname);
my @slots = split(/:/,$student);
@@ -532,8 +841,10 @@ sub release_reservation {
action => 'release',
context => $env{'form.context'},
);
- &Apache::lonnet::instructor_log('slotreservationslog',\%storehash,
- 1,$uname,$udom,$cnum,$cdom);
+ &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);
}
}
@@ -558,7 +869,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 = ''.&mt('Released reservation: [_1]',$description).'
';
+ 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);
}
@@ -598,8 +913,13 @@ sub delete_slot {
sub return_link {
my ($r) = @_;
- $r->print('
'. - &mt('Return to last resource').'
'); + if (($env{'form.command'} eq 'manageresv') || ($env{'form.context'} eq 'usermanage')) { + $r->print(''.
+ &mt('Return to reservations'));
+ } else {
+ $r->print(' '.
+ &mt('Return to last resource').' '.&mt('Already have a reservation: [_1].',$description1).' '.&mt('You already have a reservation: "[_1]", assigned by your instructor.',
+ $description1).' '.&mt('Your instructor must unassign it before you can make a new reservation.').
+ ' '
- .&mt('You can either [_1]Change[_2] your reservation from [_3] to [_4] or'
- ,''
- ,''.$description1.''
- ,''.$description2.'')
- .' '.&mt('Reservation currently unchanged').' '.&mt('To complete the transaction you [_1]must confirm[_2] you want to [_3]process the change[_4] to [_5].'
+ ,'','','','',''.$description2.'')
+ .' '
+ .''
+ .(' 'x3)
+ .''
+ .' '.&mt('Already have a reservation: [_1].',$description1).'
'
+ .&mt('Or you can choose to [_1]make no change[_2] and continue[_2] with the reservation you already had: [_3].'
+ ,'','',''.$description1.'')
+ .'
'.&mt('Success: [_1]',$description).'
'); + $r->print(''.&mt('Successfully signed up: [_1]',$description).'
'); $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(''.&mt('Already reserved: [_1]',$description).'
'); } @@ -668,7 +1005,7 @@ STUFF } my %lt = &Apache::lonlocal::texthash( - 'request' => 'Availibility list', + 'request' => 'Availability list', 'try' => 'Try again?', 'or' => 'or', ); @@ -698,7 +1035,8 @@ $lt{'or'} STUFF if (!$inhibit_return_link) { - $r->print(&mt('or').'').&return_link($r); + $r->print(&mt('or').''); + &return_link($r); } else { $r->print(''); } @@ -706,7 +1044,7 @@ STUFF } sub allowed_slot { - my ($slot_name,$slot,$symb,$slots,$consumed_uniqueperiods)=@_; + my ($slot_name,$slot,$symb,$slots,$consumed_uniqueperiods,$toskip)=@_; #already started if ($slot->{'starttime'} < time) { @@ -731,6 +1069,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; @@ -775,9 +1118,33 @@ sub allowed_slot { return 0 if (!$userallowed); # not allowed for this resource - if (defined($slot->{'symb'}) - && $slot->{'symb'} ne $symb) { - return 0; + if (defined($slot->{'symb'})) { + my $exclude = 1; + my @symbs; + if ($slot->{'symb'} =~ /,/) { + @symbs = split(/\s*,\s*/,$slot->{'symb'}); + } else { + @symbs = ($slot->{'symb'}); + } + my ($map,$id,$url) = &Apache::lonnet::decode_symb($symb); + foreach my $reqsymb (@symbs) { + next if ($reqsymb eq ''); + my ($slotmap,$slotid,$sloturl) = &Apache::lonnet::decode_symb($reqsymb); + if ($sloturl=~/\.(page|sequence)$/) { + if (($map ne '') && ($map eq $sloturl)) { + $exclude = 0; + last; + } + } elsif ($reqsymb eq $symb) { + $exclude = 0; + last; + } + } + if ($exclude) { + unless ((ref($toskip) eq 'HASH') && ($toskip->{'symb'})) { + return 0; + } + } } my $conflict = &check_for_conflict($symb,$slot_name,$slot,$slots, @@ -805,63 +1172,119 @@ sub get_description { } sub show_choices { - my ($r,$symb)=@_; - - my ($cnum,$cdom)=&get_course(); - my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); - my $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots); - if (ref($consumed_uniqueperiods) eq 'HASH') { - if (&Apache::lonnet::error(%$consumed_uniqueperiods)) { - $r->print(''. - &mt('An error occurred determining slot availability'). - ''); - return; - } - } elsif ($consumed_uniqueperiods =~ /^error: /) { - $r->print(''. - &mt('An error occurred determining slot availability'). - ''); - return; - } - my $available; + my ($symb,$formname,$num,$class,$slots,$consumed_uniqueperiods,$available,$got_slots)=@_; + my $output; &Apache::lonxml::debug("Checking Slots"); - my @got_slots=&check_for_reservation($symb,'allslots'); - if ($got_slots[0] =~ /^error: /) { - $r->print(''. - &mt('An error occurred determining slot availability'). - ''); + if (!ref($available) eq 'ARRAY') { return; } - $r->print('' + .&mt('No slots have been created in this '.lc($crstype).'.') + .'
' + ); + return; + } my %Saveable_Parameters = ('show' => 'array', 'when' => 'scalar', @@ -1031,18 +1490,26 @@ 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', - 'symb' => 'Resource slot is restricted to.', + 'symb' => 'Resource(s)/Map(s) slot is restricted to.', 'allowedsections' => 'Sections slot is restricted to.', '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'); + $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','iptied','symb','allowedsections','allowedusers','uniqueperiod', 'scheduled','proctor'); my @show = (exists($env{'form.show'})) ? &Apache::loncommon::get_env_multiple('form.show') @@ -1108,31 +1575,31 @@ sub show_table {Deleted slots: | -+ | '.&mt('Deleted slots:').' | +|
+ |
'.&mt('No slots meet the criteria for display').'
'); + } + $r->print(''); + return; +} + +sub manage_reservations { + my ($r,$crstype,$slots,$consumed_uniqueperiods,$allavailable) = @_; + my ($cnum,$cdom)=&get_course(); + my $navmap = Apache::lonnavmaps::navmap->new(); + $r->print(''
+ .&mt('Instructors may use a reservation system to place restrictions on when and where assignments can be worked on.')
+ .'
'
+ .&mt('One example is for management of laboratory space, which is only available at certain times, and has a limited number of seats.')
+ .'
'. + &mt('Your reservation status for any such assignments is listed below:'). + '
'. + ''.$spacers.''. + $icon.(' ' x6).' | '."\n"; + if (ref($output{$currmap}) eq 'HASH') { + my $formnum = $mapnum.'_'.$reservable+1; + my $class = 'LC_slotmaptext_'.$mapnum; + if ($output{$currmap}{'hasaction'}) { + $row .= ''. + $output{$currmap}{'msg'}. + ' | '. + &slot_chooser($repsymbs{$currmap},$class,$formnum, + $allavailable,$slots,$consumed_uniqueperiods). + ' | '; + } else { + $row .= ''. + $output{$currmap}{'msg'}. + ' | '; + } + $row .= ''."\n"; + } + } else { + my ($spacers,$icon) = &show_map_row($depth,$location,$currmaptype,$currmaptitle); + $row .= ' | '.$spacers.$icon.(' ' x6).' | '."\n"; + } + $r->print($row); + } + } + } elsif ($resource == $it->END_MAP()) { + $depth--; + $currcontainer = $parent{$depth}; + } elsif (ref($resource)) { + my $symb = $resource->symb(); + next if (!$resource->is_problem() && !$resource->is_tool() && + !$resource->is_sequence() && !$resource->is_page()); + $count ++; + if (($resource->is_sequence()) || ($resource->is_page())) { + $currcontainer = $count; + $container{$currcontainer} = $resource; + $container_title{$currcontainer} = $resource->compTitle(); + } + if (($resource->is_problem() || $resource->is_tool)) { + next unless (exists($output{$symb})); + $reservable ++; + $rownum ++; + if (!$shownheader) { + $r->print($slotheader); + $shownheader = 1; + } + my $style; + if (exists($output{$currmap})) { + $style = 'none'; + } else { + $style = 'table-row'; + $shown ++; + } + my $title = $resource->compTitle(); + my $bgcolor = $backgrounds[$shown % $numcolors]; + $r->print(' |
'); + for (my $i=0; $i<$depth; $i++) { + $r->print(''); + } + $r->print(''. + ''.$title.''.(' ' x6).' | '); + my $class = 'LC_slottext_'.$mapnum; + if ($output{$symb}{'hasaction'}) { + $r->print(''.$output{$symb}{'msg'}.' | '. + ''. + &slot_chooser($symb,$class,$reservable,$allavailable,$slots, + $consumed_uniqueperiods).' | '); + } else { + $r->print(''. + ''.$output{$symb}{'msg'}.''. + ' | '); + } + $r->print('
'. + &mt('Reservation History').'
'); +} + +sub show_map_row { + my ($depth,$location,$type,$title) = @_; + my $spacers; + for (my $i=0; $i<$depth-1; $i++) { + $spacers .= ''; + } + my $icon; + if ($type eq 'page') { + $icon = ' '."\n"; + } else { + $icon = ' '."\n"; + } + $icon .= $title; + return ($spacers,$icon); +} + +sub slot_chooser { + my ($symb,$class,$formnum,$allavailable,$slots,$consumed_uniqueperiods) = @_; + my $output; + my @got_slots=&check_for_reservation($symb,'allslots'); + if ($got_slots[0] =~ /^error: /) { + $output = ''. + &mt('An error occurred determining slot availability.'). + ''; + } else { + my $formname = 'manageres_'.$formnum; + if (ref($allavailable) eq 'ARRAY') { + my @available; + if (ref($slots) eq 'HASH') { + foreach my $slot (@{$allavailable}) { + # not allowed for this resource + if (ref($slots->{$slot}) eq 'HASH') { + if ($slots->{$slot}->{'symb'} ne '') { + my ($map,$id,$url) = &Apache::lonnet::decode_symb($symb); + my $exclude = 1; + my @reqsymbs = split(/\s*,\s*/,$slots->{$slot}->{'symb'}); + if (@reqsymbs) { + if (grep(/^\Q$symb\E$/,@reqsymbs)) { + $exclude = 0; + } else { + foreach my $reqsymb (@reqsymbs) { + my (undef,undef,$sloturl) = &Apache::lonnet::decode_symb($reqsymb); + if ($sloturl=~/\.(page|sequence)$/) { + if (($map ne '') && ($map eq $sloturl)) { + $exclude = 0; + last; + } + } + } + } + next if ($exclude); + } + } + } + push(@available,$slot); + } + } + $output .= &show_choices($symb,$formname,$formnum,$class, + $slots,$consumed_uniqueperiods, + \@available,\@got_slots); + } + } + return $output; +} + +sub show_reservations { + my ($r,$uname,$udom) = @_; + if (!defined($uname)) { + $uname = $env{'user.name'}; + } + if (!defined($udom)) { + $udom = $env{'user.domain'}; + } + my $formname = 'slotlog'; + my ($cnum,$cdom)=&get_course(); + 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(''. + &mt('Return to slot list').'
'); + return; + } + my $formname = 'reservationslog'; + my ($cnum,$cdom)=&get_course(); + my %slotlog=&Apache::lonnet::dump('nohist_slotreservationslog',$cdom,$cnum); + if ((keys(%slotlog))[0]=~/^error\:/) { undef(%slotlog); } + + my (%log,@allsymbs); + if (keys(%slotlog)) { + foreach my $key (keys(%slotlog)) { + if (ref($slotlog{$key}) eq 'HASH') { + if (ref($slotlog{$key}{'logentry'}) eq 'HASH') { + if ($slotlog{$key}{'logentry'}{'slot'} eq $env{'form.slotname'}) { + $log{$key} = $slotlog{$key}; + if ($slotlog{$key}{'logentry'}{'symb'} ne '') { + push(@allsymbs,$slotlog{$key}{'logentry'}{'symb'}); + } + } + } + } + } + } + + $r->print(''. + ''. + &mt('Return to slot list').'
'); + return; +} + +sub get_resource_title { + my ($symb,$titles,$maptitles) = @_; + my $title; + if ((ref($titles) eq 'HASH') && (ref($maptitles) eq 'HASH')) { + if (defined($titles->{$symb})) { + $title = $titles->{$symb}; + } else { + $title = &Apache::lonnet::gettitle($symb); + my $maptitle; + my ($mapurl) = &Apache::lonnet::decode_symb($symb); + if (defined($maptitles->{$mapurl})) { + $maptitle = $maptitles->{$mapurl}; + } else { + if ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) { + $maptitle=&mt('Main Content'); + } else { + $maptitle=&Apache::lonnet::gettitle($mapurl); + } + $maptitles->{$mapurl} = $maptitle; + } + if ($maptitle ne '') { + $title .= ' '.&mt('(in [_1])',$maptitle); + } + $titles->{$symb} = $title; + } + } else { + $title = $symb; + } + return $title; +} + +sub reservationlog_contexts { + my ($crstype) = @_; + my %lt = &Apache::lonlocal::texthash ( + any => 'Any', + user => 'By student', + manage => 'Via Slot Manager', + parameter => 'Via Parameter Manager', + reserve => 'Made reservation', + release => 'Dropped reservation', + usermanage => 'By student', + ); + if ($crstype eq 'Community') { + $lt{'user'} = &mt('By member'); + $lt{'usermanage'} = $lt{'user'}; + } + return %lt; +} + +sub display_filter { + my ($formname,$cdom,$cnum,$curr,$version,$allsymbs) = @_; + my $nolink = 1; + my (%titles,%maptitles); + my $output = ''.
+ ''.&mt('Changes/page:').' '. + &Apache::lonmeta::selectbox('show',$curr->{'show'},undef, + (&mt('all'),5,10,20,50,100,1000,10000)). + ' | '; + my $startform = + &Apache::lonhtmlcommon::date_setter($formname,'log_start_date', + $curr->{'log_start_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + my $endform = + &Apache::lonhtmlcommon::date_setter($formname,'log_end_date', + $curr->{'log_end_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + my $crstype = &Apache::loncommon::course_type(); + my %lt = &reservationlog_contexts($crstype); + $output .= ' | '.&mt('Window during which changes occurred:').
+ '
| '; + if (ref($allsymbs) eq 'ARRAY') { + $output .= ' | '.&mt('Resource').' '. + ' | '.
+ &mt('Context:').' | ';
+ } else {
+ $output .= ''.&mt('Action').' '. + ' | ';
+ }
+ $output .= '
'. + &mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.' + ,'2.9.0'); + if ($version) { + $output .= ' '.&mt('This LON-CAPA server is version [_1]',$version); + } + $output .= '
'."\n"; - $result.=' '. - &mt('Specify a file containing the slot definitions.'). - ' |
'."\n";
- my $upfile_select=&Apache::loncommon::upfile_select_html();
- my $ignore=&mt('Ignore First Line');
- $result.=< - - -ENDUPFORM - $result.=' |
'.&mt('Created [quant,_1,slot]',$countdone)."\n".'
'); foreach my $error (@errors) { $r->print(''.$error.'
'."\n"); @@ -1648,6 +3146,32 @@ sub csv_upload_assign { return ''; } +sub slot_command_titles { + my %titles = ( + slotlog => 'Reservation Logs', + showslots => 'Manage Slots', + showresv => 'Reservation History', + manageresv => 'Manage Reservations', + uploadstart => 'Upload Slots File', + csvuploadmap => 'Upload Slots File', + csvuploadassign => 'Upload Slots File', + delete => 'Slot Deletion', + release => 'Reservation Result', + remove_reservation => 'Remove Registration', + get_reservation => 'Request Reservation', + ); + 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; @@ -1659,16 +3183,84 @@ sub handler { } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); - + + my %crumb_titles = &slot_command_titles(); + my $brcrum; + my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'}); my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'}); + my (%slots,$consumed_uniqueperiods); + if ($env{'form.command'} eq 'showslots') { + if (($vgr ne 'F') && ($mgr ne 'F')) { + $env{'form.command'} = 'manageresv'; + } + } elsif ($env{'form.command'} eq 'manageresv') { + if (($vgr eq 'F') || ($mgr eq 'F')) { + $env{'form.command'} = 'showslots'; + } + } my $title='Requesting Another Worktime'; - if ($env{'form.command'} =~ /^(showslots|uploadstart|csvuploadmap|csvuploadassign)$/ && $vgr eq 'F') { - $title = 'Managing Slots'; + if ($env{'form.command'} eq 'showresv') { + $title = 'Reservation History'; + if ($env{'form.origin'} eq 'aboutme') { + $brcrum =[{href=>"/adm/$env{'form.udom'}/$env{'form.uname'}/aboutme",text=>'Personal Information Page'}]; + } else { + $brcrum =[{href=>"/adm/slotrequest?command=manageresv",text=>'Manage Reservations'}]; + } + if (ref($brcrum) eq 'ARRAY') { + push(@{$brcrum},{href=>"/adm/slotrequest?command=showresv",text=>$title}); + } + } elsif (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) { + if ($env{'form.command'} eq 'manageresv') { + $title = 'Manage Reservations'; + $brcrum =[{href=>"/adm/slotrequest?command=manageresv",text=>$title}]; + } + my ($cnum,$cdom)=&get_course(); + %slots = &Apache::lonnet::get_course_slots($cnum,$cdom); + $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots); + } elsif ($vgr eq 'F') { + if ($env{'form.command'} =~ /^(slotlog|showslots|uploadstart|csvuploadmap|csvuploadassign|delete|release|remove_registration)$/) { + $brcrum =[{href=>"/adm/slotrequest?command=showslots", + text=>$crumb_titles{'showslots'}}]; + $title = 'Managing Slots'; + unless ($env{'form.command'} eq 'showslots') { + if (ref($brcrum) eq 'ARRAY') { + push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}}); + } + } + } + } elsif ($env{'form.command'} eq 'release') { + if ($env{'form.context'} eq 'usermanage') { + $brcrum =[{href=>"/adm/slotrequest?command=manageresv", + text=>$crumb_titles{'showslots'}}]; + $title = 'Manage Reservations'; + 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); - - if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') { + my ($symb,$js,$available,$allavailable,$got_slots); + $available = []; + if ($env{'form.requestattempt'}) { + $symb=&unescape($env{'form.symb'}); + @{$got_slots}=&check_for_reservation($symb,'allslots'); + } + if (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) { + $js = &reservation_js(\%slots,$consumed_uniqueperiods,$available,$got_slots,$symb); + } + &start_page($r,$title,$brcrum,$js); + + if ($env{'form.command'} eq 'manageresv') { + $allavailable = $available; + undef($available); + undef($got_slots); + my $crstype = &Apache::loncommon::course_type(); + &manage_reservations($r,$crstype,\%slots,$consumed_uniqueperiods,$allavailable); + } elsif ($env{'form.command'} eq 'showresv') { + &show_reservations($r,$env{'form.uname'},$env{'form.udom'}); + } elsif ($env{'form.command'} eq 'showslots' && $vgr eq 'F') { &show_table($r,$mgr); } elsif ($env{'form.command'} eq 'remove_registration' && $mgr eq 'F') { &remove_registration($r); @@ -1695,6 +3287,8 @@ sub handler { } &csv_upload_map($r); } + } elsif (($env{'form.command'} eq 'slotlog') && ($vgr eq 'F')) { + &show_reservations_log($r); } else { my $symb=&unescape($env{'form.symb'}); if (!defined($symb)) { @@ -1715,18 +3309,40 @@ 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; } if ($env{'form.requestattempt'}) { - &show_choices($r,$symb); + $r->print('