[freeside-commits] branch FREESIDE_3_BRANCH updated. c4b904d326fa3bca1f9453ae9f58a50a359f98af

Jonathan Prykop jonathan at 420.am
Tue Jun 30 22:10:54 PDT 2015


The branch, FREESIDE_3_BRANCH has been updated
       via  c4b904d326fa3bca1f9453ae9f58a50a359f98af (commit)
       via  a3696f50ea05e5b8f87c24c5298fc35bee03fc75 (commit)
      from  9313346347265c5a1ad3e1da8f2fcbb965a9d6cd (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 c4b904d326fa3bca1f9453ae9f58a50a359f98af
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Tue Jun 30 05:29:49 2015 -0500

    RT#30705: Change contract end date when changing packages [got rid of chronology requirements]

diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 5ec2f5a..0b5a07f 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -2022,9 +2022,6 @@ sub _check_change {
       #option shouldn't be passed, throw error if it's non-empty
       return "Cannot add contract end date when changing packages " . $self->pkgnum;
     }
-    if ($opt->{'start_date'} && ($opt->{'contract_end'} < $opt->{'start_date'})) {
-      return "Contract end date is before change date";
-    }
   }
   return '';
 }
diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html
index c066ff5..046a979 100644
--- a/httemplate/edit/process/change-cust_pkg.html
+++ b/httemplate/edit/process/change-cust_pkg.html
@@ -41,15 +41,9 @@ if ( $cgi->param('locationnum') == -1 ) {
 }
 
 my $error;
-my $contract_end;
 my $now = time;
 if (defined($cgi->param('contract_end'))) {
-  $contract_end = parse_datetime($cgi->param('contract_end'));
-  if ($contract_end < $now) {
-    $error = "Contract end ".$cgi->param('contract_end')." is in the past.";
-  } else {
-    $change{'contract_end'} = $contract_end;
-  }
+  $change{'contract_end'} = parse_datetime($cgi->param('contract_end'));
 }
 
 unless ($error) {

commit a3696f50ea05e5b8f87c24c5298fc35bee03fc75
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Mon Jun 15 23:37:48 2015 -0500

    RT#30705 Change contract end date when changing packages

diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index dcbcfeb..5ec2f5a 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -1979,6 +1979,13 @@ can't be transferred (also see the I<cust_pkg-change_svcpart> config option).
 If unprotect_svcs is true, this method will transfer as many services as 
 it can and then unconditionally cancel the old package.
 
+=item contract_end
+
+If specified, sets this value for the contract_end date on the new package 
+(without regard for keep_dates or the usual date-preservation behavior.)
+Will throw an error if defined but false;  the UI doesn't allow editing 
+this unless it already exists, making removal impossible to undo.
+
 =back
 
 At least one of locationnum, cust_location, pkgpart, refnum, cust_main, or
@@ -1992,6 +1999,36 @@ For example:
 
 =cut
 
+#used by change and change_later
+#didn't put with documented check methods because it depends on change-specific opts
+#and it also possibly edits the value of opts
+sub _check_change {
+  my $self = shift;
+  my $opt = shift;
+  if ( defined($opt->{'contract_end'}) ) {
+    my $current_contract_end = $self->get('contract_end');
+    unless ($opt->{'contract_end'}) {
+      if ($current_contract_end) {
+        return "Cannot remove contract end date when changing packages";
+      } else {
+        #shouldn't even pass this option if there's not a current value
+        #but can be handled gracefully if the option is empty
+        warn "Contract end date passed unexpectedly";
+        delete $opt->{'contract_end'};
+        return '';
+      }
+    }
+    unless ($current_contract_end) {
+      #option shouldn't be passed, throw error if it's non-empty
+      return "Cannot add contract end date when changing packages " . $self->pkgnum;
+    }
+    if ($opt->{'start_date'} && ($opt->{'contract_end'} < $opt->{'start_date'})) {
+      return "Contract end date is before change date";
+    }
+  }
+  return '';
+}
+
 #some false laziness w/order
 sub change {
   my $self = shift;
@@ -1999,6 +2036,16 @@ sub change {
 
   my $conf = new FS::Conf;
 
+  # handle contract_end on cust_pkg same as passed option
+  if ( $opt->{'cust_pkg'} ) {
+    $opt->{'contract_end'} = $opt->{'cust_pkg'}->contract_end;
+    delete $opt->{'contract_end'} unless $opt->{'contract_end'};
+  }
+
+  # check contract_end, prevent adding/removing
+  my $error = $self->_check_change($opt);
+  return $error if $error;
+
   # Transactionize this whole mess
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE'; 
@@ -2011,8 +2058,6 @@ sub change {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my $error;
-
   if ( $opt->{'cust_location'} ) {
     $error = $opt->{'cust_location'}->find_or_insert;
     if ( $error ) {
@@ -2037,6 +2082,9 @@ sub change {
     if ( $opt->{'pkgpart'} and $opt->{'pkgpart'} != $self->pkgpart ) {
       $self->set_initial_timers;
     }
+    # but if contract_end was explicitly specified, that overrides all else
+    $self->set('contract_end', $opt->{'contract_end'})
+      if $opt->{'contract_end'};
     $error = $self->replace;
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
@@ -2094,6 +2142,9 @@ sub change {
                     start_date contract_end)) {
     $hash{$date} = $self->getfield($date);
   }
+  # but if contract_end was explicitly specified, that overrides all else
+  $hash{'contract_end'} = $opt->{'contract_end'}
+    if $opt->{'contract_end'};
 
   # allow $opt->{'locationnum'} = '' to specifically set it to null
   # (i.e. customer default location)
@@ -2366,8 +2417,10 @@ The date for the package change.  Required, and must be in the future.
 
 =item quantity
 
-The pkgpart. locationnum, and quantity of the new package, with the same 
-meaning as in C<change>.
+=item contract_end
+
+The pkgpart, locationnum, quantity and optional contract_end of the new 
+package, with the same meaning as in C<change>.
 
 =back
 
@@ -2377,6 +2430,10 @@ sub change_later {
   my $self = shift;
   my $opt = ref($_[0]) ? shift : { @_ };
 
+  # check contract_end, prevent adding/removing
+  my $error = $self->_check_change($opt);
+  return $error if $error;
+
   my $oldAutoCommit = $FS::UID::AutoCommit;
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
@@ -2390,8 +2447,6 @@ sub change_later {
     return "start_date $date is in the past";
   }
 
-  my $error;
-
   if ( $self->change_to_pkgnum ) {
     my $change_to = FS::cust_pkg->by_key($self->change_to_pkgnum);
     my $new_pkgpart = $opt->{'pkgpart'}
@@ -2400,7 +2455,9 @@ sub change_later {
         if $opt->{'locationnum'} and $opt->{'locationnum'} != $change_to->locationnum;
     my $new_quantity = $opt->{'quantity'}
         if $opt->{'quantity'} and $opt->{'quantity'} != $change_to->quantity;
-    if ( $new_pkgpart or $new_locationnum or $new_quantity ) {
+    my $new_contract_end = $opt->{'contract_end'}
+        if $opt->{'contract_end'} and $opt->{'contract_end'} != $change_to->contract_end;
+    if ( $new_pkgpart or $new_locationnum or $new_quantity or $new_contract_end ) {
       # it hasn't been billed yet, so in principle we could just edit
       # it in place (w/o a package change), but that's bad form.
       # So change the package according to the new options...
@@ -2442,8 +2499,10 @@ sub change_later {
       if $opt->{'locationnum'} and $opt->{'locationnum'} != $self->locationnum;
   my $new_quantity = $opt->{'quantity'}
       if $opt->{'quantity'} and $opt->{'quantity'} != $self->quantity;
+  my $new_contract_end = $opt->{'contract_end'}
+      if $opt->{'contract_end'} and $opt->{'contract_end'} != $self->contract_end;
 
-  return '' unless $new_pkgpart or $new_locationnum or $new_quantity; # wouldn't do anything
+  return '' unless $new_pkgpart or $new_locationnum or $new_quantity or $new_contract_end; # wouldn't do anything
 
   # allow $opt->{'locationnum'} = '' to specifically set it to null
   # (i.e. customer default location)
@@ -2454,7 +2513,7 @@ sub change_later {
     locationnum => $opt->{'locationnum'},
     start_date  => $date,
     map   {  $_ => ( $opt->{$_} || $self->$_() )  }
-      qw( pkgpart quantity refnum salesnum )
+      qw( pkgpart quantity refnum salesnum contract_end )
   } );
   $error = $new->insert('change' => 1, 
                         'allow_pkgpart' => ($new_pkgpart ? 0 : 1));
diff --git a/httemplate/edit/process/change-cust_pkg.html b/httemplate/edit/process/change-cust_pkg.html
index 96175e1..c066ff5 100644
--- a/httemplate/edit/process/change-cust_pkg.html
+++ b/httemplate/edit/process/change-cust_pkg.html
@@ -41,34 +41,49 @@ if ( $cgi->param('locationnum') == -1 ) {
 }
 
 my $error;
-if ( $cgi->param('delay') ) {
-  my $date = parse_datetime($cgi->param('start_date'));
-  if (!$date) {
-    $error = "Invalid change date '".$cgi->param('start_date')."'.";
-  } elsif ( $date < time ) {
-    $error = "Change date ".$cgi->param('start_date')." is in the past.";
+my $contract_end;
+my $now = time;
+if (defined($cgi->param('contract_end'))) {
+  $contract_end = parse_datetime($cgi->param('contract_end'));
+  if ($contract_end < $now) {
+    $error = "Contract end ".$cgi->param('contract_end')." is in the past.";
   } else {
-    # schedule the change
-    $change{'start_date'} = $date;
-    $error = $cust_pkg->change_later(\%change);
+    $change{'contract_end'} = $contract_end;
   }
-} else {
-  # special case: if there's a package change scheduled, and it matches
-  # the parameters the user requested this time, then change to the existing
-  # future package.
-  if ( $cust_pkg->change_to_pkgnum ) {
-    my $change_to = FS::cust_pkg->by_key($cust_pkg->change_to_pkgnum);
-    if ( $change_to->pkgpart      == $change{'pkgpart'} and
-         $change_to->locationnum  == $change{'locationnum'} ) {
-
-      %change = ( 'cust_pkg' => $change_to );
+}
 
+unless ($error) {
+  if ( $cgi->param('delay') ) {
+    my $date = parse_datetime($cgi->param('start_date'));
+    if (!$date) {
+      $error = "Invalid change date '".$cgi->param('start_date')."'.";
+    } elsif ( $date < $now ) {
+      $error = "Change date ".$cgi->param('start_date')." is in the past.";
+    } else {
+      # schedule the change
+      $change{'start_date'} = $date;
+      $error = $cust_pkg->change_later(\%change);
+    }
+  } else {
+    # special case: if there's a package change scheduled, and it matches
+    # the parameters the user requested this time, then change to the existing
+    # future package.
+    if ( $cust_pkg->change_to_pkgnum ) {
+      my $change_to = FS::cust_pkg->by_key($cust_pkg->change_to_pkgnum);
+      if (
+        $change_to->pkgpart      == $change{'pkgpart'} and
+        $change_to->locationnum  == $change{'locationnum'} and
+        $change_to->quantity     == $change{'quantity'} and
+        $change_to->contract_end == $change{'contract_end'}
+      ) {
+        %change = ( 'cust_pkg' => $change_to );
+      }
     }
-  }
     
-  # do a package change right now
-  my $pkg_or_error = $cust_pkg->change( \%change );
-  $error = ref($pkg_or_error) ? '' : $pkg_or_error;
+    # do a package change right now
+    my $pkg_or_error = $cust_pkg->change( \%change );
+    $error = ref($pkg_or_error) ? '' : $pkg_or_error;
+  }
 }
 
 </%init>
diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi
index 1b4a94e..e74747e 100755
--- a/httemplate/misc/change_pkg.cgi
+++ b/httemplate/misc/change_pkg.cgi
@@ -28,6 +28,14 @@
                'curr_value' => $cust_pkg->quantity
   &>
 
+% if ($use_contract_end) {
+  <& /elements/tr-input-date-field.html, {
+      'name'  => 'contract_end',
+      'value' => ($cgi->param('contract_end') || $cust_pkg->get('contract_end')),
+      'label' => '<B>Contract End</B>',
+    } &>
+% }
+
 </TABLE>
 <BR>
 
@@ -124,6 +132,8 @@ my $part_pkg = $cust_pkg->part_pkg;
 
 my $title = "Change Package";
 
+my $use_contract_end = $cust_pkg->get('contract_end') ? 1 : 0;
+
 # if there's already a package change ordered, preload it
 if ( $cust_pkg->change_to_pkgnum ) {
   my $change_to = FS::cust_pkg->by_key($cust_pkg->change_to_pkgnum);
@@ -131,6 +141,9 @@ if ( $cust_pkg->change_to_pkgnum ) {
   foreach(qw( start_date pkgpart locationnum quantity )) {
     $cgi->param($_, $change_to->get($_));
   }
+  if ($use_contract_end) {
+    $cgi->param('contract_end', $change_to->get('contract_end'));
+  }
   $title = "Edit Scheduled Package Change";
 }
 </%init>
diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html
index 047abda..3063e3f 100644
--- a/httemplate/view/cust_main/packages/status.html
+++ b/httemplate/view/cust_main/packages/status.html
@@ -417,6 +417,10 @@ sub pkg_status_row_expire {
     } elsif ( $cust_pkg->change_to_pkg->locationnum != $cust_pkg->locationnum )
     {
       $title = mt('Will <b>change location</b> on');
+    } elsif (( $cust_pkg->change_to_pkg->quantity != $cust_pkg->quantity ) ||
+             ( $cust_pkg->change_to_pkg->contract_end != $cust_pkg->contract_end ))
+    {
+      $title = mt('Will change on');
     } else {
       # FS::cust_pkg->change_later should have prevented this, but 
       # just so that we can display _something_

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

Summary of changes:
 FS/FS/cust_pkg.pm                              |   74 +++++++++++++++++++++---
 httemplate/edit/process/change-cust_pkg.html   |   59 +++++++++++--------
 httemplate/misc/change_pkg.cgi                 |   13 +++++
 httemplate/view/cust_main/packages/status.html |    4 ++
 4 files changed, 116 insertions(+), 34 deletions(-)




More information about the freeside-commits mailing list