planet telesis invoice fixups RT 8707,8406
[freeside.git] / FS / FS / cdr.pm
index cd42854..4de7aa3 100644 (file)
@@ -14,6 +14,7 @@ use FS::cdr_type;
 use FS::cdr_calltype;
 use FS::cdr_carrier;
 use FS::cdr_batch;
+use FS::cdr_termination;
 
 @ISA = qw(FS::Record);
 @EXPORT_OK = qw( _cdr_date_parser_maker _cdr_min_parser_maker );
@@ -284,6 +285,10 @@ sub check {
 #  ;
 #  return $error if $error;
 
+  for my $f ( grep { $self->$_ =~ /[a-z ]/i } qw( startdate enddate ) ) {
+    $self->$f( str2time($self->$f) );
+  }
+
   $self->calldate( $self->startdate_sql )
     if !$self->calldate && $self->startdate;
 
@@ -386,11 +391,33 @@ error, otherwise returns false.
 =cut
 
 sub set_status_and_rated_price {
-  my($self, $status, $rated_price, $svcnum) = @_;
-  $self->freesidestatus($status);
-  $self->rated_price($rated_price);
-  $self->svcnum($svcnum) if $svcnum;
-  $self->replace();
+  my($self, $status, $rated_price, $svcnum, %opt) = @_;
+  if($opt{'inbound'}) {
+    my $term = qsearchs('cdr_termination', {
+        acctid   => $self->acctid, 
+        termpart => 1 # inbound
+    });
+    my $error;
+    if($term) {
+      warn "replacing existing cdr status (".$self->acctid.")\n" if $term;
+      $error = $term->delete;
+      return $error if $error;
+    }
+    $term = FS::cdr_termination->new({
+        acctid      => $self->acctid,
+        termpart    => 1,
+        rated_price => $rated_price,
+        status      => $status,
+        svcnum      => $svcnum,
+    });
+    return $term->insert;
+  }
+  else {
+    $self->freesidestatus($status);
+    $self->rated_price($rated_price);
+    $self->svcnum($svcnum) if $svcnum;
+    return $self->replace();
+  }
 }
 
 =item calldate_unix 
@@ -503,73 +530,86 @@ my %export_names = (
   },
 );
 
-my $duration_sub = sub {
-  my($cdr, %opt) = @_;
-  if ( $opt{minutes} ) {
-    $opt{minutes}. ( $opt{granularity} ? 'm' : ' call' );
-  } else {
-    #config if anyone really wants decimal minutes back
-    #sprintf('%.2fm', $cdr->billsec / 60 );
-    int($cdr->billsec / 60).'m '. ($cdr->billsec % 60).'s';
-  }
-};
-
-my %export_formats = (
-  'simple' => [
-    sub { time2str('%D', shift->calldate_unix ) },   #DATE
-    sub { time2str('%r', shift->calldate_unix ) },   #TIME
-    'userfield',                                     #USER
-    'dst',                                           #NUMBER_DIALED
-    $duration_sub,                                   #DURATION
-    #sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE
-    sub { my($cdr, %opt) = @_; $opt{money_char}. $opt{charge}; }, #PRICE
-  ],
-  'simple2' => [
-    sub { time2str('%D', shift->calldate_unix ) },   #DATE
-    sub { time2str('%r', shift->calldate_unix ) },   #TIME
-    #'userfield',                                     #USER
-    'src',                                           #called from
-    'dst',                                           #NUMBER_DIALED
-    $duration_sub,                                   #DURATION
-    #sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE
-    sub { my($cdr, %opt) = @_; $opt{money_char}. $opt{charge}; }, #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
-
-    #DEST ("Number")
-    sub { my($cdr, %opt) = @_; $opt{pretty_dst} || $cdr->dst; },
-
-    #REGIONNAME ("Destination")
-    sub { my($cdr, %opt) = @_; $opt{dst_regionname}; },
-
-    #DURATION
-    $duration_sub,
-
-    #PRICE
-    sub { my($cdr, %opt) = @_; $opt{money_char}. $opt{charge}; },
-
-  ],
-);
-$export_formats{'source_default'} = [ 'src', @{ $export_formats{'default'} }, ];
-$export_formats{'accountcode_default'} =
-  [ @{ $export_formats{'default'} }[0,1],
-    'accountcode',
-    @{ $export_formats{'default'} }[2..5],
-  ];
+my %export_formats = ();
+sub export_formats {
+  #my $self = shift;
+
+  return %export_formats if keys %export_formats;
+
+  my $conf = new FS::Conf;
+  my $date_format = $conf->config('date_format') || '%m/%d/%Y';
+
+  my $duration_sub = sub {
+    my($cdr, %opt) = @_;
+    if ( $opt{minutes} ) {
+      $opt{minutes}. ( $opt{granularity} ? 'm' : ' call' );
+    } else {
+      #config if anyone really wants decimal minutes back
+      #sprintf('%.2fm', $cdr->billsec / 60 );
+      int($cdr->billsec / 60).'m '. ($cdr->billsec % 60).'s';
+    }
+  };
+
+  %export_formats = (
+    'simple' => [
+      sub { time2str($date_format, shift->calldate_unix ) },   #DATE
+      sub { time2str('%r', shift->calldate_unix ) },   #TIME
+      'userfield',                                     #USER
+      'dst',                                           #NUMBER_DIALED
+      $duration_sub,                                   #DURATION
+      #sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE
+      sub { my($cdr, %opt) = @_; $opt{money_char}. $opt{charge}; }, #PRICE
+    ],
+    'simple2' => [
+      sub { time2str($date_format, shift->calldate_unix ) },   #DATE
+      sub { time2str('%r', shift->calldate_unix ) },   #TIME
+      #'userfield',                                     #USER
+      'src',                                           #called from
+      'dst',                                           #NUMBER_DIALED
+      $duration_sub,                                   #DURATION
+      #sub { sprintf('%.3f', shift->upstream_price ) }, #PRICE
+      sub { my($cdr, %opt) = @_; $opt{money_char}. $opt{charge}; }, #PRICE
+    ],
+    'default' => [
+
+      #DATE
+      sub { time2str($date_format, 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
+
+      #DEST ("Number")
+      sub { my($cdr, %opt) = @_; $opt{pretty_dst} || $cdr->dst; },
+
+      #REGIONNAME ("Destination")
+      sub { my($cdr, %opt) = @_; $opt{dst_regionname}; },
+
+      #DURATION
+      $duration_sub,
+
+      #PRICE
+      sub { my($cdr, %opt) = @_; $opt{money_char}. $opt{charge}; },
+
+    ],
+  );
+  $export_formats{'source_default'} = [ 'src', @{ $export_formats{'default'} }, ];
+  $export_formats{'accountcode_default'} =
+    [ @{ $export_formats{'default'} }[0,1],
+      'accountcode',
+      @{ $export_formats{'default'} }[2..5],
+    ];
+
+  %export_formats
+}
 
 sub downstream_csv {
   my( $self, %opt ) = @_;
 
   my $format = $opt{'format'};
-  return "Unknown format $format" unless exists $export_formats{$format};
+  my %formats = $self->export_formats;
+  return "Unknown format $format" unless exists $formats{$format};
 
   #my $conf = new FS::Conf;
   #$opt{'money_char'} ||= $conf->config('money_char') || '$';
@@ -583,7 +623,7 @@ sub downstream_csv {
     map {
           ref($_) ? &{$_}($self, %opt) : $self->$_();
         }
-    @{ $export_formats{$format} };
+    @{ $formats{$format} };
 
   my $status = $csv->combine(@columns);
   die "FS::CDR: error combining ". $csv->error_input(). "into downstream CSV"
@@ -723,7 +763,10 @@ sub _cdr_date_parse {
     ($mon, $day, $year, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
   } elsif ( $date  =~ /^\s*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d+\.\d+)(\D|$)/ ) {
     # broadsoft: 20081223201938.314
-    ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6);
+    ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
+  } elsif ( $date  =~ /^\s*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/ ) {
+    # WIP: 20100329121420
+    ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6 );
   } else {
      die "unparsable date: $date"; #maybe we shouldn't die...
   }
@@ -763,7 +806,11 @@ Set true to prevent throwing an error on empty imports
 =cut
 
 my %import_options = (
-  'table'   => 'cdr',
+  'table'         => 'cdr',
+
+  'batch_keycol'  => 'cdrbatchnum',
+  'batch_table'   => 'cdr_batch',
+  'batch_namecol' => 'cdrbatch',
 
   'formats' => { map { $_ => $cdr_info{$_}->{'import_fields'}; }
                      keys %cdr_info
@@ -810,7 +857,7 @@ sub process_batch_import {
   my $job = shift;
 
   my $opt = _import_options;
-  $opt->{'params'} = [ 'format', 'cdrbatch' ];
+#  $opt->{'params'} = [ 'format', 'cdrbatch' ];
 
   FS::Record::process_batch_import( $job, $opt, @_ );