modify backdated payment application behaviour, RT11870
[freeside.git] / FS / FS / cust_main / Billing.pm
index 49ffbfe..a4603df 100644 (file)
@@ -580,27 +580,47 @@ sub bill {
 
 #discard bundled packages of 0 value
 sub _omit_zero_value_bundles {
+  my @in = @_;
 
   my @cust_bill_pkg = ();
   my @cust_bill_pkg_bundle = ();
   my $sum = 0;
   my $discount_show_always = 0;
 
-  foreach my $cust_bill_pkg ( @_ ) {
+  foreach my $cust_bill_pkg ( @in ) {
+
     $discount_show_always = ($cust_bill_pkg->get('discounts')
                                && scalar(@{$cust_bill_pkg->get('discounts')})
                                && $conf->exists('discount-show-always'));
+
+    warn "  pkgnum ". $cust_bill_pkg->pkgnum.
+         " sum $sum, recur_show_zero ". $cust_bill_pkg->recur_show_zero. "\n"
+      if $DEBUG > 0;
+
     if (scalar(@cust_bill_pkg_bundle) && !$cust_bill_pkg->pkgpart_override) {
       push @cust_bill_pkg, @cust_bill_pkg_bundle 
-                       if ($sum > 0 || ($sum == 0 && $discount_show_always));
+        if $sum > 0
+        || ($sum == 0 && (    $discount_show_always
+                           || grep $_->recur_show_zero, @cust_bill_pkg_bundle )
+           );
       @cust_bill_pkg_bundle = ();
       $sum = 0;
     }
+
     $sum += $cust_bill_pkg->setup + $cust_bill_pkg->recur;
     push @cust_bill_pkg_bundle, $cust_bill_pkg;
+
   }
+
   push @cust_bill_pkg, @cust_bill_pkg_bundle
-                       if ($sum > 0 || ($sum == 0 && $discount_show_always));
+    if $sum > 0
+    || ($sum == 0 && (    $discount_show_always
+                       || grep $_->recur_show_zero, @cust_bill_pkg_bundle )
+       );
+
+  warn "  _omit_zero_value_bundles: ". scalar(@in).
+       '->'. scalar(@cust_bill_pkg). "\n" #. Dumper(@cust_bill_pkg). "\n"
+    if $DEBUG > 2;
 
   (@cust_bill_pkg);
 
@@ -828,6 +848,7 @@ sub _make_lines {
 
   my $setup = 0;
   my $unitsetup = 0;
+  my %setup_param = ();
   if (     ! $options{recurring_only}
        and ! $options{cancel}
        and ( $options{'resetup'}
@@ -846,13 +867,16 @@ sub _make_lines {
   {
     
     warn "    bill setup\n" if $DEBUG > 1;
-    $lineitems++;
 
-    $setup = eval { $cust_pkg->calc_setup( $time, \@details ) };
-    return "$@ running calc_setup for $cust_pkg\n"
-      if $@;
+    unless ( $cust_pkg->waive_setup ) {
+        $lineitems++;
+
+        $setup = eval { $cust_pkg->calc_setup( $time, \@details, \%setup_param ) };
+        return "$@ running calc_setup for $cust_pkg\n"
+          if $@;
 
-    $unitsetup = $cust_pkg->part_pkg->unit_setup || $setup; #XXX uuh
+        $unitsetup = $cust_pkg->part_pkg->unit_setup || $setup; #XXX uuh
+    }
 
     $cust_pkg->setfield('setup', $time)
       unless $cust_pkg->setup;
@@ -907,6 +931,7 @@ sub _make_lines {
                   'discounts'           => \@discounts,
                   'real_pkgpart'        => $real_pkgpart,
                   'freq_override'      => $options{freq_override} || '',
+                  %setup_param,
                 );
 
     my $method = $options{cancel} ? 'calc_cancel' : 'calc_recur';
@@ -936,6 +961,12 @@ sub _make_lines {
 
     }
 
+    if ( defined $param{'discount_left_setup'} ) {
+        foreach my $discount_setup ( values %{$param{'discount_left_setup'}} ) {
+            $setup -= $discount_setup;
+        }
+    }
+
   }
 
   warn "\$setup is undefined" unless defined($setup);
@@ -976,10 +1007,12 @@ sub _make_lines {
     my $discount_show_always = ($recur == 0 && scalar(@discounts) 
                                && $conf->exists('discount-show-always'));
 
-    if ( $setup != 0 ||
-         $recur != 0 ||
-         (!$part_pkg->hidden && $options{has_hidden}) || #include some $0 lines
-        $discount_show_always ) 
+    if (    $setup != 0
+         || $recur != 0
+         || (!$part_pkg->hidden && $options{has_hidden}) #include some $0 lines
+         || $discount_show_always
+         || ($recur == 0 && $part_pkg->recur_show_zero)
+       ) 
     {
 
       warn "    charges (setup=$setup, recur=$recur); adding line items\n"
@@ -2077,11 +2110,14 @@ sub apply_payments {
 
     my $amount = min( $payment->unapplied, $owed );
 
-    my $cust_bill_pay = new FS::cust_bill_pay ( {
+    my $cbp = {
       'paynum' => $payment->paynum,
       'invnum' => $cust_bill->invnum,
       'amount' => $amount,
-    } );
+    };
+    $cbp->{_date} = $payment->_date 
+        if $options{'manual'} && $options{'backdate_application'};
+    my $cust_bill_pay = new FS::cust_bill_pay($cbp);
     $cust_bill_pay->pkgnum( $payment->pkgnum )
       if $conf->exists('pkg-balances') && $payment->pkgnum;
     my $error = $cust_bill_pay->insert(%options);