- if ( $spool_cdr && length($downstream_cdr) ) {
-
- use FS::UID qw(datasrc);
- my $dir = '/usr/local/etc/freeside/export.'. datasrc. '/cdr';
- mkdir $dir, 0700 unless -d $dir;
- $dir .= '/'. $cust_pkg->custnum.
- mkdir $dir, 0700 unless -d $dir;
- my $filename = time2str("$dir/CDR%Y%m%d-spool.CSV", time); #XXX invoice date instead? would require changing the order things are generated in cust_main::bill insert cust_bill first - with transactions it could be done though
-
- push @{ $param->{'precommit_hooks'} },
- sub {
- #lock the downstream spool file and append the records
- use Fcntl qw(:flock);
- use IO::File;
- my $spool = new IO::File ">>$filename"
- or die "can't open $filename: $!\n";
- flock( $spool, LOCK_EX)
- or die "can't lock $filename: $!\n";
- seek($spool, 0, 2)
- or die "can't seek to end of $filename: $!\n";
- print $spool $downstream_cdr;
- flock( $spool, LOCK_UN );
- close $spool;
- };
-
- } #if ( $spool_cdr && length($downstream_cdr) )
-
- $self->option('recur_fee') + $charges;
+ unshift @$details, { format => 'C',
+ detail => FS::cdr::invoice_header($output_format),
+ }
+ if @$details && $rating_method ne 'upstream';
+
+# if ( $spool_cdr && length($downstream_cdr) ) {
+#
+# use FS::UID qw(datasrc);
+# my $dir = '/usr/local/etc/freeside/export.'. datasrc. '/cdr';
+# mkdir $dir, 0700 unless -d $dir;
+# $dir .= '/'. $cust_pkg->custnum.
+# mkdir $dir, 0700 unless -d $dir;
+# my $filename = time2str("$dir/CDR%Y%m%d-spool.CSV", time); #XXX invoice date instead? would require changing the order things are generated in cust_main::bill insert cust_bill first - with transactions it could be done though
+#
+# push @{ $param->{'precommit_hooks'} },
+# sub {
+# #lock the downstream spool file and append the records
+# use Fcntl qw(:flock);
+# use IO::File;
+# my $spool = new IO::File ">>$filename"
+# or die "can't open $filename: $!\n";
+# flock( $spool, LOCK_EX)
+# or die "can't lock $filename: $!\n";
+# seek($spool, 0, 2)
+# or die "can't seek to end of $filename: $!\n";
+# print $spool $downstream_cdr;
+# flock( $spool, LOCK_UN );
+# close $spool;
+# };
+#
+# } #if ( $spool_cdr && length($downstream_cdr) )
+
+ $charges;
+}
+
+#returns a reason why not to rate this CDR, or false if the CDR is chargeable
+sub check_chargable {
+ my( $self, $cdr, %flags ) = @_;
+
+ #should have some better way of checking these options from a hash
+ #or something
+
+ my @opt = qw(
+ use_amaflags
+ use_carrierid
+ use_cdrtypenum
+ ignore_cdrtypenum
+ disposition_in
+ ignore_disposition
+ skip_dst_prefix
+ skip_dcontext
+ skip_dstchannel_prefix
+ skip_src_length_more noskip_src_length_accountcode_tollfree
+ skip_dst_length_less noskip_dst_length_accountcode_tollfree
+ skip_lastapp
+ skip_max_callers
+ );
+ foreach my $opt (grep !exists($flags{option_cache}->{$_}), @opt ) {
+ $flags{option_cache}->{$opt} = $self->option($opt, 1);
+ }
+ my %opt = %{ $flags{option_cache} };
+
+ return 'amaflags != 2'
+ if $opt{'use_amaflags'} && $cdr->amaflags != 2;
+
+ return "disposition NOT IN ( $opt{'disposition_in'} )"
+ if $opt{'disposition_in'} =~ /\S/
+ && !grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $opt{'disposition_in'});
+
+ return "disposition IN ( $opt{'ignore_disposition'} )"
+ if $opt{'ignore_disposition'} =~ /\S/
+ && grep { $cdr->disposition eq $_ } split(/\s*,\s*/, $opt{'ignore_disposition'});
+
+ foreach(split(/\s*,\s*/, $opt{'skip_dst_prefix'})) {
+ return "dst starts with '$_'"
+ if length($_) && substr($cdr->dst,0,length($_)) eq $_;
+ }
+
+ return "carrierid != $opt{'use_carrierid'}"
+ if length($opt{'use_carrierid'})
+ && $cdr->carrierid ne $opt{'use_carrierid'} #ne otherwise 0 matches ''
+ && ! $flags{'da_rewrote'};
+
+ # unlike everything else, use_cdrtypenum is applied in FS::svc_x::get_cdrs.
+ return "cdrtypenum != $opt{'use_cdrtypenum'}"
+ if length($opt{'use_cdrtypenum'})
+ && $cdr->cdrtypenum ne $opt{'use_cdrtypenum'}; #ne otherwise 0 matches ''
+
+ return "cdrtypenum == $opt{'ignore_cdrtypenum'}"
+ if length($opt{'ignore_cdrtypenum'})
+ && $cdr->cdrtypenum eq $opt{'ignore_cdrtypenum'}; #eq otherwise 0 matches ''
+
+ return "dcontext IN ( $opt{'skip_dcontext'} )"
+ if $opt{'skip_dcontext'} =~ /\S/
+ && grep { $cdr->dcontext eq $_ } split(/\s*,\s*/, $opt{'skip_dcontext'});
+
+ my $len_prefix = length($opt{'skip_dstchannel_prefix'});
+ return "dstchannel starts with $opt{'skip_dstchannel_prefix'}"
+ if $len_prefix
+ && substr($cdr->dstchannel,0,$len_prefix) eq $opt{'skip_dstchannel_prefix'};
+
+ my $dst_length = $opt{'skip_dst_length_less'};
+ return "destination less than $dst_length digits"
+ if $dst_length && length($cdr->dst) < $dst_length
+ && ! ( $opt{'noskip_dst_length_accountcode_tollfree'}
+ && $cdr->is_tollfree('accountcode')
+ );
+
+ return "lastapp is $opt{'skip_lastapp'}"
+ if length($opt{'skip_lastapp'}) && $cdr->lastapp eq $opt{'skip_lastapp'};
+
+ my $src_length = $opt{'skip_src_length_more'};
+ if ( $src_length ) {
+
+ if ( $opt{'noskip_src_length_accountcode_tollfree'} ) {
+
+ if ( $cdr->is_tollfree('accountcode') ) {
+ return "source less than or equal to $src_length digits"
+ if length($cdr->src) <= $src_length;
+ } else {
+ return "source more than $src_length digits"
+ if length($cdr->src) > $src_length;
+ }
+
+ } else {
+ return "source more than $src_length digits"
+ if length($cdr->src) > $src_length;
+ }