calculate unitrecur on sql_external packages with quantity details, #40558
[freeside.git] / FS / FS / cust_main / Billing.pm
index d3c618d..d953767 100644 (file)
@@ -999,9 +999,10 @@ sub _make_lines {
   #   - it doesn't already HAVE a setup date
   #   - or a start date in the future
   #   - and it's not suspended
+  # - and it doesn't have an expire date in the past
   #
-  # The last condition used to check the "disable_setup_suspended" option but 
-  # that's obsolete. We now never set the setup date on a suspended package.
+  # The "disable_setup_suspended" option is now obsolete; we never set the
+  # setup date on a suspended package.
   if (     ! $options{recurring_only}
        and ! $options{cancel}
        and ( $options{'resetup'}
@@ -1012,6 +1013,8 @@ sub _make_lines {
                   && ( ! $cust_pkg->getfield('susp') )
                 )
            )
+       and ( ! $cust_pkg->expire
+             || $cust_pkg->expire > $cmp_time )
      )
   {
     
@@ -1039,10 +1042,15 @@ sub _make_lines {
         }
     }
 
-    $cust_pkg->setfield('setup', $time)
-      unless $cust_pkg->setup;
-          #do need it, but it won't get written to the db
-          #|| $cust_pkg->pkgpart != $real_pkgpart;
+    if ( $cust_pkg->get('setup') ) {
+      # don't change it
+    } elsif ( $cust_pkg->get('start_date') ) {
+      # this allows start_date to be used to set the first bill date
+      $cust_pkg->set('setup', $cust_pkg->get('start_date'));
+    } else {
+      # if unspecified, start it right now
+      $cust_pkg->set('setup', $time);
+    }
 
     $cust_pkg->setfield('start_date', '')
       if $cust_pkg->start_date;
@@ -1059,6 +1067,23 @@ sub _make_lines {
   my $recur_billed_currency = '';
   my $recur_billed_amount = 0;
   my $sdate;
+
+  my $override_quantity;
+
+  # Conditions for billing the recurring fee:
+  # - the package doesn't have a future start date
+  # - and it's not suspended
+  #   - unless suspend_bill is enabled on the package or package def
+  #     - but still not, if the package is on hold
+  #   - or it's suspended for a delayed cancellation
+  # - and its next bill date is in the past
+  #   - or it doesn't have a next bill date yet
+  #   - or it's a one-time charge
+  #   - or it's a CDR plan with the "bill_every_call" option
+  #   - or it's being canceled
+  # - and it doesn't have an expire date in the past (this can happen with
+  #   advance billing)
+  #   - again, unless it's being canceled
   if (     ! $cust_pkg->start_date
        and 
            ( ! $cust_pkg->susp
@@ -1077,6 +1102,12 @@ sub _make_lines {
                && $part_pkg->option('bill_every_call')
             )
          || $options{cancel}
+
+       and
+          ( ! $cust_pkg->expire
+            || $cust_pkg->expire > $cmp_time
+            || $options{cancel}
+          )
   ) {
 
     # XXX should this be a package event?  probably.  events are called
@@ -1139,6 +1170,11 @@ sub _make_lines {
       $recur_billed_amount   = delete $param{'billed_amount'};
     }
 
+    if ( $param{'override_quantity'} ) {
+      $override_quantity = $param{'override_quantity'};
+      $unitrecur = $recur / $override_quantity;
+    }
+
     if ( $increment_next_bill ) {
 
       my $next_bill;
@@ -1213,7 +1249,7 @@ sub _make_lines {
         }
     }
 
-  }
+  } # end of recurring fee
 
   warn "\$setup is undefined" unless defined($setup);
   warn "\$recur is undefined" unless defined($recur);
@@ -1277,14 +1313,14 @@ sub _make_lines {
       my $cust_bill_pkg = new FS::cust_bill_pkg {
         'pkgnum'                => $cust_pkg->pkgnum,
         'setup'                 => $setup,
-        'unitsetup'             => $unitsetup,
+        'unitsetup'             => sprintf('%.2f', $unitsetup),
         'setup_billed_currency' => $setup_billed_currency,
         'setup_billed_amount'   => $setup_billed_amount,
         'recur'                 => $recur,
-        'unitrecur'             => $unitrecur,
+        'unitrecur'             => sprintf('%.2f', $unitrecur),
         'recur_billed_currency' => $recur_billed_currency,
         'recur_billed_amount'   => $recur_billed_amount,
-        'quantity'              => $cust_pkg->quantity,
+        'quantity'              => $override_quantity || $cust_pkg->quantity,
         'details'               => \@details,
         'discounts'             => [ @setup_discounts, @recur_discounts ],
         'hidden'                => $part_pkg->hidden,