[freeside-commits] branch master updated. 41967a7cac39ce2156b9b86436ade82f9a99104e

Mark Wells mark at 420.am
Tue Jun 12 16:34:27 PDT 2012


The branch, master has been updated
       via  41967a7cac39ce2156b9b86436ade82f9a99104e (commit)
      from  cc6bedada3c99e3e9ca4748546f3b4ab847c3cba (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 41967a7cac39ce2156b9b86436ade82f9a99104e
Author: Mark Wells <mark at freeside.biz>
Date:   Tue Jun 12 16:34:18 2012 -0700

    suppress all fractions of days in unearned revenue calculation, #13289

diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index de97a19..b0f20ec 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -122,6 +122,7 @@ if ( -e $addl_handler_use_file ) {
   use FS::UID qw( getotaker dbh datasrc driver_name );
   use FS::Record qw( qsearch qsearchs fields dbdef
                     str2time_sql str2time_sql_closing
+                    midnight_sql
                    );
   use FS::Conf;
   use FS::CGI qw(header menubar table itable ntable idiot
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index dfc2abf..a93a10a 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -39,6 +39,7 @@ use Tie::IxHash;
 @EXPORT_OK = qw(
   dbh fields hfields qsearch qsearchs dbdef jsearch
   str2time_sql str2time_sql_closing regexp_sql not_regexp_sql concat_sql
+  midnight_sql
 );
 
 $DEBUG = 0;
@@ -3030,7 +3031,7 @@ sub not_regexp_sql {
 
 =item concat_sql [ DRIVER_NAME ] ITEMS_ARRAYREF
 
-Returns the items concatendated based on database type, using "CONCAT()" for
+Returns the items concatenated based on database type, using "CONCAT()" for
 mysql and " || " for Pg and other databases.
 
 You can pass an optional driver name such as "Pg", "mysql" or
@@ -3051,6 +3052,24 @@ sub concat_sql {
 
 }
 
+=item midnight_sql DATE
+
+Returns an SQL expression to convert DATE (a unix timestamp) to midnight 
+on that day in the system timezone, using the default driver name.
+
+=cut
+
+sub midnight_sql {
+  my $driver = driver_name;
+  my $expr = shift;
+  if ( $driver =~ /^mysql/i ) {
+    "UNIX_TIMESTAMP(DATE(FROM_UNIXTIME($expr)))";
+  }
+  else {
+    "EXTRACT( EPOCH FROM DATE(TO_TIMESTAMP($expr)) )";
+  }
+}
+
 =back
 
 =head1 BUGS
diff --git a/httemplate/search/prepaid_income.html b/httemplate/search/prepaid_income.html
index d02345e..ebac5a2 100644
--- a/httemplate/search/prepaid_income.html
+++ b/httemplate/search/prepaid_income.html
@@ -56,7 +56,7 @@
 
 <BR>
 <% $actual_label %><% $actual_label ? 'u' : 'U' %>nearned revenue
-is the amount of unearned revenue
+is the as-yet-unearned portion of revenue
 <% $actual_label ? 'Freeside has actually' : '' %>
 invoiced for packages with 
 <% $cgi->param('include_monthly') ? 'terms extending into the future.'
@@ -148,17 +148,20 @@ foreach my $agentnum (@agentnums) {
   } elsif ( $mode eq 'paid' ) {
     $unearned_base = FS::cust_bill_pkg->paid_sql(@opt);
   }
-  my $period = "CAST(cust_bill_pkg.edate - cust_bill_pkg.sdate AS REAL)";
-  my $elapsed  = "GREATEST( $now - cust_bill_pkg.sdate, 0 )";
-  my $remaining = "(1 - $elapsed/$period)";
-
+  
+  my $edate_zero = midnight_sql('edate');
+  my $sdate_zero = midnight_sql('sdate');
+  my $period = "CAST( ($edate_zero - $sdate_zero) / 86400.0 AS DECIMAL(10,0) )";
+  my $remaining = "GREATEST(
+    CAST( ($edate_zero - $now) / 86400.0 AS DECIMAL(10,0) ),
+    0)";
+  my $fraction = "$remaining / $period";
+  
   my $unearned_sql = "CAST(
-  GREATEST( $unearned_base * $remaining, 0 )
+  GREATEST( $unearned_base * $fraction, 0 )
     AS DECIMAL(10,2)
   )";
 
-  my $float = 'REAL'; #'DOUBLE PRECISION';
-  
   my $select = "SUM( $unearned_sql )";
 
   if ( !$cgi->param('include_monthly') ) {
@@ -186,7 +189,6 @@ foreach my $agentnum (@agentnums) {
                  $where
              ";
 
-             warn $sql;
   my $sth = dbh->prepare($sql) or die dbh->errstr;
   $sth->execute or die $sth->errstr;
   my $total = $sth->fetchrow_arrayref->[0];
diff --git a/httemplate/search/unearned_detail.html b/httemplate/search/unearned_detail.html
index 831625e..02d514c 100644
--- a/httemplate/search/unearned_detail.html
+++ b/httemplate/search/unearned_detail.html
@@ -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
@@ -167,11 +168,19 @@ 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.
 
-$unearned_sql = "CAST( $unearned_base * $remaining AS DECIMAL(10,2) )";
+# 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 * $fraction AS DECIMAL(10,2) )";
 push @select, "$unearned_sql AS unearned_revenue";
 
 # last payment/credit date
@@ -187,6 +196,8 @@ foreach my $x (qw(pay credit)) {
   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

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Mason.pm                         |    1 +
 FS/FS/Record.pm                        |   21 ++++++++++++++++++++-
 httemplate/search/prepaid_income.html  |   20 +++++++++++---------
 httemplate/search/unearned_detail.html |   25 ++++++++++++++++++-------
 4 files changed, 50 insertions(+), 17 deletions(-)




More information about the freeside-commits mailing list