--- loncom/interface/spreadsheet/classcalc.pm 2003/05/16 20:55:11 1.1 +++ loncom/interface/spreadsheet/classcalc.pm 2003/12/08 19:39:08 1.17 @@ -1,5 +1,5 @@ # -# $Id: classcalc.pm,v 1.1 2003/05/16 20:55:11 matthew Exp $ +# $Id: classcalc.pm,v 1.17 2003/12/08 19:39:08 matthew Exp $ # # Copyright Michigan State University Board of Trustees # @@ -46,42 +46,67 @@ classcalc package Apache::classcalc; use strict; +use warnings FATAL=>'all'; +no warnings 'uninitialized'; use Apache::Constants qw(:common :http); use Apache::loncoursedata(); use Apache::lonhtmlcommon(); use Apache::Spreadsheet; use Apache::studentcalc; +use Apache::lonstatistics(); use HTML::Entities(); use Spreadsheet::WriteExcel; use Apache::lonnet; use Time::HiRes; +use Apache::lonlocal; @Apache::classcalc::ISA = ('Apache::Spreadsheet'); -sub get_classlist { +## +## Package variable +## + +my @Students; + +sub initialize { + &Apache::lonstatistics::clear_classlist_variables(); + @Students = &Apache::lonstatistics::get_students(); + return; +} + +sub clear_package { + undef(@Students); + &Apache::studentcalc::clear_package(); +} + +sub html_header { my $self = shift; - # Retrieve the classlist - my @Students = (); - my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist - ($self->{'cid'},$self->{'cdom'},$self->{'cnum'}); - while (my ($student,$student_data) = each (%$classlist)) { - my $studenthash = (); - for (my $i=0; $i< scalar(@$field_names);$i++) { - my $field = $field_names->[$i]; - $studenthash->{$field}=$student_data->[$i]; - } - # This is where we can skip students because they are in - # the wrong section, have expired or pending roles, whatever... - push (@Students,$studenthash); + my ($toprow,$bottomrow); + &Apache::lonstatistics::clear_classlist_variables(); + foreach (['Sections',&Apache::lonstatistics::SectionSelect('Section','multpile',3)], + ['Enrollment Status',&Apache::lonhtmlcommon::StatusOptions(undef,undef,3)], + ['Output Format',$self->output_selector()]) { + my ($name,$selector) = @{$_}; + $toprow .= '<th align="center"><b>'.&mt($name).'</b></th>'; + $bottomrow .= '<td>'.$selector.'</td>'; } - my @SortedStudents = sort { $a->{'fullname'} cmp $b->{'fullname'} } @Students; - return @SortedStudents; + return "<p>\n<table>\n". + "<tr>".$toprow."</tr>\n". + "<tr>".$bottomrow."</tr>\n". + "</table>\n</p>"; } sub get_title { my $self = shift; - my $title = '<h2>'.$self->{'coursedesc'}."</h2>\n"; # Section info should be included + my @title = ($self->{'coursedesc'}, &Apache::lonlocal::locallocaltime(time) ); + return @title; +} + +sub get_html_title { + my $self = shift; + my ($classcalc_title,$time) = $self->get_title(); + my $title = '<h1>'.$classcalc_title."</h1>\n".'<h3>'.$time."</h3>\n"; return $title; } @@ -92,25 +117,44 @@ sub parent_link { sub outsheet_html { my $self = shift; my ($r) = @_; + #################################### + # Report any calculation errors # + #################################### + $r->print($self->html_report_error()); ################################### # Determine table structure ################################### + my $importcolor = '#88FF88'; + my $exportcolor = '#BBBBFF'; my $num_uneditable = 26; my $num_left = 52-$num_uneditable; + # + my %header=&Apache::lonlocal::texthash( + 'course' => 'Course', + 'import' => 'Import', + 'calculations' => 'Calculations', + 'student' => 'Student', + 'status' => 'Status', + 'username' => 'Username', + 'domain' => 'Domain', + 'section' => 'Section', + 'row' => 'Row', + ); my $tableheader =<<"END"; +<p> <table border="2"> <tr> - <th colspan="2" rowspan="2"><font size="+2">Course</font></th> - <td bgcolor="#FFDDDD" colspan="$num_uneditable"> - <b><font size="+1">Import</font></b></td> + <th colspan="2" rowspan="2"><font size="+2">$header{'course'}</font></th> + <td bgcolor="$importcolor" colspan="$num_uneditable"> + <b><font size="+1">$header{'import'}</font></b></td> <td colspan="$num_left"> - <b><font size="+1">Calculations</font></b></td> + <b><font size="+1">$header{'calculations'}</font></b></td> </tr><tr> END my $label_num = 0; foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){ if ($label_num<$num_uneditable) { - $tableheader.='<th bgcolor="#FFDDDD">'; + $tableheader.='<th bgcolor="'.$importcolor.'">'; } else { $tableheader.='<th>'; } @@ -122,23 +166,28 @@ END $r->print($tableheader); # # Print out template row - $r->print('<tr><td>Template</td><td> </td>'. - $self->html_template_row($num_uneditable)."</tr>\n"); + $r->print('<tr><td>'.&mt('Template').'</td><td> </td>'. + $self->html_template_row($num_uneditable,$importcolor). + "</tr>\n"); # # Print out summary/export row - $r->print('<tr><td>Summary</td><td>0</td>'. - $self->html_export_row()."</tr>\n"); + $r->print('<tr><td>'.&mt('Summary').'</td><td>0</td>'. + $self->html_export_row($exportcolor)."</tr>\n"); # # Prepare to output rows $tableheader =<<"END"; +</p><p> <table border="2"> -<tr><th>Row</th> - <th>student</th><th>username</th><th>domain</th> - <th>section</th><th>status</th> +<tr><th>$header{'row'}</th> + <th>$header{'student'}</th> + <th>$header{'username'}</th> + <th>$header{'domain'}</th> + <th>$header{'section'}</th> + <th>$header{'status'}</th> END foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){ if ($label_num<$num_uneditable) { - $tableheader.='<th bgcolor="#FFDDDD">'; + $tableheader.='<th bgcolor="'.$importcolor.'">'; } else { $tableheader.='<th>'; } @@ -146,7 +195,7 @@ END } # my $num_output = 0; - foreach my $student ($self->get_classlist()) { + foreach my $student (@Students) { if ($num_output++ % 50 == 0) { $r->print("</table>\n".$tableheader); } @@ -156,57 +205,173 @@ END '&sdomain='.$student->{'domain'}.'">'; $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); $r->print('<tr>'.'<td>'.$rownum.'</td>'. - '<td>'.$link.$student->{'fullname'}.'</a></td>'. - '<td>'.$student->{'username'}.'</td>'. + '<td>'.$student->{'fullname'}.'</td>'. + '<td>'.$link.$student->{'username'}.'</a></td>'. '<td>'.$student->{'domain'} .'</td>'. '<td>'.$student->{'section'} .'</td>'. '<td>'.$student->{'status'} .'</td>'. - $self->html_row($num_uneditable,$rownum)."</tr>\n"); + $self->html_row($num_uneditable,$rownum,$exportcolor, + $importcolor). + "</tr>\n"); } - $r->print("</table>\n"); + $r->print("</table></p>\n"); return; } -sub outsheet_csv { +sub excel_rows { + # writes the meat of the spreadsheet to an excel worksheet. Called + # by Spreadsheet::outsheet_excel; my $self = shift; - my ($r) = @_; + my ($connection,$worksheet,$cols_output,$rows_output) = @_; + # + # Write a header row + $cols_output = 0; + foreach my $value ('Fullname','Username','Domain','Section','Status','ID') { + $worksheet->write($rows_output,$cols_output++,&mt($value)); + } + $rows_output++; + # + # Write each students row + foreach my $student (@Students) { + $cols_output = 0; + my $rownum = $self->get_row_number_from_key + ($student->{'username'}.':'.$student->{'domain'}); + $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); + my @studentdata = ($student->{'fullname'}, + $student->{'username'}, + $student->{'domain'}, + $student->{'section'}, + $student->{'status'}, + $student->{'id'}); + $self->excel_output_row($worksheet,$rownum,$rows_output++, + @studentdata); + } + return; } -sub outsheet_excel { +sub csv_rows { + # writes the meat of the spreadsheet to an excel worksheet. Called + # by Spreadsheet::outsheet_excel; my $self = shift; - my ($r) = @_; + my ($connection,$filehandle) = @_; + # + # Write a header row + $self->csv_output_row($filehandle,undef, + (&mt('Fullname'),&mt('Username'),&mt('Domain'),&mt('Section'),&mt('Status'),&mt('ID'))); + # + # Write each students row + foreach my $student (@Students) { + my $rownum = $self->get_row_number_from_key + ($student->{'username'}.':'.$student->{'domain'}); + $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); + my @studentdata = ($student->{'fullname'}, + $student->{'username'}, + $student->{'domain'}, + $student->{'section'}, + $student->{'status'}, + $student->{'id'}); + $self->csv_output_row($filehandle,$rownum,@studentdata); + } + return; +} + +sub output_options { + my $self = shift(); + return ({value => 'htmlclasslist', + description => 'Student Sheet Links'}, + {value => 'html', + description => 'HTML'}, + {value => 'excel', + description => 'Excel'}, + {value => 'csv', + description => 'Comma Separated Values'}, +); } sub outsheet_recursive_excel { my $self = shift; my ($r) = @_; -} +} -sub display { +sub outsheet_htmlclasslist { my $self = shift; my ($r) = @_; - $self->compute($r); - # display as html/csv/excel/etc.... - $self->outsheet_html($r); + # + $r->print('<h3>'. + &mt('Click on a student to be taken to their spreadsheet'). + '</h3>'); + # + my %header=&Apache::lonlocal::texthash( + 'student' => 'Student', + 'status' => 'Status', + 'username' => 'Username', + 'domain' => 'Domain', + 'section' => 'Section', + ); + # + # Prepare to output rows + my $tableheader =<<"END"; +</p><p> +<table border="2"> +<tr> + <th></th> + <th>$header{'student'}</th> + <th>$header{'username'}</th> + <th>$header{'domain'}</th> + <th>$header{'section'}</th> + <th>$header{'status'}</th> +</tr> +END + # + my $num_output = 0; + foreach my $student (@Students) { + if ($num_output++ % 50 == 0) { + $r->print("</table>\n".$tableheader); + } + my $link = '<a href="/adm/studentcalc?sname='.$student->{'username'}. + '&sdomain='.$student->{'domain'}.'">'; + $student->{'section'} = 'none' if ($student->{'section'} eq '-1'); + $r->print('<tr>'. + '<td>'.$num_output.'</td>'. + '<td>'.$link.$student->{'fullname'}.'</a></td>'. + '<td>'.$link.$student->{'username'}.'</a></td>'. + '<td>'.$student->{'domain'} .'</td>'. + '<td>'.$student->{'section'} .'</td>'. + '<td>'.$student->{'status'} .'</td>'. + "</tr>\n"); + } + $r->print("</table></p>\n"); return; } sub compute { my $self = shift; my ($r) = @_; + my $connection = $r->connection(); + if ($connection->aborted()) { $self->cleanup(); return; } $self->initialize_safe_space(); my %c = $self->constants(); my %f = $self->formulas(); - my @Students = $self->get_classlist(); my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin - ($r,'Spreadsheet Computation Status', - 'Spreadsheet Computation', scalar(@Students)); + ($r,&mt('Spreadsheet Computation Status'), + &mt('Spreadsheet Computation'), scalar(@Students)); + &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, + &mt('Processing course structure')); &Apache::studentcalc::initialize_package(); - foreach my $student ($self->get_classlist()) { + &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, + &mt('Processing first student')); + foreach my $student (@Students) { + if ($connection->aborted()) { $self->cleanup(); return; } my $sname = $student->{'username'}.':'.$student->{'domain'}; my $studentsheet = Apache::studentcalc->new ($student->{'username'},$student->{'domain'},undef); - my @exportdata = $studentsheet->export_data(); + if ($connection->aborted()) { $self->cleanup(); return; } + my @exportdata = $studentsheet->export_data($r); + if ($studentsheet->badcalc()) { + $self->set_calcerror($sname.' : '. + $studentsheet->calcerror()); + } + if ($connection->aborted()) { $self->cleanup(); return; } my $rownum = $self->get_row_number_from_key($sname); $f{'A'.$rownum} = $sname; $self->{'row_source'}->{$rownum} = $sname; @@ -227,6 +392,7 @@ sub compute { $self->constants(\%c); $self->formulas(\%f); $self->calcsheet(); + $self->save() if ($self->need_to_save()); } 1;