--- loncom/interface/lonrequestcourse.pm 2009/08/04 20:15:50 1.2 +++ loncom/interface/lonrequestcourse.pm 2010/03/30 15:01:17 1.49 @@ -1,7 +1,7 @@ # The LearningOnline Network # Request a course # -# $Id: lonrequestcourse.pm,v 1.2 2009/08/04 20:15:50 raeburn Exp $ +# $Id: lonrequestcourse.pm,v 1.49 2010/03/30 15:01:17 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -44,6 +44,66 @@ described at http://www.lon-capa.org. =item handler() +=item get_breadcrumbs() + +=item header() + +=item form_elements() + +=item onload_action() + +=item print_main_menu() + +=item request_administration() + +=item close_popup_form() + +=item get_instcode() + +=item print_request_form() + +=item print_enrollment_menu() + +=item show_invalid_crosslists() + +=item inst_section_selector() + +=item date_setting_table() + +=item print_personnel_menu() + +=item print_request_status() + +=item print_request_logs() + +=item print_review() + +=item dates_from_form() + +=item courseinfo_form() + +=item clone_form() + +=item clone_text() + +=item coursecode_form() + +=item get_course_dom() + +=item display_navbuttons() + +=item print_request_outcome() + +=item check_autolimit() + +=item retrieve_settings() + +=item get_request_settings() + +=item extract_instcode() + +=item generate_date_items() + =back =cut @@ -55,39 +115,171 @@ use Apache::Constants qw(:common :http); use Apache::lonnet; use Apache::loncommon; use Apache::lonlocal; -use LONCAPA; +use Apache::loncoursequeueadmin; +use Apache::lonuserutils; +use LONCAPA qw(:DEFAULT :match); sub handler { my ($r) = @_; + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; if ($r->header_only) { - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; return OK; } - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['action','showdom','cnum','state','crstype','queue']); &Apache::lonhtmlcommon::clear_breadcrumbs(); my $dom = &get_course_dom(); my $action = $env{'form.action'}; my $state = $env{'form.state'}; + my (%states,%stored); + my ($jscript,$uname,$udom,$result,$warning); - my %stored; - my $jscript; - if ((defined($state)) && (defined($action))) { - my %elements = &form_elements($dom); - if (($action eq 'view') && ($state ne 'crstype')) { - if (defined($env{'form.request_id'})) { - %stored = &retrieve_settings($dom,$env{'form.request_id'}); + $states{'display'} = ['details']; + $states{'view'} = ['pick_request','details','cancel','removal']; + $states{'log'} = ['display']; + $states{'new'} = ['courseinfo','enrollment','personnel','review','process']; + + if (($action eq 'new') && ($env{'form.crstype'} eq 'official')) { + unless ($env{'form.state'} eq 'crstype') { + unshift(@{$states{'new'}},'codepick'); + } + } + + foreach my $key (keys(%states)) { + if (ref($states{$key}) eq 'ARRAY') { + unshift (@{$states{$key}},'crstype'); + } + } + + my @invalidcrosslist; + my %trail = ( + crstype => 'Request Action', + codepick => 'Category', + courseinfo => 'Description', + enrollment => 'Access Dates', + personnel => 'Personnel', + review => 'Review', + process => 'Result', + pick_request => 'Display Summary', + details => 'Request Details', + cancel => 'Cancel Request', + removal => 'Outcome', + display => 'Request Logs', + ); + + if (($env{'form.crstype'} eq 'official') && (&Apache::lonnet::auto_run('',$dom))) { + $trail{'enrollment'} = 'Enrollment'; + } + + my ($page,$crumb,$newinstcode,$codechk,$checkedcode,$description) = + &get_breadcrumbs($dom,$action,\$state,\%states,\%trail); + if ($action eq 'display') { + if (($dom eq $env{'request.role.domain'}) && (&Apache::lonnet::allowed('ccc',$dom))) { + if ($env{'form.cnum'} ne '') { + my $cnum = $env{'form.cnum'}; + my $queue = $env{'form.queue'}; + my $reqkey = $cnum.'_'.$queue; + my $namespace = 'courserequestqueue'; + my $domconfig = &Apache::lonnet::get_domainconfiguser($dom); + my %queued = + &Apache::lonnet::get($namespace,[$reqkey],$dom,$domconfig); + if (ref($queued{$reqkey}) eq 'HASH') { + $uname = $queued{$reqkey}{'ownername'}; + $udom = $queued{$reqkey}{'ownerdom'}; + if (($udom =~ /^$match_domain$/) && ($uname =~ /^$match_username$/)) { + $result = &retrieve_settings($dom,$cnum,$udom,$uname); + } else { + if ($env{'form.crstype'} eq 'community') { + $warning = &mt('Invalid username or domain for community requestor'); + } else { + $warning = &mt('Invalid username or domain for course requestor'); + } + } + } else { + if ($env{'form.crstype'} eq 'community') { + $warning = &mt('No information was found for this community request.'); + } else { + $warning = &mt('No information was found for this course request.'); + } + } + } else { + $warning = &mt('No course request ID provided.'); + } + } else { + if ($env{'form.crstype'} eq 'any') { + $warning = &mt('You do not have rights to view course or community request information.'); + } elsif ($env{'form.crstype'} eq 'community') { + $warning = &mt('You do not have rights to view community request information.'); + } else { + $warning = &mt('You do not have rights to view course request information.'); + } + } + } elsif ((defined($state)) && (defined($action))) { + if (($action eq 'view') && ($state eq 'details')) { + if ((defined($env{'form.showdom'})) && (defined($env{'form.cnum'}))) { + my $result = &retrieve_settings($env{'form.showdom'},$env{'form.cnum'}); + } + } elsif ($env{'form.crstype'} eq 'official') { + if (&Apache::lonnet::auto_run('',$dom)) { + if (($action eq 'new') && (($state eq 'enrollment') || + ($state eq 'personnel'))) { + my $checkcrosslist = 0; + for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) { + if ($env{'form.crosslist_'.$i}) { + $checkcrosslist ++; + } + } + if ($checkcrosslist) { + my %codechk; + my (@codetitles,%cat_titles,%cat_order,@code_order,$lastitem); + &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles, + \%cat_titles, + \%cat_order, + \@code_order); + my $numtitles = scalar(@codetitles); + if ($numtitles) { + for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) { + if ($env{'form.crosslist_'.$i}) { + my $codecheck; + my $crosslistcode = ''; + foreach my $item (@code_order) { + $crosslistcode .= $env{'form.crosslist_'.$i.'_'.$item}; + } + if ($crosslistcode ne '') { + ($codechk{$i}, my $rest) = + &Apache::lonnet::auto_validate_instcode('',$dom,$crosslistcode); + } + unless ($codechk{$i} eq 'valid') { + $env{'form.crosslist_'.$i} = ''; + push(@invalidcrosslist,$crosslistcode); + } + } + } + } + } + } } } + my %elements = &form_elements($dom); my $elementsref = {}; if (ref($elements{$action}) eq 'HASH') { if (ref($elements{$action}{$state}) eq 'HASH') { $elementsref = $elements{$action}{$state}; } } - $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored); + if (($state eq 'courseinfo') && ($env{'form.clonedom'} eq '')) { + $env{'form.clonedom'} = $dom; + } + if ($state eq 'crstype') { + $jscript = &mainmenu_javascript(); + } else { + $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored); + if ($state eq 'courseinfo') { + $jscript .= &cloning_javascript(); + } + } } if ($state eq 'personnel') { @@ -96,73 +288,203 @@ sub handler { my $loaditems = &onload_action($action,$state); - my %states; - $states{'view'} = ['pick_request','details','review','process']; - $states{'log'} = ['filter','display']; - $states{'new'} = ['courseinfo','enrollment','personnel','review','process']; - if (($action eq 'new') && ($env{'form.crstype'} eq 'official')) { - unless ($env{'form.state'} eq 'crstype') { - unshift (@{$states{'new'}},'codepick'); + my (%can_request,%request_domains); + my $canreq = + &Apache::lonnet::check_can_request($dom,\%can_request,\%request_domains); + if ($action eq 'new') { + if ($canreq) { + if ($state eq 'crstype') { + &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems, + $crumb,\%request_domains); + } else { + &request_administration($r,$action,$state,$page,\%states,$dom, + $jscript,$loaditems,$crumb,$newinstcode, + $codechk,$checkedcode,$description, + \@invalidcrosslist); + } + } else { + $r->print(&header('Course/Community Requests').$crumb. + '
'); + if ($storeresult eq 'ok') { + $r->print(''. + &mt('Modify this request').''.(' 'x4)); + } + $r->print(''.&mt('Make another request').'
'); + return; + } + } + my @excluded = &get_excluded_elements($dom,$states,$action,$state); + if ($state eq 'personnel') { + push(@excluded,'persontotal'); + } + if ($state eq 'review') { + if (@disallowed > 0) { + my @items = qw(uname dom lastname firstname emailaddr hidedom role newsec); + my @currsecs = ¤t_lc_sections(); + if (@currsecs) { + push(@items,'sec'); + } + my $count = 0; + for (my $i=0; $i<$env{'form.persontotal'}; $i++) { + unless ($env{'form.person_'.$i.'_uname'} eq '') { + if (grep(/^$i$/,@disallowed)) { + foreach my $item (@items) { + $env{'form.person_'.$i.'_'.$item} = ''; + } + } else { + foreach my $item (@items) { + $env{'form.person_'.$count.'_'.$item} = $env{'form.person_'.$i.'_'.$item}; + } + } + } + $count ++; + } + $env{'form.persontotal'} = $count; + + } + } + if ($state eq 'enrollment') { + push(@excluded,'crosslisttotal'); + } + $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).''); + &display_navbuttons($r,$dom,$formname,$prev,$navtxt{'prev'},$next, + $navtxt{'next'},$state); + return; +} + +sub get_cancreate_status { + my ($persondom,$personname,$dom) = @_; + my ($rules,$ruleorder) = + &Apache::lonnet::inst_userrules($persondom,'username'); + my $usertype = &Apache::lonuserutils::check_usertype($persondom,$personname, + $rules); + return &Apache::lonuserutils::can_create_user($dom,'requestcrs',$usertype); +} + +sub check_newuser_rules { + my ($persondom,$personname,$alerts,$rulematch,$inst_results,$curr_rules, + $got_rules) = @_; + my $allowed = 1; + my $newuser = 1; + my ($checkhash,$userchkmsg); + my $checks = { 'username' => 1 }; + $checkhash->{$personname.':'.$persondom} = { 'newuser' => $newuser }; + &Apache::loncommon::user_rule_check($checkhash,$checks,$alerts,$rulematch, + $inst_results,$curr_rules,$got_rules); + if (ref($alerts->{'username'}) eq 'HASH') { + if (ref($alerts->{'username'}{$persondom}) eq 'HASH') { + my $domdesc = + &Apache::lonnet::domain($persondom,'description'); + if ($alerts->{'username'}{$persondom}{$personname}) { + if (ref($curr_rules->{$persondom}) eq 'HASH') { + $userchkmsg = + &Apache::loncommon::instrule_disallow_msg('username', + $domdesc,1). + &Apache::loncommon::user_rule_formats($persondom, + $domdesc,$curr_rules->{$persondom}{'username'}, + 'username'); + } + $allowed = 0; + } + } } + return ($allowed,$userchkmsg); +} + +sub get_excluded_elements { + my ($dom,$states,$action,$state) = @_; my @excluded = ('counter'); my %elements = &form_elements($dom); if (ref($states) eq 'HASH') { @@ -575,7 +1509,7 @@ sub print_request_form { for (my $i=$numitems-1; $i>=0; $i--) { if (ref($elements{$action}) eq 'HASH') { if (ref($elements{$action}{$items[$i]}) eq 'HASH') { - foreach my $key (keys(%{$elements{$action}{$items[$i]}})) { + foreach my $key (keys(%{$elements{$action}{$items[$i]}})) { push(@excluded,$key); } } @@ -588,20 +1522,19 @@ sub print_request_form { if (grep(/^instcode_/,@excluded)) { push(@excluded,'instcode'); } - $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).''); - &display_navbuttons($r,$formname,$prev,'Previous',$next,'Next'); - return; + return @excluded; } sub print_enrollment_menu { - my ($formname,$instcode,$dom,$codetitles,$cat_titles,$cat_order,$code_order) =@_; - my ($sections,$autoenroll,$access_dates); + my ($formname,$instcode,$dom,$codetitles,$cat_titles,$cat_order,$code_order, + $invalidcrosslist) =@_; + my ($sections,$autoenroll,$access_dates,$output,$hasauto); my $starttime = time; my $endtime = time+(6*30*24*60*60); # 6 months from now, approx my %accesstitles = ( 'start' => 'Default start access', - 'end' => 'Default end accss', + 'end' => 'Default end access', ); my %enrolltitles = ( 'start' => 'Start auto-enrollment', @@ -609,10 +1542,18 @@ sub print_enrollment_menu { ); if ($env{'form.crstype'} eq 'official') { if (&Apache::lonnet::auto_run('',$dom)) { - my ($section_form,$crosslist_form,$autoenroll_form); + $output = &show_invalid_crosslists($invalidcrosslist); + my ($section_form,$crosslist_form); $section_form = &inst_section_selector($dom,$instcode); + if ($section_form) { + $sections = &Apache::lonhtmlcommon::row_headline(). + ''.&mt('Username').' '.$uname_form.' | '."\n".
- ''.&mt('Domain').' '.$udom_form.' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'.&mt('First Name').' '.$form_elems{'first'}.' | '."\n".
- ''.&mt('Last Name').' '.$form_elems{'last'}.' | '."\n".
- ''.&mt('E-mail').' '.$form_elems{email}.' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'.&mt('Role').' '.$roleselector.' | '."\n".
- ''.&mt('Section(s)').' '.$sectionselector.' | '."\n".
+ &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel')).
+ '
'.$usersrchlink.' | '."\n". + ''.
+ &mt('Username').': '.$uname_form.' '.$userchklink.' '."\n". + ''.&mt('Domain').': '.$udom_form.' | '.
+ '|
'.&mt('First Name').' '.$form_elems{'firstname'}.' | '."\n".
+ ''.&mt('Last Name').' '.$form_elems{'lastname'}.' | '."\n".
+ ''.&mt('E-mail').' '.$form_elems{'emailaddr'}.' |
'.&Apache::loncommon::help_open_topic('Course_Roles').' '.&mt('Role').' '.$roleselector.' | '."\n".
+ ''.
+ &Apache::loncommon::help_open_topic('Course_Request_Rolesection').' '.&mt('LON-CAPA Section(s)').' '.$sectionselector.' | '."\n".
'
'.&mt('You may also add users later, once the community has been created, by using the "Manage community users" link, accessible from the "Main Menu".').'
'; + } else { + $output .= ''.&mt('You may also add users later, once the course has been created, by using the "Manage course users" link, accessible from the "Main Menu".').'
'; + } return $output; } +sub current_lc_sections { + my @currsecs; + if ($env{'form.sectotal'}) { + for (my $i=0; $i<$env{'form.sectotal'}; $i++) { + if ($env{'form.sec_'.$i}) { + if (defined($env{'form.loncapasec_'.$i})) { + my $lcsec = $env{'form.loncapasec_'.$i}; + unless (grep(/^\Q$lcsec\E$/,@currsecs)) { + push(@currsecs,$lcsec); + } + } + } + } + } + return @currsecs; +} + +sub sorted_request_history { + my ($dom,$action,$curr_req) = @_; + my ($after,$before,$statusfilter,$crstypefilter); + if ($env{'form.status'} ne '') { + $statusfilter = $env{'form.status'}; + } + if ($env{'form.crstype'} ne '') { + $crstypefilter = $env{'form.crstype'}; + } + if (ref($curr_req) eq 'HASH') { + $after = $curr_req->{'requested_after_date'}, + $before = $curr_req->{'requested_before_date'}; + $statusfilter = $curr_req->{'status'}; + $crstypefilter = $curr_req->{'crstype'}; + } + my %statusinfo = &Apache::lonnet::dump('courserequests',$env{'user.domain'}, + $env{'user.name'},'^status:'.$dom); + my %queue_by_date; + my ($types,$typenames) = &Apache::loncommon::course_types(); + foreach my $key (keys(%statusinfo)) { + if ($action eq 'view') { + next unless (($statusinfo{$key} eq 'approval') || ($statusinfo{$key} eq 'pending')); + } else { + next unless (($statusfilter eq 'any') || + ($statusfilter eq $statusinfo{$key})); + } + (undef,my($cdom,$cnum)) = split(':',$key); + next if ($cdom ne $dom); + my $requestkey = $cdom.'_'.$cnum; + if ($requestkey =~ /^($match_domain)_($match_courseid)$/) { + my %history = &Apache::lonnet::restore($requestkey,'courserequests', + $env{'user.domain'},$env{'user.name'}); + my $entry; + my $reqtime = $history{'reqtime'}; + my $lastupdate = $history{'timestamp'}; + my $crstype = $history{'crstype'}; + my $disposition = $history{'disposition'}; + my $status = $history{'status'}; + if ($action eq 'view') { + next if ((exists($history{'status'})) && ($history{'status'} eq 'created')); + } else { + next if (($reqtime < $after) || ($reqtime > $before)); + } + next unless (($crstypefilter eq 'any') || + ($crstypefilter eq $crstype)); + if ($action eq 'view') { + next unless (($disposition eq 'approval') || + ($disposition eq 'pending')); + } + if (ref($history{'details'}) eq 'HASH') { + $entry = $requestkey.':'.$crstype.':'. + &escape($history{'details'}{'cdescr'}); + if ($action eq 'log') { + $entry .= ':'.$lastupdate.':'; + if ($statusinfo{$key} ne '') { + $entry .= $statusinfo{$key}; + } elsif ($status ne '') { + $entry .= $status; + } else { + $entry .= $disposition; + } + } + if ($crstype eq 'official') { + $entry .= ':'.&escape($history{'details'}{'instcode'}); + } + } + if ($entry ne '') { + if (exists($queue_by_date{$reqtime})) { + if (ref($queue_by_date{$reqtime}) eq 'ARRAY') { + push(@{$queue_by_date{$reqtime}},$entry); + } + } else { + @{$queue_by_date{$reqtime}} = ($entry); + } + } + } + } + return %queue_by_date; +} + sub print_request_status { + my ($dom,$action) = @_; + my %queue_by_date = &sorted_request_history($dom,$action); + my @sortedtimes = sort {$a <=> $b} (keys(%queue_by_date)); + my $formname = 'requestcrs'; + my ($types,$typenames) = &Apache::loncommon::course_types(); + my $output = ''."\n". + + ''."\n". + ''."\n". + ''."\n". + ''."\n"; + if (@sortedtimes > 0) { + my $desctitle; + if ($env{'form.crstype'} eq 'any') { + $desctitle = &mt('Course/Community Description') + } elsif ($env{'form.crstype'} eq 'community') { + $desctitle = &mt('Community Description') + } else { + $desctitle = &mt('Course Description'); + } + $output .= &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + '
'.&mt('Previous [_1] changes',$curr{'show'}).' | '); + } + if ($more_records) { + $r->print(''.&mt('Next [_1] changes',$curr{'show'}).' | '); + } + $r->print('
'. + &mt('There are no records to display'). + '
'); + } + $r->print(''.
+ ''.&mt('Records/page:').' '. + &Apache::lonmeta::selectbox('show',$curr->{'show'},undef, + (&mt('all'),5,10,20,50,100,1000,10000)). + ' | '; + my $startform = + &Apache::lonhtmlcommon::date_setter($formname,'requested_after_date', + $curr->{'requested_after_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + my $endform = + &Apache::lonhtmlcommon::date_setter($formname,'requested_before_date', + $curr->{'requested_before_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + $output .= ' | '.&mt('Window during which course/community was requested:').' '. + '
| '.
+ ''; + my ($types,$typenames) = &Apache::loncommon::course_types(); + if (ref($types) eq 'ARRAY') { + if (@{$types} > 1) { + $output .= ' | '.
+ &mt('Course Type:').' | ';
+ }
+ }
+ my ($statuses,$statusnames) = &reqstatus_names($curr->{'crstype'});
+ if (ref($statuses) eq 'ARRAY') {
+ if (@{$statuses} > 1) {
+ $output .= ''.
+ &mt('Request Status:').' | ';
+ }
+ }
+ $output .= '
'. + ''. + '
'. + &mt('Institutional section').' | '. + ''.&mt('LON-CAPA section').' |
---|---|
'.$env{'form.secnum_'.$i}.' | '; + if ($env{'form.loncapasec_'.$i} ne '') { + $secinfo .= $env{'form.loncapasec_'.$i}; + } else { + $secinfo .= &mt('None'); + } + $secinfo .= ' |
'.&mt('None').' |
'. + &mt('Institutional course/section').' | '. + ''.&mt('LON-CAPA section').' |
---|---|
'; + if (ref($code_order) eq 'ARRAY') { + if (@{$code_order} > 0) { + foreach my $item (@{$code_order}) { + $xlistinfo .= $env{'form.crosslist_'.$i.'_'.$item}; + } + } + } + $xlistinfo .= $env{'form.crosslist_'.$i.'_instsec'}.' | '; + if ($env{'form.crosslist_'.$i.'_lcsec'}) { + $xlistinfo .= $env{'form.crosslist_'.$i.'_lcsec'}; + } else { + $xlistinfo .= &mt('None'); + } + $xlistinfo .= ' |
'.&mt('None').' |
'. + &mt('Not all requested personnel could be included.').'
'.&mt('Name').' | '. + ''.&mt('Username:Domain').' | '. + ''.&mt('E-mail address').' | '. + '
---|---|---|
'.$ownername.' | '.$owner.' | '. + ''.$owneremail.' | '. + '
'.&mt('Include?').' '. @@ -982,69 +2912,826 @@ sub coursecode_form { sub get_course_dom { my $codedom = &Apache::lonnet::default_login_domain(); + if ($env{'form.showdom'} ne '') { + if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') { + return $env{'form.showdom'}; + } + } if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) { + my ($types,$typename) = &Apache::loncommon::course_types(); + if (ref($types) eq 'ARRAY') { + foreach my $type (@{$types}) { + if (&Apache::lonnet::usertools_access($env{'user.name'}, + $env{'user.domain'},$type, + undef,'requestcourses')) { + return $env{'user.domain'}; + } + } + my @possible_doms; + foreach my $type (@{$types}) { + my $dom_str = $env{'environment.reqcrsotherdom.'.$type}; + if ($dom_str ne '') { + my @domains = split(',',$dom_str); + foreach my $entry (@domains) { + my ($extdom,$extopt) = split(':',$entry); + if ($extdom eq $env{'request.role.domain'}) { + return $extdom; + } + unless(grep(/^\Q$extdom\E$/,@possible_doms)) { + push(@possible_doms,$extdom); + } + } + } + } + if (@possible_doms) { + @possible_doms = sort(@possible_doms); + return $possible_doms[0]; + } + } $codedom = $env{'user.domain'}; if ($env{'request.role.domain'} ne '') { $codedom = $env{'request.role.domain'}; } } - if ($env{'form.showdom'} ne '') { - if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') { - $codedom = $env{'form.showdom'}; - } - } return $codedom; } sub display_navbuttons { - my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_; + my ($r,$dom,$formname,$prev,$prevtext,$next,$nexttext,$state,$other,$othertext) = @_; $r->print(' '); } sub print_request_outcome { + my ($dom,$codetitles,$code_order) = @_; + my ($output,$cnum,$now,$req_notifylist,$crstype,$enrollstart,$enrollend, + %sections,%crosslistings,%personnel,@baduname,@missingdom,%domconfig,); + my $sectotal = $env{'form.sectotal'}; + my $crosslisttotal = 0; + $cnum = $env{'form.cnum'}; + unless ($cnum =~ /^$match_courseid$/) { + $output = &mt('Invalid LON-CAPA course number for the new course')."\n"; + return $output; + } + + %domconfig = &Apache::lonnet::get_dom('configuration',['requestcourses'],$dom); + if (ref($domconfig{'requestcourses'}) eq 'HASH') { + if (ref($domconfig{'requestcourses'}{'notify'}) eq 'HASH') { + $req_notifylist = $domconfig{'requestcourses'}{'notify'}{'approval'}; + } + } + $now = time; + $crstype = $env{'form.crstype'}; + my $ccrole = 'cc'; + if ($crstype eq 'community') { + $ccrole = 'co'; + } + my @instsections; + if ($crstype eq 'official') { + if (&Apache::lonnet::auto_run('',$dom)) { + ($enrollstart,$enrollend)=&dates_from_form('enrollstart','enrollend'); + } + for (my $i=0; $i<$env{'form.sectotal'}; $i++) { + if ($env{'form.sec_'.$i}) { + if ($env{'form.secnum_'.$i} ne '') { + my $sec = $env{'form.secnum_'.$i}; + $sections{$i}{'inst'} = $sec; + if (($sec ne '') && (!grep(/^\Q$sec\E$/,@instsections))) { + push(@instsections,$sec); + } + $sections{$i}{'loncapa'} = $env{'form.loncapasec_'.$i}; + } + } + } + for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) { + if ($env{'form.crosslist_'.$i}) { + my $xlistinfo = ''; + if (ref($code_order) eq 'ARRAY') { + if (@{$code_order} > 0) { + foreach my $item (@{$code_order}) { + $xlistinfo .= $env{'form.crosslist_'.$i.'_'.$item}; + } + } + } + $crosslistings{$i}{'instcode'} = $xlistinfo; + if ($xlistinfo ne '') { + $crosslisttotal ++; + } + $crosslistings{$i}{'instsec'} = $env{'form.crosslist_'.$i.'_instsec'}; + $crosslistings{$i}{'loncapa'} = $env{'form.crosslist_'.$i.'_lcsec'}; + } + } + } else { + $enrollstart = ''; + $enrollend = ''; + } + for (my $i=0; $i<$env{'form.persontotal'}; $i++) { + my $uname = $env{'form.person_'.$i.'_uname'}; + my $udom = $env{'form.person_'.$i.'_dom'}; + if (($uname =~ /^$match_username$/) && ($udom =~ /^$match_domain$/)) { + if (&Apache::lonnet::domain($udom) ne '') { + unless (ref($personnel{$uname.':'.$udom}) eq 'HASH') { + $personnel{$uname.':'.$udom} = { + firstname => $env{'form.person_'.$i.'_firstname'}, + lastname => $env{'form.person_'.$i.'_lastname'}, + emailaddr => $env{'form.person_'.$i.'_emailaddr'}, + }; + } + my $role = $env{'form.person_'.$i.'_role'}; + unless ($role eq '') { + if (ref($personnel{$uname.':'.$udom}{'roles'}) eq 'ARRAY') { + my @curr_roles = @{$personnel{$uname.':'.$udom}{'roles'}}; + unless (grep(/^\Q$role\E$/,@curr_roles)) { + push(@{$personnel{$uname.':'.$udom}{'roles'}},$role); + } + } else { + @{$personnel{$uname.':'.$udom}{'roles'}} = ($role); + } + if ($role eq $ccrole) { + @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = (); + } else { + my @currsec = &Apache::loncommon::get_env_multiple('form.person_'.$i.'_sec'); + my @allsecs; + foreach my $sec (@currsec) { + next unless ($sec =~ /\w/); + next if ($sec =~ /\W/); + next if ($sec eq 'none'); + push(@allsecs,$sec); + } + my $newsec = $env{'form.person_'.$i.'_newsec'}; + $newsec =~ s/^\s+//; + $newsec =~s/\s+$//; + my @newsecs = split(/[\s,;]+/,$newsec); + foreach my $sec (@newsecs) { + next if ($sec =~ /\W/); + next if ($sec eq 'none'); + if ($sec ne '') { + unless (grep(/^\Q$sec\E$/,@allsecs)) { + push(@allsecs,$sec); + } + } + } + @{$personnel{$uname.':'.$udom}{$role}{'usec'}} = @allsecs; + } + } + } else { + push(@missingdom,$uname.':'.$udom); + } + } else { + push(@baduname,$uname.':'.$udom); + } + } + my ($accessstart,$accessend) = &dates_from_form('accessstart','accessend'); + my $autodrops = 0; + if ($env{'form.autodrops'}) { + $autodrops = $env{'form.autodrops'}; + } + my $autoadds = 0; + if ($env{'form.autoadds'}) { + $autodrops = $env{'form.autoadds'}; + } + if ($env{'form.autoadds'}) { + $autodrops = $env{'form.autoadds'}; + } + my $instcode = ''; + if (exists($env{'form.instcode'})) { + $instcode = $env{'form.instcode'}; + } + my $clonecrs = ''; + my $clonedom = ''; + if (($env{'form.cloning'}) && + ($env{'form.clonecrs'} =~ /^($match_courseid)$/) && + ($env{'form.clonedom'} =~ /^($match_domain)$/)) { + my $clonehome = &Apache::lonnet::homeserver($env{'form.clonecrs'}, + $env{'form.clonedom'}); + if ($clonehome ne 'no_host') { + my $canclone = + &Apache::loncoursequeueadmin::can_clone_course($env{'user.name'}, + $env{'user.domain'},$env{'form.clonecrs'},$env{'form.clonedom'}, + $crstype); + if ($canclone) { + $clonecrs = $env{'form.clonecrs'}; + $clonedom = $env{'form.clonedom'}; + } + } + } + my $details = { + owner => $env{'user.name'}, + domain => $env{'user.domain'}, + cdom => $dom, + cnum => $cnum, + coursehome => $env{'form.chome'}, + cdescr => $env{'form.cdescr'}, + crstype => $env{'form.crstype'}, + instcode => $instcode, + clonedom => $clonedom, + clonecrs => $clonecrs, + datemode => $env{'form.datemode'}, + dateshift => $env{'form.dateshift'}, + sectotal => $sectotal, + sections => \%sections, + crosslisttotal => $crosslisttotal, + crosslists => \%crosslistings, + autoadds => $autoadds, + autodrops => $autodrops, + enrollstart => $enrollstart, + enrollend => $enrollend, + accessstart => $accessstart, + accessend => $accessend, + personnel => \%personnel, + }; + my (@inststatuses,$storeresult,$creationresult); + my $val = + &Apache::loncoursequeueadmin::get_processtype($env{'user.name'},$env{'user.domain'}, + $env{'user.adv'},$dom,$crstype,\@inststatuses,\%domconfig); + if ($val eq '') { + if ($crstype eq 'official') { + $output = &mt('You are not permitted to request creation of official courses.'); + } elsif ($crstype eq 'unofficial') { + $output = &mt('You are not permitted to request creation of unofficial courses.'); + } elsif ($crstype eq 'community') { + $output = &mt('You are not permitted to request creation of communities'); + } else { + $output = &mt('Unrecognized course type: [_1]',$crstype); + } + $storeresult = 'notpermitted'; + } else { + my ($disposition,$message,$reqstatus); + my %reqhash = ( + reqtime => $now, + crstype => $crstype, + details => $details, + ); + my $requestkey = $dom.'_'.$cnum; + my $validationerror; + if ($val eq 'autolimit=') { + $disposition = 'process'; + } elsif ($val =~ /^autolimit=(\d+)$/) { + my $limit = $1; + $disposition = &check_autolimit($env{'user.name'},$env{'user.domain'}, + $dom,$crstype,$limit,\$message); + } elsif ($val eq 'validate') { + my ($inststatuslist,$validationchk,$validation); + if (@inststatuses > 0) { + $inststatuslist = join(',',@inststatuses); + } + my $instseclist; + if (@instsections > 0) { + $instseclist = join(',',@instsections); + } + $validationchk = + &Apache::lonnet::auto_courserequest_validation($dom, + $env{'user.name'}.':'.$env{'user.domain'},$crstype, + $inststatuslist,$instcode,$instseclist); + if ($validationchk =~ /:/) { + ($validation,$message) = split(':',$validationchk); + } else { + $validation = $validationchk; + } + if ($validation =~ /^error(.*)$/) { + $disposition = 'approval'; + $validationerror = $1; + } else { + $disposition = $validation; + } + } else { + $disposition = 'approval'; + } + $reqhash{'disposition'} = $disposition; + $reqstatus = $disposition; + my ($modified,$queued); + if ($disposition eq 'rejected') { + if ($crstype eq 'community') { + $output = &mt('Your community request was rejected.'); + } else { + $output = &mt('Your course request was rejected.'); + } + if ($message) { + $output .= ' '.$message.' ';
+ }
+ $storeresult = 'rejected';
+ } elsif ($disposition eq 'process') {
+ my %domdefs = &Apache::lonnet::get_domain_defaults($dom);
+ my ($logmsg,$newusermsg,$addresult,$enrollcount,$response,$keysmsg,%longroles);
+ my $type = 'Course';
+ if ($crstype eq 'community') {
+ $type = 'Community';
+ }
+ my @roles = &Apache::lonuserutils::roles_by_context('course','',$type);
+ foreach my $role (@roles) {
+ $longroles{$role}=&Apache::lonnet::plaintext($role,$type);
+ }
+ my $result = &Apache::loncoursequeueadmin::course_creation($dom,$cnum,
+ 'autocreate',$details,\$logmsg,\$newusermsg,\$addresult,
+ \$enrollcount,\$response,\$keysmsg,\%domdefs,\%longroles);
+ if ($result eq 'created') {
+ $disposition = 'created';
+ $reqstatus = 'created';
+ my $role_result = &update_requestors_roles($dom,$cnum,$crstype,$details,
+ \%longroles);
+ if ($crstype eq 'community') {
+ $output = ''.&mt('Your community request has been processed and the community has been created.'); + } else { + $output = ' '.&mt('Your course request has been processed and the course has been created.');
+ }
+ $output .= ' '. + &mt('You may want to review the request details and submit the request again.'). + ''; + $creationresult = 'error'; + } + } else { + my $requestid = $cnum.'_'.$disposition; + my $request = { + $requestid => { + timestamp => $now, + crstype => $crstype, + ownername => $env{'user.name'}, + ownerdom => $env{'user.domain'}, + description => $env{'form.cdescr'}, + }, + }; + if ($crstype eq 'official') { + $request->{$requestid}->{'instcode'} = $instcode; + } + my $statuskey = 'status:'.$dom.':'.$cnum; + my %userreqhash = &Apache::lonnet::get('courserequests',[$statuskey], + $env{'user.domain'},$env{'user.name'}); + if ($userreqhash{$statuskey} ne '') { + $modified = 1; + my $uname = &Apache::lonnet::get_domainconfiguser($dom); + my %queuehash = &Apache::lonnet::get('courserequestqueue', + [$cnum.'_approval', + $cnum.'_pending'],$dom,$uname); + if (($queuehash{$cnum.'_approval'} ne '') || + ($queuehash{$cnum.'_pending'} ne '')) { + $queued = 1; + } + } + unless ($queued) { + my $putresult = &Apache::lonnet::newput_dom('courserequestqueue',$request, + $dom); + if ($putresult eq 'ok') { + if ($crstype eq 'community') { + $output .= &mt('Your community request has been recorded.'); + } else { + $output .= &mt('Your course request has been recorded.') + } + $output .= ' '. + ¬ification_information($disposition,$req_notifylist, + $cnum,$now); + } else { + $reqstatus = 'domainerror'; + $reqhash{'disposition'} = $disposition; + my $warning = &mt('An error occurred saving your request in the pending requests queue.'); + $output = ''.$warning.' '; + } + } + } + ($storeresult,my $updateresult) = + &Apache::loncoursequeueadmin::update_coursereq_status(\%reqhash,$dom, + $cnum,$reqstatus,'request'); + if ($modified && $queued && $storeresult eq 'ok') { + if ($crstype eq 'community') { + $output .= ' '.&mt('Your community request has been updated').' '; + } else { + $output .= ''.&mt('Your course request has been updated').' '; + } + $output .= ¬ification_information($disposition,$req_notifylist,$cnum,$now); + } + if ($validationerror ne '') { + $output .= ''.&mt('An error occurred validating your request with institutional data sources: [_1].',$validationerror).' '; + } + if ($updateresult) { + $output .= $updateresult; + } + } + if ($creationresult ne '') { + return ($creationresult,$output); + } else { + return ($storeresult,$output); + } +} + +sub update_requestors_roles { + my ($dom,$cnum,$crstype,$details,$longroles) = @_; + my $now = time; + my ($active,$future,$numactive,$numfuture,$output); + my $owner = $env{'user.name'}.':'.$env{'user.domain'}; + if (ref($details) eq 'HASH') { + if (ref($details->{'personnel'}) eq 'HASH') { + my $ccrole = 'cc'; + if ($crstype eq 'community') { + $ccrole = 'co'; + } + unless (ref($details->{'personnel'}{$owner}) eq 'HASH') { + $details->{'personnel'}{$owner} = { + 'roles' => [$ccrole], + $ccrole => { 'usec' => [] }, + }; + } + my @roles; + if (ref($details->{'personnel'}{$owner}{'roles'}) eq 'ARRAY') { + @roles = sort(@{$details->{'personnel'}{$owner}{'roles'}}); + unless (grep(/^\Q$ccrole\E$/,@roles)) { + push(@roles,$ccrole); + } + } else { + @roles = ($ccrole); + } + foreach my $role (@roles) { + my $refresh=$env{'user.refresh.time'}; + if ($refresh eq '') { + $refresh = $env{'user.login.time'}; + } + if ($refresh eq '') { + $refresh = $now; + } + my $start = $refresh-1; + my $end = '0'; + if ($role eq 'st') { + if ($details->{'accessstart'} ne '') { + $start = $details->{'accessstart'}; + } + if ($details->{'accessend'} ne '') { + $end = $details->{'accessend'}; + } + } + my @usecs; + if ($role ne $ccrole) { + if (ref($details->{'personnel'}{$owner}{$role}{'usec'}) eq 'ARRAY') { + @usecs = @{$details->{'personnel'}{$owner}{$role}{'usec'}}; + } + } + if ($role eq 'st') { + if (@usecs > 1) { + my $firstsec = $usecs[0]; + @usecs = ($firstsec); + } + } + if (@usecs == 0) { + push(@usecs,''); + } + foreach my $usec (@usecs) { + my (%userroles,%newrole,%newgroups,$spec,$area); + my $area = '/'.$dom.'/'.$cnum; + my $spec = $role.'.'.$area; + if ($usec ne '') { + $spec .= '/'.$usec; + $area .= '/'.$usec; + } + if ($role =~ /^cr\//) { + &Apache::lonnet::custom_roleprivs(\%newrole,$role,$dom, + $cnum,$spec,$area); + } else { + &Apache::lonnet::standard_roleprivs(\%newrole,$role,$dom, + $spec,$cnum,$area); + } + &Apache::lonnet::set_userprivs(\%userroles,\%newrole, + \%newgroups); + $userroles{'user.role.'.$spec} = $start.'.'.$end; + &Apache::lonnet::appenv(\%userroles,[$role,'cm']); + if (($end == 0) || ($end > $now)) { + my $showrole = $role; + if ($role =~ /^cr\//) { + $showrole = &Apache::lonnet::plaintext($role,$crstype); + } elsif (ref($longroles) eq 'HASH') { + if ($longroles->{$role} ne '') { + $showrole = $longroles->{$role}; + } + } + if ($start <= $now) { + $active .= '
'; + } + if ($future) { + if ($crstype eq 'Community') { + $output .= &mt('The following community [quant,_1,role] will become available for selection from your [_2]roles page[_3], once the default student access start date - [_4] - has been reached:',$numfuture,'','',&Apache::lonlocal::locallocaltime($details->{'accessstart'})) + } else { + $output .= &mt('The following course [quant,_1,role] will become available for selection from your [_2]roles page[_3], once the default student access start date - [_4] - has been reached:',$numfuture,'','',&Apache::lonlocal::locallocaltime($details->{'accessstart'})); + } + $output .= '
'. + &mt('To access your LON-CAPA message, go to the Main Menu and click on "Send and Receive Messages".').' '; + if ($address ne '') { + $output.= &mt('An e-mail will also be sent to: [_1] when this occurs.',$address).' '; + } + if ($req_notifylist) { + my $fullname = &Apache::loncommon::plainname($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); + } + } elsif ($disposition eq 'pending') { + $output .= ' '.
+&mt('Your request has been placed in a queue pending administrative action.').' ';
+ } else {
+ $output .= ''. +&mt("Usually this means that your institution's information systems do not list you among the instructional personnel for this course.").' '. +&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('Your request status is: [_1].',$disposition).
+ ' ';
+ }
+ return $output;
+}
+
+sub check_autolimit {
+ my ($uname,$udom,$dom,$crstype,$limit,$message) = @_;
+ my %crsroles = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},
+ 'userroles',['active','future'],['cc','co'],[$dom]);
+ my ($types,$typename) = &Apache::loncommon::course_types();
+ my %requests = &Apache::lonnet::dumpstore('courserequests',$udom,$uname);
+ my $count = 0;
+ foreach my $key (keys(%requests)) {
+ my ($cdom,$cnum) = split('_',$key);
+ if (ref($requests{$key}) eq 'HASH') {
+ next if ($requests{$key}{'crstype'} ne $crstype);
+ if (($crstype eq 'community') &&
+ (exists($crsroles{$cnum.':'.$cdom.':co'}))) {
+ $count ++;
+ } elsif ((($crstype eq 'official') || ($crstype eq 'unofficial')) &&
+ (exists($crsroles{$cnum.':'.$cdom.':cc'}))) {
+ $count ++;
+ }
+ }
+ }
+ if ($count < $limit) {
+ return 'process';
+ } else {
+ if (ref($typename) eq 'HASH') {
+ if ($crstype eq 'community') {
+ $$message = &mt('Your request has not been processed because you have reached the limit for the number of communities.').
+ ''.&mt("Your limit is [_1].",$limit); + } else { + $$message = &mt('Your request has not been processed because you have reached the limit for the number of courses of this type.'). + ' '.&mt("Your $typename->{$crstype} limit is [_1].",$limit); + } + } + return 'rejected'; + } return; } sub retrieve_settings { - my ($dom,$request_id) = @_; - my %reqinfo = &get_request_settings($request_id,$dom); - my %stored; - $stored{'cdescr'} = &unescape($reqinfo{'description'}); - $stored{'startaccess'} = $reqinfo{'startaccess'}; - $stored{'endaccess'} = $reqinfo{'endaccess'}; - if ($stored{'endaccess'} == 0) { - $stored{'no_end_date'} = 1; - } - $stored{'startenroll'} = $reqinfo{'startenroll'}; - $stored{'endenroll'} = $reqinfo{'endenroll'}; - $stored{'crosslist'} = $reqinfo{'crosslist'}; - $stored{'clonecourse'} = $reqinfo{'clonecourse'}; - $stored{'clonedomain'} = $reqinfo{'clonedomain'}; - $stored{'sections'} = $reqinfo{'sections'}; - $stored{'personnel'} = $reqinfo{'personnel'}; - - return %stored; + my ($dom,$cnum,$udom,$uname) = @_; + if ($udom eq '' || $uname eq '') { + $udom = $env{'user.domain'}; + $uname = $env{'user.name'}; + } + my ($result,%reqinfo) = &get_request_settings($dom,$cnum,$udom,$uname); + if ($result eq 'ok') { + if (($udom eq $reqinfo{'domain'}) && ($uname eq $reqinfo{'owner'})) { + $env{'form.chome'} = $reqinfo{'coursehome'}; + $env{'form.cdescr'} = $reqinfo{'cdescr'}; + $env{'form.crstype'} = $reqinfo{'crstype'}; + &generate_date_items($reqinfo{'accessstart'},'accessstart'); + &generate_date_items($reqinfo{'accessend'},'accessend'); + if ($reqinfo{'accessend'} == 0) { + $env{'form.no_end_date'} = 1; + } + if (($reqinfo{'crstype'} eq 'official') && (&Apache::lonnet::auto_run('',$dom))) { + &generate_date_items($reqinfo{'enrollstart'},'enrollstart'); + &generate_date_items($reqinfo{'enrollend'},'enrollend'); + } + $env{'form.clonecrs'} = $reqinfo{'clonecrs'}; + $env{'form.clonedom'} = $reqinfo{'clonedom'}; + $env{'form.datemode'} = $reqinfo{'datemode'}; + $env{'form.dateshift'} = $reqinfo{'dateshift'}; + if (($reqinfo{'crstype'} eq 'official') && ($reqinfo{'instcode'} ne '')) { + $env{'form.sectotal'} = $reqinfo{'sectotal'}; + $env{'form.crosslisttotal'} = $reqinfo{'crosslisttotal'}; + $env{'form.autoadds'} = $reqinfo{'autoadds'}; + $env{'form.autdrops'} = $reqinfo{'autodrops'}; + $env{'form.instcode'} = $reqinfo{'instcode'}; + my $crscode = { + $cnum => $reqinfo{'instcode'}, + }; + &extract_instcode($dom,'instcode',$crscode,$cnum); + } + my @currsec; + if (ref($reqinfo{'sections'}) eq 'HASH') { + foreach my $i (sort(keys(%{$reqinfo{'sections'}}))) { + if (ref($reqinfo{'sections'}{$i}) eq 'HASH') { + my $sec = $reqinfo{'sections'}{$i}{'inst'}; + $env{'form.secnum_'.$i} = $sec; + $env{'form.sec_'.$i} = '1'; + if (!grep(/^\Q$sec\E$/,@currsec)) { + push(@currsec,$sec); + } + $env{'form.loncapasec_'.$i} = $reqinfo{'sections'}{$i}{'loncapa'}; + } + } + } + if (ref($reqinfo{'crosslists'}) eq 'HASH') { + foreach my $i (sort(keys(%{$reqinfo{'crosslists'}}))) { + if (ref($reqinfo{'crosslists'}{$i}) eq 'HASH') { + $env{'form.crosslist_'.$i} = '1'; + $env{'form.crosslist_'.$i.'_instsec'} = $reqinfo{'crosslists'}{$i}{'instsec'}; + $env{'form.crosslist_'.$i.'_lcsec'} = $reqinfo{'crosslists'}{$i}{'loncapa'}; + if ($reqinfo{'crosslists'}{$i}{'instcode'} ne '') { + my $key = $cnum.$i; + my $crscode = { + $key => $reqinfo{'crosslists'}{$i}{'instcode'}, + }; + &extract_instcode($dom,'crosslist',$crscode,$key,$i); + } + } + } + } + if (ref($reqinfo{'personnel'}) eq 'HASH') { + my $i = 0; + foreach my $user (sort(keys(%{$reqinfo{'personnel'}}))) { + my ($uname,$udom) = split(':',$user); + if (ref($reqinfo{'personnel'}{$user}) eq 'HASH') { + if (ref($reqinfo{'personnel'}{$user}{'roles'}) eq 'ARRAY') { + foreach my $role (sort(@{$reqinfo{'personnel'}{$user}{'roles'}})) { + $env{'form.person_'.$i.'_role'} = $role; + $env{'form.person_'.$i.'_firstname'} = $reqinfo{'personnel'}{$user}{'firstname'}; + $env{'form.person_'.$i.'_lastname'} = $reqinfo{'personnel'}{$user}{'lastname'}; ; + $env{'form.person_'.$i.'_emailaddr'} = $reqinfo{'personnel'}{$user}{'emailaddr'}; + $env{'form.person_'.$i.'_uname'} = $uname; + $env{'form.person_'.$i.'_dom'} = $udom; + if (ref($reqinfo{'personnel'}{$user}{$role}) eq 'HASH') { + if (ref($reqinfo{'personnel'}{$user}{$role}{'usec'}) eq 'ARRAY') { + my @usecs = @{$reqinfo{'personnel'}{$user}{$role}{'usec'}}; + my @newsecs; + if (@usecs > 0) { + foreach my $sec (@usecs) { + if (grep(/^\Q$sec\E/,@currsec)) { + $env{'form.person_'.$i.'_sec'} = $sec; + } else { + push(@newsecs,$sec); + } + } + } + if (@newsecs > 0) { + $env{'form.person_'.$i.'_newsec'} = join(',',@newsecs); + } + } + } + $i ++; + } + } + } + } + $env{'form.persontotal'} = $i; + } + } + } + return $result; } sub get_request_settings { - my ($request_id,$dom); + my ($dom,$cnum,$udom,$uname) = @_; + my $requestkey = $dom.'_'.$cnum; + my ($result,%reqinfo); + if ($requestkey =~ /^($match_domain)_($match_courseid)$/) { + my %history = &Apache::lonnet::restore($requestkey,'courserequests',$udom,$uname); + my $disposition = $history{'disposition'}; + if (($disposition eq 'approval') || ($disposition eq 'pending')) { + if (ref($history{'details'}) eq 'HASH') { + %reqinfo = %{$history{'details'}}; + $result = 'ok'; + } else { + $result = 'nothash'; + } + } else { + $result = 'notqueued'; + } + } else { + $result = 'invalid'; + } + return ($result,%reqinfo); +} + +sub extract_instcode { + my ($cdom,$element,$crscode,$crskey,$counter) = @_; + my (%codes,@codetitles,%cat_titles,%cat_order); + if (&Apache::lonnet::auto_instcode_format('requests',$cdom,$crscode,\%codes, + \@codetitles,\%cat_titles, + \%cat_order) eq 'ok') { + if (ref($codes{$crskey}) eq 'HASH') { + if (@codetitles > 0) { + my $sel = $element; + if ($element eq 'crosslist') { + $sel .= '_'.$counter; + } + foreach my $title (@codetitles) { + $env{'form.'.$sel.'_'.$title} = $codes{$crskey}{$title}; + } + } + } + } + return; +} + +sub generate_date_items { + my ($currentval,$item) = @_; + if ($currentval =~ /\d+/) { + my ($tzname,$sec,$min,$hour,$mday,$month,$year) = + &Apache::lonhtmlcommon::get_timedates($currentval); + $env{'form.'.$item.'_day'} = $mday; + $env{'form.'.$item.'_month'} = $month+1; + $env{'form.'.$item.'_year'} = $year; + } + return; } 1; |