#!/usr/bin/perl # Copyright 2001-2008 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. # Generate Receipts for Payments. # Note: The payment id (id of record with a trans_type = 'pay'), will # find all of the payments on existing records, but will not locate # any new roa (received on account) records created by this # payment. These are found by looking up the receipt number for a # record of type 'roa'. This will be a new roa type created by this # payment. roa records are only generated if a particular charge is # not paid in full by the payment. Since this payment cannot be linked # to this charge (since not paid in full), a non linked roa record is # created instead. # ROA's are NULL for paid_id but have a receipt value from payment # that created them. Once 'paid'... associated with a payment # transaction... the paid_id is filled in with this payment # transaction. my %lex = ('View / Print Receipts' => 'View / Print Receipts', 'No Transactions Found' => 'No Transactions Found', 'Fees' => 'Fees', 'Main' => 'Main', 'Total' => 'Total', 'Payment' => 'Payment', 'Date' => 'Date', 'Invoice' => 'Invoice', 'Description' => 'Description', 'Owing' => 'Owing', 'Receipt Number' => 'Receipt Number', 'Paid' => 'Paid', 'Total Paid' => 'Total Paid', 'View Log File' => 'View Log File', 'Student' => 'Student', 'Action' => 'Action', 'Search' => 'Search', 'No Students Found' => 'No Students Found', 'Please search again' => 'Please search again', 'Student (Last,First/Last/Initials/Studnum)' => 'Student (Last,First/Last/Initials/Studnum)', 'Print Receipt' => 'Print Receipt', 'Continue' => 'Continue', 'Date' => 'Date', 'Amount' => 'Amount', 'Description' => 'Description', 'View/Download' => 'View/Download', 'Grade' => 'Grade', 'Receipt' => 'Receipt', 'Address' => 'Address', 'Phone' => 'Phone', 'Fax' => 'Fax', 'Payment' => 'Payment', 'Signature' => 'Signature', 'Payee' => 'Payee', 'Name' => 'Name', 'Error' => 'Error', ); my $self = 'receipt.pl'; use CGI; use DBI; use Cwd; my $q = new CGI; print $q->header; my %arr = $q->Vars; eval require "../../etc/admin.conf"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } eval require "../../etc/fees.conf"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } my $dsn = "DBI:$dbtype:dbname=$dbase"; my $dbh = DBI->connect($dsn,$user,$password); # Get current dir so know what CSS to display; #if (getcwd() =~ /tcgi/){ # we are in tcgi # $css = $tchcss; #} # Show page Header print "$doctype\n". $lex{'View / Print Receipts'}. "\n"; print "\n"; if ( not $arr{page} ) { $focus = 1; } else { $focus = 0; } print "$chartype\n\n"; print "[ ". $lex{Main}. " |\n"; print "". $lex{Fees}. " ]\n"; print "

". $lex{'View / Print Receipts'}. "

\n"; if ( not $arr{page} ) { showStartPage(); } if ( $arr{page} == 1 ) { selectStudent( $arr{student} ); } elsif ( $arr{page} == 2 ) { selectReceipts( $arr{studnum} ); } elsif ( $arr{page} == 3 ) { printHtmlReceipt( $arr{payid} ); printReceipt( $arr{payid} ); } print "\n"; #================ sub showStartPage { #================ my $maxdisplay = 8; # max number of previous payments to display; # display the last 8 payments, for receipt printing. print "\n"; print "\n"; # Get payments my $sth = $dbh->prepare("select id, studnum, trans_date, total, description, name from fees_jrl where trans_type = 'pay' or trans_type = 'roa' order by trans_date desc"); $sth->execute; if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my $sth1 = $dbh->prepare("select lastname, firstname from studentall where studnum = ?"); my $count = 1; while ( my ($id, $studnum, $trans_date, $total, $description, $name ) = $sth->fetchrow ) { if ( $count > $maxdisplay ) { next; } else { $count++; } $total = sprintf("%3.2f", abs $total); # remove the negative value from payment. # Get student name $sth1->execute( $studnum ); my ($lastname, $firstname) = $sth1->fetchrow; if ( not $description ) { $description = $name; } # req'd for roa transactions. print "\n"; print "\n"; } print "
". $lex{Student}. "". $lex{Date}. ""; print $lex{Amount}. ""; print $lex{Description}. "". $lex{Action}. "
$firstname $lastname$trans_date$total$description\n"; print "
\n"; print "\n"; print "\n"; print ""; print "
\n"; showSearchForm(); print "\n"; exit; } #---------------- sub printReceipt { # pdf version using LaTeX #---------------- # Load Latex filtering script; eval require "../../lib/liblatex.pl"; if ( $@ ) { print $lex{Error}. " $@
\n"; die $lex{Error}. " $@\n"; } my $paymentid = shift; if ( not $paymentid ){ # No outstanding transaction found print '

'. $lex{'No Transactions Found'}. "!

\n"; print "[ ". $lex{Fees}. " ]\n"; print "\n"; exit; } my $shortname = "pdfreceipt$$"; my $filename = "$shortname.tex"; # Find payment transaction from paymentid. my $sth = $dbh->prepare("select studnum, trans_date, name, description, total, receipt from fees_jrl where id = ?"); $sth->execute( $paymentid ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } my ( $studnum, $trans_date, $name, $description, $total, $receipt ) = $sth->fetchrow; if ( not $description ) { $description = $name; } # for roa payments only. ($description) = latex_filter( ($description) ); # Extract Payee information from the description. my ($dud, $name) = split /\(/, $description; chop $name; # remove trailing bracket; my ($dud, $payee) = split /:/, $name; # Get Records paid by this payment $sth = $dbh->prepare("select id from fees_jrl where paid_id = ?"); $sth->execute( $paymentid ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } while ( my $newid = $sth->fetchrow ) { push @transactions, $newid; } # Now find any new roa records created by this payment $sth = $dbh->prepare("select id from fees_jrl where receipt = ? and trans_type = 'roa'"); $sth->execute( $receipt ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } while ( my $newid = $sth->fetchrow ) { push @roapayments, $newid; } # Start the TeX file... open(TEX,">$filename") || die "Can't open tex file"; # Letter paper size is 279mm x 213mm # 200mm wide - 50mm name, 20mm extra fld, leaves 130mm for columns. # The tabcolsep of 1mm leaves 128 mm where each col is $width + 1mm wide. print TEX "\\documentclass[12pt,letterpaper]{article}\n"; print TEX "\\usepackage{array,newcent,rotating,colortbl, inputenc}\n"; print TEX "\\inputencoding{latin1}\n\\renewcommand{\\familydefault}{\\sfdefault}\n"; print TEX "\\pagestyle{empty}\\setlength{\\textwidth}{200mm}\n"; print TEX "\\setlength{\\textheight}{270mm}\\setlength{\\hoffset}{-1in}\n"; print TEX "\\setlength{\\voffset}{-1.4in}\\addtolength{\\evensidemargin}{0in}\n"; print TEX "\\addtolength{\\oddsidemargin}{0in}\\setlength{\\tabcolsep}{1mm}\n"; #print TEX "\\setlength{\\extrarowheight}{2mm}\n"; #\\newcolumntype{G}{>{\\columncolor[gray]{1.00}}p{$namewidth mm}}\n"; # Note above... a columncolor of 1.00 means white, smaller number is darker. print TEX "\\begin{document}\n"; # print School Info print TEX "\\begin{center}{\\large $schoolname}\n\n"; print TEX "$schooladdress1 $schooladdress2 \n\n"; print TEX "$schoolcity $schoolprov $schoolpcode\n\n"; print TEX $lex{Phone}. " $schoolphone\n\n"; print TEX $lex{Fax}. " $schoolfax\n\n"; print TEX "\\end{center}\n\\medskip\n\n"; print TEX "{\\Large ". $lex{Payment}. q{ }. $lex{Receipt}. " \\# $receipt}\n\\bigskip\n\n"; # get Student Info $sth = $dbh->prepare("select lastname, firstname, grade, address1, city1, pcode1 from studentall where studnum = ?"); $sth->execute( $studnum ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } my $stud_ref = $sth->fetchrow_arrayref; my @stud = @{$stud_ref}; #($lastname, $firstname, $grade, $address1, $city1, $pcode1 ) @stud = latex_filter( @stud ); #print @{$stud_ref}; # print Student Info print TEX "\\begin{tabular}{ll}\n"; print TEX "{\\bf ". $lex{Student}. "}: & $stud[1] $stud[0] \\\\ \n"; print TEX " &". $lex{Grade}. " $stud[2] \\\\\n"; print TEX " & $stud[3] \\\\\n"; print TEX " & $stud[4] $stud[5] \\\\\n"; print TEX "\\end{tabular}\n\n\\medskip\n"; # print Payment Date print TEX "{\\bf ". $lex{Payment}. q{ }. $lex{Date}. "}: $trans_date \n\\bigskip\n\n"; # print Amount of Payment $total =~ s/^-//; # strip negative sign print TEX "{\\bf ". $lex{Amount}. "}: $total \n\\bigskip\n\n"; # print Amount of Payment print TEX "{\\bf ". $lex{Payee}. "}: $payee\n\\bigskip\n\n"; $sth = $dbh->prepare("select trans_date, name, description, total from fees_jrl where id = ?"); print TEX "{\\bf ". $lex{Fees}. q{ }. $lex{Paid}. "}\n\\medskip\n\n"; print TEX "\\setlength{\\extrarowheight}{4pt}\n"; print TEX "\\begin{tabular}{|l|l|r|}\\hline\n"; print TEX "\\rowcolor[gray]{0.92}". $lex{Date}. " & ". $lex{Description}. ' & '. $lex{Amount}; print TEX "\\\\ \\hline\n"; my $studenttotal; # First do all transactions paid by this payment (including associated previous roa records) foreach my $id ( @transactions ) { $sth->execute( $id ); my ($trans_date, $name, $description, $total) = $sth->fetchrow; ($name,$description) = latex_filter( ($name,$description) ); print TEX "$trans_date & {\\it $name} $description & \\hfil $total \\\\ \\hline\n"; $studenttotal += $total; } foreach my $id ( @roapayments ) { $sth->execute( $id ); my ($trans_date, $name, $description, $total) = $sth->fetchrow; $total =~ s/^-//; # remove any negative values... ($name,$description) = latex_filter( ($name,$description) ); print TEX "$trans_date & {\\it $name} $description & \\hfil $total \\\\ \\hline\n"; $studenttotal += $total; } $studenttotal = sprintf("%3.2f", $studenttotal); print TEX " & ". $lex{Total}. "& {\\bf $studenttotal} \\\\ \\hline\n"; print TEX "\\end{tabular}\n\n\\vspace{0.5in}\n"; print TEX "\\underline{\\hspace{3in}}\n\n"; print TEX "{\\small ". $lex{Signature}. "}\n\n"; print TEX "\n\\end{document}"; close TEX; system("$pdflatex $filename >pdflog$$.txt"); system("mv $shortname.pdf $downloaddir"); system("mv pdflog$$.txt $downloaddir"); system("rm -f $shortname.*"); print "

"; print $lex{'View/Download'}. ' ', $lex{'Receipt'}. "

\n"; print "

[ ". $lex{Main}. " |\n"; print ""; print $lex{'View Log File'}. "\n ]

\n"; } #------------------- sub printHtmlReceipt { #------------------- my $paymentid = shift; # passed payment id number. # Get Payment transaction and get the amount, student number, and receipt #. my $sth = $dbh->prepare("select studnum, total, receipt from fees_jrl where id = ?"); $sth->execute( $paymentid ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } my ($studnum, $total, $receipt) = $sth->fetchrow; # Note: receipt= receipt num;pay xactions. # Get student name. my $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?"); $sth->execute( $studnum ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } my ($lastname, $firstname) = $sth->fetchrow; my $payment = sprintf("%3.2f", -$total); print "

$firstname $lastname ($studnum)  ". $lex{Payment}; print ": $payment

\n"; print "

". $lex{'Receipt Number'}. "  $receipt

\n"; print "\n"; print "\n"; # Get chg and roa transactions for this payment. my $sth = $dbh->prepare("select trans_date, name, description, total from fees_jrl where paid_id = ? order by trans_date"); $sth->execute( $paymentid ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } my $grandtotal; while (my ($trans_date, $name, $description, $total ) = $sth->fetchrow ) { $grandtotal += $total; print "\n"; } # Now find any new roa records created by this payment $sth = $dbh->prepare("select trans_date, name, description, total from fees_jrl where receipt = ? and trans_type = 'roa'"); $sth->execute( $receipt ); if ( $DBI::errstr ){ print $DBI::errstr; die $DBI::errstr; } while (my ($trans_date, $name, $description, $total ) = $sth->fetchrow ) { $total =~ s/^-//; # remove any negative values... $grandtotal += $total; print "\n"; } $grandtotal = sprintf("%3.2f", $grandtotal); print "\n"; print "\n"; print "
". $lex{Date}. "". $lex{Name}. '/'. $lex{Description}; print "". $lex{Paid}. "
$trans_date$name - $description$total
$trans_date$name - $description$total
". $lex{'Total Paid'}; print "$grandtotal
"; #print "\n"; } # end of printHtmlReceipt #--------------------- sub selectReceipts { #--------------------- my $studnum = shift; # Get student name. my $sth = $dbh->prepare("select lastname, firstname from studentall where studnum = ?"); $sth->execute( $studnum ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my ($lastname, $firstname) = $sth->fetchrow; print "

". $lex{Receipts}. "

\n"; print "\n"; print "\n"; # Get payments my $sth = $dbh->prepare("select id, trans_date, total, description, name from fees_jrl where studnum = ? and trans_type = 'pay' or trans_type = 'roa' order by trans_date desc"); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } $sth->execute( $studnum ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } while ( my ($id, $trans_date, $total, $description) = $sth->fetchrow ) { if ( not $description ) { $description = $name; } # only for roa transactions. print "\n"; } print "
". $lex{Date}. "". $lex{Amount}. ""; print $lex{Description}. "". $lex{Action}. "
$trans_date$total$description\n"; print "
\n"; print "\n"; print "\n"; print ""; print "
\n"; exit; } # End of selectReceipts #---------------- sub selectStudent { #---------------- my $student = shift; # Setup the Search if ($student =~ /\d+/) { # we have a student number $sth = $dbh->prepare("select lastname, firstname, studnum from studentall where studnum = ?"); $sth->execute( $student ); } else { # we have words possibly with a comma ($lastname,$firstname) = split /\,/, $student; $firstname =~ s/^\s*//; $lastname =~ s/^\s*//; if ($lastname and $firstname){ # both entered. $sth = $dbh->prepare("select lastname, firstname, studnum from studentall where lastname = ? and firstname = ?"); $sth->execute( $lastname, $firstname ); } elsif ($lastname and not $firstname){ # only lastname (no comma) if (length($lastname) == 2){ # search by initials: fi, li. my $fi = substr($lastname,0,1). '%'; my $li = substr($lastname,1,1). '%'; $sth = $dbh->prepare("select lastname, firstname, studnum from studentall where lastname $sql{like} ? and firstname $sql{like} ?"); $sth->execute( $li, $fi ); } else { $sth = $dbh->prepare("select lastname, firstname, studnum from studentall where lastname = ? order by firstname"); $sth->execute( $lastname ); } } else { # print an error.... showSearchForm(); print "\n"; die; } } # Last Else # We should now have a $sth defined. if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; } my $rows = $sth->rows; #print "Rows: $rows
\n"; if ($rows < 1) { print "

". $lex{'No Students Found'}. ". ". $lex{'Please search again'}. ".

\n"; showSearchForm(); print "\n"; die; } print "\n"; print "\n"; my $first = 1; for (1..$rows){ my ($lastname, $firstname, $studnum) = $sth->fetchrow; # Find any payments; otherwise skip my $sth1 = $dbh->prepare("select count(*) from fees_jrl where studnum = ? and trans_type = 'pay' or trans_type = 'roa' and receipt is not null"); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } $sth1->execute( $studnum ); if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; } my $count = $sth1->fetchrow; if (not $count) { next; } print "\n"; } print "
". $lex{Student}. "". $lex{Action}. "
$firstname $lastname ($studnum)\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "
\n"; if ( $rows > 20 ) { # only show if lots of records showSearchForm(); } print "\n"; exit; } # end of selectStudent #---------------- sub showSearchForm { #---------------- print "
\n"; print "". $lex{Receipt}. q{ }. $lex{Search}. "
\n"; print "
\n"; print "\n"; print "
\n"; print "\n"; print $lex{'Student (Last,First/Last/Initials/Studnum)'}. "\n"; print "
\n"; }