RT#39638 [selective v3 backport of commit 7516e3da0f17eeecba27219ef96a8b5f46af2083...
authorJonathan Prykop <jonathan@freeside.biz>
Fri, 29 Jan 2016 21:14:17 +0000 (15:14 -0600)
committerJonathan Prykop <jonathan@freeside.biz>
Fri, 29 Jan 2016 21:14:17 +0000 (15:14 -0600)
FS/FS/Schema.pm
FS/FS/cdr.pm
FS/FS/cust_bill_pkg_detail.pm
FS/FS/detail_format.pm
FS/FS/detail_format/sum_count.pm
FS/FS/detail_format/sum_duration.pm
FS/FS/detail_format/sum_duration_prefix.pm

index cd05be3..a71b902 100644 (file)
@@ -3844,6 +3844,9 @@ sub tables_hashref {
         #new
         'cdrbatchnum',      'int',    'NULL',      '', '', '',
 
+        # FK to cust_bill_pkg_detail; having a value here absolutely means
+        # that the CDR appears on an invoice
+        'detailnum',     'bigint',    'NULL',      '', '', '',
       ],
       'primary_key' => 'acctid',
       'unique' => [],
index 5a1d8ea..8ccf7af 100644 (file)
@@ -161,6 +161,8 @@ following fields are currently supported:
 
 =item cdrbatch
 
+=item detailnum - Link to invoice detail (L<FS::cust_bill_pkg_detail>)
+
 =back
 
 =head1 METHODS
@@ -227,6 +229,7 @@ sub table_info {
         'freesiderewritestatus' => 'Freeside rewrite status',
         'cdrbatch'              => 'Legacy batch',
         'cdrbatchnum'           => 'Batch',
+        'detailnum'             => 'Freeside invoice detail line',
     },
 
   };
@@ -338,8 +341,12 @@ sub check {
 
   #check the foreign keys even?
   #do we want to outright *reject* the CDR?
-  my $error =
-       $self->ut_numbern('acctid');
+  my $error = $self->ut_numbern('acctid');
+  return $error if $error;
+
+  if ( $self->freesidestatus ne 'done' ) {
+    $self->set('detailnum', ''); # can't have this on an unbilled call
+  }
 
   #add a config option to turn these back on if someone needs 'em
   #
@@ -352,8 +359,6 @@ sub check {
   #  # Telstra =1, Optus = 2, RSL COM = 3
   #  || $self->ut_foreign_keyn('carrierid', 'cdr_carrier', 'carrierid' )
 
-  return $error if $error;
-
   $self->SUPER::check;
 }
 
index d0cbdbe..dd118c1 100644 (file)
@@ -86,15 +86,52 @@ sub table { 'cust_bill_pkg_detail'; }
 Adds this record to the database.  If there is an error, returns the error,
 otherwise returns false.
 
+=cut
+
+sub insert {
+  my $self = shift;
+  my $error = $self->SUPER::insert(@_);
+  return $error if $error;
+
+  # link CDRs
+  my $acctids = $self->get('acctid') or return '';
+  $acctids = [ $acctids ] unless ref $acctids;
+  foreach my $acctid ( @$acctids ) {
+    my $cdr = FS::cdr->by_key($acctid);
+    $cdr->set('detailnum', $self->detailnum);
+    $error = $cdr->replace;
+    # this should never happen
+    return "error linking CDR #$acctid: $error" if $error;
+  }
+  '';
+}
+
 =item delete
 
 Delete this record from the database.
 
+=cut
+
+sub delete {
+  my $self = shift;
+  my $error = $self->SUPER::delete;
+  return $error if $error;
+  foreach my $cdr (qsearch('cdr', { detailnum => $self->detailnum })) {
+    $cdr->set('detailnum', '');
+    $error = $cdr->replace;
+    return "error unlinking CDR #" . $cdr->acctid . ": $error" if $error;
+  }
+}
+
 =item replace OLD_RECORD
 
 Replaces the OLD_RECORD with this one in the database.  If there is an error,
 returns the error, otherwise returns false.
 
+=cut
+
+# the replace method can be inherited from FS::Record (doesn't touch CDRs)
+
 =item check
 
 Checks all fields to make sure this is a valid line item detail.  If there is
index 8840a00..be84680 100644 (file)
@@ -178,6 +178,7 @@ Takes a single CDR and returns an invoice detail to describe it.
 
 By default, this maps the following fields from the CDR:
 
+acctid            => acctid
 rated_price       => amount
 rated_classnum    => classnum
 rated_seconds     => duration
@@ -208,6 +209,7 @@ sub single_detail {
   $price = 0 if $cdr->freesidestatus eq 'no-charge';
 
   FS::cust_bill_pkg_detail->new( {
+      'acctid'      => $cdr->acctid,
       'amount'      => $price,
       'classnum'    => $cdr->rated_classnum,
       'duration'    => $cdr->rated_seconds,
index c40fcb8..253956f 100644 (file)
@@ -24,6 +24,7 @@ sub header_detail {
 sub append {
   my $self = shift;
   my $svcnums = ($self->{svcnums} ||= {});
+  my $acctids = $self->{acctids} ||= [];
   foreach my $cdr (@_) {
     my $object = $self->{inbound} ? $cdr->cdr_termination(1) : $cdr;
     my $svcnum = $object->svcnum; # yes, $object->svcnum.
@@ -33,6 +34,8 @@ sub append {
     $subtotal->{count}++;
     $subtotal->{amount} += $object->rated_price
       if $object->freesidestatus ne 'no-charge';
+
+    push @$acctids, $cdr->acctid;
   }
 }
 
@@ -68,6 +71,7 @@ sub finish {
         startdate   => '', #could use the earliest startdate in the bunch?
         regionname  => '', #no, we're using prefix instead
         detail      => $self->csv->string,
+        acctid      => $self->{acctids},
     });
   } #foreach $svcnum
 
index 1b967b4..c41bed3 100644 (file)
@@ -24,6 +24,7 @@ sub header_detail {
 sub append {
   my $self = shift;
   my $svcnums = ($self->{svcnums} ||= {});
+  my $acctids = ($self->{acctids} ||= []);
   foreach my $cdr (@_) {
     my $object = $self->{inbound} ? $cdr->cdr_termination(1) : $cdr;
     my $svcnum = $object->svcnum; # yes, $object->svcnum.
@@ -34,6 +35,8 @@ sub append {
     $subtotal->{duration} += $object->rated_seconds;
     $subtotal->{amount} += $object->rated_price
       if $object->freesidestatus ne 'no-charge';
+
+    push @$acctids, $cdr->acctid;
   }
 }
 
@@ -70,6 +73,7 @@ sub finish {
         startdate   => '', #could use the earliest startdate in the bunch?
         regionname  => '', #no, we're using prefix instead
         detail      => $self->csv->string,
+        acctid      => $self->{acctids},
     });
   } #foreach $svcnum
 
index cd7bbe3..3c33dc1 100644 (file)
@@ -24,6 +24,7 @@ my $prefix_length = 6;
 sub append {
   my $self = shift;
   my $prefixes = ($self->{prefixes} ||= {});
+  my $acctids = ($self->{acctids} ||= []);
   foreach my $cdr (@_) {
     my (undef, $phonenum) = $cdr->parse_number(
       column => ( $self->{inbound} ? 'src' : 'dst' ),
@@ -52,6 +53,8 @@ sub append {
     $subtotal->{duration} += $object->rated_seconds;
     $subtotal->{amount} += $object->rated_price
       if $object->freesidestatus ne 'no-charge';
+
+    push @$acctids, $cdr->acctid;
   }
 }
 
@@ -91,6 +94,7 @@ sub finish {
         startdate   => '', #could use the earliest startdate in the bunch?
         regionname  => '', #no, we're using prefix instead
         detail      => $self->csv->string,
+        acctid      => $self->{acctids},
     });
   } #foreach $prefix
 }