add suspended package browse (closes: Bug#467)
[freeside.git] / httemplate / search / cust_pkg.cgi
index 8a0dfd1..78a5bb3 100755 (executable)
 <%
-# <!-- $Id: cust_pkg.cgi,v 1.4 2001-08-21 02:03:32 ivan Exp $ -->
-
-use strict;
-use vars qw ( $cgi @cust_pkg $sortby $query %part_pkg );
-use CGI;
-use CGI::Carp qw(fatalsToBrowser);
-use FS::UID qw(cgisuidsetup);
-use FS::Record qw(qsearch qsearchs dbdef);
-use FS::CGI qw(header eidiot popurl table);
-use FS::cust_pkg;
-use FS::pkg_svc;
-use FS::cust_svc;
-use FS::cust_main;
-
-$cgi = new CGI;
-&cgisuidsetup($cgi);
+
+my $conf = new FS::Conf;
+my $maxrecords = $conf->config('maxsearchrecordsperpage');
 
 my %part_pkg = map { $_->pkgpart => $_ } qsearch('part_pkg', {});
 
-($query) = $cgi->keywords;
-#this tree is a little bit redundant
-if ( $query eq 'pkgnum' ) {
-  $sortby=\*pkgnum_sort;
-  @cust_pkg=qsearch('cust_pkg',{});
-} elsif ( $query eq 'APKG_pkgnum' ) {
-  $sortby=\*pkgnum_sort;
-  @cust_pkg=();
-  #perhaps this should go in cust_pkg as a qsearch-like constructor?
-  my($cust_pkg);
-  foreach $cust_pkg (qsearch('cust_pkg',{})) {
-    my($flag)=0;
-    my($pkg_svc);
-    PKG_SVC: 
-    foreach $pkg_svc (qsearch('pkg_svc',{ 'pkgpart' => $cust_pkg->pkgpart })) {
-      if ( $pkg_svc->quantity 
-           > scalar(qsearch('cust_svc',{
-               'pkgnum' => $cust_pkg->pkgnum,
-               'svcpart' => $pkg_svc->svcpart,
-             }))
+my $limit = '';
+$limit .= "LIMIT $maxrecords" if $maxrecords;
+
+my $offset = $cgi->param('offset') || 0;
+$limit .= " OFFSET $offset" if $offset;
+
+my $total;
+
+my($query) = $cgi->keywords;
+my $sortby;
+my @cust_pkg;
+
+if ( $cgi->param('magic') && $cgi->param('magic') eq 'bill' ) {
+  $sortby=\*bill_sort;
+  my $range = '';
+  if ( $cgi->param('beginning')
+       && $cgi->param('beginning') =~ /^([ 0-9\-\/]{0,10})$/ ) {
+    my $beginning = str2time($1);
+    $range = " WHERE bill >= $beginning ";
+  }
+  if ( $cgi->param('ending')
+            && $cgi->param('ending') =~ /^([ 0-9\-\/]{0,10})$/ ) {
+    my $ending = str2time($1) + 86400;
+    $range .= ( $range ? ' AND ' : ' WHERE ' ). " bill <= $ending ";
+  }
+
+  #false laziness with below
+  my $statement = "SELECT COUNT(*) FROM cust_pkg $range";
+  warn $statement;
+  my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
+  $sth->execute or die "Error executing \"$statement\": ". $sth->errstr;
+  
+  $total = $sth->fetchrow_arrayref->[0];
+  
+  @cust_pkg = qsearch('cust_pkg',{}, '', " $range ORDER BY bill $limit" );
+
+} else {
+
+  my $qual = '';
+  if ( $query eq 'pkgnum' ) {
+    $sortby=\*pkgnum_sort;
+
+  } elsif ( $query eq 'SUSP_pkgnum' ) {
+
+    $sortby=\*pkgnum_sort;
+
+    $qual = 'WHERE susp IS NOT NULL AND susp != 0';
+
+  } elsif ( $query eq 'APKG_pkgnum' ) {
+  
+    $sortby=\*pkgnum_sort;
+  
+    #@cust_pkg=();
+    ##perhaps this should go in cust_pkg as a qsearch-like constructor?
+    #my($cust_pkg);
+    #foreach $cust_pkg (
+    #  qsearch('cust_pkg',{}, '', "ORDER BY pkgnum $limit" )
+    #) {
+    #  my($flag)=0;
+    #  my($pkg_svc);
+    #  PKG_SVC: 
+    #  foreach $pkg_svc (qsearch('pkg_svc',{ 'pkgpart' => $cust_pkg->pkgpart })) {
+    #    if ( $pkg_svc->quantity 
+    #         > scalar(qsearch('cust_svc',{
+    #             'pkgnum' => $cust_pkg->pkgnum,
+    #             'svcpart' => $pkg_svc->svcpart,
+    #           }))
+    #       )
+    #    {
+    #      $flag=1;
+    #      last PKG_SVC;
+    #    }
+    #  }
+    #  push @cust_pkg, $cust_pkg if $flag;
+    #}
+
+    if ( driver_name eq 'mysql' ) {
+      #$query = "DROP TABLE temp1_$$,temp2_$$;";
+      #my $sth = dbh->prepare($query);
+      #$sth->execute;
+
+      $query = "CREATE TEMPORARY TABLE temp1_$$ TYPE=MYISAM
+                  SELECT cust_svc.pkgnum,cust_svc.svcpart,COUNT(*) as count
+                    FROM cust_pkg,cust_svc,pkg_svc
+                      WHERE cust_pkg.pkgnum = cust_svc.pkgnum
+                      AND cust_svc.svcpart = pkg_svc.svcpart
+                      AND cust_pkg.pkgpart = pkg_svc.pkgpart
+                      GROUP BY cust_svc.pkgnum,cust_svc.svcpart";
+      $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";
+         
+      $sth->execute or die "Error executing \"$query\": ". $sth->errstr;
+  
+      $query = "CREATE TEMPORARY TABLE temp2_$$ TYPE=MYISAM
+                  SELECT cust_pkg.pkgnum FROM cust_pkg
+                    LEFT JOIN pkg_svc ON (cust_pkg.pkgpart=pkg_svc.pkgpart)
+                    LEFT JOIN temp1_$$ ON (cust_pkg.pkgnum = temp1_$$.pkgnum
+                                           AND pkg_svc.svcpart=temp1_$$.svcpart)
+                    WHERE ( pkg_svc.quantity > temp1_$$.count
+                            OR temp1_$$.pkgnum IS NULL )
+                          AND pkg_svc.quantity != 0;";
+      $sth = dbh->prepare($query) or die dbh->errstr. " preparing $query";   
+      $sth->execute or die "Error executing \"$query\": ". $sth->errstr;
+      $qual = " LEFT JOIN temp2_$$ ON cust_pkg.pkgnum = temp2_$$.pkgnum
+                  WHERE temp2_$$.pkgnum IS NOT NULL";
+
+    } else {
+
+     $qual = "
+       WHERE 0 <
+         ( SELECT count(*) FROM pkg_svc
+             WHERE pkg_svc.pkgpart = cust_pkg.pkgpart
+               AND pkg_svc.quantity > ( SELECT count(*) FROM cust_svc
+                                        WHERE cust_svc.pkgnum = cust_pkg.pkgnum
+                                          AND cust_svc.svcpart = pkg_svc.svcpart
+                                      )
          )
-      {
-        $flag=1;
-        last PKG_SVC;
-      }
+     ";
+
     }
-    push @cust_pkg, $cust_pkg if $flag;
+    
+  } else {
+    die "Empty or unknown QUERY_STRING!";
   }
-} else {
-  die "Empty QUERY_STRING!";
+  
+  my $statement = "SELECT COUNT(*) FROM cust_pkg $qual";
+  my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
+  $sth->execute or die "Error executing \"$statement\": ". $sth->errstr;
+  
+  $total = $sth->fetchrow_arrayref->[0];
+
+  my $tblname = driver_name eq 'mysql' ? 'cust_pkg.' : '';
+  @cust_pkg =
+    qsearch('cust_pkg',{}, '', "$qual ORDER BY ${tblname}pkgnum $limit" );
+
+  if ( driver_name eq 'mysql' ) {
+    $query = "DROP TABLE temp1_$$,temp2_$$;";
+    my $sth = dbh->prepare($query) or die dbh->errstr. " doing $query";
+    $sth->execute; # or die "Error executing \"$query\": ". $sth->errstr;
+  }
+  
 }
 
 if ( scalar(@cust_pkg) == 1 ) {
   my($pkgnum)=$cust_pkg[0]->pkgnum;
   print $cgi->redirect(popurl(2). "view/cust_pkg.cgi?$pkgnum");
-  exit;
+  #exit;
 } elsif ( scalar(@cust_pkg) == 0 ) { #error
+%>
+<!-- mason kludge -->
+<%
   eidiot("No packages found");
 } else {
-  my($total)=scalar(@cust_pkg);
-  print $cgi->header( '-expires' => 'now' ),
-        header('Package Search Results',''),
-        "$total matching packages found<BR>", &table(), <<END;
+%>
+<!-- mason kludge -->
+<%
+  $total ||= scalar(@cust_pkg);
+
+  #begin pager
+  my $pager = '';
+  if ( $total != scalar(@cust_pkg) && $maxrecords ) {
+    unless ( $offset == 0 ) {
+      $cgi->param('offset', $offset - $maxrecords);
+      $pager .= '<A HREF="'. $cgi->self_url.
+                '"><B><FONT SIZE="+1">Previous</FONT></B></A> ';
+    }
+    my $poff;
+    my $page;
+    for ( $poff = 0; $poff < $total; $poff += $maxrecords ) {
+      $page++;
+      if ( $offset == $poff ) {
+        $pager .= qq!<FONT SIZE="+2">$page</FONT> !;
+      } else {
+        $cgi->param('offset', $poff);
+        $pager .= qq!<A HREF="!. $cgi->self_url. qq!">$page</A> !;
+      }
+    }
+    unless ( $offset + $maxrecords > $total ) {
+      $cgi->param('offset', $offset + $maxrecords);
+      $pager .= '<A HREF="'. $cgi->self_url.
+                '"><B><FONT SIZE="+1">Next</FONT></B></A> ';
+    }
+  }
+  #end pager
+  
+  print header('Package Search Results',''),
+        "$total matching packages found<BR><BR>$pager", &table(), <<END;
       <TR>
         <TH>Package</TH>
+        <TH><FONT SIZE=-1>Setup</FONT></TH>
+        <TH><FONT SIZE=-1>Next<BR>bill</FONT></TH>
+        <TH><FONT SIZE=-1>Susp.</FONT></TH>
+        <TH><FONT SIZE=-1>Expire</FONT></TH>
+        <TH><FONT SIZE=-1>Cancel</FONT></TH>
         <TH><FONT SIZE=-1>Cust#</FONT></TH>
         <TH>(bill) name</TH>
         <TH>company</TH>
@@ -86,8 +221,24 @@ END
     sort $sortby grep(!$saw{$_->pkgnum}++, @cust_pkg)
   ) {
     my($cust_main)=qsearchs('cust_main',{'custnum'=>$cust_pkg->custnum});
-    my($pkgnum, $custnum, $last, $first, $company) = (
+    my($pkgnum, $setup, $bill, $susp, $expire, $cancel,
+       $custnum, $last, $first, $company ) = (
       $cust_pkg->pkgnum,
+      $cust_pkg->getfield('setup')
+        ? time2str("%D", $cust_pkg->getfield('setup') )
+        : '',
+      $cust_pkg->getfield('bill')
+        ? time2str("%D", $cust_pkg->getfield('bill') )
+        : '',
+      $cust_pkg->getfield('susp')
+        ? time2str("%D", $cust_pkg->getfield('susp') )
+        : '',
+      $cust_pkg->getfield('expire')
+        ? time2str("%D", $cust_pkg->getfield('expire') )
+        : '',
+      $cust_pkg->getfield('cancel')
+        ? time2str("%D", $cust_pkg->getfield('cancel') )
+        : '',
       $cust_pkg->custnum,
       $cust_main ? $cust_main->last : '',
       $cust_main ? $cust_main->first : '',
@@ -118,6 +269,11 @@ END
     my $p = popurl(2);
     print $n1, <<END;
       <TD ROWSPAN=$rowspan><A HREF="${p}view/cust_pkg.cgi?$pkgnum"><FONT SIZE=-1>$pkgnum - $pkg</FONT></A></TD>
+      <TD ROWSPAN=$rowspan>$setup</TD>
+      <TD ROWSPAN=$rowspan>$bill</TD>
+      <TD ROWSPAN=$rowspan>$susp</TD>
+      <TD ROWSPAN=$rowspan>$expire</TD>
+      <TD ROWSPAN=$rowspan>$cancel</TD>
 END
     if ( $cust_main ) {
       print <<END;
@@ -154,11 +310,7 @@ END
   }
     print '</TR>';
  
-  print <<END;
-    </TABLE>
-  </BODY>
-</HTML>
-END
+  print "</TABLE>$pager</BODY></HTML>";
 
 }
 
@@ -166,4 +318,8 @@ sub pkgnum_sort {
   $a->getfield('pkgnum') <=> $b->getfield('pkgnum');
 }
 
+sub bill_sort {
+  $a->getfield('bill') <=> $b->getfield('bill');
+}
+
 %>