4 This script is for fixing CDRs that were supposed to receive Taqua
5 accountcode/caller ID rewrites but didn't. It will skip records that had
6 any rewrites performed, but will operate on CDRs that have already been
9 -s DATE: find calls on or after DATE (required)
10 -e DATE: find calls on or before DATE (optional, defaults to right now)
11 -v: show records as they're updated
16 use FS::Record qw(qsearch qsearchs dbh);
23 die $usage unless $opt{start};
28 my $extra_sql = 'WHERE lastapp IS NOT NULL AND freesiderewritestatus IS NULL' .
29 ' AND cdrtypenum = 1'.
30 ' AND calldate >= to_timestamp('.$opt{start}.')';
32 $extra_sql .= ' AND calldate < to_timestamp('.$opt{end}.')';
34 my $cursor = FS::Cursor->new({
37 extra_sql => $extra_sql,
40 $FS::UID::AutoCommit = 0;
42 while (my $cdr = $cursor->fetch) {
43 # copy-paste from cdrrewrited, except:
44 # - move all conditions for this rewrite into the SQL
45 # - don't check for config option to enable rewriting
46 # - don't retry, don't remember not-found acctids
50 #find the matching CDR
51 my %search = ( 'sessionnum' => $cdr->sessionnum );
52 if ( $cdr->lastapp eq 'acctcode' ) {
53 $search{'src'} = $cdr->subscriber;
54 } elsif ( $cdr->lastapp eq 'CallerId' ) {
55 $search{'dst'} = $cdr->subscriber;
58 my $desc = '#'.$cdr->acctid . ': sessionnum ' . $cdr->sessionnum . ', '.
59 "subscriber ".$cdr->subscriber;
62 my $primary = qsearchs('cdr', \%search);
66 my $cantfind = "can't find primary CDR with session ". $cdr->sessionnum .
69 $cantfind .= 'src '.$search{'src'};
71 $cantfind .= 'dst '.$search{'dst'};
73 warn "ERROR: $cantfind\n";
79 if ( $cdr->lastapp eq 'acctcode' ) {
80 # lastdata contains the dialed account code
81 $primary->accountcode( $cdr->lastdata );
82 push @status, 'taqua-accountcode';
83 warn '#'.$primary->acctid . ': accountcode = '.$cdr->lastdata . "\n"
85 } elsif ( $cdr->lastapp eq 'CallerId' ) {
86 # lastdata contains "allowed" or "restricted"
87 # or case variants thereof
88 if ( lc($cdr->lastdata) eq 'restricted' ) {
89 $primary->clid( 'PRIVATE' );
91 push @status, 'taqua-callerid';
92 warn '#'.$primary->acctid . ': clid = '.$cdr->lastdata . "\n"
95 warn "unknown Taqua service name: ".$cdr->lastapp."\n";
97 #$primary->freesiderewritestatus( 'taqua-accountcode-primary' );
98 my $error = $primary->replace if $primary->modified;
100 warn "WARNING: error rewriting primary CDR: $error\n";
105 if ( $primary->freesidestatus eq 'done' and
106 $cdr->lastapp eq 'acctcode' and
107 $primary->rated_price > 0 ) {
108 # then have to update the billing detail also
110 if ( $primary->detailnum ) {
111 # has been on 3.x since January 2016...
112 $detail = qsearchs('cust_bill_pkg_detail', {
113 'detailnum' => $primary->detailnum
116 # otherwise, try our best: find a detail with the right price,
117 # source number, and start and end dates
118 $detail = qsearchs('cust_bill_pkg_detail', {
119 'amount' => $primary->rated_price,
120 'classnum' => $cdr->rated_classnum,
121 'duration' => $primary->rated_seconds,
122 'startdate' => $primary->startdate,
124 'phonenum' => $primary->src, # not perfect
128 warn "detail #".$detail->detailnum."\n" if $DEBUG;
129 $detail->set('accountcode', $primary->accountcode);
130 $error = $detail->replace;
132 warn "WARNING: error rewriting invoice detail: $error\n";
138 warn "ERROR: can't find invoice detail for cdr#".$primary->acctid."\n";
143 } # if this is an acctcode record and the primary was billed
145 $cdr->status('done'); #so it doesn't try to rate
149 $cdr->freesiderewritestatus(
150 scalar(@status) ? join('/', @status) : 'skipped'
153 my $error = $cdr->replace;
155 warn "WARNING: error rewriting CDR: $error\n";
166 Primary record not found: $notfound