--- loncom/interface/Attic/londropadd.pm 2003/12/12 18:04:38 1.94 +++ loncom/interface/Attic/londropadd.pm 2005/01/31 11:27:14 1.124 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to drop and add students in courses # -# $Id: londropadd.pm,v 1.94 2003/12/12 18:04:38 sakharuk Exp $ +# $Id: londropadd.pm,v 1.124 2005/01/31 11:27:14 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,11 +25,6 @@ # # http://www.lon-capa.org/ # -# (Handler to set parameters for assessments -# -# (Handler to resolve ambiguous file locations -# -# (TeX Content Handler # ############################################################### ############################################################## @@ -42,6 +37,7 @@ use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::Constants qw(:common :http REDIRECT); use Spreadsheet::WriteExcel; +use Apache::lonstathelpers(); use Apache::lonlocal; ############################################################### @@ -140,41 +136,61 @@ sub domain_form { ############################################################### # Menu Phase One sub print_main_menu { - my $r=shift; - my %Text = &Apache::lonlocal::texthash - ('upload' => 'Upload a class list', - 'enrollone' => 'Enroll a single student', - 'modify' => 'Modify student data', - 'view' => 'View Class List', - 'drop' => 'Drop Students', - 'populate' => 'Automated Enrollment Manager'); - - $r->print(<<END); -<p> -<font size="+1"> - <a href="/adm/dropadd?action=upload">$Text{'upload'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=enrollstudent">$Text{'enrollone'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=modifystudent">$Text{'modify'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=classlist">$Text{'view'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=drop">$Text{'drop'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/populate">$Text{'populate'}</a> -</font> -END + my ($r,$enrl_permission,$view_permission)=@_; + # + my ($cdom,$cnum) = split/_/,$ENV{'request.course.id'}; + my @menu = + ( + { text => 'Upload a class list', + help => 'Course_Create_Class_List', + action => 'upload', + permission => $enrl_permission, + }, + { text => 'Enroll a single student', + help => 'Course_Add_Student', + action => 'enrollstudent', + permission => $enrl_permission, + }, + { text => 'Modify student data', + help => 'Course_Modify_Student_Data', + action => 'modifystudent', + permission => $enrl_permission, + }, + { text => 'View Class List', + help => 'Course_View_Class_List', + action => 'classlist', + permission => $view_permission, + }, + { text => 'Drop Students', + help => 'Course_Drop_Student', + action => 'drop', + permission => $enrl_permission, + }, + { text => 'Automated Enrollment Manager', + permission => &Apache::lonnet::auto_run($cnum,$cdom), + url => '/adm/populate', + }, + ); + my $menu_html = ''; + foreach my $menu_item (@menu) { + next if (! $menu_item->{'permission'}); + $menu_html.='<p>'; + $menu_html.='<font size="+1">'; + if (exists($menu_item->{'url'})) { + $menu_html.=qq{<a href="$menu_item->{'url'}">}; + } else { + $menu_html.= + qq{<a href="/adm/dropadd?action=$menu_item->{'action'}">}; + } + $menu_html.= &mt($menu_item->{'text'}).'</a></font>'; + if (exists($menu_item->{'help'})) { + $menu_html.= + &Apache::loncommon::help_open_topic($menu_item->{'help'}); + } + $menu_html.='</p>'.$/; + } + $r->print($menu_html); + return; } ############################################################### @@ -187,6 +203,7 @@ sub hidden_input { sub print_upload_manager_header { my ($r,$datatoken,$distotal,$krbdefdom)=@_; my $javascript; + # if (! exists($ENV{'form.upfile_associate'})) { $ENV{'form.upfile_associate'} = 'forward'; } @@ -202,7 +219,20 @@ sub print_upload_manager_header { } else { $javascript=&upload_manager_javascript_forward_associate(); } - my $javascript_validations=&javascript_validations('auth',$krbdefdom); + # + # Deal with restored settings + my $password_choice = ''; + if (exists($ENV{'form.ipwd_choice'}) && + $ENV{'form.ipwd_choice'} ne '') { + # If a column was specified for password, assume it is for an + # internal password. This is a bug waiting to be filed (could be + # local or krb auth instead of internal) but I do not have the + # time to mess around with this now. + $password_choice = 'int'; + } + # + my $javascript_validations=&javascript_validations('auth',$krbdefdom, + $password_choice); my $checked=(($ENV{'form.noFirstLine'})?' checked="1"':''); $r->print('<h3>'.&mt('Uploading Class List')."</h3>\n". "<hr>\n". @@ -232,17 +262,27 @@ sub print_upload_manager_header { ############################################################### ############################################################### sub javascript_validations { - my ($mode,$krbdefdom)=@_; + my ($mode,$krbdefdom,$curr_authtype,$curr_authfield)=@_; my $authheader; if ($mode eq 'auth') { my %param = ( formname => 'studentform', - kerb_def_dom => $krbdefdom ); + kerb_def_dom => $krbdefdom, + curr_authtype => $curr_authtype); $authheader = &Apache::loncommon::authform_header(%param); } elsif ($mode eq 'createcourse') { my %param = ( formname => 'ccrs', - kerb_def_dom => $krbdefdom ); + kerb_def_dom => $krbdefdom, + curr_authtype => $curr_authtype ); + $authheader = &Apache::loncommon::authform_header(%param); + } elsif ($mode eq 'modifycourse') { + my %param = ( formname => 'cmod', + kerb_def_dom => $krbdefdom, + mode => 'modifycourse', + curr_authtype => $curr_authtype, + curr_autharg => $curr_authfield ); $authheader = &Apache::loncommon::authform_header(%param); } + my %alert = &Apache::lonlocal::texthash (username => 'You need to specify the username field.', @@ -260,24 +300,59 @@ sub javascript_validations { my $function_name =(<<END); function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) { END - my $auth_checks = (<<END); - var foundatype=0; + my $auth_checks; + if ($mode eq 'createcourse') { + $auth_checks .= (<<END); + if (vf.autoadds[0].checked == true) { + if (current.radiovalue == null || current.radiovalue == 'nochange') { + alert('$alert{'authen'}'); + return; + } + } END - unless ($mode eq 'createcourse') { + } else { $auth_checks .= (<<END); + var foundatype=0; if (founduname==0) { alert('$alert{'username'}'); return; } -END - } - $auth_checks .= (<<END); // alert('current.radiovalue = '+current.radiovalue); - if (current.radiovalue == null || current.radiovalue == 'nochange') { + if (current.radiovalue == null || current.radiovalue == '' || current.radiovalue == 'nochange') { // They did not check any of the login radiobuttons. alert('$alert{'authen'}'); return; } +END + } + if ($mode eq 'createcourse') { + $auth_checks .= " + if ( (vf.autoadds[0].checked == true) && + (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') ) { +"; + } elsif ($mode eq 'modifycourse') { + $auth_checks .= " + if (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') { +"; + } + if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) { + $auth_checks .= (<<END); + var alertmsg = ''; + switch (current.radiovalue) { + case 'krb': + alertmsg = '$alert{'krb'}'; + break; + default: + alertmsg = ''; + } + if (alertmsg != '') { + alert(alertmsg); + return; + } + } +END + } else { + $auth_checks .= (<<END); foundatype=1; if (current.argfield == null || current.argfield == '') { var alertmsg = ''; @@ -301,8 +376,9 @@ END } } END + } my $optional_checks = ''; - if ($mode eq 'createcourse') { + if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) { $optional_checks = (<<END); vf.submit(); } @@ -345,11 +421,11 @@ END END } my $result = $function_name; - if ( ($mode eq 'auth') || ($mode eq 'createcourse') ) { + if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) { $result .= $auth_checks; } $result .= $optional_checks; - if ( ($mode eq 'auth') || ($mode eq 'createcourse') ) { + if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) { $result .= $authheader; } return $result; @@ -514,6 +590,11 @@ sub print_upload_manager_footer { kerb_def_dom => $krbdefdom, kerb_def_auth => $krbdef ); + if (exists($ENV{'form.ipwd_choice'}) && + defined($ENV{'form.ipwd_choice'}) && + $ENV{'form.ipwd_choice'} ne '') { + $param{'curr_authtype'} = 'int'; + } my $krbform = &Apache::loncommon::authform_kerberos(%param); my $intform = &Apache::loncommon::authform_internal(%param); my $locform = &Apache::loncommon::authform_local(%param); @@ -543,7 +624,7 @@ sub print_upload_manager_footer { 'of Conflicting IDs (only do if you know what you are doing)'). "\n</p><p>\n"; $Str .= '<input type="button" onClick="javascript:verify(this.form)" '. - 'value="Update Courselist" />'."<br />\n"; + 'value="Update Class List" />'."<br />\n"; $Str .= &mt('Note: for large courses, this operation may be time '. 'consuming'); $r->print($Str); @@ -554,6 +635,7 @@ sub print_upload_manager_footer { ############################################################### sub print_upload_manager_form { my $r=shift; + my $firstLine; my $datatoken; if (!$ENV{'form.datatoken'}) { @@ -570,23 +652,41 @@ sub print_upload_manager_form { my $distotal=$total+1; my $today=time; my $halfyear=$today+15552000; + # + # Restore memorized settings + &Apache::loncommon::restore_course_settings + ('enrollment_upload',{ 'username_choice' => 'scalar', # column settings + 'names_choice' => 'scalar', + 'fname_choice' => 'scalar', + 'mname_choice' => 'scalar', + 'lname_choice' => 'scalar', + 'gen_choice' => 'scalar', + 'id_choice' => 'scalar', + 'sec_choice' => 'scalar', + 'ipwd_choice' => 'scalar', + 'email_choice' => 'scalar', + }); + # + # Determine kerberos parameters as appropriate my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; my ($krbdef,$krbdefdom) = &Apache::loncommon::get_kerberos_defaults($defdom); + # &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom); my $i; my $keyfields; if ($total>=0) { - my @field=(['username',&mt('Username')], - ['names',&mt('Last Name, First Names')], - ['fname',&mt('First Name')], - ['mname',&mt('Middle Names/Initials')], - ['lname',&mt('Last Name')], - ['gen',&mt('Generation')], - ['id',&mt('ID/Student Number')], - ['sec',&mt('Group/Section')], - ['ipwd',&mt('Initial Password')], - ['email',&mt('EMail Address')]); + my @field= + (['username',&mt('Username'), $ENV{'form.username_choice'}], + ['names',&mt('Last Name, First Names'),$ENV{'form.names_choice'}], + ['fname',&mt('First Name'), $ENV{'form.fname_choice'}], + ['mname',&mt('Middle Names/Initials'),$ENV{'form.mname_choice'}], + ['lname',&mt('Last Name'), $ENV{'form.lname_choice'}], + ['gen', &mt('Generation'), $ENV{'form.gen_choice'}], + ['id', &mt('ID/Student Number'),$ENV{'form.id_choice'}], + ['sec', &mt('Group/Section'), $ENV{'form.sec_choice'}], + ['ipwd', &mt('Initial Password'),$ENV{'form.ipwd_choice'}], + ['email',&mt('EMail Address'), $ENV{'form.email_choice'}]); if ($ENV{'form.upfile_associate'} eq 'reverse') { &Apache::loncommon::csv_print_samples($r,\@records); $i=&Apache::loncommon::csv_print_select_table($r,\@records, @@ -614,7 +714,7 @@ sub enroll_single_student { $ENV{'form.csec'}=~s/\W//g; # # We do the dates first because the action of making them the defaul - # in the course is entirely seperate from the action of enrolling the + # in the course is entirely separate from the action of enrolling the # student. Also, a failure in setting the dates as default is not fatal # to the process of enrolling / modifying a student. my ($startdate,$enddate) = &get_dates_from_form(); @@ -670,7 +770,7 @@ sub enroll_single_student { $ENV{'form.clast'},$ENV{'form.cgen'}, $ENV{'form.csec'},$enddate, $startdate,$ENV{'form.forceid'}, - $desiredhost); + $desiredhost,$ENV{'form.emailaddress'}); if ($login_result =~ /^ok/) { $r->print($login_result); $r->print("<p> ".&mt('If active, the new role will be available when the student next logs in to LON-CAPA.')."</p>"); @@ -695,7 +795,7 @@ sub setup_date_selectors { my ($starttime,$endtime,$mode) = @_; if (! defined($starttime)) { $starttime = time; - unless ($mode eq 'createcourse') { + unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') { if (exists($ENV{'course.'.$ENV{'request.course.id'}. '.default_enrollment_start_date'})) { $starttime = $ENV{'course.'.$ENV{'request.course.id'}. @@ -719,12 +819,20 @@ sub setup_date_selectors { my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform', 'enddate', $endtime); - if ($mode eq 'createcourse') { + if ($mode eq 'create_enrolldates') { $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs', - 'startdate', + 'startenroll', $starttime); $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs', - 'enddate', + 'endenroll', + $endtime); + } + if ($mode eq 'create_defaultdates') { + $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs', + 'startaccess', + $starttime); + $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs', + 'endaccess', $endtime); } return ($startdateform,$enddateform); @@ -745,7 +853,7 @@ sub date_setting_table { my $dateDefault = '<nobr>'. '<input type="checkbox" name="makedatesdefault" /> '. &mt('make these dates the default for future enrollment'); - if ($mode eq 'createcourse') { + if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') { $dateDefault = ' '; } my $perpetual = '<nobr><input type="checkbox" name="no_end_date"'; @@ -753,6 +861,9 @@ sub date_setting_table { $perpetual .= ' checked'; } $perpetual.= ' /> '.&mt('no ending date').'</nobr>'; + if ($mode eq 'create_enrolldates') { + $perpetual = ' '; + } my $result = ''; $result .= "<table>\n"; $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'. @@ -812,6 +923,10 @@ sub get_student_username_domain_form { <input type="submit" name="Begin Enrollment" value="$lt{'been'}" /> </td></tr> </table> +<script type="text/javascript"> +// the if prevents the script error if the browser can not handle this +if ( document.studentform.cuname ) { document.studentform.cuname.focus(); } +</script> END return; } @@ -822,6 +937,8 @@ sub print_enroll_single_student_form { # my $username = $ENV{'form.cuname'}; my $domain = $ENV{'form.cudomain'}; + $username=~s/\W//gs; + $domain=~s/\W//gs; my $home = &Apache::lonnet::homeserver($username,$domain); # $new_user flags whether we are creating a new user or using an old one my $new_user = 1; @@ -866,6 +983,7 @@ sub print_enroll_single_student_form { 'hs' => "Home Server", 'pswd' => "Password", 'psam' => "Please select an authentication mechanism", + 'mail' => "Email Address" ); $user_data_html = <<END; <h3>$lt{'udf'} $username\@$domain</h3> @@ -880,6 +998,8 @@ sub print_enroll_single_student_form { <td><input type="text" name="cgen" size="5"> </td></tr> <tr><th>$lt{'hs'}:</th> <td>$homeserver_form</td></tr> +<tr><th>$lt{'mail'}:</th> + <td><input type="text" name="emailaddress" size="20" /></td></tr> </table> <h3>$lt{'pswd'}</h3> $lt{'psam'} @@ -902,6 +1022,7 @@ END 'mn' => "Middle Name", 'ln' => "Last Name", 'gen' => "Generation", + 'mail' => "Email Address", ); $user_data_html = <<END; <h3>$lt{'udf'} $username\@$domain</h3> @@ -923,6 +1044,10 @@ END <td> <input type="text" name="cgen" value="$uenv{'generation'}" size="5" /> </td></tr> +<tr><th>$lt{'mail'}:</th> + <td> + <input type="text" name="emailaddress" value="$uenv{'permanentemail'}" size="20" /> + </td></tr> </table> END } @@ -1015,7 +1140,7 @@ sub print_drop_menu { # ============================================== view classlist sub print_html_classlist { - my $r=shift; + my ($r,$mode) = @_; if (! exists($ENV{'form.sortby'})) { $ENV{'form.sortby'} = 'username'; } @@ -1023,94 +1148,136 @@ sub print_html_classlist { $ENV{'form.Status'} = 'Active'; } my $status_select = &Apache::lonhtmlcommon::StatusOptions - ($ENV{'form.Status'},'studentform'); - my $CCL=&mt('Current Class List'); - $r->print(<<END); -<input type="hidden" name="action" value="$ENV{'form.action'}" /> -<input type="hidden" name="state" value="" /> -<p> -<font size="+1">$CCL</font> - -END + ($ENV{'form.Status'}); + my $cid=$ENV{'request.course.id'}; + my $cdom=$ENV{'course.'.$cid.'.domain'}; + my $cnum=$ENV{'course.'.$cid.'.num'}; + # + # List course personnel + my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum); + # + if (! defined($ENV{'form.output'}) || + $ENV{'form.output'} !~ /^(csv|excel|html)$/ ) { + $ENV{'form.output'} = 'html'; + } + # + $r->print('<br /><table border="2">'); + foreach my $role (sort keys %coursepersonnel) { + next if ($role =~ /^\s*$/); + $r->print('<tr><td>'.$role.'</td><td>'); + foreach my $user (split(',',$coursepersonnel{$role})) { + my ($puname,$pudom)=split(':',$user); + $r->print(' '.&Apache::loncommon::aboutmewrapper( + &Apache::loncommon::plainname($puname, + $pudom), + $puname,$pudom)); + } + $r->print('</td></tr>'); + } + $r->print('</table>'); + # + # Interface output + $r->print('<input type="hidden" name="action" value="'. + $ENV{'form.action'}.'" />'); + $r->print("<p>\n"); if ($ENV{'form.action'} ne 'modifystudent') { - my %lt=&Apache::lonlocal::texthash( - 'ef' => "Excel format", - 'ss' => "Student Status", - ); - $r->print(<<END); -<font size="+1"> -<a href="javascript:document.studentform.state.value='csv';document.studentform.submit();">CSV format</a> - -<a href="javascript:document.studentform.state.value='excel';document.studentform.submit();">$lt{'ef'}</a> -</font> - -$lt{'ss'}: -END + my %lt=&Apache::lonlocal::texthash('csv' => "CSV", + 'excel' => "Excel", + 'html' => 'HTML'); + my $output_selector = '<select size="1" name="output" >'; + foreach my $outputformat ('html','csv','excel') { + my $option = '<option value="'.$outputformat.'" '; + if ($outputformat eq $ENV{'form.output'}) { + $option .= 'selected '; + } + $option .='>'.$lt{$outputformat}.'</option>'; + $output_selector .= "\n".$option; + } + $output_selector .= '</select>'; + $r->print(&mt('Output Format: [_1]',$output_selector).(' 'x3)); } - $r->print($status_select."</p>\n"); - my $cid=$ENV{'request.course.id'}; + $r->print(&mt('Student Status: [_1]',$status_select)."\n"); + $r->print('<input type="submit" value="'.&mt('Update Display').'" />'. + "\n</p>\n"); + # + # Print the classlist + $r->print('<h2>'.&mt('Current Class List').'</h2>'); my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { $r->print(&mt('There are no students currently enrolled.')."\n"); } else { # Print out the available choices if ($ENV{'form.action'} eq 'modifystudent') { - &show_class_list($r,'view','modify','modifystudent', + &show_class_list($r,'view','modify', $ENV{'form.Status'},$classlist,$keylist); } else { - &show_class_list($r,'view','aboutme','classlist', + &show_class_list($r,$ENV{'form.output'},'aboutme', $ENV{'form.Status'},$classlist,$keylist); } } } -# ============================================== view classlist -sub print_formatted_classlist { - my $r=shift; - my $mode = shift; - my $cid=$ENV{'request.course.id'}; - my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist(); - if (! defined($classlist)) { - $r->print(&mt('There are no students currently enrolled.')."\n"); - } else { - &show_class_list($r,$mode,'nolink','csv', - $ENV{'form.Status'},$classlist,$keylist); - } -} - # =================================================== Show student list to drop sub show_class_list { - my ($r,$mode,$linkto,$action,$statusmode,$classlist,$keylist)=@_; + my ($r,$mode,$linkto,$statusmode,$classlist,$keylist)=@_; my $cid=$ENV{'request.course.id'}; # # Variables for excel output - my ($excel_workbook, $excel_sheet, $excel_filename,$row); + my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format); + # + # Variables for csv output + my ($CSVfile,$CSVfilename); # my $sortby = $ENV{'form.sortby'}; - if ($sortby !~ /^(username|domain|section|fullname|id)$/) { + if ($sortby !~ /^(username|domain|section|fullname|id|start|end|type)$/) { $sortby = 'username'; } # Print out header - if ($mode eq 'view') { + unless ($mode eq 'autoenroll') { + $r->print(<<END); +<input type="hidden" name="state" value="$ENV{'form.state'}" /> +END + } + $r->print(<<END); +<input type="hidden" name="sortby" value="$sortby" /> +END + if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') { if ($linkto eq 'aboutme') { $r->print(&mt('Select a user name to view the users personal page.')); } elsif ($linkto eq 'modify') { $r->print(&mt('Select a user name to modify the students information')); } my %lt=&Apache::lonlocal::texthash( - 'usrn' => "username", - 'dom' => "domain", - 'sn' => "student name", - 'sec' => "section", + 'usrn' => "username", + 'dom' => "domain", + 'sn' => "student name", + 'sec' => "section", + 'start' => "start date", + 'end' => "end date", + 'type' => "enroll type/action" ); - $r->print(<<END); - -<input type="hidden" name="sortby" value="$sortby" /> + unless ($mode eq 'autoenroll') { + $r->print(<<END); <input type="hidden" name="sname" value="" /> <input type="hidden" name="sdom" value="" /> +END + } + $r->print(" <p> <table border=2> -<tr><th> +<tr> + "); + if ($mode eq 'autoenroll') { + $r->print(" + <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th> + "); + } else { + $r->print(" +<th>Count</th> + "); + } + $r->print(<<END); + <th> <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a> </th><th> <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a> @@ -1120,20 +1287,41 @@ sub show_class_list { <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a> </th><th> <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a> + </th><th> + <a href="javascript:document.studentform.sortby.value='start';document.studentform.submit();">$lt{'start'}</a> + </th><th> + <a href="javascript:document.studentform.sortby.value='end';document.studentform.submit();">$lt{'end'}</a> </th> -</tr> + </tr> END } elsif ($mode eq 'csv') { + # + # Open a file + $CSVfilename = '/prtspool/'. + $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. + time.'_'.rand(1000000000).'.csv'; + unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) { + $r->log_error("Couldn't open $CSVfilename for output $!"); + $r->print("Problems occured in writing the csv file. ". + "This error has been logged. ". + "Please alert your LON-CAPA administrator."); + $CSVfile = undef; + } + # + # Write headers and data to file if($statusmode eq 'Expired') { - $r->print(&mt('Students with expired roles')); + print $CSVfile '"'.&mt('Students with expired roles').'"'."\n"; } if ($statusmode eq 'Any') { - $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID", - &mt("student name"),&mt("section"),&mt("status"))). - '"'."\n"); + print $CSVfile '"'.join('","',map { + &Apache::loncommon::csv_translate(&mt($_)) + } ("username","domain","ID","student name", + "section","start date","end date","status")).'"'."\n"; } else { - $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID", - &mt("student name"),&mt("section"))).'"'."\n"); + print $CSVfile '"'.join('","',map { + &Apache::loncommon::csv_translate(&mt($_)) + } ("username","domain","ID","student name", + "section","start date","end date")).'"'."\n"; } } elsif ($mode eq 'excel') { # Create the excel spreadsheet @@ -1143,14 +1331,18 @@ END $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'. $excel_filename); $excel_workbook->set_tempdir('/home/httpd/perl/tmp'); + # + $format = &Apache::loncommon::define_excel_formats($excel_workbook); $excel_sheet = $excel_workbook->addworksheet('classlist'); # my $description = 'Class List for '. $ENV{'course.'.$ENV{'request.course.id'}.'.description'}; - $excel_sheet->write($row++,0,$description); + $excel_sheet->write($row++,0,$description,$format->{'h1'}); # $excel_sheet->write($row++,0,["username","domain","ID", - "student name","section","status"]); + "student name","section", + "start date","end date","status"], + $format->{'bold'}); } # # Sort the students @@ -1169,16 +1361,58 @@ END || lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third]) } (keys(%$classlist)); + my $studentcount = 0; + my $autocount = 0; + my $manualcount = 0; + my $unlockcount = 0; + my $lockcount = 0; foreach my $student (@Sorted_Students) { - my $username = $classlist->{$student}->[$index{'username'}]; - my $domain = $classlist->{$student}->[$index{'domain'}]; - my $section = $classlist->{$student}->[$index{'section'}]; - my $name = $classlist->{$student}->[$index{'fullname'}]; - my $id = $classlist->{$student}->[$index{'id'}]; - my $status = $classlist->{$student}->[$index{'status'}]; + my $sdata = $classlist->{$student}; + my $username = $sdata->[$index{'username'}]; + my $domain = $sdata->[$index{'domain'}]; + my $section = $sdata->[$index{'section'}]; + my $name = $sdata->[$index{'fullname'}]; + my $id = $sdata->[$index{'id'}]; + my $status = $sdata->[$index{'status'}]; + my $start = $sdata->[$index{'start'}]; + my $end = $sdata->[$index{'end'}]; + my $type = $sdata->[$index{'type'}]; next if (($statusmode ne 'Any') && ($status ne $statusmode)); - if ($mode eq 'view') { - $r->print("<tr>\n <td>\n "); + if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') { + if (! defined($start) || $start == 0) { + $start = &mt('none'); + } else { + $start = &Apache::lonlocal::locallocaltime($start); + } + if (! defined($end) || $end == 0) { + $end = &mt('none'); + } else { + $end = &Apache::lonlocal::locallocaltime($end); + } + $r->print("<tr>\n "); + if ($mode eq 'autoenroll') { + my $lockedtype = $sdata->[$index{'lockedtype'}]; + $studentcount++; + my $cellentry; + if ($type eq 'auto') { + $cellentry = '<b>'.&mt('auto').'</b> <input type="checkbox" name="chgauto" value="'.$username.':'.$domain.'" /> Change'; + $autocount ++; + } else { + $cellentry = '<table border="0" cellspacing="0"><tr><td rowspan="2"><b>'.&mt('manual').'</b></td><td><nobr><input type="checkbox" name="chgmanual" value="'.$username.':'.$domain.'" /> Change</nobr></td></tr><tr><td><nobr>'; + $manualcount ++; + if ($lockedtype) { + $cellentry .= '<input type="checkbox" name="unlockchg" value="'.$username.':'.$domain.'" /> '.&mt('Unlock'); + $unlockcount ++; + } else { + $cellentry .= '<input type="checkbox" name="lockchg" value="'.$username.':'.$domain.'" /> '.&mt('Lock'); + $lockcount ++; + } + $cellentry .= '</nobr></td></tr></table>'; + } + $r->print("<td>$cellentry<td>\n "); + } else { + $r->print("<td>".(++$studentcount)."</td><td>\n "); + } if ($linkto eq 'nothing') { $r->print($username); } elsif ($linkto eq 'aboutme') { @@ -1200,33 +1434,61 @@ END <td>$id</td> <td>$name</td> <td>$section</td> -</tr> + <td>$start</td> + <td>$end</td> + </tr> END } elsif ($mode eq 'csv') { + next if (! defined($CSVfile)); # no need to bother with $linkto + if (! defined($start) || $start == 0) { + $start = &mt('none'); + } else { + $start = &Apache::lonlocal::locallocaltime($start); + } + if (! defined($end) || $end == 0) { + $end = &mt('none'); + } else { + $end = &Apache::lonlocal::locallocaltime($end); + } my @line = (); - foreach ($username,$domain,$id,$name,$section) { + foreach ($username,$domain,$id,$name,$section,$start,$end) { push @line,&Apache::loncommon::csv_translate($_); } if ($statusmode eq 'Any') { push @line,&Apache::loncommon::csv_translate($status); } - my $tmp = $"; - $" = '","'; - $r->print("\"@line\"\n"); - $" = $tmp; + print $CSVfile '"'.join('","',@line).'"'."\n"; } elsif ($mode eq 'excel') { - $excel_sheet->write($row++,0,[$username,$domain,$id, - $name,$section,$status]); + $excel_sheet->write($row,0,[$username,$domain,$id, + $name,$section]); + my $col = 5; + foreach my $time ($start,$end) { + $excel_sheet->write($row,$col++, + &Apache::lonstathelpers::calc_serial($time), + $format->{'date'}); + } + $excel_sheet->write($row,$col++,$status); + $row++; } } - if ($mode eq 'view') { + if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') { $r->print('</table><br>'); } elsif ($mode eq 'excel') { $excel_workbook->close(); $r->print('<p><a href="'.$excel_filename.'">'. &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n"); + } elsif ($mode eq 'csv') { + close($CSVfile); + $r->print('<a href="'.$CSVfilename.'">'. + &mt('Your CSV file').'</a> is ready for download.'. + "\n"); + $r->rflush(); } + if ($mode eq 'autoenroll') { + return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount); + } + return; } @@ -1261,7 +1523,28 @@ sub print_modify_student_form { $r->print('<p>'.$starttime.'</p>'); return; } + # # Deal with date forms + my $current_date_description = ''; + my $textdate = ''; + + if (! defined($starttime) || $starttime == 0) { + $current_date_description = &mt('Current Starting Date: not set'). + '<br />'; + } else { + $current_date_description = + &mt('Current Starting Date: [_1]', + &Apache::lonlocal::locallocaltime($starttime)).'<br />'; + } + if (! defined($endtime) || $endtime == 0) { + $current_date_description.= &mt('Current Ending Date: not set'). + '<br />'; + } else { + $current_date_description.= + &mt('Current Ending Date: [_1]', + &Apache::lonlocal::locallocaltime($endtime)).'<br />'; + + } my $date_table = &date_setting_table($starttime,$endtime); # if (! exists($ENV{'form.Status'}) || @@ -1294,7 +1577,6 @@ $lt{'odcc'} <input type="hidden" name="state" value="done" /> <input type="hidden" name="sortby" value="$sortby" /> <input type="hidden" name="Status" value="$ENV{'form.Status'}" /> - <h2>$lt{'mef'} $info{'firstname'} $info{'middlename'} $info{'lastname'} $info{'generation'}, $sname\@$sdom</h2> <p> @@ -1313,8 +1595,9 @@ $info{'lastname'} $info{'generation'}, $ <input type="checkbox" name="forceid" > $lt{'disn'} </p><p> -<b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="4"/> +<b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14"/> </p> +<p>$current_date_description</p> <p>$date_table</p> <input type="submit" value="$lt{'sm'}" /> </body></html> @@ -1540,7 +1823,7 @@ sub show_drop_list { ['sortby']); } my $sortby = $ENV{'form.sortby'}; - if ($sortby !~ /^(username|domain|section|fullname|id)$/) { + if ($sortby !~ /^(username|domain|section|fullname|id|start|end)$/) { $sortby = 'username'; } # @@ -1564,13 +1847,14 @@ function uncheckAll(field) { <input type="hidden" name="phase" value="four"> END +my %lt=&Apache::lonlocal::texthash('usrn' => "username", + 'dom' => "domain", + 'sn' => "student name", + 'sec' => "section", + 'start' => "start date", + 'end' => "end date", + ); if ($nosort) { - my %lt=&Apache::lonlocal::texthash( - 'usrn' => "username", - 'dom' => "domain", - 'sn' => "student name", - 'sec' => "section", - ); $r->print(<<END); <table border=2> <tr> @@ -1580,16 +1864,12 @@ END <th>ID</th> <th>$lt{'sn'}</th> <th>$lt{'sec'}</th> + <th>$lt{'start'}</th> + <th>$lt{'end'}</th> </tr> END } else { - my %lt=&Apache::lonlocal::texthash( - 'usrn' => "username", - 'dom' => "domain", - 'sn' => "student name", - 'sec' => "section", - ); $r->print(<<END); <table border=2> <tr><th> </th> @@ -1603,6 +1883,10 @@ END <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a> </th><th> <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a> + </th><th> + <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a> + </th><th> + <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a> </th> </tr> END @@ -1626,12 +1910,25 @@ END } (keys(%$classlist)); foreach my $student (@Sorted_Students) { my $error; - my $username = $classlist->{$student}->[$index{'username'}]; - my $domain = $classlist->{$student}->[$index{'domain'}]; - my $section = $classlist->{$student}->[$index{'section'}]; - my $name = $classlist->{$student}->[$index{'fullname'}]; - my $id = $classlist->{$student}->[$index{'id'}]; - my $status = $classlist->{$student}->[$index{'status'}]; + my $sdata = $classlist->{$student}; + my $username = $sdata->[$index{'username'}]; + my $domain = $sdata->[$index{'domain'}]; + my $section = $sdata->[$index{'section'}]; + my $name = $sdata->[$index{'fullname'}]; + my $id = $sdata->[$index{'id'}]; + my $start = $sdata->[$index{'start'}]; + my $end = $sdata->[$index{'end'}]; + if (! defined($start) || $start == 0) { + $start = &mt('none'); + } else { + $start = &Apache::lonlocal::locallocaltime($start); + } + if (! defined($end) || $end == 0) { + $end = &mt('none'); + } else { + $end = &Apache::lonlocal::locallocaltime($end); + } + my $status = $sdata->[$index{'status'}]; next if ($status ne 'Active'); # $r->print(<<"END"); @@ -1642,11 +1939,13 @@ END <td>$id</td> <td>$name</td> <td>$section</td> + <td>$start</td> + <td>$end</td> </tr> END } $r->print('</table><br>'); - my %lt=&Apache::lonlocal::texthash( + %lt=&Apache::lonlocal::texthash( 'dp' => "Drop Students", 'ca' => "check all", 'ua' => "uncheck all", @@ -1706,6 +2005,24 @@ sub upfile_drop_add { } } # + # Store the field choices away + foreach my $field (qw/username names + fname mname lname gen id sec ipwd email/) { + $ENV{'form.'.$field.'_choice'}=$fields{$field}; + } + &Apache::loncommon::store_course_settings('enrollment_upload', + { 'username_choice' => 'scalar', + 'names_choice' => 'scalar', + 'fname_choice' => 'scalar', + 'mname_choice' => 'scalar', + 'lname_choice' => 'scalar', + 'gen_choice' => 'scalar', + 'id_choice' => 'scalar', + 'sec_choice' => 'scalar', + 'ipwd_choice' => 'scalar', + 'email_choice' => 'scalar' }); + + # my ($startdate,$enddate) = &get_dates_from_form(); if ($ENV{'form.makedatesdefault'}) { $r->print(&make_dates_default($startdate,$enddate)); @@ -1961,30 +2278,50 @@ sub handler { } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['action','state']); + + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/dropadd", + text=>"Enrollment Manager", + faq=>9,bug=>'Instructor Interface',}); # Needs to be in a course - if (! (($ENV{'request.course.fn'}) && - (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'})))) { - # Not in a course, or not allowed to modify parms + if (! ($ENV{'request.course.fn'})) { + # Not in a course $ENV{'user.error.msg'}= "/adm/dropadd:cst:0:0:Cannot drop or add students"; return HTTP_NOT_ACCEPTABLE; } # + my $view_permission = + &Apache::lonnet::allowed('vcl',$ENV{'request.course.id'}); + my $enrl_permission = + &Apache::lonnet::allowed('cst',$ENV{'request.course.id'}); + if (! $view_permission && ! $enrl_permission) { + $ENV{'user.error.msg'}= + "/adm/dropadd:cst:0:0:Cannot drop or add students"; + return HTTP_NOT_ACCEPTABLE; + } + # # Only output the header information if they did not request csv format # - if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) { - $r->content_type('text/csv'); - } else { - # Start page - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - $r->print(&header()); - } + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['state','action']); + # Start page + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; + $r->print(&header()); # # Main switch on form.action and form.state, as appropriate if (! exists($ENV{'form.action'})) { - &print_main_menu($r); - } elsif ($ENV{'form.action'} eq 'upload') { + $r->print(&Apache::lonhtmlcommon::breadcrumbs + (undef,'Enrollment Manager')); + &print_main_menu($r,$enrl_permission,$view_permission); + } elsif ($ENV{'form.action'} eq 'upload' && $enrl_permission) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=upload&state=', + text=>"Upload Classlist"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs + (undef,'Upload Classlist','Course_Create_Class_List')); if (! exists($ENV{'form.state'})) { &print_first_courselist_upload_form($r); } elsif ($ENV{'form.state'} eq 'got_file') { @@ -1998,7 +2335,12 @@ sub handler { } else { &print_first_courselist_upload_form($r); } - } elsif ($ENV{'form.action'} eq 'drop') { + } elsif ($ENV{'form.action'} eq 'drop' && $enrl_permission) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=drop', + text=>"Drop Students"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs + (undef,'Drop Students','Course_Drop_Student')); if (! exists($ENV{'form.state'})) { &print_drop_menu($r); } elsif ($ENV{'form.state'} eq 'done') { @@ -2006,7 +2348,12 @@ sub handler { } else { &print_drop_menu($r); } - } elsif ($ENV{'form.action'} eq 'enrollstudent') { + } elsif ($ENV{'form.action'} eq 'enrollstudent' && $enrl_permission) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=enrollstudent', + text=>"Enroll Student"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs + (undef,'Enroll Student','Course_Add_Student')); if (! exists($ENV{'form.state'})) { &get_student_username_domain_form($r); } elsif ($ENV{'form.state'} eq 'gotusername') { @@ -2016,17 +2363,27 @@ sub handler { } else { &get_student_username_domain_form($r); } - } elsif ($ENV{'form.action'} eq 'classlist') { + } elsif ($ENV{'form.action'} eq 'classlist' && $view_permission) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=classlist', + text=>"View Classlist"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs + (undef,'View Classlist','Course_View_Class_List')); if (! exists($ENV{'form.state'})) { - &print_html_classlist($r); + &print_html_classlist($r,undef); } elsif ($ENV{'form.state'} eq 'csv') { - &print_formatted_classlist($r,'csv'); + &print_html_classlist($r,'csv'); } elsif ($ENV{'form.state'} eq 'excel') { - &print_formatted_classlist($r,'excel'); + &print_html_classlist($r,'excel'); } else { - &print_html_classlist($r); + &print_html_classlist($r,undef); } - } elsif ($ENV{'form.action'} eq 'modifystudent') { + } elsif ($ENV{'form.action'} eq 'modifystudent' && $enrl_permission) { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=modifystudent', + text=>"Modify Student Data"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs + (undef,'Modify Student Data','Course_Modify_Student_Data')); if (! exists($ENV{'form.state'})) { &print_html_classlist($r); } elsif ($ENV{'form.state'} eq 'selected') { @@ -2041,15 +2398,13 @@ sub handler { &Apache::lonnet::logthis("Undetermined state in londropadd.pm. ". "form.action = ".$ENV{'form.action'}. "Someone should fix this."); - &print_main_menu($r); + $r->print(&Apache::lonhtmlcommon::breadcrumbs + (undef,'Enrollment Manager')); + &print_main_menu($r,$enrl_permission,$view_permission); } # # Finish up - if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) { - $r->print("\n"); - } else { - $r->print('</form></body></html>'); - } + $r->print('</form></body></html>'); return OK; }