use vars qw( $conf );
use FS::Daemon ':all'; #daemonize1 drop_root daemonize2 myexit logfile sig*
use FS::UID qw( adminsuidsetup );
-use FS::Record qw( qsearch qsearchs );
+use FS::Record qw( qsearch qsearchs dbh );
#use FS::cdr;
#use FS::cust_pkg;
#use FS::queue;
$conf = new FS::Conf;
-die "not running; cdr-asterisk_forward_rewrite, cdr-charged_party_rewrite ".
- " and cdr-taqua-accountcode_rewrite conf options are all off\n"
+die "not running; relevant conf options are all off\n"
unless _shouldrun();
#--
+#used for taqua
my %sessionnum_unmatch = ();
my $sessionnum_retry = 4 * 60 * 60; # 4 hours
my $sessionnum_giveup = 4 * 24 * 60 * 60; # 4 days
# instead of just doing this search like normal CDRs
#hmm :/
+ #used only by taqua, should have no effect otherwise
my @recent = grep { ($sessionnum_unmatch{$_} + $sessionnum_retry) > time }
keys %sessionnum_unmatch;
my $extra_sql = scalar(@recent)
? ' AND acctid NOT IN ('. join(',', @recent). ') '
: '';
+ #order matters for removing dupes--only the first is preserved
+ $extra_sql .= ' ORDER BY acctid '
+ if $conf->exists('cdr-skip_duplicate_rewrite');
+
my $found = 0;
- my %skip = ();
+ my %skip = (); #used only by taqua
my %warning = ();
foreach my $cdr (
qsearch( {
'table' => 'cdr',
- 'extra_sql' => 'FOR UPDATE',
'hashref' => {},
'extra_sql' => 'WHERE freesidestatus IS NULL '.
' AND freesiderewritestatus IS NULL '.
$extra_sql.
- ' LIMIT 1024', #arbitrary, but don't eat too much memory
+ ' LIMIT 1024 FOR UPDATE', #arbitrary, but don't eat too much memory
} )
) {
- next if $skip{$cdr->acctid};
+ next if $skip{$cdr->acctid}; #used only by taqua
$found = 1;
my @status = ();
+ if ($conf->exists('cdr-skip_duplicate_rewrite')) {
+ #qsearch can't handle timestamp type of calldate
+ my $sth = dbh->prepare(
+ 'SELECT 1 FROM cdr WHERE src=? AND dst=? AND calldate=? AND acctid < ? LIMIT 1'
+ ) or die dbh->errstr;
+ $sth->execute($cdr->src,$cdr->dst,$cdr->calldate,$cdr->acctid) or die $sth->errstr;
+ my $isdup = $sth->fetchrow_hashref;
+ $sth->finish;
+ if ($isdup) {
+ #we only act on this cdr, not touching previous dupes
+ #if a dupe somehow creeped in previously, too late to fix it
+ $cdr->freesidestatus('skipped'); #prevent it from being billed
+ push(@status,'duplicate');
+ }
+ }
+
if ( $conf->exists('cdr-asterisk_forward_rewrite')
&& $cdr->dstchannel =~ /^Local\/(\d+)/i && $1 ne $cdr->dst
)
}
+ if ( $conf->exists('cdr-userfield_dnis_rewrite') and
+ $cdr->userfield =~ /DNIS=(\d+)/ ) {
+ $cdr->dst($1);
+ push @status, 'userfield_dnis';
+ }
+
if ( $conf->exists('cdr-intl_to_domestic_rewrite') and
$cdr->dst =~ /^(011)(\d{0,7})$/ ) {
$cdr->dst($2);
|| $conf->exists('cdr-taqua-accountcode_rewrite')
|| $conf->exists('cdr-taqua-callerid_rewrite')
|| $conf->exists('cdr-intl_to_domestic_rewrite')
+ || $conf->exists('cdr-userfield_dnis_rewrite')
+ || $conf->exists('cdr-skip_duplicate_rewrite')
|| 0
;
}
=over 4
+=item cdr-skip_duplicate_rewrite
+
+Marks as 'skipped' (prevents billing for) any CDRs with
+a src, dst and calldate identical to an existing CDR
+
=item cdr-asterisk_australia_rewrite
Classifies Australian numbers as domestic, mobile, tollfree, international, or