[freeside-commits] branch FREESIDE_2_3_BRANCH updated. 14f3259eef6cbc440a9ce0cdc20ee2cde87c41b0

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


The branch, FREESIDE_2_3_BRANCH has been updated
       via  14f3259eef6cbc440a9ce0cdc20ee2cde87c41b0 (commit)
      from  db7d5ea2de851705fb4dbe2bd23b07476110e20c (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 14f3259eef6cbc440a9ce0cdc20ee2cde87c41b0
Author: Mark Wells <mark at freeside.biz>
Date:   Tue Jun 12 16:32:30 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 a465063..045a5b1 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 a8b912c..3667d51 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -38,6 +38,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;
@@ -3245,7 +3246,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
@@ -3266,6 +3267,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