--- loncom/interface/slotrequest.pm 2005/06/04 08:17:06 1.4 +++ loncom/interface/slotrequest.pm 2005/08/15 19:55:37 1.9 @@ -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.4 2005/06/04 08:17:06 albertel Exp $ +# $Id: slotrequest.pm,v 1.9 2005/08/15 19:55:37 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -38,9 +38,14 @@ use Apache::lonnet; 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>'.$env{'form.symb'}); + $r->print('<p>'.&mt('Unable to understand what resource you wanted to sign up for.').'</p>'); + } elsif ($code eq 'not_allowed') { + $r->print('<p>'.&mt('Not allowed to sign up or change reservations at this time.').'</p>'); + } else { + $r->print('<p>'.&mt('Failed.').'</p>'); } + $r->print('<p><a href="/adm/flip?postdata=return:">'. &mt('Return to last resource').'</a></p>'); &end_page($r); @@ -125,17 +130,38 @@ sub check_for_reservation { &Apache::lonxml::debug(time." $slot_name ". $slots{$slot_name}->{'starttime'}." -- ". $slots{$slot_name}->{'startreserve'}); - if ($slots{$slot_name}->{'starttime'} > time && + if ($slots{$slot_name}->{'endtime'} > time && $slots{$slot_name}->{'startreserve'} < time) { - # between start of reservation times and start of slot + # between start of reservation times and end of slot return($slot_name, $slots{$slot_name}); } } return (undef,undef); } -# FIXME - depends on the parameter for the resource to be correct -# tho prevent multiple reservations +sub check_for_conflict { + my ($symb,$new_slot_name)=@_; + 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)); + my ($cnum,$cdom)=&get_course(); + my %slots=&Apache::lonnet::get('slots', [@slots], $cdom, $cnum); + foreach my $slot_name (@slots) { + next if (!defined($slots{$slot_name}) || + !ref($slots{$slot_name})); + + next if (!defined($slots{$slot_name}->{'uniqueperiod'}) || + !ref($slots{$slot_name}->{'uniqueperiod'})); + my ($start,$end)=@{$slots{$slot_name}->{'uniqueperiod'}}; + if ($start<time && time < $end) { + return $slot_name; + } + } + return undef; + +} sub make_reservation { my ($slot_name,$slot,$symb)=@_; @@ -165,7 +191,6 @@ sub make_reservation { my (@ids)=&get_reservation_ids($slot_name); - # FIXME we could end up having holes... my $last=0; foreach my $id (@ids) { my $num=(split('\0',$id))[1]; @@ -174,9 +199,9 @@ sub make_reservation { my $wanted=$last+1; &Apache::lonxml::debug("wanted $wanted<br />"); - if ($wanted >= $max) { + if (scalar(@ids) >= $max) { # full up - return -1; + return undef; } my %reservation=('name' => $env{'user.name'}.'@'.$env{'user.domain'}, @@ -189,7 +214,6 @@ sub make_reservation { $cdom, $cnum); if ($success eq 'ok') { - #FIXME need to set the parm my $new_value=$slot_name; if ($value) { $new_value=$value.':'.$new_value; @@ -207,26 +231,104 @@ sub make_reservation { return undef; } +sub release_slot { + my ($r,$symb,$slot_name,$inhibit_return_link)=@_; + + if ($slot_name eq '') { $slot_name=$env{'form.slotname'}; } + my ($cnum,$cdom)=&get_course(); + + # get parameter string, check for existance, rebuild string with the slot + + my @slots = split(/:/,&Apache::lonnet::EXT("resource.0.availablestudent", + $symb,$env{'user.domain'}, + $env{'user.name'})); + my @new_slots; + foreach my $exist_slot (@slots) { + if ($exist_slot eq $slot_name) { next; } + push(@new_slots,$exist_slot); + } + my $new_param = join(':',@new_slots); + + # get slot reservations, check if user has one, if so remove reservation + my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum, + "^$slot_name\0"); + foreach my $entry (keys(%consumed)) { + if ( $consumed{$entry}->{'name'} eq + ($env{'user.name'}.'@'.$env{'user.domain'}) ) { + &Apache::lonnet::del('slot_reservations',[$entry], + $cdom,$cnum); + } + } + # store new parameter string + my $result=&Apache::lonparmset::storeparm_by_symb($symb, + '0_availablestudent', + 1, $new_param, 'string', + $env{'user.name'}, + $env{'user.domain'}); + my %slot=&Apache::lonnet::get_slot($slot_name); + my $description=&get_description($env{'form.slotname'},\%slot); + $r->print("<p>Released Reservation: $description</p>"); + if (!$inhibit_return_link) { + $r->print('<p><a href="/adm/flip?postdata=return:">'. + &mt('Return to last resource').'</a></p>'); + } + return 1; +} + sub get_slot { my ($r,$symb)=@_; + my $slot_name=&check_for_conflict($symb,$env{'form.slotname'}); + if ($slot_name) { + my %slot=&Apache::lonnet::get_slot($slot_name); + 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>Already have a reservation: $description1</p>"); + if ($slot_name ne $env{'form.slotname'}) { + $r->print(<<STUFF); +<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" /> + <input type="hidden" name="command" value="change" /> +STUFF + $r->print("<p>You can either "); + $r->print(<<STUFF); + <input type="submit" name="change" value="Change" /> +STUFF + $r->print(' your reservation from <b>'.$description1.'</b> to <b>'. + $description2. + '</b> <br />or <a href="/adm/flip?postdata=return:">'. + &mt('Return to last resource').'</a></p>'); + $r->print(<<STUFF); +</form> +STUFF + } else { + $r->print('<p><a href="/adm/flip?postdata=return:">'. + &mt('Return to last resource').'</a></p>'); + } + return; + } my %slot=&Apache::lonnet::get_slot($env{'form.slotname'}); my $reserved=&make_reservation($env{'form.slotname'}, \%slot,$symb); my $description=&get_description($env{'form.slotname'},\%slot); - if ($reserved > -1) { - $r->print("<p>Success: $description</p>"); - $r->print('<p><a href="/adm/flip?postdata=return:">'. - &mt('Return to last resource').'</a></p>'); - return; - } elsif ($reserved < 0) { - $r->print("<p>Already reserved: $description</p>"); - $r->print('<p><a href="/adm/flip?postdata=return:">'. - &mt('Return to last resource').'</a></p>'); - return; + if (defined($reserved)) { + if ($reserved > -1) { + $r->print("<p>Success: $description</p>"); + $r->print('<p><a href="/adm/flip?postdata=return:">'. + &mt('Return to last resource').'</a></p>'); + return; + } elsif ($reserved < 0) { + $r->print("<p>Already reserved: $description</p>"); + $r->print('<p><a href="/adm/flip?postdata=return:">'. + &mt('Return to last resource').'</a></p>'); + return; + } } - my %lt=('request'=>"Request another attempt", + my %lt=('request'=>"Availibility list", 'try' =>'Try again'); %lt=&Apache::lonlocal::texthash(%lt); @@ -259,26 +361,27 @@ sub allowed_slot { my ($slot_name,$slot,$symb)=@_; #already started if ($slot->{'starttime'} < time) { - return 0; + # all open slot to be schedulable + #return 0; } - + &Apache::lonxml::debug("$slot_name starttime good"); #already ended if ($slot->{'endtime'} < time) { return 0; } - + &Apache::lonxml::debug("$slot_name endtime good"); # not allowed to pick this one if (defined($slot->{'type'}) && $slot->{'type'} ne 'schedulable_student') { return 0; } - + &Apache::lonxml::debug("$slot_name type good"); # not allowed for this resource if (defined($slot->{'symb'}) && $slot->{'symb'} ne $symb) { return 0; } - + &Apache::lonxml::debug("$slot_name symb good"); return 1; } @@ -300,10 +403,13 @@ sub show_choices { my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); my $available; $r->print('<table border="1">'); + &Apache::lonxml::debug("Checking Slots"); + my ($got_slot)=&check_for_reservation($symb); foreach my $slot (sort { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} } (keys(%slots))) { - + + &Apache::lonxml::debug("Checking Slot $slot"); next if (!&allowed_slot($slot,$slots{$slot})); $available++; @@ -311,14 +417,21 @@ sub show_choices { my $description=&get_description($slot,$slots{$slot}); my $form=&mt('Unavailable'); - if (&space_available($slot,$slots{$slot},$symb)) { + if (($slot eq $got_slot) || + &space_available($slot,$slots{$slot},$symb)) { + my $text=&mt('Select'); + my $command='get'; + if ($slot eq $got_slot) { + $text=&mt('Free Reservation'); + $command='release'; + } my $escsymb=&Apache::lonnet::escape($symb); $form=<<STUFF; <form method="POST" action="/adm/slotrequest"> - <input type="submit" name="Select" value="Select" /> + <input type="submit" name="Select" value="$text" /> <input type="hidden" name="symb" value="$escsymb" /> <input type="hidden" name="slotname" value="$slot" /> - <input type="hidden" name="command" value="get" /> + <input type="hidden" name="command" value="$command" /> </form> STUFF } @@ -331,15 +444,54 @@ STUFF } if (!$available) { - $r->print('<tr><td>No avaliable times. <a href="/adm/flip?postdata=return:">'. + $r->print('<tr><td>No available times. <a href="/adm/flip?postdata=return:">'. &mt('Return to last resource').'</a></td></tr>'); } $r->print('</table>'); } +sub show_table { + my ($r,$symb)=@_; + + my ($cnum,$cdom)=&get_course(); + my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); + my $available; + $r->print('<table border="1">'); + foreach my $slot (sort + { return $slots{$a}->{'starttime'} <=> $slots{$b}->{'starttime'} } + (keys(%slots))) { + if (defined($slots{$slot}->{'type'}) + && $slots{$slot}->{'type'} ne 'schedulable_student') { + next; + } + my $description=&get_description($slot,$slots{$slot}); + my %consumed=&Apache::lonnet::dump('slot_reservations',$cdom,$cnum, + "^$slot\0"); + my $ids; + foreach my $entry (sort(keys(%consumed))) { + my (undef,$id)=split("\0",$entry); + $ids.= $id.'-> '.$consumed{$entry}->{'name'}.'<br />'; + } + my $start=localtime($slots{$slot}->{'starttime'}); + my $end=localtime($slots{$slot}->{'endtime'}); + $r->print(<<STUFF); +<tr> + <td>$slot</td> + <td>$description</td> + <td>$start</td> + <td>$end</td> + <td>$slots{$slot}->{'maxspace'}</td> + <td>$ids</td> +</tr> +STUFF + } + $r->print('</table>'); +} + sub handler { my $r=shift; + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}); &start_page($r); my $symb=&Apache::lonnet::unescape($env{'form.symb'}); my (undef,undef,$res)=&Apache::lonnet::decode_symb($symb); @@ -347,11 +499,28 @@ sub handler { &fail($r,'not_valid'); return OK; } - - if ($env{'form.requestattempt'}) { + $env{'request.symb'}=$symb; + my ($status) = &Apache::lonhomework::check_task_access('0'); + if ($status eq 'CAN_ANSWER' || + $status eq 'NEEDS_CHECKIN' || + $status eq 'WAITING_FOR_GRADE') { + &fail($r,'not_allowed'); + return OK; + } + my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'}); + if ($env{'form.command'} eq 'showslots' && $vgr eq 'F') { + &show_table($r,$symb); + } elsif ($env{'form.requestattempt'}) { &show_choices($r,$symb); + } elsif ($env{'form.command'} eq 'release') { + &release_slot($r,$symb); } elsif ($env{'form.command'} eq 'get') { &get_slot($r,$symb); + } elsif ($env{'form.command'} eq 'change') { + &release_slot($r,$symb,$env{'form.releaseslot'},1); + &get_slot($r,$symb); + } else { + $r->print("<p>Unknown command: ".$env{'form.command'}."</p>"); } &end_page($r); return OK;