add troop CDRs, RT#4413
[freeside.git] / FS / FS / cdr.pm
index 27db89e..5bfd91d 100644 (file)
@@ -234,6 +234,15 @@ sub check {
   $self->calldate( $self->startdate_sql )
     if !$self->calldate && $self->startdate;
 
+  #was just for $format eq 'taqua' but can't see the harm... add something to
+  #disable if it becomes a problem
+  if ( $self->duration eq '' && $self->enddate && $self->startdate ) {
+    $self->duration( $self->enddate - $self->startdate  );
+  }
+  if ( $self->billsec eq '' && $self->enddate && $self->answerdate ) {
+    $self->billsec(  $self->enddate - $self->answerdate );
+  } 
+
   my $conf = new FS::Conf;
 
   unless ( $self->charged_party ) {
@@ -431,7 +440,7 @@ my %export_names = (
   },
   'source_default' => {
     'name'           => 'Default with source',
-    'invoice_header' => 'Caller,Date,Time,Duration,Price,Number,Destination',
+    'invoice_header' => 'Caller,Date,Time,Duration,Number,Destination,Price',
   },
 );
 
@@ -494,7 +503,11 @@ my %export_formats = (
 
   ],
 );
-$export_formats{'source_default'} = [ 'src', @{ $export_formats{'default'} } ];
+$export_formats{'source_default'} = [ 'src',
+                                      @{ $export_formats{'default'} }[0..2],
+                                      @{ $export_formats{'default'} }[4..5],
+                                      @{ $export_formats{'default'} }[3],
+                                    ];
 
 sub downstream_csv {
   my( $self, %opt ) = @_;
@@ -659,7 +672,7 @@ Imports CDR records.  Available options are:
 
 =over 4
 
-=item filehandle
+=item file
 
 =item format
 
@@ -667,138 +680,63 @@ Imports CDR records.  Available options are:
 
 =cut
 
-sub batch_import {
-  my $param = shift;
-
-  my $fh = $param->{filehandle};
-  my $format = $param->{format};
-  my $cdrbatch = $param->{cdrbatch};
-
-  return "Unknown format $format"
-    unless exists( $cdr_info{$format} )
-        && exists( $cdr_info{$format}->{'import_fields'} );
-
-  my $info = $cdr_info{$format};
-
-  my $type = exists($info->{'type'}) ? lc($info->{'type'}) : 'csv';
-
-  my $parser;
-  if ( $type eq 'csv' ) {
-    eval "use Text::CSV_XS;";
-    die $@ if $@;
-    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 $@;
-    $parser = new Parse::FixedLength $info->{'fixedlength_format'};
-  } else {
-    die "Unknown CDR format type $type for format $format\n";
-  }
-
-  my $imported = 0;
-  #my $columns;
-
-  local $SIG{HUP} = 'IGNORE';
-  local $SIG{INT} = 'IGNORE';
-  local $SIG{QUIT} = 'IGNORE';
-  local $SIG{TERM} = 'IGNORE';
-  local $SIG{TSTP} = 'IGNORE';
-  local $SIG{PIPE} = 'IGNORE';
-
-  my $oldAutoCommit = $FS::UID::AutoCommit;
-  local $FS::UID::AutoCommit = 0;
-  my $dbh = dbh;
-
-  my $header_lines = exists($info->{'header'}) ? $info->{'header'} : 0;
-
-  my $line;
-  while ( defined($line=<$fh>) ) {
-
-    next if $header_lines-- > 0; #&& $line =~ /^[\w, "]+$/ 
-
-    my @columns = ();
-    if ( $type eq 'csv' ) {
 
-      $parser->parse($line) or do {
-        $dbh->rollback if $oldAutoCommit;
-        return "can't parse: ". $parser->error_input();
-      };
+my %import_options = (
+  'table'   => 'cdr',
 
-      @columns = $parser->fields();
+  'formats' => { map { $_ => $cdr_info{$_}->{'import_fields'}; }
+                     keys %cdr_info
+               },
 
-    } elsif ( $type eq 'fixedlength' ) {
+                          #drop the || 'csv' to allow auto xls for csv types?
+  'format_types' => { map { $_ => ( lc($cdr_info{$_}->{'type'}) || 'csv' ); }
+                          keys %cdr_info
+                    },
 
-      @columns = $parser->parse($line);
+  'format_headers' => { map { $_ => ( $cdr_info{$_}->{'header'} || 0 ); }
+                            keys %cdr_info
+                      },
 
-    } else {
-      die "Unknown CDR format type $type for format $format\n";
-    }
-
-    #warn join('-',@columns);
-
-    if ( $format eq 'simple' ) { #should be a callback or opt in FS::cdr::simple
-      @columns = map { s/^ +//; $_; } @columns;
-    }
+  'format_sep_chars' => { map { $_ => $cdr_info{$_}->{'sep_char'}; }
+                              keys %cdr_info
+                        },
 
-    my @later = ();
-    my %cdr =
-      map {
-
-        my $field_or_sub = $_;
-        if ( ref($field_or_sub) ) {
-          push @later, $field_or_sub, shift(@columns);
-          ();
-        } else {
-          ( $field_or_sub => shift @columns );
-        }
+  'format_fixedlength_formats' =>
+    { map { $_ => $cdr_info{$_}->{'fixedlength_format'}; }
+          keys %cdr_info
+    },
+);
 
-      }
-      @{ $info->{'import_fields'} }
-    ;
-    $cdr{cdrbatch} = $cdrbatch;
+sub _import_options {
+  \%import_options;
+}
 
-    my $cdr = new FS::cdr ( \%cdr );
+sub batch_import {
+  my $opt = shift;
 
-    while ( scalar(@later) ) {
-      my $sub = shift @later;
-      my $data = shift @later;
-      &{$sub}($cdr, $data);  # $cdr->&{$sub}($data); 
-    }
+  my $iopt = _import_options;
+  $opt->{$_} = $iopt->{$_} foreach keys %$iopt;
 
-    if ( $format eq 'taqua' ) { #should be a callback or opt in FS::cdr::taqua
-      if ( $cdr->enddate && $cdr->startdate  ) { #a bit more?
-        $cdr->duration( $cdr->enddate - $cdr->startdate  );
-      }
-      if ( $cdr->enddate && $cdr->answerdate ) { #a bit more?
-        $cdr->billsec(  $cdr->enddate - $cdr->answerdate );
-      } 
-    }
+  FS::Record::batch_import( $opt );
 
-    my $error = $cdr->insert;
-    if ( $error ) {
-      $dbh->rollback if $oldAutoCommit;
-      return $error;
+}
 
-      #or just skip?
-      #next;
-    }
+=item process_batch_import
 
-    $imported++;
-  }
+=cut
 
-  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+sub process_batch_import {
+  my $job = shift;
 
-  #might want to disable this if we skip records for any reason...
-  return "Empty file!" unless $imported || $param->{empty_ok};
+  my $opt = _import_options;
+  $opt->{'params'} = [ 'format', 'cdrbatch' ];
 
-  '';
+  FS::Record::process_batch_import( $job, $opt, @_ );
 
 }
+#  if ( $format eq 'simple' ) { #should be a callback or opt in FS::cdr::simple
+#    @columns = map { s/^ +//; $_; } @columns;
+#  }
 
 =back