optimize Reports->Customers->List Customers, RT#20173
[freeside.git] / FS / FS / part_pkg / flat.pm
index 22eb698..da1f0ad 100644 (file)
@@ -120,9 +120,7 @@ sub calc_setup {
     push @$details, $self->option( 'additional_info' . $i++ );
   }
 
-  my $quantity = $cust_pkg->quantity || 1;
-
-  my $charge = $quantity * $self->unit_setup($cust_pkg, $sdate, $details);
+  my $charge = $self->unit_setup($cust_pkg, $sdate, $details);
 
   my $discount = 0;
   if ( $charge > 0 ) {
@@ -131,13 +129,16 @@ sub calc_setup {
       delete $param->{'setup_charge'};
   }
 
-  sprintf('%.2f', $charge - $discount);
+  sprintf( '%.2f', ($cust_pkg->quantity || 1) * ($charge - $discount) );
 }
 
 sub unit_setup {
   my($self, $cust_pkg, $sdate, $details ) = @_;
-
-  $self->option('setup_fee') || 0;
+  ( exists( $self->{'Hash'}{'_opt_setup_fee'} )
+      ? $self->{'Hash'}{'_opt_setup_fee'}
+      : $self->option('setup_fee', 1) 
+  )
+    || 0;
 }
 
 sub calc_recur {
@@ -162,11 +163,9 @@ sub calc_recur {
     $charge *= $param->{freq_override} if $param->{freq_override};
   }
 
-  my $quantity = $cust_pkg->quantity || 1;
-  $charge *= $quantity;
-
   my $discount = $self->calc_discount($cust_pkg, $sdate, $details, $param);
-  return sprintf('%.2f', $charge - $discount);
+
+  sprintf( '%.2f', ($cust_pkg->quantity || 1) * ($charge - $discount) );
 }
 
 sub cutoff_day {
@@ -175,6 +174,12 @@ sub cutoff_day {
   if ( $self->option('sync_bill_date',1) ) {
     my $next_bill = $cust_pkg->cust_main->next_bill_date;
     if ( defined($next_bill) ) {
+      # careful here. if the prorate calculation is going to round to 
+      # the nearest day, this needs to always return the same result
+      if ( $self->option('prorate_round_day', 1) ) {
+        my $hour = (localtime($next_bill))[2];
+        $next_bill += 64800 if $hour >= 12;
+      }
       return (localtime($next_bill))[3];
     }
   }
@@ -183,7 +188,11 @@ sub cutoff_day {
 
 sub base_recur {
   my($self, $cust_pkg, $sdate) = @_;
-  $self->option('recur_fee', 1) || 0;
+  ( exists( $self->{'Hash'}{'_opt_recur_fee'} )
+      ? $self->{'Hash'}{'_opt_recur_fee'}
+      : $self->option('recur_fee', 1) 
+  )
+    || 0;
 }
 
 sub base_recur_permonth {
@@ -201,13 +210,13 @@ sub calc_cancel {
        and $self->option('bill_recur_on_cancel', 1) ) {
     # run another recurring cycle
     return $self->calc_recur(@_);
-  }
-  elsif ( $conf->exists('bill_usage_on_cancel') # should be a package option?
+  } elsif ( $conf->exists('bill_usage_on_cancel') # should be a package option?
           and $self->can('calc_usage') ) {
     # bill for outstanding usage
     return $self->calc_usage(@_);
+  } else {
+    return 'NOTHING'; # numerically zero, but has special meaning
   }
-  0;
 }
 
 sub calc_remain {
@@ -257,7 +266,16 @@ sub is_free_options {
 
 sub is_prepaid { 0; } #no, we're postpaid
 
-sub can_start_date { ! shift->option('start_1st', 1) }
+sub can_start_date {
+  my $self = shift;
+  my %opt = @_;
+  return 0 if $self->start_on_hold;
+
+  ! $self->option('start_1st', 1) && (   ! $self->option('sync_bill_date',1)
+                                      || ! $self->option('prorate_defer_bill',1)
+                                      || ! $opt{'num_ncancelled_pkgs'}
+                                     ); 
+}
 
 sub can_discount { 1; }