summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan <ivan>2011-11-18 00:09:50 +0000
committerivan <ivan>2011-11-18 00:09:50 +0000
commit4b4d74a09dd4e39f53b7d0944b20b178cbecd5ec (patch)
tree9e7129827f550acb74c831a67005186e102b642a
parentf1371047a59f62165fa3b6d639af72e03cba9a8f (diff)
reduce memory usage of voip_tiered, RT#14903
-rw-r--r--FS/FS/cdr.pm47
-rw-r--r--FS/FS/cdr_termination.pm4
-rw-r--r--FS/FS/part_pkg/voip_tiered.pm130
-rw-r--r--FS/FS/svc_phone.pm31
4 files changed, 129 insertions, 83 deletions
diff --git a/FS/FS/cdr.pm b/FS/FS/cdr.pm
index 850f797..1507dde 100644
--- a/FS/FS/cdr.pm
+++ b/FS/FS/cdr.pm
@@ -130,9 +130,9 @@ following fields are currently supported:
=item svcnum - Link to customer service (see L<FS::cust_svc>)
-=item freesidestatus - NULL, done (or something)
+=item freesidestatus - NULL, processing-tiered, done
-=item freesiderewritestatus - NULL, done (or something)
+=item freesiderewritestatus - NULL, done, skipped
=item cdrbatch
@@ -404,10 +404,7 @@ sub set_status_and_rated_price {
if ($opt{'inbound'}) {
- my $term = qsearchs('cdr_termination', {
- acctid => $self->acctid,
- termpart => 1 # inbound
- });
+ my $term = $self->cdr_termination( 1 ); #1: inbound
my $error;
if ( $term ) {
warn "replacing existing cdr status (".$self->acctid.")\n" if $term;
@@ -419,10 +416,10 @@ sub set_status_and_rated_price {
termpart => 1,
rated_price => $rated_price,
status => $status,
- svcnum => $svcnum,
});
$term->rated_seconds($opt{rated_seconds}) if exists($opt{rated_seconds});
$term->rated_minutes($opt{rated_minutes}) if exists($opt{rated_minutes});
+ $term->svcnum($svcnum) if $svcnum;
return $term->insert;
} else {
@@ -437,6 +434,29 @@ sub set_status_and_rated_price {
}
}
+=item cdr_termination [ TERMPART ]
+
+=cut
+
+sub cdr_termination {
+ my $self = shift;
+
+ if ( scalar(@_) && $_[0] ) {
+ my $termpart = shift;
+
+ qsearchs('cdr_termination', { acctid => $self->acctid,
+ termpart => $termpart,
+ }
+ );
+
+ } else {
+
+ qsearch('cdr_termination', { acctid => $self->acctid, } );
+
+ }
+
+}
+
=item calldate_unix
Parses the calldate in SQL string format and returns a UNIX timestamp.
@@ -753,14 +773,13 @@ sub clear_status {
return $error;
}
- my @cdr_termination = qsearch('cdr_termination',
- { 'acctid' => $self->acctid } );
- foreach my $cdr_termination ( @cdr_termination ) {
- $cdr_termination->status('');
- $error = $cdr_termination->replace;
+ foreach my $cdr_termination ( $self->cdr_termination ) {
+ #$cdr_termination->status('');
+ #$error = $cdr_termination->replace;
+ $error = $cdr_termination->delete;
if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return $error;
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
}
}
diff --git a/FS/FS/cdr_termination.pm b/FS/FS/cdr_termination.pm
index 5e30805..0209f0d 100644
--- a/FS/FS/cdr_termination.pm
+++ b/FS/FS/cdr_termination.pm
@@ -119,8 +119,8 @@ sub check {
|| $self->ut_foreign_key('acctid', 'cdr', 'acctid')
#|| $self->ut_foreign_key('termpart', 'part_termination', 'termpart')
|| $self->ut_number('termpart')
- || $self->ut_float('rated_price')
- || $self->ut_enum('status', [ '', 'done' ] ) # , 'skipped' ] )
+ || $self->ut_floatn('rated_price')
+ || $self->ut_enum('status', [ '', 'processing-tiered', 'done' ] ) # , 'skipped' ] )
;
return $error if $error;
diff --git a/FS/FS/part_pkg/voip_tiered.pm b/FS/FS/part_pkg/voip_tiered.pm
index 29e60d4..1ed2450 100644
--- a/FS/FS/part_pkg/voip_tiered.pm
+++ b/FS/FS/part_pkg/voip_tiered.pm
@@ -107,7 +107,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) ) {
@@ -161,11 +160,16 @@ 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
@@ -191,55 +195,79 @@ sub calc_usage {
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;
}
- 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;
+ foreach my $pass (split('_', $cdr_inout)) {
+ $options{'inbound'} = ( $pass eq 'inbound' );
- }
+ foreach my $cdr (
+ $svc_x->get_cdrs( %options )
+ ) {
+
+ my $object = $options{'inbound'}
+ ? $cdr->cdr_termination( 1 ) #1: inbound
+ : $cdr;
+
+ 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 $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 => $object->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 ];
+ }
+
+ 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;
+
+ } # $cdr
+
+ } # $pass
+
+ } # $cust_svc
my @sorted_invoice_details = sort { ${$a}[1] <=> ${$b}[1] } @invoice_details_sort;
foreach my $sorted_call_detail ( @sorted_invoice_details ) {
diff --git a/FS/FS/svc_phone.pm b/FS/FS/svc_phone.pm
index 4945391..e3d18e0 100644
--- a/FS/FS/svc_phone.pm
+++ b/FS/FS/svc_phone.pm
@@ -650,7 +650,7 @@ Accepts the following options:
=item for_update => 1: SELECT the CDRs "FOR UPDATE".
-=item status => "" (or "done"): Return only CDRs with that processing status.
+=item status => "" (or "processing-tiered", "done"): Return only CDRs with that processing status.
=item inbound => 1: Return CDRs for inbound calls. With "status", will filter
on inbound processing status.
@@ -673,25 +673,24 @@ sub get_cdrs {
my @where;
if ( $options{'inbound'} ) {
+
@fields = ( 'dst' );
if ( exists($options{'status'}) ) {
- # must be 'done' or ''
- my $sq = 'EXISTS ( SELECT 1 FROM cdr_termination '.
- 'WHERE cdr.acctid = cdr_termination.acctid '.
- 'AND cdr_termination.status = \'done\' '.
- 'AND cdr_termination.termpart = 1 )';
- if ( $options{'status'} eq 'done' ) {
- push @where, $sq;
- }
- elsif ($options{'status'} eq '' ) {
- push @where, "NOT $sq";
- }
- else {
- warn "invalid status: $options{'status'} (ignored)\n";
+ my $status = $options{'status'};
+ if ( $status ) {
+ push @where, 'EXISTS ( SELECT 1 FROM cdr_termination '.
+ 'WHERE cdr.acctid = cdr_termination.acctid '.
+ "AND cdr_termination.status = '$status' ". #quoting kludge
+ 'AND cdr_termination.termpart = 1 )';
+ } else {
+ push @where, 'NOT EXISTS ( SELECT 1 FROM cdr_termination '.
+ 'WHERE cdr.acctid = cdr_termination.acctid '.
+ 'AND cdr_termination.termpart = 1 )';
}
}
- }
- else {
+
+ } else {
+
@fields = ( 'charged_party' );
push @fields, 'src' if !$options{'disable_src'};
$hash{'freesidestatus'} = $options{'status'}