#! /usr/bin/perl # Copyright 2001-2022 Leslie Richardson # This file is part of Open Admin for Schools. # Open Admin for Schools is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # Outline: Print the report cards for a single grade or homeroom. # Customizations: Note ANY customizations for this school here # along with line numbers and/or markers to find them... my %lex = ('Generate' => 'Generate', 'Main' => 'Main', 'Report Cards' => 'Report Cards', 'Report Card' => 'Report Card', 'Cannot open term file' => 'Cannot open term file', 'View/Download/Print' => 'View/Download/Print', 'View Log File' => 'View Log File', 'Report to Parents' => 'Report to Parents', 'Grade' => 'Grade', 'Teacher(s)' => 'Teacher(s)', 'Evaluation and Comment Key' => 'Evaluation Key', 'Class Average' => 'Class Average', 'Attendance' => 'Attendance', 'Days Open' => 'Days Open', 'Days Enrolled' => 'Days Enrolled', 'Days Absent' => 'Days Absent', 'General Comments' => 'General Comments', 'Term' => 'Term', 'Teacher' => 'Teacher', 'Principal' => 'Principal', 'Please tear off this portion and return it to the school' => 'Please tear off this portion and return it to the school', 'in the report envelope with any comments and your signature' => 'in the report envelope with any comments and your signature', 'Parent/Guardian Signature' => 'Parent/Guardian Signature', 'Student' => 'Student', 'Date' => 'Date', 'Comments' => 'Comments', 'Days per Month Override' => 'Days per Month Override', 'Student Group' => 'Student Group', 'Homeroom' => 'Homeroom', 'Days Open' => 'Days Open', 'Month' => 'Month', 'Continue' => 'Continue', 'Duplicate Evaluation Record' => 'Duplicate Evaluation Record', 'Average' => 'Average', 'No Quality Score' => 'No Quality Score', 'Error' => 'Error', 'Printed' => 'Printed', 'Override Term Days' => 'Override Term Days', 'Font Size' => 'Font Size', 'One Student per File' => 'One Student per File', 'GPA' => 'GPA', 'Current Year GPA' => 'Current Year GPA', 'Phone' => 'Phone', 'Fax' => 'Fax', 'Absent' => 'Absent', 'Late' => 'Late', 'Student Name' => 'Student Name', 'Date of Birth' => 'Date of Birth', 'Teacher Name' => 'Teacher Name', 'Principal' => 'Principal', 'Vice-Principal' => 'Vice-Principal', 'Periods' => 'Periods', 'Evaluation Key' => 'Evaluation Key', 'Select Subjects' => 'Select Subjects', 'For Duplexing/Stapling' => 'For Duplexing/Stapling', 'Show Withdrawn Students' => 'Show Withdrawn Students', 'Please Log In' => 'Please Log In', 'Pre-kindergarten Class' => 'Pre-kindergarten Class', 'Subject' => 'Subject', 'Mark' => 'Mark', 'Printing Date' => 'Printing Date', 'Absent' => 'Absent', 'Late' => 'Late', 'Letter' => 'Letter', 'Legal' => 'Legal', 'A4' => 'A4', 'Paper Size' => 'Paper Size', 'Start Term' => 'Start Term', 'End Term' => 'End Term', 'Blank=All' => 'Blank=All', 'Periods per Day' => 'Periods per Day', 'Rank' => 'Rank', 'Demerits' => 'Demerits', 'Skipping' => 'Skipping', 'Undefined Value' => 'Undefined Value', 'Missing' => 'Missing', 'Value' => 'Value', 'Track' => 'Track', 'Only' => 'Only', 'Not Found' => 'Not Found', 'Picture' => 'Picture', 'Email' => 'Email', 'Address' => 'Address', 'Select' => 'Select', 'Post' => 'Post', 'Complete' => 'Complete', 'OR' => 'OR', 'Form' => 'Form', ); use DBI; use CGI; use CGI::Session; use Cwd; use Number::Format qw(:all); use Carp; use Time::JulianDay; my $deleteTeX = 1; # change to zero to check the generated TeX files. my$showEmailOption = 0; # Non School Day Grades my %nonschoolgrades = ('K' => 1,'PK' => 1,'P3' => 1); # Email Configuration Values my $r_MailServer = 'richtech.ca'; my$r_NoReplyName = 'OpenAdmin Messaging System'; my $r_NoReplyEmail = 'no-reply@yoursite.net'; my$message = "Dear Parents of <\@firstname\@> <\@lastname\@>, Attached is a copy of the report card for <\@firstname\@>. Sincerely, <\@r_Principal\@> <\@schoolname\@> <\@schooladdr1\@> <\@schooladdr2\@> "; # These new config values control whether the subject printing will # have empty cells before or after in situation where the current term # is later, and for a second semester class it will produce blank # cells before the current subject while for a first semester subject # (already done), it will show blanks after. # $r_TermDisplayLeading = 1; # Allows current later starting subjects to display back to start (with blanks) #$r_TermDisplayTrailing = 1; # effectively sets ending display term to current term # Allows completed subjects to extend to current term (with blanks) # ---------------------------- my $self = 'rptrepcard.pl'; # Get current dir so know what path for config files. my$configpath; my $teachermode; if ( getcwd() =~ /tcgi/ ){ # we are in tcgi$teachermode = 1; $configpath = '..'; # go back one to get to etc. } else {$configpath = '../..'; # go back two to get to etc. } # main config file eval require "$configpath/etc/admin.conf"; if ($@ ) { print $lex{Error}. ":$@
\n"; die $lex{Error}. ":$@\n"; } my $schoolmode; if ($g_BritishSchoolMode ) { $schoolmode = 1; # will there be a mode 2? } my$dsn = "DBI:$dbtype:dbname=$dbase"; $dbh = DBI->connect($dsn,$user,$password); $dbh->{mysql_enable_utf8} = 1; # populate jdclosed with dates from dates table; used by calcTermDays; my %jdclosed; my$sth = $dbh->prepare("select date, dayfraction from dates where date is not NULL and date != ''");$sth->execute; if ($DBI::errstr) { print$DBI::errstr; die $DBI::errstr; } while ( my ($date, $dayfraction ) =$sth->fetchrow ) { my $jd = julian_day( split( '-',$date ) ); $jdclosed{$jd} = $dayfraction; } # load report card configuration my$sth = $dbh->prepare("select id, datavalue from conf_system where filename = 'repcard' order by dataname");$sth->execute; if ( $DBI::errstr ) { print$DBI::errstr; die $DBI::errstr; } while ( my ($id, $datavalue) =$sth->fetchrow ) { eval $datavalue; if ($@ ) { print "$lex{Error}:$@
\n"; die "$lex{Error}:$@\n"; } } # LaTeX filter function eval require "$configpath/lib/liblatex.pl"; if ($@ ) { print $lex{Error}. ":$@
\n"; die $lex{Error}. ":$@\n"; } # Filter any r_NoteX found. (only done once here.) foreach my $note ($r_Note1, $r_Note2,$r_Note3, $r_Note4 ){ if ( defined$note ) { ($note) = latex_filter($note); } } # attendance library functions eval require "$configpath/lib/libattend.pl"; if ($@ ) { print $lex{Error}. ":$@
\n"; die $lex{Error}. ":$@\n"; } # Get current dir so know what CSS to display and shift to teacher settings. if ( getcwd() =~ /tcgi/ ) { # we are in tcgi $css =$tchcss; $homepage =$tchpage; $downloaddir =$tchdownloaddir; $webdownloaddir =$tchwebdownloaddir; $reppage =$tchpage; } my $q = new CGI; my %arr =$q->Vars; print $q->header( -charset,$charset ); #foreach my $key ( sort keys %arr ) { # print qq{ K:$key VAL:$arr{$key}
\n}; #} if ( not $r_TeacherModeOverride and$teachermode ) { # not allowed to print from teacher site print qq{
}; print qq{$lex{Teacher}$lex{'Report Card'} printing not enabled
\n}; print qq{\n}; exit; } # Set Date my ( $currsdate,$currdate); if ( not $arr{date} ) { my ($sec, $min,$hour, $mday,$mon, $year,$wday, $yday,$iddst) = localtime(time); $year =$year + 1900; $mon++;$wday++; if ( length($mon) == 1 ) {$mon = '0'. $mon; } if ( length($mday) == 1 ) { $mday = '0'.$mday; } $currsdate = "$year-$mon-$mday"; $currdate = "$dow[$wday],$month[$mon]$mday, $year"; } else { # we have a passed value; my ($yr, $mo,$da ) = split('-', $arr{date}); if ( length($mo) == 1 ) { $mo = '0'.$mo; } if ( length($da) == 1 ) {$da = '0'. $da; }$currsdate = "$yr-$mo-$da";$currdate = "$month[$mo] $da,$yr"; } # Print HTML Page Header my $title = "$lex{Generate} $lex{'Report Cards'}"; print qq{$doctype\n$title\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; print qq{$chartype\n\n}; print qq{[ $lex{Main} | \n}; if ( not$teachermode ) { print qq{$lex{'Report Card'} ]\n}; } print qq{ #$title

### Missing Track

\n}; print qq{\n}; exit; } =head #extract the subjec's, if any ( in TEACHER mode ); foreach my $key (sort keys %arr ) { if ($arr{$key} == -1 ) { #print "K:$key V:$arr{$key}
\n"; push @subjects, $key; delete$arr{$key}; } } my %subjects; my$sth = $dbh->prepare("select sequence, description from subject where subjsec = ?"); foreach my$subjsec ( @subjects ) { $sth->execute($subjsec ); if ( $DBI::errstr ) { print$DBI::errstr; die $DBI::errstr; } my ($sequence, $description ) =$sth->fetchrow; $subjects{"$sequence$description"} =$subjsec; } =cut # Show withdrawn students, as well, if they have data. if ( $showwithdrawn ) {$studenttable = 'studentall'; } else { $studenttable = 'student'; } =head # Get %students, to match @subjects; none in normal mode; key will provide sort order my$sth = $dbh->prepare("select distinct e.studnum, s.lastname, s.firstname from eval as e,$studenttable as s where s.studnum = e.studnum and subjcode = ?"); foreach my $subjsec ( @subjects ) { # find the students for this, if any (not normally)$sth->execute( $subjsec ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } while ( my ( $studnum,$lastname, $firstname ) =$sth->fetchrow ) { $students{"$lastname$firstname$studnum"} = $studnum; #print "$firstname $lastname ($studnum)
\n"; } } #foreach my $key (sort keys %students ) { print "K:$key V:$students{$key}
\n"; } =cut # Get a grade in order to get correct PPD (Periods per day that attendance is done). my $periodsperday; if ($group eq 'homeroom' ) { # Get the grade for this class my $sth =$dbh->prepare("select distinct grade from student where homeroom = ?"); $sth->execute($groupid ); if ($DBI::errstr) { print$DBI::errstr; die $DBI::errstr; } while ( my$gr = $sth->fetchrow ) { my$tempppd = $g_ppd{$gr}; if ( $tempppd >$periodsperday ) { $periodsperday =$tempppd; } } } else { $periodsperday =$g_ppd{$groupid}; } if ( not$periodsperday and not $teachermode ) { print qq{ ###$lex{Grade}:$grade Periods Per Day:$g_ppd{$grade}\n}; print qq{No grade found or Periods per day not set in configuration \n}; exit; } my %homeroomTeachers; # homeroomTeachers{homeroom} = @names. if ($r_ShowHomeroomTeacher ) { # set in repcard.conf # Get all homeroom userid values..... my %rooms; my $sth1 =$dbh->prepare("select sal, firstname, lastname from staff where userid = ?"); my $sth =$dbh->prepare("select id, userid, field_value from staff_multi where field_name = 'homeroom'"); $sth->execute; if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } while ( my ($id,$userid, $hr) =$sth->fetchrow ) { if ( not $userid or not$hr ) { next; } # just in case.... $rooms{$hr}{$userid} = 1; } foreach my$hr ( keys %rooms ) { my @tch; foreach my $userid ( keys %{$rooms{$hr} } ) { # Get Name$sth1->execute( $userid ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } my ($sal,$firstname, $lastname ) =$sth1->fetchrow; push @tch, "$sal$firstname $lastname"; } if ( @tch ) {$homeroomTeachers{$hr} = \@tch; } } } # end of ShowHomeroomTeacher #foreach my$hr ( sort keys %homeroomTeachers ) { # print qq{HR:$hr TCH:}, @{$homeroomTeachers{$hr}}, " \n"; #} # CLASS AVERAGE # Calculate the class averages for all subjects in the current term. # Easier than doing this just for subjects in current grade, since they # may take subjects from another grade level, etc. # Only do this if$r_classavg in repcard.conf is 1; my %classavg; if ( $r_ClassAvg ){ # create %classavg - class average hash. # First Find all courses done this term. (actually a subjsec field)$sth = $dbh->prepare("select distinct subjcode from eval where term = '$endterm' and subjcode is not NULL and subjcode != '' order by subjcode desc"); $sth->execute; if ($DBI::errstr) {print $DBI::errstr; die$DBI::errstr;} my $sth1 =$dbh->prepare("select id, $r_MarkField from eval where term = '$endterm' and subjcode = ?"); # Loop through each subjsec (subject-section) while ( my $subjsec =$sth->fetchrow ) { # print "Subjsec:$subjsec \n";$sth1->execute( $subjsec ); if ($DBI::errstr) {print $DBI::errstr; die$DBI::errstr;} my $totalmark = 0; my$totalcount++; while ( my ($id,$mark) = $sth1->fetchrow ){ # print "ID:$id Mark:$mark \n";$mark =~ s/\%//; # strip any percent signs. if ( $mark =~ m/\d+/ ) { # if we have digits...$totalmark += $mark;$totalcount++; } } my $average; if ($totalcount ) { $average = format_number($totalmark / $totalcount,$r_AveragePrecision ); } else { $average = 0; }$classavg{$subjsec} =$average; } } # End of Class Average Calculations (creates %classavg) # print "Class Average
\n"; # foreach my $key ( sort keys %classavg ) { print "K:$key V:$classavg{$key}
\n"; } =head # Calculate number of days in the terms for my $trm ($starterm..$endterm ) { my$val = calcTermDays($g_MTrackTerm{$track}{$trm}{'start'},$g_MTrackTerm{$track}{$trm}{'end'}, \%jdclosed ); my ($open,$closed) = split(':', $val);$termdays{$trm} =$open; } =cut # Format: key: year-month value: days # The $homeroom value will trigger the function to look for non school days for early grades. my$nsdhomeroom; if ( $nsdflag ) {$nsdhomeroom = $groupid; # groupid IS a homeroom if nsdflag is set. } # IF nsdhomeroom is passed, then mkSchoolDays will also look for those days closed also. my %schooldays = mkSchoolDays($schoolstart, $currsdate,$dbh, $nsdhomeroom ); if ($override ){ # we are overriding days per month... foreach my $key ( sort keys %arr ) { # %arr now contains all the months of interest. if ($key eq 'date' or $key eq 'papersize' ) { next; }$schooldaysorig{$key} =$schooldays{$key};$schooldays{$key} =$arr{$key}; } } # print qq{School Days Hash \n}; # foreach my$key ( keys %schooldays ) { print "K: $key Val:$schooldays{$key} \n"; } my ($tempdir, $shortname,$filename); if ( not $oneStudentPerFile ) {$shortname = "repcard$$"; filename = "shortname.tex"; open( TEX,">filename" ) || die "Can't open tex file\n"; prTexDocStart(); # print document preamble. } else { # we are doing one student per file; create temporary folder. tempdir = "tempdir$$"; system("mkdir $tempdir"); open( LOG,">pdflog$$.txt" ) || die "Can't open LOG file\n"; } # Get Students my sth = dbh->prepare("select studnum, lastname, firstname, homeroom from studenttable where group = ? order by homeroom, lastname, firstname"); sth->execute( groupid ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } while ( my ( studnum, lastname, firstname, homeroom ) = sth->fetchrow ) { students{"homeroomlastnamefirstnamestudnum"} = studnum; } # Calculate Term Average for student and Ranking my termavg_ref; if ( r_ShowTermAverage or r_ShowRanking or r_ShowGradeCategory ) { # Other functions depend on this hash_ref. my sth = dbh->prepare("select id, r_MarkField from eval where term = ? and studnum = ?"); # termavg_ref->{term}->{studnum} = average. foreach my key ( sort keys %students ) { my studnum = students{key}; foreach my trm ( startterm .. endterm ) { my ( markcount, marktotal ); sth->execute( trm, studnum ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } while ( my ( ignore, mark ) = sth->fetchrow ) { if ( mark =~ m/[.0-9]+/ ) { # is a number markcount++; marktotal += mark; } } my avg; if ( markcount ) { avg = marktotal / markcount; } else { avg = 0; } termavg_ref->{trm}->{studnum} = avg; } } } # Print Out termavg double hash. # foreach my key ( sort keys %termavg_ref ) { # print " K:key Ref:$$termavg_ref{$key}
\n"; # foreach my $key1 ( sort keys %{ $$termavg_ref{key} } ) { # print "Key:key1 Val:$$termavg_ref{$key}->{$key1} \n"; # } # } # end of TermAvg calc; not showing these values until later in table. my$rank_ref; if ( $r_ShowRanking ) { # Now create ranking hash for each term. foreach my$trm ( $startterm ..$endterm ) { my $prevavg = -1; my$rank = 1; my $count = 1; my %average = %{ $$termavg_ref{trm} }; # setup hash to do. foreach my studnum ( sort { average{b} <=> average{a} } keys %average ) { if ( average{studnum} != prevavg ) { # normal operation. rank_ref->{trm}->{studnum} = count; #rank{studnum} = count; prevavg = average{studnum}; rank = count; } else { # if the average is same as previous... rank_ref->{trm}->{studnum} = rank; #rank{studnum} = rank; } #print "Count: count Term:trm Student:studnum Average:average{studnum}"; #print " Rank: rank_ref->{trm}->{studnum} \n"; count++; } } # end of %rank creation. } # end of Ranking section. my sth = dbh->prepare("select lastname, firstname, initial, grade, homeroom, birthdate, provnum from studenttable where studnum = ?"); # Loop through all students, one report card each. foreach my key ( sort keys %students ) { my studnum = students{key}; # Get Student Info sth->execute( studnum ); my ( lastname, firstname, middlename, grade, homeroom, birthdate, provnum ) = sth->fetchrow; if ( r_SkipBlankReportCard ) { # Check that she/he actually has some info in database. my sth1 = dbh->prepare("select count(*) from eval where term >= ? and term <= ? and studnum = ?"); # and a1 != '' sth1->execute( startterm, endterm, studnum ); if (DBI::errstr) {print DBI::errstr; die DBI::errstr; } my evcount = sth1->fetchrow; if ( not evcount ) { next; } # skip kids with blank values for terms } if ( oneStudentPerFile ) { # Create this student's filename my (lname, fname); fname = firstname; lname = lastname; fname =~ s/\W|\-//g; # remove 'nonword' characters lname =~ s/\W|\-//g; if ( length(lname) > 12 ) { lname = substr lname, 0, 12; } if ( length(fname) > 8 ) { fname = substr fname, 0, 8; } #print "LN: lname FN: fname \n"; shortname = "lnamefname-studnum"; filename = "shortname.tex"; open( TEX,">filename" ) || die "Can't open tex file"; prTexDocStart(); # print document preamble. } # Print the heading section for each new report card prTexHead( grade, lastname, firstname, middlename, birthdate, provnum, studnum ); # print a Note 1 - if set in repcard.conf if ( r_Note1 ) { print TEX "\\fbox{\\parbox[b]{\\textwidth}{ "; print TEX "\\begin{center}{\\it r_Note1}\\end{center} }}\n\n"; } # print homeroom teachers for this student (if any). if ( r_ShowHomeroomTeacher and homeroomTeachers{homeroom} ) { # set in repcard.conf prHomeroomTeachers( homeroom, @{ homeroomTeachers{homeroom}} ); } # put in rule divider print TEX "\\hrulefill \n\\smallskip\n\n"; # Attendance 1 - print block if ( r_ShowMonthlyAttendance == 1 ) { prMonthlyAttendance( studnum ); } if ( r_ShowGradeScheme ) { # set in repcard.conf print_grade_scheme( grade ); } # End of head section for each new report card. if ( r_ShowMonthlyAttendance == 2 ) { prMonthlyAttendance( studnum ); } # print a Note 2 - if set in repcard.conf if ( r_Note2 ) { print TEX "\\begin{center}{\\it r_Note2}\\end{center}\n\n"; } my %mycourses; # Find eval records for this student # my sth1 = dbh->prepare("select distinct e.subjcode, s.sequence, # s.startrptperiod from eval as e, subject as s where # e.studnum = ? and e.subjcode = s.subjsec order by s.sequence"); my sth2 = dbh->prepare("select sequence from subject where subjsec = ?"); # Get Subjects for this student in this term range. my sth1 = dbh->prepare("select distinct subjcode from eval where studnum = ? and term >= startterm and term <= endterm"); sth1->execute( studnum ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } while ( my subjsec = sth1->fetchrow ) { # skip if member of %r_SupressSubject or %r_AdditionalComments my (tsubjcode, dud) = split('-', subjsec ); if ( r_SupressSubject{tsubjcode} or r_SupressSubject{subjsec} or r_AdditionalComments{tsubjcode} or r_AdditionalComments{subjsec} ) { next; } sth2->execute( subjsec ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } my seq = sth2->fetchrow; while ( length( seq ) < 4 ) { # pad with leading zeros seq = '0'. seq; } mycourses{"seqsubjsec"} = subjsec; } # print "SN: studnum SUB:", %mycourses, " \n"; my firstsubjectflag = 1; # mark if still at first subject # Initialize the GPA hash. my %gpa; my biggestterm; # track largest term values in subjects if ( r_CenterSubjects ) { print TEX "\\begin{center}\n"; } my sth1 = dbh->prepare("select * from subject where subjsec = ?"); # Now Loop through all courses of this student foreach my key ( sort keys %mycourses ) { my subjsec = mycourses{ key }; # req'd since mycourses for sorting only # Get this subject's info... sth1->execute( subjsec ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } my subjref = sth1->fetchrow_hashref; my %s = %subjref; # my sequence = subjref->{sequence}; # my startrptperiod = subjref->{startrptperiod}; # my endrptperiod = subjref->{endrptperiod}; # my subjcode = subjref->{subjcode}; #=== Various Skip Reasons # skip if this subject hasn't started yet. if ( s{startrptperiod} > endterm ) { next; } # skip if all done. if ( startterm > s{endrptperiod} ) { next; } my @objdesc; # objective descriptions my objectivecount; for my i ( 1 .. 20 ) { my fieldname = 'q'. i; if ( s{fieldname} ) { objdesc[i] = s{fieldname}; objectivecount = i; } } if ( not @objdesc ) { # no objectives, put in 1 for mark; objdesc = lex{Mark}; objectivecount = 1; } # Start setting up eval data structure: array of arrays. my @eval; # Sets first column with description of objectives ( by q1, q2, etc) eval = [ @objdesc ]; # Testing: foreach my desc ( @{ eval } ) { print "desc \n"; } # Do Any Leading Blanks here. =head if ( r_TermDisplayLeading ) { # pad front of subject my leadidx = startterm; # startterm is passed starting term to print. while ( leadidx < s{startrptperiod} ) { # startrptperiod is from subject record. my @temp = (); temp[ #objdesc ] = ''; # dimension that thar array. push @eval, [ @temp ]; leadidx++; } } =cut # Now pull in the records for this subject for this student # Pull in full records sth2 = dbh->prepare("select * from eval where studnum = ? and subjcode = ? order by eval.term"); sth2->execute( studnum, subjsec ) ; if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } # read eval records for each term of this subject. my currtrm = 0; my prevtrm; # for error checking for redundant records below. my lastterm; # last term value in @eval; used for trailing blank cells. while ( my evalref = sth2->fetchrow_hashref ){ # load temp eval record my evalterm = lastterm = evalref->{term}; if ( evalterm > endterm or evalterm < startterm ) { next; } # not there yet, or skipping earlier. # Set values into GPA Hash if ( defined evalref->{r_MarkField} ) { # markfield comes from repcard.conf gpa{subjsec}[evalterm] = evalref->{r_MarkField}; } # Check for largest term ( so know how many gpa calcs to do). if ( evalterm > biggestterm ) { biggestterm = evalterm; } # Error Checking for any mistakes in eval records prevtrm = currtrm; currtrm = evalterm; if ( currtrm == prevtrm){ # Error! two eval records with the same term value. print lex{'Duplicate Evaluation Record'}. ":\n"; print "lex{Student}: studnum - lex{Subject}:"; print "subjnum - lex{Term}:currtrm.\n"; print "Contact Les Richardson\n"; } # use array slice to put in eval record fields with possible values my @temp = (); push @temp, evalterm; for my i ( 1 .. objectivecount ) { fieldname = 'a'. i; push @temp, evalref->{fieldname}; } push @eval, [ @temp ]; } # Done stuffing eval recs into eval array (with reference). if ( r_TermDisplayTrailing ) { # pad end of course, if necessary. my trailidx = lastterm; # lastterm is last term in @eval while ( trailidx < s{endrptperiod} ) { # was endterm my @temp = (); temp[ #objdesc ] = ''; # dimension that thar array. push @eval, [ @temp ]; trailidx++; } } prCourse( subjsec, studnum, currterm, startterm, endterm, \@eval ); # print course; prComment( subjsec, studnum, startterm, endterm ); # print the comments (all) } # End of this course; loop to print the next. # Now do the GPA row... if ( r_CalcGPA ) { calcGPA(\%gpa, biggestterm ); print TEX "\\smallskip\n\n"; } # Now show the Ranking / Demerits / Term Average / Grade Category if ( r_ShowRanking or r_ShowTermAverage or r_ShowDemerits or r_ShowGradeCategory ) { showRankDemAvgBlock( studnum, grade ); print TEX "\\smallskip\n\n"; } # End Subject Centering, if turned on. if ( r_CenterSubjects ) { print TEX "\\end{center}\n"; } # Start a new page for attendance, etc. if ( r_NewPageBeforeAttendance ) { print TEX "\\newpage\n"; } # Attendance - print block if ( r_ShowMonthlyAttendance == 3) { prMonthlyAttendance( studnum ); } if ( teachermode ) { print TEX "\\vspace{10mm}\n\n"; } else { print TEX "\n\n"; # to push over additional comments. } if ( r_ShowAdditionalComments ) { prAddComments( studnum, startterm, endterm ); # Additional comments } if ( r_ShowMonthlyAttendance == 4 ) { prMonthlyAttendance( studnum ); } if ( r_Note3 ) { print TEX "\\fbox{\\parbox[b]{\\textwidth}{ "; print TEX "\\begin{center}{\\it r_Note3}\\end{center} }}\n"; print TEX "\\vspace{6mm}\n\n"; } # Now finish off the report card; last term gets the promotion format. # There are 3 signature fns: Teacher, Principal, or Combo. Pick your mix. # Placement Text block my blockFlag; # indicates if a placement block is used with this grade level if ( r_PlacementTex{ "r_PlacementIndex{ grade }" } ) { blockFlag = 1; } if ( endterm != r_FinalTerm{grade} or not blockFlag ){ # not final term or no Placement Block ( even IF final term) # Also... if no teachersign value, then not shown... if ( r_TeacherSign eq 'teacher' ){ prTeacherSig(); #Teacher Signature } elsif ( r_TeacherSign eq 'principal' ){ prPrincipalSig(); #Principal Signature } elsif ( r_TeacherSign eq 'combo' ) { prComboSig(); # Combination Signature (both teacher / principal side by side.) } # print if we have a showTearoff (or not updated) if ( r_ShowTearoff ){ if ( r_PrintParentSig ) { # block them together tearoffblock = 1; } prTearoff(); # print a signature line for parents on tear off line. if ( r_PrintParentSig ) { prParentSig( currdate, lastname, firstname, middlename ); # Parent Signature } elsif ( tearoffblock ) { # close off the parbox print TEX "} \n "; } } } else { # we're in the last term; print graduation box, if set... if ( r_PrintYearEnd ) { prYearEnd("firstname middlename lastname", grade); } } if ( r_Note4 ) { print TEX "\\fbox{\\parbox[b]{\\textwidth}{ "; print TEX "\\begin{center}{\\it r_Note4}\\end{center} }}\n\n"; } # End Section for this student. if ( oneStudentPerFile ) { # build pdf and put into tempdir; append to pdflog$$.txt #print TEX "\\end{center}\n"; print TEX "\\end{document}\n"; close TEX; print LOG "\n\n$firstname $lastname ($studnum)\n-----------------\n"; system("$pdflatex$filename >>pdflog$$.txt"); system("mv shortname.pdf tempdir"); system("rm -f shortname.*"); } else { print TEX "\\newpage\n"; # new page for next student. } } # End of Main Loop; Back to Next Student. # Final section # Done report card, now setup the web page. if ( emailRepcard ) { selectEmailAddress( tempdir ); # this will then cause skip to final email post function. } elsif ( oneStudentPerFile ) { # create single zip and copy all zip to webdownload dir; pdflog$$.txt too. $shortname = "repcard$$"; system("zip shortname.zip tempdir/* >> pdflog$$.txt"); system("mv$shortname.zip $downloaddir"); system("mv pdflog$$.txt downloaddir"); system("rm -r tempdir"); print qq{\n}; print qq{ # [ \n}; print qq{lex{'View/Download/Print'} lex{'Report Cards'} ] \n}; print qq{ \n}; } else { # all in one. # Print ending of report print TEX "\\end{document}\n"; close TEX; system("pdflatex filename >pdflog$$.txt"); system("mv$shortname.pdf $downloaddir"); system("mv pdflog$$.txt downloaddir"); if ( deleteTeX ) { # set at top system("rm -f shortname.*"); } print qq{\n}; print qq{ # [ \n}; print qq{lex{'View/Download/Print'} lex{'Report Cards'} ] \n}; } print qq{[ lex{'View Log File'} ]\n}; print qq{\n}; # ====== End of Main Section ================ #---------------- sub showStartPage { #---------------- my ( @subjects, %subjdesc ); if ( teachermode ) { # we are running on teacher site # Get their subjects my sth = dbh->prepare("select subjsec, description from subject where teacher = ? order by sequence, description "); sth->execute( userid ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } while ( my ( subjsec, description ) = sth->fetchrow ) { push @subjects, subjsec; subjdesc{ subjsec } = description; } } # Get School Months for Override my %schoolmonths = mkSchoolDays( schoolstart, currsdate, dbh ); # Format: yyyy-mm; first record is blank (zeroth) # Form Start print qq{ \n}; print qq{\n}; # Get the grades my @grades; my sth = dbh->prepare("select distinct grade from student where grade is not NULL and grade != ''"); sth->execute; if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } while ( my gr = sth->fetchrow ) { push @grades, gr; } # Get the homerooms. my @homerooms; my sth = dbh->prepare("select distinct homeroom from student where homeroom is not NULL and homeroom != ''"); sth->execute; if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } while ( my hr = sth->fetchrow ) { push @homerooms, hr; # removed checking below } # Start Table. print qq{\n}; # Grades print qq{}; print qq{\n}; print qq{\n}; # Homeroom print qq{}; print qq{\n}; print qq{\n}; # Printing Date print qq{\n\n}; # Terms (to use to get courses during those term blocks). print qq{\n\n}; print qq{\n\n}; # Paper Size defaultpapersize =~ s/paper//; # strip out word paper so lex works; from admin.conf my defpaper = ucfirst( defaultpapersize ); print qq{\n}; print qq{\n} ; # Font Size print qq{\n\n}; if ( teachermode ) { print qq{\n}; foreach my subjsec ( @subjects ) { print qq{\n}; print qq{\n}; } } # Withdrawn Students print qq{\n\n}; # One Student per File print qq{\n}; print qq{\n}; # Enable/Disable the email report card option from top of script. if ( showEmailOption ) { # Email report card. print qq{\n}; print qq{\n}; print qq{\n}; print qq{\n}; } print qq{\n}; # Spacer print qq{\n}; # Override for Days open in month print qq{}; print qq{\n}; # Inner Table print qq{\n}; # End of Inner Table print qq{\n}; print qq{ lex{Grade}}; if ( schoolmode == 1 ) { print qq{/lex{Form}}; } print qq{ lex{OR} lex{Homeroom} lex{'Printing Date'}}; print qq{\n}; print qq{\n}; print qq{ lex{'Start Term'}}; print qq{ lex{'End Term'}}; print qq{ lex{'Paper Size'} lex{'Font Size'}}; print qq{ lex{'Select Subjects'} }; print qq{subjdesc{subjsec} (subjsec) lex{'Show Withdrawn Students'}}; print qq{ lex{'One Student per File'}}; print qq{lex{'For Duplexing/Stapling'} lex{Email} lex{'Report Card'} Check All Email Addresses lex{'Override Term Days'} \n}; print qq{\n}; print qq{\n}; print qq{\n}; for my ym ( sort keys %schoolmonths ) { # keys are yyyy-mm format my (y,m) = split('-', ym); print qq{}; print qq{\n}; } print qq{ lex{'Days per Month Override'} lex{Month}lex{'Days Open'} month[m] (ym) \n}; print qq{\n}; print qq{\n}; exit; } # end of showStartPage #---------------- sub prTexDocStart { #---------------- # Preamble and Head of Document # papersize, textwidth and textheight set at top of script. print TEX <<"EOS1"; \\documentclass[ fontsize, papersize, oneside]{article} \\usepackage{array,graphicx,multicol,colortbl,inputenc,fancyhdr} a_latex_header \\renewcommand{\\familydefault}{\\sfdefault} \\setlength{\\hoffset}{ r_HOffset } \\setlength{\\voffset}{ r_VOffset } \\setlength{\\headsep}{10pt} \\setlength{\\headheight}{14pt} \\setlength{\\topmargin}{0in} \\setlength{\\textwidth}{ textwidth } \\setlength{\\textheight}{ textheight } \\setlength{\\parindent}{0pt} \\setlength{\\evensidemargin}{0in} \\setlength{\\oddsidemargin}{0in} \\setlength{\\extrarowheight}{4pt} \\pagestyle{headings} \\newcolumntype{G}{>{\\columncolor[gray]{ r_GrayScale }}p{r_SubjSpace}} \\pagestyle{fancy} \\lhead{schoolname -- schoolyear} \\rfoot{ lex{Printed}: currdate } \\cfoot{ } \\begin{document} EOS1 } #---------------------- sub showRankDemAvgBlock { #---------------------- my (studnum, grade) = @_; print TEX "\\bigskip\n"; # Start TeX head print TEX "\\begin{tabular}{|p{r_SubjSpace}|"; for ( startterm .. endterm ){ print TEX "p{r_MarkSpace}|"; } print TEX "}\\hline\n"; my track = g_MTrackTermType{ grade }; # Do Header print TEX "\\rowcolor[gray]{ r_GrayScale }"; foreach my term ( startterm .. endterm ) { #loop through all terms my title; if ( g_TermDisplay{track}{term} ) { title = g_TermDisplay{track}{term}; } else { title = term; } print TEX "& \\hfil title \\hfil"; } print TEX "\\\\ \\hline\n"; # Do Average if ( r_ShowTermAverage ) { #print TEX "\\rowcolor[gray]{ r_GrayScale }"; print TEX "\\bf ". lex{Average}; # Loop through each term displaying the average foreach my term ( startterm .. endterm ) { #loop through all terms my average = format_number( termavg_ref->{term}->{studnum} , r_AveragePrecision ); print TEX "&\\hfil average \\hfil "; # change to GPA value... } # End of terms loop print TEX "\\\\ \\hline\n"; } # Do Rank if ( r_ShowRanking ) { #print TEX "\\rowcolor[gray]{ r_GrayScale }"; print TEX "\\bf ". lex{Rank}; # Loop through each term displaying the average foreach my term ( startterm .. endterm ) { #loop through all terms my rank = rank_ref->{term}->{studnum}; print TEX "&\\hfil rank \\hfil "; # change to GPA value... } # End of terms loop print TEX "\\\\ \\hline\n"; } # Do Grade Category if ( r_ShowGradeCategory ) { #print TEX "\\rowcolor[gray]{ r_GrayScale }"; print TEX "\\bf ". lex{Grade}; # really Grade Category foreach my term ( startterm .. endterm ) { #loop through all terms my gradecategory = calcGradeCategory( studnum, term ); print TEX "&\\hfil gradecategory \\hfil "; } # End of terms loop print TEX "\\\\ \\hline\n"; } # end of showGradeCategory # Do Demerits if ( r_ShowDemerits ) { #print TEX "\\rowcolor[gray]{ r_GrayScale }"; print TEX "\\bf ". lex{Demerits}; foreach my term ( startterm .. endterm ) { #loop through all terms my start = g_MTrackTerm{track}{term}{'start'}; my end = g_MTrackTerm{track}{term}{'end'}; my sth = dbh->prepare("select sum( demerit ) from disc_ident i, disc_event e where e.id = i.eventid and studnum = ? and to_days(e.date) >= to_days('start') and to_days(e.date) <= to_days('end') "); sth->execute( studnum ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } my demerits = sth->fetchrow; if ( not demerits ) { demerits = '0'; } print TEX "&\\hfil demerits \\hfil "; # change to GPA value... } # End of terms loop print TEX "\\\\ \\hline\n"; } # end of showDemerits; print TEX "\\end{tabular}\n\n"; } # end of showRankDemAvgBlock #-------------------- sub calcGradeCategory { #-------------------- my ( studnum, term ) = @_; # Now in configuration system. # my %r_GCDisplay = ( '1' => 'I', '2' => 'II', '3' => 'III', '4' => 'P', '5' => 'U' ); my %dud; # just need a blank hash. # Find if any marks below a fail value; don't count blanks. my failmark = 55; my sth = dbh->prepare("select count(*) from eval where studnum = ? and term = ? and r_MarkField is not null and r_MarkField != '' and r_MarkField < failmark "); sth->execute( studnum, term ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } my failcount = sth->fetchrow; my sth1 = dbh->prepare("select lastname, firstname from studentall where studnum = ?"); if ( failcount ) { # display the values # Get Name sth1->execute( studnum ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } my (lastname, firstname) = sth1->fetchrow; # Display Courses and Marks my sth = dbh->prepare("select subjcode, r_MarkField from eval where studnum = ? and term = ?"); sth->execute( studnum, term ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } print qq{ #### FAILURE for firstname lastname \n}; while ( my (subjcode, mark ) = sth->fetchrow ) { print " SN:studnum TERM:term COURSE:subjcode MARK:mark \n"; } } # Level 1 my avg1 = calcTopAverage( studnum, term ); # my %names = ('English' => '1' ); # my count2 = calcTopCount( studnum, term, 70, \%names,1 ); # my count3 = calcTopCount( studnum, term, 55, \%dud, 1 ); # print "Studnum:studnum Level:1 A1:avg1 C2:count2 C3:count3 \n"; if ( avg1 >= 85 and not failcount ) { # and count2 >= 5 and count3 >= 7 ) { # print "Level 1 Return \n"; return r_GCDisplay{1}; } # Level 2 avg1 = calcTopAverage( studnum, term ); # count2 = calcTopCount( studnum, term, 70,\%dud,1 ); # %names = ('English' => '1' ); # count3 = calcTopCount( studnum, term, 55, \%names, 1 ); # print "Studnum:studnum Level:2 A1:avg1 C2:count2 C3:count3 \n"; if ( avg1 >= 75 and not failcount ) { # and count2 >= 4 and count3 >= 6 ) { # print "Level 2 Return \n"; return r_GCDisplay{2}; } # otherwise just... return; =head # Level 3 avg1 = calcTopAverage( studnum, term ); count2 = calcTopCount( studnum, term, 70,\%dud, 1); %names = ('English' => '1' ); count3 = calcTopCount( studnum, term, 55, \%names, 1); # print "Studnum:studnum Level:3 A1:avg1 C2:count2 C3:count3 \n"; if ( avg1 >= 60 and count2 >= 2 and count3 >= 6 and not failcount ) { # print "Level 3 Return \n"; return r_GCDisplay{3}; } # Level 4 - Pass avg1 = calcTopAverage( studnum, term ); count2 = calcTopCount( studnum, term, 55,\%dud,1 ); # print "Studnum:studnum Level:4 (Pass) A1:avg1 C2:count2 \n"; if ( avg1 >= 55 and count2 >= 5 and not failcount ) { # print "Level 4 (Pass) Return \n"; return r_GCDisplay{4}; } # Fail return r_GCDisplay{5}; =cut } # end of calcGradeCategory #----------------- sub calcTopAverage { # Find Averages for GradeCategory Results #----------------- my ( studnum, term, subjnum, name_ref ) = @_; # student number, term, number of subject to avg, names of subj to include in avg (hash ref) my sth = dbh->prepare("select r_MarkField, subjcode from eval where studnum = ? and term = ? order by r_MarkField desc"); sth->execute( studnum, term ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } my sth1= dbh->prepare("select description from subject where subjsec = ?"); my (subjcount, marktotal ); my (%marks, %found ); while ( my ( mark, subjcode ) = sth->fetchrow ) { # skip if member of %r_SupressSubject or AdditionalComments my (tsubjcode, dud) = split('-', subjcode ); if ( r_SupressSubject{tsubjcode} or r_SupressSubject{subjcode} or r_AdditionalComments{tsubjcode} or r_AdditionalComments{subjcode} ) { next; } # Get course description. sth1->execute( subjcode ); if ( DBI::errstr ) { print DBI::errstr; die DBI::errstr; } my description = sth1->fetchrow; if ( not defined mark ) { # NULL value in table print "lex{Skipping}: lex{'Undefined Value'}"; print " description (subjcode) - studnum \n"; next; } if ( name_ref ) { # we have names to store and check against. marks{ subjcode } = mark; # store mark in hash. foreach my name ( keys %{ name_ref } ) { if ( description =~ m/(name)/ ) { # subject match found{ subjcode } = mark; delete$$name_ref{$name }; last; } } } $mark =~ s/\s+//g; # strip any spaces. if ($mark =~ m/[^.0-9]/ or not $mark ) { # non-numeric mark or no value print qq{$lex{Skipping}: $mark -$description ($subjcode) -$studnum
\n}; next; } $marktotal +=$mark; $subjcount++; if ( not$name_ref and $subjcount ==$subjnum ) { # no names and enough subjects my $average; if ($subjcount ) { # not zero. $average =$marktotal / $subjcount; return$average; } else { return undef; } } } # end of data retrieval loop. # just find overall average for this term. if ( not defined $subjnum or$subjcount < $subjnum ) { if ($subjcount ) { my $average =$marktotal / $subjcount; return$average; } else { return undef; } } # else here.... we should have some names, etc. # check %found and if anything left in %$name_ref$marktotal = 0; $subjcount = 0;$subjnum -= $subjcount = keys %found; # foreach my$subjsec ( keys %found ) { delete $marks{$subjsec}; # don't want to count twice. $marktotal +=$found{ $subjsec }; } my$count; foreach my $subjsec ( sort {$marks{$b} <=>$marks{$a} } keys %marks ) {$marktotal += $marks{$subjsec }; $subjcount++;$count++; if ( $count ==$subjnum ) { last; } } my $average; if ($subjcount ) { $average =$marktotal / $subjcount; return$average; } else { return undef; } } # end of calcTopAverage #--------------- sub calcTopCount { # Find Count of subjects above certain value, including subject names; #--------------- # returned: number of subjects above (or >= based on $eqmode ) mark limit, must include subject names. # EQMODE is new my ($studnum, $term,$marklimit ,$name_ref,$eqmode ) = @_; # student number, term, lower mark limit, names of subj to include # in $subjcount returned. # subjects that are required to be in this group. my %subjects = %$name_ref; my $sth =$dbh->prepare("select $r_MarkField, subjcode from eval where studnum = ? and term = ? order by$r_MarkField desc"); $sth->execute($studnum, $term ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } my $sth1=$dbh->prepare("select description from subject where subjsec = ?"); my $subjcount; while ( my ($mark, $subjcode ) =$sth->fetchrow ) { # skip if member of %r_SupressSubject or AdditionalComments my ($tsubjcode,$dud) = split(/-/, $subjcode ); if ($r_SupressSubject{$tsubjcode} or$r_SupressSubject{$subjcode} or$r_AdditionalComments{$tsubjcode} or$r_AdditionalComments{$subjcode} ) { next; } # Get subject description for skipping.$sth1->execute( $subjcode ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } my $description =$sth1->fetchrow; # skip NULL value in table if ( not defined $mark ) { print "$lex{Skipping}: $lex{'Undefined Value'}"; print "$description ($subjcode) -$studnum
\n"; next; } # skip non-numeric mark if ( $mark =~ m/[^.0-9]/ ) { print$lex{Skipping}. ": $mark -$description ($subjcode) -$studnum
\n"; next; } # Check if a certain subject if ( %subjects ) { # we have names to store and check against. foreach my $name ( keys %subjects ) { if ($description =~ m/($name)/ ) { # subject match if ($eqmode ) { # >= mode if ( $mark >=$marklimit ) { $subjects{$name} = 0; # set to zero, from 1. } } else { # > mode if ( $mark >$marklimit ) { $subjects{$name} = 0; # set to zero, from 1. } } } # end if subject match } # name loop } if ( $eqmode ) { # >= mode if ($mark >= $marklimit ) {$subjcount++; } } else { # > mode if ( $mark >$marklimit ) { $subjcount++; } } # print "SN:$studnum SUB:$subjcode Mark:$mark Count:$subjcount \n"; } # end of data retrieval loop. # check to make sure %subjects all zeroed out (ie. matched) foreach my$key ( keys %subjects ) { if ( $subjects{$key} ) { return 0; } } return $subjcount; } # end of calcTopCount #---------- sub calcGPA { #---------- my$gpa_ref = shift; my $maxterm = shift; eval require "$configpath/etc/transcript.conf"; if ( $@ ) { print$lex{Error}. ": $@ \n"; die$lex{Error}. ": $@\n"; } # Get credit and difficulty values for each subject. my$sth = $dbh->prepare("select credit, difficulty from subject where subjsec = ?"); # Start TeX head print TEX "\\begin{tabular}{|p{$r_SubjSpace}|"; for ( 1..$maxterm ){ print TEX "p{$r_MarkSpace}|";} print TEX "}\\hline\n"; print TEX "\\rowcolor[gray]{ $r_GrayScale }"; print TEX "\\bf$lex{Term} $lex{GPA}"; my ($totalGPQuality, $totalGPCredits); # needed for overall at end. # Loop through each term calculating the GPA for each term... foreach my$term ( 1..$maxterm ) { #loop through all terms my ($termCreditTotal, $termGPTotal ); my ($termCredits, $termAttempts ); # not used, yet. TermCredits includes P/F courses. my ($termGPCredits, $termGPQuality ); foreach my$subjsec ( keys %{$gpa_ref} ) { if ( defined$gpa_ref->{$subjsec}[$term] ) { # If we have a value for this term.. my $mark =$gpa_ref->{$subjsec}[$term]; # could be letter or number... # Get Subject Data $sth->execute($subjsec ); if ( $DBI::errstr ) { print$DBI::errstr; die $DBI::errstr; }; my ($credit, $difficulty) =$sth->fetchrow; $credit = 1 if not$credit; if ( not $difficulty ) {$difficulty = 0; } # Convert the mark to a letter (and then to a quality score below... my $letter; # letter grade. if ($mark =~ /[a-zA-Z]/ ) { # We have a 'letter' mark, copy into $letter$letter = $mark; } else { # find the matching letter for this numeric value.. foreach my$threshold (reverse sort keys %markToLetter ) { # large to small if ($mark >=$threshold) { $letter =$markToLetter{$threshold}; # print "Mark:$mark Letter: $letter \n"; last; } } } # Now convert$letter to a quality score. # letterToQual hash in transcript.conf; add up quality scores and credit counts. # Check for missing Quality value in transcript.conf if ( ( not defined $letterToQual{$letter } ) and ( $letter ne$passletter ) ) { print "
$lex{'No Quality Score'}:$letter\n"; next; # skip to next subject. } # Update Attempts $termAttempts +=$credit; # Now do Pass Letter settings. if ( $letter eq$passletter ) { $termCredits +=$credit; $totalCredits +=$credit; } elsif ( $letter eq$failletter ) { # No additions to credits, GP credits increase to bring down avg. $totalGPCredits +=$credit; $termGPCredits +=$credit; } else { # calculate passing grade settings. my $quality =$letterToQual{ $letter }; if ($quality ) { $quality +=$difficulty; } # if non-zero add on difficulty factor. # Update Quality scores for weighted average. $termGPQuality +=$quality * $credit;$totalGPQuality += $quality *$credit; # Update GP Credit totals for weighted average. $totalGPCredits +=$credit; $termGPCredits +=$credit; # Update the credits $termCredits +=$credit; $totalCredits +=$credit; } # print "$subjsec$term ". $gpa_ref->{$subjsec}[$term]. " \n"; } # End of If mark exists } # End of Subject Loop for this term. my$gpa; if ($termGPCredits) {$gpa = format_number( ($termGPQuality /$termGPCredits ), $r_AveragePrecision ); } else {$gpa = 0; } print TEX "&\\hfil $gpa \\hfil "; # change to GPA value... } # End of terms loop my$cumgpa; if ($totalGPCredits) {$cumgpa = format_number( ($totalGPQuality /$totalGPCredits), $r_AveragePrecision ); } else {$cumgpa = 0; } print TEX "\\\\ \\hline\n"; print TEX "\\hfil\\bf ". $lex{'Current Year GPA'}. "$cumgpa \\hfil "; for ( 1..$maxterm ){ print TEX "& ";} print TEX "\\\\ \\hline \\end{tabular}\n\n"; } # end of calcGPA #--------------- sub calcTermDays { #--------------- # passed a start date and an end date for a term, and a ref to a # hash storing the closure dates in julian day format, it will # return a count of the days open in the month. # outline: convert start/end dates to jd. Loop over all days. Use modulus function to ident weekend days. my ($startdate, $enddate,$closeref ) = @_; my %jdclosed = %$closeref; =head print qq{JDClosed \n"; foreach my$key ( sort keys %jdclosed ) { print qq{K:$key V:$jdclosed{$key} \n"; } print qq{End JDClosed \n"; =cut my$startjd = julian_day(split('-',$startdate)); my$endjd = julian_day(split('-',$enddate)); my %modclosed; # modulus for days closed foreach my$inc ( 0..6 ) { my $testjd =$startjd + $inc; my$dow = day_of_week($testjd); if ($dowclosed{$dow} ) { #$testjd is a closed dow my $mod =$testjd % 7; $modclosed{$mod} = 1; } } # foreach my $d ( sort keys %modclosed ) { # print qq{Closed Mod:$d
\n"; # } my ($daysopen,$daysclosed); foreach my $jd ($startjd..$endjd ) { my$dow = day_of_week( $jd ); my$mod = $jd % 7; if ($modclosed{$mod} ) { # closed for weekend next; } # check if a day closed my$cl = $jdclosed{$jd }; if ( $cl ) { # this gives us the fraction closed$daysclosed += $cl; # only add on the fraction of day open$daysopen += (1 - $cl ); # print qq{ INSIDE \n"; } else {$daysopen += 1; } # print qq{JD:$jd Count:$daycount
\n"; } # print qq{ST:$startdate END:$enddate Count:$daycount \n"; return "$daysopen:$daysclosed"; } =head #----------------- sub calcAttendance { #----------------- my ($studnum, $startdate,$enddate, $periodsperday ) = @_; my$sth = $dbh->prepare("select * from attend where studentid = ? and to_days(absdate) >= to_days('$startdate') and to_days(absdate) <= to_days('$enddate') order by absdate,period"); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } $sth->execute($studnum ); if ( $DBI::errstr ) { print$DBI::errstr; die $DBI::errstr; } my$absent = 0; my $late = 0; while ( my @absence =$sth->fetchrow ) { if ( $absence =~ /$lex{Absent}/) { $absent++; } if ($absence =~ /$lex{Late}/) {$late++; } } if ( $periodsperday ) {$absent = $absent /$periodsperday; #convert periods into days } return "$absent:$late"; } =cut #------------ sub prTexHead { # Print the head of each new report card #------------ # globals: schoolname, $schoolyear my ($grade, $lastname,$firstname, $middlename,$birthdate, $provnum,$studnum ) = @_; print TEX "\\thispagestyle{empty}\n\\setcounter{page}{1}\n"; print TEX "\\rhead{$firstname$middlename $lastname -- \\thepage}\n\\begin{center}\n"; if ($r_ShowLogo ) { if ( not $r_LogoFile and$r_logoFile ) { $r_LogoFile =$r_logoFile; } print TEX "\\includegraphics[width=$r_LogoWidth]{"; print TEX "$configpath/etc/$r_LogoFile}\\quad \n"; print TEX "\\parbox[b]{$r_SchoolAddressWidth}{\\begin{center}{"; print TEX "\\Large\\bf $schoolname}\\\\"; if ($schooladdr1 ) { print TEX "$schooladdr1\\\\ \n"; } if ($schoolcity or $schoolprov ) { print TEX "$schoolcity, $schoolprov$schoolpcode\\\\ \n"; } # Phone / Fax Line if ( $schoolphone and$schoolfax ) { # use an hfill print TEX qq{$lex{Phone}$schoolphone \\hfill $lex{Fax}$schoolfax}; # if ( $r_ShowAdmins ) { print TEX "\\hfill ";} # else { print TEX "\\qquad "; } } elsif ($schoolphone ) { print TEX "$lex{Phone}$schoolphone "; } elsif ( $schoolfax ) { print TEX$lex{Fax}. " $schoolfax"; } if ($schoolphone or $schoolfax ) { print TEX "\\\\\n\n"; } # Note:\quad is eM horizontal width, \qquad is eMM's width. # Administrator Lines if ($r_ShowAdmins ) { print TEX "$r_Principal \\hfill$r_VicePrincipal \\\\\n\n"; print TEX "{\\footnotesize $lex{Principal} \\hfill "; if ($r_VicePrincipal ) { print TEX $lex{'Vice-Principal'}; } print TEX "}\\\\\n\n"; } print TEX "\\vspace{$r_AddressSpacer}\n\n"; print TEX " \\end{center}}\\qquad\n"; # note extra parens to close parbox. my $sth =$dbh->prepare("select pic from studentall where studnum = ?"); $sth->execute($studnum ); if ( $DBI::errstr ) { print$DBI::errstr; die $DBI::errstr; } my$pic = $sth->fetchrow; if ($r_ShowStudentPicture and $pic ) { # verify that file exists my$fpath = $configpath. '/admin/pic-big/'.$studnum. '.jpg'; if ( not -e $fpath ) { print " ###$lex{Picture} $lex{'Not Found'}:$firstname $lastname ($studnum)

\n"; $pic = ''; # set to blank, so next section fails to try to print picture } } if ($r_ShowStudentPicture and $pic ) { # note: must have ShowLogo on... print TEX "\\includegraphics[width=$r_StudentPictureWidth]{"; print TEX "$configpath/admin/pic-big/$studnum.jpg}\\\\\n"; } elsif ( $r_DivLogoFile ) { print TEX "\\includegraphics[width=$r_DivLogoWidth]{"; print TEX "$configpath/etc/$r_DivLogoFile}\\\\\n"; } } else { print TEX "\n{\\sf\\Huge $schoolname}\n\n"; } print TEX "\n\\smallskip\n{\\sf\\Large "; my$displaygrade = $grade; if ($schoolmode == 1 ) { # British mode my $val =$g_FormMap{$grade}; if ( not$val ) { $val =$grade; } if ( $val =~ m/F|f/ ) { # we are adding form.$val =~ s/F|f/$lex{Form} /; } else { # put in grade text.$val = "$lex{Grade}$val"; } $displaygrade =$val; } else { # normal mode $displaygrade = qq{$lex{Grade} $displaygrade}; } print TEX "$displaygrade ". $lex{'Report to Parents'}; print TEX "}\n\n$currdate\n"; print TEX "\n\\medskip\n{\\sf\\Large\\it $firstname$middlename $lastname} "; if ($r_ShowProvNum and $provnum ) { print TEX "{\\sf($provnum)}"; } print TEX "\n\n"; print TEX "{\\sf ($birthdate)}\n\\smallskip\n\n"; print TEX "\\end{center}\n"; } # End of prTexHead #--------------------- sub prHomeroomTeachers { #--------------------- my$homeroom = shift; my @teachers = @_; print TEX "\\begin{center}\n"; print TEX "\\setlength{\\extrarowheight}{0pt}\n"; print TEX "\\begin{tabular}{ll}\n{\\small\\bf "; print TEX "$lex{Homeroom}$homeroom $lex{'Teacher(s)'} }"; foreach my$teach ( @teachers ){ print TEX "& {\\it $teach} \\\\ \n"; } print TEX "\\end{tabular}\n\\setlength{\\extrarowheight}{4pt}\n"; print TEX "\\end{center}\n\n"; } # End of prHomeroomTeachers #--------------------- sub print_grade_scheme { #--------------------- my$grade = shift; # Set Grading Scheme choice ( 'a', 'b', etc.) my $scheme =$r_EvalSch{$grade}; # is letter a,b,c, etc. from repcard configuration my$schemeAlt1 = $r_EvalSchAlt1{$grade}; my $first; if ($r_CenterSubjects ) { print TEX "\\begin{center}\n"; } if ( @{$r_Eval{$scheme}} ) { # set width of section. my $width =$textwidth; $width =~ s/mm//; # strip 'mm'.$width -= 30; my $col1 = 10; my$col2 = $width -$col1; # rest of width; print TEX "\\begin{tabular}{|p{$col1 mm}|p{$col2 mm}|}\\hline\n"; print TEX "\\multicolumn{2}{|c|}{\\sf\\large\\bf ". $lex{'Evaluation and Comment Key'}; print TEX " }\\\\ \\hline\n"; for my$item ( @{ $r_Eval{$scheme} } ){ ( $item ) = latex_filter($item ); my ($itema,$itemb ) = split(/::/, $item); if ( not$itemb ) { # no double colons:: print TEX "\\multicolumn{2}{|p{$width mm}|}{$itema}\\\\ \\hline\n"; # print TEX "\\multicolumn{2}{|l|}{$itema}\\\\ \\hline\n"; } else { print TEX "$itema &$itemb\\\\ \\hline\n"; } } print TEX "\\end{tabular}\n\\medskip\n\n"; #$first = 1; # print TEX "\\begin{center}{\\sf\\Large "; # print TEX $lex{'Evaluation and Comment Key'}. "}\n\n"; # print TEX "\\parbox[b]{$r_AssessKeyWidth}"; # print TEX "{\\begin{multicols}{$r_AssessKeyCols}\n"; # for my$item ( @{$r_Eval{$scheme}} ){ # if (not $first){ # print TEX "\\\\\n"; # } else { #$first = 0; # } # print TEX $item; # } # print TEX "\\end{multicols}}\n"; # Note parbox ending. # print TEX "\\end{center}\n"; } # Now print Alt1 Eval keys, if any. if ( @{$r_EvalAlt1{$schemeAlt1}} ) { # assume we have something # set width of section. my$width = $textwidth;$width =~ s/mm//; # strip 'mm'. $width -= 30; my$col1 = 10; my $col2 =$width - $col1; # rest of width; print TEX "\\begin{tabular}{|p{$col1 mm}|p{$col2 mm}|}\\hline\n"; print TEX "\\multicolumn{2}{|c|}{\\sf\\large\\bf$r_EvalAlt1Title "; print TEX " }\\\\ \\hline\n"; for my $item ( @{$r_EvalAlt1{$schemeAlt1} } ){ ($item ) = latex_filter( $item ); my ($itema, $itemb ) = split(/::/,$item); if ( not $itemb ) { # no double colons:: print TEX "\\multicolumn{2}{|p{$width mm}|}{$itema}\\\\ \\hline\n"; # print TEX "\\multicolumn{2}{|l|}{$itema}\\\\ \\hline\n"; } else { print TEX "$itema &$itemb\\\\ \\hline\n"; } } print TEX "\\end{tabular}\n\\medskip\n\n"; # $first = 1; # print TEX "\\begin{center}{\\sf\\Large "; # print TEX$r_EvalAlt1Title. "}\n\n"; # print TEX "\\parbox[b]{$r_AssessKeyWidth}"; # print TEX "{\\begin{multicols}{$r_AssessKeyCols}\n"; # for my $item ( @{$r_EvalAlt1{$schemeAlt1}} ) { # if ( not$first ){ # print TEX "\\\\\n"; # } else { # $first = 0; # } # print TEX$item; # } # print TEX "\\end{multicols}}\n"; # Note parbox ending. # print TEX "\\end{center}\n"; } if ( $r_CenterSubjects ) { print TEX "\\end{center}\n"; } } # end of print grade scheme #------------ sub prCourse { # Print Course Results #------------ # @eval array set with current subjsec, and refs... #$startterm, and $endterm are starting and ending term for the report card display. # This will be modified by$r_TermDisplayLeading and $r_TermDisplayTrailing values; my ($subjsec, $studnum,$currterm, $startterm,$endterm, $evalref ) = @_; my @eval = @{$evalref }; # Get info for this course; my $sth =$dbh->prepare("select description, teacher, startrptperiod, endrptperiod, calcavg, grade from subject where subjsec = ?"); $sth->execute($subjsec ); if ( $DBI::errstr ) { print$DBI::errstr; die $DBI::errstr; } my ($description, $teacher,$startterm, $endterm,$calcavg, $subjgrade ) =$sth->fetchrow; if ( $calcavg eq 'N' ) {$calcavg = 0; } # # Set the Track for this course based on it's grade my $track =$g_MTrackTermType{ $subjgrade }; # Set Personal Growth Flag before latex filtering/escaping. my$personal_growth_flag; # flag for printing keys to personal growth evals if ( $description eq$r_Personal_Growth ) { $personal_growth_flag = 1; } else {$personal_growth_flag = 0; } # LaTeX filter subject fields ( $description,$teacher ) = latex_filter( $description,$teacher ); # calculate the average mark my $averagemark; if ($calcavg ) { my ( $totalscore,$totalweight ); my @tempeval = @eval; # in order to remove first column (objectives) shift @tempeval; foreach my $evalref ( @tempeval ) { my$term = $evalref->; my$score = $evalref->;$score =~ s/[A-Za-z]//g; # strip any non digits. Leave decimals intact. if ( not defined $score ) { print qq{ No Score for$subjsec Term $term Student$studnum. Skipping
\n}; next; } # Make sure hash %r_AverageWeight is defined for this term. if (not $r_AverageWeight{$term} ) { # Error print qq{

### No Average Weight (r_AverageWeight) defined }; print qq{for this term $term \n}; print qq{\n}; exit; } # print qq{Term$term Score $score \n}; my$wt = $r_AverageWeight{$term}; # The weight for this term of course $totalscore += ($wt * $score );$totalweight += $wt; } if ($totalweight ) { $averagemark =$totalscore / $totalweight; } else {$averagemark = 0; } $averagemark = format_number($averagemark, $r_AveragePrecision,$r_AveragePrecision); } # Check if we should add the Personal Growth Key... if ( $personal_growth_flag ) { # print row with objectives... # Figure out width of section. my$width = $textwidth;$width =~ s/mm//; # strip 'mm'. $width -= 30;$col1 = 10; $col2 =$width - $col1; # rest of width; print TEX "\\begin{tabular}{|p{$col1 mm}|p{$col2 mm}|}\\hline\n"; my$key = $r_PDEvalGrp{$subjgrade}; if ( @{ $r_PDEval{$key} } ) { # if we have a non blank objective group... print TEX "\\multicolumn{2}{|c|}{\\sf\\large\\bf $description "; print TEX$lex{'Evaluation Key'}. " }\\\\ \\hline\n"; } for my $item ( @{$r_PDEval{$key} } ){ ($item ) = latex_filter( $item ); my ($itema, $itemb ) = split(/::/,$item); print TEX "$itema &$itemb\\\\ \\hline\n"; } print TEX "\\end{tabular}\\medskip\n\n"; } # Print Out Eval Table for viewing ------- # print qq{Original Eval: $subjsec}; # print qq{}; # # foreach my$idx ( 0.. $#eval ) { # print ""; # foreach my$val ( @{ $eval[$idx] } ) { # print "\n"; # } # print "\n"; # } # print "
 $idx -$eval[$idx]$val
\n"; #-------- print TEX "\\begin{tabular}{|p{$r_SubjSpace}|"; foreach my$ref ( @eval ) { print TEX "p{$r_MarkSpace}|"; } if ($calcavg ){ print TEX "p{$r_MarkSpace}|"; } print TEX "}\\hline\n"; # pull off first column of objectives my @objectives = @{ shift @eval }; shift @objectives; # remove top blank one. @objectives = latex_filter( @objectives ); # Get Teacher Information my$sth = $dbh->prepare("select sal, firstname, lastname from staff where userid = ? ");$sth->execute( $teacher ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } my ($sal,$firstname, $lastname) =$sth->fetchrow; my $subjectteacher; if ($lastname ) { if ( $sal ) {$subjectteacher = " ($sal$lastname)"; } else { # fall back to using first name $subjectteacher = " ($firstname $lastname)"; } } # Print Term Line with Subject name, Teacher and term numbers. print TEX "\\rowcolor[gray]{$r_GrayScale }"; print TEX "{\\sf\\large\\bf $description}"; if ( length($description ) > 20 ) { print TEX "\n\n"; } print TEX "$subjectteacher"; foreach my$ref ( @eval ) { my $title =$ref->; # top of column if ( $g_TermDisplay{$track}{ $title } ) { # if defined, reset$title = $g_TermDisplay{$track}{ $title }; } print TEX "& \\hfil$title \\hfil"; } if ( $calcavg ){ print TEX "& \\hfil ".$lex{Average}. " \\hfil"; } print TEX "\\\\ \\hline\n"; # LaTeX filter characters in @eval 2D array. foreach my $ref ( @eval ) { @{$ref} = latex_filter( @{$ref} ); } my ($absents, $lates) = split(':', calcSubjectAttendance($subjsec, $studnum )); my$objcount = 1; foreach my $objective ( @objectives ) { # Skip showing 'Mark' objective and show attendance if ($r_ShowSubjectAttendance{$subjgrade} and$objcount == 1 ) { # only on line 1 print TEX qq{$lex{Periods}$lex{Absent} $absents$lex{Late} $lates}; if ($objective ne $lex{Mark} ) { # print rest of line blank foreach my$ref ( @eval ) { print TEX "& "; } if ( $calcavg ) { print TEX "& "; } print TEX "\\\\ \\hline\n\n"; print TEX$objective; } } else { # print objective print TEX $objective; } # Print Rest of Line foreach my$ref ( @eval ) { print TEX "& \\hfil $ref->[$objcount]\\hfil"; } if ( $calcavg and$objcount == 1 ){ # only print average for first. print TEX "& \\hfil $averagemark \\hfil"; } elsif ($calcavg ) { print TEX "& "; } print TEX "\\\\ \\hline\n\n"; $objcount++; } print TEX "\\end{tabular}\\\\"; } # End of prCourse #------------ sub prComment { # print all the comments. #------------ my ($subjsec, $studnum,$startterm, $endterm ) = @_; # startterm since we use values from the subject table instead. We # use endterm in case not yet at end of the course. # print "Comment:$subjsec - $studnum - Start:$startterm END:$endterm \n"; print TEX "\n\\smallskip\n\n"; # small space if ($r_ClassAvg and $classavg{$subjsec} ){ print TEX "{\\bf ". $lex{'Class Average'}. ":}$classavg{$subjsec}\n\n"; } # Load comments, if any. my %comments; my$sth = $dbh->prepare("select comment, term from eval where studnum = ? and subjcode = ? order by term");$sth->execute( $studnum,$subjsec ); if ( $DBI::errstr ) { print$DBI::errstr; die $DBI::errstr; } while ( my ($comment, $term ) =$sth->fetchrow ) { if ( $term >=$startterm and $term <=$endterm ) { $comments{$term} = $comment; } } if ( not %comments ) { return; } my$sth = $dbh->prepare("select calcavg, grade, startrptperiod, endrptperiod from subject where subjsec = ?");$sth->execute( $subjsec ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } my ($calcavg,$subjgrade, $start,$end) = $sth->fetchrow; # note 'start','end' terms are set in subject table (courses), not passed if ($calcavg eq 'N' ) { $calcavg = 0; } my$track = $g_MTrackTermType{$subjgrade }; # Figure out Comment Width; assume 6pt tabcolsep (2.12mm); first 2 is subject cell my $subjspace =$r_SubjSpace; $subjspace =~ s/mm//; # strip 'mm'; my$markspace = $r_MarkSpace;$markspace =~ s/mm//; # strip 'mm'; if ( $endterm <$end ) { # not at end of course term. $end =$endterm; } # my $termcount =$endterm - $startterm + 1; my$termcount = $end -$start + 1; # now using values from the subject table (ie. course) if ( $termcount < 1 ) {$termcount = 1; } my $width; if ($r_CommentWidth eq 'termwidth' ) { $width =$subjspace + ($termcount *$markspace) + ( 2 + 2 * $termcount ) * 2.1; if ($calcavg ){ $width =$width + $markspace;} } elsif ($r_CommentWidth eq 'pagewidth' ) { $width =$textwidth; # Set on line 1450; part of prTextDocStart $width =~ s/mm|\s+//g; # strip trailing 'mm' text. } elsif ($r_CommentWidth =~ m/\d+/ ) { # must be digits $width =$r_CommentWidth; $width =~ s/\D+//g; # strip any non digits, just in case it has 'mm'. } else { print qq{ ### Error setting comment width with:$r_CommentWidth

\n}; print qq{\n}; exit; } # print TEX "\n\\parbox{$width mm}{\n"; # moved below in case of big comments foreach my$term ( sort keys %comments ) { if ( not $comments{$term} ) { next; } print TEX "\n\\parbox{$width mm}{"; # start parbox. my$title = $g_TermDisplay{$track}{$term}; my ($comment) = latex_filter ( $comments{$term} ); $comment =~ s/\s*[\n|\r]/ /g; print TEX "\n{\\bf$title:} {\\it $comment }\n}\n"; # second parenthesis ends parbox. } # print TEX "\n}\\smallskip\n\n"; # Note: brace ends parbox. print TEX "\\smallskip\n\n"; # removed ending of parbox. print TEX "\n\\medskip\n\n"; } # End of prComment #---------------------- sub prMonthlyAttendance { # Version with monthly attendance info #---------------------- my$studnum = shift; # Needs globals: # %schooldays - days in each month in hash. # $periodsperday - number of periods in the school day. # calculate attendance, one for each month. foreach my$yrmo ( sort keys %schooldays ) { my $absrec = calcMonthlyAttendance($studnum, $yrmo,$periodsperday, $currsdate, \%lex,$dbh ); # print "$studnum YRMO:$yrmo REC:$absrec \n"; ($absent{$yrmo},$tardy{$yrmo} ) = split(':',$absrec); } # calculate enrollment, one for each month my $ymref = calcMonthlyEnrollment($studnum, $schoolstart,$currsdate, $dbh ); my %ymenrol = %$ymref; # yyyy-mm -> start,end,days # Print Start of Attendance Table print TEX "\\begin{center}\n"; # Setup Table print TEX "\\medskip\n\\begin{tabular}{|p{32mm}|\n"; foreach my $mo ( sort keys %schooldays ) { #$mo not used print TEX "p{9mm}|"; } print TEX "}\n"; # Print Heading Line my $colcount = scalar (keys %schooldays ) + 1; print TEX " \\multicolumn{$colcount}{\@{}c}{\\rule{0pt}{12pt} "; print TEX "\\sf\\bf\\Large ". $lex{Attendance}. "}\n\n"; print TEX "\\\\\\hline\n"; # Print Months Line print TEX "\\rowcolor[gray]{$r_GrayScale }\n"; foreach my $mo ( sort keys %schooldays ) { my ($yr,$mn) = split(/-/,$mo ); print TEX "& \\hfil $s_month[$mn] \\hfil \n"; } print TEX "\\\\\\hline\n"; # Print Days Open print TEX "{\\large\\bf ". $lex{'Days Open'}. "}\n"; foreach my$yrmon ( sort keys %schooldays ) { print TEX "& \\hfil $schooldays{$yrmon} \\hfil \n"; } print TEX "\\\\\\hline\n"; # Print Days Enrolled print TEX "{\\large\\bf ". $lex{'Days Enrolled'}. "}\n"; foreach my$yrmo ( sort keys %schooldays ){ if ( $override ) { my$do = $schooldaysorig{$yrmo }; # Days Open my $ado =$schooldays{ $yrmo }; # Adjusted Days Open my$de = $ymenrol{$yrmo}{'days'}; # Days Enrolled. #print "
SCHOOL DAYS:",%schooldaysorig,"
\n"; #print "$student$student DO: $do ADO:$ado DE: $de \n"; my$ade; # adjusted days enrolled if ( $do ) {$ade = format_number( ($de *$ado / $do), 2, 0); } else {$ade = 0; } print TEX "& \\hfil $ade \\hfil \n"; } else { print TEX "& \\hfil$ymenrol{$yrmo}{'days'} \\hfil \n"; } } print TEX "\\\\\\hline\n"; # Print Days Absent print TEX "{\\large\\bf ".$lex{'Days Absent'}. "}\n"; foreach my $yrmo ( sort keys %schooldays ){ my$abs = format_number( $absent{$yrmo}, 2, 0); print TEX "& \\hfil $abs \\hfil\n"; } print TEX "\\\\ \\hline\n"; # Print Periods Late print TEX "{\\sf\\large\\bf$lex{Periods} $lex{Late} }\n"; foreach my$yrmo ( sort keys %schooldays ){ print TEX "& \\hfil $tardy{$yrmo } \\hfil\n"; } print TEX "\\\\ \\hline\n"; # Finish Attendance Box print TEX "\\end{tabular}\n"; print TEX "\\end{center}\n"; print TEX "\\bigskip\n"; } #---------------- sub prAddComments { #---------------- my ( $studnum,$startterm, $endterm ) = @_; # Updated to show additional comment data for each student. #$r_AdditionalComments{$tsubjcode} or$r_AdditionalComments{$subjcode} ) { # Get student information for this student for this term. # Get the student grade, and then the track for this grade (rather than subject based) my$sth = $dbh->prepare("select grade from studentall where studnum = ?");$sth->execute( $studnum ); if ($DBI::errstr){ print $DBI::errstr; die$DBI::errstr;} my $grade =$sth->fetchrow; my $track =$g_MTrackTermType{ $grade };$sth = $dbh->prepare("select count(*) from eval where subjcode = ? and studnum = ?"); my$sth1 = $dbh->prepare("select subjcode from eval where subjcode like ? and studnum = ?"); my @subjcodes; # codes for this student # Loop through subjects looking for records for this student. foreach my$subj ( keys %r_AdditionalComments ) { if ( $subj =~ m/-/ ) { # has dash, thus subjsec$sth->execute( $subj,$studnum ); if ($DBI::errstr){ print$DBI::errstr; die $DBI::errstr;} my$count = $sth->fetchrow; if ($count > 0 ) { # we have records push @subjcodes, $subj; next; } } else { # no dash, a subject code, use 'like' match$subj = $subj. '-%';$sth1->execute( $subj,$studnum ); if ($DBI::errstr){ print$DBI::errstr; die $DBI::errstr;}$subjcode = $sth1->fetchrow; if ($subjcode ) { # we have records push @subjcodes, $subjcode; next; } } } # @subjcodes now defined if any additional comment subjects enrolled$sth = $dbh->prepare("select comment from eval where subjcode = ? and studnum = ? and term = ?"); print TEX "{\\bf\\Large$lex{'General Comments'}}\n\n"; foreach my $term ($startterm .. $endterm ) { my$first = 1; foreach my $subjcode ( @subjcodes ) {$sth->execute( $subjcode,$studnum, $term ); if ($DBI::errstr){ print $DBI::errstr; die$DBI::errstr;} my $comment =$sth->fetchrow; if (not $comment) { next; }$comment =~ s/\s*[\n\r]/ /g; # strip cr/lf ($comment) = latex_filter(($comment)); # filter content if ( $first ) { print TEX "{\\bf ".$g_TermDisplay{$track}{$term}. " $currterm:} ";$first = 0; } print TEX "$comment \n\n"; } } print TEX "\\vspace{0.6in}\n\n"; } #--------------- sub prTeacherSig { #--------------- print TEX "\\underline{\\hspace{2.5in}} \n\n"; print TEX "{\\small$lex{Teacher}}\n\n \\medskip\n"; } #----------------- sub prPrincipalSig { #----------------- print TEX "\\underline{\\hspace{2.5in}}\n\n"; print TEX "{\\small $lex{'Principal'}}\n\n\\medskip\n"; } #------------- sub prComboSig { # both teacher and principal #------------- print TEX "\\underline{\\hspace{2.5in}}"; print TEX "\\hfill \\underline{\\hspace{2.5in}}\n\n"; print TEX "{\\small$lex{Teacher}} \\hfill "; print TEX "{\\small $lex{'Principal'}}\n\n\\medskip\n"; } #------------ sub prTearoff { # print tearoff line. #------------ # block these 2 sections together over page breaks if ($tearoffblock ) { print TEX "\\parbox{\\textwidth}{ "; } print TEX "\\dotfill\n\n\\bigskip\n\n{\\bf Parents/Guardians:}\n"; print TEX $lex{'Please tear off this portion and return it to the school'}; print TEX " \n"; print TEX$lex{'in the report envelope with any comments and your signature'}. ".\n"; } #-------------- sub prParentSig { # print parent signature. #-------------- my ($currdate,$lastname, $firstname,$middlename) = @_; print TEX "\n\n\\vspace{0.5in}\n\n\\underline{\\hspace{2.5in}}\n\n"; print TEX "{\\small $lex{'Parent/Guardian Signature'}}\n\n\\medskip\n"; print TEX "{\\bf$lex{'Student'}:} {\\it $firstname$middlename $lastname}\n\n"; print TEX "{\\bf$lex{Comments}:}\n\n"; if ( $tearoffblock ) { print TEX "} \n "; } } #------------ sub prYearEnd { #------------ my ($studentname, $grade) = @_; my ($yearstart,$yearend) = split('-',$schoolyear); # global my ($nextgrade,$currgrade); if ($grade eq 'PK'){$nextgrade = 'K';} elsif ($grade eq 'K'){$nextgrade = 1;} else { $nextgrade =$grade + 1;} if ( $schoolmode == 1 ) { # British mode my$val = $g_FormMap{$nextgrade}; if ( not $val ) {$val = $nextgrade; } if ($val =~ m/F|f/ ) { # we are adding form. $val =~ s/F|f/$lex{Form} /; } else { $val = qq{$lex{Grade} $val}; }$nextgrade = $val; # now do the same with grade to make currgrade values my$val = $g_FormMap{$grade}; if ( not $val ) {$val = $grade; } if ($val =~ m/F|f/ ) { # we are adding form. $val =~ s/F|f/$lex{Form} /; } else { $val = qq{$lex{Grade} $val}; }$currgrade = $val; } my$key = $r_PlacementIndex{$grade }; my $tempTex =$r_PlacementTex{ $key }; if ($tempTex ) { # Replace variables. $tempTex =~ s/%studentname%/$studentname/; $tempTex =~ s/%nextgrade%/$nextgrade/g; $tempTex =~ s/%schoolyearend%/$yearend/; $tempTex =~ s/%currgrade%/$currgrade/; print TEX "\\begin{center}\n\\bigskip\n\n"; print TEX "\\framebox[7in][c]{"; print TEX $tempTex; # Variable values found in repcard.conf. print TEX "}\\end{center}\n"; #End of Framebox also. } } #------------ sub calcFinal { #------------ # Passed values: ref to @eval array to do the calcs. my @localeval =${shift}; print @localeval; } #------------------------ sub calcSubjectAttendance { #------------------------ my ( $subjsec,$studnum ) = @_; # pass subject and student. my ($periods,$lates); # periods absent/late my $sth =$dbh->prepare("select distinct reason, count(*) from attend where subjsec = ? and studentid = ? group by reason"); $sth->execute($subjsec, $studnum ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } while ( my ( $reason,$count ) = $sth->fetchrow ) { #print "Reason:$reason Count: $count \n"; if ($reason =~ m/$absentString/ ) {$periods += $count; } elsif ($reason =~ m/$lateString/ ) { #if ($r_LateAbsentRatio ) { # $periods += ($count / $r_LateAbsentRatio ); # } else { #$periods += $count / 3; # default to 3 Late = 1 Absent # }$lates += $count; } # No other reasons affecting. } #print "P:$periods
\n"; if ( not $periods ) {$periods = '0'; } if ( not $latest ) {$lates = 0; } return "$periods:$lates" # format_number( $periods, 2); } #--------------------- sub selectEmailAddress { #--------------------- my$tempdir = shift; my @files = glob("$tempdir/*.pdf"); my$checked; if ( $checknextpage ) {$checked = qq{checked="checked"}; } # Start the form. print qq{
\n}; print qq{\n}; # cause jump to email post print qq{\n}; # pass directory containing the files. # Start the table. print qq{\n}; print qq{\n}; my $sth =$dbh->prepare("select lastname, firstname, email, par1_email, par2_email from studentall where studnum = ?"); my %emailtypes = ( 'email' => 'Student', 'par1_email' => 'Parent 1', 'par2_email' => 'Parent 2'); foreach my $filename ( sort @files ) { my ($dud,$studnum) = split('-',$filename); $studnum =~ s/\.pdf//; # find the email addresses for student and parents.$sth->execute( $studnum ); if ($DBI::errstr ) { print $DBI::errstr; die$DBI::errstr; } my $ref =$sth->fetchrow_hashref; my %r = %$ref; # print "Stud:$studnum Rec:", %r, "
\n"; # print name print qq{\n}; } print qq{\n}; print qq{
$lex{Student}$lex{Email} $lex{Address}$r{firstname} $r{lastname}\n}; foreach my$field ( 'email','par1_email','par2_email') { if ( $r{$field} ) { print qq{}; print qq{$emailtypes{$field}: $r{$field}
\n} }; } print qq{
\n}; exit; } #------------ sub postEmail { #------------ # foreach my $key ( sort keys %arr ) { print "K:$key V:$arr{$key}
{"ft_lang_label":"__label__en","ft_lang_prob":0.6554372,"math_prob":0.78454244,"size":6884,"snap":"2022-27-2022-33","text_gpt3_token_len":2049,"char_repetition_ratio":0.11206395,"word_repetition_ratio":0.08169014,"special_character_ratio":0.34645554,"punctuation_ratio":0.20680629,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.994334,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-07-05T19:43:19Z\",\"WARC-Record-ID\":\"<urn:uuid:b7463902-dacc-4b38-8e7a-9c9b210dd9f2>\",\"Content-Length\":\"96069\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:f1bfff68-4e09-49b4-9cec-e83178ab7b5d>\",\"WARC-Concurrent-To\":\"<urn:uuid:ff2ed5c6-6e3b-4863-9e89-eeb3a7df9297>\",\"WARC-IP-Address\":\"69.11.91.94\",\"WARC-Target-URI\":\"http://richtech.ca/updates/14/rptrepcard.pl\",\"WARC-Payload-Digest\":\"sha1:ARZSP4KN4GAMDLHN7Z5NTI5RRCCCAVAS\",\"WARC-Block-Digest\":\"sha1:MB5HYAGTYO546XVZ3FK6RO6XPLM6HLBK\",\"WARC-Identified-Payload-Type\":\"text/x-perl\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-27/CC-MAIN-2022-27_segments_1656104597905.85_warc_CC-MAIN-20220705174927-20220705204927-00754.warc.gz\"}"}