Annotation of loncom/interface/lonpopulate.pm, revision 1.91

1.4       albertel    1: # automated enrollment configuration handler
1.91    ! raeburn     2: # $Id: lonpopulate.pm,v 1.90 2021/12/28 02:04:35 raeburn Exp $
1.4       albertel    3: #
                      4: # Copyright Michigan State University Board of Trustees
                      5: #
                      6: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      7: #
                      8: # LON-CAPA is free software; you can redistribute it and/or modify
                      9: # it under the terms of the GNU General Public License as published by
                     10: # the Free Software Foundation; either version 2 of the License, or
                     11: # (at your option) any later version.
                     12: #
                     13: # LON-CAPA is distributed in the hope that it will be useful,
                     14: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: # GNU General Public License for more details.
                     17: #
                     18: # You should have received a copy of the GNU General Public License
                     19: # along with LON-CAPA; if not, write to the Free Software
                     20: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     21: #
                     22: # /home/httpd/html/adm/gpl.txt
                     23: #
                     24: # http://www.lon-capa.org/
                     25: #
1.1       raeburn    26: package Apache::lonpopulate;
                     27: 
                     28: use strict;
                     29: use lib qw(/home/httpd/lib/perl);
1.7       raeburn    30: use Apache::lonnet;
                     31: use Apache::loncommon;
                     32: use Apache::lonhtmlcommon;
1.3       albertel   33: use Apache::lonlocal;
1.14      raeburn    34: use Apache::loncoursedata;
1.43      raeburn    35: use Apache::longroup;
1.51      raeburn    36: use Apache::lonuserutils;
1.1       raeburn    37: use Apache::Constants qw(:common :http REDIRECT);
                     38: use Time::Local;
1.7       raeburn    39: use LONCAPA::Enrollment;
1.87      raeburn    40: use LONCAPA qw(:DEFAULT :match);
1.1       raeburn    41: 
                     42: ###############################################################
                     43: sub header {
1.85      raeburn    44:     my ($action,$permref) = @_;
                     45:     my $args = &make_crumbs($action,$permref);
1.74      raeburn    46:     return 
                     47:         &Apache::loncommon::start_page('Classlist Manager',undef,$args);
1.1       raeburn    48: }
                     49: 
                     50: ###############################################################
                     51: 
                     52: sub choose_header {
1.90      raeburn    53:     my ($action,$permref,$dom) = @_;
1.45      raeburn    54:     my $notify_check = '/^note_[0-9]+$/';
1.90      raeburn    55:     my $additems;
1.83      damieng    56:     my %js_lt = 
1.74      raeburn    57:         &Apache::lonlocal::texthash(
                     58:             adds => 'You must select either "Enable" or "Disable" for nightly additions based on classlist changes',
                     59:             drop => 'You must select either "Enable" or "Disable" for nightly removals based on classlist changes',
                     60:             noup => 'Hence there is no update to carry out',
                     61:             ysno => 'You must select either "Yes" or "No" for immediate removal of unregistered students from the roster',
                     62:             eras => 'Click "OK" to erase all recipients, or "Cancel".',
                     63:             ynot => 'You have indicated that you want notification of roster changes messages to be sent, but you have not selected any recipients.',
                     64:             atle => 'You must check at least one checkbox, before proceeding to the next page',
1.85      raeburn    65:             noed => 'You do not have rights to modify automated enrollment settings',
1.74      raeburn    66:     );
1.83      damieng    67:     $js_lt{'both'} = &mt('You have selected "No" for both addition and removal of students[_1] in the institutional classlist but not in your LON-CAPA course.[_1]',"\n");
                     68:     $js_lt{'nnot'} = &mt('You have indicated that you do not want notification of roster changes messages to be sent, but [_1] have been checked as recipients.[_2]',"'+totalnote+'","\n");
                     69:     &js_escape(\%js_lt);
1.85      raeburn    70: 
                     71:     my $scripttag = '
1.74      raeburn    72: <script type="text/javascript" language="JavaScript">
                     73: // <![CDATA[
1.85      raeburn    74: ';
                     75:     if ((ref($permref) ne 'HASH') || (!$permref->{'edit'})) {
                     76:         $scripttag .= <<ENDJS;
                     77: function process(calling,numauto,nummanual,numlock,numunlock) {
                     78:     alert('$js_lt{'noed'}');
                     79:     return false;
                     80: }
                     81: ENDJS
                     82:     } else {
                     83:         $scripttag .= <<ENDJSONE;
1.16      raeburn    84: function process(calling,numauto,nummanual,numlock,numunlock) {
1.1       raeburn    85:  var checker = 1
                     86:  var rad1 = 0
                     87:  var rad2 = 0
                     88:  var formName = document.forms.enter
1.14      raeburn    89:  if (calling == "viewclass") {
                     90:      formName = document.forms.studentform
                     91:  }
1.1       raeburn    92:  formName.action.value = calling
1.74      raeburn    93:  if (calling == 'chgsettings') {
1.1       raeburn    94:    for (var j=0; j<formName.autoadds.length; j++) {
                     95:        if (formName.autoadds[j].checked) {
1.74      raeburn    96:            rad1 = 1;
1.1       raeburn    97:        }
                     98:    }
                     99:    for (var k=0; k<formName.autodrops.length; k++) {
                    100:        if (formName.autodrops[k].checked) {
1.74      raeburn   101:            rad2 = 1;
1.1       raeburn   102:        }
                    103:    }
                    104:    if (rad1 == 0) {
1.83      damieng   105:        alert('$js_lt{'adds'}');
1.1       raeburn   106:        checker = 0
                    107:    }
                    108:    if (rad2 == 0) {
1.83      damieng   109:        alert('$js_lt{'drop'}');
1.1       raeburn   110:        checker = 0
                    111:    }
                    112:  }
1.74      raeburn   113:  if (calling == 'updatenow') {
                    114:      var enrolldis;
                    115:      var unenrolldis;
1.1       raeburn   116:      for (var j=0; j<formName.updateadds.length; j++) {
                    117:          if (formName.updateadds[j].value == 0) {
1.74      raeburn   118:              enrolldis = j;
1.1       raeburn   119:          }
                    120:          if (formName.updateadds[j].checked) {
1.74      raeburn   121:              rad1 = 1;
1.1       raeburn   122:          }
                    123:      }
                    124:      for (var k=0; k<formName.updatedrops.length; k++) {
                    125:          if (formName.updatedrops[k].value == 0) {
1.74      raeburn   126:              unenrolldis = k;
1.1       raeburn   127:          }
                    128:          if (formName.updatedrops[k].checked) {
1.74      raeburn   129:              rad2 = 1;
1.1       raeburn   130:          }
                    131:      }
                    132:      if (rad1 == 0) {
1.83      damieng   133:          alert('$js_lt{'drop'}');
1.74      raeburn   134:          checker = 0;
1.1       raeburn   135:      }
                    136:      if (rad2 == 0) {
1.83      damieng   137:          alert('$js_lt{'ysno'}');
1.74      raeburn   138:          checker = 0;
1.1       raeburn   139:      }
                    140:      if (formName.updatedrops[unenrolldis].checked && formName.updateadds[enrolldis].checked ) {
1.83      damieng   141:          alert('$js_lt{'both'}$js_lt{'noup'}');
1.74      raeburn   142:          checker = 0;
1.1       raeburn   143:      }
                    144:  }
1.74      raeburn   145:  if (calling == 'notify') {
1.45      raeburn   146:      var totalnote = 0;
1.47      albertel  147:      for (var i=0; i<formName.elements.length; i++) {
                    148: 	 var elementname = formName.elements[i].name;
                    149: 	 var check_name = elementname.match($notify_check);
                    150: 	 if (check_name != null) {
                    151: 	     if (formName.elements[i].checked) {
                    152: 		 totalnote ++;
                    153: 	     }
                    154: 	 } 
                    155:      }
                    156:      if (totalnote > 0) {
                    157: 	 if (formName.notify[1].checked == true) {
1.83      damieng   158: 	     if (confirm('$js_lt{'nnot'}$js_lt{'eras'}')) {
1.74      raeburn   159: 		 checker = 1;
1.47      albertel  160: 	     } else {
                    161: 		 checker = 0;
                    162: 	     }
                    163: 	 }
                    164:      } else {
                    165: 	 if (formName.notify[0].checked == true) {
1.83      damieng   166: 	     alert('$js_lt{'ynot'}');
1.47      albertel  167: 	     checker = 0;
                    168: 	 }
1.45      raeburn   169:      }
                    170:  }
1.74      raeburn   171:  if (calling == 'viewclass') {
                    172:      var totcheck = 0;
                    173:      var numchk = 0;
1.16      raeburn   174:      if (numauto > 0) {
1.20      raeburn   175:          numchk = countChecked(document.studentform.chgauto);
1.74      raeburn   176:          totcheck = totcheck + numchk;
1.16      raeburn   177:      }
                    178:      if (nummanual > 0) {
1.20      raeburn   179:          numchk = countChecked(document.studentform.chgmanual);
1.74      raeburn   180:          totcheck = totcheck + numchk;
1.16      raeburn   181:      }
                    182:      if (numlock > 0) {
1.20      raeburn   183:          numchk = countChecked(document.studentform.lockchg);
1.74      raeburn   184:          totcheck = totcheck + numchk;
1.16      raeburn   185:      }
                    186:      if (numunlock > 0) {
1.20      raeburn   187:          numchk = countChecked(document.studentform.unlockchg);
1.74      raeburn   188:          totcheck = totcheck + numchk;
1.16      raeburn   189:      }
                    190:      if (totcheck > 0) {
1.20      raeburn   191:         document.forms.studentform.state.value = "process";
                    192:      }
                    193:      if (totcheck == 0) {
1.83      damieng   194:         alert('$js_lt{'atle'}')
1.74      raeburn   195:         checker = 0;
1.16      raeburn   196:      }
1.14      raeburn   197:  } 
1.1       raeburn   198:  if (checker == 1) {  
                    199:      formName.submit();
                    200:  }
                    201: }
1.74      raeburn   202: ENDJSONE
1.85      raeburn   203:     }
1.16      raeburn   204:     if ($action eq 'viewclass') {
1.25      raeburn   205:         $scripttag .= &Apache::loncommon::check_uncheck_jscript();
1.74      raeburn   206:         $scripttag .= <<ENDJSTWO;
1.20      raeburn   207: function countChecked(field) {
                    208:     var count = 0;
                    209:     if (field.length > 0) {
                    210:         for (var i=0; i<field.length; i++) {
                    211:             if (field[i].checked == true) {
1.74      raeburn   212:                 count ++;
1.20      raeburn   213:             }
                    214:         }
                    215:     } else {
                    216:         if (field.checked == true) {
1.74      raeburn   217:             count ++;
1.20      raeburn   218:         }
                    219:     }
1.74      raeburn   220:     return count;
1.20      raeburn   221: }
                    222: 
1.74      raeburn   223: ENDJSTWO
1.90      raeburn   224:     } elsif ($action eq 'chgfailsafe') {
                    225:         my %domconfig =
                    226:             &Apache::lonnet::get_dom('configuration',['autoenroll'],$dom);
                    227:         my $includedom = 1;
                    228:         if (ref($domconfig{'autoenroll'}) eq 'HASH') {
                    229:             if ($domconfig{'autoenroll'}->{'failsafe'} eq 'off') {
                    230:                 $includedom = 0;
                    231:             }
                    232:         }
                    233:         $scripttag .= <<ENDJSTHREE;
                    234: 
                    235: function toggleFailsafe(form) {
                    236:     var radioname = 'autodropfailsafetype';
                    237:     var divid = 'autodropfailsafe';
                    238:     var num = form.elements[radioname].length;
                    239:     if (num) {
                    240:         var includedom = '$includedom';
                    241:         var setvis = '';
                    242:         for (var i=0; i<num; i++) {
                    243:             if (form.elements[radioname][i].checked) {
                    244:                 if ((form.elements[radioname][i].value == 'zero') || (form.elements[radioname][i].value == 'any') || ((form.elements[radioname][i].value == 'dom') && (includedom == 1))) {
                    245:                     if (document.getElementById(divid)) {
                    246:                         document.getElementById(divid).style.display = 'inline-block';
                    247:                     }
                    248:                     setvis = 1;
                    249:                 }
                    250:                 break;
                    251:             }
                    252:         }
                    253:         if (!setvis) {
                    254:             if (document.getElementById(divid)) {
                    255:                 document.getElementById(divid).style.display = 'none';
                    256:             }
                    257:         }
                    258:     }
                    259:     return;
                    260: }
                    261: 
                    262: ENDJSTHREE
                    263:         $additems = { 'onload' => "toggleFailsafe(document.enter);" };
1.16      raeburn   264:     }
1.74      raeburn   265:     $scripttag .= <<ENDJS;
                    266: // ]]>
1.1       raeburn   267: </script>
1.74      raeburn   268: ENDJS
1.90      raeburn   269:     my $args = &make_crumbs($action,$permref,$additems);
1.41      albertel  270:     return &Apache::loncommon::start_page('Classlist Manager',
1.74      raeburn   271: 					  $scripttag,$args);
1.1       raeburn   272: }
                    273: 
1.74      raeburn   274: sub make_crumbs {
1.90      raeburn   275:     my ($action,$permref,$additems) = @_;
1.85      raeburn   276:     my ($tasklong,$tasktitle) = &get_task_text($permref);
1.74      raeburn   277:     my $brcrum = [{href=>"/adm/createuser",
                    278:                    text=>"User Management",},
                    279:                  {href=>"/adm/populate",
                    280:                    text=>"Automated Enrollment",
                    281:                    help=>'Course_Automated_Enrollment'},
                    282:                  ];
                    283:     if ($action eq 'newcross') {
                    284:         $action = 'crosslist';
                    285:     } elsif ($action eq 'newsections') {
                    286:         $action = 'sections';
                    287:     }
                    288:     my $text;
                    289:     if (ref($tasklong) eq 'HASH') {
                    290:         $text = $tasklong->{$action};
                    291:     }
                    292:     unless ($action eq 'information') {
                    293:         push(@{$brcrum},
                    294:                  {href => "javascript:backPage(document.crtuser)",
                    295:                   text => $text}
                    296:             );
1.1       raeburn   297:     }
1.74      raeburn   298:     return {bread_crumbs           => $brcrum,
1.90      raeburn   299:             bread_crumbs_component => 'Automated Management',
                    300:             add_entries => $additems};
1.1       raeburn   301: }
                    302: 
                    303: sub print_navmenu {
1.74      raeburn   304:     my ($r,$tasksref,$tasklongref,$action,$state) = @_;
                    305: #LC_pick_box is used in the following. This is only a temporary solution to adapt the site to the design.
                    306:     $r->print('
                    307:     <br />
                    308:     <table width="100%" border="0" cellpadding="0" cellspacing="0" class="LC_pick_box">
                    309:     <tr class="LC_pick_box_row">
                    310:       <td valign="top" class="LC_pick_box_title">
                    311: ');
1.1       raeburn   312:     foreach my $task (@{$tasksref}) {
1.74      raeburn   313:         if (($task eq $action) && ($state eq 'choose')) {
                    314:             $r->print(' 
1.1       raeburn   315:    <p>
1.74      raeburn   316:    <font color="#999999">
                    317:     <b>'.$tasklongref->{$task}.'</b><br/>
1.1       raeburn   318:    </font>
1.74      raeburn   319:    </p>'); 
1.1       raeburn   320:         } else {
1.74      raeburn   321:             $r->print('
1.1       raeburn   322:    <p>
1.74      raeburn   323:    <font color="#004263">
                    324:     <b><a href="/adm/populate?action='.$task.'">'.$tasklongref->{$task}.'</a></b><br/>
1.1       raeburn   325:    </font> 
1.74      raeburn   326:    </p>');
1.1       raeburn   327: 
                    328:         }
                    329:     }
1.74      raeburn   330:     $r->print('
1.1       raeburn   331:   <p>&nbsp;</p>
                    332:   </td>
1.74      raeburn   333:   <td valign="top" class="LC_pick_box_value">');
1.1       raeburn   334: }
                    335: 
                    336: ###############################################################
                    337: 
                    338: sub print_main_frame {
1.85      raeburn   339:   my ($r,$realm,$dom,$crs,$tasktitleref,$permref) = @_;
1.1       raeburn   340:   my $action = "information";
1.23      albertel  341:   if (exists($env{'form.action'}) ) {
                    342:       $action = $env{'form.action'};
1.1       raeburn   343:   }
1.85      raeburn   344:   my ($disabled,$readonly);
                    345:   unless ($permref->{'edit'}) {
                    346:       $disabled = ' disabled="disabled"';
                    347:       $readonly = 1;
                    348:   }
1.1       raeburn   349: 
                    350: # Get course settings
                    351:   my %enrollvar;
                    352:   my %settings = &Apache::lonnet::dump('environment',$dom,$crs);
1.82      raeburn   353:   foreach my $item (keys(%settings)) {
1.1       raeburn   354:       if ($item =~ m/^internal\.(.+)$/) {
                    355:           $enrollvar{$1} = $settings{$item};
1.14      raeburn   356:       } elsif ($item =~ /^default_enrollment_(start|end)_date$/) {
                    357:           $enrollvar{$item} = $settings{$item};
1.1       raeburn   358:       }
                    359:   }
                    360: 
1.74      raeburn   361:   if ($action eq 'information') {
                    362:       $r->print('
                    363:           <br /><table border="0" width="100%">
1.1       raeburn   364:             <tr>
                    365:               <td>&nbsp;</td>
1.74      raeburn   366:               <td><b>'.&mt('Use the menu on the left to choose an enrollment management task.').'</b><br /><br /></td>
1.85      raeburn   367:             </tr>');
                    368:       if ($permref->{'edit'}) {
                    369:           $r->print(' 
1.1       raeburn   370:             <tr>
                    371:               <td>&nbsp;</td>
1.74      raeburn   372:               <td>'.&mt('Use [_1]Automated adds/drops[_2] to enable or disable automatic nightly adds or drops in your LON-CAPA course based on institutional enrollment information.','<i>"','"</i>').'</td>
1.1       raeburn   373:             </tr>
                    374:             <tr>
                    375:               <td>&nbsp;</td>
1.74      raeburn   376:               <td>'.&mt('Use [_1]Change enrollment dates[_2] to change the date of first automated enrollment and/or the date of last automated enrollment for registered students.','<i>"','"</i>').'</td>
1.1       raeburn   377:             </tr>
                    378:             <tr>
                    379:               <td>&nbsp;</td>
1.74      raeburn   380:               <td>'.&mt('Use [_1]Change access dates[_2] to change the default start and/or end dates for student roles created by automated enrollment.','<i>"','"</i>').'</td>
1.14      raeburn   381:             </tr>
                    382:             <tr>
                    383:               <td>&nbsp;</td>
1.74      raeburn   384:               <td>'.&mt('Use [_1]Notification of changes[_2] to enable or disable notification of enrollment changes and to add or remove course coordinators from the recipient list.','<i>"','"</i>').'</td>
1.1       raeburn   385:             </tr>
                    386:             <tr>
                    387:               <td>&nbsp;</td>
1.74      raeburn   388:               <td>'.&mt('Use [_1]Change crosslisting[_2] to include or exclude enrollment from crosslisted classes.',
                    389:                         '<i>"','"</i>').'</td>
1.1       raeburn   390:             </tr>
                    391:             <tr>
                    392:               <td>&nbsp;</td>
1.74      raeburn   393:               <td>'.&mt('Use [_1]Section settings[_2] to make changes to the choice of sections included for enrollment in your LON-CAPA course.',
                    394:                         '<i>"','"</i>').'</td>
1.1       raeburn   395:             </tr>
1.74      raeburn   396:             <tr>
1.1       raeburn   397:               <td>&nbsp;</td>
1.74      raeburn   398:               <td>'.&mt('Use [_1]Student photo settings[_2] to enable or disable automatic import of photos for registered students in your course.',
                    399:                         '<i>"','"</i>').'</td>
1.1       raeburn   400:             </tr>
                    401:             <tr>
                    402:               <td>&nbsp;</td>
1.74      raeburn   403:               <td>'.&mt('Use [_1]Update roster now[_2] to add and/or drop students from your course based on the [_3]most current[_4] institutional classlist information.','<i>"','"</i>','<b>','</b>').'</td>
1.1       raeburn   404:             </tr>
                    405:             <tr>
1.16      raeburn   406:               <td>&nbsp;</td>
1.74      raeburn   407:               <td>'.&mt("Use [_1]Update student photos[_2] to import your institution's [_3]most current[_4] digital photos for registered students in your course.",'<i>"','"</i>','<b>','</b>').'</td>
1.34      raeburn   408:             </tr>
                    409:             <tr>
                    410:               <td>&nbsp;</td>
1.74      raeburn   411:               <td>'.&mt('Use [_1]View students and change type[_2] to display the current course roster, and (optionally) change enrollment type for selected students from "auto" to "manual" and vice versa.','<i>"','"</i>').'</td>
1.16      raeburn   412:             </tr>
                    413:             <tr>
1.90      raeburn   414:              <td>&nbsp;</td>
                    415:              <td>'.&mt('Use [_1]View/change enrollment failsafe[_2] to (a) set number of drops from existing enrollments in an institutional section above which no automated drops will occur (e.g., when section enrollment retrieved from institutional data is incomplete) and (b) set whether this only applies when retrieved data contains zero records for the institutional section.','<i>"','"</i>').'</td>
1.85      raeburn   416:             </tr>');
                    417:       } else {
                    418:           if (($permref->{'view'}) || ($permref->{'view_section'} ne '')) {
                    419:               $r->print('
                    420:             <tr>
                    421:               <td>&nbsp;</td>
                    422:               <td>'.&mt('Use [_1]Automated adds/drops[_2] to display status of automatic nightly adds or drops based on institutional enrollment information.','<i>"','"</i>').'</td>
                    423:             </tr>
                    424:             <tr>
                    425:               <td>&nbsp;</td>
                    426:               <td>'.&mt('Use [_1]Enrollment dates[_2] to display the date of first automated enrollment and last automated enrollment for registered students.','<i>"','"</i>').'</td>
                    427:             </tr>
                    428:             <tr>
                    429:               <td>&nbsp;</td>
                    430:               <td>'.&mt('Use [_1]Access dates[_2] to display the default start and/or end dates for student roles created by automated enrollment.','<i>"','"</i>').'</td>
                    431:             </tr>
                    432:             <tr>
                    433:               <td>&nbsp;</td>
                    434:               <td>'.&mt('Use [_1]Notification of changes[_2] to display which course coordinators (if any) receive notification of enrollment changes.','<i>"','"</i>').'</td>
                    435:             </tr>
                    436:             <tr>
                    437:               <td>&nbsp;</td>
                    438:               <td>'.&mt('Use [_1]Crosslisting[_2] to display enrollment settings for crosslisted classes.',
                    439:                         '<i>"','"</i>').'</td>
                    440:             </tr>
                    441:             <tr>
                    442:               <td>&nbsp;</td>
                    443:               <td>'.&mt('Use [_1]Section settings[_2] to display sections included for enrollment.',
                    444:                         '<i>"','"</i>').'</td>
                    445:             </tr>
                    446:             <tr>
                    447:               <td>&nbsp;</td>
                    448:               <td>'.&mt('Use [_1]Student photo settings[_2] to display settings for automatic import of photos for registered students.',
                    449:                         '<i>"','"</i>').'</td>
1.84      raeburn   450:             </tr>
                    451:             <tr>
1.90      raeburn   452:              <td>&nbsp;</td>
                    453:              <td>'.&mt('Use [_1]Enrollment failsafe[_2] to display (a) number of drops from existing enrollments in an institutional section above which no automated drops occur (e.g., when section enrollment retrieved from institutional data is incomplete), and (b) whether this only applies when retrieved data contains zero records for the institutional section.','<i>"','"</i>').'</td>
1.85      raeburn   454:             </tr>');
                    455:           }
                    456:           if (($permref->{'show'}) || ($permref->{'show_section'} ne '')) {
                    457:               $r->print('
                    458:             <tr>
                    459:               <td>&nbsp;</td>
                    460:               <td>'.&mt('Use [_1]View students and enrollment type[_2] to display the current course roster and enrollment type ("auto" or "manual").','<i>"','"</i>').'</td>
                    461:             </tr>');
                    462:           }
                    463:           $r->print('
                    464:             <tr>
1.74      raeburn   465:              <td colspan="2">&nbsp;</td>
1.1       raeburn   466:             </tr>
                    467:             <tr>
                    468:              <td>&nbsp;</td>
1.74      raeburn   469:              <td><b>'.&mt('Note: if automated adds and/or drops are enabled, the nightly enrollment update will ONLY occur once the first enrollment date has been reached.').'</b></td>
1.1       raeburn   470:             </tr>
1.74      raeburn   471:           </table>');
1.85      raeburn   472:       }
1.74      raeburn   473:   } elsif ($action eq 'chgsettings') {
                    474:       my @autosets = (&mt('OFF'),&mt('ON'));
                    475:       $r->print('
                    476:                   <form name="enter" method="post" action=""><br />
1.1       raeburn   477: 		  <table width="100%" border="0" cellpadding="2" cellspacing="2">
                    478: 		   <tr>
1.74      raeburn   479: 		    <td align="left"><b>'.$$tasktitleref{$action}.'</b><br />
                    480: 		       '.&mt('Currently: Nightly adds: [_1], Nightly drops: [_2]',"<i>$autosets[$enrollvar{autoadds}]</i>","<i>$autosets[$enrollvar{autodrops}]</i>").'
1.1       raeburn   481: 		    </td>
                    482:                    </tr>
                    483: 		  </table>
                    484: 		  <table width="100%" border="0" cellpadding="3" cellspacing="3">
                    485: 		    <tr>
                    486: 		     <td>
1.74      raeburn   487: 		        '.&mt('Additions based on classlist changes:').'&nbsp;&nbsp;');
1.1       raeburn   488:       if ($enrollvar{autoadds}) {
1.74      raeburn   489:           $r->print('
1.85      raeburn   490: 			    <label><input type="radio" name="autoadds" value="1" checked="checked"'.$disabled.' />&nbsp;'.
1.74      raeburn   491:                             &mt('Enable').'&nbsp;&nbsp;&nbsp;</label>
1.85      raeburn   492: 			    <label><input type="radio" name="autoadds" value="0"'.$disabled.' />&nbsp;'.
1.74      raeburn   493:                             &mt('Disable').'</label>');
1.1       raeburn   494:       } else {
1.74      raeburn   495:           $r->print('
1.85      raeburn   496:                             <label><input type="radio" name="autoadds" value="1"'.$disabled.' />&nbsp;'.
1.74      raeburn   497:                             &mt('Enable').'&nbsp;&nbsp;&nbsp;</label>
1.85      raeburn   498:                             <label><input type="radio" name="autoadds" value="0" checked="checked"'.$disabled.' />&nbsp;'.
1.74      raeburn   499:                             &mt('Disable').'</label>');
1.1       raeburn   500:       }
1.74      raeburn   501:       $r->print('
1.1       raeburn   502:               </td>
                    503:              </tr>
                    504:              <tr>
                    505:               <td>
1.74      raeburn   506:  	       '.&mt('Removals based on classlist changes:').'&nbsp;&nbsp;');
1.1       raeburn   507:       if ($enrollvar{autodrops}) {
1.74      raeburn   508:           $r->print('
1.85      raeburn   509:                 <label><input type="radio" name="autodrops" value="1" checked="checked"'.$disabled.' />&nbsp;'.
1.74      raeburn   510:                 &mt('Enable').'&nbsp;&nbsp;&nbsp;</label>
1.85      raeburn   511:                 <label><input type="radio" name="autodrops" value="0"'.$disabled.' />&nbsp;'.
1.74      raeburn   512:                 &mt('Disable').'</label>');
1.1       raeburn   513:       } else {
1.74      raeburn   514:           $r->print('
1.85      raeburn   515:                 <label><input type="radio" name="autodrops" value="1"'.$disabled.' />&nbsp;'.
1.74      raeburn   516:                 &mt('Enable').'&nbsp;&nbsp;&nbsp;</label>
1.85      raeburn   517:                 <label><input type="radio" name="autodrops" value="0" checked="checked"'.$disabled,' />&nbsp;'.
1.74      raeburn   518:                 &mt('Disable').'</label>');
1.1       raeburn   519:       }
1.74      raeburn   520:       $r->print('
1.1       raeburn   521:               </td>
                    522:              </tr>
                    523:              <tr>
                    524:               <td>
1.74      raeburn   525:                <span style="color: #888888">'.
                    526: &mt('Note: Any students added manually by course coordinators using the User Manager will be unaffected by the nightly removal process if you choose to enable it.').'
                    527:                </span>
1.1       raeburn   528:               </td>
                    529:              </tr>
                    530:              <tr>
1.74      raeburn   531:               <td align="right">
1.85      raeburn   532:                <input type="button" name="chgsettings" value="'.&mt('Go').'" onclick="process('."'chgsettings'".')"'.$disabled.' />
1.1       raeburn   533: 	      </td>
                    534:              </tr>
                    535: 	    </table>
1.74      raeburn   536:             <input type="hidden" name="action" value="'.$action.'" />
                    537:             <input type="hidden" name="state" value="process" />
                    538:             </form>'."\n");
1.84      raeburn   539:   } elsif ($action eq 'chgfailsafe') {
1.90      raeburn   540:       my ($autofailsafe,$failsafetype,$failsafesty,%failsafechecked);
                    541:       $failsafesty = 'inline-block';
                    542:       %failsafechecked = (
                    543:           dom => ' checked="checked"',
                    544:       );
                    545:       my $domdefault;
1.84      raeburn   546:       my %domconfig =
                    547:           &Apache::lonnet::get_dom('configuration',['autoenroll'],$dom);
                    548:       if (ref($domconfig{'autoenroll'}) eq 'HASH') {
                    549:           $autofailsafe = $domconfig{'autoenroll'}->{'autofailsafe'};
                    550:           if ($autofailsafe =~ /\D/) {
                    551:               undef($autofailsafe);
                    552:           }
1.90      raeburn   553:           if ($domconfig{'autoenroll'}->{'failsafe'} eq 'off') {
                    554:               undef($autofailsafe);
                    555:               $failsafesty = 'none';
                    556:               $failsafetype = 'off';
                    557:               $domdefault = &mt('Failsafe is not in use.');
                    558:           } elsif ($domconfig{'autoenroll'}->{'failsafe'} eq 'any') {
                    559:               $failsafesty = 'inline-block';
                    560:               $failsafetype = 'any';
                    561:               $domdefault = &mt('Failsafe will apply if retrieved enrollment for institutional section is zero or greater.');
                    562:           } else {
                    563:               $failsafesty = 'inline-block';
                    564:               $failsafetype = 'zero';
                    565:               $domdefault = &mt('Failsafe will only apply if retrieved enrollment for institutional section is zero.');
                    566:           }
                    567:       }
                    568:       if ((exists($enrollvar{'autodropfailsafetype'})) &&
                    569:           ($enrollvar{'autodropfailsafetype'} ne '')) {
                    570:           if ($enrollvar{'autodropfailsafetype'} eq 'off') {
                    571:               $failsafesty = 'none';
                    572:               $failsafechecked{'dom'} = '';
                    573:               $failsafechecked{'off'} = ' checked="checked"';
                    574:           } elsif ($enrollvar{'autodropfailsafetype'} eq 'any') {
                    575:               $failsafesty = 'inline-block';
                    576:               $failsafechecked{'dom'} = '';
                    577:               $failsafechecked{'any'} = ' checked="checked"';
                    578:           } elsif ($enrollvar{'autodropfailsafetype'} eq 'zero') {
                    579:               $failsafesty = 'inline-block';
                    580:               $failsafechecked{'dom'} = '';
                    581:               $failsafechecked{'zero'} = ' checked="checked"';
                    582:           }
1.84      raeburn   583:       }
                    584:       $r->print('
                    585:           <form name="enter" method="post" action=""><br />
                    586:            <table width="100%" border="0" cellpadding="2" cellspacing="2">
                    587:             <tr>
                    588:              <td align="left"><b>'.$$tasktitleref{$action}.'</b><br /><p>'.
1.90      raeburn   589:              &mt('The "failsafe" mechanism for automated enrollment can prevent unwanted expiration of student roles for registered students in an institutional section, in the case where either no enrollment, or only partial enrollment, is returned for that particular section because of a temporary institutional data retrieval problem external to LON-CAPA.').'</p>'.
                    590:             '<p>'.&mt('For example if the threshold is set to 10, and the current LON-CAPA enrollment count is 11 or more for a particular course section, no role expiration will occur if the latest retrieved enrollment count is zero for that institutional section (or cross-listing).').'</p>');
1.84      raeburn   591:       if ($enrollvar{'autodropfailsafe'} eq '') {
1.90      raeburn   592:           $r->print('<p>'.&mt('Currently no course-specific failsafe threshold is set.').' ');
1.84      raeburn   593:           if ($autofailsafe eq '') {
                    594:               $r->print(&mt('Currently no domain default failsafe is set either.'));
                    595:           } else {
1.90      raeburn   596:               $r->print(&mt('The current domain default of [_1] will apply unless a value is set here specific to this course.','<b>'.$autofailsafe.'</b>'));
1.84      raeburn   597:           }
                    598:           $r->print('</p>');
                    599:       } else {
1.90      raeburn   600:           unless (($enrollvar{'autodropfailsafetype'} eq 'off') || 
                    601:                   (($enrollvar{'autodropfailsafetype'} eq '') && ($failsafetype eq 'off'))) {
                    602:               $r->print('<p>'.&mt('Currently, the course-specific failsafe is set to [_1].',"<i>$enrollvar{'autodropfailsafe'}</i>").'</p>');
                    603:           }
                    604:       }
                    605:       unless (($enrollvar{'autodropfailsafe'} eq '') && ($autofailsafe eq '')) {
                    606:           if ($enrollvar{'autodropfailsafetype'} eq '') {
                    607:               $r->print('<p>'.&mt('Currently no course-specific failsafe condition is set.').' ');
                    608:               if ($failsafetype eq 'any') {
                    609:                   $r->print(&mt('The current domain default, whereby the failsafe is in effect if the retrieved section enrollment is zero or greater, will apply unless overridden here for this specific course.'));
                    610:               } elsif ($failsafetype eq 'zero') {
                    611:                   $r->print(&mt('The current domain default, whereby the failsafe is only in effect if the retrieved section enrollment is zero, will apply unless overridden here for this specific course.'));
                    612:               } elsif ($failsafetype eq 'off') {
                    613:                   $r->print(&mt('The current domain default (failsafe not in use) will apply unless overridden here for this specific course.'));
                    614:               }
                    615:               $r->print('</p>');
                    616:           } else {
                    617:               if ($enrollvar{'autodropfailsafetype'} eq 'zero') {
                    618:                   $r->print('<p>'.&mt('Currently, the course-specific failsafe condition is set such that any failsafe threshold is only in effect when the retrieved institutional section enrollment is zero.'));
                    619:               } elsif ($enrollvar{'autodropfailsafetype'} eq 'any') {
                    620:                   $r->print('<p>'.&mt('Currently, the course-specific failsafe condition is set such that any failsafe threshold is in effect when the retrieved institutional section enrollment is zero (or greater).'));
                    621:               } elsif ($enrollvar{'autodropfailsafetype'} eq 'off') {
                    622:                   $r->print('<p>'.&mt('Currently, the course-specific failsafe condition is set such that a failsafe will not be used.'));
                    623:               }
                    624:               $r->print('</p>');
                    625:           }
1.84      raeburn   626:       }
                    627:       $r->print('
                    628:              </td>
                    629:             </tr>
                    630:            </table>
                    631:            <table width="100%" border="0" cellpadding="3" cellspacing="3">
1.90      raeburn   632:              <tr>
                    633:              <td><b>'.&mt('Condition for use of failsafe in this course').'</b><br />
                    634:              <span class="LC_nobreak"><label><input type="radio" name="autodropfailsafetype" value="dom" onclick="toggleFailsafe(this.form);"'.$failsafechecked{'dom'}.$disabled.' />'.&mt('Use domain default').'</label></span>&nbsp;--&nbsp;'.$domdefault.'<br />
                    635:              <span class="LC_nobreak"><label><input type="radio" name="autodropfailsafetype" value="zero" onclick="toggleFailsafe(this.form);"'.$failsafechecked{'zero'}.$disabled.' />'.&mt('Failsafe will apply if retrieved institutional section enrollment is zero.').'</label></span><br />
                    636:              <span class="LC_nobreak"><label><input type="radio" name="autodropfailsafetype" value="any" onclick="toggleFailsafe(this.form);"'.$failsafechecked{'any'}.$disabled.' />'.&mt('Failsafe will apply if retrieved institutional section enrollment is zero or greater.').'</label></span><br />
                    637:              <span class="LC_nobreak"><label><input type="radio" name="autodropfailsafetype" value="off" onclick="toggleFailsafe(this.form);"'.$failsafechecked{'off'}.$disabled.' />'.&mt('Failsafe will not be in use in this course.').'</label></span><br />
                    638:              <div class="LC_floatleft" style="display:'.$failsafesty.';" id="autodropfailsafe">
                    639:              <span class="LC_nobreak"><b>'.
                    640:              &mt('Failsafe threshold (enter an integer)').'</b>&nbsp;&nbsp;
                    641:              <input type="text" name="autodropfailsafe" value="'.$enrollvar{'autodropfailsafe'}.'" size="4"'.$disabled.' /></span><br />');
                    642:        if ($autofailsafe) {
                    643:            $r->print(&mt('Leave blank to use domain default of [_1].','<b>'.$autofailsafe.'</b>'));
                    644:        } else {
                    645:            $r->print(&mt('As no domain default is set, failsafe will not be used if blank.'));
1.84      raeburn   646:        }
1.90      raeburn   647:        $r->print('</div>
1.84      raeburn   648:              </td>
                    649:             </tr>
                    650:             <tr>
                    651:               <td>&nbsp;</td>
                    652:             </tr>
                    653:             <tr>
                    654:               <td>'.&mt('Push "Go" to save your changes').'
                    655:             <tr>
                    656:               <td>&nbsp;</td>
                    657:             </tr>
                    658:             <tr>
                    659:              <td align="right">
1.85      raeburn   660:               <input type="button" name="updatefailsafe" value="'.&mt('Go').'" onclick="'."process('chgfailsafe')".'"'.$disabled.' />
1.84      raeburn   661:              </td>
                    662:             </tr>
                    663:            </table>
                    664:            <input type="hidden" name="action" value="'.$action.'" />
                    665:            <input type="hidden" name="state" value="process" />
                    666:            </form>'."\n");
1.74      raeburn   667:   } elsif ($action eq 'setdates') {
1.85      raeburn   668:       my ($start_table,$end_table) = &date_setting_table($enrollvar{autostart},$enrollvar{autoend},$action,$readonly);
1.10      raeburn   669:       my $oldstartshow = '';
                    670:       my $oldendshow = '';
                    671:       if ( defined($enrollvar{autostart}) ) {
1.14      raeburn   672:           $oldstartshow = &Apache::lonlocal::locallocaltime($enrollvar{autostart});
1.10      raeburn   673:       }
                    674:       if ( defined($enrollvar{autoend}) ) {
1.14      raeburn   675:           $oldendshow = &Apache::lonlocal::locallocaltime($enrollvar{autoend});
1.10      raeburn   676:           if ($enrollvar{autoend} == 0) {
1.74      raeburn   677:               $oldendshow = &mt("'No end date'");
1.10      raeburn   678:           }
                    679:       }
                    680:       my $dateshow;
                    681:       if ( ($oldendshow eq '') && ($oldstartshow eq '') ) {
1.74      raeburn   682:          $dateshow = '<br /><span class="LC_warning"><b>'.&mt('Warning.').'</b> '.&mt('Currently [_1]NO[_2] first enrollment or last enrollment dates are set.','<b>','</b>').' '.
                    683:                      &mt('You [_1]must[_2] use this menu to set a start date and an end date if you plan to utilise automated adds and/or drops in this course.','<b>','</b>')."</span>\n";
1.10      raeburn   684:       } else {
1.74      raeburn   685:          $dateshow = &mt('Currently: First enrollment[_1] Last enrollment[_2]',
                    686:                          " -- <b><i>$oldstartshow</i></b>"," -- <b><i>$oldendshow</i></b>")."\n";
1.1       raeburn   687:       }
1.74      raeburn   688:       $r->print('
                    689:                   <form name="enter" method="post" action=""><br />              
1.1       raeburn   690:                   <table width="100%" border="0" cellpadding="2" cellspacing="2">
                    691: 	           <tr>
1.74      raeburn   692: 	            <td align="left"><b>'.$$tasktitleref{$action}.'</b><br /><br />
                    693:                      '.$dateshow.'
1.1       raeburn   694: 	            </td>
                    695:                    </tr>
                    696: 	          </table>
                    697:                   <table width="100%" border="0" cellpadding="3" cellspacing="3">
                    698:                    <tr>
                    699:                     <td align="left" colspan="2">
                    700:                      <table border="0" cellspacing="0" cellpadding="2">
                    701:                       <tr>
                    702:                        <td colspan="3">
1.74      raeburn   703:                         <i>'.&mt('Set date of first automated enrollment for registered students').'</i>
1.1       raeburn   704:                        </td>
                    705:                       </tr>
                    706:                       <tr>
1.74      raeburn   707:                        <td>'.$start_table.'
1.1       raeburn   708:                        </td>
                    709:                       </tr>
                    710:                      </table>
                    711:                     </td>
                    712:                    </tr>
                    713:                    <tr>
1.74      raeburn   714:                     <td colspan="2"><span style="color: #888888">'.
                    715:                     &mt('If automated adds and/or drops are enabled, then your class roster will be automatically updated nightly, once the first enrollment date has been reached. Prior to this date, the class roster will only contain students you have added directly using the standard LON-CAPA enrollment tools.').'</span></td>
1.1       raeburn   716:                    </tr>
                    717:                    <tr>
                    718:                     <td align="left" colspan="2">
1.74      raeburn   719:                      <table border="0" cellspacing="0" cellpadding="2">
1.1       raeburn   720:                       <tr>
                    721:                        <td colspan="3">
1.74      raeburn   722:                         <i>'.&mt('Set date of last automated enrollment for registered students').'</i>
1.1       raeburn   723:                        </td>
                    724:                       </tr>
                    725:                       <tr>
1.74      raeburn   726:                        <td>'.$end_table.'
1.1       raeburn   727:                        </td>
                    728:                       </tr>
                    729:                      </table>
                    730:                     </td>
                    731:                    </tr>
                    732:                    <tr>
1.74      raeburn   733:                     <td colspan="2"><span style="color: #888888">'.&mt('If automated adds and/or drops are enabled, then your class roster will be automatically updated nightly, until the last enrollment date has been reached.').'</span></td>
1.1       raeburn   734:                    </tr>
                    735:                   </table>
                    736:                   <table width="100%">
                    737:                    <tr>
                    738:                     <td align="right">
1.85      raeburn   739:                       <input type="button" name="setdates" value="'.&mt('Go').'" onclick="process('."'setdates'".')"'.$disabled.' />
1.1       raeburn   740:                     </td>
                    741: 	           </tr>
                    742:                   </table>
1.74      raeburn   743:                   <input type="hidden" name="action" value="'.$action.'" />
1.39      albertel  744:                   <input type="hidden" name="state" value="process" />
1.14      raeburn   745:                   </form>
1.74      raeburn   746: ');
                    747:   } elsif ($action eq 'setaccess') {
1.85      raeburn   748:       &print_accessdate_table($r,\%enrollvar,$tasktitleref,$action,$readonly);
1.74      raeburn   749:       $r->print('
1.14      raeburn   750:                   <table width="100%">
                    751:                    <tr>
                    752:                     <td align="right">
1.85      raeburn   753:                       <input type="button" name="'.$action.'" value="'.&mt('Go').'" onclick="'."process('$action')".'"'.$disabled.' />
1.14      raeburn   754:                     </td>
                    755:                    </tr>
                    756:                   </table>
1.74      raeburn   757:                   <input type="hidden" name="action" value="'.$action.'" />
1.39      albertel  758:                   <input type="hidden" name="state" value="process" />
1.1       raeburn   759:                   </form>
1.74      raeburn   760:       ');
                    761:   } elsif ($action eq 'notify') {
1.30      raeburn   762:       my $notifycount = 0;
1.28      albertel  763:       my @notified = split(/,/,$enrollvar{notifylist});
1.65      raeburn   764:       my (@domcoord,@showdom,@olddomcoord,@futuredomcoord);
1.42      raeburn   765:       for (my $i=0; $i<@notified; $i++) {
                    766:           if ($notified[$i] !~ /:/) {
                    767:               $notified[$i] =~ s/\@/:/;
                    768:           }
                    769: 	  unless ($notified[$i] eq '') { $notifycount ++; } 
1.1       raeburn   770:       }
                    771:       my $noteset = '';
                    772:       if ($notifycount) {
1.74      raeburn   773:           $noteset = &mt('ON');
1.1       raeburn   774:       } else {
1.74      raeburn   775:           $noteset = &mt('OFF');
1.1       raeburn   776:       }
1.65      raeburn   777:       my $now = time;
1.44      raeburn   778:       my %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc']);
1.45      raeburn   779:       foreach my $server (keys(%dompersonnel)) {
                    780:           foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
1.44      raeburn   781:               my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
1.65      raeburn   782:               my ($end,$start) = split(':',$dompersonnel{$server}{$user});
                    783:               if (($end eq '') || ($end == 0) || ($end > $now)) {
                    784:                   if ($start > $now) {
                    785:                       if (!grep(/^\Q$uname\E:\Q$udom\E$/,@futuredomcoord)) {
                    786:                           push(@futuredomcoord,$uname.':'.$udom);
                    787:                       }
                    788:                   } else {
                    789:                       if (!grep(/^\Q$uname\E:\Q$udom\E$/,@domcoord)) {
                    790:                           push(@domcoord,$uname.':'.$udom);
                    791:                       }
                    792:                   }
                    793:               } else {
                    794:                   if (!grep(/^\Q$uname\E:\Q$udom\E$/,@olddomcoord)) {
                    795:                       push(@olddomcoord,$uname.':'.$udom);
                    796:                   }
1.44      raeburn   797:               }
                    798:           }
                    799:       }
1.74      raeburn   800:       $r->print('
                    801:                   <form name="enter" method="post" action=""><br />
                    802:                    <table width="100%" border="0" cellpadding="6" cellspacing="0">
1.1       raeburn   803:                     <tr>
1.74      raeburn   804:                      <td align="left"><b>'.$tasktitleref->{$action}.'</b><br />'.
                    805:                       &mt('Currently -- Notification:').' '.$noteset.'
1.1       raeburn   806:                      </td>
                    807:                     </tr>
                    808:                    </table>
1.74      raeburn   809:                    <table width="100%" border="0" cellpadding="3" cellspacing="3">
1.1       raeburn   810:                     <tr>
1.74      raeburn   811:                      <td>'.
                    812:                      &mt('Notification of LON-CAPA course roster changes resulting from nightly automated enrollment process?')
                    813:       );
1.1       raeburn   814:       if ($notifycount) {
1.74      raeburn   815:           $r->print('
1.85      raeburn   816:                         <label><input type="radio" name="notify" value="1" checked="checked"'.$disabled.' />&nbsp;'.&mt('Yes').'&nbsp;&nbsp;&nbsp;</label>
                    817:                         <label><input type="radio" name="notify" value="0"'.$disabled.' />&nbsp;'.&mt('No').'</label>
1.74      raeburn   818:           ');
1.1       raeburn   819:       } else {
1.74      raeburn   820:           $r->print('
1.85      raeburn   821:                         <label><input type="radio" name="notify" value="1"'.$disabled.' />&nbsp;'.&mt('Yes').'&nbsp;&nbsp;&nbsp;</label>
                    822:                         <label><input type="radio" name="notify" value="0" checked="checked"'.$disabled.' />&nbsp;'.&mt('No').'</label>
1.74      raeburn   823:           ');
1.1       raeburn   824:       }
1.74      raeburn   825:       $r->print('
1.1       raeburn   826:               </td>
                    827:              </tr>
1.74      raeburn   828:       ');
1.44      raeburn   829:       my %coursepersonnel = &Apache::lonnet::dump('nohist_userroles',$dom,$crs);
                    830:       my @ccs;
                    831:       my %pname;
                    832:       my %notifystate;
                    833:       my %status;
                    834:       foreach my $person (sort(keys(%coursepersonnel))) {
                    835:           my $match = 0;
                    836:           my ($role,$user,$usec) = ($person =~ /^([^:]+):([^:]+:[^:]+):([^:]*)/);
                    837:           $user =~ s/:$//;
                    838:           my ($end,$start) = split(/:/,$coursepersonnel{$person});
                    839:           if ($end == -1 || $start == -1) {
                    840:               next;
                    841:           }
                    842:           if ($role eq 'cc')  {
1.45      raeburn   843:               unless (grep(/^$user$/,@ccs)) {
1.44      raeburn   844:                   if ($end && $end < $now) {
                    845:                       $status{$user} = 'previous';
                    846:                   } elsif ($start > $now) {
                    847:                       $status{$user} = 'future';
                    848:                   } else {
                    849:                       $status{$user} = 'active';
                    850:                   }
                    851:                   push(@ccs,$user);
                    852:                   my ($uname,$udom) = split(/:/,$user);
                    853:                   $pname{$user} = 
                    854:                            &Apache::loncommon::plainname($uname,$udom);
1.45      raeburn   855:                   if (grep(/^$user$/,@notified)) {
1.44      raeburn   856:                       $notifystate{$user} = 1;
1.1       raeburn   857:                   } else {
1.44      raeburn   858:                       $notifystate{$user} = 0;
1.1       raeburn   859:                   }
                    860:               }
                    861:           }
                    862:       }
1.45      raeburn   863:       my $notifyshow = 0; 
1.44      raeburn   864:       my %lt = &Apache::lonlocal::texthash(
                    865:                                   name => 'Name',
                    866:                                   usnm => 'username:domain',
                    867:                                   coac => 'Course Access',
                    868:                                   curn => 'Current notification status',
1.65      raeburn   869:                                   doms => 'Domain Coordinator status',
1.44      raeburn   870:                                   notf => 'Notification?',
                    871:                                   ntac => 'Notification active',
                    872:                                   ntin => 'Notification inactive',
                    873:       );
1.7       raeburn   874:       if (@ccs > 0) {
                    875:           @ccs = sort @ccs;
1.74      raeburn   876:           $r->print('
1.1       raeburn   877:              <tr>
1.74      raeburn   878:                <td>'.&mt('The table below contains a list of [_1]s in this course.',&Apache::lonnet::plaintext('cc')).'
1.1       raeburn   879:               </td>
                    880:              </tr>
                    881:              <tr>
1.74      raeburn   882:               <td>
                    883:           ');
1.44      raeburn   884:           $r->print(&notifier_tables('cc',\%lt,\@ccs,\%status,\%notifystate,
1.85      raeburn   885:                                      \%pname,\$notifyshow,undef,undef,$disabled));
1.74      raeburn   886:           $r->print('</td></tr>');
1.44      raeburn   887:       } else {
1.74      raeburn   888:           $r->print('
1.44      raeburn   889:              <tr>
1.74      raeburn   890:               <td>'.
                    891:              &mt('No [_1]s found.',
                    892:                  &Apache::lonnet::plaintext('cc')).'
1.44      raeburn   893:             </td>
1.74      raeburn   894:            </tr>
                    895:           ');
1.44      raeburn   896:       }
                    897:       my $viewer = $env{'user.name'}.':'.$env{'user.domain'};
                    898:       my $showalldc = 0;
1.74      raeburn   899:       if (grep(/^\Q$viewer\E$/,@domcoord)) {
1.44      raeburn   900:           $showalldc = 1;
                    901:       }
1.65      raeburn   902:       foreach my $dc (@domcoord,@futuredomcoord) {
1.74      raeburn   903:           if (!grep(/^\Q$dc\E$/,@ccs)) {
                    904:               if (grep(/^\Q$dc\E$/,@notified)) {
1.44      raeburn   905:                   $notifystate{$dc} = 1;
1.7       raeburn   906:               } else {
1.44      raeburn   907:                   $notifystate{$dc} = 0;
                    908:                   if (!$showalldc) {
                    909:                       next;
                    910:                   }
1.7       raeburn   911:               }
1.44      raeburn   912:               my ($dcuname,$dcdom) = split(/:/,$dc);
                    913:               $pname{$dc} =  &Apache::loncommon::plainname($dcuname,$dcdom);
                    914:               push(@showdom,$dc);
1.7       raeburn   915:           }
1.44      raeburn   916:       }
1.65      raeburn   917:       foreach my $olddc (@olddomcoord) {
1.74      raeburn   918:           if (grep(/^\Q$olddc\E$/,@notified)) {
1.65      raeburn   919:               if (!grep(/^\Q$olddc\E$/,@ccs)) {
                    920:                   $notifystate{$olddc} = 1;
                    921:                   my ($dcname,$dcdom) = split(/:/,$olddc);
                    922:                   $pname{$olddc} =  &Apache::loncommon::plainname($dcname,$dcdom);
                    923:                   push(@showdom,$olddc);
                    924:               }
                    925:           }
                    926:       }
1.44      raeburn   927:       my $showdomnum = scalar(@showdom);
                    928:       if ($showdomnum) {
1.74      raeburn   929:           $r->print('
1.44      raeburn   930:              <tr>
                    931:               <td>&nbsp;</td>
                    932:              </tr><tr>
1.74      raeburn   933:               <td>');
1.44      raeburn   934:           if ($showalldc) {
                    935:               $r->print(&mt("The table below contains a list of [_1]s from this course's domain who are not also [_2]s.",&Apache::lonnet::plaintext('dc'),&Apache::lonnet::plaintext('cc')));
                    936:           } else {
1.74      raeburn   937:               $r->print(&mt("The table below contains a list of [_1]s from this course's domain who currently receive notification, and are not also [_2]s.",&Apache::lonnet::plaintext('dc'),&Apache::lonnet::plaintext('cc')));
1.44      raeburn   938:           }
1.74      raeburn   939:           $r->print('
1.7       raeburn   940:               </td>
                    941:              </tr>
1.44      raeburn   942:              <tr>
1.74      raeburn   943:               <td>');
1.65      raeburn   944:           $r->print(&notifier_tables('dc',\%lt,\@showdom,\%status,\%notifystate,\%pname,
1.85      raeburn   945:                                      \$notifyshow,\@olddomcoord,\@futuredomcoord,$disabled));
1.74      raeburn   946:           $r->print('
1.44      raeburn   947:              </td>
1.74      raeburn   948:           </tr>');
1.44      raeburn   949:       }
1.45      raeburn   950:       if (@ccs > 0 || @showdom > 0) {
1.74      raeburn   951:           $r->print('<tr><td>&nbsp;</td></tr><tr><td>');
1.45      raeburn   952:           if ($notifycount) {
1.69      raeburn   953:               $r->print(&mt('Uncheck the checkbox(es) to terminate notification for people currently informed of roster changes from the nightly enrollment update.').'<br />');
1.45      raeburn   954:          }
                    955:          if ((@ccs + @showdom) > $notifycount) {
1.72      raeburn   956:              $r->print(&mt('Check the checkbox(es) to initiate notification for people not currently informed of roster changes from the nightly enrollment update.').'<br />');
1.45      raeburn   957:          }
1.74      raeburn   958:          $r->print(&mt("Click 'Go' to save your changes.").'
                    959:            <br />
                    960:            <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.44      raeburn   961:             <tr>
1.74      raeburn   962:              <td align="right">
1.85      raeburn   963:               <input type="button" name="notifyset" value="'.&mt('Go').'" onclick="'."process('notify')".'"'.$disabled.' />
1.44      raeburn   964:              </td>
                    965:             </tr>
                    966:            </table>
                    967:           </td>
                    968:          </tr>
1.74      raeburn   969:       ');
1.1       raeburn   970:       }
1.74      raeburn   971:       $r->print('
1.44      raeburn   972:       </table>
1.74      raeburn   973:       <input type="hidden" name="notifyshow" value="'.$notifyshow.'" />
                    974:       <input type="hidden" name="action" value="'.$action.'" />
                    975:       <input type="hidden" name="state" value="process" />
1.44      raeburn   976:       </form>
1.74      raeburn   977:       ');
1.1       raeburn   978:   } elsif ($action eq "crosslist") {
1.28      albertel  979:       my @xlists;
                    980:       if ($enrollvar{crosslistings} ne '') {
                    981: 	  @xlists = split(/,/,$enrollvar{crosslistings});
1.1       raeburn   982:       }
1.29      albertel  983:       my $cross_str = @xlists;
1.74      raeburn   984:       $r->print('
                    985:             <form name="enter" method="post" action=""><br />
                    986:             <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.1       raeburn   987:              <tr>
1.74      raeburn   988:               <td align="left"><b>'.$tasktitleref->{$action}.'</b><br />
                    989:       ');
1.1       raeburn   990:       if ($cross_str > 0) {
1.74      raeburn   991:           $r->print(
                    992:               &mt('Currently, this LON-CAPA course is crosslisted with [quant,_1,course section,course sections].',$cross_str).' '.
                    993:               &mt('Students enrolling in these course sections will be automatically added to the class roster for the course, if you have chosen to enable a nightly automated enrollment update.').' '.
1.81      raeburn   994:               &mt('For each crosslisting, leave the checkbox checked if you want registered students in that course to be included in the student roster for LON-CAPA course: [_1]; otherwise uncheck it.',"<b>$realm ($enrollvar{coursecode})</b>").' '.
1.74      raeburn   995:               &mt('If you wish to change the section ID assigned in your LON-CAPA course for a crosslisted course, enter the new section ID in the appropriate textbox.').' '.
                    996:               &mt('The LON-CAPA section ID can be left (or set to) empty, if you do not wish to tie a section ID to this crosslisting.').' '.
                    997:               &mt('If you wish to add new crosslisted courses, enter the number of new courses to add in the textbox at the bottom of the page.').' '.
                    998:               &mt('You will provide information about each of the new crosslistings on a subsequent page.').' '.
                    999:               &mt("Click 'Go' to save your changes.").'
1.1       raeburn  1000:               </td>
                   1001:              </tr>
                   1002:             </table>
1.74      raeburn  1003:             <br />
                   1004:           ');
                   1005:           $r->print(&Apache::loncommon::start_data_table());
                   1006:           $r->print(&Apache::loncommon::start_data_table_row());
                   1007:           $r->print('
                   1008:                  <th>'.&mt('Enrollment?').'</th>
                   1009:                  <th>'.&mt('Crosslisted course').'</th>
                   1010:                  <th>'.&mt('LON-CAPA section ID').'</th>
                   1011:           ');
                   1012:           $r->print(&Apache::loncommon::end_data_table_row());
1.87      raeburn  1013:           my @showable;
                   1014:           &reformat_xlists($dom,$crs,$enrollvar{'coursecode'},\@xlists,\@showable);
                   1015:           for (my $i=0; $i<@showable; $i++) {
1.1       raeburn  1016:               my $xl = '&nbsp;';
1.42      raeburn  1017:               my $lc_sec = '&nbsp;';
1.87      raeburn  1018:               if ($showable[$i] =~ /^([^:]+):?(.*)$/) {
1.1       raeburn  1019:                   $xl = $1;
1.42      raeburn  1020:                   $lc_sec = $2;
1.1       raeburn  1021:               }               
1.42      raeburn  1022:               $r->print(&Apache::loncommon::start_data_table_row());
1.74      raeburn  1023:               $r->print('
1.85      raeburn  1024:                  <td><input type="checkbox" name="cross_'.$i.'" checked="checked"'.$disabled.' /></td>
1.74      raeburn  1025:                  <td>'.$xl.'</td>
1.85      raeburn  1026:                  <td><input type="text" size="10" name="lcsec_'.$i.'" value="'.$lc_sec.'"'.$disabled.' /></td>
1.74      raeburn  1027:               ');
1.42      raeburn  1028:               $r->print(&Apache::loncommon::end_data_table_row());
1.1       raeburn  1029:           }
1.42      raeburn  1030:           $r->print(&Apache::loncommon::end_data_table());
1.1       raeburn  1031:       }
                   1032:       else {
1.74      raeburn  1033:           $r->print(
                   1034:                 &mt('Currently no crosslisted courses are recorded for [_1].',$enrollvar{coursecode}).'
1.1       raeburn  1035:               </td>
                   1036:              </tr>
                   1037:             </table>
1.74      raeburn  1038:           ');
1.1       raeburn  1039:       }
1.74      raeburn  1040:       $r->print('   
                   1041:             <br />
                   1042:             <table width="100%" border="0" cellpadding="3" cellspacing="3">
1.1       raeburn  1043:              <tr>
1.74      raeburn  1044:               <td align="left">
                   1045:                <b>'.&mt('Add new crosslistings.').'</b><br />'.
1.85      raeburn  1046:                &mt('Number of new crosslistings to add:[_1]','&nbsp;&nbsp;<input type="text" size="2" name="numcross" value="0"'.$disabled.' />').'
1.1       raeburn  1047:               </td>
                   1048:              </tr>
                   1049:             </table>
1.74      raeburn  1050:             <br />
                   1051:             <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.1       raeburn  1052:              <tr>
1.74      raeburn  1053:               <td align="right">
1.85      raeburn  1054:                <input type="button" name="crosslist" value="',&mt('Go').'" onclick="'."process('crosslist')".'"'.$disabled.' />
1.1       raeburn  1055:               </td>
                   1056:              </tr>
                   1057:             </table>
1.74      raeburn  1058:             <input type="hidden" name="action" value="$action" />
                   1059:             <input type="hidden" name="state" value="process" />
1.1       raeburn  1060:             </form> 
1.74      raeburn  1061:       ');
                   1062:   } elsif ($action eq 'sections') {
1.12      raeburn  1063:       my @sections = ();
1.13      raeburn  1064:       @sections = &Apache::lonnet::auto_get_sections($crs,$dom,$enrollvar{coursecode});
1.28      albertel 1065:       my @storedsections = split(/,/,$enrollvar{sectionnums});
1.1       raeburn  1066:       my @currsections = ();
                   1067:       my %sec_id = ();
                   1068:       foreach (@storedsections) {
                   1069:           if ($_ =~ m/^(\w+):(\w*)$/) {
1.74      raeburn  1070:               push(@currsections,$1);
1.1       raeburn  1071:               $sec_id{$1} = $2;
                   1072:           }
                   1073:       }
                   1074:       if (@sections > 0) {
1.29      albertel 1075:           my $secshow = @sections;
1.74      raeburn  1076:           $r->print('
                   1077:             <form name="enter" method="post" action=""><br />
                   1078:             <table width="100%" border="0" cellpadding="3" cellspacing="3">
1.1       raeburn  1079:              <tr>
1.74      raeburn  1080:               <td align="left">
                   1081:                <b>'.$tasktitleref->{$action}.'</b><br />'.
                   1082:                &mt("Your institution's course catalog includes [quant,_1,section] for course code: [_2].",$secshow,$enrollvar{coursecode}).'
1.1       raeburn  1083:               </td>
                   1084:              </tr>
                   1085:              <tr>
1.74      raeburn  1086:               <td>'.&mt('For each section, check the checkbox if you want registered students in that section to be included in the student roster for LON-CAPA course: [_1]; otherwise uncheck it.',"<b>$realm ($enrollvar{coursecode})</b>").' '.
                   1087:                    &mt('If you want to change the section ID designation used for this section in LON-CAPA, delete the current value in the LON-CAPA section ID textbox and enter the new value.').' '.
                   1088:                    &mt('The LON-CAPA section ID can be left (or set to) empty, if you do not wish to tie a section ID to this section.').' '.
                   1089:                    &mt("To add a new section, check the 'Enrollment in this course?' checkbox, and enter the desired LON-CAPA section ID in the appropriate textbox.").' '.
                   1090:                    &mt("Click 'Go' to save your changes.").'</td>
1.1       raeburn  1091:              </tr>
                   1092:             </table>
1.74      raeburn  1093:             <br />
                   1094:           ');
1.42      raeburn  1095:           $r->print(&Apache::loncommon::start_data_table());
                   1096:           $r->print(&Apache::loncommon::start_data_table_row());
1.74      raeburn  1097:           $r->print('
                   1098:               <th>'.&mt('Enrollment').'</th>
                   1099:               <th>'.&mt('Institutional Section').'</th>
                   1100:               <th>'.&mt('LON-CAPA section ID').'</th>
                   1101:           ');
1.42      raeburn  1102:           $r->print(&Apache::loncommon::end_data_table_row());
1.8       raeburn  1103:           for (my $i=0; $i<@sections; $i++) {
1.74      raeburn  1104:               my $checked;
                   1105:               if (grep/^\Q$sections[$i]\E$/,@currsections) {
                   1106:                   $checked = ' checked="checked"';
1.8       raeburn  1107:               }
1.74      raeburn  1108:               $r->print(&Apache::loncommon::start_data_table_row().'
1.85      raeburn  1109:                   <td><input type="checkbox" name="sec_'.$i.'"'.$checked.$disabled.' /></td>
1.74      raeburn  1110:                   <td>'.$sections[$i].'<input type="hidden" name="secnum_'.$i.'" value="'.$sections[$i].'" /></td>
1.85      raeburn  1111:                   <td><input type="text" size="10" name="loncapasec_'.$i.'" value="'.$sec_id{$sections[$i]}.'"'.$disabled.' /></td>'.
1.74      raeburn  1112:                   &Apache::loncommon::end_data_table_row());
1.8       raeburn  1113:           }
1.42      raeburn  1114:           $r->print(&Apache::loncommon::end_data_table());
1.74      raeburn  1115:           $r->print('
                   1116:             <br />
                   1117:             <table width="100%" border="0" cellspacing="3" cellpadding="3">
1.7       raeburn  1118:              <tr> 
1.74      raeburn  1119:               <td align="right">
                   1120:                <input type="hidden" name="secshow" value="'.$secshow.'" />
1.85      raeburn  1121:                <input type="button" name="sections" value="'.&mt('Go').'" onclick="'."process('sections')".'"'.$disabled.' />
1.7       raeburn  1122:               </td>
                   1123:              </tr>
                   1124:             </table>
1.74      raeburn  1125:             <input type="hidden" name="action" value="'.$action.'" />
                   1126:             <input type="hidden" name="state" value="process" />
1.7       raeburn  1127:             </form>
1.74      raeburn  1128:           ');
1.1       raeburn  1129:       } else {
1.74      raeburn  1130:           $r->print('
                   1131:             <form name="enter" method="post" action=""><br />
                   1132:             <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.1       raeburn  1133:              <tr>
1.74      raeburn  1134:               <td align="left"><b>'.$tasktitleref->{$action}.'</b><br />
                   1135:           ');
1.1       raeburn  1136:           if (@currsections) {
1.29      albertel 1137:               my $secshow = @currsections;
1.74      raeburn  1138:               $r->print(
                   1139:                   &mt('Currently, this LON-CAPA course incorporates enrollment from [quant,_1,section].',$secshow).' '.
                   1140:                   &mt('Students enrolling in any of these course sections will be automatically added to the class roster for the course, if you have chosen to enable a nightly automated enrollment update.').' '.
                   1141:                   &mt('For each section, uncheck the checkbox if you want registered students in that section to cease being included in the student roster for LON-CAPA course: [_1]; otherwise leave it checked.',"<b>$realm ($enrollvar{coursecode})</b>").' '.
                   1142:                   &mt('If you want to change the section ID designation used for this section in LON-CAPA, delete the current value in the LON-CAPA section ID textbox and enter the new value.').' '.
                   1143:                   &mt('If you wish to add new course section, enter the number of new sections to add in the textbox at the bottom of the page.').' '.
                   1144:                   &mt('You will provide information about each of the new sections on a subsequent page.').' '.
                   1145:                   &mt("Click 'Go' to save your changes.").'
1.1       raeburn  1146:               </td>
                   1147:              </tr>
                   1148:             </table>
1.74      raeburn  1149:             <br />
                   1150:               ');
                   1151:               $r->print(&Apache::loncommon::start_data_table().
                   1152:                         &Apache::loncommon::start_data_table_row().'
                   1153:                  <th>'.&mt('Enrollment?').'</th>
                   1154:                  <th>'.&mt('Section').'</th>
                   1155:                  <th>'.&mt('LON-CAPA section ID').'</th>
                   1156:               ');
1.42      raeburn  1157:               $r->print(&Apache::loncommon::end_data_table_row());
1.1       raeburn  1158:               for (my $j=0; $j<@currsections; $j++) {
1.74      raeburn  1159:                   $r->print(
                   1160:                  &Apache::loncommon::start_data_table_row().
1.85      raeburn  1161:                  '<td><input type="checkbox" name="sec_'.$j.'" checked="checked"'.$disabled.' /></td>
1.74      raeburn  1162:                  <td>'.$currsections[$j].'</td>
1.85      raeburn  1163:                  <td><input type="text" name="lcsec_'.$j.'" size="10" value="'.$sec_id{$currsections[$j]}.'"'.$disabled.' /></td>
1.74      raeburn  1164:                  '.&Apache::loncommon::end_data_table_row());
1.1       raeburn  1165:               }
1.42      raeburn  1166:               $r->print(&Apache::loncommon::end_data_table());
1.1       raeburn  1167:           } else {
1.74      raeburn  1168:               $r->print(
                   1169:                   &mt('Currently no sections of [_1] are contributing enrollment to the LON-CAPA class roster.',"$realm ($enrollvar{coursecode})").'
1.1       raeburn  1170:               </td>
                   1171:              </tr>
                   1172:             </table>
1.74      raeburn  1173:               ');
1.1       raeburn  1174:           }
1.74      raeburn  1175:           $r->print('
                   1176:             <br />
                   1177:             <table width="100%" border="0" cellpadding="3" cellspacing="3">
1.1       raeburn  1178:              <tr>
1.74      raeburn  1179:               <td align="left">
                   1180:                <b>'.&mt('Add enrollment from additional sections.').'</b><br />'.
1.85      raeburn  1181:                &mt('Number of new sections to add:').'&nbsp;&nbsp;<input type="text" size="2" name="numsec" value="0"'.$disabled.' />
1.1       raeburn  1182:               </td>
                   1183:              </tr>
                   1184:             </table>
1.74      raeburn  1185:             <br />
                   1186:             <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.1       raeburn  1187:              <tr>
1.74      raeburn  1188:               <td align="right">
1.85      raeburn  1189:                <input type="button" name="sections" value="'.&mt('Go').'" onclick="'."process('sections')".'"'.$disabled.' />
1.1       raeburn  1190:               </td>
                   1191:              </tr>
                   1192:             </table>
1.74      raeburn  1193:             <input type="hidden" name="action" value="'.$action.'" />
                   1194:             <input type="hidden" name="state" value="process" />
1.1       raeburn  1195:             </form> 
1.74      raeburn  1196:           ');
1.1       raeburn  1197:       }
1.74      raeburn  1198:   } elsif ($action eq 'photos') {
                   1199:       my @photosets = (&mt('OFF'),&mt('ON'));
                   1200:       $r->print('
                   1201:                   <form name="enter" method="post" action=""><br />
                   1202:                   <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.1       raeburn  1203:                    <tr>
1.74      raeburn  1204:                     <td align="left"><b>'.$tasktitleref->{$action}.'</b><br />'.
                   1205:                        &mt('Currently -- Student photo import:').' <i>'.$photosets[$enrollvar{showphoto}].'</i>
1.1       raeburn  1206:                     </td>
                   1207:                    </tr>
                   1208:                   </table>
1.74      raeburn  1209:                   <table width="100%" border="0" cellpadding="3" cellspacing="3">
1.1       raeburn  1210:                     <tr>
                   1211:                      <td>
1.74      raeburn  1212:                          '.&mt('Automatic import of student photos from institutional data repository:').'&nbsp;&nbsp;');
1.37      raeburn  1213:       if ($enrollvar{showphoto}) {
1.74      raeburn  1214:           $r->print('
1.85      raeburn  1215:                         <label><input type="radio" name="showphotos" value="1" checked="checked"'.$disabled.' />&nbsp;'.&mt('Yes').'&nbsp;&nbsp;&nbsp;</label>
                   1216:                         <label><input type="radio" name="showphotos" value="0"'.$disabled.' />&nbsp;'.&mt('No').'</label>
1.74      raeburn  1217:           ');
1.1       raeburn  1218:       } else {
1.74      raeburn  1219:           $r->print('
1.85      raeburn  1220:                         <label><input type="radio" name="showphotos" value="1"'.$disabled.' />&nbsp;'.&mt('Yes').'&nbsp;&nbsp;&nbsp;</label>
                   1221:                         <label><input type="radio" name="showphotos" value="0" checked="checked"'.$disabled.' />&nbsp;'.&mt('No').'</label>
1.74      raeburn  1222:           ');
1.1       raeburn  1223:       }
1.34      raeburn  1224:       $r->print('
                   1225:                      </td>
                   1226:                     </tr>
                   1227:       ');
                   1228:       my ($result,$perm_reqd)=&Apache::lonnet::auto_photo_permission($crs,$dom);
                   1229:       my $can_enable = 1;
1.49      albertel 1230:       my $institution = &Apache::lonnet::domain($dom,'description');
1.34      raeburn  1231:       if ($result eq 'ok') {
                   1232:           if ($perm_reqd eq 'yes') {
                   1233:               if (!($enrollvar{'photopermission'} eq 'yes')) {
                   1234:                   $can_enable = 0;
                   1235:               } else {
1.48      albertel 1236:                   if (&user_is_courseowner($enrollvar{'courseowner'})) {
1.34      raeburn  1237:                       $r->print('
                   1238:                     <tr>
                   1239:                      <td>'.
1.74      raeburn  1240: &mt('Previously the owner of this course agreed to the conditions of use of digital student photos required by [_1].', $institution).'<br />'.
                   1241: &mt('As a result [_1]s can choose to automatically import student photos into this course.',&Apache::lonnet::plaintext('cc')).
                   1242: '<br /><span class="LC_nobreak"><label>'.
1.85      raeburn  1243: &mt('[_1]Cancel[_2] owner acceptance of these conditions of use?','<b>','</b>').'&nbsp;<input type="checkbox" name="cancel_agreement" value="1"'.$disabled.' /></label></span>
1.1       raeburn  1244:                      </td>
                   1245:                     </tr>
1.34      raeburn  1246:                       ');
                   1247:                   }
                   1248:               }
                   1249:           }
                   1250:       } else {
                   1251:           $r->print('
                   1252:                     <tr>
                   1253:                      <td>'.
1.74      raeburn  1254: &mt('There was a problem determining whether course owner permission is required in order for a course coordinator to have access to student photos in this domain.').' '.
                   1255: &mt('As a result you will not be able to configure access to student photos at this time').
                   1256: '<br /><br /><input type="button" name="mainmenu" value="'.&mt('Go back').'" onclick="javascript:history.go(-1);" />
1.34      raeburn  1257:                     </td>
                   1258:                    </tr>
                   1259:                   </form>
                   1260:           ');
                   1261:           return;
                   1262:       }
                   1263:       if ($can_enable) {
                   1264:           $r->print('
1.1       raeburn  1265:                     <tr>
                   1266:                      <td>
1.74      raeburn  1267:                       <span style="color: #888888">'.
                   1268: &mt('Note: if you enable automatic import of student photos, your course will automatically have access to photos saved by your institution for officially registered students, via a conduit established by your LON-CAPA domain coordinator.').'
                   1269:                       </span>
1.1       raeburn  1270:                      </td>
                   1271:                     </tr>
1.74      raeburn  1272:           ');
1.34      raeburn  1273:       } else {
1.48      albertel 1274:           if (&user_is_courseowner($enrollvar{'courseowner'})) {
1.34      raeburn  1275:               $r->print('
                   1276:                     <tr>
                   1277:                      <td>'.
1.74      raeburn  1278: &mt('[_1] requires a course owner to indicate acceptance of conditions of use of digital student photos before enabling automatic import into a course.',$institution).' '.
                   1279: &mt('If you choose to enable import of photos you will be prompted for your agreement on the next page.').'
1.34      raeburn  1280:                      </td>
                   1281:                     </tr>
1.74      raeburn  1282:               ');
1.34      raeburn  1283:           } else {
                   1284:               my ($ownername,$owneremail) = &get_ownerinfo($dom,
                   1285:                                                     $enrollvar{'courseowner'});
1.38      raeburn  1286:               my $emailstr;
                   1287:               if ($owneremail) {
                   1288:                   $emailstr = "(e-mail: $owneremail)";
                   1289:               }
1.34      raeburn  1290:               $r->print('
                   1291:                     <tr>
1.56      bisitz   1292:                      <td>'
                   1293:                       .&mt('The policies of your institution ([_1]) require that the course owner ([_2]) must indicate acceptance of the conditions of use of digital photos of registered students, before they may be made available for use in a course.',$institution,$ownername)
                   1294:                       .'<br /><br />'
                   1295:                       .&mt('Please direct the course owner [_1] to visit the "Student photos" page in the Automated Enrollment Manager to indicate acceptance of these conditions of use.',$emailstr)
1.74      raeburn  1296:                       .'<br /><br /><input type="button" name="mainmenu" value="'.&mt('Go back').'" onclick="javascript:history.go(-1);" />
1.34      raeburn  1297:                     </td>
                   1298:                    </tr>
                   1299:                   </form>
                   1300:              ');
                   1301:              return;
                   1302:           }
                   1303:       }
                   1304:       $r->print('
1.1       raeburn  1305:                     <tr>
1.74      raeburn  1306:                      <td>&nbsp;</td>
1.1       raeburn  1307:                     </tr>
                   1308:                     <tr>
1.34      raeburn  1309:                      <td align="right">
1.85      raeburn  1310:                       <input type="button" name="showphotos" value="'.&mt('Go').'" onclick="process('."'photos'".')"'.$disabled.' />
1.1       raeburn  1311:                      </td>
                   1312:                     </tr>
                   1313:                    </table>
1.39      albertel 1314:                    <input type="hidden" name="action" value="'.$action.'" />
                   1315:                    <input type="hidden" name="state" value="process" />
1.1       raeburn  1316:                    </form>
1.34      raeburn  1317:       ');
1.1       raeburn  1318:   } elsif ($action eq "updatenow") {
1.74      raeburn  1319:       $r->print('
                   1320:                    <form name="enter" method="post" action=""><br />
                   1321: 		   <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.1       raeburn  1322: 		    <tr>
1.74      raeburn  1323: 		     <td align="left"><b>'.$tasktitleref->{$action}.'</b>
1.1       raeburn  1324: 		     </td>
                   1325:                     </tr>
                   1326: 		   </table>
1.74      raeburn  1327: 		   <table width="100%" border="0" cellpadding="3" cellspacing="3">
1.1       raeburn  1328: 		    <tr>
1.74      raeburn  1329: 		     <td>'.
                   1330: 	             &mt('Add any students currently included in institutional classlist(s) but not enrolled in your LON-CAPA course.').'<br />  
1.85      raeburn  1331: 		      <label><input type="radio" name="updateadds" value="1"'.$disabled.' />&nbsp;'.&mt('Yes').'&nbsp;</label>
                   1332:                       <label><input type="radio" name="updateadds" value="0"'.$disabled.' />&nbsp;'.&mt('No').'&nbsp;</label>
1.1       raeburn  1333:                      </td>
                   1334:                     </tr>
                   1335:                     <tr>
1.74      raeburn  1336:                      <td>'.
                   1337:  	             &mt('Expire students previously added by nightly enrollment process, but no longer listed in institutional classlist(s).').'<br />
1.85      raeburn  1338:                       <label><input type="radio" name="updatedrops" value="1"'.$disabled.' />&nbsp;'.&mt('Yes').'&nbsp;</label>
                   1339:                       <label><input type="radio" name="updatedrops" value="0"'.$disabled.' />&nbsp;'.&mt('No').'&nbsp;</label><br />
1.14      raeburn  1340:                      </td>
                   1341:                     </tr>
                   1342:                     <tr>
1.74      raeburn  1343:                      <td><span style="color: #888888;">'.
                   1344: &mt("Note: Any students previously added manually by course coordinator(s) using either 'Upload classlist CSV file' or 'Enroll a single user' will be unaffected by the removal process.").'
                   1345:                       </span>
1.14      raeburn  1346:                      </td>
                   1347:                     </tr>
                   1348:                     <tr>
                   1349:                      <td>
1.74      raeburn  1350:       ');
1.85      raeburn  1351:       &print_accessdate_table($r,\%enrollvar,$tasktitleref,$action,$readonly);
1.74      raeburn  1352:       $r->print('
1.14      raeburn  1353:                      </td>
                   1354:                     </tr>
                   1355:                     <tr>
1.74      raeburn  1356:                      <td align="right">
1.85      raeburn  1357:                       <input type="button" name="updatenow" value="'.&mt('Go').'" onclick="'."process('updatenow')".'"'.$disabled.' />
1.14      raeburn  1358:                      </td>
                   1359:                     </tr>
                   1360: 	           </table>
1.74      raeburn  1361:                    <input type="hidden" name="action" value="'.$action.'" />
                   1362:                    <input type="hidden" name="state" value="process" />
1.14      raeburn  1363:                   </form>
1.74      raeburn  1364:       ');
1.34      raeburn  1365:   } elsif ($action eq 'updatephotos') {
1.74      raeburn  1366:       $r->print('
                   1367:                    <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.34      raeburn  1368:                     <tr>
1.74      raeburn  1369:                      <td align="left"><b>'.$tasktitleref->{$action}.'</b>
1.34      raeburn  1370:                      </td>
1.74      raeburn  1371:                     </tr><tr><td>');
1.37      raeburn  1372:       if ($enrollvar{'showphoto'}) {
1.35      albertel 1373:           my ($update,$commentary) = &Apache::lonnet::auto_photochoice($crs,
                   1374: 								       $dom);
1.40      raeburn  1375:           if ($update) { 
                   1376:               $r->print('<br />'.$commentary.'<br /><br />
1.74      raeburn  1377: <form name="photoupdate" method="post" action="">
1.62      bisitz   1378: <input type="button" name="retrieve" value="'.&mt('Update photo repository').'"
1.85      raeburn  1379: onclick="javascript:document.photoupdate.submit()"'.$disabled.' />
1.62      bisitz   1380: <input type="hidden" name="action" value="'.$action.'" />
                   1381: <input type="hidden" name="state" value="process" />
1.34      raeburn  1382: </form>');
1.40      raeburn  1383:           } else {
1.56      bisitz   1384:               $r->print(&mt('Update of photos via the Automated Enrollment Manager is unavailable in this domain.')
1.61      bisitz   1385:                        .'<br /><br /><input type="button" name="mainmenu" value="'.&mt('Go back').'" onclick="javascript:history.go(-1);" />');
1.40      raeburn  1386:           }
1.34      raeburn  1387:       } else {
1.74      raeburn  1388:           $r->print(&mt('Update of photos is unavailable, as import of student photos is currently disabled.').'<br />'.
                   1389:                     &mt('Enable this first via: [_1]','<a href="/adm/populate?action=photos">'.$tasktitleref->{'photos'}.'</a>'));
1.34      raeburn  1390:       }
                   1391:       $r->print('</td></tr>
                   1392:                  <tr><td>&nbsp;</td></tr>
                   1393:                 </table>');
1.14      raeburn  1394:   } elsif ($action eq 'viewclass') {
1.74      raeburn  1395:       $r->print('
                   1396:                    <form name="studentform" method="post" action=""><br />
                   1397:                    <table width="100%" border="0" cellpadding="2" cellspacing="2">
1.14      raeburn  1398:                     <tr>
1.74      raeburn  1399:                      <td align="left"><b>'.$tasktitleref->{$action}.'</b>
1.14      raeburn  1400:                      </td>
                   1401:                     </tr>
1.16      raeburn  1402:                     <tr>
1.74      raeburn  1403:                      <td>'.
                   1404:                 &mt('Section changes, name changes, and class drops that can be set to occur either automatically or when using the [_1]Update roster now[_2] feature, will affect only those students with an enroll type of [_1]auto[_2].',"'<b>","'</b>").' '.
                   1405:                 &mt("Students with an enroll type of [_1]manual[_2], will be converted automatically to the 'auto' type, when they first appear in the institutional classlist for the course - as long as nightly adds are enabled and active, or the update roster utility is used.","'<b>","'</b>").' '.
                   1406:                 &mt("Use the 'Lock' checkbox for any manually enrolled students for whom you wish to prevent type conversion.").' '.
                   1407:                 &mt("Use the 'Change' checkbox to switch the enroll type from auto to manual, and vice versa.").' '.
                   1408:                 &mt("Use the 'Unlock' checkbox for any maually enrolled students for whom you no longer wish to lock the enroll type.").' '.
                   1409:                 &mt("Click the 'Go' button at the end of the page to process your desired changes.").'</td>
1.16      raeburn  1410:                     </tr>
                   1411:                     <tr><td>&nbsp;</td></tr> 
1.14      raeburn  1412:                    </table>
                   1413:                    <table>
                   1414:                     <tr>
                   1415:                      <td>
1.74      raeburn  1416:       ');
1.23      albertel 1417:       if (! exists($env{'form.sortby'})) {
                   1418:           $env{'form.sortby'} = 'username';
1.14      raeburn  1419:       }
1.46      albertel 1420:       if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.23      albertel 1421:           $env{'form.Status'} = 'Active';
1.14      raeburn  1422:       }
1.23      albertel 1423:       my $status_select = &Apache::lonhtmlcommon::StatusOptions($env{'form.Status'});
1.14      raeburn  1424: #  Get current classlist
1.51      raeburn  1425:       my %userlist;
                   1426:       my ($indexhash,$keylist) = &Apache::lonuserutils::make_keylist_array();
                   1427:       my $classlist = &Apache::loncoursedata::get_classlist();
                   1428:       my $secidx = &Apache::loncoursedata::CL_SECTION();
1.66      raeburn  1429:       my $crstype =&Apache::loncommon::course_type();
                   1430:       my ($permission,$allowed) = &Apache::lonuserutils::get_permission('course',$crstype);
1.51      raeburn  1431:       foreach my $student (keys(%{$classlist})) {
                   1432:           if (exists($permission->{'view_section'})) {
                   1433:               if ($classlist->{$student}[$secidx] ne $permission->{'view_section'}) {
                   1434:                   next;
                   1435:               } else {
                   1436:                   $userlist{$student} = $classlist->{$student};
                   1437:               }
                   1438:           } else {
                   1439:               $userlist{$student} = $classlist->{$student};
                   1440:           }
                   1441:       }
                   1442: 
1.14      raeburn  1443:       if (! defined($classlist)) {
1.74      raeburn  1444:           $r->print(&mt('There are no students either currently or previously enrolled.').'
1.51      raeburn  1445:                       </td>
1.74      raeburn  1446:                      </tr>'."\n");
1.14      raeburn  1447:       } else {
                   1448:           $r->print(&mt('Student Status: [_1]',$status_select)."\n");
                   1449:           $r->print('<input type="submit" value="'.&mt('Update Display').'" />'.
1.74      raeburn  1450:               "\n");
1.51      raeburn  1451:           my $context = 'course';
                   1452:           my $mode = 'autoenroll';
1.85      raeburn  1453:           my ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount) = 
                   1454:               &Apache::lonuserutils::show_users_list($r,$context,$mode,$permission,$env{'form.Status'},\%userlist,$keylist);
1.74      raeburn  1455:           $r->print('
1.14      raeburn  1456:                      </td>
                   1457:                     </tr>
1.74      raeburn  1458:           ');
1.14      raeburn  1459:           if ($studentcount > 0) {
1.74      raeburn  1460:               $r->print('
                   1461:                     <tr><td><table border="0" cellpadding="5"><tr>
                   1462:               ');
1.16      raeburn  1463:               my $cellcount = 0;
                   1464:               if ($autocount > 0) {
                   1465:                   $cellcount ++;
1.74      raeburn  1466:                   $r->print('
1.85      raeburn  1467:                       <td><fieldset><legend>'.&mt('Change auto').'</legend><input type="button" value="'.&mt('check all').'" onclick="javascript:checkAll(document.studentform.chgauto)"'.$disabled.' />&nbsp;&nbsp;
                   1468:                       <input type="button" value="'.&mt('uncheck all').'" onclick="javascript:uncheckAll(document.studentform.chgauto)"'.$disabled.' /></fieldset></td>
1.74      raeburn  1469:                   ');
1.16      raeburn  1470:               }
                   1471:               if ($manualcount > 0) {
                   1472:                   $cellcount ++;
1.74      raeburn  1473:                   $r->print('
1.85      raeburn  1474:                       <td><fieldset><legend>'.&mt('Change manual').'</legend><input type="button" value="'.&mt('check all').'" onclick="javascript:checkAll(document.studentform.chgmanual)"'.$disabled.' />&nbsp;&nbsp;
                   1475:                       <input type="button" value="'.&mt('uncheck all').'" onclick="javascript:uncheckAll(document.studentform.chgmanual)"'.$disabled.' /></fieldset></td>
1.74      raeburn  1476:                   ');
1.16      raeburn  1477:               }
                   1478:               if ($lockcount > 0) {
                   1479:                   if ($cellcount == 2) {
1.74      raeburn  1480:                       $r->print('</tr><tr>');
1.16      raeburn  1481:                   }
                   1482:                   $cellcount ++;
1.74      raeburn  1483:                   $r->print('
1.85      raeburn  1484:                        <td><fieldset><legend>'.&mt('Lock manual').'</legend><input type="button" value="'.&mt('check all').'" onclick="javascript:checkAll(document.studentform.lockchg)"'.$disabled.' />&nbsp;&nbsp;
                   1485:                        <input type="button" value="'.&mt('uncheck all').'" onclick="javascript:uncheckAll(document.studentform.lockchg)"'.$disabled.' /></fieldset></td>
1.74      raeburn  1486:                   ');
1.16      raeburn  1487:               }
                   1488:               if ($unlockcount > 0) {
                   1489:                   if ($cellcount == 2) {
1.74      raeburn  1490:                       $r->print('</tr><tr>');
1.16      raeburn  1491:                   }
                   1492:                   $cellcount ++;
1.74      raeburn  1493:                   $r->print('
                   1494:                        <td><fieldset><legend>'.&mt('Unlock manual').'
1.85      raeburn  1495:                        </legend><input type="button" value="'.&mt('check all').'" onclick="javascript:checkAll(document.studentform.unlockchg)"'.$disabled.' />&nbsp;&nbsp;
                   1496:                        <input type="button" value="'.&mt('uncheck all').'" onclick="javascript:uncheckAll(document.studentform.unlockchg)"'.$disabled.' /></fieldset></td>');
1.16      raeburn  1497:               }
1.74      raeburn  1498:               $r->print('
1.16      raeburn  1499:                        </tr>
                   1500:                       </table>
1.14      raeburn  1501:                      <td>&nbsp;</td>
                   1502:                     </tr>
                   1503:                     <tr>
1.74      raeburn  1504:                      <td align="right">
1.85      raeburn  1505:                       <input type="button" name="viewclass" value="'.&mt('Go').'" onclick="'."process('viewclass','$autocount','$manualcount','$lockcount','$unlockcount')".'"'.$disabled.' />
1.14      raeburn  1506:                      </td>
                   1507:                     </tr>
1.74      raeburn  1508:               ');
1.51      raeburn  1509:           } else {
                   1510:               $r->print('
                   1511:                     <tr>
                   1512:                      <td><br />
                   1513:                       '.&mt('There are no students with the selected status.').'
                   1514:                      </td>
                   1515:                     </tr>
                   1516:               ');
1.14      raeburn  1517:           }
1.74      raeburn  1518:           $r->print('
1.14      raeburn  1519:                    </table>
1.74      raeburn  1520:                    <input type="hidden" name="action" value="'.$action.'" />
                   1521:                    <input type="hidden" name="state" value="choose" />
1.14      raeburn  1522:                   </form>
1.74      raeburn  1523:           ');
1.14      raeburn  1524:       }
1.1       raeburn  1525:   }
                   1526: }
                   1527: 
1.44      raeburn  1528: sub notifier_tables {
1.65      raeburn  1529:     my ($role,$lt,$users,$status,$notifystate,$pname,$notifyshow,$olddomcoord,
1.85      raeburn  1530:         $futuredomcoord,$disabled) = @_;
1.44      raeburn  1531:     my $output = &Apache::loncommon::start_data_table();
                   1532:     $output .= &Apache::loncommon::start_data_table_header_row();
                   1533:     $output .= "<th>$$lt{name}</th>
                   1534:                 <th>$$lt{usnm}</th>";
1.65      raeburn  1535:     if ($role eq 'dc') {
                   1536:         $output .= "<th>$$lt{doms}</th>";
                   1537:     } elsif ($role eq 'cc') {
1.44      raeburn  1538:         $output .= "<th>$$lt{coac}</th>";
                   1539:     } 
                   1540:     $output .=  "<th>$$lt{curn}</th>
                   1541:                  <th>$$lt{notf}</th>";
                   1542:     $output .= &Apache::loncommon::end_data_table_header_row();
                   1543:     for (my $i=0; $i<@{$users}; $i++) {
                   1544:         $output .= &Apache::loncommon::start_data_table_row();
                   1545:         $output .= '<td>'.$$pname{$$users[$i]}.'</td>'.
                   1546:                    '<td><input type="hidden" name="notifyname_'.$$notifyshow.
                   1547:                    '" value="'.$$users[$i].'" />'.$$users[$i].'</td>';
1.65      raeburn  1548:         if ($role eq 'dc') {
                   1549:             $output .= '<td>';
                   1550:             if ((ref($olddomcoord) eq 'ARRAY') && (ref($futuredomcoord) eq 'ARRAY')) {
                   1551:                 if (grep(/^\Q$users->[$i]\E$/,@{$olddomcoord})) {
                   1552:                     $output .= &mt('expired');
                   1553:                 } elsif (grep(/^\Q$users->[$i]\E$/,@{$futuredomcoord})) {
                   1554:                     $output .= &mt('future');
                   1555:                 } else {
                   1556:                     $output .= &mt('active');
                   1557:                 }
                   1558:             }
                   1559:             $output .= '</td>';
                   1560:         } elsif ($role eq 'cc') {
1.44      raeburn  1561:             $output .= '<td>'.$$status{$$users[$i]}.'</td>';
                   1562:         }
                   1563:         $output .= '<td>';
                   1564:         if ($$notifystate{$$users[$i]} == 1) {
                   1565:             $output .= $$lt{ntac};
                   1566:         } else {
                   1567:             $output .= $$lt{ntin};
                   1568:         }
                   1569:         $output .= '</td><td><input type="checkbox" name="note_'.$$notifyshow.'"'; 
                   1570:         if ($$notifystate{$$users[$i]} == 1) {
                   1571:             $output .= ' checked="checked"';
                   1572:         }
1.85      raeburn  1573:         $output .= $disabled.' /></td>';
1.44      raeburn  1574:         $output .= &Apache::loncommon::end_data_table_row();
                   1575:         $$notifyshow ++;
                   1576:     }
                   1577:     $output .= &Apache::loncommon::end_data_table();
                   1578:     return $output;
                   1579: }
                   1580: 
1.14      raeburn  1581: sub print_accessdate_table {
1.85      raeburn  1582:     my ($r,$enrollvar,$tasktitleref,$action,$readonly) = @_;
                   1583:     my ($start_table,$end_table) = &date_setting_table($$enrollvar{'default_enrollment_start_date'},$$enrollvar{'default_enrollment_end_date'},$action,$readonly);
1.74      raeburn  1584:     my ($oldstartshow,$oldendshow);
1.14      raeburn  1585:     if ( defined($$enrollvar{'default_enrollment_start_date'}) ) {
                   1586:         $oldstartshow = &Apache::lonlocal::locallocaltime($$enrollvar{'default_enrollment_start_date'});
                   1587:     }
                   1588:     if ( defined($$enrollvar{'default_enrollment_end_date'}) ) {
                   1589:         $oldendshow = &Apache::lonlocal::locallocaltime($$enrollvar{default_enrollment_end_date});
                   1590:         if ($$enrollvar{'default_enrollment_end_date'} eq '0') {
1.74      raeburn  1591:             $oldendshow = &mt("'No end date'");
1.14      raeburn  1592:         }
                   1593:     }
                   1594:     my %lt =&Apache::lonlocal::texthash(
                   1595:          'cuno' => 'Currently NO default first access or last access dates are set.',
                   1596:          'ifyo' => 'If you do not set a start date and an end date, then student roles for students added by the automated enrollment process will start immediately when the student is added and will never become inactive.',
                   1597:          'ifyd' => 'If you do not set an access start date and an end date, then student roles for new students added when you click "Go" will become active immediately and will never become inactive.',
                   1598:          'setf' => 'Set date of first access',
                   1599:          'setl' => 'Set date of last access',
                   1600:          'freg' => 'for registered students added via automated enrollment',
                   1601:          'fnew' => 'for new students added when you update the class roster',
1.16      raeburn  1602:          'ifad'  => 'If automated adds are enabled, then when students are added their student roles will become active on the date set here for first access, and their roles will become inactive on the date set here for last access.  These default access dates will be overridden for specific students if the institutional classlist data supplied to the automatic enrollment process includes entries for the startdate and enddate fields for those students.',
1.69      raeburn  1603:     );
1.77      bisitz   1604:     $lt{'ncds'} = &mt('Changing default start and end access dates will affect [_1]future enrollments[_2] and also [_1]currently inactive[_2] students (i.e., those for whom access will begin in the future).','<b>','</b>');
1.73      raeburn  1605:     $lt{'tcha'} = &mt('To change access dates for [_1]currently active[_2] students, use User Management -> "Manage Course Users" to display currently active students, then use the dropdown menu for "Action to take for selected users:" to choose "Change starting/ending dates", select the students to change, and click "Proceed".','<b>','</b>');
1.14      raeburn  1606:     my $dateshow;
                   1607:     if ( ($oldendshow eq '') && ($oldstartshow eq '') ) {
1.74      raeburn  1608:        $dateshow = '<br /><span class="LC_warning">'.
                   1609:                    &mt('Warning.').'&nbsp;'.$lt{'cuno'}.' ';
1.14      raeburn  1610:        if ($action eq 'setaccess') {
                   1611:            $dateshow .= $lt{'ifyo'}."\n";
                   1612:        } elsif ($action eq 'updatenow') {
                   1613:            $dateshow .= $lt{'ifyd'}."\n";
                   1614:        }
1.74      raeburn  1615:        $dateshow .= '</span>';
1.14      raeburn  1616:     } else {
                   1617:         $dateshow = &mt('Currently: default first access').": <b><i>$oldstartshow</i></b>, ".&mt('default last access').": <b><i>$oldendshow</i></b>\n";
                   1618:     }
                   1619:     if ($action eq 'setaccess') {
1.74      raeburn  1620:         $r->print('
                   1621:                 <form name="enter" method="post" action=""><br />
1.14      raeburn  1622:                 <table width="100%" border="0" cellpadding="2" cellspacing="2">
                   1623:                  <tr>
1.74      raeburn  1624:                   <td align="left"><b>'.$tasktitleref->{$action}.'</b>
                   1625:                   <br /><br />'.
                   1626:                    $dateshow.'
1.14      raeburn  1627:                   </td>
                   1628:                  </tr>
                   1629:                 </table>
1.74      raeburn  1630:         ');
1.14      raeburn  1631:     } elsif ($action eq 'updatenow') {
1.74      raeburn  1632:         $r->print('
                   1633:                 <br /><br />'.$dateshow."\n");
1.14      raeburn  1634:     }
1.74      raeburn  1635:     $r->print('
1.14      raeburn  1636:                 <table width="100%" border="0" cellpadding="3" cellspacing="3">
                   1637:                  <tr>
                   1638:                   <td align="left" colspan="2">
                   1639:                    <table border="0" cellspacing="0" cellpadding="2">
                   1640:                     <tr>
                   1641:                      <td colspan="3">
1.74      raeburn  1642: ');
                   1643:     if ($action eq 'setaccess') {
                   1644:         $r->print("<i>$lt{'setf'} $lt{'freg'}</i>");
                   1645:     } elsif ($action eq 'updatenow') {
                   1646:         $r->print("<i>$lt{'setf'} $lt{'fnew'}</i>");
                   1647:     }
                   1648:     $r->print(' 
1.14      raeburn  1649:                        </td>
                   1650:                       </tr>
                   1651:                       <tr>
1.74      raeburn  1652:                        <td>'.$start_table.'
1.14      raeburn  1653:                        </td>
                   1654:                       </tr>
                   1655:                      </table>
                   1656:                     </td>
                   1657:                    </tr>
                   1658:                    <tr>
                   1659:                     <td align="left" colspan="2">
1.15      albertel 1660:                      <table border="0" cellspacing="0" cellpadding="2">
1.14      raeburn  1661:                       <tr>
                   1662:                        <td colspan="3">
1.74      raeburn  1663:     ');
1.14      raeburn  1664:     if ($action eq 'setaccess') {
                   1665:         $r->print("<i>$lt{'setl'} $lt{'freg'}</i>");
                   1666:     } elsif ($action eq 'updatenow') {
                   1667:         $r->print("<i>$lt{'setl'} $lt{'fnew'}</i>");
                   1668:     }
1.74      raeburn  1669:     $r->print('
1.14      raeburn  1670:                        </td>
                   1671:                       </tr>
                   1672:                       <tr>
1.74      raeburn  1673:                        <td>'.$end_table.'
1.14      raeburn  1674:                        </td>
                   1675:                       </tr>
                   1676:                      </table>
                   1677:                     </td>
                   1678:                    </tr>
1.74      raeburn  1679:     ');
1.14      raeburn  1680:     if ($action eq 'setaccess') {
1.74      raeburn  1681:         $r->print('
1.14      raeburn  1682:                    <tr>
1.74      raeburn  1683:                     <td colspan="2"><span style="color: #888888">'.$lt{'ifad'}.'</span></td>
1.14      raeburn  1684:                    </tr>
1.16      raeburn  1685:                    <tr>
1.74      raeburn  1686:                     <td colspan="2">&nbsp;</td>
1.16      raeburn  1687:                    </tr>
                   1688:                    <tr>
1.74      raeburn  1689:                     <td colspan="2"><b>'.&mt('Note').':</b> '.$lt{'ncds'}.' '.$lt{'tcha'}.'</td>
1.16      raeburn  1690:                    </tr>
1.14      raeburn  1691:                   </table>
1.74      raeburn  1692:         ');
1.14      raeburn  1693:     } elsif ($action eq 'updatenow') {
1.74      raeburn  1694:         $r->print('
1.14      raeburn  1695:                   </table>
1.74      raeburn  1696:         ');
1.14      raeburn  1697:     }
                   1698: }
                   1699: 
1.1       raeburn  1700: ###############################################################
                   1701: sub print_doc_base {
1.41      albertel 1702:     my ($r) = @_;
1.74      raeburn  1703:     $r->print('
1.1       raeburn  1704:   </td>
                   1705:  </tr>
                   1706: </table>
1.74      raeburn  1707: <br />'."\n".
                   1708:     &Apache::loncommon::end_page());
1.1       raeburn  1709: }
                   1710:  
                   1711: ###################################################################
                   1712: sub print_chgsettings_response {
1.15      albertel 1713:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.84      raeburn  1714:     my %settings = &Apache::lonnet::get('environment',['internal.autoadds','internal.autodrops'],$dom,$crs);
                   1715:     my ($curradds,$currdrops,$autoadds,$autodrops,$response,$warning,
                   1716:         $warn_prefix,$warn_suffix,$warnfiller);
1.15      albertel 1717:     if ( defined($settings{'internal.autoadds'}) ) {
                   1718: 	$curradds = $settings{'internal.autoadds'};
                   1719:     }
                   1720:     if ( defined($settings{'internal.autodrops'}) ) {
                   1721: 	$currdrops = $settings{'internal.autodrops'};
                   1722:     }
1.23      albertel 1723:     if ( exists($env{'form.autoadds'}) ) {
                   1724: 	$autoadds=$env{'form.autoadds'};
1.15      albertel 1725:     }
1.23      albertel 1726:     if ( exists($env{'form.autodrops'}) ) {
                   1727: 	$autodrops=$env{'form.autodrops'};
1.15      albertel 1728:     }
                   1729:     my %cenv = ('internal.autoadds' => $autoadds,
                   1730: 		'internal.autodrops' => $autodrops);
                   1731:     my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  1732:     if ($reply ne 'ok') {
                   1733: 	$response = 
                   1734:             &mt('There was a problem processing your requested changes.').' '.
                   1735:             &mt('The automated enrollment settings for this course have been left unchanged.').'<br />';
1.15      albertel 1736:     } else {
                   1737: 	if ($autoadds) {
                   1738: 	    if ($curradds) {
1.74      raeburn  1739:                 $response =
                   1740:                     &mt('Nightly additions based on classlist changes still [_1]enabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1741: 	    } else {
1.74      raeburn  1742:                 $response = 
                   1743:                     &mt('Nightly additions based on classlist changes now [_1]enabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1744: 	    }
                   1745: 	} else {
                   1746: 	    if ($curradds) {
1.74      raeburn  1747: 		$response = 
                   1748:                     &mt('Nightly additions based on classlist changes now [_1]disabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1749: 	    } else {
1.74      raeburn  1750: 		$response = 
                   1751:                     &mt('Nightly additions based on classlist changes still [_1]disabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1752: 	    }
                   1753: 	}
                   1754: 	if ($autodrops) {
                   1755: 	    if ($currdrops) {
1.74      raeburn  1756: 		$response .= &mt('Nightly removals based on classlist changes still [_1]enabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1757: 	    } else {
1.74      raeburn  1758: 		$response .= &mt('Nightly removals based on classlist changes now [_1]enabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1759: 	    }
                   1760: 	} else {
                   1761: 	    if ($currdrops) {
1.74      raeburn  1762: 		$response .= &mt('Nightly removals based on classlist changes now [_1]disabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1763: 	    } else {
1.74      raeburn  1764: 		$response .= &mt('Nightly removals based on classlist changes still [_1]disabled[_2]','<b>','</b>').'<br />';
1.15      albertel 1765: 	    }
                   1766: 	}
                   1767: 	if ($autoadds || $autodrops) {
                   1768: 	    $warning = &warning_message($dom,$crs,$action);
1.74      raeburn  1769:             unless ($warning eq '') {
                   1770: 	        $response .= '<br /><span class="LC_warning">'.
                   1771:                              '<b>'.&mt('Warning.').'</b> ';
1.84      raeburn  1772:                 if ($autoadds && $autodrops) {
1.74      raeburn  1773:                     $response .= 
                   1774:                         &mt('Although you indicated that nightly adds and drops should be enabled, additional action is required.');
                   1775:                 } elsif ($autoadds) {
                   1776:                     $response .= 
                   1777:                         &mt('Although you indicated that nightly adds should be enabled, additional action is required.');
                   1778:                 } else {
                   1779:                     $response .=
                   1780:                         &mt('Although you indicated that nightly drops should be enabled, additional action is required.');
                   1781:                 }
                   1782: 	        $response .= '</span><br />'.$warning;
1.15      albertel 1783: 	    }
1.74      raeburn  1784:         }
1.15      albertel 1785:     }
                   1786:     &print_reply($r,$response,$$tasktitleref{$action});
                   1787:     return;
1.1       raeburn  1788: }
                   1789: 
1.84      raeburn  1790: sub print_chgfailsafe_response {
                   1791:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.90      raeburn  1792:     my %settings = &Apache::lonnet::get('environment',
                   1793:                                         ['internal.autodropfailsafe',
                   1794:                                          'internal.autodropfailsafetype'],
1.84      raeburn  1795:                                         $dom,$crs);
1.90      raeburn  1796:     my ($currfailsafe,$newfailsafe,$currfailsafetype,$newfailsafetype,$response);
                   1797:     if (defined($settings{'internal.autodropfailsafe'})) {
1.84      raeburn  1798:         $currfailsafe = $settings{'internal.autodropfailsafe'};
                   1799:     }
1.90      raeburn  1800:     if (defined($settings{'internal.autodropfailsafetype'})) {
                   1801:         $currfailsafetype = $settings{'internal.autodropfailsafetype'};
                   1802:     }
1.84      raeburn  1803:     if (exists($env{'form.autodropfailsafe'})) {
                   1804:         $env{'form.autodropfailsafe'} =~ s{^\s+|\s+$}{}g;
                   1805:         if ($env{'form.autodropfailsafe'} !~ /\D/) { 
                   1806:             $newfailsafe = $env{'form.autodropfailsafe'};
                   1807:         }
                   1808:     }
1.90      raeburn  1809:     if ($env{'form.autodropfailsafetype'} =~ /^(any|zero|off)$/) {
                   1810:         $newfailsafetype = $env{'form.autodropfailsafetype'};
                   1811:     }
                   1812:     if (($currfailsafe ne $newfailsafe) || ($currfailsafetype ne $newfailsafetype)) {
                   1813:         my %cenv = ('internal.autodropfailsafe' => $newfailsafe,
                   1814:                     'internal.autodropfailsafetype' => $newfailsafetype,
                   1815:                    );
1.84      raeburn  1816:         my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
                   1817:         if ($reply ne 'ok') {
                   1818:             $response =
                   1819:                 &mt('There was a problem processing your requested changes.').' '.
                   1820:                 &mt('The automated enrollment settings for this course have been left unchanged.').'<br />';
                   1821:         } else {
1.90      raeburn  1822:             if ($currfailsafetype ne $newfailsafetype) {
                   1823:                 if ($env{'form.autodropfailsafetype'} eq 'dom') {
                   1824:                     $response = &mt('Course-specific setting for condition for when failsafe applies deleted; domain default now applies.');
                   1825:                 } elsif ($newfailsafetype eq 'off') {
                   1826:                     $response = &mt('Course-specific setting set to disable failsafe use.');
                   1827:                 } elsif ($newfailsafetype eq 'zero') {
                   1828:                     $response = &mt('Course-specific setting set so failsafe applies when zero enrollment retrieved for an institutional section.');
                   1829:                 } else {
                   1830:                     $response = &mt('Course-specific setting set so failsafe applies when zero or greater enrollment is retrieved for an institutional section.');
                   1831:                 }
                   1832:                 $response .= '<br />';
                   1833:             }
                   1834:             if ($currfailsafe ne $newfailsafe) {
                   1835:                 if ($newfailsafe ne '') {
                   1836:                     $response .= &mt('Course-specific setting for drop failsafe threshold set to [_1]',$newfailsafe);
                   1837:                 } else {
                   1838:                     $response .= &mt('Course-specific setting for drop failsafe threshold deleted; domain default now applies.');
                   1839:                 }
                   1840:             }
1.84      raeburn  1841:         }
                   1842:     } else {
1.90      raeburn  1843:         $response = &mt('The new values for the automated drop failsafe threshold and conditions under which failsafe applies were the same as the existing values, so no changes have been made.'); 
1.84      raeburn  1844:     }
                   1845:     &print_reply($r,$response,$$tasktitleref{$action});
                   1846:     return;
                   1847: }
                   1848: 
1.1       raeburn  1849: sub print_setdates_response {
1.15      albertel 1850:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  1851:     my %settings = 
                   1852:         &Apache::lonnet::get('environment',
                   1853:                              ['internal.autostart','internal.autoend'],
                   1854:                              $dom,$crs);
1.15      albertel 1855:     my $currstart = $settings{'internal.autostart'};
                   1856:     my $currend = $settings{'internal.autoend'};
1.74      raeburn  1857:     my ($response,$showstart,$showend,$warning,$warn_prefix);
1.19      raeburn  1858:     my ($autostart,$autoend) = &get_dates_from_form();
                   1859:     if ( ($autostart eq '') || ($autoend eq '') ) {
1.74      raeburn  1860:         $response = 
                   1861:             &mt('There was a problem processing your requested changes.').' '.
                   1862:             &mt('The automated enrollment settings for this course have been left unchanged.').'<br />';
1.19      raeburn  1863:     } elsif (($autoend > 0) && ($autoend <= $autostart)) {
1.74      raeburn  1864:         $response = 
                   1865:             &mt('The date/time selected for starting auto-enrollment was the same or later than the date/time selected for ending auto-enrollment.').' '.
                   1866:             &mt('As this means auto-enrollment will never be active, your requested changes have not been processed, and the existing values remain in effect.').' '.
                   1867:             &mt('Please [_1]go back[_2] to the previous page to try your changes again.',
                   1868:                 '<a href="javascript:history.go(-1)">','</a>')."\n";
1.19      raeburn  1869:     } else {       
                   1870:         $showstart = &Apache::lonlocal::locallocaltime($autostart);
                   1871:         if ($autoend) {
                   1872: 	    $showend = &Apache::lonlocal::locallocaltime($autoend);
                   1873:         } else {
1.74      raeburn  1874: 	    $showend = &mt("'No end date'");
1.19      raeburn  1875:         } 
1.15      albertel 1876: 
1.19      raeburn  1877:         my %cenv = ('internal.autostart' => $autostart,
                   1878:   		    'internal.autoend' => $autoend);
                   1879:         my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  1880:         if ($reply ne 'ok') {
                   1881: 	    $response = 
                   1882:                 &mt('There was a problem processing your requested changes.').' '.
                   1883:                 &mt('The automated enrollment settings for this course have been left unchanged.').'<br />';
1.19      raeburn  1884:         } else {
                   1885: 	    if ($currstart == $autostart) {
1.74      raeburn  1886: 	        $response = &mt('The first date for automated enrollment has been left unchanged as [_1]',$showstart).'<br />';
1.19      raeburn  1887: 	    } else {
1.74      raeburn  1888: 	        $response = &mt('The first date for automated enrollment has been changed to [_1]',$showstart).'<br />';
1.19      raeburn  1889: 	    } 
                   1890: 	    if ($currend == $autoend) {
1.74      raeburn  1891: 	        $response .= &mt('The last date for automated enrollment has been left unchanged as [_1]',$showend).'<br />';
1.19      raeburn  1892: 	    } else {
1.74      raeburn  1893: 	        $response .= &mt('The last date for automated enrollment has been changed to [_1]',$showend).'<br />';
1.19      raeburn  1894: 	    }
1.1       raeburn  1895:  
1.14      raeburn  1896: # Generate message in case where old first enrollment date was later than today, but new first enrollment date is now today or earlier.
1.1       raeburn  1897: 
1.19      raeburn  1898: 	    my $rosterupdated = 0;
1.74      raeburn  1899:             my ($firstaccess,$nextupdate,$lastupdate);
1.19      raeburn  1900: 	    my $nowstamp = time;
                   1901: 	    my @date_list=localtime(time);
                   1902: 	    my $cur_year = $date_list[5];
                   1903: 	    my $curday = $date_list[3];
                   1904: 	    my $curmonth = $date_list[4];
                   1905: 	    my $lastmidnt = timelocal(0,0,0,$date_list[3],$date_list[4],$date_list[5]);
                   1906: 	    my $nextmidnt = 86400 + $lastmidnt;
                   1907: 
                   1908: 	    my $todayupdate = timelocal(0,30,1,$date_list[3],$date_list[4],$date_list[5]);
                   1909: 	    my $lastupdate = $todayupdate - 86400;
                   1910: 	    if ($nowstamp < $todayupdate) {
                   1911: 	      $nextupdate = "today";
1.15      albertel 1912: 	    } else {
1.19      raeburn  1913: 	      $nextupdate = "tomorrow";
1.15      albertel 1914: 	    }
1.19      raeburn  1915: 	    if ($currstart < $lastupdate) {
                   1916: 	        $rosterupdated = 1;
1.15      albertel 1917: 	    }
1.19      raeburn  1918: 	    if ($autostart < $nextmidnt ) {
                   1919: 	        if ( $autostart >= $lastmidnt) {
                   1920: 		    $firstaccess = "today";
                   1921: 	        } else {
                   1922: 	  	    $firstaccess = "a date prior to today";
                   1923: 	        }
                   1924: 	        if (($nowstamp >= $autostart) && ($rosterupdated == 0)) {
1.74      raeburn  1925: 		    $response .= 
                   1926:                         '<br />'.
                   1927:                         &mt("Although you have now set the first enrollment date to $firstaccess, automatic enrollment will [_1]not[_2] occur until the next automatic enrollment update occurs for all LON-CAPA courses at 1.30 am $nextupdate.",'<b>','</b>').' '.
                   1928:                         &mt('If you wish to immediately enroll registered students included in the institutional classlist for this class, please visit the [_1]roster update page[_2].'.
                   1929:                            '<a href="/adm/populate?action=updatenow">','</a>').
                   1930:                         '<br />';
1.19      raeburn  1931: 	        }
                   1932: 	    }
                   1933: 	    $warning = &warning_message($dom,$crs,$action);
1.74      raeburn  1934:             unless ($warning eq '') {
                   1935:                 $response .= 
                   1936:                     '<br /><span class="LC_warning">'.
                   1937:                     '<b>'.&mt('Warning.').'</b> '.
                   1938:                     &mt('Although you set a start and end date for auto-enrollment, additional action is required.').'</span><br />'.$warning;
1.19      raeburn  1939: 	    }
                   1940:         }
1.15      albertel 1941:     }
                   1942:     &print_reply($r,$response,$$tasktitleref{$action});
                   1943:     return;
1.1       raeburn  1944: }
                   1945: 
1.14      raeburn  1946: sub print_setaccess_response {
1.15      albertel 1947:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  1948:     my %settings = 
                   1949:         &Apache::lonnet::get('environment',
                   1950:                              ['default_enrollment_start_date',
                   1951:                               'default_enrollment_end_date',
                   1952:                               'internal.autostart'],$dom,$crs);
1.15      albertel 1953:     my $currstart = $settings{'default_enrollment_start_date'};
                   1954:     my $currend = $settings{'default_enrollment_end_date'};
                   1955:     my $autostart = $settings{'internal.autostart'};
1.74      raeburn  1956:     my $response;
1.15      albertel 1957:     my ($startaccess,$endaccess) = &get_dates_from_form();
1.19      raeburn  1958:     if (($startaccess eq '') || ($endaccess eq '')) {
1.74      raeburn  1959:         $response = 
                   1960:             &mt('There was a problem processing your requested changes.').' '.
                   1961:             &mt('The default start and end access dates for this course have been left unchanged.').
                   1962:             '<br />';
1.19      raeburn  1963:     } elsif (($endaccess > 0) && ($endaccess <= $startaccess)) {
1.74      raeburn  1964:         $response = 
                   1965:             &mt('The default start access date/time you chose was the same or later than the default end access date/time.').' '.
                   1966:             &mt('As this means that roles will never be active, your requested changes have not been processed, and the existing values remain in effect.').' '.
                   1967:             &mt('Please [_1]go back[_2] to the previous page to try your changes again.',
                   1968:                 '<a href="javascript:history.go(-1)">','</a>')."\n";
1.15      albertel 1969:     } else {
1.19      raeburn  1970:         my $showstart = &Apache::lonlocal::locallocaltime($startaccess);
1.74      raeburn  1971:         my ($showend,$warning,$warn_prefix);
1.19      raeburn  1972:         if ($endaccess) {
                   1973: 	    $showend = &Apache::lonlocal::locallocaltime($endaccess);
                   1974:         } else {
1.74      raeburn  1975: 	    $showend = &mt("'No end date'");
1.19      raeburn  1976:         }
1.15      albertel 1977: 
1.19      raeburn  1978:         my %cenv = ('default_enrollment_start_date' => $startaccess,
1.15      albertel 1979: 		'default_enrollment_end_date' => $endaccess);
1.19      raeburn  1980:         my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  1981:         if ($reply ne 'ok') {
                   1982: 	    $response = 
                   1983:                 &mt('There was a problem processing your requested changes.').' '.
                   1984:                 &mt('The automated enrollment settings for this course have been left unchanged.').'<br />';
1.19      raeburn  1985:         } else {
                   1986: 	    if ($currstart == $startaccess) {
1.74      raeburn  1987: 	        $response = &mt('The first access date for students being added via automated enrollment has been left unchanged as [_1].',$showstart).'<br />';
1.19      raeburn  1988: 	    } else {
1.74      raeburn  1989: 	        $response = &mt('The first access date for students being added via automated enrollment has been changed to [_1].',$showstart).'<br />';
1.19      raeburn  1990: 	    }
                   1991: 	    if ($currend == $endaccess) {
1.74      raeburn  1992: 	        $response .= &mt('The last access date for students being added via automated enrollment has been left unchanged as [_1].',$showend).'<br />';
1.19      raeburn  1993: 	    } else {
1.74      raeburn  1994: 	        $response .= &mt('The last access date for students being added via automated enrollment has been changed to [_1]',$showend).'<br />';
1.19      raeburn  1995: 	    }
1.74      raeburn  1996:             $response .= 
                   1997:                 '<br />'.
                   1998:                 &mt('Any change in access dates will only apply to students who are not currently active, i.e., those who currently have access start dates in the future, and to those added by future automated enrollment.').
                   1999:                 '<br /><br />'.
1.77      bisitz   2000:                  &mt('To change access dates for [_1]currently active[_2] students, use User Management -> "Manage course users" to display currently active students, then use the dropdown menu for "Action to take for selected users:" to choose "Change starting/ending dates", select the students to change, and click "Proceed".','<b>','</b>').
1.74      raeburn  2001:                 '<br />';
                   2002: 
1.14      raeburn  2003: # Generate message in case where old first access date was later than today, but new first access date is now today or earlier.
1.74      raeburn  2004: 
1.19      raeburn  2005: 	    my $accessgiven= 0;
1.74      raeburn  2006: 	    my ($firstaccess,$nextupdate,$lastupdate);
1.19      raeburn  2007: 	    my $nowstamp = time;
                   2008: 	    my @date_list=localtime(time);
                   2009: 	    my $cur_year = $date_list[5];
                   2010: 	    my $curday = $date_list[3];
                   2011: 	    my $curmonth = $date_list[4];
                   2012: 	    my $lastmidnt = timelocal(0,0,0,$date_list[3],$date_list[4],$date_list[5]);
                   2013: 	    my $nextmidnt = 86400 + $lastmidnt;
                   2014: 
                   2015: 	    my $todayupdate = timelocal(0,30,1,$date_list[3],$date_list[4],$date_list[5]);
                   2016: 	    my $tomorrowupdate = $todayupdate + 86400;
                   2017: 	    my $lastupdate = $todayupdate - 86400;
                   2018: 
                   2019: 	    if ($autostart < $nextmidnt) {
                   2020: 	        if ($nowstamp < $todayupdate) {
1.74      raeburn  2021: 		    $nextupdate = 'at 1.30 am today';
1.19      raeburn  2022: 	        } else {
1.74      raeburn  2023: 		    $nextupdate = 'at 1.30 am tomorrow';
1.19      raeburn  2024: 	        }
1.15      albertel 2025: 	    } else {
1.19      raeburn  2026: 	        my @enrollstart = localtime($autostart);
                   2027: 	        $nextupdate = timelocal(0,30,1,$enrollstart[3],$enrollstart[4],$enrollstart[5]);
                   2028: 	        unless (($enrollstart[2] < 1) || ($enrollstart[2] == 1 && $enrollstart[1] <=30))  {
                   2029: 		    $nextupdate += 86400; 
                   2030: 	        }
                   2031: 	        $nextupdate = &Apache::lonlocal::locallocaltime($nextupdate);
                   2032: 	    }
                   2033: 	    if (($currstart < $lastupdate) && ($autostart < $lastupdate)) {
                   2034: 	        $accessgiven = 1;
                   2035: 	    }
                   2036: 	    if ($startaccess < $nextmidnt ) {
                   2037: 	        if ( $startaccess >= $lastmidnt) {
1.74      raeburn  2038: 	    	    $firstaccess = 'today';
1.19      raeburn  2039: 	        } else {
1.74      raeburn  2040: 		    $firstaccess = 'a date prior to today';
1.19      raeburn  2041: 	        }
                   2042: 	        if (($nowstamp >= $startaccess) && ($accessgiven == 0)) {
1.74      raeburn  2043: 		    $response .= 
                   2044:                         '<br />'.
                   2045:                         &mt("Although you have now set the first access date to $firstaccess, automatic enrollment will [_1]not[_2] occur until the next automatic enrollment update occurs for all LON-CAPA courses $nextupdate.",
                   2046:                             '<b>','</b>').' '.
                   2047:                         &mt('If you wish to grant immediate course access for registered students included in the institutional classlist for this class, please visit the [_1]roster update page[_2].',
                   2048:                             '<a href="/adm/populate?action=updatenow">','</a>').
                   2049:                        '<br />';
1.19      raeburn  2050: 	        }
1.15      albertel 2051: 	    }
1.19      raeburn  2052: 	    $warning = &warning_message($dom,$crs,$action);
1.74      raeburn  2053:             unless ($warning eq '') {
                   2054: 	        $response .= '<br /><span class="LC_warning">'.
                   2055:                              '<b>'.&mt('Warning.').'</b> '.
                   2056:                              &mt('Although you have set default first and last access dates for students who are added via automatic enrollment, additional action is required.').
                   2057:                             '</span><br />'.$warning;
1.15      albertel 2058: 	    }
1.19      raeburn  2059:         }
1.15      albertel 2060:     }
                   2061:     &print_reply($r,$response,$$tasktitleref{$action});
                   2062:     return;
1.14      raeburn  2063: }
                   2064: 
1.1       raeburn  2065: sub print_notify_response {
1.15      albertel 2066:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.1       raeburn  2067: 
                   2068: # Get current settings
1.74      raeburn  2069:     my %settings = 
                   2070:         &Apache::lonnet::get('environment',
                   2071:                              ['internal.notifylist','internal.coursecode'],
                   2072:                              $dom,$crs);
1.15      albertel 2073:     my $notifylist = $settings{'internal.notifylist'};
                   2074:     my $coursecode = $settings{'internal.coursecode'};
1.28      albertel 2075:     my @currpeople = split(/,/,$notifylist);
1.15      albertel 2076:     my $notify = 0;
1.74      raeburn  2077:     my ($peoplestr,$response,@people);
1.15      albertel 2078:     my $noprocess = 0;
                   2079:     my $currcount = 0;
1.74      raeburn  2080:     foreach my $item (@currpeople) {
                   2081: 	unless ($item eq '') { $currcount ++; } 
1.15      albertel 2082:     }
1.23      albertel 2083:     if ( exists($env{'form.notify'}) ) {
                   2084: 	$notify=$env{'form.notify'};
1.15      albertel 2085:     }
1.23      albertel 2086:     if ( exists($env{'form.notifyshow'}) ) {
                   2087: 	my $notifyshow = $env{'form.notifyshow'};
1.15      albertel 2088: 	for (my $i=0; $i<$notifyshow; $i++) {
1.23      albertel 2089: 	    if ( exists($env{"form.note_$i"}) ) {
                   2090: 		if ( exists($env{"form.notifyname_$i"}) ) {
                   2091: 		    unless ( $env{"form.notifyname_$i"} eq '' ) {
1.74      raeburn  2092: 			push(@people,$env{"form.notifyname_$i"});
1.15      albertel 2093: 		    }
                   2094: 		}
                   2095: 	    }
                   2096: 	}
1.74      raeburn  2097: 	if ($notify) { $peoplestr = join(',',@people); }
1.15      albertel 2098:     } else {
                   2099: 	if ($notify) {
                   2100: 	    if ($currcount) {
1.74      raeburn  2101: 		$response = &mt('There was a problem retrieving the updated list of recipients of notification messages.').' '.
                   2102:                             &mt('The notification settings for this course have been left unchanged.').'<br />';
1.15      albertel 2103: 		$peoplestr = $notifylist;
                   2104: 		@people = @currpeople;
                   2105: 		$noprocess = 1;
                   2106: 	    }
                   2107: 	}
                   2108:     }
                   2109:     unless ($noprocess == 1) {
                   2110: 	my %cenv = ('internal.notifylist' => $peoplestr);
                   2111: 	my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  2112: 	if ($reply ne 'ok') {
                   2113: 	    $response = 
                   2114:                 &mt('There was a problem processing your requested changes.').' '.
                   2115:                 &mt('The notification settings for this course have been left unchanged.').
                   2116:                 '<br />';
1.15      albertel 2117: 	} else {
                   2118: 	    if ($notify) {
                   2119: 		if (@people) {
                   2120: 		    if ($currcount) {
1.74      raeburn  2121: 			$response .=
                   2122:                             &mt('Notification of enrollment changes still [_1]enabled[_2]','<b>','</b>').
                   2123:                             '<br />';
1.15      albertel 2124: 		    } else {
1.74      raeburn  2125: 			$response .=
                   2126:                             &mt('Notification of enrollment changes now [_1]enabled[_2]'.'<b>','</b>').
                   2127:                             '<br />';
1.15      albertel 2128: 		    }
1.74      raeburn  2129: 		    $response .= 
                   2130:                         '<br />'.
                   2131:                         &mt('The following will receive notification if there are any changes in enrollment in LON-CAPA course: [_1] as a result of the nightly enrollment check:',"$realm ($coursecode)").
                   2132:                         '<br /><ul>'."\n";
1.15      albertel 2133: 		    foreach my $person (@people) {
                   2134: 			$response .= "<li>$person</li>\n";
                   2135: 		    }
                   2136: 		    $response .= "</ul>\n";
                   2137: 		} else {
1.70      bisitz   2138: 		    $response = &mt('Notification of enrollment changes was [_1]not enabled[_2] as no [_3]s were selected as recipients.','<b>','</b>',&Apache::lonnet::plaintext('cc')).'<br />';
1.15      albertel 2139: 		}
                   2140: 	    } else {
                   2141: 		if ($currcount) {
1.74      raeburn  2142: 		    $response = &mt('Notification of enrollment changes now [_1]disabled[_2]','<b>','</b>').'<br />';
1.15      albertel 2143: 		} else {
1.74      raeburn  2144: 		    $response = &mt('Notification of enrollment changes still [_1]disabled[_2]','<b>','</b>').'<br />';
1.15      albertel 2145: 		}
                   2146: 	    }
                   2147: 	}
                   2148:     }
                   2149:     &print_reply($r,$response,$$tasktitleref{$action});
                   2150:     return;
1.1       raeburn  2151: }
                   2152: 
1.74      raeburn  2153: sub print_crosslistings_menu {
1.15      albertel 2154:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  2155:     my %settings = 
                   2156:         &Apache::lonnet::get('environment',
                   2157:                              ['internal.crosslistings','internal.coursecode'],
                   2158:                              $dom,$crs);
                   2159:     my (@currxlists,@xlists,$xliststr,$response);
1.15      albertel 2160:     my $crosscount = 0;
                   2161:     my $removecount = 0;
                   2162:     my $coursecode = $settings{'internal.coursecode'};
1.28      albertel 2163:     if ($settings{'internal.crosslistings'} ne '') {
                   2164: 	@currxlists = split(/,/,$settings{'internal.crosslistings'});
1.15      albertel 2165:     }
                   2166:     if (@currxlists > 0) {
                   2167: 	for (my $i=0; $i<@currxlists; $i++) {
                   2168: 	    my $xlist = "cross_".$i;
1.42      raeburn  2169: 	    my $lc_sec = "lcsec_".$i;
1.23      albertel 2170: 	    if ( exists($env{"form.$xlist"}) ) {
1.15      albertel 2171: 		my $xlistentry = '';
1.74      raeburn  2172: 		if ($currxlists[$i] =~ /^([^:]+)/) {
1.15      albertel 2173: 		    $xlistentry = $1.':';
                   2174: 		}
1.42      raeburn  2175: 		if ( exists($env{"form.$lc_sec"}) ) {
                   2176: 		    $xlistentry .= $env{"form.$lc_sec"};
1.15      albertel 2177: 		}
1.74      raeburn  2178: 		push(@xlists,$xlistentry);
1.15      albertel 2179: 		$crosscount ++;
                   2180: 	    } else {
                   2181: 		$removecount ++;
                   2182: 	    }
                   2183: 	}
                   2184:     }
1.1       raeburn  2185: 
1.74      raeburn  2186:     $xliststr = join(',',@xlists);
1.28      albertel 2187: 
1.15      albertel 2188:     my %cenv = ('internal.crosslistings' => $xliststr);
                   2189:     my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  2190:     if ($reply ne 'ok') {
                   2191: 	$response = &mt('There was a problem processing your requested changes.').' '.
                   2192:                     &mt('The automated enrollment settings for this course have been left unchanged.').'<br />';
1.15      albertel 2193:     } else {
                   2194: 	if ($removecount > 0) {
1.74      raeburn  2195: 	    $response = &mt('A total of [quant,_1,course is,courses are] no longer crosslisted with LON-CAPA course: [_2].',
                   2196:                             $removecount,"$realm ($coursecode").'<br /><br />';
1.15      albertel 2197: 	}
                   2198: 	if ($crosscount > 0) {
1.74      raeburn  2199: 	    $response .= &mt('The [quant,_1,course] listed below remain crosslisted with this LON-CAPA course, and students enrolling in these course sections will be automatically added to the class roster for the course, if you have chosen to enable a nightly automated enrollment update.',$crosscount).
                   2200:                          '<br /><ul>'."\n";
1.87      raeburn  2201:             my @showable;
                   2202:             &reformat_xlists($dom,$crs,$coursecode,\@xlists,\@showable);
                   2203:             foreach my $item (@showable) {
                   2204:                 my ($xlist,$lc_sec) = split(/:/,$item);
1.74      raeburn  2205: 		$response .= 
                   2206:                     '<li>'.&mt('[_1] - ID: [_2]',$xlist,$lc_sec).'</li>'."\n";
1.15      albertel 2207: 	    }
1.74      raeburn  2208: 	    $response .= '</ul><br />'."\n";
1.15      albertel 2209: 	}
                   2210:     }
1.23      albertel 2211:     if ( exists($env{'form.numcross'}) ) {
                   2212: 	my $numcross = $env{'form.numcross'};
1.74      raeburn  2213: 	if ($numcross) {
1.87      raeburn  2214:             my (@codetitles,%cat_titles,%cat_order,@code_order);
                   2215:             &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
                   2216:                                                      \%cat_order,\@code_order);       
                   2217: 	    $response .=
                   2218:                 &mt('You indicated that you wish to add an additional [quant,_1,crosslisting].',$numcross).' ';
                   2219:             if (@codetitles > 0) {
                   2220:                 my $lastitem = pop(@codetitles);
                   2221:                 $response .=
                   2222:                     &mt('For each new crosslisting select [_1], and enter the [_2] and the LON-CAPA section ID.',join(', ',@codetitles),$lastitem).' '.
                   2223:                     &mt('The LON-CAPA section ID can be left blank, if you do not wish to tie a section ID to this crosslisting.').' '.
                   2224:                     '<br /><br />'.
                   2225:                     '<form name="enter" method="post" action="">'."\n".
                   2226:                     &Apache::loncommon::start_data_table()."\n".
                   2227:                     &Apache::loncommon::start_data_table_header_row()."\n";
                   2228:                 foreach my $title (@codetitles) {
                   2229:                     if (ref($cat_order{$title}) eq 'ARRAY') {
                   2230:                         if (@{$cat_order{$title}} > 0) {
                   2231:                             $response .= '<th>'.$title.'</th>';
                   2232:                         }
                   2233:                     }
                   2234:                 }
                   2235:                 $response .= '<th>'.$lastitem.'</th>'."\n".
                   2236:                              '<th>'.&mt('Institutional section').'</th>'."\n".
                   2237:                              '<th>'.&mt('LON-CAPA section').'</th>'."\n".
                   2238:                              &Apache::loncommon::end_data_table_header_row()."\n";
                   2239:                 for (my $i=0; $i<$numcross; $i++) {
                   2240:                     $response .=
                   2241:                         &Apache::loncommon::start_data_table_row()."\n";
                   2242:                     foreach my $title (@codetitles) {
                   2243:                         if (ref($cat_order{$title}) eq 'ARRAY') {
                   2244:                             if (@{$cat_order{$title}} > 0) {
                   2245:                                 $response .= '<td align="center">'.
                   2246:                                              '<select name="newcross_'.$i.'_'.$title.'">'."\n".
                   2247:                                              ' <option value="" selected="selected">'.
                   2248:                                              &mt('Select').'</option>'."\n";
                   2249:                                 foreach my $item (@{$cat_order{$title}}) {
                   2250:                                     my $longitem = $item;
                   2251:                                     if (ref($cat_titles{$title}) eq 'HASH') {
                   2252:                                         if ($cat_titles{$title}{$item} ne '') {
                   2253:                                             $longitem = $cat_titles{$title}{$item};
                   2254:                                         }
                   2255:                                     }
                   2256:                                     $response .= '<option value="'.$item.'">'.$longitem.
                   2257:                                                  '</option>'."\n";
                   2258:                                 }
                   2259:                                 $response .= '</select></td>'."\n";
                   2260:                             }
                   2261:                         }
                   2262:                     }
                   2263:                     $response .= '<td align="center">'.
                   2264:                                  '<input type="text" size="5" name="newcross_'.$i.'_'.$lastitem.'" />'.
                   2265:                                  '</td>'."\n".'<td align="center">'.
                   2266:                                  '<input type="text" size="10" name="newcross_'.$i.'_instsec" />'.
                   2267:                                  '</td>'."\n".'<td align="center">'.
                   2268:                                  '<input type="text" size="10" name="newlcsec_'.$i.'" /></td>'.
                   2269:                                  &Apache::loncommon::end_data_table_row()."\n";
                   2270:                 }
                   2271:                 $response .= &Apache::loncommon::end_data_table()."\n";
                   2272:             } else {
                   2273:                 $response .=              
                   2274:                     &mt('For each new crosslisting enter the institutional course section code (e.g., fs03zol101001, for section 001 of zol101 for fs03 semester), and the LON-CAPA section ID you wish to assign to students who will be enrolled in your LON-CAPA class as a result of their registration in the crosslisted course section.').' '.
                   2275:                     &mt('The LON-CAPA section ID can be left blank, if you do not wish to tie a section ID to this crosslisting.').' '.
                   2276:                     &mt("The institutional course section code should only contain letters and/or numbers, and must be consistent with the scheme adopted by your Domain Coordinator to map course codes (and section numbers) to your institution's student information system.").
                   2277:                     '<br /><br />'.
                   2278:                     '<form name="enter" method="post" action="">'."\n".
                   2279:                     &Apache::loncommon::start_data_table()."\n".
                   2280:                     &Apache::loncommon::start_data_table_row()."\n".
                   2281:                     '<th>'.&mt('Crosslisting').'</th>'."\n".
                   2282:                     '<th>'.&mt('LON-CAPA section ID').'</th>'."\n".
1.74      raeburn  2283:                     &Apache::loncommon::end_data_table_row();
1.87      raeburn  2284: 	       for (my $i=0; $i<$numcross; $i++) {
                   2285:                    $response .= 
                   2286:                        &Apache::loncommon::start_data_table_row().'
                   2287:                        <td><input type="text" size="15" name="newcross_'.$i.'" /></td>
                   2288:                        <td align="right"><input type="text" size="10" name="newlcsec_'.$i.'" /></td>'.
                   2289:                        &Apache::loncommon::end_data_table_row();
                   2290: 	        }
                   2291:                 $response .= &Apache::loncommon::end_data_table();
                   2292:             }
                   2293:             $response .= '
1.1       raeburn  2294:               </td>
                   2295:              </tr>
                   2296:              <tr>
                   2297:               <td align="right">
1.74      raeburn  2298:                <input type="button" name="newcross" value="'.&mt('Go').'" onclick="'."process('newcross')".'" />
1.1       raeburn  2299:               </td>
                   2300:              </tr>
                   2301:             </table>
1.74      raeburn  2302:             <input type="hidden" name="numcross" value="'.$numcross.'" />
                   2303:             <input type="hidden" name="action" value="newcross" />
                   2304:             <input type="hidden" name="state" value="process" />
                   2305:             </form>'."\n";
1.15      albertel 2306:         }
                   2307:     }
                   2308:     &print_reply($r,$response,$$tasktitleref{$action});
                   2309:     return;
1.1       raeburn  2310: }
                   2311: 
1.74      raeburn  2312: sub print_crosslistings_response {
1.15      albertel 2313:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  2314:     my %settings = 
                   2315:         &Apache::lonnet::get('environment',
                   2316:                              ['internal.crosslistings','internal.coursecode',
                   2317:                               'internal.courseowner','internal.co-owners'],
                   2318:                              $dom,$crs);
                   2319:     my (@currxlists,@xlists,@allxlists,@badxlists,@badowner,@reserved,
                   2320:         @matchgroup,$response,$warning,$warn_prefix);
1.15      albertel 2321:     my $numcross = 0;
                   2322:     my $xliststr =  $settings{'internal.crosslistings'};
                   2323:     my $coursecode = $settings{'internal.coursecode'};
                   2324:     my $owner = $settings{'internal.courseowner'};
1.68      raeburn  2325:     my $coowners = $settings{'internal.co-owners'};
1.28      albertel 2326:     if ($xliststr ne '') {
                   2327: 	@allxlists = split(/,/,$xliststr);
1.15      albertel 2328:     }
1.23      albertel 2329:     if ( exists($env{'form.numcross'}) ) {
                   2330: 	$numcross = $env{'form.numcross'};
1.15      albertel 2331:     }
1.74      raeburn  2332:     if ($numcross) {
1.43      raeburn  2333:         my %curr_groups = &Apache::longroup::coursegroups();
1.87      raeburn  2334:         my (@codetitles,%cat_titles,%cat_order,@code_order);
                   2335:         &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
                   2336:                                                  \%cat_order,\@code_order);
                   2337:         my $lastitem = $codetitles[-1];
1.15      albertel 2338: 	for (my $i=0; $i<$numcross; $i++) {
1.87      raeburn  2339: 	    my $xl = '';
                   2340:             if (@code_order > 0) {
                   2341:                 foreach my $item (@code_order) {
                   2342:                     my $possval = $env{'form.newcross_'.$i.'_'.$item};
                   2343:                     if ($item eq $lastitem) {
                   2344:                         $xl .= $possval;
                   2345:                     } else {
                   2346:                         my $possval = $env{'form.newcross_'.$i.'_'.$item};
                   2347:                         if (ref($cat_order{$item}) eq 'ARRAY') {
                   2348:                             if (grep(/^\Q$possval\E$/,@{$cat_order{$item}})) {
                   2349:                                 $xl .= $possval;
                   2350:                             }
                   2351:                         }
                   2352:                     }
                   2353:                 }
                   2354:                 if ($xl ne '') {
                   2355:                     my $crskey = $crs.':'.$xl;
                   2356:                     if ($env{'form.newcross_'.$i.'_instsec'} ne '') {
                   2357:                         my $poss_sec = $env{'form.newcross_'.$i.'_instsec'};
                   2358:                         my %formatted = &Apache::lonnet::auto_instsec_reformat($dom,'clutter',
                   2359:                                                                                {$crskey => [$poss_sec]});
                   2360:                         if (ref($formatted{$crskey}) eq 'ARRAY') {
                   2361:                             $xl .= $formatted{$crskey}->[0];
                   2362:                         }
                   2363:                     }
                   2364:                 }
                   2365:             } else {
                   2366:                 $xl = $env{'form.newcross_'.$i};
                   2367:             }
1.42      raeburn  2368: 	    my $lc_sec = "newlcsec_".$i;
1.87      raeburn  2369: 	    if ($xl ne '') {
1.42      raeburn  2370:                 if (exists($env{"form.$lc_sec"})) {
                   2371:                     my $lc_sec_check = &validate_lcsec(\%curr_groups,
                   2372:                                                     $env{"form.$lc_sec"});
                   2373:                     if ($lc_sec_check eq 'reserved') {
1.87      raeburn  2374:                         push(@reserved,$xl.':'.$env{"form.$lc_sec"});
1.42      raeburn  2375:                         next;
                   2376:                     } elsif ($lc_sec_check eq 'group') {
1.87      raeburn  2377:                         push(@matchgroup,$xl.':'.$env{"form.$lc_sec"});
1.42      raeburn  2378:                         next;
                   2379:                     }
                   2380:                 }
1.86      raeburn  2381: 		my $coursecheck =
1.87      raeburn  2382:                     &Apache::lonnet::auto_validate_courseID($crs,$dom,$xl);
1.15      albertel 2383: 		if ($coursecheck eq 'ok') {
                   2384: 		    my $addcheck = '';
1.87      raeburn  2385: 		    $addcheck = &Apache::lonnet::auto_new_course($crs,$dom,$xl,$owner,$coowners);
1.86      raeburn  2386: 		    unless ($addcheck eq 'ok') {
                   2387:                         if ($coowners) {
                   2388:                             foreach my $user (split(/,/,$coowners)) {
                   2389:                                 if ($user =~ /^($match_username):($match_domain)$/) {
                   2390:                                     if (&Apache::lonnet::auto_validate_inst_crosslist($crs,$dom,$coursecode,
1.87      raeburn  2391:                                                                                       $xl,$user) eq 'valid') {
1.86      raeburn  2392:                                         $addcheck = 'ok';
                   2393:                                         last;
                   2394:                                     }
                   2395:                                 }
                   2396:                             }
                   2397:                         }
                   2398:                     }
                   2399:                     if ($addcheck eq 'ok') {
1.87      raeburn  2400:                         push(@xlists,$xl.':'.$env{"form.$lc_sec"});
1.86      raeburn  2401:                     } else { 
1.87      raeburn  2402: 			push(@badowner,$xl.':'.$env{"form.$lc_sec"});
1.15      albertel 2403: 		    }
                   2404: 		} else {
1.87      raeburn  2405: 		    push(@badxlists,$xl.':'.$env{"form.$lc_sec"}.":".$coursecheck);
1.15      albertel 2406: 		}
                   2407: 	    }
                   2408: 	}
1.74      raeburn  2409: 	push(@allxlists,@xlists);
1.15      albertel 2410:     }
                   2411:     
                   2412:     if (@xlists > 0 ) {
                   2413: 	unless ($xliststr eq '') { $xliststr .= ","; }
1.28      albertel 2414: 	$xliststr .= join(",",@xlists);
                   2415: 
1.15      albertel 2416: 	my %cenv = ('internal.crosslistings' => $xliststr);
                   2417: 	my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  2418: 	if ($reply ne 'ok') {
                   2419: 	    $response = 
                   2420:                 &mt('There was a problem processing your requested changes.').' '.
                   2421:                 &mt('The automated enrollment settings for this course have been left unchanged.').
                   2422:                 '<br /><br />';
1.15      albertel 2423: 	} else {
1.74      raeburn  2424: 	    $response = &mt('The courses listed below are now crosslisted with this LON-CAPA course, and students enrolling in these course sections will be automatically added to the class roster for the course, if you have chosen to enable a nightly automated enrollment update.').'<br /><ul>'."\n";
1.87      raeburn  2425:             my @showable;
                   2426:             &reformat_xlists($dom,$crs,$coursecode,\@allxlists,\@showable);
                   2427:             foreach my $item (@showable) {
1.74      raeburn  2428: 		my ($xlist,$lc_sec) = split(/:/,$item);
                   2429: 		$response .= '<li>'.&mt('[_1] - ID: [_2]',$xlist,$lc_sec).'</li>'.
                   2430:                               "\n";
1.15      albertel 2431: 	    }
1.74      raeburn  2432: 	    $response .= '</ul><br /><br />'."\n";
1.15      albertel 2433: 	}
                   2434:     } else {
1.74      raeburn  2435: 	if ($xliststr =~ /:/) {
                   2436: 	    my @oldxlists = split(/,/,$xliststr);
                   2437: 	    $response .= &mt('Although no new crosslistings were added, the courses listed below continue to be crosslisted with your LON-CAPA course.').
                   2438:                          '<br /><ul>'."\n";
1.87      raeburn  2439:             my @showable;
                   2440:             &reformat_xlists($dom,$crs,$coursecode,\@oldxlists,\@showable);
                   2441:             foreach my $item (@showable) {
1.88      raeburn  2442: 		my ($xlist,$lc_sec) = split(/:/,$item);
1.74      raeburn  2443: 		$response .= '<li>'.&mt('[_1] - ID: [_2]',$xlist,$lc_sec).'</li>'.
                   2444:                              "\n";
1.15      albertel 2445: 	    }
1.74      raeburn  2446: 	    $response .= '</ul><br /><br />'."\n";
1.15      albertel 2447: 	}
                   2448:     }
                   2449:     if (@badxlists > 0) {
1.74      raeburn  2450: 	$response .= &mt("The courses listed below could not be included in the crosslistings for this LON-CAPA course, because they are not valid courses according to your institution's official schedule of classes and sections.").
                   2451:                      '<br /><ul>'."\n";
1.87      raeburn  2452:         my @showable;
                   2453:         &reformat_xlists($dom,$crs,$coursecode,\@badxlists,\@showable);
                   2454:         foreach my $item (@showable) {
1.74      raeburn  2455: 	    my ($xlist,$lc_sec,$prob) = split(/:/,$item);
                   2456: 	    $response .= '<li>'.
                   2457:                          &mt('[_1] - ID: [_2] - Error: [_3]',
                   2458:                              $xlist,$lc_sec,$prob).
                   2459:                          '</li>'."\n";
1.15      albertel 2460: 	}
1.74      raeburn  2461: 	$response .= '</ul><br /><br />'."\n";
1.15      albertel 2462:     }
                   2463:     if (@badowner > 0) {
1.74      raeburn  2464: 	$response .= &mt("The courses listed below could not be included in the crosslistings for this LON-CAPA course, because the owner of this course - [_1] - does not have rights to view enrollment in those classes, as determined by your instititution's policies on access to official classlists.",$owner).
                   2465:                      '<br /><ul>'."\n";
1.87      raeburn  2466:         my @showable;
                   2467:         &reformat_xlists($dom,$crs,$coursecode,\@badowner,\@showable);
                   2468:         foreach my $item (@showable) {
1.74      raeburn  2469: 	    my ($xlist,$lc_sec) = split(/:/,$item);
                   2470: 	    $response .= '<li>'.&mt('[_1] - ID: [_2]',$xlist,$lc_sec).'</li>'.
                   2471:                          "\n";
1.15      albertel 2472: 	}
1.74      raeburn  2473: 	$response .= '</ul><br /><br />'."\n";
1.15      albertel 2474:     }
1.42      raeburn  2475:     if (@reserved > 0) {
1.74      raeburn  2476:         $response .= &mt('The courses listed below could not be included in the crosslistings for this LON-CAPA course, because the section ID associated with the crosslisted course is a reserved word.').' '.
                   2477:                      &mt('Please [_1]go back[_2]</a> and change the section ID for each of these courses.',
                   2478:                          '<a href="javascript:history(-1)">','>/a>').
                   2479:                      '<br /><ul>'."\n";  
1.87      raeburn  2480:         my @showable;
                   2481:         &reformat_xlists($dom,$crs,$coursecode,\@reserved,\@showable);
                   2482:         foreach my $item (@showable) {
1.74      raeburn  2483:             my ($xlist,$lc_sec) = split(/:/,$item);
                   2484:             $response .= '<li>'.&mt('[_1] - ID: [_2]',$xlist,$lc_sec).'</li>'.
                   2485:                          "\n";
1.42      raeburn  2486:         }
1.74      raeburn  2487:         $response .= '</ul><br /><br />'."\n";
1.42      raeburn  2488:     }
                   2489: 
                   2490:     if (@matchgroup > 0) {
1.74      raeburn  2491:         $response .= &mt('The courses listed below could not be included in the crosslistings for this LON-CAPA course, because the section ID associated with the crosslisted course is the name of a group in this course.').' '.
                   2492:                      &mt('Please [_1]go back[_2] and change the section ID for each of these courses.','<a href="javascript:history(-1)">','</a>').
                   2493:                      '<br /><ul>'."\n";
1.87      raeburn  2494:         my @showable;
                   2495:         &reformat_xlists($dom,$crs,$coursecode,\@matchgroup,\@showable);
                   2496:         foreach my $item (@showable) {
1.74      raeburn  2497:             my ($xlist,$lc_sec) = split(/:/,$item);
                   2498:             $response .= '<li>'.&mt('[_1] - ID: [_2]',$xlist,$lc_sec).'</li>'.
                   2499:                          "\n";
1.42      raeburn  2500:         }
1.74      raeburn  2501:         $response .= '</ul><br /><br />'."\n";
1.42      raeburn  2502:     }
1.15      albertel 2503:     if (@allxlists > 0) {
                   2504: 	$warning = &warning_message($dom,$crs,$action);
1.74      raeburn  2505:         unless ($warning eq '') {
                   2506: 	    $response .= '<br /><span class="LC_warning"><b>'.
                   2507:                          &mt('Warning.').'</b> '.
                   2508:                          &mt('Although you have selected crosslisted courses to contribute enrollment to this course, additional action is required.').
                   2509:                          '</span><br />'.$warning;
1.15      albertel 2510: 	}
                   2511:     }
                   2512:     &print_reply($r,$response,$$tasktitleref{$action});
                   2513:     return;
1.1       raeburn  2514: }
                   2515: 
1.87      raeburn  2516: sub reformat_xlists {
                   2517:     my ($dom,$crs,$coursecode,$xlistsref,$showxlistsref) = @_;
                   2518:     return unless ((ref($xlistsref) eq 'ARRAY') && (ref($showxlistsref) eq 'ARRAY'));
                   2519:     my $crskey = $crs.':'.$coursecode;
                   2520:     my (@xlcodes,@lcsecs,@extras);
                   2521:     foreach my $xl (@{$xlistsref}) {
                   2522:         my ($instcodesec,$lc_sec,$extra) = split(/:/,$xl);
                   2523:         push(@xlcodes,$instcodesec);
                   2524:         push(@lcsecs,$lc_sec);
                   2525:         push(@extras,$extra);
                   2526:     }
                   2527:     my %reformatted =
                   2528:         &Apache::lonnet::auto_instsec_reformat($dom,'declutter',
                   2529:                                                {$crskey => \@xlcodes});
                   2530:     if (ref($reformatted{$crskey}) eq 'ARRAY') {
                   2531:         @xlcodes = @{$reformatted{$crskey}};
                   2532:         for (my $i=0; $i<@xlcodes; $i++) {
                   2533:             my $value = $xlcodes[$i].':'.$lcsecs[$i];
                   2534:             if ($extras[$i] ne '') {
                   2535:                 $value .= ':'.$extras[$i];
                   2536:             }
                   2537:             push(@{$showxlistsref},$value);
                   2538:         }
                   2539:     }
                   2540:     return;
                   2541: }
                   2542: 
1.74      raeburn  2543: sub print_sections_menu {
1.15      albertel 2544:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  2545:     my %settings = 
                   2546:         &Apache::lonnet::get('environment',
                   2547:                              ['internal.sectionnums','internal.coursecode',
                   2548:                               'internal.courseowner','internal.co-owners'],
                   2549:                              $dom,$crs);
                   2550:     my (@currsections,@sections,@badowner,@badsections,$secstr,$response,
                   2551:         $warning,$warn_prefix); 
1.15      albertel 2552:     my $seccount = 0;
                   2553:     my $removecount = 0;
                   2554:     my $addcount = 0;
                   2555:     my $coursecode = $settings{'internal.coursecode'};
                   2556:     my $owner = $settings{'internal.courseowner'};
1.68      raeburn  2557:     my $coowners = $settings{'internal.co-owners'};
1.28      albertel 2558:     if ($settings{'internal.sectionnums'} ne '') {
                   2559: 	@currsections = split(/,/,$settings{'internal.sectionnums'});
1.15      albertel 2560:     }
1.23      albertel 2561:     if ( exists($env{'form.secshow'}) ) {
                   2562: 	for (my $i=0; $i<$env{'form.secshow'}; $i++) {
1.42      raeburn  2563: 	    my $lc_sec = "loncapasec_".$i;
1.15      albertel 2564: 	    my $secnum = "secnum_".$i;
                   2565: 	    my $sec = "sec_".$i;
1.23      albertel 2566: 	    if ( exists( $env{"form.$sec"} ) ) {
1.15      albertel 2567: 		my $secentry;
1.23      albertel 2568: 		if ( exists( $env{"form.$secnum"} ) ) { 
                   2569: 		    $secentry = $env{"form.$secnum"}.':';
1.15      albertel 2570: 		}
1.42      raeburn  2571: 		if ( exists( $env{"form.$lc_sec"} ) ) {
                   2572: 		    $secentry .= $env{"form.$lc_sec"};
1.15      albertel 2573: 		}
1.74      raeburn  2574: 		if ( grep/\Q$env{"form.$secnum"}:\E/,@currsections) {
                   2575: 		    push(@sections,$secentry);
1.15      albertel 2576: 		    $seccount ++;
                   2577: 		} else {
1.89      raeburn  2578:                     my $newsec;
                   2579:                     my $crskey = $crs.':'.$coursecode;
                   2580:                     my %formattedsec = &Apache::lonnet::auto_instsec_reformat($dom,'clutter',
                   2581:                                                                   {$crskey => [$env{"form.$secnum"}]});
                   2582:                     if (ref($formattedsec{$crskey}) eq 'ARRAY') {
                   2583:                         $newsec = $coursecode.$formattedsec{$crskey}->[0];
                   2584:                     } else {
                   2585:                         $newsec = $coursecode.$env{"form.$secnum"};
                   2586:                     }
1.15      albertel 2587: 		    my $coursecheck = &Apache::lonnet::auto_validate_courseID($crs,$dom,$newsec);
                   2588: 		    if ($coursecheck eq 'ok') {
1.68      raeburn  2589: 			my $addcheck = &Apache::lonnet::auto_new_course($crs,$dom,$newsec,$owner,$coowners);
1.15      albertel 2590: 			if ($addcheck eq 'ok') {
1.74      raeburn  2591: 			    push(@sections,$env{"form.$secnum"}.":".$env{"form.$lc_sec"});
1.15      albertel 2592: 			    $seccount ++;
                   2593: 			    $addcount ++;
                   2594: 			} else {
1.74      raeburn  2595: 			    push(@badowner,$env{"form.$secnum"}.":".$env{"form.$lc_sec"});
1.15      albertel 2596: 			}
                   2597: 		    } else {
1.74      raeburn  2598: 			push(@badsections,$env{"form.$secnum"}.":".$env{"form.$lc_sec"}.":".$coursecheck);
1.15      albertel 2599: 		    }
                   2600: 		}
                   2601: 	    }
                   2602: 	}
                   2603: 	if (@currsections > 0) {
                   2604: 	    for (my $i=0; $i<@currsections; $i++) {
1.74      raeburn  2605: 		if ($currsections[$i] =~ /^(\w+:)/) {
1.15      albertel 2606: 		    my $oldsec  = $1;
                   2607: 		    unless (grep/^$oldsec/,@sections) {
                   2608: 			$removecount ++;
                   2609: 		    }
                   2610: 		}
                   2611: 	    }
                   2612: 	}
                   2613:     } elsif (@currsections > 0) {
                   2614: 	for (my $i=0; $i<@currsections; $i++) {
                   2615: 	    my $sec = "sec_".$i;
1.42      raeburn  2616: 	    my $lc_sec = "lcsec_".$i;
1.23      albertel 2617: 	    if ( exists($env{"form.$sec"}) ) {
1.15      albertel 2618: 		my $secentry = '';
1.74      raeburn  2619: 		if ($currsections[$i] =~ /^(\w+:)/) {
1.15      albertel 2620: 		    $secentry = $1;
                   2621: 		}
1.42      raeburn  2622: 		if ( exists($env{"form.$lc_sec"}) ) {
                   2623: 		    $secentry .= $env{"form.$lc_sec"};
1.15      albertel 2624: 		}
1.74      raeburn  2625: 		push(@sections,$secentry);
1.15      albertel 2626: 		$seccount ++;
                   2627: 	    } else {
                   2628: 		$removecount ++;
                   2629: 	    }
                   2630: 	}
                   2631:     }
                   2632:     
1.74      raeburn  2633:     $secstr = join(',',@sections);
1.28      albertel 2634: 
1.15      albertel 2635:     my %cenv = ('internal.sectionnums' => $secstr);
                   2636:     my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  2637:     if ($reply ne 'ok') {
                   2638: 	$response = &mt('There was a problem processing your requested changes.').' '.
                   2639:                      &mt('The automated enrollment settings for this course have been left unchanged.').'<br />';
1.15      albertel 2640:     } else {
1.74      raeburn  2641: 	if ($removecount) {
                   2642: 	    $response = &mt('A total of [quant,_1,section] have been removed from the list of sections which contribute to enrollment in LON-CAPA course: [_2].',$removecount,"$realm ($coursecode)").
                   2643:                         '<br /><br />';
                   2644: 	}
                   2645: 	if ($addcount) {
                   2646: 	    $response .= &mt('A total of [quant,_1,section] have been added to the list of sections which contribute to enrollment in LON-CAPA course: [_2].',
                   2647:                              $addcount,"$realm ($coursecode)").
                   2648:                              '<br /><br />';
                   2649: 	}
                   2650: 	if ($seccount) { 
                   2651: 	    $response .= &mt('Students enrolling in the [quant,_1,section] listed below will be automatically added to the class roster for the course, if you have chosen to enable a nightly automated enrollment update.',$seccount).
                   2652:                          '<br /><ul>'."\n";
                   2653: 	    foreach my $section (@sections) {
                   2654: 		my ($sec,$lc_sec) = split(/:/,$section);
                   2655: 		$response .= '<li>'.&mt('[_1] - ID: [_2]',$sec,$lc_sec).'</li>'
                   2656: .
                   2657:                               "\n";
1.15      albertel 2658: 	    }
1.74      raeburn  2659: 	    $response .= '</ul><br />'."\n";
1.15      albertel 2660: 	}
                   2661:     }
                   2662:     if (@badsections > 0) {
1.74      raeburn  2663: 	$response .= &mt("The sections listed below could not be included in the sections for this LON-CAPA course, because they are not valid section numbers according to your institution's official schedule of classes and sections.").
                   2664:                      '<br /><ul>'."\n";
                   2665: 	foreach my $section (@badsections) {
                   2666: 	    my ($secnum,$lc_sec,$prob) = split(/:/,$section);
                   2667: 	    $response .= '<li>'.&mt('[_1] - ID: [_2] - Error: [_3]',
                   2668:                                     $secnum,$lc_sec,$prob).'</li>'."\n";
1.15      albertel 2669: 	}
1.74      raeburn  2670: 	$response .= "</ul><br /><br />\n";
1.15      albertel 2671:     }
                   2672:     
                   2673:     if (@badowner > 0) {
1.74      raeburn  2674: 	$response .= &mt("The sections listed below could not be included in the sections for this LON-CAPA course, because the owner of this course - [_1] - does not have rights to view enrollment in those classes as determined by your instititution's policies on access to official classlists.",$owner).
                   2675:                      '<br /><ul>'."\n";
                   2676: 	foreach my $section (@badowner) {
                   2677: 	    my ($secnum,$lc_sec) = split(/:/,$section);
                   2678: 	    $response .= '<li>'.&mt('[_1] - ID: [_2]',$secnum,$lc_sec).'</li>'.
                   2679:                          "\n";
1.15      albertel 2680: 	}
1.74      raeburn  2681: 	$response .= '</ul><br /><br />'."\n";
1.15      albertel 2682:     }
                   2683:     
                   2684:     if ($seccount > 0) {
                   2685: 	$warning = &warning_message($dom,$crs,$action);
1.74      raeburn  2686:         unless ($warning eq '') { 
                   2687: 	    $response .= '<br /><span class="LC_warning">'.
                   2688:                          '<b>'.&mt('Warning.').'</b> '.
                   2689:                          &mt('Although you have selected sections to contribute enrollment to this course, additional action is required.').
                   2690:                          '</span><br />'.$warning;
1.15      albertel 2691: 	}
                   2692:     }
1.23      albertel 2693:     if ( exists($env{'form.numsec'}) ) {
                   2694: 	my $numsec = $env{'form.numsec'};
1.15      albertel 2695: 	if ($numsec > 0) {
1.74      raeburn  2696: 	    $response .= 
                   2697:                 &mt('You indicated that you wish to incorporate student enrollment in your LON-CAPA course from an additional [quant,_1,section].',$numsec).' '.
1.79      raeburn  2698:                &mt('For each new section enter the institutional section code (e.g., 004), and the LON-CAPA section ID you wish to assign to students who will be enrolled in your LON-CAPA class as a result of their registration in this particular section.').' '.
1.74      raeburn  2699:                &mt('The LON-CAPA section ID can be left blank, if you do not wish to designate a section ID for this course section.').' '.
                   2700:                &mt("The institutional section code should only contain letters and/or numbers, and must be consistent with the scheme adopted by your Domain Coordinator to map course section numbers to your institution's student information system.").'
                   2701:                <br /><br />
                   2702:            <form name="enter" method="post" action="">
1.1       raeburn  2703:            <table border="0" cellpadding="2" cellspacing="2" width="100%">
                   2704:              <tr>
1.74      raeburn  2705:               <td>'.
                   2706:             &Apache::loncommon::start_data_table().
                   2707:             &Apache::loncommon::start_data_table_row().'
                   2708:                  <th>'.&mt('Section number').'</th>
                   2709:                  <th>'.&mt('LON-CAPA section ID').'</th>'.
                   2710:             &Apache::loncommon::end_data_table_row();
1.15      albertel 2711: 	    for (my $i=0; $i<$numsec; $i++) {
1.74      raeburn  2712:                 $response .= &Apache::loncommon::start_data_table_row().'
                   2713:                  <td><input type="text" size="10" name="newsec_'.$i.'" /></td>
1.42      raeburn  2714:                  <td align="right">
1.74      raeburn  2715:                    <input type="text" size="10" name="newlcsec_'.$i.'" />
1.42      raeburn  2716:                  </td>
1.74      raeburn  2717:                 '.&Apache::loncommon::end_data_table_row();
1.15      albertel 2718: 	    }
1.74      raeburn  2719:             $response .= &Apache::loncommon::end_data_table().'
1.1       raeburn  2720:               </td>
                   2721:              </tr>
                   2722:              <tr>
                   2723:               <td align="right">
1.74      raeburn  2724:                <input type="button" name="newsections" value="'.&mt('Go').'" onclick="'."process('newsections')".'" />
1.1       raeburn  2725:               </td>
                   2726:              </tr>
                   2727:             </table>
1.74      raeburn  2728:             <input type="hidden" name="numsec" value="'.$numsec.'" />
                   2729:             <input type="hidden" name="action" value="newsections" />
                   2730:             <input type="hidden" name="state" value="process" />
1.1       raeburn  2731:             </form>
1.74      raeburn  2732: 	    ';
1.15      albertel 2733: 	}
                   2734:     }
                   2735:     &print_reply($r,$response,$$tasktitleref{$action});
                   2736:     return;
1.1       raeburn  2737: }
                   2738: 
1.74      raeburn  2739: sub print_sections_response {
1.15      albertel 2740:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  2741:     my %settings = &Apache::lonnet::get('environment',
                   2742:                        ['internal.sectionnums','internal.coursecode',
                   2743:                         'internal.courseowner','internal.co-owners'],
                   2744:                        $dom,$crs);
                   2745:     my (@currsections,@sections,@allsections,@badowner,@badsections,
                   2746:         @reserved,@matchgroup,$response,$putreply,$warning,$warn_prefix); 
1.15      albertel 2747:     my $numsec = 0;
                   2748:     my $secstr =  $settings{'internal.sectionnums'};
                   2749:     my $coursecode = $settings{'internal.coursecode'};
                   2750:     my $owner = $settings{'internal.courseowner'};
1.68      raeburn  2751:     my $coowners = $settings{'internal.co-owners'};
1.28      albertel 2752:     if ($secstr ne '') {
                   2753: 	@allsections = split(/,/,$secstr);
1.15      albertel 2754:     }
1.23      albertel 2755:     if ( exists($env{'form.numsec'}) ) {
                   2756: 	$numsec = $env{'form.numsec'};
1.15      albertel 2757:     }
                   2758:     if ($numsec > 0) {
1.43      raeburn  2759:         my %curr_groups = &Apache::longroup::coursegroups();
1.15      albertel 2760: 	for (my $i=0; $i<$numsec; $i++) {
                   2761: 	    my $sec = "newsec_".$i;
1.42      raeburn  2762: 	    my $lc_sec = "newlcsec_".$i;
1.23      albertel 2763: 	    if ( exists($env{"form.$sec"}) ) {
1.74      raeburn  2764: 		unless ( (grep/^\Q$env{"form.$sec"}:\E/,@allsections) || 
                   2765:                          (grep/^\Q$env{"form.$sec"}:\E/,@sections) ) {
1.42      raeburn  2766:                     my $lc_sec_check = &validate_lcsec(\%curr_groups,                                                     $env{"form.$lc_sec"});
                   2767:                     if ($lc_sec_check eq 'reserved') {
                   2768:                         push(@reserved,$env{"form.$sec"}.":".$env{"form.$lc_sec"});
                   2769:                         next;
                   2770:                     } elsif ($lc_sec_check eq 'group') {
1.74      raeburn  2771:                         push(@matchgroup,$env{"form.$sec"}.":".$env{"form.$lc_sec"});
1.42      raeburn  2772:                         next;
                   2773:                     }
1.89      raeburn  2774:                     my $newsec;
                   2775:                     my $crskey = $crs.':'.$coursecode;
                   2776:                     my %formattedsec = &Apache::lonnet::auto_instsec_reformat($dom,'clutter',
                   2777:                                                                   {$crskey => [$env{"form.$sec"}]});
                   2778:                     if (ref($formattedsec{$crskey}) eq 'ARRAY') {
                   2779:                         $newsec = $coursecode.$formattedsec{$crskey}->[0];
                   2780:                     } else {
                   2781:                         $newsec = $coursecode.$env{"form.$sec"};
                   2782:                     }
1.15      albertel 2783: 		    my $coursecheck = &Apache::lonnet::auto_validate_courseID($crs,$dom,$newsec);
                   2784: 		    if ($coursecheck eq 'ok') {
1.68      raeburn  2785: 			my $addcheck = &Apache::lonnet::auto_new_course($crs,$dom,$newsec,$owner,$coowners);
1.15      albertel 2786: 			if ($addcheck eq 'ok') {
1.74      raeburn  2787: 			    push(@sections,$env{"form.$sec"}.":".$env{"form.$lc_sec"});
1.15      albertel 2788: 			} else {
1.74      raeburn  2789: 			    push(@badowner,$env{"form.$sec"}.":".$env{"form.$lc_sec"});
1.15      albertel 2790: 			}
                   2791: 		    } else {
1.74      raeburn  2792: 			push(@badsections,$env{"form.$sec"}.":".$env{"form.$lc_sec"}.":".$coursecheck);
1.15      albertel 2793: 		    }
                   2794: 		}
                   2795: 	    }
                   2796: 	}
1.74      raeburn  2797: 	push(@allsections,@sections);
1.15      albertel 2798:     }
                   2799:     
1.74      raeburn  2800:     if (@sections > 0) {
1.15      albertel 2801: 	unless ($secstr eq '') { $secstr .= ","; } 
1.74      raeburn  2802: 	$secstr .= join(',',@sections);
1.15      albertel 2803: 	my %cenv = ('internal.sectionnums' => $secstr);
                   2804: 	$putreply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  2805: 	if ($putreply ne 'ok') {
                   2806: 	    $response = &mt('There was a problem processing your requested changes.').' '.
                   2807:                         &mt('The automated enrollment settings for this course have been left unchanged.').
                   2808:                         '<br /><br />';
1.15      albertel 2809: 	}
                   2810:     }
                   2811: 
1.78      raeburn  2812:     if ($putreply eq 'ok') {
1.74      raeburn  2813: 	$response = &mt('Students enrolling in the sections listed below will be automatically added to the class roster for LON-CAPA course [_1], if you have chosen to enable a nightly automated enrollment update.',
                   2814:                         "$realm ($coursecode)").'<br /><ul>'."\n";
                   2815: 	foreach my $section (@allsections) {
                   2816: 	    my ($sec,$lc_sec) = split(/:/,$section);
                   2817: 	    $response .= '<li>'.&mt('[_1] - ID: [_2]',$sec,$lc_sec).'</li>'.
                   2818:                          "\n";
1.15      albertel 2819: 	}
1.74      raeburn  2820: 	$response .= '</ul><br /><br />'."\n";
1.15      albertel 2821:     }
                   2822: 
                   2823:     if (@badsections > 0) {
1.74      raeburn  2824: 	$response .= &mt("The sections listed below could not be included in the sections for this LON-CAPA course, because they are not valid section numbers according to your institution's official schedule of classes and sections.").
                   2825:                      '<br /><ul>'."\n";
                   2826: 	foreach my $item (@badsections) {
                   2827: 	    my ($secnum,$lc_sec,$prob) = split(/:/,$item);
                   2828: 	    $response .= '<li>'.
                   2829:                          &mt('[_1] - ID: [_2] - Error: [_3]',
                   2830:                              $secnum,$lc_sec,$prob).
                   2831:                          '</li>'."\n";
1.15      albertel 2832: 	}
1.74      raeburn  2833: 	$response .= '</ul><br /><br />'."\n";
1.15      albertel 2834:     }
                   2835: 
                   2836:     if (@badowner > 0) {
1.74      raeburn  2837: 	$response .= &mt("The sections listed below could not be included in the sections for this LON-CAPA course, because the owner of this course - [_1] - does not have rights to view enrollment in those classes as determined by your instititution's policies on access to official classlists.",$owner).
                   2838:                      '<br /><ul>'."\n";
                   2839: 	foreach my $item (@badowner) {
                   2840: 	    my ($secnum,$lc_sec) = split(/:/,$item);
                   2841: 	    $response .= '<li>'.&mt('[_1] - ID: [_2]',$secnum,$lc_sec).'</li>'.
                   2842:                          "\n";
1.15      albertel 2843: 	}
1.74      raeburn  2844: 	$response .= '</ul><br /><br />'."\n";
1.15      albertel 2845:     }
                   2846: 
1.42      raeburn  2847:     if (@reserved > 0) {
1.74      raeburn  2848:         $response .= &mt('The sections listed below could not be included in the sections for this LON-CAPA course, because the section ID associated with the institutional section is a reserved word.').' '.
                   2849:                      &mt('Please [_1]go back[_2] and change the section ID for each of these sections.',
                   2850:                         '<a href="javascript:history.go(-1)">','</a>').
                   2851:                      '<br /><ul>'."\n";
                   2852:         foreach my $xl (@reserved) {
                   2853:             my ($xlist,$lc_sec) = split(/:/,$xl);
                   2854:             $response .= '<li>'.
                   2855:                          &mt('[_1] - ID: [_2]',$xlist,$lc_sec).
                   2856:                          '</li>'."\n";
1.42      raeburn  2857:         }
1.74      raeburn  2858:         $response .= "</ul><br /><br />\n";
1.42      raeburn  2859:     }
                   2860:                                                                                  
                   2861:     if (@matchgroup > 0) {
1.74      raeburn  2862:         $response .= &mt('The sections listed below could not be included in the sections for this LON-CAPA course, because the section ID associated with the institutional section is the name of a group in this course.').' '.
                   2863:                      &mt('Please [_1]go back[_2] and change the section ID for each of these sections.','<a href="javascript:history.go(-1)">','</a>').
                   2864:                      '<br /><ul>'."\n";
                   2865:         foreach my $section (@matchgroup) {
                   2866:             my ($xlist,$lc_sec) = split(/:/,$section);
                   2867:             $response .= '<li>'.&mt('[_1] - ID: [_2]',$xlist,$lc_sec).
                   2868:                          '</li>'."\n";
1.42      raeburn  2869:         }
1.74      raeburn  2870:         $response .= '</ul><br /><br />'."\n";
1.42      raeburn  2871:     }
1.15      albertel 2872:     if (@allsections > 0) {
                   2873: 	$warning = &warning_message($dom,$crs,$action);
1.74      raeburn  2874:         unless ($warning eq '') {
                   2875: 	    '<br />'.
                   2876:             '<span class="LC_warning"><b>'.&mt('Warning.').'</b> '."\n".
                   2877:             &mt('Although you have selected sections to contribute enrollment to this course, additional action is required.').'<span><br />'.$warning;
1.15      albertel 2878: 	}
                   2879:     }
                   2880:     &print_reply($r,$response,$$tasktitleref{$action});
                   2881:     return;
1.1       raeburn  2882: }
                   2883: 
1.34      raeburn  2884: sub photo_permission {
1.15      albertel 2885:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.35      albertel 2886:     my %settings = &Apache::lonnet::get('environment',
                   2887: 					['internal.courseowner',
                   2888: 					 'internal.photopermission',
1.37      raeburn  2889: 					 'internal.showphoto'],
1.35      albertel 2890: 					$dom,$crs);
1.34      raeburn  2891:     my ($showphotos,$response);
                   2892:     if (exists($env{'form.cancel_agreement'})) {
1.48      albertel 2893:         if (&user_is_courseowner($settings{'internal.courseowner'})) {
1.34      raeburn  2894:             my %cenv = (
                   2895:                 'internal.photopermission' => 'no',
                   2896:             );
                   2897:             my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  2898:             if ($reply ne 'ok') {
                   2899:                 $response = 
                   2900:                     &mt('There was a problem processing the record of your agreement to the conditions of use.').' '.
                   2901:                     &mt('Settings for this course have been left unchanged.').'<br />'."\n";
1.34      raeburn  2902:                 &print_reply($r,$response,$$tasktitleref{$action});
                   2903:             } else {
                   2904:                 &print_photos_response($r,$realm,$dom,$crs,$action,
                   2905:                        $tasktitleref,$showphotos,'no',\%cenv);
                   2906:             }
                   2907:             return;            
                   2908:         }
                   2909:     } 
                   2910:     if (exists($env{'form.showphotos'})) {
                   2911:         $showphotos=$env{'form.showphotos'};
                   2912:     }
                   2913:     if ($showphotos) {
                   2914:         if ($env{'form.photopermission'}) {
                   2915:             my %cenv = (
                   2916:                 'internal.photopermission' => $env{'form.photopermission'},
                   2917:             );
                   2918:             my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  2919:             if ($reply ne 'ok') {
                   2920:                 $response = 
                   2921:                     &mt('There was a problem processing the record of your agreement to the conditions of use.').' '.
                   2922:                     &mt('Settings for this course have been left unchanged.').'<br />'."\n";
1.34      raeburn  2923:             } else {
                   2924:                 &print_photos_response($r,$realm,$dom,$crs,$action,
1.35      albertel 2925: 				       $tasktitleref,$showphotos,
                   2926: 				       $env{'form.photopermission'},\%cenv);
1.34      raeburn  2927:             }
                   2928:         } else {
                   2929:             my ($result,$perm_reqd,$conditions) = 
1.35      albertel 2930: 		&Apache::lonnet::auto_photo_permission($crs,$dom);
1.34      raeburn  2931:             my $permcheck;
                   2932:             if ($result eq 'ok') { 
                   2933:                 if ($perm_reqd eq 'yes') {
                   2934:                     if ($settings{'internal.photopermission'} eq 'yes') {
                   2935:                         &print_photos_response($r,$realm,$dom,$crs,$action,
1.35      albertel 2936: 					       $tasktitleref,$showphotos);
1.34      raeburn  2937:                     } else {
                   2938:                         return(&print_photo_agreement($r,$realm,$dom,$crs,
1.35      albertel 2939: 						      $action,$tasktitleref,
                   2940: 						      $conditions,
                   2941: 						      $settings{'internal.courseowner'}));
1.34      raeburn  2942:                     }
                   2943:                 } elsif ($perm_reqd eq 'no') {
                   2944:                     &print_photos_response($r,$realm,$dom,$crs,$action,
1.35      albertel 2945: 					   $tasktitleref,$showphotos);
1.34      raeburn  2946:                 } else {
                   2947:                     $permcheck = 'fail';
                   2948:                 }
                   2949:             } else {
                   2950:                 $permcheck = 'fail';
                   2951:             }
                   2952:             if ($permcheck eq 'fail') {
1.74      raeburn  2953:                 my $response = 
                   2954:                     &mt('There was a problem processing your requested change, because it could not be determined whether course owner permission is required in order for a course coordinator to have access to student photos in this domain.').' '.
                   2955:                     &mt('The student photo import setting for this course has been left unchanged.').'<br />';
1.34      raeburn  2956:                 &print_reply($r,$response,$$tasktitleref{$action});
                   2957:             }
                   2958:         }
                   2959:     } else {
                   2960:         &print_photos_response($r,$realm,$dom,$crs,$action,$tasktitleref);
                   2961:     }
                   2962:     return;
                   2963: }
                   2964: 
                   2965: sub print_photo_agreement {
                   2966:     my ($r,$realm,$dom,$crs,$action,$tasktitleref,$conditions,$courseowner)=@_;
                   2967:     my $response;
1.49      albertel 2968:     my $institution = &Apache::lonnet::domain($dom,'description');
1.48      albertel 2969:     if (&user_is_courseowner($courseowner)) {
1.34      raeburn  2970:         $response = '
1.58      bisitz   2971: <script type="text/javascript" language="JavaScript">
1.34      raeburn  2972: function agreement_result(caller) {
                   2973:     document.permission.photopermission.value = caller;
                   2974:     if (caller == 0) {
                   2975:         document.location.href="/adm/populate";
                   2976:     } else {
                   2977:         document.permission.submit();
                   2978:     }
                   2979:     return;
                   2980: }
                   2981: </script>
1.74      raeburn  2982:   <form name="permission" method="post" action="">
1.34      raeburn  2983:    <table width="100%" border="0" cellpadding="2" cellspacing="2">
                   2984:     <tr>
1.74      raeburn  2985:      <td align="left"><b>'.&mt('Use of student photos').'</b><br />'."\n".
                   2986:       &mt('Acceptance by the course owner of the conditions of use of photos is currently [_1]not[_2] set.','<b>','</b>').'<br />'.
                   2987:       &mt('Please indicate your acceptance of the conditions of use of digital photos of registered students in courses at [_1].',$institution).'
1.34      raeburn  2988:      </td>
                   2989:     </tr>
                   2990:    </table>
                   2991:    <table border="0" cellpadding="3" cellspacing="3">
                   2992:     <tr>
                   2993:      <td colspan="2">
                   2994:       <textarea rows="20" cols="80">'.$conditions.'</textarea>
                   2995:      </td>
                   2996:      <tr>
                   2997:       <td align="left">  
1.74      raeburn  2998:        <input type="button" name="disagree" value="'.&mt('I do not agree').'" onclick="javascript:agreement_result('."'no'".');" />
1.34      raeburn  2999:       </td>
                   3000:       <td align="right">
1.74      raeburn  3001:        <input type="button" name="agree" value="'.&mt('I agree').'" onclick="javscript:agreement_result('."'yes'".');" />
1.34      raeburn  3002:       </td>
                   3003:     </tr>
                   3004:    </table>
1.62      bisitz   3005:    <input type="hidden" name="action" value="'.$action.'" />
                   3006:    <input type="hidden" name="state" value="process" />
                   3007:    <input type="hidden" name="showphotos" value="1" />
                   3008:    <input type="hidden" name="photopermission" value="" />
1.34      raeburn  3009:   </form>
                   3010: ';
                   3011:     } else {
1.44      raeburn  3012:         my ($ownername,$owneremail) = &get_ownerinfo($dom,$courseowner);
                   3013:         my $emailstr;
                   3014:         if ($owneremail) {
1.74      raeburn  3015:             $emailstr = &mt('(e-mail: [_1])',$owneremail);
1.44      raeburn  3016:         }
1.56      bisitz   3017:         $response = &mt('The policies of your institution [_1] require that the course owner [_2] must indicate acceptance of the conditions of use of digital photos of registered students, before they may be made available for use in a course.',$institution,$ownername)
                   3018:                    .'<br /><br />'
                   3019:                    .&mt('Please direct the course owner [_1] to visit the "Student photos" page in the Automated Enrollment Manager to indicate acceptance of these conditions of use.',$emailstr);
1.34      raeburn  3020:     }
                   3021:     &print_reply($r,$response,$$tasktitleref{$action});
                   3022: }
                   3023: 
                   3024: sub print_photos_response {
                   3025:     my ($r,$realm,$dom,$crs,$action,$tasktitleref,$showphotos,$photopermission,
1.35      albertel 3026: 	$permissionenv)=@_;
1.34      raeburn  3027:     my %newenv;
                   3028:     if (defined($permissionenv)) {
                   3029:         foreach my $key (keys(%{$permissionenv})) {
                   3030:             if (exists($env{'request.course.id'})) {
                   3031:                 $newenv{$env{'request.course.id'}.'.'.$key} =
1.35      albertel 3032: 		    $$permissionenv{$key};
1.34      raeburn  3033:             }
                   3034:         }
                   3035:     }
1.37      raeburn  3036:     my %settings = &Apache::lonnet::get('environment',['internal.showphoto'],
1.35      albertel 3037: 					$dom,$crs);
1.37      raeburn  3038:     my $currphotos = $settings{'internal.showphoto'};
1.34      raeburn  3039:     my $response = "";
                   3040:     if (defined($photopermission)) {
                   3041:         if ($photopermission eq 'yes') {
                   3042:             $response = &mt('Acceptance of photo use policy recorded.').'<br />'."\n";
                   3043:         } else {
1.74      raeburn  3044:             $response = &mt('Rejection of photo use policy recorded.').'<br />'."\n";
1.34      raeburn  3045:             $showphotos = 0;
                   3046:         }
1.15      albertel 3047:     }
1.37      raeburn  3048:     my %cenv = ('internal.showphoto' => $showphotos);
1.15      albertel 3049:     my $reply = &Apache::lonnet::put('environment',\%cenv,$dom,$crs);
1.74      raeburn  3050:     if ($reply ne 'ok') {
                   3051: 	$response .= &mt('There was a problem processing your requested change.').' '.
                   3052:                      &mt('The student photo retrieval setting for this course has been left unchanged.').'<br />';
1.15      albertel 3053:     } else {
                   3054: 	if ($showphotos) {
                   3055: 	    if ($currphotos) {
1.74      raeburn  3056: 		$response .= &mt('Retrieval of student photos is still [_1]enabled[_2].','<b>','</b>').'<br />';
1.15      albertel 3057: 	    } else {
1.74      raeburn  3058: 		$response .= &mt('Retrieval of student photos in now [_1]enabled[_2].','<b>','</b>').'<br />';
1.35      albertel 3059:                 my ($update,$commentary) = 
                   3060: 		    &Apache::lonnet::auto_photochoice($crs,$dom);
1.34      raeburn  3061:                 if ($update) {
                   3062:                     $response .= '<br />'.$commentary.'<br /><br />
1.74      raeburn  3063: <form name="photoupdate" method="post" action="">
1.62      bisitz   3064: <input type="button" name="retrieve" value="'.&mt('Update photo repository').'" 
1.34      raeburn  3065: onclick="javascript:document.photoupdate.submit()" /> 
1.62      bisitz   3066: <input type="hidden" name="action" value="'.$action.'" />
                   3067: <input type="hidden" name="state" value="photoupdate" />
1.34      raeburn  3068: </form>';
                   3069:                 }
1.15      albertel 3070: 	    }
                   3071: 	} else {
                   3072: 	    if ($currphotos) {
1.74      raeburn  3073: 		$response .= &mt('Retrieval of student photos is now [_1]disabled[_2].','<b>','</b>').'<br />';
1.15      albertel 3074: 	    } else {
1.74      raeburn  3075: 		$response .= &mt('Retrieval of student photos is still [_1]disabled[_2].','<b>','</b>').'<br />';
1.15      albertel 3076: 	    }
                   3077: 	}
1.34      raeburn  3078:         foreach my $key (keys(%cenv)) {
                   3079:             if (exists($env{'request.course.id'})) {
                   3080:                 $newenv{'course.'.$env{'request.course.id'}.'.'.$key} = 
1.35      albertel 3081: 		    $cenv{$key};
1.34      raeburn  3082:             }
                   3083:         }
                   3084:     }
                   3085:     if (keys(%newenv) > 0) {
1.54      raeburn  3086:         &Apache::lonnet::appenv(\%newenv);
1.34      raeburn  3087:     }
                   3088:     &print_reply($r,$response,$$tasktitleref{$action});
                   3089:     return;
                   3090: }
                   3091: 
                   3092: sub print_photoupdate_response {
                   3093:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  3094:     my ($response,$outcome,%changes,@allcourses,%LC_code,%affiliates);
1.34      raeburn  3095:     my %lt = &LONCAPA::Enrollment::photo_response_types();
1.35      albertel 3096:     my %settings = &Apache::lonnet::get('environment',
                   3097: 					['internal.coursecode',
                   3098: 					 'internal.sectionnums',
                   3099: 					 'internal.crosslistings'],
                   3100: 					$dom,$crs);
1.87      raeburn  3101:     &Apache::loncommon::get_institutional_codes($dom,$crs,\%settings,\@allcourses,\%LC_code);
1.34      raeburn  3102:     if (@allcourses > 0) {
                   3103:         @{$affiliates{$crs}} = @allcourses;
                   3104:         $outcome = &Apache::lonnet::auto_photoupdate(\%affiliates,$dom,$crs,\%changes);
                   3105:         unless ($outcome eq 'ok') {
                   3106:             &Apache::lonnet::logthis("lonpopulate::print_photoupdate_response".
1.35      albertel 3107: 				     "failed to update student photos".
                   3108: 				     " for ".$crs."\@".$dom." by ".
                   3109: 				     $env{'user.name'}." \@ ".$env{'user.domain'}.
                   3110: 				     ": ".$outcome);
1.34      raeburn  3111:         }
                   3112:         if ($outcome eq 'ok') {
                   3113:             if (keys(%changes) > 0) {
1.58      bisitz   3114:                 $response = &mt('Update of photos for registered students resulted in the following ').': <br />'
                   3115:                            .'<script type="text/javascript" language="JavaScript">
1.34      raeburn  3116: function photowindow(photolink) {
                   3117:     var title = "Photo_Viewer";
                   3118:     var options = "scrollbars=1,resizable=1,menubar=0";
                   3119:     options += ",width=240,height=240";
                   3120:     stdeditbrowser = open(photolink,title,options,"1");
                   3121:     stdeditbrowser.focus();
                   3122: }
                   3123: </script>
                   3124: ';
                   3125:                 foreach my $type (sort(keys(%changes))) {
                   3126:                     my @usernames = sort(split(/\&/,$changes{$type})); 
                   3127:                     my $count = @usernames; 
1.74      raeburn  3128:                     $response .= '<b>'.&mt('For [quant,_1,student], photos [_2]',
                   3129: 					   $count,$lt{$type}).'</b><ul>';
1.34      raeburn  3130:                     foreach my $username (@usernames) {
                   3131:                         $response .= '<li>'.$username;
                   3132:                         if (($type eq 'new') || ($type eq 'same') || ($type eq 'update')) {
1.74      raeburn  3133:                             $response .= '&nbsp;<a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($dom,$username,'jpg')."'".')">'.&mt('View').'</a></li>';
1.34      raeburn  3134:                         }
                   3135:                     }
                   3136:                     $response .= '</ul><br />';
                   3137:                 }
                   3138:             } else {
                   3139:                 $response = &mt('No updates of photos of registered students occurred').
                   3140:                          '<br />';
                   3141:             }    
                   3142:         } else {
1.74      raeburn  3143:             $response = &mt('There was a problem updating student photos for registered students in this course.').'<br />';
1.34      raeburn  3144:         }
                   3145:     } else {
1.74      raeburn  3146:         $response = &mt('No institutional course sections are currently associated with this course so there are no registered students for whom photos can be imported/updated.');
1.15      albertel 3147:     }
                   3148:     &print_reply($r,$response,$$tasktitleref{$action});
                   3149:     return;
1.1       raeburn  3150: }
                   3151: 
1.34      raeburn  3152: sub get_ownerinfo {
                   3153:     my ($dom,$owner) = @_; 
1.44      raeburn  3154:     my ($ownername,$owneremail,$own_uname,$own_udom);
1.34      raeburn  3155:     if ($owner) {
1.44      raeburn  3156:         if ($owner =~ /^([^:]+):([^:]+)$/) {
                   3157:             $own_uname = $1;
                   3158:             $own_udom = $2; 
                   3159:         } else {
                   3160:             $own_uname = $owner;
                   3161:             $own_udom = $dom; 
                   3162:         }
                   3163:         $ownername=&Apache::loncommon::plainname($own_uname,$own_udom,
                   3164:                                                  'firstname');
1.36      raeburn  3165:         my %ownerinfo = &Apache::lonnet::get('environment',['permanentemail'],
1.44      raeburn  3166: 					     $own_udom,$own_uname);
1.34      raeburn  3167:         $owneremail = $ownerinfo{'permanentemail'};
                   3168:     }
                   3169:     return ($ownername,$owneremail);
                   3170: }
                   3171: 
1.74      raeburn  3172: sub print_update_result {
1.15      albertel 3173:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  3174:     my ($response,$logmsg,$newusermsg,%affiliates,%reply,@allcourses,
                   3175:         %LC_code,%phototypes);
1.15      albertel 3176:     my $updateadds = 0;
                   3177:     my $updatedrops = 0;
                   3178:     my $changecount = 0;
1.74      raeburn  3179:     my %settings = 
                   3180:         &Apache::lonnet::get('environment',
                   3181:             ['internal.coursecode','internal.sectionnums','internal.crosslistings',
1.80      raeburn  3182:              'internal.authtype','internal.autharg','internal.showphoto','internal.defaultcredits',
1.91    ! raeburn  3183:              'internal.autodropfailsafe','internal.autodropfailsafetype','internal.textbook'],
1.74      raeburn  3184:             $dom,$crs);
1.15      albertel 3185:     my $coursecode = $settings{'internal.coursecode'};
                   3186:     my $authtype = $settings{'internal.authtype'};
                   3187:     my $autharg = $settings{'internal.autharg'};
1.37      raeburn  3188:     my $showphotos = $settings{'internal.showphoto'};
1.80      raeburn  3189:     my $textbook = $settings{'internal.textbook'};
1.76      raeburn  3190:     my ($showcredits,$defaultcredits);
                   3191:     my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
1.80      raeburn  3192:     if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
1.76      raeburn  3193:         $showcredits = 1;
                   3194:         $defaultcredits = $settings{'internal.defaultcredits'};
                   3195:         if ($defaultcredits eq '') {
                   3196:             if ($coursecode ne '') {
                   3197:                 $defaultcredits = $domdefaults{'officialcredits'};   
1.80      raeburn  3198:             } elsif ($textbook ne '') {
                   3199:                 $defaultcredits = $domdefaults{'textbookcredits'};
1.76      raeburn  3200:             } else {
                   3201:                 $defaultcredits = $domdefaults{'unofficialcredits'};
                   3202:             }
                   3203:         }
                   3204:     }
1.91    ! raeburn  3205:     my $failsafetype = $settings{'internal.autodropfailsafetype'};
        !          3206:     if ($failsafetype eq '') {
        !          3207:         $failsafetype = $domdefaults{'failsafe'};
        !          3208:     }
1.84      raeburn  3209:     my $failsafe = $settings{'internal.autodropfailsafe'};
                   3210:     if ($failsafe eq '') {
                   3211:         $failsafe = $domdefaults{'autofailsafe'};
                   3212:     }
1.15      albertel 3213:     my ($startaccess,$endaccess) = &get_dates_from_form();
1.23      albertel 3214:     if ( exists($env{'form.updateadds'}) ) {
                   3215:         $updateadds = $env{'form.updateadds'};
1.15      albertel 3216:     }
1.23      albertel 3217:     if ( exists($env{'form.updatedrops'}) ) {
                   3218:         $updatedrops = $env{'form.updatedrops'};
1.15      albertel 3219:     }
1.19      raeburn  3220:     if (($startaccess eq '') || ($endaccess eq '')) {
1.74      raeburn  3221:         $response = &mt('There was a problem processing your requested roster update because start and and access dates could not be determined.').' '.
                   3222:                     &mt('No changes have been made to the class roster.').
                   3223:                     '<br />'; 
1.19      raeburn  3224:     } elsif ($updateadds && (($endaccess > 0) && ($endaccess <= $startaccess))) {
1.74      raeburn  3225:         $response = &mt('The start access date/time is the same or later than the end access date/time.').' '.
                   3226:                     &mt('As this means that new roles will never be active, your requested roster update has not been carried out, and the roster remains unchanged.').' '.
                   3227:                     &mt('Please [_1]go back[_2] to the previous page to try your changes again.',
                   3228:                         '<a href="javascript:history.go(-1)">','</a>')."\n";
1.19      raeburn  3229:     } elsif (!$updateadds && !$updatedrops) {
1.74      raeburn  3230: 	$response = &mt('An update of the class roster has not been carried out because you indicated that you wanted to neither add new students, nor expire dropped students based on a comparison between the institutional class lists for the course sections and crosslisted courses that contribure enrollment to this LON-CAPA course.');
1.15      albertel 3231:     } elsif ($coursecode eq '') {
1.74      raeburn  3232: 	$response = &mt('There was a problem retrieving the course code for this LON-CAPA course.').' '.
                   3233:                     &mt('An update of the class roster has not been carried out, and enrollment remains unchanged.');
1.15      albertel 3234:     } else {
1.87      raeburn  3235:         &Apache::loncommon::get_institutional_codes($dom,$crs,\%settings,\@allcourses,\%LC_code);
1.15      albertel 3236: 	if (@allcourses > 0) {
                   3237: 	    @{$affiliates{$crs}} = @allcourses;
                   3238: 	    my $outcome = &Apache::lonnet::fetch_enrollment_query('updatenow',\%affiliates,\%reply,$dom,$crs);
1.19      raeburn  3239:             unless ($outcome eq 'ok') {
                   3240:                 &Apache::lonnet::logthis("lonpopulate:update roster".
                   3241:                                          "failed to retrieve classlist".
1.74      raeburn  3242:                                  " data for ".$crs.':'.$dom." by ".
1.23      albertel 3243:                                  $env{'user.name'}." \@ ".$env{'user.domain'}.
1.19      raeburn  3244:                                  ": ".$outcome);
                   3245:             }
1.15      albertel 3246: 	    if ($reply{$crs} > 0) {
1.91    ! raeburn  3247: 		($changecount,$response) = &LONCAPA::Enrollment::update_LC($dom,$crs,$updateadds,$updatedrops,$startaccess,$endaccess,$authtype,$autharg,$showcredits,$defaultcredits,$failsafe,$failsafetype,\@allcourses,\%LC_code,\$logmsg,\$newusermsg,"updatenow",\%phototypes);
1.15      albertel 3248: 	    } else {
1.74      raeburn  3249: 		$response = &mt('There was a problem retrieving institutional class list data for the course sections and crosslisted courses which contribute enrollment to this course.').' '.
                   3250:                             &mt('No updates have been carried out, and the roster remains unchanged.');
1.15      albertel 3251: 	    }  
                   3252: 	} else {
1.74      raeburn  3253: 	    $response = &mt('There are currently no course sections or crosslisted courses designated as contributors to enrollment in this LON-CAPA course.').' '.
                   3254:                         &mt('As a result a student roster update has not been carried out for [_1].',"$realm ($coursecode)");
1.15      albertel 3255: 	}
                   3256:     }
                   3257:     unless ($logmsg eq '') {
                   3258: 	my $loglength = length($logmsg);
                   3259: 	$logmsg = substr($logmsg,0,$loglength-4);
1.74      raeburn  3260: 	$logmsg = '<br /><br />'.&mt('The following messages were generated by the roster update process: [_1]','<br /><ul><li>'.$logmsg.'</ul><br />');
1.15      albertel 3261:     }
                   3262:     unless ($newusermsg eq '') {
                   3263: 	$newusermsg = substr( $newusermsg,0,rindex($newusermsg,'<li>') );
1.74      raeburn  3264: 	$newusermsg = '<br /><br />'.
                   3265:                       &mt('The following new system user(s) who was/were created will be using local or internal authentication with an initial randomly generated password.').' '.
                   3266:                       &mt('A valid e-mail address was not available for this/these user(s) so LON-CAPA account credentials could not be sent via e-mail.').
                   3267:                       '<br /><ul><li>'.$newusermsg.'</ul><br />';
1.15      albertel 3268:     }
                   3269:     $response .= $logmsg.$newusermsg;
                   3270:     &print_reply($r,$response,$$tasktitleref{$action});
                   3271:     return;
1.10      raeburn  3272: }
                   3273: 
1.14      raeburn  3274: sub print_viewclass_response {
                   3275:     my ($r,$realm,$dom,$crs,$action,$tasktitleref) = @_;
1.74      raeburn  3276:     my ($response,%chg,%nochg,%otherdom,%lockchg,%nolockchg);
1.14      raeburn  3277:     my $chgtotal = 0;
                   3278:     my $chgok = 0;
                   3279:     my $chgfail = 0;
                   3280:     my $othdom = 0;
1.16      raeburn  3281:     my $locktotal = 0;
                   3282:     my $lockok = 0;
                   3283:     my $lockfail = 0;
1.74      raeburn  3284:     my $cid = $dom.'_'.$crs;
1.27      albertel 3285:     my $classlist = &Apache::loncoursedata::get_classlist($dom,$crs);
1.14      raeburn  3286:     my $endidx = &Apache::loncoursedata::CL_END;
                   3287:     my $startidx = &Apache::loncoursedata::CL_START;
                   3288:     my $ididx=&Apache::loncoursedata::CL_ID;
                   3289:     my $secidx=&Apache::loncoursedata::CL_SECTION;
                   3290:     my $typeidx=&Apache::loncoursedata::CL_TYPE;
1.16      raeburn  3291:     my $lockedidx=&Apache::loncoursedata::CL_LOCKEDTYPE;
1.76      raeburn  3292:     my $creditsidx=&Apache::loncoursedata::CL_CREDITS;
1.74      raeburn  3293:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   3294:                                ['chgauto','chgmanual','lockchg','unlockchg']);
1.24      albertel 3295:     my @typechglist = (&Apache::loncommon::get_env_multiple('form.chgauto'),
                   3296: 		       &Apache::loncommon::get_env_multiple('form.chgmanual'));
                   3297:     my @lockchglist = (&Apache::loncommon::get_env_multiple('form.lockchg'),
                   3298: 		       &Apache::loncommon::get_env_multiple('form.unlockchg'));
                   3299: 
1.76      raeburn  3300:     foreach my $student (sort(@typechglist)) {
1.51      raeburn  3301:         my ($uname,$udom) = split(/:/,$student);
1.16      raeburn  3302:         my $sdata    = $classlist->{$student};
                   3303:         my $section  = $sdata->[$secidx];
                   3304:         my $uid       = $sdata->[$ididx];
                   3305:         my $start    = $sdata->[$startidx];
                   3306:         my $end      = $sdata->[$endidx];
                   3307:         my $type     = $sdata->[$typeidx];
                   3308:         my $lock   = $sdata->[$lockedidx];
1.76      raeburn  3309:         my $credits = $sdata->[$creditsidx];
1.16      raeburn  3310:         my $newlock = $lock;
                   3311:         $chgtotal ++;
                   3312:         my $newtype = 'auto';
                   3313:         my $change = 'auto';
                   3314:         my $oldtype = 'manual';
                   3315:         if ($type eq 'auto') { 
                   3316:             $oldtype = 'auto';
                   3317:             $newtype = '';
                   3318:             $change = 'manual';
                   3319:         }
                   3320:         if ($udom eq $dom) {
                   3321:             if ($newtype eq 'auto') {
                   3322:                 $newlock = '';
                   3323:             } elsif ($newtype eq '') {
                   3324:                 $newlock = '1';
1.14      raeburn  3325:             }
1.76      raeburn  3326:             my $modreply = 
                   3327:                 &Apache::lonnet::modify_student_enrollment($udom,$uname,$uid,'',
                   3328:                                                            '','','',$section,$end,
                   3329:                                                            $start,$newtype,
                   3330:                                                            $newlock,$cid,'',
                   3331:                                                            'chgtype',$credits);
1.16      raeburn  3332:             if ($modreply eq 'ok') {
                   3333:                 $chgok ++;
1.74      raeburn  3334:                 $chg{$student} = &mt("Changed to $change");
1.16      raeburn  3335:             } else {
                   3336:                 $chgfail ++;
1.74      raeburn  3337:                 $nochg{$student} = &mt("Still set to $oldtype");
1.16      raeburn  3338:             } 
                   3339:         } else {
                   3340:             $othdom ++;
1.74      raeburn  3341:             $otherdom{$student} = &mt("Still set to $oldtype"); 
1.16      raeburn  3342:         }
                   3343:     }
                   3344:     foreach my $student (@lockchglist) {
1.51      raeburn  3345:         my ($uname,$udom) = split(/:/,$student);
1.16      raeburn  3346:         my $sdata    = $classlist->{$student};
                   3347:         my $section  = $sdata->[$secidx];
                   3348:         my $uid       = $sdata->[$ididx];
                   3349:         my $start    = $sdata->[$startidx];
                   3350:         my $end      = $sdata->[$endidx];
                   3351:         my $type     = $sdata->[$typeidx];
                   3352:         my $lock   = $sdata->[$lockedidx];
1.76      raeburn  3353:         my $credits = $sdata->[$creditsidx];
1.16      raeburn  3354:         my $newlock = 1;
                   3355:         my $oldlockname = &mt('unlocked');
                   3356:         my $newlockname = &mt('locked');
                   3357:         $locktotal++;
                   3358:         unless ($type eq 'auto') {
                   3359:             if ($lock) {
                   3360:                 $newlock = '';
                   3361:                 $newlockname = &mt('unlocked');
                   3362:                 $oldlockname = &mt('locked'); 
                   3363:             }
1.76      raeburn  3364:             my $lockreply = &Apache::lonnet::modify_student_enrollment($udom,$uname,$uid,'','','','',$section,$end,$start,$type,$newlock,$cid,'','chgtype',$credits);
1.16      raeburn  3365:             if ($lockreply eq 'ok') {
                   3366:                 $lockok ++;
1.74      raeburn  3367:                 $lockchg{$student} = &mt('Changed to [_1]',$newlockname);
1.14      raeburn  3368:             } else {
1.16      raeburn  3369:                 $lockfail ++;
1.74      raeburn  3370:                 $nolockchg{$student} = &mt('Still set to [_1]',$oldlockname);
1.14      raeburn  3371:             }
                   3372:         }
                   3373:     }
                   3374:     if ($chgtotal > 0) {
1.51      raeburn  3375:         $response = &mt('You requested a change in enrollment type for [quant,_1,student].',$chgtotal).'<br /><br />'."\n";
1.27      albertel 3376:         $classlist = &Apache::loncoursedata::get_classlist($dom,$crs);
1.14      raeburn  3377:         if ($chgok > 0) {
1.51      raeburn  3378:             $response .= &mt('The following [quant,_1,change was,changes were] successful;',$chgtotal).':<br /><br />';
1.14      raeburn  3379:             $response .= &enrolltype_result(\%chg,$classlist,$endidx,$startidx,$ididx,$secidx,$typeidx);
                   3380:         }
                   3381:         if ($chgfail > 0) {
1.51      raeburn  3382:             $response .= &mt('The following [quant,_1,student was,students were] not modified successfully',$chgfail).':&nbsp;<br />';
1.14      raeburn  3383:             $response .= &enrolltype_result(\%nochg,$classlist,$endidx,$startidx,$ididx,$secidx,$typeidx);
                   3384:         }
                   3385:         if ($othdom > 0) {
1.51      raeburn  3386:             $response .= &mt("The following [quant,_1,student was,students were] not modified because students must be in the same LON-CAPA domain as the course, in order to be set to an enrollment type of 'auto'",$othdom).':<br />'; 
1.14      raeburn  3387:             $response .= &enrolltype_result(\%otherdom,$classlist,$endidx,$startidx,$ididx,$secidx,$typeidx);
                   3388:         }
1.74      raeburn  3389:         $response .= '<br /><br />';
1.16      raeburn  3390:     }
                   3391:     if ($locktotal > 0) {
1.51      raeburn  3392:         $response .= &mt('You requested locking/unlocking for [quant,_1,manually enrolled student]',$locktotal).'<br /><br />'."\n";
1.27      albertel 3393:         $classlist = &Apache::loncoursedata::get_classlist($dom,$crs);
1.16      raeburn  3394:         if ($lockok > 0) {
1.51      raeburn  3395:             $response .= &mt('The following [quant,_1,change was,changes were] successful',$lockok).':<br /><br />';
1.16      raeburn  3396:             $response .= &enrolltype_result(\%lockchg,$classlist,$endidx,$startidx,$ididx,$secidx,$typeidx,$lockedidx);
                   3397:         }
                   3398:         if ($lockfail > 0) {
1.51      raeburn  3399:             $response .= &mt('The following [quant,_1,student was,students were] not modified successfully',$lockfail).':&nbsp;<br />';
1.16      raeburn  3400:             $response .= &enrolltype_result(\%nolockchg,$classlist,$endidx,$startidx,$ididx,$secidx,$typeidx,$lockedidx);
                   3401:         }
1.14      raeburn  3402:     }
                   3403:     &print_reply($r,$response,$$tasktitleref{$action});
                   3404:     return;
                   3405: }
                   3406: 
                   3407: sub enrolltype_result {
1.16      raeburn  3408:     my ($changes,$classlist,$endidx,$startidx,$ididx,$secidx,$typeidx,$lockedidx) = @_;
1.51      raeburn  3409:     my $reply = &Apache::loncommon::start_data_table().
                   3410:                 &Apache::loncommon::start_data_table_header_row().'
1.74      raeburn  3411:               <th>'.&mt('username').'</th>
                   3412:               <th>'.&mt('domain').'</th>
                   3413:               <th>'.&mt('ID').'</th>
                   3414:               <th>'.&mt('student name').'</th>
                   3415:               <th>'.&mt('section').'</th>
                   3416:               <th>'.&mt('start date').'</th>
                   3417:               <th>'.&mt('end date').'</th>
                   3418:               <th>'.&mt('enrollment change').'</th>'."\n".
1.51      raeburn  3419:                 &Apache::loncommon::end_data_table_header_row();
1.74      raeburn  3420:     foreach my $chg (sort(keys(%{$changes}))) {
1.51      raeburn  3421:         my $sdata  = $classlist->{$chg};
                   3422:         my ($uname,$udom) = split(/:/,$chg);
1.14      raeburn  3423:         my $section  = $sdata->[$secidx];
                   3424:         my $uid      = $sdata->[$ididx];
                   3425:         my $start    = $sdata->[$startidx];
                   3426:         my $end      = $sdata->[$endidx];
                   3427:         my $type     = $sdata->[$typeidx];
                   3428:         if (! defined($start) || $start == 0) {
                   3429:             $start = &mt('none');
                   3430:         } else {
                   3431:             $start = &Apache::lonlocal::locallocaltime($start);
                   3432:         }
                   3433:         if (! defined($end) || $end == 0) {
                   3434:             $end = &mt('none');
                   3435:         } else {
                   3436:             $end = &Apache::lonlocal::locallocaltime($end);
                   3437:         }
                   3438:         if (!defined($section) || ($section eq '')) {
1.51      raeburn  3439:             $section = '&nbsp;';
1.14      raeburn  3440:         }
                   3441:         if (!defined($uid) || ($uid eq '')) {
1.51      raeburn  3442:             $uid = '&nbsp;';
1.14      raeburn  3443:         }
1.51      raeburn  3444:         $reply .= &Apache::loncommon::start_data_table_row().' 
                   3445:               <td>'.$uname.'</td>
                   3446:               <td>'.$udom.'</td>
                   3447:               <td>'.$uid.'</td>
                   3448:               <td>'.&Apache::loncommon::plainname($uname,$udom).'</td>
                   3449:               <td>'.$section.'</td>
                   3450:               <td>'.$start.'</td>
                   3451:               <td>'.$end.'</td>
                   3452:               <td>'.$$changes{$chg}.'</td>'."\n".
                   3453:              &Apache::loncommon::end_data_table_row();
1.14      raeburn  3454:     }
1.51      raeburn  3455:     $reply .= &Apache::loncommon::end_data_table();
1.14      raeburn  3456:     return $reply;
                   3457: }
                   3458: 
1.10      raeburn  3459: sub warning_message {
                   3460:     my ($dom,$crs,$caller) = @_;
1.74      raeburn  3461:     my %settings = 
                   3462:         &Apache::lonnet::get('environment',
                   3463:              ['internal.autoadds','internal.autodrops','internal.sectionnums',
                   3464:               'internal.crosslistings','internal.autostart','internal.autoend'],
                   3465:              $dom,$crs);
                   3466:     my ($currend,$currstart,$currsecs,$currxlists,$curradds,$currdrops);
1.10      raeburn  3467:     if ( defined($settings{'internal.autoadds'}) ) {
                   3468:         $curradds = $settings{'internal.autoadds'};
                   3469:     }
                   3470:     if (defined($settings{'internal.autodrops'}) ) {
                   3471:         $currdrops = $settings{'internal.autodrops'};
                   3472:     }
                   3473:     if ( defined($settings{'internal.autostart'}) ) {
                   3474:         $currstart = $settings{'internal.autostart'};
                   3475:     }
                   3476:     if ( defined($settings{'internal.autoend'}) ) {
                   3477:         $currend = $settings{'internal.autoend'};
                   3478:     }
                   3479:     if ( defined($settings{'internal.sectionnums'}) ) {
                   3480:         $currsecs = $settings{'internal.sectionnums'};
                   3481:     }
                   3482:     if ( defined($settings{'internal.crosslistings'}) ) {
                   3483:         $currxlists = $settings{'internal.crosslistings'}
                   3484:     }
1.74      raeburn  3485:     my $warning = '';
1.10      raeburn  3486:     unless ($caller eq 'setdates') {
                   3487:         if ( ($currstart eq '') && ($currend eq '') )  {
1.74      raeburn  3488:             $warning .= '<li>'.
                   3489:                 &mt("You [_1]must[_2] now use [_3]Change enrollment dates[_4] to set a start date [_5]and[_6] an end date for the enrollment (or check the 'No end date' checkbox) for the nightly adds process to actually occur.",'<b>','</b>','<a href="/adm/populate?action=setdates">','</a>'.'<i>','</i>').'</li>';
1.10      raeburn  3490:         }
                   3491:     }
                   3492:     unless ( ($caller eq 'sections') || ($caller eq 'crosslist') ) {
                   3493:         if ( ($currsecs eq '') && ($currxlists eq '') ) {
1.74      raeburn  3494:             $warning .= '<li>'.
                   3495:                 &mt('You [_1]must[_2] now use [_3]Section settings[_4] and/or [_5]Change crosslistings[_4] to choose at least one section of the course, or at least one crosslisted course which will contribute enrollment to this LON-CAPA course.','<b>','</b>','<a href="/adm/populate?action=sections">','</a>','<a href="/adm/populate?action=crosslist">').' '.
                   3496:                         &mt('At present there are [_1]NO[_2] sections or crosslisted courses that are affiliated with this course that are set to contribute to the automated enrollment process.','<b>','</b>').'</li>';
1.10      raeburn  3497:         }
                   3498:     }
                   3499:     unless ( $caller eq 'chgsettings') {
                   3500:         if ( (!$curradds) && (!$currdrops) ) {
1.74      raeburn  3501:             $warning .= '<li>'.
1.78      raeburn  3502:                 &mt('You [_1]must[_2] now use [_3]Automated adds/drops[_4] to enable automated adds and/or drops if you want automatic enrollment updates to occur in this course.','<b>','</b>','<a href="/adm/populate?action=chgsettings">','</a>').'</li>';
1.10      raeburn  3503:         }
                   3504:     }
1.74      raeburn  3505:     if ($warning) {
                   3506:         return '<p class="LC_info"><ul>'.$warning.'</ul></p>';
                   3507:     }
                   3508:     return;
1.1       raeburn  3509: }
                   3510: 
1.74      raeburn  3511: sub print_reply {
1.1       raeburn  3512:   my ($r,$response,$caller) = @_;
1.74      raeburn  3513:   $r->print('
                   3514:             <br /><table width="100%" border="0" cellpadding="2" cellspacing="2">
1.1       raeburn  3515:              <tr>
1.74      raeburn  3516:               <td align="left"><b>'.$caller.'</b> - '.&mt('result').'
                   3517:               <br /><br />'.$response.'</td>
1.1       raeburn  3518:              </tr>
                   3519:             </table>
1.74      raeburn  3520:   ');
1.1       raeburn  3521:   return;
                   3522: }
                   3523: 
                   3524: sub setup_date_selectors {
1.85      raeburn  3525:     my ($starttime,$endtime,$action,$readonly) = @_;
                   3526:     my $disabled;
                   3527:     if ($readonly) {
                   3528:         $disabled = 'disabled';
                   3529:     }
1.1       raeburn  3530:     if (! defined($starttime)) {
                   3531:         $starttime = time;
1.14      raeburn  3532:         if ($action eq 'setdates') {
1.23      albertel 3533:             if (exists($env{'course.'.$env{'request.course.id'}.
1.1       raeburn  3534:                             '.default_enrollment_start_date'})) {
1.23      albertel 3535:                 $starttime = $env{'course.'.$env{'request.course.id'}.
1.1       raeburn  3536:                                   '.default_enrollment_start_date'};
1.14      raeburn  3537:             }
1.1       raeburn  3538:         }
                   3539:     }
                   3540:     if (! defined($endtime)) {
                   3541:         $endtime = time+(6*30*24*60*60); # 6 months from now, approx
1.14      raeburn  3542:         if ($action eq 'setdates') {
1.23      albertel 3543:             if (exists($env{'course.'.$env{'request.course.id'}.
1.1       raeburn  3544:                             '.default_enrollment_end_date'})) {
1.23      albertel 3545:                 $endtime = $env{'course.'.$env{'request.course.id'}.
1.1       raeburn  3546:                                 '.default_enrollment_end_date'};
1.14      raeburn  3547:             }
1.1       raeburn  3548:         }
                   3549:     }
                   3550:     my $startdateform = &Apache::lonhtmlcommon::date_setter('enter',
                   3551:                                                             'startdate',
1.85      raeburn  3552:                                                             $starttime,'','',$disabled);
1.1       raeburn  3553:     my $enddateform = &Apache::lonhtmlcommon::date_setter('enter',
                   3554:                                                           'enddate',
1.85      raeburn  3555:                                                           $endtime,'','',$disabled);
1.1       raeburn  3556:     return ($startdateform,$enddateform);
                   3557: }
                   3558: 
                   3559: sub get_dates_from_form {
1.74      raeburn  3560:     my ($startdate,$enddate);
1.14      raeburn  3561:     $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
                   3562:     $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
1.23      albertel 3563:     if ( exists ($env{'form.no_end_date'}) ) {
1.1       raeburn  3564:         $enddate = 0;
                   3565:     }
                   3566:     return ($startdate,$enddate);
                   3567: }
                   3568: 
                   3569: sub date_setting_table {
1.85      raeburn  3570:     my ($starttime,$endtime,$action,$readonly) = @_;
                   3571:     my $disabled;
                   3572:     if ($readonly) {
                   3573:         $disabled = ' disabled="disabled"';
                   3574:     }
1.74      raeburn  3575:     my ($startform,$endform) = 
1.85      raeburn  3576:         &setup_date_selectors($starttime,$endtime,$action,$readonly);
1.74      raeburn  3577:     my $perpetual = '<span class="LC_nobreak"><label>'.
                   3578:                     '<input type="checkbox" name="no_end_date"';
                   3579:     if (($action eq 'setdates' && defined($endtime) && $endtime == 0) || 
                   3580:         (($action eq 'setaccess' || $action eq 'updatenow') && 
                   3581:          ($endtime eq '' || $endtime == 0)) ) {
                   3582:         $perpetual .= ' checked="checked"';
                   3583:     }
1.85      raeburn  3584:     $perpetual.= $disabled.' /> '.&mt('no end date').'</label></span>';
1.74      raeburn  3585:     my $start_table = "<table>\n".
                   3586:                       '<tr><td align="right">'.&mt('Starting Date').'</td>'.
                   3587:                       '<td>'.$startform.'</td>'.
                   3588:                       '<td>&nbsp;</td>'."</tr>\n".
                   3589:                       "</table>";
                   3590:     my $end_table = "<table>\n".
                   3591:                     '<tr><td align="right">'.&mt('Ending Date').'</td>'.
                   3592:                     '<td>'.$endform.'</td>'.
                   3593:                     '<td>'.$perpetual.'</td>'."</tr>\n".
                   3594:                     "</table>\n";
1.1       raeburn  3595:     return ($start_table, $end_table);
                   3596: }
                   3597: 
1.42      raeburn  3598: sub validate_lcsec {
                   3599:     my ($curr_groups,$lcsec) = @_;
                   3600:     if (($lcsec eq 'all') || ($lcsec eq 'none')) {
                   3601:         return 'reserved';
                   3602:     } else {
                   3603:         if (exists($$curr_groups{$lcsec})) {
                   3604:             return 'group'; 
                   3605:         }
                   3606:     }
                   3607:     return 'ok';
                   3608: }
                   3609: 
1.48      albertel 3610: sub user_is_courseowner {
                   3611:     my ($courseowner) = @_;
                   3612:     my $user;
                   3613:     if ($courseowner =~ /^[^:]+:[^:]+$/) {
                   3614: 	$user = $env{'user.name'}.':'.$env{'user.domain'};
                   3615:     } else {
                   3616: 	$user = $env{'user.name'};
                   3617:     }
                   3618:     return ($user eq $courseowner);
                   3619: }
1.74      raeburn  3620: 
                   3621: sub get_task_text {
1.85      raeburn  3622:     my ($permref) = @_;
                   3623:     my %tasklong =
1.74      raeburn  3624:         &Apache::lonlocal::texthash(
1.85      raeburn  3625:            information   => 'Task information',
                   3626:            chgsettings   => 'Automated adds/drops',
1.90      raeburn  3627:            chgfailsafe   => 'View/change enrollment failsafe',
1.85      raeburn  3628:            setdates      => 'Change enrollment dates',
                   3629:            setaccess     => 'Change access dates',
                   3630:            notify        => 'Notification of changes',
                   3631:            crosslist     => 'Change crosslistings',
                   3632:            sections      => 'Section settings',
                   3633:            photos        => 'Student photo settings',
                   3634:            updatephotos  => 'Update student photos',
                   3635:            updatenow     => 'Update roster now',
                   3636:            newcross      => 'Add crosslistings',
                   3637:            newsections   => 'Add sections',
                   3638:            viewclass     => 'View students and change type',
1.74      raeburn  3639:     );
                   3640: 
1.85      raeburn  3641:     my %tasktitle =
1.74      raeburn  3642:         &Apache::lonlocal::texthash(
1.85      raeburn  3643:            chgsettings  => 'Changes to nightly automated enrollments',
                   3644:            chgfailsafe  => 'Changes to failsafe protection for data retrieval problems',
                   3645:            setdates     => 'Changes to first and/or last automated enrollment dates',
                   3646:            setaccess    => 'Changes to default start and/or end dates for student access',
                   3647:            notify       => 'Notification of enrollment changes',
                   3648:            crosslist    => 'Changes to crosslistings',
                   3649:            sections     => 'Changes to section settings',
                   3650:            photos       => 'Student photo settings',
                   3651:            updatephotos => 'Update student photos',
                   3652:            updatenow => "Immediate course roster update",
                   3653:            newcross => "Adding new crosslisted courses",
                   3654:            newsections => "Adding new course sections",
                   3655:            viewclass => "Viewing class roster and enrollment type"
1.74      raeburn  3656:     );
1.85      raeburn  3657: 
                   3658:     if ((ref($permref) eq 'HASH') && (!$permref->{'edit'})) {
1.90      raeburn  3659:         $tasklong{'chgfailsafe'} = &mt('Enrollment failsafe');
1.85      raeburn  3660:         $tasklong{'setdates'}    = &mt('Enrollment dates');
                   3661:         $tasklong{'setaccess'}   = &mt('Access dates');
                   3662:         $tasklong{'crosslist'}   = &mt('Crosslistings');
                   3663:         $tasklong{'viewclass'}   = &mt('View students and type');
                   3664:     }
1.74      raeburn  3665:     return (\%tasklong,\%tasktitle);
                   3666: }
1.85      raeburn  3667: 
                   3668: sub check_permission {
                   3669:     my ($permref) = @_;
                   3670:     return unless (ref($permref) eq 'HASH');
                   3671:     my $hasaccess;
                   3672:     if ($env{'request.course.id'}) {
                   3673:         foreach my $priv ('cst','vpa','vcl') {
                   3674:             my ($allowed,$section);
                   3675:             if (&Apache::lonnet::allowed($priv,$env{'request.course.id'})) {
                   3676:                 $allowed = 1;
                   3677:             } elsif ($env{'request.course.sec'} ne '') {
                   3678:                 if (&Apache::lonnet::allowed($priv,$env{'request.course.id'}.'/'.
                   3679:                                                    $env{'request.course.sec'})) {
                   3680:                     $allowed = 1;
                   3681:                     $section = $env{'request.course.sec'};
                   3682:                 }
                   3683:             }
                   3684:             if ($allowed) {
                   3685:                 $hasaccess = 1;
                   3686:                 if ($priv eq 'cst') {
                   3687:                     if ($section ne '') {
                   3688:                         $permref->{'edit_section'} = $section;
                   3689:                     } else {
                   3690:                         $permref->{'edit'} = 1;
                   3691:                     }
                   3692:                 } elsif ($priv eq 'vpa') {
                   3693:                     if ($section ne '') {
                   3694:                         $permref->{'view_section'} = $section;
                   3695:                     } else {
                   3696:                         $permref->{'view'} = 1;
                   3697:                     }
                   3698:                 } elsif ($priv eq 'vcl') {
                   3699:                     if ($section ne '') {
                   3700:                         $permref->{'show_section'} = $section;
                   3701:                     } else {
                   3702:                         $permref->{'show'} = 1;
                   3703:                     }
                   3704:                 }
                   3705:             }
                   3706:         }
                   3707:     }
                   3708:     return $hasaccess;
                   3709: }
                   3710: 
1.48      albertel 3711:     
1.1       raeburn  3712: ###################################################################
                   3713: sub handler {
                   3714:     my $r = shift;
                   3715:     if ($r->header_only) {
1.22      albertel 3716: 	&Apache::loncommon::content_type($r,'text/html');
1.1       raeburn  3717:         $r->send_http_header;
                   3718:         return OK;
                   3719:     }
1.74      raeburn  3720:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   3721:                                             ['action','state']);
1.85      raeburn  3722:     my %permhash;
1.1       raeburn  3723:     #  Needs to be in a course
1.85      raeburn  3724:     if (!($env{'request.course.fn'})) {
                   3725:         # Not in a course
                   3726:         $env{'user.error.msg'}="/adm/populate:cst:0:0:Cannot display automated enrollment";
1.34      raeburn  3727:         return HTTP_NOT_ACCEPTABLE;
1.85      raeburn  3728:     } elsif (!&check_permission(\%permhash)) {
                   3729:         # Not allowed to modify students, view settings, or view classlist.
                   3730:         $env{'user.error.msg'}="/adm/populate:cst:0:0:Cannot display automated enrollment";
                   3731:         return HTTP_NOT_ACCEPTABLE; 
1.1       raeburn  3732:     }
                   3733:     # Start page
1.22      albertel 3734:     &Apache::loncommon::content_type($r,'text/html');
1.1       raeburn  3735:     $r->send_http_header;
                   3736: 
1.74      raeburn  3737:     my @tasks = ('information','chgsettings','setdates','setaccess','notify','crosslist',
1.84      raeburn  3738:                  'sections','photos','updatenow','updatephotos','viewclass','chgfailsafe');
1.74      raeburn  3739:  
1.85      raeburn  3740:     my ($tasklong,$tasktitle) = &get_task_text(\%permhash);
1.74      raeburn  3741:     my $realm;
1.23      albertel 3742:     if ( exists($env{'request.course.id'}) ) {
1.74      raeburn  3743:         $realm=$env{'course.'.$env{'request.course.id'}.'.description'};
1.1       raeburn  3744:     }
                   3745:     unless ($realm) { $realm='&nbsp;'; }
1.23      albertel 3746:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3747:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.85      raeburn  3748: 
1.1       raeburn  3749:     #
                   3750:     # Main switch on form.action and form.state, as appropriate
                   3751:     #
                   3752: 
                   3753:     my $action = "information";
1.23      albertel 3754:     if ( exists($env{'form.action'}) ) {
                   3755:         $action = $env{'form.action'};
1.1       raeburn  3756:     }
                   3757:     my $state = "choose";
                   3758: 
1.23      albertel 3759:     if ( exists($env{'form.state'}) ) {
                   3760:         $state = $env{'form.state'};
1.1       raeburn  3761:     }
                   3762: 
                   3763:     if ($action eq "information") {
1.85      raeburn  3764:         $r->print(&header($action,\%permhash));
1.1       raeburn  3765:     } else {
                   3766:         if ($state eq "choose") {
1.90      raeburn  3767:             $r->print(&choose_header($action,\%permhash,$dom));
1.1       raeburn  3768:         } else {
                   3769:             if ($action eq "crosslist") {
1.23      albertel 3770:                 if ( exists($env{'form.numcross'}) ) {
                   3771:                     if ( $env{'form.numcross'} > 0 ) {
1.90      raeburn  3772:                         $r->print(&choose_header($action,\%permhash,$dom));
1.1       raeburn  3773:                     } else {
1.85      raeburn  3774:                         $r->print(&header($action,\%permhash));
1.1       raeburn  3775:                     }
                   3776:                 } else {
1.85      raeburn  3777:                     $r->print(&header(undef,\%permhash));
1.1       raeburn  3778:                 }
                   3779:             } elsif ($action eq "sections") {
1.23      albertel 3780:                 if ( exists($env{'form.numsec'}) ) {
                   3781:                     if ( $env{'form.numsec'} > 0 ) {
1.90      raeburn  3782:                         $r->print(&choose_header($action,\%permhash,$dom));
1.1       raeburn  3783:                     } else {
1.85      raeburn  3784:                         $r->print(&header($action,\%permhash));
1.1       raeburn  3785:                     }
                   3786:                 } else {
1.85      raeburn  3787:                     $r->print(&header($action,\%permhash));
1.1       raeburn  3788:                 }
                   3789:             } else {
1.85      raeburn  3790:                 $r->print(&header($action,\%permhash));
1.1       raeburn  3791:             }
                   3792:         }
                   3793:     }
1.12      raeburn  3794: 
1.1       raeburn  3795:     my $reply = 0;
                   3796:     unless ($state eq "choose") { $reply = 1; }
                   3797: 
1.74      raeburn  3798:     &print_navmenu($r,\@tasks,$tasklong,$action,$state);
                   3799: 
1.1       raeburn  3800:     if (($state eq "choose") || ($action eq "information")) {
1.85      raeburn  3801:         &print_main_frame($r,$realm,$dom,$crs,$tasktitle,\%permhash);
                   3802:     } elsif (($action eq "chgsettings") && ($permhash{'edit'})) {
1.74      raeburn  3803:         &print_chgsettings_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3804:     } elsif (($action eq "chgfailsafe") && ($permhash{'edit'})) {
1.84      raeburn  3805:         &print_chgfailsafe_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3806:     } elsif (($action eq "setdates") && ($permhash{'edit'})) {
1.74      raeburn  3807:         &print_setdates_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3808:     } elsif (($action eq "setaccess") && ($permhash{'edit'})) {
1.74      raeburn  3809:         &print_setaccess_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3810:     } elsif (($action eq "notify") && ($permhash{'edit'})) {
1.74      raeburn  3811:         &print_notify_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3812:     } elsif (($action eq "sections") && ($permhash{'edit'})) {
1.74      raeburn  3813:         &print_sections_menu($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3814:     } elsif (($action eq "crosslist") && ($permhash{'edit'})) {
1.74      raeburn  3815:         &print_crosslistings_menu($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3816:     } elsif (($action eq "updatenow") && ($permhash{'edit'})) {
1.74      raeburn  3817:         &print_update_result($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3818:     } elsif (($action eq "photos") && ($permhash{'edit'})) {
1.34      raeburn  3819:         if ($state eq "photoupdate") {
1.74      raeburn  3820:             &print_photoupdate_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3821:         } else {
1.74      raeburn  3822:             &photo_permission($r,$realm,$dom,$crs,$action,$tasktitle);
1.34      raeburn  3823:         }
1.85      raeburn  3824:     } elsif (($action eq "updatephotos") && ($permhash{'edit'})) {
1.74      raeburn  3825:         &print_photoupdate_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3826:     } elsif (($action eq "newcross") && ($permhash{'edit'})) {
1.74      raeburn  3827:         &print_crosslistings_response($r,$realm,$dom,$crs,$action,$tasktitle);    
1.85      raeburn  3828:     } elsif (($action eq "newsections") && ($permhash{'edit'})) {
1.74      raeburn  3829:         &print_sections_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.85      raeburn  3830:     } elsif (($action eq "viewclass") && ($permhash{'edit'})) {
1.74      raeburn  3831:         &print_viewclass_response($r,$realm,$dom,$crs,$action,$tasktitle);
1.1       raeburn  3832:     }
                   3833:     &print_doc_base($r);  
                   3834:     return OK;
                   3835: }
                   3836: ###################################################################
                   3837: 1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>