Diff for /loncom/interface/lonrequestcourse.pm between versions 1.67 and 1.73

version 1.67, 2013/05/11 21:10:31 version 1.73, 2014/01/03 18:39:51
Line 128  sub handler { Line 128  sub handler {
     }      }
   
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
         ['action','showdom','cnum','state','crstype','queue']);          ['action','showdom','cnum','state','crstype','queue','tabs']);
     &Apache::lonhtmlcommon::clear_breadcrumbs();      &Apache::lonhtmlcommon::clear_breadcrumbs();
     my $dom = &get_course_dom();      my $dom = &get_course_dom();
     my $action = $env{'form.action'};      my $action = $env{'form.action'};
     my $state = $env{'form.state'};      my $state = $env{'form.state'};
     my (%states,%stored);      my (%states,%stored);
     my ($jscript,$uname,$udom,$result,$warning,$showcredits,$instcredits);      my ($jscript,$uname,$udom,$result,$warning,$showcredits,$instcredits,%can_request,
           %request_domains,@incdoms);
     my %domdefs = &Apache::lonnet::get_domain_defaults($dom);      my %domdefs = &Apache::lonnet::get_domain_defaults($dom);
     if ($domdefs{'officialcredits'} || $domdefs{'unofficialcredits'}) {      if ($domdefs{'officialcredits'} || $domdefs{'unofficialcredits'} || $domdefs{'textbookcredits'}) {
         $showcredits = 1;          $showcredits = 1;
     }      }
   
       my $canreq =
           &Apache::lonnet::check_can_request($dom,\%can_request,\%request_domains);
   
       foreach my $item (keys(%request_domains)) {
           if (ref($request_domains{$item}) eq 'ARRAY') {
               foreach my $possdom (@{$request_domains{$item}}) {
                   unless(grep(/^\Q$possdom\E$/,@incdoms)) {
                       push(@incdoms,$possdom);
                   }
               }
           }
       }
   
       if ($canreq) {
           if (($env{'form.crstype'} eq 'textbook') || 
               (scalar(keys(%can_request)) == 1) && ($can_request{'textbook'})) {
               my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom);
               if ($action eq 'log') {
                   my $usetabs;
                   if ((scalar(keys(%can_request)) == 1) && ($can_request{'textbook'})) {
                       $usetabs = 1;
                   } elsif ($env{'form.tabs'} eq 'on') {
                       $usetabs = 1;
                   }
                   &Apache::lonhtmlcommon::add_breadcrumb({text=>'Course Request'});
                   my $crumb = &Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests');
                   &print_request_logs($r,$dom,undef,undef,$crumb,$usetabs);
               } elsif ($action eq 'process') {
                   if ($can_request{'textbook'}) {
                       &process_textbook_request($r,$dom,$action,\%domdefs,\%domconfig,\%can_request);
                   } else {
                       &textbook_request_disabled($r,$dom,\%can_request);
                   }
               } else {
                   if ($can_request{'textbook'}) {
                       &print_textbook_form($r,$dom,\@incdoms,\%domdefs,$domconfig{'requestcourses'},\%can_request);
                   } else {
                       &textbook_request_disabled($r,$dom,\%can_request);
                   }
               }
               return OK;
           }
       }
   
     $states{'display'} = ['details'];      $states{'display'} = ['details'];
     $states{'view'} = ['pick_request','details','cancel','removal'];      $states{'view'} = ['pick_request','details','cancel','removal'];
     $states{'log'} = ['display'];      $states{'log'} = ['display'];
Line 165  sub handler { Line 210  sub handler {
   
     my @invalidcrosslist;      my @invalidcrosslist;
     my %trail = (      my %trail = (
                  crstype       => 'Request Action',                   crstype       => 'Pick Action',
                  codepick      => 'Category',                   codepick      => 'Category',
                  courseinfo    => 'Description',                   courseinfo    => 'Description',
                  enrollment    => 'Access Dates',                   enrollment    => 'Access Dates',
Line 299  sub handler { Line 344  sub handler {
   
     my $loaditems = &onload_action($action,$state);      my $loaditems = &onload_action($action,$state);
   
     my (%can_request,%request_domains);  
     my $canreq =   
         &Apache::lonnet::check_can_request($dom,\%can_request,\%request_domains);  
     if ($action eq 'new') {      if ($action eq 'new') {
         if ($canreq) {          if ($canreq) {
             if ($state eq 'crstype') {              if ($state eq 'crstype') {
                 &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems,                  &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems,
                                  $crumb,\%request_domains);                                   $crumb,\@incdoms);
             } else {              } else {
                 &request_administration($r,$action,$state,$page,\%states,$dom,                  &request_administration($r,$action,$state,$page,\%states,$dom,
                                         $jscript,$loaditems,$crumb,$newinstcode,                                          $jscript,$loaditems,$crumb,$newinstcode,
Line 321  sub handler { Line 363  sub handler {
         }          }
     } elsif ($action eq 'view') {      } elsif ($action eq 'view') {
         if ($state eq 'crstype') {          if ($state eq 'crstype') {
             &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems,$crumb,\%request_domains);              &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems,$crumb,\@incdoms);
         } else {          } else {
             &request_administration($r,$action,$state,$page,\%states,$dom,$jscript,              &request_administration($r,$action,$state,$page,\%states,$dom,$jscript,
                                     $loaditems,$crumb,'','','','',$showcredits);                                      $loaditems,$crumb,'','','','',$showcredits);
Line 340  sub handler { Line 382  sub handler {
         }          }
     } elsif ($action eq 'log') {      } elsif ($action eq 'log') {
         if ($state eq 'crstype') {          if ($state eq 'crstype') {
             &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb,\%request_domains);              &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb,\@incdoms);
         } else {          } else {
             $jscript .= <<ENDJS;              $jscript .= <<ENDJS;
   
Line 355  function setPage(formname) { Line 397  function setPage(formname) {
 }  }
   
 ENDJS  ENDJS
             &print_request_logs($r,$dom,$jscript,$loaditems,$crumb);              &print_request_logs($r,$dom,$jscript,$loaditems,$crumb,\%can_request);
         }          }
     } else {      } else {
         &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb,\%request_domains);          &print_main_menu($r,\%can_request,\%states,$dom,$jscript,'',$crumb,\@incdoms);
     }      }
     return OK;      return OK;
 }  }
Line 614  sub form_elements { Line 656  sub form_elements {
             if ($showcredits && $instcredits eq '') {              if ($showcredits && $instcredits eq '') {
                 $extras{'coursecredits'} = 'text';                  $extras{'coursecredits'} = 'text';
             }              }
         } elsif ($env{'form.crstype'} eq 'unofficial') {          } elsif (($env{'form.crstype'} eq 'unofficial') || ($env{'form.crstype'} eq 'textbook')) {
             if ($showcredits) {              if ($showcredits) {
                 $extras{'coursecredits'} = 'text';                  $extras{'coursecredits'} = 'text';
             }              }
Line 683  sub onload_action { Line 725  sub onload_action {
 }  }
   
 sub print_main_menu {  sub print_main_menu {
     my ($r,$can_request,$states,$dom,$jscript,$loaditems,$crumb,$request_domains) = @_;      my ($r,$can_request,$states,$dom,$jscript,$loaditems,$crumb,$incdoms) = @_;
     my ($types,$typename) = &Apache::loncommon::course_types();      my ($types,$typename) = &Apache::loncommon::course_types();
     my $onchange = 'this.form.submit()';      my $onchange = 'this.form.submit()';
     my $nextstate_setter = "\n";      my $nextstate_setter = "\n";
Line 721  $nextstate_setter Line 763  $nextstate_setter
 function check_can_request(crschoice,actionchoice) {  function check_can_request(crschoice,actionchoice) {
     var official = '';      var official = '';
     var unofficial = '';      var unofficial = '';
     var community = '';          var community = '';
       var textbook = '';
 END  END
     if (ref($can_request) eq 'HASH') {      if (ref($can_request) eq 'HASH') {
         foreach my $item (keys(%{$can_request})) {          foreach my $item (keys(%{$can_request})) {
Line 733  END Line 776  END
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
         official => 'You are not permitted to request creation of an official course in this domain.',          official => 'You are not permitted to request creation of an official course in this domain.',
         unofficial => 'You are not permitted to request creation of an unofficial course in this domain.',          unofficial => 'You are not permitted to request creation of an unofficial course in this domain.',
         community => 'You are not permitted to request creation of a community this domain.',          community => 'You are not permitted to request creation of a community in this domain.',
           textbook => 'You are not permitted to request creation of a textbook course in this domain',
         all => 'You must choose a specific course type when making a new course request.',          all => 'You must choose a specific course type when making a new course request.',
         allt => '"All types" is not allowed.',          allt => '"All types" is not allowed.',
     );       ); 
Line 756  END Line 800  END
                     return false;                      return false;
                 }                  }
             } else {              } else {
                 if (actionchoice == 'new') {                  if (crschoice == 'textbook') {
                     alert('$lt{'all'}'+'\\n'+'$lt{'allt'}');                      if (textbook != 1) {
                     return false;                          alert("$lt{'community'}");
                 }                                         return false;
                       }
                   } else {
                       if (actionchoice == 'new') {
                           alert('$lt{'all'}'+'\\n'+'$lt{'allt'}');
                           return false;
                       }
                   }
             }              }
         }          }
     }      }
Line 768  END Line 819  END
 END  END
     my ($pagetitle,$pageinfo,$domaintitle);      my ($pagetitle,$pageinfo,$domaintitle);
     if (ref($can_request) eq 'HASH') {      if (ref($can_request) eq 'HASH') {
         if (($can_request->{'official'}) || ($can_request->{'unofficial'})) {          if (($can_request->{'official'}) || ($can_request->{'unofficial'}) || $can_request->{'textbook'}) {
             if ($can_request->{'community'}) {              if ($can_request->{'community'}) {
                 $pagetitle = 'Course/Community Requests';                  $pagetitle = 'Course/Community Requests';
                 $pageinfo = &mt('Request creation of a new course or community, or review your pending requests.');                  $pageinfo = &mt('Request creation of a new course or community, or review your pending requests.');
Line 788  END Line 839  END
             $domaintitle = &mt('Course/Community Domain');              $domaintitle = &mt('Course/Community Domain');
         }          }
     }      }
     my @incdoms;  
     if (ref($request_domains) eq 'HASH') {  
         foreach my $item (keys(%{$request_domains})) {  
             if (ref($request_domains->{$item}) eq 'ARRAY') {  
                 foreach my $possdom (@{$request_domains->{$item}}) {  
                     unless(grep(/^\Q$possdom\E$/,@incdoms)) {  
                         push(@incdoms,$possdom);  
                     }   
                 }   
             }  
         }  
     }  
     $r->print(&header($pagetitle,$js.$jscript,$loaditems).$crumb.      $r->print(&header($pagetitle,$js.$jscript,$loaditems).$crumb.
              '<p>'.$pageinfo.'</p>'.               '<p>'.$pageinfo.'</p>'.
              '<div>'.               '<div>'.
               &Apache::lonhtmlcommon::start_pick_box().                &Apache::lonhtmlcommon::start_pick_box().
               &Apache::lonhtmlcommon::row_title($domaintitle).                &Apache::lonhtmlcommon::row_title($domaintitle).
               '<form name="domforcourse" method="post" action="/adm/requestcourse">'.                '<form name="domforcourse" method="post" action="/adm/requestcourse">'.
               &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange,\@incdoms));                &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange,$incdoms));
     if (!$onchange) {      if (!$onchange) {
         $r->print('&nbsp;<input type="submit" name="godom" value="'.          $r->print('&nbsp;<input type="submit" name="godom" value="'.
                    &mt('Change').'" />');                     &mt('Change').'" />');
     }      }
     unless ((ref($can_request) eq 'HASH') && (keys(%{$can_request}) > 0)) {      unless ((ref($can_request) eq 'HASH') && (keys(%{$can_request}) > 0)) {
         $r->print(&Apache::lonhtmlcommon::row_closure(1)."\n".          $r->print('</form>'.&Apache::lonhtmlcommon::row_closure(1)."\n".
                   &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n".                    &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n".
                   &Apache::loncommon::end_page());                    &Apache::loncommon::end_page());
         return;          return;
Line 945  END Line 984  END
                 $title = &mt('Pending requests for official courses');                  $title = &mt('Pending requests for official courses');
             } elsif ($env{'form.crstype'} eq 'unofficial') {              } elsif ($env{'form.crstype'} eq 'unofficial') {
                 $title = &mt('Pending requests for unofficial courses');                  $title = &mt('Pending requests for unofficial courses');
               } elsif ($env{'form.crstype'} eq 'textbook') {
                   $title = &mt('Pending requests for textbook courses');
             } else {              } else {
                 $title = &mt('Pending course/community requests');                   $title = &mt('Pending course/community requests'); 
             }              }
Line 1457  sub print_request_form { Line 1498  sub print_request_form {
         }          }
         $r->print(&print_review($dom,\@codetitles,\%cat_titles,\%cat_order,\@code_order,'','',\@disallowed,\%disallowmsg,$instcredits).          $r->print(&print_review($dom,\@codetitles,\%cat_titles,\%cat_order,\@code_order,'','',\@disallowed,\%disallowmsg,$instcredits).
                   '<input type="hidden" name="cnum" value="'.$cnum.'" />');                    '<input type="hidden" name="cnum" value="'.$cnum.'" />');
           my $fullname = &Apache::loncommon::plainname($env{'user.name'},
                                                        $env{'user.domain'});
           my $postprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,'review',$env{'user.name'},
                                                                 $env{'user.domain'},$fullname,$env{'form.cdescr'});
           if (ref($postprocess) eq 'HASH') {
               if ($postprocess->{'reviewweb'}) {
                   $r->print($postprocess->{'reviewweb'});
               }
           }
         if ($crstype eq 'community') {          if ($crstype eq 'community') {
             $navtxt{'next'} = &mt('Submit community request');              $navtxt{'next'} = &mt('Submit community request');
         } else {          } else {
Line 1477  sub print_request_form { Line 1527  sub print_request_form {
                           '<a href="/adm/requestcourse">'.&mt('Make another request').'</a></p>');                            '<a href="/adm/requestcourse">'.&mt('Make another request').'</a></p>');
             }              }
             if (&Apache::loncoursequeueadmin::author_prompt()) {              if (&Apache::loncoursequeueadmin::author_prompt()) {
                 $r->print('<h3>'.&mt('Access to authoring space').'</h3>'.                  &print_author_prompt($r,$env{'form.action'},$env{'form.cnum'},$env{'form.showdom'},
                           '<p>'.                                       $env{'form.crstype'},$storeresult);
                           &mt('Although assessment items can be created directly inside a course, such items only use part of the assessment capabilities of LON-CAPA.').  
                           '<br />'.  
                           &mt('By contrast, items created in authoring space, then imported into a course, can use all of the features of the assessment engine.').'</p>'.  
                           '<p>'.&mt('Request authoring space access now?').  
                           '<span class="LC_nobreak">&nbsp;'.  
                           '<label><input type="radio" name="requestauthor" value="1" />'.&mt('Yes').'</label>'.  
                           ('&nbsp;'x2).  
                           '<label><input type="radio" name="requestauthor" value="0" checked="checked"/>'.&mt('No').'</label>'.  
                           '</span></p>'.  
                           '<input type="submit" name="newauthor" value="'.&mt('Submit authoring request').'" />'.  
                           '<input type="hidden" name="state" value="reqauthor" />'.  
                           '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'.  
                           '<input type="hidden" name="cnum" value="'.$env{'form.cnum'}.'" />'.  
                           '<input type="hidden" name="showdom" value="'.$env{'form.showdom'}.'" />'.  
                           '<input type="hidden" name="crstype" value="'.$env{'form.crstype'}.'" />'.  
                           '<input type="hidden" name="disposition" value="'.$storeresult.'" />'.  
                           '<br />');  
             } elsif ($storeresult eq 'created') {              } elsif ($storeresult eq 'created') {
                 $r->print('<p><a href="/adm/requestcourse">'.&mt('Make another request').'</a></p>');                  $r->print('<p><a href="/adm/requestcourse">'.&mt('Make another request').'</a></p>');
             }              }
Line 1580  sub print_request_form { Line 1613  sub print_request_form {
     return;      return;
 }  }
   
   sub print_author_prompt {
       my ($r,$action,$cnum,$showdom,$crstype,$storeresult) = @_;
       $r->print('<h3>'.&mt('Access to authoring space').'</h3>'.
                 '<p>'.
                 &mt('Although assessment items can be created directly inside a course, such items only use part of the assessment capabilities of LON-CAPA.').
                 '<br />'.
                 &mt('By contrast, items created in authoring space, then imported into a course, can use all of the features of the assessment engine.').'</p>'.
                 '<p>'.&mt('Request authoring space access now?').
                 '<span class="LC_nobreak">&nbsp;'.
                 '<label><input type="radio" name="requestauthor" value="1" />'.&mt('Yes').'</label>'.
                 ('&nbsp;'x2).
                 '<label><input type="radio" name="requestauthor" value="0" checked="checked"/>'.&mt('No').'</label>'.
                 '</span></p>'.
                 '<input type="submit" name="newauthor" value="'.&mt('Submit authoring request').'" />'.
                 '<input type="hidden" name="state" value="reqauthor" />'.
                 '<input type="hidden" name="action" value="'.$action.'" />'.
                 '<input type="hidden" name="cnum" value="'.$cnum.'" />'.
                 '<input type="hidden" name="showdom" value="'.$showdom.'" />'.
                 '<input type="hidden" name="crstype" value="'.$crstype.'" />'.
                 '<input type="hidden" name="disposition" value="'.$storeresult.'" />'.
                 '<br />');
   }    
   
 sub get_usertype {  sub get_usertype {
     my ($persondom,$personname,$curr_rules,$got_rules) = @_;      my ($persondom,$personname,$curr_rules,$got_rules) = @_;
     my ($rules,$ruleorder) =      my ($rules,$ruleorder) =
Line 1771  sub print_enrollment_menu { Line 1827  sub print_enrollment_menu {
                 $hascredits = 1;                  $hascredits = 1;
             }              }
         }          }
     } elsif ($env{'form.crstype'} eq 'unofficial') {      } elsif (($env{'form.crstype'} eq 'unofficial') || ($env{'form.crstype'} eq 'textbook')) {
         if ($showcredits) {          if ($showcredits) {
             $creditsrow = '<span class="LC_nobreak">'.              $creditsrow = '<span class="LC_nobreak">'.
                           '<input type="text" size="3" name="coursecredits"'.                            '<input type="text" size="3" name="coursecredits"'.
Line 1976  sub print_personnel_menu { Line 2032  sub print_personnel_menu {
             official => 'Requestor is automatically assigned Course Coordinator role.',              official => 'Requestor is automatically assigned Course Coordinator role.',
         );          );
         $lt{'unofficial'} = $lt{'official'};          $lt{'unofficial'} = $lt{'official'};
           $lt{'textbook'} = $lt{'textbook'};
         $output .= &Apache::lonhtmlcommon::row_headline().          $output .= &Apache::lonhtmlcommon::row_headline().
                   '<h3>'.&Apache::loncommon::help_open_topic('Course_Request_Personnel').'&nbsp;'.$lt{$crstype}.' '.&mt('Include other personnel?').'</h3>';                    '<h3>'.&Apache::loncommon::help_open_topic('Course_Request_Personnel').'&nbsp;'.$lt{$crstype}.' '.&mt('Include other personnel?').'</h3>';
     }      }
Line 2093  sub sorted_request_history { Line 2150  sub sorted_request_history {
             my $crstype = $history{'crstype'};              my $crstype = $history{'crstype'};
             my $disposition = $history{'disposition'};              my $disposition = $history{'disposition'};
             my $status = $history{'status'};              my $status = $history{'status'};
               my $uniquecode = $history{'code'}; 
             if ($action eq 'view') {              if ($action eq 'view') {
                 next if ((exists($history{'status'})) && ($history{'status'} eq 'created'));                  next if ((exists($history{'status'})) && ($history{'status'} eq 'created'));
             } else {              } else {
Line 2108  sub sorted_request_history { Line 2166  sub sorted_request_history {
                 $entry = $requestkey.':'.$crstype.':'.                  $entry = $requestkey.':'.$crstype.':'.
                          &escape($history{'details'}{'cdescr'});                           &escape($history{'details'}{'cdescr'});
                 if ($action eq 'log') {                  if ($action eq 'log') {
                     $entry .= ':'.$lastupdate.':';                      $entry .= ':'.$uniquecode.':'.$lastupdate.':';
                     if ($statusinfo{$key} ne '') {                      if ($statusinfo{$key} ne '') {
                         $entry .= $statusinfo{$key};                          $entry .= $statusinfo{$key};
                     } elsif ($status ne '') {                      } elsif ($status ne '') {
Line 2306  ENDJS Line 2364  ENDJS
 }  }
   
 sub viewcancel_javascript {  sub viewcancel_javascript {
     my $alert = &mt('Are you sure you want to cancel this request?\\n'.      my $alert = &mt('Are you sure you want to cancel this request?').'\\n'.
                     'Your request will be removed.');                  &mt('Your request will be removed.');
     return << "ENDJS";      return << "ENDJS";
 function nextPage(formname,nextstate) {  function nextPage(formname,nextstate) {
     if (confirm('$alert')) {      if (confirm('$alert')) {
Line 2321  ENDJS Line 2379  ENDJS
 }  }
   
 sub print_request_logs {  sub print_request_logs {
     my ($r,$dom,$jscript,$loaditems,$crumb) = @_;      my ($r,$dom,$jscript,$loaditems,$crumb,$usetabs) = @_;
     my $title;      my $title;
     if ($env{'form.crstype'} eq 'community') {      if ($env{'form.crstype'} eq 'community') {
         $title = 'Community Request Logs';          $title = 'Community Request Logs';
Line 2331  sub print_request_logs { Line 2389  sub print_request_logs {
         $title = 'Course Request Logs';          $title = 'Course Request Logs';
     }      }
     $r->print(&header($title,$jscript,$loaditems).$crumb);      $r->print(&header($title,$jscript,$loaditems).$crumb);
       if ($usetabs) {
           &startContentScreen($r,'textbooklogs');
       }
     my $formname = 'requestcrs';      my $formname = 'requestcrs';
     $r->print('<form action="/adm/requestcourse" method="post" name="'.$formname.'" onsubmit="javascript:setPage(this);">'."\n".      $r->print('<form action="/adm/requestcourse" method="post" name="'.$formname.'" onsubmit="javascript:setPage(this);">'."\n".
               '<input type="hidden" name="action" value="log" />'."\n".                '<input type="hidden" name="action" value="log" />'."\n".
Line 2375  sub print_request_logs { Line 2436  sub print_request_logs {
     if (($curr{'crstype'} eq 'official') || ($curr{'crstype'} eq 'any')) {      if (($curr{'crstype'} eq 'official') || ($curr{'crstype'} eq 'any')) {
         $tablehdr .= '<th>'.&mt('Institutional Code').'</th>';          $tablehdr .= '<th>'.&mt('Institutional Code').'</th>';
     }      }
       my $showuniquecode;
       my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom);
       if (($curr{'status'} eq 'any') || ($curr{'status'} eq 'created')) {
           if (ref($domconfig{'requestcourses'}) eq 'HASH') {
               if (ref($domconfig{'requestcourses'}{'uniquecode'}) eq 'HASH') {
                   if ($curr{'crstype'} eq 'any') {
                       my @types = qw(official unofficial community textbook);
                       foreach my $type (@types) {
                           if ($domconfig{'requestcourses'}{'uniquecode'}{$type}) {
                               $showuniquecode = 1;
                               last;
                           }
                       }
                   } elsif ($domconfig{'requestcourses'}{'uniquecode'}{$curr{'crstype'}}) {
                       $showuniquecode = 1;
                   }
               }
           }
       }
       if ($showuniquecode) {
           $tablehdr .= '<th>'.&mt('Unique Code').'</th>';    
       }
     if ($curr{'status'} eq 'any') {      if ($curr{'status'} eq 'any') {
         $tablehdr .= '<th>'.&mt('Status').'</th>';          $tablehdr .= '<th>'.&mt('Status').'</th>';
     } elsif ($curr{'status'} eq 'created') {      } elsif ($curr{'status'} eq 'created') {
Line 2412  sub print_request_logs { Line 2495  sub print_request_logs {
             my $showtime = &Apache::lonlocal::locallocaltime($item);              my $showtime = &Apache::lonlocal::locallocaltime($item);
             if (ref($queue_by_date{$item}) eq 'ARRAY') {              if (ref($queue_by_date{$item}) eq 'ARRAY') {
                 foreach my $request (sort(@{$queue_by_date{$item}})) {                  foreach my $request (sort(@{$queue_by_date{$item}})) {
                     my ($key,$crstype,$desc,$timestamp,$status,$instcode) = split(':',$request);                      my ($key,$crstype,$desc,$uniquecode,$timestamp,$status,$instcode) = split(':',$request);
                     my ($cdom,$cnum) = split('_',$key);                      my ($cdom,$cnum) = split('_',$key);
                     my $output = &Apache::loncommon::start_data_table_row().                      my $output = &Apache::loncommon::start_data_table_row().
      '<td>'.$count.'</td>'.       '<td>'.$count.'</td>'.
Line 2438  sub print_request_logs { Line 2521  sub print_request_logs {
                         }                          }
                         $output .= '<td>'.$showinstcode.'</td>';                          $output .= '<td>'.$showinstcode.'</td>';
                     }                      }
                       if ($showuniquecode) {
                           if ($status eq 'created') {
                               $output .= '<td>'.$uniquecode.'</td>';
                           } else {
                               $output .= '<td>'.&mt('Not applicable').'</td>';
                           }    
                       }
                     if ($curr{'status'} eq 'any') {                      if ($curr{'status'} eq 'any') {
                         my $statusname = &mt('Unknown status');                          my $statusname = &mt('Unknown status');
                         if (ref($statusnames) eq 'HASH') {                          if (ref($statusnames) eq 'HASH') {
Line 2498  ENDSCRIPT Line 2588  ENDSCRIPT
                   &mt('There are no records to display').                    &mt('There are no records to display').
                   '</p>');                    '</p>');
     }      }
     $r->print('</form>'.      if ($usetabs) {
               &Apache::loncommon::end_page());          $r->print('<input type="hidden" name="tabs" value="on" />');
       }
       $r->print('</form>');
       if ($usetabs) {
           &endContentScreen($r);
       }
       $r->print(&Apache::loncommon::end_page());
     return;      return;
 }  }
   
Line 2514  sub reqstatus_names { Line 2610  sub reqstatus_names {
                         rejected  => 'Request rejected',                          rejected  => 'Request rejected',
                         cancelled => 'Request cancelled',                          cancelled => 'Request cancelled',
             );              );
     if (($crstype eq 'official') || ($crstype eq 'unofficial')) {      if (($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'textbook')) {
         $statusnames{'created'} = &mt('Course created');          $statusnames{'created'} = &mt('Course created');
     } elsif ($crstype eq 'community') {      } elsif ($crstype eq 'community') {
         $statusnames{'created'} = &mt('Community created');          $statusnames{'created'} = &mt('Community created');
Line 2731  sub print_review { Line 2827  sub print_review {
             $section_values .= $xlistinfo;              $section_values .= $xlistinfo;
         }          }
         $section_values .= '</table></td>';          $section_values .= '</table></td>';
     } elsif ($env{'form.crstype'} eq 'unofficial') {      } elsif (($env{'form.crstype'} eq 'unofficial') || ($env{'form.crstype'} eq 'textbook')) {
         $inst_headers .= '<th>'.&mt('Credits').'</th>';          $inst_headers .= '<th>'.&mt('Credits').'</th>';
         $inst_values .= '<td>'.$env{'form.coursecredits'}.'</td>';          $inst_values .= '<td>'.$env{'form.coursecredits'}.'</td>';
     }      }
Line 2910  sub courseinfo_form { Line 3006  sub courseinfo_form {
                 community => 'You must provide a (brief) community description.'                  community => 'You must provide a (brief) community description.'
              );               );
     $lt{'unofficial'} = $lt{'official'};      $lt{'unofficial'} = $lt{'official'};
       $lt{'textbook'} = $lt{'official'};
     my $js_validate = <<"ENDJS";      my $js_validate = <<"ENDJS";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA['  // <![CDATA['
Line 3231  sub display_navbuttons { Line 3328  sub display_navbuttons {
 sub print_request_outcome {  sub print_request_outcome {
     my ($dom,$codetitles,$code_order,$instcredits) = @_;      my ($dom,$codetitles,$code_order,$instcredits) = @_;
     my ($output,$cnum,$now,$req_notifylist,$crstype,$enrollstart,$enrollend,      my ($output,$cnum,$now,$req_notifylist,$crstype,$enrollstart,$enrollend,
         %sections,%crosslistings,%personnel,@baduname,@missingdom,%domconfig);          %sections,%crosslistings,%personnel,@baduname,@missingdom,%domconfig,
           $uniquecode);
     my $sectotal = $env{'form.sectotal'};      my $sectotal = $env{'form.sectotal'};
     my $crosslisttotal = 0;      my $crosslisttotal = 0;
     $cnum = $env{'form.cnum'};      $cnum = $env{'form.cnum'};
Line 3239  sub print_request_outcome { Line 3337  sub print_request_outcome {
         $output = &mt('Invalid LON-CAPA course number for the new course')."\n";           $output = &mt('Invalid LON-CAPA course number for the new course')."\n"; 
         return $output;          return $output;
     }      }
       $crstype = $env{'form.crstype'};
     %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom);      my %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom);
     if (ref($domconfig{'requestcourses'}) eq 'HASH') {      if (ref($domconfig{'requestcourses'}) eq 'HASH') {
         if (ref($domconfig{'requestcourses'}{'notify'}) eq 'HASH') {          if (ref($domconfig{'requestcourses'}{'notify'}) eq 'HASH') {
             $req_notifylist = $domconfig{'requestcourses'}{'notify'}{'approval'};              $req_notifylist = $domconfig{'requestcourses'}{'notify'}{'approval'};
         }          }
           if (ref($domconfig{'requestcourses'}{'uniquecode'}) eq 'HASH') {
               $uniquecode = $domconfig{'requestcourses'}{'uniquecode'}{$crstype};
           }
     }      }
     $now = time;      $now = time;
     $crstype = $env{'form.crstype'};  
     my $ccrole = 'cc';      my $ccrole = 'cc';
     if ($crstype eq 'community') {      if ($crstype eq 'community') {
         $ccrole = 'co';          $ccrole = 'co';
Line 3454  sub print_request_outcome { Line 3554  sub print_request_outcome {
                     crstype        => $env{'form.crstype'},                      crstype        => $env{'form.crstype'},
                     instcode       => $instcode,                      instcode       => $instcode,
                     defaultcredits => $credits,                       defaultcredits => $credits, 
                       uniquecode     => $uniquecode,
                     clonedom       => $clonedom,                      clonedom       => $clonedom,
                     clonecrs       => $clonecrs,                      clonecrs       => $clonecrs,
                     datemode       => $env{'form.datemode'},                      datemode       => $env{'form.datemode'},
Line 3470  sub print_request_outcome { Line 3571  sub print_request_outcome {
                     accessend      => $accessend,                      accessend      => $accessend,
                     personnel      => \%personnel,                      personnel      => \%personnel,
                   };                    };
     my (@inststatuses,$storeresult,$creationresult);      my ($result,$output) = &process_request($dom,$cnum,$crstype,$now,$details,$instcode,
                                               $req_notifylist,\@instsections,\%domconfig);
       return ($result,$output);
   }
       
   sub process_request {
       my ($dom,$cnum,$crstype,$now,$details,$instcode,$req_notifylist,$instsections,$domconfig) = @_; 
       my (@inststatuses,$storeresult,$creationresult,$output);
     my $val =       my $val = 
         &Apache::loncoursequeueadmin::get_processtype('course',$env{'user.name'},          &Apache::loncoursequeueadmin::get_processtype('course',$env{'user.name'},
                                                       $env{'user.domain'},$env{'user.adv'},                                                        $env{'user.domain'},$env{'user.adv'},
                                                       $dom,$crstype,\@inststatuses,\%domconfig);                                                        $dom,$crstype,\@inststatuses,$domconfig);
     if ($val eq '') {      if ($val eq '') {
         if ($crstype eq 'official') {          if ($crstype eq 'official') {
             $output = &mt('You are not permitted to request creation of official courses.');              $output = &mt('You are not permitted to request creation of official courses.');
Line 3482  sub print_request_outcome { Line 3590  sub print_request_outcome {
             $output = &mt('You are not permitted to request creation of unofficial courses.');              $output = &mt('You are not permitted to request creation of unofficial courses.');
         } elsif ($crstype eq 'community') {          } elsif ($crstype eq 'community') {
             $output = &mt('You are not permitted to request creation of communities');              $output = &mt('You are not permitted to request creation of communities');
           } elsif ($crstype eq 'textbook') {
               $output = &mt('You are not permitted to request creation of textbook courses');
         } else {          } else {
             $output = &mt('Unrecognized course type: [_1]',$crstype);              $output = &mt('Unrecognized course type: [_1]',$crstype);
         }          }
Line 3507  sub print_request_outcome { Line 3617  sub print_request_outcome {
                 $inststatuslist = join(',',@inststatuses);                  $inststatuslist = join(',',@inststatuses);
             }              }
             my $instseclist;              my $instseclist;
             if (@instsections > 0) {              if (ref($instsections) eq 'ARRAY') {
                 $instseclist = join(',',@instsections);                  if (@{$instsections} > 0) {
                       $instseclist = join(',',@{$instsections});
                   }
             }              }
             $validationchk =               $validationchk = 
                 &Apache::lonnet::auto_courserequest_validation($dom,                  &Apache::lonnet::auto_courserequest_validation($dom,
Line 3530  sub print_request_outcome { Line 3642  sub print_request_outcome {
         }          }
         $reqhash{'disposition'} = $disposition;          $reqhash{'disposition'} = $disposition;
         $reqstatus = $disposition;          $reqstatus = $disposition;
         my ($modified,$queued);          my ($modified,$queued,$coursedesc,%customitems);
           unless ($disposition eq 'rejected') {
               if (ref($details) eq 'HASH') {
                   $coursedesc = $details->{'cdescr'};
               }
               my $fullname = &Apache::loncommon::plainname($env{'user.name'},
                                                            $env{'user.domain'});
               my $inprocess = &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,'process',$env{'user.name'},
                                                                   $env{'user.domain'},$fullname,$coursedesc);
               if (ref($inprocess) eq 'HASH') {
                   if (ref($inprocess->{'formitems'}) eq 'HASH') {
                       foreach my $key (keys(%{$inprocess->{'formitems'}})) {
                           if ($inprocess->{'formitems'}->{$key} eq 'multiple') {
                               if (exists($env{'form.'.$key})) {
                                   @{$customitems{$key}} = &Apache::loncommon::get_env_multiple($env{'form.'.$key});
                               }
                           } else {
                               if (exists($env{'form.'.$key})) {
                                   $customitems{$key} = $env{'form.'.$key};
                                   $reqhash{'custom'}{$key} = $customitems{$key};
                               }
                           }
                       }
                   }
               }
           }
         if ($disposition eq 'rejected') {          if ($disposition eq 'rejected') {
             if ($crstype eq 'community') {              if ($crstype eq 'community') {
                 $output = &mt('Your community request was rejected.');                  $output = &mt('Your community request was rejected.');
Line 3543  sub print_request_outcome { Line 3680  sub print_request_outcome {
             $storeresult = 'rejected';              $storeresult = 'rejected';
         } elsif ($disposition eq 'process') {          } elsif ($disposition eq 'process') {
             my %domdefs = &Apache::lonnet::get_domain_defaults($dom);              my %domdefs = &Apache::lonnet::get_domain_defaults($dom);
             my ($logmsg,$newusermsg,$addresult,$enrollcount,$response,$keysmsg,%longroles);              my ($logmsg,$newusermsg,$addresult,$enrollcount,$response,$keysmsg,%longroles,$code);
             my $type = 'Course';              my $type = 'Course';
             if ($crstype eq 'community') {              if ($crstype eq 'community') {
                 $type = 'Community';                  $type = 'Community';
Line 3552  sub print_request_outcome { Line 3689  sub print_request_outcome {
             foreach my $role (@roles) {              foreach my $role (@roles) {
                 $longroles{$role}=&Apache::lonnet::plaintext($role,$type);                  $longroles{$role}=&Apache::lonnet::plaintext($role,$type);
             }              }
             my $result = &Apache::loncoursequeueadmin::course_creation($dom,$cnum,              my ($result,$postprocess) = &Apache::loncoursequeueadmin::course_creation($dom,$cnum,
                                    'autocreate',$details,\$logmsg,\$newusermsg,\$addresult,                                            'autocreate',$details,\$logmsg,\$newusermsg,\$addresult,
                                    \$enrollcount,\$response,\$keysmsg,\%domdefs,\%longroles);                                            \$enrollcount,\$response,\$keysmsg,\%domdefs,\%longroles,
                                             \$code,\%customitems);
             if ($result eq 'created') {              if ($result eq 'created') {
                 $disposition = 'created';                  $disposition = 'created';
                 $reqstatus = 'created';                  $reqstatus = 'created';
Line 3565  sub print_request_outcome { Line 3703  sub print_request_outcome {
                 } else {                  } else {
                     $output = '<p>'.&mt('Your course request has been processed and the course has been created.');                      $output = '<p>'.&mt('Your course request has been processed and the course has been created.');
                 }                  }
                   if (($code) || ((ref($postprocess) eq 'HASH') && 
                                   (($postprocess->{'createdweb'}) || ($postprocess->{'createdmsg'})))) {
                       $output .= &notification_information($disposition,$env{'user.name'}.':'.$env{'user.domain'},
                                                            $cnum,$now,$code,$postprocess);
                   }
                   if ($code) {
                       $reqhash{'code'} = $code;
                   }
                 $output .= '<br />'.$role_result.'</p>';                  $output .= '<br />'.$role_result.'</p>';
                 $creationresult = 'created';                  $creationresult = 'created';
             } else {              } else {
Line 3581  sub print_request_outcome { Line 3727  sub print_request_outcome {
             }              }
         } else {          } else {
             my $requestid = $cnum.'_'.$disposition;              my $requestid = $cnum.'_'.$disposition;
             my $request = {               my $request = {
                             $requestid => {                              $requestid => {
                                             timestamp   => $now,                                              timestamp   => $now,
                                             crstype     => $crstype,                                              crstype     => $crstype,
Line 3637  sub print_request_outcome { Line 3783  sub print_request_outcome {
                 $output .= '<p>'.&mt('Your course request has been updated').'</p>';                  $output .= '<p>'.&mt('Your course request has been updated').'</p>';
             }              }
             $output .= &notification_information($disposition,$req_notifylist,$cnum,$now);              $output .= &notification_information($disposition,$req_notifylist,$cnum,$now);
               if ($disposition eq 'approval') {
                   my $fullname = &Apache::loncommon::plainname($env{'user.name'},
                                                                $env{'user.domain'});
                   my $postprocess = 
                       &Apache::lonnet::auto_crsreq_update($dom,$cnum,$crstype,'queued',$env{'user.name'},
                                                           $env{'user.domain'},$fullname,$env{'form.cdescr'});
                   if ((ref($postprocess) eq 'HASH') && 
                       ((ref($postprocess->{'queuedmsg'}) eq 'HASH') || ($postprocess->{'queuedweb'}))) { 
                       my $recipient = $env{'user.name'}.':'.$env{'user.domain'};
                       $output .= &notification_information($disposition,$recipient,$cnum,$now,undef,$postprocess);
                   }
               }
         }          }
         if ($validationerror ne '') {          if ($validationerror ne '') {
             $output .= '<p class="LC_warning">'.&mt('An error occurred validating your request with institutional data sources: [_1].',$validationerror).'</p>';              $output .= '<p class="LC_warning">'.&mt('An error occurred validating your request with institutional data sources: [_1].',$validationerror).'</p>';
Line 3788  sub update_requestors_roles { Line 3946  sub update_requestors_roles {
 }  }
   
 sub notification_information {  sub notification_information {
     my ($disposition,$req_notifylist,$cnum,$now) = @_;      my ($disposition,$req_notifylist,$cnum,$now,$code,$postprocess) = @_;
     my %emails = &Apache::loncommon::getemails();      my %emails = &Apache::loncommon::getemails();
     my $address;      my $address;
     if (($emails{'permanentemail'} ne '') || ($emails{'notification'} ne '')) {      if (($emails{'permanentemail'} ne '') || ($emails{'notification'} ne '')) {
Line 3806  sub notification_information { Line 3964  sub notification_information {
         }          }
         if ($req_notifylist) {          if ($req_notifylist) {
             my $fullname = &Apache::loncommon::plainname($env{'user.name'},              my $fullname = &Apache::loncommon::plainname($env{'user.name'},
                                                                      $env{'user.domain'});                                                           $env{'user.domain'});
             my $sender = $env{'user.name'}.':'.$env{'user.domain'};              my $sender = $env{'user.name'}.':'.$env{'user.domain'};
             &Apache::loncoursequeueadmin::send_selfserve_notification($req_notifylist,"$fullname ($env{'user.name'}:$env{'user.domain'})",$cnum,$env{'form.cdescr'},$now,'coursereq',$sender);              &Apache::loncoursequeueadmin::send_selfserve_notification($req_notifylist,"$fullname ($env{'user.name'}:$env{'user.domain'})",$cnum,$env{'form.cdescr'},$now,'coursereq',$sender);
         }          }
           if (ref($postprocess) eq 'HASH') {
               if (ref($postprocess->{'queuedmsg'}) eq 'ARRAY') {
                   if (scalar(@{$postprocess->{'queuedmsg'}}) > 0) {
                       my $recipient = $env{'user.name'}.':'.$env{'user.domain'};
                       my $sender = $recipient;
                       my $addmsg = [];
                       foreach my $item (@{$postprocess->{'queuedmsg'}}) {
                           if (ref($item) eq 'HASH') {
                               if ($item->{'mt'} ne '') {
                                   push(@{$addmsg},$item);
                               }
                           }
                       }
                       if (scalar(@{$addmsg}) > 0) {
                           &Apache::loncoursequeueadmin::send_selfserve_notification($recipient,$addmsg,$cnum,
                                                                                     $env{'form.cdescr'},$now,
                                                                                     'queuedreq',$sender);
                       }
                   }
               }
               if ($postprocess->{'queuedweb'}) {
                   $output .= $postprocess->{'queuedweb'};
               }
           }
     } elsif ($disposition eq 'pending') {      } elsif ($disposition eq 'pending') {
         $output .= '<div class="LC_info">'.          $output .= '<div class="LC_info">'.
 &mt('Your request has been placed in a queue pending administrative action.').'<br />'.  &mt('Your request has been placed in a queue pending administrative action.').'<br />'.
 &mt("Usually this means that your institution's information systems do not list you among the instructional personnel for this course.").'<br />'.  &mt("Usually this means that your institution's information systems do not list you among the instructional personnel for this course.").'<br />'.
 &mt('The list of instructional personnel for the course will be automatically checked daily, and once you are listed the request will be processed.').  &mt('The list of instructional personnel for the course will be automatically checked daily, and once you are listed the request will be processed.').
                    '</div>';                     '</div>';
       } elsif ($disposition eq 'created') {
           if (($code) || ((ref($postprocess) eq 'HASH') && 
               ((ref($postprocess->{'createdmsg'}) eq 'ARRAY') || ($postprocess->{'createdweb'})))) {
               my $addmsg = [];
               my $recipient = $env{'user.name'}.':'.$env{'user.domain'};
               my $sender = $recipient;
               if ($code) {
                   push(@{$addmsg},{
                                     mt   => 'Students can automatically select your course by entering this code: [_1]',
                                     args => [$code],
                                   });
                   $output .= '<p>'.
                              &mt('Students can automatically select your course by entering this code: [_1].','<b>'.$code.'</b>').
                              '<br />'.
                              &mt('A message has been sent to your LON-CAPA account with this information.');
                   if ($address ne '') {
                       $output.= '<br />'.&mt('An e-mail has also been sent to: [_1] with this code.',$address);
                   }
                   $output .= '</p>';
               }
               if (ref($postprocess) eq 'HASH') {
                   if (ref($postprocess->{'createdmsg'}) eq 'ARRAY') {
                       foreach my $item (@{$postprocess->{'createdmsg'}}) {
                           if (ref($item) eq 'HASH') {
                               if ($item->{'mt'} ne '') {  
                                   push(@{$addmsg},$item);
                               }
                           }
                       }
                   }
                   if ($postprocess->{'createdweb'}) {
                       $output .= $postprocess->{'createdweb'}
                   }
               }
               if (scalar(@{$addmsg}) > 0) {
                   my $type = 'createdreq';
                   if ($code) {
                       $type = 'uniquecode';
                   }
                   &Apache::loncoursequeueadmin::send_selfserve_notification($recipient,$addmsg,$cnum,$env{'form.cdescr'},
                                                                             $now,$type,$sender);
               }
           }
     } else {      } else {
         $output .= '<div class="LC_warning">'.          $output .= '<div class="LC_warning">'.
                    &mt('Your request status is: [_1].',$disposition).                     &mt('Your request status is: [_1].',$disposition).
Line 3838  sub check_autolimit { Line 4063  sub check_autolimit {
             if (($crstype eq 'community') &&               if (($crstype eq 'community') && 
                 (exists($crsroles{$cnum.':'.$cdom.':co'}))) {                  (exists($crsroles{$cnum.':'.$cdom.':co'}))) {
                 $count ++;                  $count ++;
             } elsif ((($crstype eq 'official') || ($crstype eq 'unofficial')) &&              } elsif ((($crstype eq 'official') || ($crstype eq 'unofficial') || ($crstype eq 'textbook')) &&
                      (exists($crsroles{$cnum.':'.$cdom.':cc'}))) {                       (exists($crsroles{$cnum.':'.$cdom.':cc'}))) {
                 $count ++;                  $count ++;
             }              }
Line 3907  sub retrieve_settings { Line 4132  sub retrieve_settings {
                         $env{'form.coursecredits'} = $reqinfo{'defaultcredits'};                          $env{'form.coursecredits'} = $reqinfo{'defaultcredits'};
                     }                      }
                 }                  }
             } elsif ($reqinfo{'crstype'} eq 'unofficial') {              } elsif (($reqinfo{'crstype'} eq 'unofficial') || ($reqinfo{'crstype'} eq 'textbook')) {
                 $env{'form.coursecredits'} = $reqinfo{'defaultcredits'};                  $env{'form.coursecredits'} = $reqinfo{'defaultcredits'};
             }              }
             my @currsec;              my @currsec;
Line 4039  sub generate_date_items { Line 4264  sub generate_date_items {
     return;      return;
 }  }
   
   sub print_textbook_form {
       my ($r,$dom,$incdoms,$domdefs,$settings,$can_request) = @_;
       my ($bookshash,%ordered);
       my $crstype = 'textbook';
   #
   #  Retrieve list of textbook courses cloneable by user
   #
       my $numbook;
       if (ref($settings) eq 'HASH') {
           $bookshash = $settings->{'textbooks'};
           if (ref($bookshash) eq 'HASH') {
               foreach my $item (keys(%{$bookshash})) {
                   my ($clonedom,$clonecrs) = split(/_/,$item);
                   if (ref($bookshash->{$item}) eq 'HASH') {
                       my ($clonedom,$clonecrs) = split(/_/,$item);
                       if (&Apache::loncoursequeueadmin::can_clone_course($env{'user.name'},
                                           $env{'user.domain'},$clonecrs,$clonedom,$crstype)) {
   
                           my $num = $bookshash->{$item}{'order'};
                           $ordered{$num} = $item;
                           $numbook ++;
                       }
                   }
               }
           }
       }
   
   #
   # Check if domain has multiple library servers
   #
       my ($home_server_pick,$numlib) =
           &Apache::loncommon::home_server_form_item($dom,'chome',
                                                     'default','hide');
       if ($numlib > 1) {
           $home_server_pick = &mt('Home Server for Course').': '.$home_server_pick.'<br />';
       }
   
   #
   # Retrieve information about courses owned by user, or in which user has an active or future 
   # Course Coordinator role 
   #
       my $numcurrent;
       my %cloneable = &Apache::lonnet::courseiddump($dom,'.',1,'.',$env{'user.name'}.':'.$env{'user.domain'},
                                                 undef,undef,undef,'Course');
       my %ccroles = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',
                                                   ['active','future'],['cc']);
       foreach my $role (keys(%ccroles)) {
           my ($cnum,$cdom,$rest) = split(/:/,$role,3);
           unless (exists($cloneable{$cdom.'_'.$cnum})) {
               my %courseinfo = &Apache::lonnet::coursedescription($cdom.'_'.$cnum,{'one_time' => 1});
               $cloneable{$cdom.'_'.$cnum} = \%courseinfo;
           }
       }
   
       my $numcurrent = scalar(keys(%cloneable));
   
       my $jscript = &textbook_request_javascript($numbook,$numcurrent);
       my %loaditems;
       $loaditems{'onload'} = 'javascript:uncheckAllRadio();';
       $r->print(&header('Course Request',$jscript,\%loaditems));
   
       if (ref($can_request) eq 'HASH') {
           unless ((scalar(keys(%{$can_request})) == 1) && ($can_request->{'textbook'})) {
               &Apache::lonhtmlcommon::add_breadcrumb(
                   { href => '/adm/requestcourse',
                     text => 'Pick action',
                   });
           }
       }
       &Apache::lonhtmlcommon::add_breadcrumb({text=>'Course Request'});
       $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests'));
   
       &startContentScreen($r,'textbookrequests');
   #
   # Show domain selector form, if required.
   #
       if (@{$incdoms} > 1) {
           my $onchange = 'this.form.submit()';
           $r->print('<form name="domforcourse" method="post" action="/adm/requestcourse">'.
                     '<div><fieldset><legend>'.&mt('Domain').'</legend>'.
                     &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange,$incdoms).
                     '</fieldset></form>');
       }
   
   #
   # Course request form
   #
   
   #
   # Course Title
   #
       $r->print('<form name="requestcourse" method="post" action="/adm/requestcourse" onsubmit="return validTextbookReq();">'.
                 '<div>'.
                 '<fieldset>'.
                 '<legend>'.&mt('Course Information').'</legend>'.
                 '<span class="LC_nobreak">'.&mt('Title').':&nbsp'.
                 '<input type="text" size="60" name="cdescr" value="" /></span><br />'.
                 $home_server_pick.'<br /></fieldset>'.
                 '</div>');
   
   #
   # Content source selection, if more than one available
   #
       if (keys(%cloneable) || keys(%ordered)) {
           $r->print('<div>'. 
                     '<fieldset><legend>'.&mt('Course Content').'</legend>');
           if (keys(%ordered)) {
               $r->print('<span class="LC_nobreak"><label>'.
                         '<input type="radio" name="cloning" value="textbook" onclick="javascript:cloneChoice();" />'.
                         &mt('Load textbook content').'</span>'.('&nbsp;'x2).' ');
           }
           if (keys(%cloneable)) {
               $r->print('<span class="LC_nobreak"><label>'.
                         '<input type="radio" name="cloning" value="existing" onclick="javascript:cloneChoice();" />'.
                         &mt('Copy one of your courses').'</label></span>'.('&nbsp;'x2).' ');
           }
           $r->print('<span class="LC_nobreak"><label>'.
                     '<input type="radio" name="cloning" value="none" checked="checked" onclick="javascript:cloneChoice();" />'.
                     &mt('Empty course shell').'</label></span>');
       } else {
           $r->print('<input type="hidden" name="cloning" value="none" />');
       }
   
   #
   # Table of cloneable textbook courses
   #
       if (keys(%ordered)) {
           $r->print('<div id="showtextbook" style="display:none">'.
                     &Apache::loncommon::start_data_table().
                     &Apache::loncommon::start_data_table_header_row().
                     '<th>'.&mt('Title').'</th>'.
                     '<th>'.&mt('Author(s)').'</th>'.
                     '<th>'.&mt('Subject').'</th>'.
                     '<th>'.&mt('Book').'</th>'.
                     &Apache::loncommon::end_data_table_header_row());
           my @items = sort { $a <=> $b } keys(%ordered);
           foreach my $num (@items) {
               my $item = $ordered{$num};
               my $cleantitle=&HTML::Entities::encode($bookshash->{$item}->{'title'},'<>&"');
               $cleantitle=~s/'/\\'/g;
               $cleantitle =~ s/^\s+//;
               $r->print(&Apache::loncommon::start_data_table_row().
                         '<td><label><input type="radio" name="book" value="'.$item.'" />'.
                         $cleantitle.'</label></td>'.
                         '<td>'.$bookshash->{$item}->{'author'}.'</td>'.
                         '<td>'.$bookshash->{$item}->{'subject'}.'</td>'.
                         '<td><img border="0" src="'.$bookshash->{$item}->{'image'}.
                         '" alt="'.$cleantitle.'" /></td>'. 
                         &Apache::loncommon::end_data_table_row());
           }
           $r->print(&Apache::loncommon::end_data_table().
                     '</div>');
       }
   
   #
   # Table of user's current courses (owner and/or course coordinator)
   #
       if (keys(%cloneable)) {
           my %lt = &clone_text();
           $r->print('<div id="showexisting" style="display:none">'.
                     &Apache::loncommon::start_data_table().
                     &Apache::loncommon::start_data_table_header_row().
                     '<th>'.&mt('Title').'</th>'.
                     '<th>'.&mt('Owner/co-owner(s)').'</th>'.
                     &Apache::loncommon::end_data_table_header_row());
           my %allownernames;
           my %sortbytitle; 
           foreach my $cid (sort(keys(%cloneable))) {
               if (ref($cloneable{$cid}) eq 'HASH') {
                   my $cdesc = $cloneable{$cid}{'description'};
                   $cdesc =~ s/`/'/g;
                   if ($cdesc ne '') {
                       push(@{$sortbytitle{$cdesc}},$cid);
                   }
               }
            }
            foreach my $title (sort(keys(%sortbytitle))) {
                if (ref($sortbytitle{$title}) eq 'ARRAY') {
                   foreach my $cid (sort(@{$sortbytitle{$title}})) {
                       my $cleantitle=&HTML::Entities::encode($title,'<>&"');
                       $cleantitle=~s/'/\\'/g;
                       $cleantitle =~ s/^\s+//;
                       my ($namestr,@owners,%ownernames);
                       my $singleowner = $cloneable{$cid}{'internal.courseowner'};
                       push(@owners,$singleowner);
                       if ($cloneable{$cid}{'co-owners'} ne '') {
                           foreach my $item (split(/,/,$cloneable{$cid}{'internal.co-owners'})) {
                               push(@owners,$item);
                           }
                       }
                       foreach my $owner (@owners) {
                           my ($ownername,$ownerdom);
                           if ($owner =~ /:/) {
                               ($ownername,$ownerdom) = split(/:/,$owner);
                           } else {
                               $ownername = $owner;
                               if ($owner ne '') {
                                   $ownerdom = $dom;
                               }
                           }
                           if ($ownername ne '' && $ownerdom ne '') {
                               if (exists($allownernames{$ownername.':'.$ownerdom})) {
                                   $ownernames{$ownername.':'.$ownerdom} = $allownernames{$ownername.':'.$ownerdom}; 
                               } else {
                                   my %namehash=&Apache::loncommon::getnames($ownername,$ownerdom);
                                   $ownernames{$ownername.':'.$ownerdom} = \%namehash;
                                   $allownernames{$ownername.':'.$ownerdom} = $ownernames{$ownername.':'.$ownerdom};
                               }
                           }
                       }
                       my @lastnames;
                       foreach my $owner (keys(%ownernames)) {
                           if (ref($ownernames{$owner}) eq 'HASH') {
                               push(@lastnames,$ownernames{$owner}{'lastname'});
                           }
                       }
                       if (@lastnames) {
                           $namestr = join(', ',sort(@lastnames));
                       }
                       $r->print(&Apache::loncommon::start_data_table_row().
                                 '<td><label><input type="radio" name="owned" value="'.$cid.'" />'.
                                 '&nbsp'.$cleantitle.'</label></td>'.
                                 '<td>'.$namestr.'</td>'.
                                 &Apache::loncommon::end_data_table_row());
                   }
               }
           }
           $r->print(&Apache::loncommon::end_data_table().
                 '<p><input type="radio" name="datemode" value="delete" /> '.$lt{'ncd'}.
                 '</label><br /><label>'.
                 '<input type="radio" name="datemode" value="preserve" /> '.$lt{'prd'}.
                 '</label><br /><label>'.
                 '<input type="radio" name="datemode" value="shift" checked="checked" /> '.
                 $lt{'shd'}.'</label>'.
                 '<input type="text" size="5" name="dateshift" value="365" />'.
                 '</div>');
       }
   #
   # End of content selector
   #
       if (keys(%cloneable) || keys(%ordered)) {
           $r->print('</fieldset></div>');
       }
   
       my %accesstitles = (
                             'start' => 'Default start access',
                              'end'   => 'Default end access',
                          );
       my %help_item = (
                          start => 'Course_Request_Access_Start',
                          end   => 'Course_Request_Access_End',
                       );
       my $starttime = time;
       my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
       my $startform = &Apache::lonhtmlcommon::date_setter('requestcourse','accessstart',
                                                           $starttime,'','','',1,'','','',1);
       my $endform = &Apache::lonhtmlcommon::date_setter('requestcourse','accessend',
                                                         $endtime,'','','',1,'','','',1);
   #
   # Set default start and end dates for student access
   # 
       $r->print('<div>'.
                 '<fieldset><legend>'.&mt('Student Access Dates').'</legend>'.
                 &Apache::loncommon::help_open_topic($help_item{'start'}).
                 '&nbsp;'.&mt($accesstitles{'start'}).$startform.'<br />'.
                 &Apache::loncommon::help_open_topic($help_item{'end'}).
                 '&nbsp;'.&mt($accesstitles{'end'}).$endform.'<br /></div>');
   
   #
   # Display any custom fields for this course type
   #
       my $fullname = &Apache::loncommon::plainname($env{'user.name'},
                                                    $env{'user.domain'});
       my $postprocess = &Apache::lonnet::auto_crsreq_update($dom,undef,$crstype,'review',
                                                             $env{'user.name'},
                                                             $env{'user.domain'},$fullname);
       if (ref($postprocess) eq 'HASH') {
           if ($postprocess->{'reviewweb'}) {
               $r->print($postprocess->{'reviewweb'});
           }
       }
   
   #
   # Submit button
   #
       $r->print('<input type="hidden" name="crstype" value="textbook" />'.
                 '<input type="hidden" name="action" value="process" />'.
                 '<input type="submit" value="'.&mt('Create course').'" />');
   
   #
   # End request form
   #
       $r->print('</form>');
       &endContentScreen($r).
       $r->print(&Apache::loncommon::end_page());
       return;
   }
   
   sub process_textbook_request {
       my ($r,$dom,$action,$domdefs,$domconfig,$can_request) = @_;
       my ($uniquecode,$req_notifylist);
       my $crstype = 'textbook';
       if (ref($domconfig) eq 'HASH') {
           if (ref($domconfig->{'requestcourses'}) eq 'HASH') {
               if (ref($domconfig->{'requestcourses'}{'notify'}) eq 'HASH') {
                   $req_notifylist = $domconfig->{'requestcourses'}{'notify'}{'approval'};
               }
               if (ref($domconfig->{'requestcourses'}{'uniquecode'}) eq 'HASH') {
                   $uniquecode = $domconfig->{'requestcourses'}{'uniquecode'}{$crstype};
               }
           }
       }
       my $crstype = 'textbook';
       my $now = time;
       my $reqtype = $env{'form.cloning'};
       my (@inststatuses,$storeresult,$creationresult);
       my $cnum = &Apache::lonnet::generate_coursenum($dom,'Course');
       my ($clonefrom,$clonedom,$clonecrs);
       if ($reqtype eq 'textbook') {
           $clonefrom = $env{'form.book'};
       } elsif ($reqtype eq 'existing') {
           $clonefrom = $env{'form.owned'};
       }
       my ($accessstart,$accessend) = &dates_from_form('accessstart','accessend');
       if ($clonefrom) {
           ($clonedom,$clonecrs) = split(/_/,$clonefrom);
           if (&Apache::lonnet::homeserver($clonecrs,$clonedom) ne 'no_host') {
               my $canclone =
                   &Apache::loncoursequeueadmin::can_clone_course($env{'user.name'},
                               $env{'user.domain'},$clonecrs,$clonedom,$crstype);
               unless ($canclone) {
                   undef($clonecrs);
                   undef($clonedom);
               }
           } else {
               undef($clonecrs);
               undef($clonedom);
           }
       }
       $r->print(&header('Course Creation'));
   
       if (ref($can_request) eq 'HASH') {
           unless ((scalar(keys(%{$can_request})) == 1) && ($can_request->{'textbook'})) {
               &Apache::lonhtmlcommon::add_breadcrumb(
                   { href => '/adm/requestcourse',
                     text => 'Pick action',
                   });
           }
       }
       &Apache::lonhtmlcommon::add_breadcrumb(
                                              { href => '/adm/requestcourse',
                                                text => "Create Course",
                                              }
                                             );
       &Apache::lonhtmlcommon::add_breadcrumb({text=>'Request Processed'});
       $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Requests','Course_Requests'));
       &startContentScreen($r,'textbookrequests');
   
       my $details = {
                       owner          => $env{'user.name'},
                       domain         => $env{'user.domain'},
                       cdom           => $dom,
                       cnum           => $cnum,
                       coursehome     => $env{'form.chome'},
                       cdescr         => $env{'form.cdescr'},
                       crstype        => $crstype,
                       uniquecode     => $uniquecode,
                       clonedom       => $clonedom,
                       clonecrs       => $clonecrs,
                       accessstart    => $accessstart,
                       accessend      => $accessend,
                       personnel      => {},
                     };
       if ($reqtype eq 'existing') {
           $details->{datemode} = $env{'form.datemode'};
           $details->{dateshift} = $env{'form.dateshift'};
       }
       my ($result,$output) = &process_request($dom,$cnum,$crstype,$now,$details,'',$req_notifylist,[],$domconfig);
       $r->print($output);
       if (&Apache::loncoursequeueadmin::author_prompt()) {
           &print_author_prompt($r,$action,$cnum,$dom,$crstype,$result);
       } elsif ($result eq 'created') {
           $r->print('<p><a href="/adm/requestcourse">'.&mt('Create another course').'</a></p>');
       }
       &endContentScreen($r);
       $r->print(&Apache::loncommon::end_page());
   }
   
   sub textbook_request_javascript {
       my ($numbook,$numcurrent) = @_;
       my %lt = &Apache::lonlocal::texthash(
                    choose   => 'Please select a content option.',
                    textbook => 'Please select a textbook, or choose a different option.',
                    existing => 'Please select one of your existing courses to copy, or choose a different option.',
                    title    => 'Please enter a course title.',
                );
       return if (!$numbook && !$numcurrent);
       return <<"ENDSCRIPT";
   function cloneChoice() {
       if (document.requestcourse.cloning) {
           var radioLength = document.requestcourse.cloning.length;
           if (radioLength == undefined) {
               var val = document.requestcourse.cloning.value;
               if ((val == 'textbook') || (val == 'existing')) {
                   var elem = document.getElementById('show'+val);
                   if (document.requestcourse.cloning.checked) {
                       elem.style.display = 'block';
                   } else {
                       uncheckRadio(val);
                       elem.style.display = 'none';
                   }
               }
           } else {
               for (var i=0; i<radioLength; i++) {
                   var val = document.requestcourse.cloning[i].value;
                   if ((val == 'textbook') || (val == 'existing')) {
                       var elem = document.getElementById('show'+val);
                       if (document.requestcourse.cloning[i].checked) {
                           elem.style.display = 'block';
                       }  else {
                           if (val == 'textbook') {
                               uncheckRadio('book');
                           }
                           if (val == 'existing') {
                               uncheckRadio('owned');
                           }
                           elem.style.display = 'none';
                       }
                   }
               }
           }
       }
       return;
   }
   
   function uncheckRadio(radioGroupName) {
       var group = document.getElementsByName(radioGroupName);
       var radioLength = group.length;
       if (radioLength == undefined) {
           group.checked = false;
       } else {
           for (var i=0; i<radioLength; i++) {
               group[i].checked = false;
           }
       }
       return;
   }
   
   function uncheckAllRadio() {
       uncheckRadio('cloning');
       var numbook = $numbook;
       var numcurrent = $numcurrent;
       if (numbook > 0) {
           uncheckRadio('textbook'); 
       }
       if (numcurrent > 0) {
           uncheckRadio('existing');
       }
       return;
   }
   
   function validTextbookReq() {
       if (document.requestcourse.cloning) {
           var cloneChoice = 0;
           var radioLength = document.requestcourse.cloning.length;
           if (radioLength == undefined) {
               if (document.requestcourse.cloning.checked == false) {
                   alert("$lt{'choose'}");
                   return false;
               } else {
                   cloneChoice = document.requestcourse.cloning.value;
               }
           } else {
               for (var i=0; i<radioLength; i++) {
                   if (document.requestcourse.cloning[i].checked) {
                       cloneChoice = document.requestcourse.cloning[i].value;
                       break;
                   }
               }
               if (cloneChoice == 0) {
                   alert("$lt{'choose'}");
                   return false;
               }
           }
           var group;
           if ((cloneChoice == 'textbook') || (cloneChoice == 'existing')) {
               var group;
               if (cloneChoice == 'textbook') {
                   group = document.getElementsByName('book');
               } else {
                   group = document.getElementsByName('owned');
               }
               var groupLength = group.length;
               var chosen = 0;
               if (groupLength == undefined) {
                   if (group.checked) {
                       chosen = 1;
                   }
               } else {
                   for (var j=0; j<groupLength; j++) {
                       if (group[j].checked) {
                           chosen = 1;
                           break;
                       }
                   }
              }
              if (chosen == 0) {
                  if (cloneChoice == 'textbook') {
                      alert("$lt{'textbook'}");
                  } else {
                      alert("$lt{'existing'}");
                  }
                  return false;
               }
           }
       }
       if (document.requestcourse.cdescr.value == '') {
           alert("$lt{'title'}");
           return false;
       }
       return true;
   }
    
   ENDSCRIPT
   
   }
   
   sub startContentScreen {
       my ($r,$mode)=@_;
       $r->print("\n".'<ul class="LC_TabContentBigger" id="textbookreq">'."\n");
       $r->print('<li'.(($mode eq 'textbookrequests')?' class="active"':'').'><a href="/adm/requestcourse"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Request a Course').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n");
       $r->print('<li'.(($mode eq 'textbooklogs')?' class="active"':'').'><a href="/adm/requestcourse?action=log&amp;crstype=textbook&amp;tabs=on"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.&mt('Course Request History').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></a></li>'."\n");
       $r->print("\n".'</ul>'."\n");
       $r->print('<div class="LC_Box" style="clear:both;margin:0;"><div id="mainbox" style="margin:0 0;padding:0 0;"><div class="LC_ContentBox" id="maincontentbox" style="display: block;">');
   }
   
   sub endContentScreen {
      my ($r)=@_;
      $r->print('</div></div></div>');
   }
      
 1;  1;
   

Removed from v.1.67  
changed lines
  Added in v.1.73


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.