use Tie::IxHash module explicitly, don't rely on load order
[freeside.git] / FS / FS / cdr.pm
index 306dbd0..a2b9a8c 100644 (file)
@@ -216,6 +216,7 @@ sub table_info {
         #'upstream_rateplanid'   => '',
         #'ratedetailnum'         => '',
         'rated_price'           => 'Rated price',
         #'upstream_rateplanid'   => '',
         #'ratedetailnum'         => '',
         'rated_price'           => 'Rated price',
+        'rated_cost'            => 'Rated cost',
         #'distance'              => '',
         #'islocal'               => '',
         #'calltypenum'           => '',
         #'distance'              => '',
         #'islocal'               => '',
         #'calltypenum'           => '',
@@ -468,7 +469,9 @@ Sets the status and rated price.
 
 Available options are: inbound, rated_pretty_dst, rated_regionname,
 rated_seconds, rated_minutes, rated_granularity, rated_ratedetailnum,
 
 Available options are: inbound, rated_pretty_dst, rated_regionname,
 rated_seconds, rated_minutes, rated_granularity, rated_ratedetailnum,
-rated_classnum, rated_ratename.
+rated_classnum, rated_ratename.  If rated_ratedetailnum is provided,
+will also set a recalculated L</rate_cost> in the rated_cost field 
+after the other fields are set (does not work with inbound.)
 
 If there is an error, returns the error, otherwise returns false.
 
 
 If there is an error, returns the error, otherwise returns false.
 
@@ -506,6 +509,8 @@ sub set_status_and_rated_price {
         qw( pretty_dst regionname seconds minutes granularity
             ratedetailnum classnum ratename );
     $self->svcnum($svcnum) if $svcnum;
         qw( pretty_dst regionname seconds minutes granularity
             ratedetailnum classnum ratename );
     $self->svcnum($svcnum) if $svcnum;
+    $self->rated_cost($self->rate_cost) if $opt{'rated_ratedetailnum'};
+
     return $self->replace();
 
   }
     return $self->replace();
 
   }
@@ -541,6 +546,9 @@ sub parse_number {
 
   my $field = $options{column} || 'dst';
   my $intl = $options{international_prefix} || '011';
 
   my $field = $options{column} || 'dst';
   my $intl = $options{international_prefix} || '011';
+  # Still, don't break anyone's CDR rating if they have an empty string in
+  # there. Require an explicit statement that there's no prefix.
+  $intl = '' if lc($intl) eq 'none';
   my $countrycode = '';
   my $number = $self->$field();
 
   my $countrycode = '';
   my $number = $self->$field();
 
@@ -919,8 +927,10 @@ sub rate_prefix {
 
       # by default, set the included minutes for this region/time to
       # what's in the rate_detail
 
       # by default, set the included minutes for this region/time to
       # what's in the rate_detail
-      $included_min->{$regionnum}{$ratetimenum} = $rate_detail->min_included
-        unless exists $included_min->{$regionnum}{$ratetimenum};
+      if (!exists( $included_min->{$regionnum}{$ratetimenum} )) {
+        $included_min->{$regionnum}{$ratetimenum} =
+          ($rate_detail->min_included * $cust_pkg->quantity || 1);
+      }
 
       if ( $included_min->{$regionnum}{$ratetimenum} >= $minutes ) {
         $charge_sec = 0;
 
       if ( $included_min->{$regionnum}{$ratetimenum} >= $minutes ) {
         $charge_sec = 0;
@@ -1254,6 +1264,10 @@ my %export_names = (
     'name'           => 'Number of calls, one line per service',
     'invoice_header' => 'Caller,Rate,Messages,Price',
   },
     'name'           => 'Number of calls, one line per service',
     'invoice_header' => 'Caller,Rate,Messages,Price',
   },
+  'sum_duration' => {
+    'name'           => 'Summary, one line per service',
+    'invoice_header' => 'Caller,Rate,Calls,Minutes,Price',
+  },
   'sum_duration_prefix' => {
     'name'           => 'Summary, one line per destination prefix',
     'invoice_header' => 'Caller,Rate,Calls,Minutes,Price',
   'sum_duration_prefix' => {
     'name'           => 'Summary, one line per destination prefix',
     'invoice_header' => 'Caller,Rate,Calls,Minutes,Price',
@@ -1262,6 +1276,10 @@ my %export_names = (
     'name'           => 'Summary, one line per usage class',
     'invoice_header' => 'Caller,Class,Calls,Price',
   },
     'name'           => 'Summary, one line per usage class',
     'invoice_header' => 'Caller,Class,Calls,Price',
   },
+  'sum_duration_accountcode' => {
+    'name'           => 'Summary, one line per accountcode',
+    'invoice_header' => 'Caller,Rate,Calls,Minutes,Price',
+  },
 );
 
 my %export_formats = ();
 );
 
 my %export_formats = ();
@@ -1463,7 +1481,7 @@ as keys (for use with part_pkg::voip_cdr) and "pretty" format names as values.
 sub invoice_formats {
   map { ($_ => $export_names{$_}->{'name'}) }
     grep { $export_names{$_}->{'invoice_header'} }
 sub invoice_formats {
   map { ($_ => $export_names{$_}->{'name'}) }
     grep { $export_names{$_}->{'invoice_header'} }
-    keys %export_names;
+    sort keys %export_names;
 }
 
 =item invoice_header FORMAT
 }
 
 =item invoice_header FORMAT
@@ -1632,7 +1650,7 @@ sub _cdr_date_parse {
     # optionally without seconds
     ($mon, $day, $year, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
     $sec = 0 if !defined($sec);
     # optionally without seconds
     ($mon, $day, $year, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
     $sec = 0 if !defined($sec);
-   } elsif ( $date  =~ /^\s*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d+$)/ ) {
+   } elsif ( $date  =~ /^\s*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d+)$/ ) {
     # broadsoft: 20081223201938.314
     ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
   } elsif ( $date  =~ /^\s*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\d+(\D|$)/ ) {
     # broadsoft: 20081223201938.314
     ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
   } elsif ( $date  =~ /^\s*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\d+(\D|$)/ ) {
@@ -1642,7 +1660,7 @@ sub _cdr_date_parse {
     # WIP: 20100329121420
     ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
   } elsif ( $date =~ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/) {
     # WIP: 20100329121420
     ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
   } elsif ( $date =~ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/) {
-    # Telos
+    # Telos 2014-10-10T05:30:33Z
     ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
     $options{gmt} = 1;
   } else {
     ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
     $options{gmt} = 1;
   } else {