in rated CDR packages, multiply included minutes by package quantity, #71003
[freeside.git] / FS / FS / part_pkg / voip_tiered.pm
index 29e60d4..0ad0ff6 100644 (file)
@@ -81,6 +81,7 @@ sub calc_usage {
     && ( $last_bill eq '' || $last_bill == 0 );
 
   my $included_min    = $self->option('min_included', 1) || 0;
+  $included_min *= ($cust_pkg->quantity || 1);
   my $cdr_svc_method  = $self->option('cdr_svc_method',1)||'svc_phone.phonenum';
   my $cdr_inout       = ($cdr_svc_method eq 'svc_phone.phonenum')
                           && $self->option('cdr_inout',1)
@@ -98,6 +99,7 @@ sub calc_usage {
   my %options = (
     'disable_src'    => $self->option('disable_src'),
     'default_prefix' => $self->option('default_prefix'),
+    'cdrtypenum'     => $self->option('use_cdrtypenum'),
     'status'         => '',
     'for_update'     => 1,
   );  # $last_bill, $$sdate )
@@ -107,7 +109,6 @@ sub calc_usage {
   # pass one: find the total minutes/calls and store the CDRs
   ###
   my $total = 0;
-  my @cdrs = ();
 
   my @cust_svc;
   if( $self->option('bill_inactive_svcs',1) ) {
@@ -132,9 +133,11 @@ sub calc_usage {
 
       $options{'inbound'} = ( $pass eq 'inbound' );
 
-      foreach my $cdr (
-        $svc_x->get_cdrs( %options )
-      ) {
+      my $cdr_search = $svc_x->psearch_cdrs(%options);
+      $cdr_search->limit(1000);
+      $cdr_search->increment(0);
+      while ( my $cdr = $cdr_search->fetch ) {
+
         if ( $DEBUG > 1 ) {
           warn "rating CDR $cdr\n".
                join('', map { "  $_ => ". $cdr->{$_}. "\n" } keys %$cdr );
@@ -161,13 +164,20 @@ sub calc_usage {
            $included_min = 0;
         }
 
-        $cdr->tmp_inout( $pass );
-        $cdr->tmp_rated_seconds( $seconds );
-        $cdr->tmp_rated_minutes( $charge_min );
-        $cdr->tmp_svcnum( $cust_svc->svcnum );
-        push @cdrs, $cdr;
+        my $error = $cdr->set_status_and_rated_price(
+          'processing-tiered',
+          '', #charge,
+          $cust_svc->svcnum,
+          'inbound'       => ($pass eq 'inbound'),
+          'rated_minutes' => $charge_min,
+          'rated_seconds' => $seconds,
+        );
+        die $error if $error;
+
         $total += $charge_min;
 
+        $cdr_search->adjust(1) if $cdr->freesidestatus eq '';
+
       } # $cdr
 
     } # $pass
@@ -186,70 +196,68 @@ sub calc_usage {
 
   my $output_format = $self->option('output_format', 'Hush!') || 'default';
 
-  my $csv = new Text::CSV_XS;
+  my $formatter = FS::detail_format->new($output_format, buffer => $details);
 
   my $charges = 0;
-  my @invoice_details_sort;
-
-  foreach my $cdr (@cdrs) {
-
-    my $charge_min = $cdr->tmp_rated_minutes;
-
-    my $charge = sprintf('%.4f', ( $min_charge * $charge_min )
-                                 + 0.0000000001 ); #so 1.00005 rounds to 1.0001
-
-
-    if ( $charge > 0 ) {
-      $charges += $charge;
-
-      my $detail = 
-        $cdr->downstream_csv( 'format'  => $output_format,
-                              'charge'  => $charge,
-                              'seconds' => ($use_duration ? 
-                                              $cdr->duration : 
-                                              $cdr->billsec),
-                              'granularity' => $granularity,
-                            );
-
-      my $call_details =
-        { format      => 'C',
-          detail      => $detail,
-          amount      => $charge,
-          #classnum    => $cdr->calltypenum, #classnum
-          #phonenum    => $phonenum, #XXX need this to sort on them
-          accountcode => $cdr->accountcode,
-          startdate   => $cdr->startdate,
-          duration    => $cdr->tmp_rated_seconds,
-        };
-
-       #warn "  adding details on charge to invoice: [ ".
-      #    join(', ', @{$call_details} ). " ]"
-      #  if ( $DEBUG && ref($call_details) );
-      push @invoice_details_sort, [ $call_details, $cdr->calldate_unix ];
+
+  $options{'status'} = 'processing-tiered';
+
+  foreach my $cust_svc (@cust_svc) {
+
+    my $svc_x;
+    if( $self->option('bill_inactive_svcs',1) ) {
+      $svc_x = $cust_svc->h_svc_x($$sdate, $last_bill);
     }
+    else {
+      $svc_x = $cust_svc->svc_x;
+    }
+
+    foreach my $pass (split('_', $cdr_inout)) {
 
-    my $error = $cdr->set_status_and_rated_price(
-      'done',
-      $charge,
-      $cdr->tmp_svcnum,
-      'inbound'       => ($cdr->tmp_inout eq 'inbound'),
-      'rated_minutes' => $charge_min,
-      'rated_seconds' => $cdr->tmp_rated_seconds,
-    );
-    die $error if $error;
+      $options{'inbound'} = ( $pass eq 'inbound' );
+      # tell the formatter what we're sending it
+      $formatter->inbound($options{'inbound'});
 
+      my $cdr_search = $svc_x->psearch_cdrs(%options);
+      $cdr_search->limit(1000);
+      $cdr_search->increment(0);
+      while ( my $cdr = $cdr_search->fetch ) {
 
-  }
+        my $object = $options{'inbound'}
+                       ? $cdr->cdr_termination( 1 ) #1: inbound
+                       : $cdr;
 
-  my @sorted_invoice_details = sort { ${$a}[1] <=> ${$b}[1] } @invoice_details_sort;
-  foreach my $sorted_call_detail ( @sorted_invoice_details ) {
-      push @$details, ${$sorted_call_detail}[0];
-  }
+        my $charge_min = $object->rated_minutes;
+
+        my $charge = sprintf('%.4f', ( $min_charge * $charge_min )
+                                     + 0.0000000001 ); #so 1.00005 rounds to 1.0001
+
+        if ( $charge > 0 ) {
+          $charges += $charge;
+        }
+
+        my $error = $cdr->set_status_and_rated_price(
+          'done',
+          $charge,
+          $cust_svc->svcnum,
+          'inbound'       => $options{'inbound'},
+          'rated_minutes' => $charge_min,
+          'rated_seconds' => $object->rated_seconds,
+        );
+        die $error if $error;
+
+        $formatter->append($cdr);
+
+        $cdr_search->adjust(1) if $cdr->freesidestatus eq 'processing-tiered';
+
+      } # $cdr
+
+    } # $pass
+
+  } # $cust_svc
 
-  unshift @$details, { format => 'C',
-                       detail => FS::cdr::invoice_header($output_format),
-                     }
-    if @$details;
+  $formatter->finish;
+  unshift @$details, $formatter->header if @$details;
 
   $charges;
 }