option to reprocess CDRs when voiding an invoice, RT#79001
authorIvan Kohler <ivan@freeside.biz>
Mon, 5 Feb 2018 01:47:48 +0000 (17:47 -0800)
committerIvan Kohler <ivan@freeside.biz>
Mon, 5 Feb 2018 01:47:48 +0000 (17:47 -0800)
FS/FS/cust_bill.pm
FS/FS/cust_bill_pkg.pm
FS/FS/cust_bill_pkg_detail.pm
httemplate/misc/process/void-cust_bill.html
httemplate/misc/void-cust_bill.html

index 8b94dcc..bd1b8bb 100644 (file)
@@ -215,7 +215,7 @@ sub insert {
 
 }
 
-=item void [ REASON ]
+=item void [ REASON [ , REPROCESS_CDRS ] ]
 
 Voids this invoice: deletes the invoice and adds a record of the voided invoice
 to the FS::cust_bill_void table (and related tables starting from
@@ -226,6 +226,7 @@ FS::cust_bill_pkg_void).
 sub void {
   my $self = shift;
   my $reason = scalar(@_) ? shift : '';
+  my $reprocess_cdrs = scalar(@_) ? shift : '';
 
   unless (ref($reason) || !$reason) {
     $reason = FS::reason->new_or_existing(
@@ -257,7 +258,7 @@ sub void {
   }
 
   foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) {
-    my $error = $cust_bill_pkg->void($reason);
+    my $error = $cust_bill_pkg->void($reason, $reprocess_cdrs);
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return $error;
@@ -3541,6 +3542,23 @@ sub _items_aging_balances {
   return map{ sprintf('%.2f',$_) } @aging_balances;
 }
 
+=item has_call_details
+
+Returns true if this invoice has call details.
+
+=cut
+
+sub has_call_details {
+  my $self = shift;
+  $self->scalar_sql("
+    SELECT 1 FROM cust_bill_pkg_detail
+             LEFT JOIN cust_bill_pkg USING (billpkgnum)
+      WHERE cust_bill_pkg_detail.format = 'C'
+        AND cust_bill_pkg.invnum = ?
+      LIMIT 1
+  ", $self->invnum);
+}
+
 =item call_details [ OPTION => VALUE ... ]
 
 Returns an array of CSV strings representing the call details for this invoice
index e44a847..77dce24 100644 (file)
@@ -324,7 +324,7 @@ sub insert {
 
 }
 
-=item void [ REASON ]
+=item void [ REASON [ , REPROCESS_CDRS ] ]
 
 Voids this line item: deletes the line item and adds a record of the voided
 line item to the FS::cust_bill_pkg_void table (and related tables).
@@ -334,6 +334,7 @@ line item to the FS::cust_bill_pkg_void table (and related tables).
 sub void {
   my $self = shift;
   my $reason = scalar(@_) ? shift : '';
+  my $reprocess_cdrs = scalar(@_) ? shift : '';
 
   unless (ref($reason) || !$reason) {
     $reason = FS::reason->new_or_existing(
@@ -373,6 +374,9 @@ sub void {
     cust_tax_exempt_pkg
     cust_bill_pkg_fee
   )) {
+    my %delete_args = ();
+    $delete_args{'reprocess_cdrs'} = $reprocess_cdrs
+      if $table eq 'cust_bill_pkg_detail';
 
     foreach my $linked ( qsearch($table, { billpkgnum=>$self->billpkgnum }) ) {
 
@@ -380,7 +384,7 @@ sub void {
       my $void = $vclass->new( {
         map { $_ => $linked->get($_) } $linked->fields
       });
-      my $error = $void->insert || $linked->delete;
+      my $error = $void->insert || $linked->delete(%delete_args);
       if ( $error ) {
         $dbh->rollback if $oldAutoCommit;
         return $error;
@@ -863,7 +867,7 @@ sub _item_discount {
   # show introductory rate as a pseudo-discount
   if (!$d) { # this will conflict with showing real discounts
     my $part_pkg = $self->part_pkg;
-    if ( $part_pkg and $part_pkg->option('show_as_discount') ) {
+    if ( $part_pkg and $part_pkg->option('show_as_discount',1) ) {
       my $cust_pkg = $self->cust_pkg;
       my $intro_end = $part_pkg->intro_end($cust_pkg);
       my $_date = $self->cust_bill->_date;
index dd118c1..19b15f7 100644 (file)
@@ -106,21 +106,37 @@ sub insert {
   '';
 }
 
-=item delete
+=item delete [ ARG => VALUE ... ]
 
 Delete this record from the database.
 
+If the "reprocess_cdrs" argument is set to true, resets the status of any
+related CDRs (and deletes their associated cdr_termination records, if any).
+
 =cut
 
 sub delete {
-  my $self = shift;
+  my( $self, %args ) = @_;
+
   my $error = $self->SUPER::delete;
   return $error if $error;
+
   foreach my $cdr (qsearch('cdr', { detailnum => $self->detailnum })) {
+
     $cdr->set('detailnum', '');
+    $cdr->set('freesidestatus', '') if $args{'reprocess_cdrs'};
     $error = $cdr->replace;
     return "error unlinking CDR #" . $cdr->acctid . ": $error" if $error;
+
+    #well, technically this could have been on other invoices / termination
+    # partners... separate flag?
+    $self->scalar_sql( 'DELETE FROM cdr_termination WHERE acctid = ?',
+                       $cdr->acctid )
+      if $args{'reprocess_cdrs'};
+
   }
+
+  '';
 }
 
 =item replace OLD_RECORD
index 32a2fc5..49dda18 100755 (executable)
@@ -19,8 +19,8 @@ my $invnum = $1;
 
 my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum});
 
-my $custnum = $cust_bill->custnum;
-
-my $error = $cust_bill->void( scalar($cgi->param('reason')) );
+my $error = $cust_bill->void( scalar($cgi->param('reason')),
+                              scalar($cgi->param('reprocess_cdrs')),
+                            );
 
 </%init>
index e4e4705..e5fbdc6 100755 (executable)
              'cgi'            => $cgi
 &>
 
+% if ( $cust_bill->has_call_details ) {
+  <& /elements/tr-checkbox.html,
+       label => 'Reprocess CDRs',
+       field => 'reprocess_cdrs',
+       value => '1',
+  &>
+% }
+
 </TABLE>
 
 <BR>