print customer statements on the fly, #15864
authormark <mark>
Wed, 1 Feb 2012 05:30:16 +0000 (05:30 +0000)
committermark <mark>
Wed, 1 Feb 2012 05:30:16 +0000 (05:30 +0000)
FS/FS/Conf.pm
FS/FS/cust_statement.pm
httemplate/view/cust_main/payment_history.html
httemplate/view/cust_main_statement-pdf.cgi [new file with mode: 0755]

index 2899de3..8e48dc2 100644 (file)
@@ -4673,6 +4673,13 @@ and customer address. Include units.',
     'select_enum' => [ 'Classic', 'Recurring' ],
   },
 
+  {
+    'key'         => 'cust_main-print_statement_link',
+    'section'     => 'UI',
+    'description' => 'Show a link to download a current statement for the customer.',
+    'type'        => 'checkbox',
+  },
+
   { 
     'key'         => 'username-pound',
     'section'     => 'username',
index 83dd5c1..45fae1c 100644 (file)
@@ -60,6 +60,10 @@ Creates a new record.  To add the record to the database, see L<"insert">.
 Note that this stores the hash reference, not a distinct copy of the hash it
 points to.  You can ask the object for a copy with the I<hash> method.
 
+Pass "statementnum => 'ALL'" to create a temporary statement that includes 
+all of the customer's invoices.  This statement can't be inserted and won't
+set the statementnum field on any invoices.
+
 =cut
 
 sub new { FS::Record::new(@_); }
@@ -165,7 +169,16 @@ Returns the associated invoices (cust_bill records) for this statement.
 
 sub cust_bill {
   my $self = shift;
-  qsearch('cust_bill', { 'statementnum' => $self->statementnum } );
+  # we use it about a thousand times, let's cache it
+  $self->{Hash}->{cust_bill} ||= [
+    qsearch('cust_bill', { 
+        $self->statementnum eq 'ALL' ?
+          ('custnum' => $self->custnum) :
+          ('statementnum' => $self->statementnum)
+    } )
+  ];
+
+  @{ $self->{Hash}->{cust_bill} }
 }
 
 sub _aggregate {
index 63708e6..b5b7161 100644 (file)
     </TD>
     <TD ALIGN="right" VALIGN="top">
 
-%# invoice reports
+%# invoice reports, combined statement
 % if ( $curuser->access_right('List invoices') ) { 
+%   if ( $conf->exists('cust_main-print_statement_link')
+%        and $num_cust_bill > 0 ) {
+  <A HREF="<% $p %>view/cust_main_statement-pdf.cgi?<% $custnum %>"><%
+  mt('Print a current statement') |h %></A>
+  <BR>
+%   }
   <A HREF="<% $p %>search/report_cust_bill.html?custnum=<% $custnum %>"><% mt('Invoice reports') |h %></A>
 % } 
 <BR>
@@ -410,12 +416,14 @@ foreach my $legacy_cust_bill ($cust_main->legacy_cust_bill) {
 }
 
 #invoices
+my $num_cust_bill = 0;
 foreach my $cust_bill ($cust_main->cust_bill) {
   push @history, {
     'date'   => $cust_bill->_date,
     'desc'   => include('payment_history/invoice.html', $cust_bill, %opt ),
     'charge' => $cust_bill->charged,
   };
+  $num_cust_bill++;
 }
 
 #statements
diff --git a/httemplate/view/cust_main_statement-pdf.cgi b/httemplate/view/cust_main_statement-pdf.cgi
new file mode 100755 (executable)
index 0000000..7a0e198
--- /dev/null
@@ -0,0 +1,39 @@
+<%doc>
+Like view/cust_statement-pdf.cgi, but for viewing/printing the implicit 
+statement containing all of a customer's invoices.  Slightly redundant.
+I don't see the need to create an equivalent to view/cust_statement.html 
+for this case, but one can be added if necessary.
+</%doc>
+<% $pdf %>
+<%init>
+
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right('View invoices');
+
+#untaint statement
+my($query) = $cgi->keywords;
+$query =~ /^((.+)-)?(\d+)$/;
+my $templatename = $2 || 'statement'; #XXX configure... via event??  eh..
+my $custnum = $3;
+
+my $cust_main = qsearchs({
+  'select'    => 'cust_main.*',
+  'table'     => 'cust_main',
+  'hashref'   => { 'custnum' => $custnum },
+  'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+});
+die "Customer #$custnum not found!" unless $cust_main;
+
+my $cust_statement = FS::cust_statement->new({
+  'custnum'       => $custnum,
+  'statementnum'  => 'ALL', #magic
+  '_date'         => time,
+});
+
+my $pdf = $cust_statement->print_pdf( '', $templatename );
+
+http_header('Content-Type' => 'application/pdf' );
+http_header('Content-Length' => length($pdf) );
+http_header('Cache-control' => 'max-age=60' );
+
+</%init>