[freeside-commits] freeside/FS/FS cust_credit.pm, 1.24.2.7, 1.24.2.8 cust_main.pm, 1.271.2.37, 1.271.2.38 cust_refund.pm, 1.29, 1.29.2.1 cust_pay.pm, 1.50.2.5, 1.50.2.6

Ivan,,, ivan at wavetail.420.am
Tue Jan 8 03:28:38 PST 2008


Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail:/tmp/cvs-serv32403/FS/FS

Modified Files:
      Tag: FREESIDE_1_7_BRANCH
	cust_credit.pm cust_main.pm cust_refund.pm cust_pay.pm 
Log Message:
show negative balances on A/R report, closes: RT#2983

Index: cust_pay.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_pay.pm,v
retrieving revision 1.50.2.5
retrieving revision 1.50.2.6
diff -u -d -r1.50.2.5 -r1.50.2.6
--- cust_pay.pm	29 Nov 2007 02:55:08 -0000	1.50.2.5
+++ cust_pay.pm	8 Jan 2008 11:28:36 -0000	1.50.2.6
@@ -620,6 +620,36 @@
 
 =back
 
+=head1 CLASS METHODS
+
+=over 4
+
+=item unapplied_sql
+
+Returns an SQL fragment to retreive the unapplied amount.
+
+=cut 
+
+sub unapplied_sql {
+  #my $class = shift;
+
+  "paid
+        - COALESCE( 
+                    ( SELECT SUM(amount) FROM cust_bill_pay
+                        WHERE cust_pay.paynum = cust_bill_pay.paynum )
+                    ,0
+                  )
+        - COALESCE(
+                    ( SELECT SUM(amount) FROM cust_pay_refund
+                        WHERE cust_pay.paynum = cust_pay_refund.paynum )
+                    ,0
+                  )
+  ";
+
+}
+
+=back
+
 =head1 BUGS
 
 Delete and replace methods.  

Index: cust_refund.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_refund.pm,v
retrieving revision 1.29
retrieving revision 1.29.2.1
diff -u -d -r1.29 -r1.29.2.1
--- cust_refund.pm	8 Jan 2007 17:36:52 -0000	1.29
+++ cust_refund.pm	8 Jan 2008 11:28:36 -0000	1.29.2.1
@@ -307,6 +307,36 @@
 
 =back
 
+=head1 CLASS METHODS
+
+=over 4
+
+=item unapplied_sql
+
+Returns an SQL fragment to retreive the unapplied amount.
+
+=cut 
+
+sub unapplied_sql {
+  #my $class = shift;
+
+  "refund
+    - COALESCE( 
+                ( SELECT SUM(amount) FROM cust_credit_refund
+                    WHERE cust_refund.refundnum = cust_credit_refund.refundnum )
+                ,0
+              )
+    - COALESCE(
+                ( SELECT SUM(amount) FROM cust_pay_refund
+                    WHERE cust_refund.refundnum = cust_pay_refund.refundnum )
+                ,0
+              )
+  ";
+
+}
+
+=back
+
 =head1 BUGS
 
 Delete and replace methods.

Index: cust_credit.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_credit.pm,v
retrieving revision 1.24.2.7
retrieving revision 1.24.2.8
diff -u -d -r1.24.2.7 -r1.24.2.8
--- cust_credit.pm	19 Dec 2007 01:55:57 -0000	1.24.2.7
+++ cust_credit.pm	8 Jan 2008 11:28:35 -0000	1.24.2.8
@@ -331,15 +331,15 @@
   ;
 }
 
-=item credited
+=item unapplied
 
-Returns the amount of this credit that is still outstanding; which is
+Returns the amount of this credit that is still unapplied/outstanding; 
 amount minus all refund applications (see L<FS::cust_credit_refund>) and
 applications to invoices (see L<FS::cust_credit_bill>).
 
 =cut
 
-sub credited {
+sub unapplied {
   my $self = shift;
   my $amount = $self->amount;
   $amount -= $_->amount foreach ( $self->cust_credit_refund );
@@ -347,6 +347,18 @@
   sprintf( "%.2f", $amount );
 }
 
+=item credited
+
+Deprecated name for the unapplied method.
+
+=cut
+
+sub credited {
+  my $self = shift;
+  #carp "cust_credit->credited deprecated; use ->unapplied";
+  $self->unapplied(@_);
+}
+
 =item cust_main
 
 Returns the customer (see L<FS::cust_main>) for this credit.
@@ -524,10 +536,58 @@
 
 =back
 
+=head1 CLASS METHODS
+
+=over 4
+
+=item unapplied_sql
+
+Returns an SQL fragment to retreive the unapplied amount.
+
+=cut
+
+sub unapplied_sql {
+  #my $class = shift;
+
+  "amount
+        - COALESCE(
+                    ( SELECT SUM(amount) FROM cust_credit_refund
+                        WHERE cust_credit.crednum = cust_credit_refund.crednum )
+                    ,0
+                  )
+        - COALESCE(
+                    ( SELECT SUM(amount) FROM cust_credit_bill
+                        WHERE cust_credit.crednum = cust_credit_bill.crednum )
+                    ,0
+                  )
+  ";
+
+}
+
+=item credited_sql
+
+Deprecated name for the unapplied_sql method.
+
+=cut
+
+sub credited_sql {
+  #my $class = shift;
+
+  #carp "cust_credit->credited_sql deprecated; use ->unapplied_sql";
+
+  #$class->unapplied_sql(@_);
+  unapplied_sql();
+}
+
+=back
+
 =head1 BUGS
 
 The delete method.  The replace method.
 
+B<credited> and B<credited_sql> are now called B<unapplied> and
+B<unapplied_sql>.  The old method names should start to give warnings.
+
 =head1 SEE ALSO
 
 L<FS::Record>, L<FS::cust_credit_refund>, L<FS::cust_refund>,

Index: cust_main.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/cust_main.pm,v
retrieving revision 1.271.2.37
retrieving revision 1.271.2.38
diff -u -d -r1.271.2.37 -r1.271.2.38
--- cust_main.pm	21 Dec 2007 21:38:10 -0000	1.271.2.37
+++ cust_main.pm	8 Jan 2008 11:28:35 -0000	1.271.2.38
@@ -3767,17 +3767,38 @@
   sprintf( "%.2f", $total_unapplied );
 }
 
+=item total_unapplied_refunds
+
+Returns the total unrefunded refunds (see L<FS::cust_refund>) for this
+customer.  See L<FS::cust_refund/unapplied>.
+
+=cut
+
+sub total_unapplied_refunds {
+  my $self = shift;
+  my $total_unapplied = 0;
+  foreach my $cust_refund ( qsearch('cust_refund', {
+    'custnum' => $self->custnum,
+  } ) ) {
+    $total_unapplied += $cust_refund->unapplied;
+  }
+  sprintf( "%.2f", $total_unapplied );
+}
+
 =item balance
 
-Returns the balance for this customer (total_owed minus total_credited
-minus total_unapplied_payments).
+Returns the balance for this customer (total_owed plus total_unrefunded, minus
+total_credited minus total_unapplied_payments).
 
 =cut
 
 sub balance {
   my $self = shift;
   sprintf( "%.2f",
-    $self->total_owed - $self->total_credited - $self->total_unapplied_payments
+      $self->total_owed
+    + $self->total_unapplied_refunds
+    - $self->total_credited
+    - $self->total_unapplied_payments
   );
 }
 
@@ -3795,7 +3816,8 @@
   my $self = shift;
   my $time = shift;
   sprintf( "%.2f",
-    $self->total_owed_date($time)
+        $self->total_owed_date($time)
+      + $self->total_unapplied_refunds
       - $self->total_credited
       - $self->total_unapplied_payments
   );
@@ -4514,58 +4536,99 @@
 =cut
 
 sub balance_sql { "
-    COALESCE( ( SELECT SUM(charged) FROM cust_bill
-                  WHERE cust_bill.custnum   = cust_main.custnum ), 0)
-  - COALESCE( ( SELECT SUM(paid)    FROM cust_pay
-                  WHERE cust_pay.custnum    = cust_main.custnum ), 0)
-  - COALESCE( ( SELECT SUM(amount)  FROM cust_credit
-                  WHERE cust_credit.custnum = cust_main.custnum ), 0)
-  + COALESCE( ( SELECT SUM(refund)  FROM cust_refund
-                   WHERE cust_refund.custnum = cust_main.custnum ), 0)
+    ( SELECT COALESCE( SUM(charged), 0 ) FROM cust_bill
+        WHERE cust_bill.custnum   = cust_main.custnum     )
+  - ( SELECT COALESCE( SUM(paid),    0 ) FROM cust_pay
+        WHERE cust_pay.custnum    = cust_main.custnum     )
+  - ( SELECT COALESCE( SUM(amount),  0 ) FROM cust_credit
+        WHERE cust_credit.custnum = cust_main.custnum     )
+  + ( SELECT COALESCE( SUM(refund),  0 ) FROM cust_refund
+        WHERE cust_refund.custnum = cust_main.custnum     )
 "; }
 
-=item balance_date_sql TIME
+=item balance_date_sql START_TIME [ END_TIME [ OPTION => VALUE ... ] ]
 
 Returns an SQL fragment to retreive the balance for this customer, only
-considering invoices with date earlier than TIME. (total_owed_date minus total_credited minus
-total_unapplied_payments).  TIME is specified as an SQL fragment or a numeric
-UNIX timestamp; see L<perlfunc/"time">).  Also see L<Time::Local> and
-L<Date::Parse> for conversion functions.
+considering invoices with date earlier than START_TIME, and optionally not
+later than END_TIME (total_owed_date minus total_credited minus
+total_unapplied_payments).
+
+Times are specified as SQL fragments or numeric
+UNIX timestamps; see L<perlfunc/"time">).  Also see L<Time::Local> and
+L<Date::Parse> for conversion functions.  The empty string can be passed
+to disable that time constraint completely.
+
+Available options are:
+
+=over 4
+
+=item unapplied_date - set to true to disregard unapplied credits, payments and refunds outside the specified time period - by default the time period restriction only applies to invoices (useful for reporting, probably a bad idea for event triggering)
+
+=item total - set to true to remove all customer comparison clauses, for totals
+
+=item where - WHERE clause hashref (elements "AND"ed together) (typically used with the total option)
+
+=item join - JOIN clause (typically used with the total option)
+
+=item 
+
+=back
 
 =cut
 
 sub balance_date_sql {
-  my( $class, $time ) = @_;
+  my( $class, $start, $end, %opt ) = @_;
 
-  my $owed_sql         = FS::cust_bill->owed_sql;
-  my $unapp_refund_sql = FS::cust_refund->unapplied_sql;
-  #my $unapp_credit_sql = FS::cust_credit->unapplied_sql;
-  my $unapp_credit_sql = FS::cust_credit->credited_sql;
-  my $unapp_pay_sql    = FS::cust_pay->unapplied_sql;
+  my $owed         = FS::cust_bill->owed_sql;
+  my $unapp_refund = FS::cust_refund->unapplied_sql;
+  my $unapp_credit = FS::cust_credit->unapplied_sql;
+  my $unapp_pay    = FS::cust_pay->unapplied_sql;
 
-  "
-      COALESCE( ( SELECT SUM($owed_sql) FROM cust_bill
-                    WHERE cust_bill.custnum   = cust_main.custnum
-                      AND cust_bill._date    <= $time             )
-                ,0
-              )
-    + COALESCE( ( SELECT SUM($unapp_refund_sql) FROM cust_refund
-                    WHERE cust_refund.custnum = cust_main.custnum )
-                ,0
-              )
-    - COALESCE( ( SELECT SUM($unapp_credit_sql) FROM cust_credit
-                    WHERE cust_credit.custnum = cust_main.custnum )
-                ,0
-              )
-    - COALESCE( ( SELECT SUM($unapp_pay_sql) FROM cust_pay
-                    WHERE cust_pay.custnum = cust_main.custnum )
-                ,0
-              )
+  my $j = $opt{'join'} || '';
+
+  my $owed_wh   = $class->_money_table_where( 'cust_bill',   $start,$end,%opt );
+  my $refund_wh = $class->_money_table_where( 'cust_refund', $start,$end,%opt );
+  my $credit_wh = $class->_money_table_where( 'cust_credit', $start,$end,%opt );
+  my $pay_wh    = $class->_money_table_where( 'cust_pay',    $start,$end,%opt );
 
+  "   ( SELECT COALESCE(SUM($owed),         0) FROM cust_bill   $j $owed_wh   )
+    + ( SELECT COALESCE(SUM($unapp_refund), 0) FROM cust_refund $j $refund_wh )
+    - ( SELECT COALESCE(SUM($unapp_credit), 0) FROM cust_credit $j $credit_wh )
+    - ( SELECT COALESCE(SUM($unapp_pay),    0) FROM cust_pay    $j $pay_wh    )
   ";
 
 }
 
+=item _money_table_where TABLE START_TIME [ END_TIME [ OPTION => VALUE ... ] ]
+
+Helper method for balance_date_sql; name (and usage) subject to change
+(suggestions welcome).
+
+Returns a WHERE clause for the specified monetary TABLE (cust_bill,
+cust_refund, cust_credit or cust_pay).
+
+If TABLE is "cust_bill" or the unapplied_date option is true, only
+considers records with date earlier than START_TIME, and optionally not
+later than END_TIME .
+
+=cut
+
+sub _money_table_where {
+  my( $class, $table, $start, $end, %opt ) = @_;
+
+  my @where = ();
+  push @where, "cust_main.custnum = $table.custnum" unless $opt{'total'};
+  if ( $table eq 'cust_bill' || $opt{'unapplied_date'} ) {
+    push @where, "$table._date <= $start" if length($start);
+    push @where, "$table._date >  $end"   if length($end);
+  }
+  push @where, @{$opt{'where'}} if $opt{'where'};
+  my $where = scalar(@where) ? 'WHERE '. join(' AND ', @where ) : '';
+
+  $where;
+
+}
+
 =item fuzzy_search FUZZY_HASHREF [ HASHREF, SELECT, EXTRA_SQL, CACHE_OBJ ]
 
 Performs a fuzzy (approximate) search and returns the matching FS::cust_main



More information about the freeside-commits mailing list