[freeside-commits] branch master updated. 17b4664d50ba04809cb8b68fa0f3b6146b0c8ff3

Ivan ivan at 420.am
Mon Jun 4 15:29:24 PDT 2012


The branch, master has been updated
       via  17b4664d50ba04809cb8b68fa0f3b6146b0c8ff3 (commit)
      from  93786ae8b97b3b11b11eff8ee5fdf78b6b53f26f (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 17b4664d50ba04809cb8b68fa0f3b6146b0c8ff3
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Mon Jun 4 15:29:18 2012 -0700

    suspend and unsuspend whole customer action, RT#17841

diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm
index bcf3f64..4aa777b 100644
--- a/FS/FS/AccessRight.pm
+++ b/FS/FS/AccessRight.pm
@@ -111,6 +111,8 @@ tie my %rights, 'Tie::IxHash',
     'Edit customer tags',
     'Edit referring customer',
     'View customer history',
+    'Suspend customer',
+    'Unsuspend customer',
     'Cancel customer',
     'Complimentary customer', #aka users-allow_comp 
     'Merge customer',
diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm
index 26a480b..52cae34 100644
--- a/FS/FS/access_right.pm
+++ b/FS/FS/access_right.pm
@@ -3,6 +3,7 @@ package FS::access_right;
 use strict;
 use vars qw( @ISA );
 use FS::Record qw( qsearch qsearchs );
+use FS::upgrade_journal;
 
 @ISA = qw(FS::Record);
 
@@ -183,9 +184,13 @@ sub _upgrade_data { # class method
   my @all_groups = qsearch('access_group', {});
 
   my %onetime = (
-    'List customers'   => 'List all customers',
-    'List packages'    => 'Summarize packages',
-    'Post payment'     => 'Backdate payment',
+    'List customers'                      => 'List all customers',
+    'List packages'                       => 'Summarize packages',
+    'Post payment'                        => 'Backdate payment',
+    'Cancel customer package immediately' => 'Un-cancel customer package',
+    'Suspend customer package'            => 'Suspend customer',
+    'Unsuspend customer package'          => 'Unsuspend customer',
+
     'List services'    => [ 'Services: Accounts',
                             'Services: Domains',
                             'Services: Certificates',
@@ -205,7 +210,6 @@ sub _upgrade_data { # class method
                             'Usage: Call Detail Records (CDRs)',
                             'Usage: Unrateable CDRs',
                           ],
-    'Cancel customer package immediately' => 'Un-cancel customer package',
   );
 
   foreach my $old_acl ( keys %onetime ) {
diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm
index 887ac49..957043a 100644
--- a/FS/FS/cust_main/Packages.pm
+++ b/FS/FS/cust_main/Packages.pm
@@ -355,6 +355,7 @@ Returns all suspended packages (see L<FS::cust_pkg>) for this customer.
 
 sub suspended_pkgs {
   my $self = shift;
+  return $self->num_suspended_pkgs unless wantarray;
   grep { $_->susp } $self->ncancelled_pkgs;
 }
 
@@ -381,6 +382,7 @@ this customer.
 
 sub unsuspended_pkgs {
   my $self = shift;
+  return $self->num_unsuspended_pkgs unless wantarray;
   grep { ! $_->susp } $self->ncancelled_pkgs;
 }
 
@@ -442,6 +444,16 @@ sub num_ncancelled_pkgs {
   shift->num_pkgs("( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )");
 }
 
+sub num_suspended_pkgs {
+  shift->num_pkgs("     ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
+                    AND cust_pkg.susp IS NOT NULL AND cust_pkg.susp != 0   ");
+}
+
+sub num_unsuspended_pkgs {
+  shift->num_pkgs("     ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
+                    AND ( cust_pkg.susp   IS NULL OR cust_pkg.susp   = 0 ) ");
+}
+
 sub num_pkgs {
   my( $self ) = shift;
   my $sql = scalar(@_) ? shift : '';
diff --git a/httemplate/misc/cust_main-suspend.cgi b/httemplate/misc/cust_main-suspend.cgi
new file mode 100755
index 0000000..6185136
--- /dev/null
+++ b/httemplate/misc/cust_main-suspend.cgi
@@ -0,0 +1,75 @@
+<& /elements/header-popup.html, mt("Customer suspended") &>
+  <SCRIPT TYPE="text/javascript">
+    window.top.location.reload();
+  </SCRIPT>
+  </BODY>
+</HTML>
+<%init>
+
+#false laziness w/cust_main-cancel.cgi
+
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right('Suspend customer');
+
+my $custnum;
+my $adjourn = '';
+if ( $cgi->param('custnum') =~ /^(\d+)$/ ) {
+  $custnum = $1;
+  $adjourn = $cgi->param('adjourn');
+} else {
+  my($query) = $cgi->keywords;
+  $query =~ /^(\d+)$/ || die "Illegal custnum";
+  $custnum = $1;
+}
+
+#false laziness w/process/cancel_pkg.html
+
+#untaint reasonnum
+my $reasonnum = $cgi->param('reasonnum');
+$reasonnum =~ /^(-?\d+)$/ || die "Illegal reasonnum";
+$reasonnum = $1;
+
+if ($reasonnum == -1) {
+  $reasonnum = {
+    'typenum' => scalar( $cgi->param('newreasonnumT') ),
+    'reason'  => scalar( $cgi->param('newreasonnum' ) ),
+  };
+}
+
+#eslaf
+
+my $cust_main = qsearchs( {
+  'table'     => 'cust_main',
+  'hashref'   => { 'custnum' => $custnum },
+  'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+} );
+
+my @errors;
+if($cgi->param('now_or_later')) {
+  $adjourn = parse_datetime($adjourn);
+  if($adjourn) {
+    #warn "setting adjourn dates on custnum#$custnum\n";
+    my @pkgs = $cust_main->unsuspended_pkgs;
+    @errors = grep {$_} map { $_->suspend(
+      'reason'  => $reasonnum,
+      'date'    => $adjourn,
+    ) } @pkgs;
+  }
+  else {
+    @errors = ("error parsing adjourn date: ".$cgi->param('adjourn'));
+  }
+}
+else {
+  warn "suspending $cust_main";
+  @errors = $cust_main->suspend(
+    'reason' => $reasonnum,
+  );
+}
+my $error = join(' / ', @errors) if scalar(@errors);
+
+if ( $error ) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(1). "suspend_cust.html?". $cgi->query_string );
+}
+
+</%init>
diff --git a/httemplate/misc/cust_main-unsuspend.cgi b/httemplate/misc/cust_main-unsuspend.cgi
new file mode 100755
index 0000000..eb4a2c8
--- /dev/null
+++ b/httemplate/misc/cust_main-unsuspend.cgi
@@ -0,0 +1,56 @@
+<& /elements/header-popup.html, mt("Customer unsuspended") &>
+  <SCRIPT TYPE="text/javascript">
+    window.top.location.reload();
+  </SCRIPT>
+  </BODY>
+</HTML>
+<%init>
+
+#false laziness w/cust_main-cancel.cgi
+
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right('Unsuspend customer');
+
+my $custnum;
+my $resume = '';
+if ( $cgi->param('custnum') =~ /^(\d+)$/ ) {
+  $custnum = $1;
+  $resume = $cgi->param('resume');
+} else {
+  my($query) = $cgi->keywords;
+  $query =~ /^(\d+)$/ || die "Illegal custnum";
+  $custnum = $1;
+}
+
+my $cust_main = qsearchs( {
+  'table'     => 'cust_main',
+  'hashref'   => { 'custnum' => $custnum },
+  'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+} );
+
+my @errors;
+if($cgi->param('now_or_later')) {
+  $resume = parse_datetime($resume);
+  if($resume) {
+    #warn "setting resume dates on custnum#$custnum\n";
+    my @pkgs = $cust_main->suspended_pkgs;
+    @errors = grep {$_} map { $_->unsuspend(
+      'date'    => $resume,
+    ) } @pkgs;
+  }
+  else {
+    @errors = ("error parsing adjourn date: ".$cgi->param('adjourn'));
+  }
+}
+else {
+  warn "unsuspending $cust_main";
+  @errors = $cust_main->unsuspend;
+}
+my $error = join(' / ', @errors) if scalar(@errors);
+
+if ( $error ) {
+  $cgi->param('error', $error);
+  print $cgi->redirect(popurl(1). "unsuspend_cust.html?". $cgi->query_string );
+}
+
+</%init>
diff --git a/httemplate/misc/suspend_cust.html b/httemplate/misc/suspend_cust.html
new file mode 100644
index 0000000..b41f36f
--- /dev/null
+++ b/httemplate/misc/suspend_cust.html
@@ -0,0 +1,79 @@
+<& /elements/header-popup.html, mt('Suspend customer')  &>
+
+<& /elements/error.html &>
+
+<FORM NAME="cust_suspend_popup" ACTION="<% popurl(1) %>cust_main-suspend.cgi" METHOD=POST>
+<INPUT TYPE="hidden" NAME="custnum" VALUE="<% $custnum %>">
+
+ <P ALIGN="center"><B><% mt('Suspend this customer?') |h %></B>
+
+<TABLE BORDER="0" CELLSPACING="2"
+STYLE="margin-left:auto; margin-right:auto">
+<TR>
+  <TD ALIGN="right">
+    <INPUT TYPE="radio" NAME="now_or_later" VALUE="0" onclick="toggle(false)" CHECKED />
+  </TD>
+  <TD ALIGN="left"><% mt('Suspend now') |h %></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">
+    <INPUT TYPE="radio" NAME="now_or_later" VALUE="1" onclick="toggle(true)" />
+  </TD>
+  <TD ALIGN="left"><% mt('Suspend on date: ') |h %> 
+  <& /elements/input-date-field.html, {
+              'name'    => 'adjourn',
+              'value'   => time,
+    }  &>
+  </TD>
+</TR>
+</TABLE>
+<SCRIPT type="text/javascript">
+function toggle(val) {
+  document.getElementById("adjourn_text").disabled = !val;
+  document.getElementById("adjourn_button").style.visibility = 
+    val ? 'visible' : 'hidden';
+}
+toggle(false);
+</SCRIPT> 
+
+<TABLE BGCOLOR="#cccccc", BORDER="0" CELLSPACING="2"
+STYLE="margin-left:auto; margin-right:auto">
+<& /elements/tr-select-reason.html,
+             'field'          => 'reasonnum',
+             'reason_class'   => 'C',
+             'cgi'            => $cgi,
+             'control_button' => "document.getElementById('confirm_suspend_cust_button')",
+&>
+
+</TABLE>
+
+<BR>
+<P ALIGN="CENTER">
+<INPUT TYPE="submit" NAME="submit" ID="confirm_suspend_cust_button" VALUE="<% mt('Suspend customer') |h %>" DISABLED> 
+        
+<INPUT TYPE="BUTTON" VALUE="<% mt("Don't suspend") |h %>" onClick="parent.cClick();"> 
+
+</FORM>
+</BODY>
+</HTML>
+
+<%init>
+
+#false laziness w/cancel_cust.html
+
+$cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum';
+my $custnum = $1;
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied" unless $curuser->access_right('Suspend customer');
+
+my $cust_main = qsearchs( {
+  'table'     => 'cust_main',
+  'hashref'   => { 'custnum' => $custnum },
+  'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+} );
+die "No customer # $custnum" unless $cust_main;
+
+</%init>
+
diff --git a/httemplate/misc/unsuspend_cust.html b/httemplate/misc/unsuspend_cust.html
new file mode 100644
index 0000000..600eb26
--- /dev/null
+++ b/httemplate/misc/unsuspend_cust.html
@@ -0,0 +1,68 @@
+<& /elements/header-popup.html, mt('Unsuspend customer')  &>
+
+<& /elements/error.html &>
+
+<FORM NAME="cust_unsuspend_popup" ACTION="<% popurl(1) %>cust_main-unsuspend.cgi" METHOD=POST>
+<INPUT TYPE="hidden" NAME="custnum" VALUE="<% $custnum %>">
+
+ <P ALIGN="center"><B><% mt('Unsuspend this customer?') |h %></B>
+
+<TABLE BORDER="0" CELLSPACING="2"
+STYLE="margin-left:auto; margin-right:auto">
+<TR>
+  <TD ALIGN="right">
+    <INPUT TYPE="radio" NAME="now_or_later" VALUE="0" onclick="toggle(false)" CHECKED />
+  </TD>
+  <TD ALIGN="left"><% mt('Unsuspend now') |h %></TD>
+</TR>
+<TR>
+  <TD ALIGN="right">
+    <INPUT TYPE="radio" NAME="now_or_later" VALUE="1" onclick="toggle(true)" />
+  </TD>
+  <TD ALIGN="left"><% mt('Unsuspend on date: ') |h %> 
+  <& /elements/input-date-field.html, {
+              'name'    => 'resume',
+              'value'   => time,
+    }  &>
+  </TD>
+</TR>
+</TABLE>
+<SCRIPT type="text/javascript">
+function toggle(val) {
+  document.getElementById("resume_text").disabled = !val;
+  document.getElementById("resume_button").style.visibility = 
+    val ? 'visible' : 'hidden';
+}
+toggle(false);
+</SCRIPT> 
+
+<BR>
+<P ALIGN="CENTER">
+<INPUT TYPE="submit" NAME="submit" ID="confirm_unsuspend_cust_button" VALUE="<% mt('Unsuspend customer') |h %>"> 
+        
+<INPUT TYPE="BUTTON" VALUE="<% mt("Don't unsuspend") |h %>" onClick="parent.cClick();"> 
+
+</FORM>
+</BODY>
+</HTML>
+
+<%init>
+
+#false laziness w/cancel_cust.html
+
+$cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum';
+my $custnum = $1;
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied" unless $curuser->access_right('Unsuspend customer');
+
+my $cust_main = qsearchs( {
+  'table'     => 'cust_main',
+  'hashref'   => { 'custnum' => $custnum },
+  'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+} );
+die "No customer # $custnum" unless $cust_main;
+
+</%init>
+
diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi
index 83f28d3..ec31919 100755
--- a/httemplate/view/cust_main.cgi
+++ b/httemplate/view/cust_main.cgi
@@ -46,10 +46,39 @@ function areyousure(href, message) {
   <A HREF="<% $p %>edit/cust_main.cgi?<% $custnum %>"><% mt('Edit this customer') |h %></A> | 
 % } 
 
-% if ( $curuser->access_right('Cancel customer')
-%        && $cust_main->ncancelled_pkgs
+% if ( $curuser->access_right('Suspend customer')
+%        && scalar($cust_main->unsuspended_pkgs)
+%      ) {
+  <& /elements/popup_link-cust_main.html,
+              { 'action'      => $p. 'misc/suspend_cust.html',
+                'label'       => emt('Suspend this customer'),
+                'actionlabel' => emt('Confirm Suspension'),
+                'color'       => '#ff9900',
+                'cust_main'   => $cust_main,
+                'width'       => 616, #make room for reasons
+                'height'      => 366,
+              }
+  &> | 
+% }
+
+% if ( $curuser->access_right('Unsuspend customer')
+%        && scalar($cust_main->suspended_pkgs)
 %      ) {
+  <& /elements/popup_link-cust_main.html,
+              { 'action'      => $p. 'misc/unsuspend_cust.html',
+                'label'       => emt('Unsuspend this customer'),
+                'actionlabel' => emt('Confirm Unsuspension'),
+                #'color'       => '#ff9900',
+                'cust_main'   => $cust_main,
+                #'width'       => 616, #make room for reasons
+                #'height'      => 366,
+              }
+  &> | 
+% }
 
+% if ( $curuser->access_right('Cancel customer')
+%        && scalar($cust_main->ncancelled_pkgs)
+%      ) {
   <& /elements/popup_link-cust_main.html,
               { 'action'      => $p. 'misc/cancel_cust.html',
                 'label'       => emt('Cancel this customer'),
@@ -60,11 +89,9 @@ function areyousure(href, message) {
                 'height'      => 366,
               }
   &> | 
-
 % }
 
 % if ( $curuser->access_right('Merge customer') ) {
-
   <& /elements/popup_link-cust_main.html,
               { 'action'      => $p. 'misc/merge_cust.html',
                 'label'       => emt('Merge this customer'),
@@ -74,7 +101,6 @@ function areyousure(href, message) {
                 'height'      => 192,
               }
   &> | 
-
 % } 
 
 % if ( $conf->exists('deletecustomers')

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

Summary of changes:
 FS/FS/AccessRight.pm                               |    2 +
 FS/FS/access_right.pm                              |   12 ++-
 FS/FS/cust_main/Packages.pm                        |   12 ++++
 ...{cust_main-cancel.cgi => cust_main-suspend.cgi} |   33 +++++-----
 httemplate/misc/cust_main-unsuspend.cgi            |   56 ++++++++++++++++
 .../misc/{cancel_cust.html => suspend_cust.html}   |   34 ++++------
 httemplate/misc/unsuspend_cust.html                |   68 ++++++++++++++++++++
 httemplate/view/cust_main.cgi                      |   36 +++++++++--
 8 files changed, 207 insertions(+), 46 deletions(-)
 copy httemplate/misc/{cust_main-cancel.cgi => cust_main-suspend.cgi} (61%)
 create mode 100755 httemplate/misc/cust_main-unsuspend.cgi
 copy httemplate/misc/{cancel_cust.html => suspend_cust.html} (54%)
 create mode 100644 httemplate/misc/unsuspend_cust.html




More information about the freeside-commits mailing list