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',      '', '', '',
 
         #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' => [],
       ],
       'primary_key' => 'acctid',
       'unique' => [],
index 5a1d8ea..8ccf7af 100644 (file)
@@ -161,6 +161,8 @@ following fields are currently supported:
 
 =item cdrbatch
 
 
 =item cdrbatch
 
+=item detailnum - Link to invoice detail (L<FS::cust_bill_pkg_detail>)
+
 =back
 
 =head1 METHODS
 =back
 
 =head1 METHODS
@@ -227,6 +229,7 @@ sub table_info {
         'freesiderewritestatus' => 'Freeside rewrite status',
         'cdrbatch'              => 'Legacy batch',
         'cdrbatchnum'           => 'Batch',
         '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?
 
   #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
   #
 
   #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' )
 
   #  # Telstra =1, Optus = 2, RSL COM = 3
   #  || $self->ut_foreign_keyn('carrierid', 'cdr_carrier', 'carrierid' )
 
-  return $error if $error;
-
   $self->SUPER::check;
 }
 
   $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.
 
 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.
 
 =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.
 
 =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
 =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:
 
 
 By default, this maps the following fields from the CDR:
 
+acctid            => acctid
 rated_price       => amount
 rated_classnum    => classnum
 rated_seconds     => duration
 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( {
   $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,
       '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} ||= {});
 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.
   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';
     $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,
         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
 
     });
   } #foreach $svcnum
 
index 1b967b4..c41bed3 100644 (file)
@@ -24,6 +24,7 @@ sub header_detail {
 sub append {
   my $self = shift;
   my $svcnums = ($self->{svcnums} ||= {});
 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.
   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';
     $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,
         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
 
     });
   } #foreach $svcnum
 
index cd7bbe3..3c33dc1 100644 (file)
@@ -24,6 +24,7 @@ my $prefix_length = 6;
 sub append {
   my $self = shift;
   my $prefixes = ($self->{prefixes} ||= {});
 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' ),
   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';
     $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,
         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
 }
     });
   } #foreach $prefix
 }