quiet warnings about CGI::param in list context
[freeside.git] / httemplate / search / unearned_detail.html
index 831625e..b87a747 100644 (file)
@@ -1,5 +1,6 @@
 <& elements/search.html,
-  'title'       => emt("Unearned revenue - ".ucfirst($unearned_mode)),
+  'title'       => emt("Unearned revenue - ".ucfirst($unearned_mode)) . ' (' .
+                   time2str('%b %d %Y', $unearned) . ')',
   'name'        => emt('line items'),
   'query'       => $query,
   'count_query' => $count_query,
@@ -41,8 +42,8 @@
     date_sub('last_credit'),
     #Charge start
     date_sub('sdate'),
-    #Charge end
-    date_sub('edate'),
+    #Charge end, minus most of a day
+    date_sub('before_edate'),
     #Invoice
     'invnum',
     #Invoice date
@@ -104,6 +105,10 @@ my $agentnums_sql =
 
 my @where = ( $agentnums_sql );
 
+if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
+  push @where, "cust_main.agentnum = $1";
+}
+
 my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi);
 
 if ( $cgi->param('status') =~ /^([a-z]+)$/ ) {
@@ -113,8 +118,13 @@ if ( $cgi->param('status') =~ /^([a-z]+)$/ ) {
 push @where, "cust_bill._date >= $beginning",
              "cust_bill._date <= $ending";
 
-if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
-  push @where, "cust_main.agentnum = $1";
+# cust_classnum (false laziness w/ elements/cust_main_dayranges.html, elements/cust_pay_or_refund.html, prepaid_income.html, cust_bill_pay.html, cust_bill_pkg.html, cust_bill_pkg_referral.html, cust_credit.html, cust_credit_refund.html, cust_main::Search::search_sql)
+if ( grep { $_ eq 'cust_classnum' } $cgi->param ) {
+  my @classnums = grep /^\d*$/, $cgi->param('cust_classnum');
+  push @where, 'COALESCE( cust_main.classnum, 0) IN ( '.
+                   join(',', map { $_ || '0' } @classnums ).
+               ' )'
+    if @classnums;
 }
 
 # no pkgclass, no taxclass, no tax location...
@@ -167,34 +177,48 @@ else {
 # whatever we're using as the base, only show rows where it's positive
 push @where, "$unearned_base > 0";
 
-my $period = "CAST(cust_bill_pkg.edate - cust_bill_pkg.sdate AS REAL)";
-my $elapsed = "GREATEST( $unearned - cust_bill_pkg.sdate, 0 )";
-my $remaining = "(1 - $elapsed/$period)";
+my $edate_zero = midnight_sql('edate');
+my $sdate_zero = midnight_sql('sdate');
+# $unearned is one second before midnight on the date requested for the report.
+
+# suppress partial days for more accounting-like behavior
+my $period = "CAST( ($edate_zero - $sdate_zero) / 86400.0 AS DECIMAL(10,0) )";
+
+my $remaining = "GREATEST( 
+  CAST( ($edate_zero - $unearned) / 86400.0 AS DECIMAL(10,0) ),
+  0)";
+my $fraction = "$remaining / $period";
 
-$unearned_sql = "CAST( $unearned_base * $remaining AS DECIMAL(10,2) )";
+$unearned_sql = "CAST( $unearned_base * $fraction AS DECIMAL(10,2) )";
 push @select, "$unearned_sql AS unearned_revenue";
 
 # last payment/credit date
 my %t = (pay => 'cust_bill_pay', credit => 'cust_credit_bill');
 foreach my $x (qw(pay credit)) {
-  my $table = $t{$x};
-  my $link = $table.'_pkg';
-  my $pkey = dbdef->table($table)->primary_key;
-  my $last_date_sql = "SELECT MAX(_date) 
-  FROM $table JOIN $link USING ($pkey)
-  WHERE $link.billpkgnum = cust_bill_pkg.billpkgnum 
+  my $table     = "cust_$x";
+  my $link_bill = $t{$x};
+  my $link_pkg  = $link_bill.'_pkg';
+  my %pkey = map { $_ => dbdef->table($_)->primary_key }
+    ( $table, $link_bill );
+
+  my $last_date_sql = "SELECT MAX($table._date) 
+  FROM $table JOIN $link_bill USING ($pkey{$table})
+              JOIN $link_pkg  USING ($pkey{$link_bill})
+  WHERE $link_pkg.billpkgnum = cust_bill_pkg.billpkgnum 
   AND $table._date <= $unearned";
   push @select, "($last_date_sql) AS last_$x";
 }
 
+push @select, '(edate - 82799) AS before_edate';
+
 #no itemdesc
 #no tax report group kludge
 #no tax exemption
 #usage always excluded
 
 # always 'nottax', not 'istax'
-$join_cust =  '        JOIN cust_bill USING ( invnum )
-                  LEFT JOIN cust_main USING ( custnum ) ';
+$join_cust =  '        JOIN cust_bill USING ( invnum ) '.
+                  FS::UI::Web::join_cust_main('cust_pkg', 'cust_pkg');
 
 $join_pkg .=  ' LEFT JOIN cust_pkg USING ( pkgnum )
                 LEFT JOIN part_pkg USING ( pkgpart )
@@ -205,7 +229,7 @@ my $where = ' WHERE '. join(' AND ', @where);
 
 my $count_query = "SELECT COUNT(DISTINCT billpkgnum), 
   SUM( $unearned_base ), SUM( $unearned_sql )
-  FROM cust_bill_pkg $join_cust $join_pkg $where";
+  FROM cust_bill_pkg $join_pkg $join_cust $where";
 
 push @select, 'part_pkg.pkg',
               'part_pkg.freq',
@@ -214,7 +238,7 @@ push @select, 'part_pkg.pkg',
 
 my $query = {
   'table'     => 'cust_bill_pkg',
-  'addl_from' => "$join_cust $join_pkg",
+  'addl_from' => "$join_pkg $join_cust",
   'hashref'   => {},
   'select'    => join(",\n", @select ),
   'extra_sql' => $where,
@@ -224,7 +248,8 @@ my $query = {
 my $ilink = [ "${p}view/cust_bill.cgi?", 'invnum' ];
 my $clink = [ "${p}view/cust_main.cgi?", 'custnum' ];
 
-my $money_char;
+my $conf = new FS::Conf;
+my $money_char = $conf->config('money_char') || '$';
 
 sub money_sub {
   $conf ||= new FS::Conf;