[freeside-commits] branch FREESIDE_4_BRANCH updated. 31c48790731207e89a80d056dbd44e1ac6f6e453

Mark Wells mark at 420.am
Thu Jul 7 20:31:40 PDT 2016


The branch, FREESIDE_4_BRANCH has been updated
       via  31c48790731207e89a80d056dbd44e1ac6f6e453 (commit)
       via  e18cfb0670bc742200dacee7073b5e29b4927159 (commit)
      from  fba4614e057708bc585b869a517938f29bff25d8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 31c48790731207e89a80d056dbd44e1ac6f6e453
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Jul 7 20:22:39 2016 -0700

    when changing a package with scheduled expiration, transfer the expiration reason to the new package, #71623

diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 9d20fd6..de88cc0 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -2536,6 +2536,21 @@ sub change {
       return "transferring package notes: $error";
     }
   }
+
+  # transfer scheduled expire/adjourn reasons
+  foreach my $action ('expire', 'adjourn') {
+    if ( $cust_pkg->get($action) ) {
+      my $reason = $self->last_cust_pkg_reason($action);
+      if ( $reason ) {
+        $reason->set('pkgnum', $cust_pkg->pkgnum);
+        $error = $reason->replace;
+        if ( $error ) {
+          $dbh->rollback if $oldAutoCommit;
+          return "transferring $action reason: $error";
+        }
+      }
+    }
+  }
   
   my @new_supp_pkgs;
 
diff --git a/FS/FS/cust_pkg_reason.pm b/FS/FS/cust_pkg_reason.pm
index d11d05e..29b4b0a 100644
--- a/FS/FS/cust_pkg_reason.pm
+++ b/FS/FS/cust_pkg_reason.pm
@@ -209,6 +209,54 @@ sub _upgrade_data { # class method
     FS::upgrade_journal->set_done('cust_pkg_reason__missing_reason');
   }
 
+  # Fix misplaced expire/suspend reasons due to package change (RT#71623).
+  # These will look like:
+  # - there is an expire reason linked to pkg1
+  # - pkg1 has been canceled before the reason's date
+  # - pkg2 was changed from pkg1, has an expire date equal to the reason's
+  #   date, and has no expire reason (check this later)
+
+  my $error;
+  foreach my $action ('expire', 'adjourn') {
+    # Iterate this, because a package could be scheduled to expire, then
+    # changed several times, and we need to walk the reason forward to the
+    # last one.
+    while(1) {
+      my @reasons = qsearch(
+        {
+          select    => 'cust_pkg_reason.*',
+          table     => 'cust_pkg_reason',
+          addl_from => ' JOIN cust_pkg pkg1 USING (pkgnum)
+                         JOIN cust_pkg pkg2 ON (pkg1.pkgnum = pkg2.change_pkgnum)',
+          hashref   => { 'action' => uc(substr($action, 0, 1)) },
+          extra_sql => " AND pkg1.cancel IS NOT NULL
+                         AND cust_pkg_reason.date > pkg1.cancel
+                         AND pkg2.$action = cust_pkg_reason.date"
+        });
+      last if !@reasons;
+      warn "Checking ".scalar(@reasons)." possible misplaced $action reasons.\n";
+      foreach my $cust_pkg_reason (@reasons) {
+        my $new_pkg = qsearchs('cust_pkg', { change_pkgnum => $cust_pkg_reason->pkgnum });
+        my $new_reason = $new_pkg->last_cust_pkg_reason($action);
+        if ($new_reason and $new_reason->_date == $new_pkg->get($action)) {
+          # the expiration reason has been recreated on the new package, so
+          # just delete the old one
+          warn "Cleaning $action reason from canceled pkg#" .
+               $cust_pkg_reason->pkgnum . "\n";
+          $error = $cust_pkg_reason->delete;
+        } else {
+          # then the old reason needs to be transferred
+          warn "Moving $action reason from canceled pkg#" .
+               $cust_pkg_reason->pkgnum .
+               " to new pkg#" . $new_pkg->pkgnum ."\n";
+          $cust_pkg_reason->set('pkgnum' => $new_pkg->pkgnum);
+          $error = $cust_pkg_reason->replace;
+        }
+        die $error if $error;
+      }
+    }
+  }
+
   #still can't fill in an action?  don't abort the upgrade
   local($ignore_empty_action) = 1;
 

commit e18cfb0670bc742200dacee7073b5e29b4927159
Author: Mark Wells <mark at freeside.biz>
Date:   Thu Jul 7 13:01:09 2016 -0700

    enable cancel_pkgs to expire packages even if the reason is missing, #71623, from #37177

diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 6c43747..1253ac3 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -76,6 +76,7 @@ use FS::upgrade_journal;
 use FS::sales;
 use FS::cust_payby;
 use FS::contact;
+use FS::reason;
 
 # 1 is mostly method/subroutine entry and options
 # 2 traces progress of some operations
@@ -2391,7 +2392,11 @@ FS::cust_pkg::cancel() methods.
 
 =item quiet - can be set true to supress email cancellation notices.
 
-=item reason - can be set to a cancellation reason (see L<FS:reason>), either a reasonnum of an existing reason, or passing a hashref will create a new reason.  The hashref should have the following keys: typenum - Reason type (see L<FS::reason_type>, reason - Text of the new reason.
+=item reason - can be set to a cancellation reason (see L<FS:reason>), either a
+reasonnum of an existing reason, or passing a hashref will create a new reason.
+The hashref should have the following keys:
+typenum - Reason type (see L<FS::reason_type>)
+reason - Text of the new reason.
 
 =item cust_pkg_reason - can be an arrayref of L<FS::cust_pkg_reason> objects
 for the individual packages, parallel to the C<cust_pkg> argument. The
@@ -2485,12 +2490,26 @@ sub cancel_pkgs {
   if ($opt{'cust_pkg_reason'}) {
     @cprs = @{ delete $opt{'cust_pkg_reason'} };
   }
+  my $null_reason;
   foreach (@pkgs) {
     my %lopt = %opt;
     if (@cprs) {
       my $cpr = shift @cprs;
-      $lopt{'reason'}        = $cpr->reasonnum;
-      $lopt{'reason_otaker'} = $cpr->otaker;
+      if ( $cpr ) {
+        $lopt{'reason'}        = $cpr->reasonnum;
+        $lopt{'reason_otaker'} = $cpr->otaker;
+      } else {
+        warn "no reason found when canceling package ".$_->pkgnum."\n";
+        # we're not actually required to pass a reason to cust_pkg::cancel,
+        # but if we're getting to this point, something has gone awry.
+        $null_reason ||= FS::reason->new_or_existing(
+          reason  => 'unknown reason',
+          type    => 'Cancel Reason',
+          class   => 'C',
+        );
+        $lopt{'reason'} = $null_reason->reasonnum;
+        $lopt{'reason_otaker'} = $FS::CurrentUser::CurrentUser->username;
+      }
     }
     my $error = $_->cancel(%lopt);
     push @errors, 'pkgnum '.$_->pkgnum.': '.$error if $error;

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/cust_main.pm       |   25 +++++++++++++++++++++---
 FS/FS/cust_pkg.pm        |   15 +++++++++++++++
 FS/FS/cust_pkg_reason.pm |   48 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 3 deletions(-)




More information about the freeside-commits mailing list