use Date::Format;
use Time::Local;
use FS::UID qw( dbh );
+use FS::Conf;
use FS::Record qw( qsearch qsearchs );
use FS::cdr_type;
use FS::cdr_calltype;
=item freesidestatus - NULL, done (or something)
+=item cdrbatch
+
=back
=head1 METHODS
$self->calldate( $self->startdate_sql )
if !$self->calldate && $self->startdate;
+ my $conf = new FS::Conf;
+
unless ( $self->charged_party ) {
- if ( $self->dst =~ /^(\+?1)?8[02-8]{2}/ ) {
- $self->charged_party($self->dst);
+
+ if ( $conf->exists('cdr-charged_party-accountcode') && $self->accountcode ){
+
+ $self->charged_party( $self->accountcode );
+
} else {
- $self->charged_party($self->src);
+
+ if ( $self->dst =~ /^(\+?1)?8[02-8]{2}/ ) {
+ $self->charged_party($self->dst);
+ } else {
+ $self->charged_party($self->src);
+ }
+
}
+
}
#check the foreign keys even?
my $error =
$self->ut_numbern('acctid')
- #Usage = 1, S&E = 7, OC&C = 8
- || $self->ut_foreign_keyn('cdrtypenum', 'cdr_type', 'cdrtypenum' )
-
- #the big list in appendix 2
- || $self->ut_foreign_keyn('calltypenum', 'cdr_calltype', 'calltypenum' )
-
- # Telstra =1, Optus = 2, RSL COM = 3
- || $self->ut_foreign_keyn('carrierid', 'cdr_carrier', 'carrierid' )
+ #add a config option to turn these back on if someone needs 'em
+ #
+ # #Usage = 1, S&E = 7, OC&C = 8
+ # || $self->ut_foreign_keyn('cdrtypenum', 'cdr_type', 'cdrtypenum' )
+ #
+ # #the big list in appendix 2
+ # || $self->ut_foreign_keyn('calltypenum', 'cdr_calltype', 'calltypenum' )
+ #
+ # # Telstra =1, Optus = 2, RSL COM = 3
+ # || $self->ut_foreign_keyn('carrierid', 'cdr_carrier', 'carrierid' )
;
return $error if $error;
my %export_names = (
'convergent' => {},
- 'simple' => { 'name' => 'Simple',
- 'invoice_header' =>
- "Date,Time,Name,Destination,Duration,Price",
- },
- 'simple2' => { 'name' => 'Simple with source',
- 'invoice_header' =>
- #"Date,Time,Name,Called From,Destination,Duration,Price",
- "Date,Time,Called From,Destination,Duration,Price",
- },
+ 'simple' => {
+ 'name' => 'Simple',
+ 'invoice_header' => "Date,Time,Name,Destination,Duration,Price",
+ },
+ 'simple2' => {
+ 'name' => 'Simple with source',
+ 'invoice_header' => "Date,Time,Called From,Destination,Duration,Price",
+ #"Date,Time,Name,Called From,Destination,Duration,Price",
+ },
+ 'default' => {
+ 'name' => 'Default',
+ 'invoice_header' => 'Date,Time,Duration,Price,Number,Destination',
+ },
+ 'source_default' => {
+ 'name' => 'Default with source',
+ 'invoice_header' => 'Caller,Date,Time,Duration,Price,Number,Destination',
+ },
);
my %export_formats = (
sub { sprintf('%.2fm', shift->billsec / 60 ) }, #DURATION
sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE
],
+ 'default' => [
+
+ #DATE
+ sub { time2str('%D', shift->calldate_unix ) },
+ # #time2str("%Y %b %d - %r", $cdr->calldate_unix ),
+
+ #TIME
+ sub { time2str('%r', shift->calldate_unix ) },
+ # time2str("%c", $cdr->calldate_unix), #XXX this should probably be a config option dropdown so they can select US vs- rest of world dates or whatnot
+
+ #DURATION
+ sub { my($cdr, %opt) = @_;
+ $opt{minutes}. ( $opt{granularity} ? 'm' : ' call' );
+ },
+
+ #PRICE
+ sub { my($cdr, %opt) = @_; $opt{money_char}. $opt{charge}; },
+
+ #DEST ("Number")
+ sub { my($cdr, %opt) = @_; $opt{pretty_dst} || $cdr->dst; },
+
+ #REGIONNAME ("Destination")
+ sub { my($cdr, %opt) = @_; $opt{dst_regionname}; },
+
+ ],
);
+$export_formats{'source_default'} = [ 'src', @{ $export_formats{'default'} } ];
sub downstream_csv {
my( $self, %opt ) = @_;
my $format = $opt{'format'}; # 'convergent';
return "Unknown format $format" unless exists $export_formats{$format};
+ #my $conf = new FS::Conf;
+ #$opt{'money_char'} ||= $conf->config('money_char') || '$';
+ $opt{'money_char'} ||= FS::Conf->new->config('money_char') || '$';
+
eval "use Text::CSV_XS;";
die $@ if $@;
my $csv = new Text::CSV_XS;
my @columns =
map {
- ref($_) ? &{$_}($self) : $self->$_();
+ ref($_) ? &{$_}($self, %opt) : $self->$_();
}
@{ $export_formats{$format} };
sub _cdr_min_parser_maker {
my $field = shift;
my @fields = ref($field) ? @$field : ($field);
- @fields = qw( billsec duration ) unless scalar(@fields);
+ @fields = qw( billsec duration ) unless scalar(@fields) && $fields[0];
return sub {
my( $cdr, $min ) = @_;
my $sec = eval { _cdr_min_parse($min) };
my $fh = $param->{filehandle};
my $format = $param->{format};
+ my $cdrbatch = $param->{cdrbatch};
return "Unknown format $format"
unless exists( $cdr_info{$format} )
if ( $type eq 'csv' ) {
eval "use Text::CSV_XS;";
die $@ if $@;
- $parser = new Text::CSV_XS;
+ my %attr = ();
+ foreach ( grep exists($info->{$_}), qw( sep_char ) ) {
+ $attr{$_} = $info->{$_};
+ }
+ $parser = new Text::CSV_XS \%attr;
} elsif ( $type eq 'fixedlength' ) {
eval "use Parse::FixedLength;";
die $@ if $@;
}
@{ $info->{'import_fields'} }
;
+
+ $cdr{cdrbatch} = $cdrbatch;
my $cdr = new FS::cdr ( \%cdr );
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
#might want to disable this if we skip records for any reason...
- return "Empty file!" unless $imported;
+ return "Empty file!" unless $imported || $param->{empty_ok};
'';