#!/usr/bin/perl -Tw use strict; use Date::Parse; use Time::Local; use Getopt::Std; use Text::Template; use Net::SMTP; use Mail::Header; use Mail::Internet; use FS::Conf; use FS::UID qw(adminsuidsetup); use FS::Record qw(qsearch qsearchs); use FS::cust_pay; use FS::cust_pay_batch; &untaint_argv; #what it sounds like (eww) use vars qw($opt_v $opt_p $opt_m $opt_e $opt_t $opt_s $opt_f $report_lines $report_template @buf $header); getopts("vpmef:s:"); #switches #we're at now now (and later). my($_finishdate)= $opt_f ? str2time($main::opt_f) : $^T; my($_startdate)= $opt_s ? str2time($main::opt_s) : $^T; # Get the current month my ($ssec,$smin,$shour,$smday,$smon,$syear) = (localtime($_startdate) )[0,1,2,3,4,5]; $smon++; $syear += 1900; # Get the current month my ($fsec,$fmin,$fhour,$fmday,$fmon,$fyear) = (localtime($_finishdate) )[0,1,2,3,4,5]; $fmon++; $fyear += 1900; # Login to the database my $user = shift or die &usage; adminsuidsetup $user; # Get the needed configuration files my $conf = new FS::Conf; my $lpr = $conf->config('lpr'); my $email = $conf->config('email'); my $smtpmachine = $conf->config('smtpmachine'); my $mail_sender = $conf->exists('invoice_from') ? $conf->config('invoice_from') : 'postmaster'; my @report_template = $conf->config('report_template') or die "cannot load config file report_template"; $report_lines = 0; foreach ( grep /report_lines\(\d+\)/, @report_template ) { #kludgy :/ /report_lines\((\d+)\)/; $report_lines += $1; } die "no report_lines() functions in template?" unless $report_lines; $report_template = new Text::Template ( TYPE => 'ARRAY', SOURCE => [ map "$_\n", @report_template ], ) or die "can't create new Text::Template object: $Text::Template::ERROR"; my(@cust_pays)=qsearch('cust_pay',{}); if (scalar(@cust_pays) == 0) { exit 1; } # Open print and email pipes # $lpr and opt_p for printing # $email and opt_m for email if ($lpr && $main::opt_p) { open(LPR, "|$lpr"); } if ($email && $main::opt_m) { $ENV{MAILADDRESS} = $mail_sender; $header = new Mail::Header ( [ "From: Account Processor", "To: $email", "Sender: $mail_sender", "Reply-To: $mail_sender", "Subject: Credit Card Receipts", ] ); } my $uninvoiced = 0; my $total = 0; my $taxed = 0; my $untaxed = 0; my $total_tax = 0; # Now I can start looping foreach my $cust_pay (@cust_pays) { my $_date = $cust_pay->getfield('_date'); my $invnum = $cust_pay->getfield('invnum'); my $paid = $cust_pay->getfield('paid'); my $payby = $cust_pay->getfield('payby'); if ($_date >= $_startdate && $_date <= $_finishdate && $payby =~ 'CARD') { $total += $paid; $uninvoiced += $cust_pay->unapplied; my @cust_bill_pays = $cust_pay->cust_bill_pay; foreach my $cust_bill_pay (@cust_bill_pays) { my $invoice_amt =0; my $invoice_tax =0; my(@cust_bill_pkgs)= $cust_bill_pay->cust_bill->cust_bill_pkg; foreach my $cust_bill_pkg (@cust_bill_pkgs) { my $recur = $cust_bill_pkg->getfield('recur'); my $setup = $cust_bill_pkg->getfield('setup'); my $pkgnum = $cust_bill_pkg->getfield('pkgnum'); if ($pkgnum == 0) { $invoice_tax += $recur; $invoice_tax += $setup; } else { $invoice_amt += $recur; $invoice_amt += $setup; } } if ($invoice_tax > 0) { if ($invoice_amt != $paid) { # attempt to prorate partially paid invoices $total_tax += $paid / ($invoice_amt + $invoice_tax) * $invoice_tax; $taxed += $paid / ($invoice_amt + $invoice_tax) * $invoice_amt; } else { $total_tax += $invoice_tax; $taxed += $invoice_amt; } } else { $untaxed += $paid; } } } } push @buf, sprintf(qq{\n%25s%14.2f\n}, "Uninvoiced", $uninvoiced); push @buf, sprintf(qq{%25s%14.2f\n}, "Untaxed", $untaxed); push @buf, sprintf(qq{%25s%14.2f\n}, "Taxed", $taxed); push @buf, sprintf(qq{%25s%14.2f\n}, "Tax", $total_tax); push @buf, sprintf(qq{\n%39s\n%39.2f\n}, "=========", $total); sub FS::cc_receipts_report::_template::report_lines { my $lines = shift; map { scalar(@buf) ? shift @buf : '' ; } ( 1 .. $lines ); } $FS::cc_receipts_report::_template::title = qq~CREDIT CARD RECEIPTS for period $smon/$smday/$syear through $fmon/$fmday/$fyear~; $FS::cc_receipts_report::_template::title = $opt_t if $opt_t; $FS::cc_receipts_report::_template::page = 1; $FS::cc_receipts_report::_template::date = $^T; $FS::cc_receipts_report::_template::date = $^T; $FS::cc_receipts_report::_template::fdate = $_finishdate; $FS::cc_receipts_report::_template::fdate = $_finishdate; $FS::cc_receipts_report::_template::sdate = $_startdate; $FS::cc_receipts_report::_template::sdate = $_startdate; $FS::cc_receipts_report::_template::total_pages = int( scalar(@buf) / $report_lines); $FS::cc_receipts_report::_template::total_pages++ if scalar(@buf) % $report_lines; my @report; while (@buf) { push @report, split("\n", $report_template->fill_in( PACKAGE => 'FS::cc_receipts_report::_template' ) ); $FS::cc_receipts_report::_template::page++; } if ($opt_v) { print map "$_\n", @report; } if($lpr && $opt_p) { print LPR map "$_\n", @report; print LPR "\f" if $opt_e; close LPR || die "Could not close printer: $lpr\n"; } if($email && $opt_m) { my $message = new Mail::Internet ( 'Header' => $header, 'Body' => [ (@report) ], ); $!=0; $message->smtpsend( Host => "$smtpmachine" ) or die "can't send report to $email via $smtpmachine: $!"; } # subroutines sub untaint_argv { foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV $ARGV[$_] =~ /^([\w\-\/ :\.]*)$/ || die "Illegal argument \"$ARGV[$_]\""; $ARGV[$_]=$1; } } sub usage { die "Usage:\n\n freeside-cc-receipts-report [-v] [-p] [-e] user\n"; } =head1 NAME freeside-cc-receipts-report - Prints or emails total credit card receipts in a given period. =head1 SYNOPSIS freeside-cc-receipts-report [-v] [-p] [-m] [-e] [-t "title"] [-s date] [-f date] user =head1 DESCRIPTION Prints or emails sales taxes invoiced in a given period. -v: Verbose - Prints records to STDOUT. -p: Print to printer lpr as found in the conf directory. -m: Email output to user found in the Conf email file. -e: Print a final form feed to the printer. -t: supply a title for the top of each page. -s: starting date for inclusion -f: final date for inclusion user: From the mapsecrets file - see config.html from the base documentation =head1 VERSION $Id: freeside-cc-receipts-report,v 1.4.4.1 2002-09-09 22:57:32 ivan Exp $ =head1 BUGS Yes..... Use at your own risk. No guarantees or warrantees of any kind apply to this program. Parts of this program are hacked from other GNU licensed software created mainly by Ivan Kohler. This is released under the GNU Public License. See www.gnu.org for more information regarding this license. =head1 SEE ALSO L, config.html from the base documentation =head1 AUTHOR Jeff Finucane based on print-batch by Joel Griffiths =cut