move query logic from perl to sql for scalability
[freeside.git] / httemplate / search / cust_bill.cgi
index a961455..dbe7e7d 100755 (executable)
@@ -1,61 +1,86 @@
 <%
-#<!-- $Id: cust_bill.cgi,v 1.2 2001-08-21 02:31:56 ivan Exp $ -->
-
-use strict;
-use vars qw ( $cgi $invnum $query $sortby @cust_bill );
-use CGI;
-use CGI::Carp qw(fatalsToBrowser);
-use Date::Format;
-use FS::UID qw(cgisuidsetup);
-use FS::CGI qw(popurl header menubar eidiot table );
-use FS::Record qw(qsearch qsearchs);
-use FS::cust_bill;
-use FS::cust_main;
-
-$cgi = new CGI;
-cgisuidsetup($cgi);
 
+my $conf = new FS::Conf;
+my $maxrecords = $conf->config('maxsearchrecordsperpage');
+
+my $orderby = ''; #removeme
+
+my $limit = '';
+$limit .= "LIMIT $maxrecords" if $maxrecords;
+
+my $offset = $cgi->param('offset') || 0;
+$limit .= " OFFSET $offset" if $offset;
+
+my $total;
+
+my(@cust_bill, $sortby);
 if ( $cgi->keywords ) {
   my($query) = $cgi->keywords;
+  my $open_sql =
+    "having 0 != charged - coalesce(sum(cust_bill_pay.amount),0)
+                         - coalesce(sum(cust_credit_bill.amount),0)";
+  my $having = '';
+  my $where = '';
   if ( $query eq 'invnum' ) {
     $sortby = \*invnum_sort;
-    @cust_bill = qsearch('cust_bill', {} );
+    #@cust_bill = qsearch('cust_bill', {} );
   } elsif ( $query eq 'date' ) {
     $sortby = \*date_sort;
-    @cust_bill = qsearch('cust_bill', {} );
+    #@cust_bill = qsearch('cust_bill', {} );
   } elsif ( $query eq 'custnum' ) {
     $sortby = \*custnum_sort;
-    @cust_bill = qsearch('cust_bill', {} );
+    #@cust_bill = qsearch('cust_bill', {} );
   } elsif ( $query eq 'OPEN_invnum' ) {
     $sortby = \*invnum_sort;
-    @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+    #@cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+    $having = $open_sql;
   } elsif ( $query eq 'OPEN_date' ) {
     $sortby = \*date_sort;
-    @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+    #@cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+    $having = $open_sql;
   } elsif ( $query eq 'OPEN_custnum' ) {
     $sortby = \*custnum_sort;
-    @cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+    #@cust_bill = grep $_->owed != 0, qsearch('cust_bill', {} );
+    $having = $open_sql;
   } elsif ( $query =~ /^OPEN(\d+)_invnum$/ ) {
     my $open = $1 * 86400;
     $sortby = \*invnum_sort;
-    @cust_bill =
-      grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+    #@cust_bill =
+    #  grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+    $having = $open_sql;
+    $where = "where cust_bill._date < ". (time-$open);
   } elsif ( $query =~ /^OPEN(\d+)_date$/ ) {
     my $open = $1 * 86400;
     $sortby = \*date_sort;
-    @cust_bill =
-      grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+    #@cust_bill =
+    #  grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+    $having = $open_sql;
+    $where = "where cust_bill._date < ". (time-$open);
   } elsif ( $query =~ /^OPEN(\d+)_custnum$/ ) {
     my $open = $1 * 86400;
     $sortby = \*custnum_sort;
-    @cust_bill =
-      grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+    #@cust_bill =
+    #  grep $_->owed != 0 && $_->_date < time - $open, qsearch('cust_bill', {} );
+    $having = $open_sql;
+    $where = "where cust_bill._date < ". (time-$open);
   } else {
     die "unknown query string $query";
   }
+  @cust_bill = qsearch(
+    'cust_bill',
+    {},
+    'cust_bill.*,
+     charged - coalesce(sum(cust_bill_pay.amount),0)
+              - coalesce(sum(cust_credit_bill.amount),0) as owed',
+    "left outer join cust_bill_pay using ( invnum )
+     left outer join cust_credit_bill using ( invnum )
+     $where
+     group by ". join(', ', map "cust_bill.$_", fields('cust_bill') ). ' '.
+     $having
+  );
 } else {
   $cgi->param('invnum') =~ /^\s*(FS-)?(\d+)\s*$/;
-  $invnum = $2;
+  my $invnum = $2;
   @cust_bill = qsearchs('cust_bill', { 'invnum' => $invnum } );
   $sortby = \*invnum_sort;
 }
@@ -64,11 +89,16 @@ if ( scalar(@cust_bill) == 1 ) {
   my $invnum = $cust_bill[0]->invnum;
   print $cgi->redirect(popurl(2). "view/cust_bill.cgi?$invnum");  #redirect
 } elsif ( scalar(@cust_bill) == 0 ) {
+%>
+<!-- mason kludge -->
+<%
   eidiot("Invoice not found.");
 } else {
-  my $total = scalar(@cust_bill);
-  print $cgi->header( '-expires' => 'now' ),
-        &header("Invoice Search Results", menubar(
+%>
+<!-- mason kludge -->
+<%
+  $total = scalar(@cust_bill);
+  print header("Invoice Search Results", menubar(
           'Main Menu', popurl(2)
         )), "$total matching invoices found<BR>", &table(), <<END;
       <TR>
@@ -82,25 +112,29 @@ if ( scalar(@cust_bill) == 1 ) {
 END
 
   my(%saw, $cust_bill);
+  my($tot_balance, $tot_amount) = (0, 0);
   foreach $cust_bill (
     sort $sortby grep(!$saw{$_->invnum}++, @cust_bill)
   ) {
     my($invnum, $owed, $charged, $date ) = (
       $cust_bill->invnum,
-      $cust_bill->owed,
-      $cust_bill->charged,
+      sprintf("%.2f", $cust_bill->owed),
+      sprintf("%.2f", $cust_bill->charged),
       $cust_bill->_date,
     );
     my $pdate = time2str("%b %d %Y", $date);
 
+    $tot_balance += $owed;
+    $tot_amount += $charged;
+
     my $rowspan = 1;
 
     my $view = popurl(2). "view/cust_bill.cgi?$invnum";
     print <<END;
       <TR>
         <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$invnum</FONT></A></TD>
-        <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>\$$owed</FONT></A></TD>
-        <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>\$$charged</FONT></A></TD>
+        <TD ROWSPAN=$rowspan ALIGN="right"><A HREF="$view"><FONT SIZE=-1>\$$owed</FONT></A></TD>
+        <TD ROWSPAN=$rowspan ALIGN="right"><A HREF="$view"><FONT SIZE=-1>\$$charged</FONT></A></TD>
         <TD ROWSPAN=$rowspan><A HREF="$view"><FONT SIZE=-1>$pdate</FONT></A></TD>
 END
     my $custnum = $cust_bill->custnum;
@@ -123,8 +157,11 @@ END
 
     print "</TR>";
   }
-
+  $tot_balance = sprintf("%.2f", $tot_balance);
+  $tot_amount = sprintf("%.2f", $tot_amount);
   print <<END;
+      <TR><TD></TD><TH><FONT SIZE=-1>Total</FONT></TH><TH><FONT SIZE=-1>Total</FONT></TH></TR>
+      <TR><TD></TD><TD ALIGN="right"><FONT SIZE=-1>\$$tot_balance</FONT></TD><TD ALIGN="right"><FONT SIZE=-1>\$$tot_amount</FONT></TD></TD></TR>
     </TABLE>
   </BODY>
 </HTML>