[freeside-commits] branch master updated. 3846acae1c2a7ecb275e400cf3802ada6bc89ed2

Jonathan Prykop jonathan at 420.am
Fri May 29 21:06:00 PDT 2015


The branch, master has been updated
       via  3846acae1c2a7ecb275e400cf3802ada6bc89ed2 (commit)
      from  d0ba32be1771276ed7f54c987c0e23cf496108bd (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 3846acae1c2a7ecb275e400cf3802ada6bc89ed2
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Fri May 29 23:05:00 2015 -0500

    RT#25929: Customer self-service forward editing

diff --git a/FS/FS/ClientAPI/MasonComponent.pm b/FS/FS/ClientAPI/MasonComponent.pm
index b6f8aa4..50597e2 100644
--- a/FS/FS/ClientAPI/MasonComponent.pm
+++ b/FS/FS/ClientAPI/MasonComponent.pm
@@ -22,6 +22,7 @@ my %allowed_comps = map { $_=>1 } qw(
   /misc/counties.cgi
   /misc/svc_acct-domains.cgi
   /misc/part_svc-columns.cgi
+  /edit/elements/svc_forward.html
 );
 
 my %session_comps = map { $_=>1 } qw(
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index dfa90e2..c57584e 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -2786,6 +2786,15 @@ sub provision_external {
             );
 }
 
+sub provision_forward {
+  my $p = shift;
+  _provision( 'FS::svc_forward',
+              ['srcsvc','src','dstsvc','dst'],
+              [],
+              $p,
+            );
+}
+
 sub _provision {
   my( $class, $fields, $return_fields, $p ) = splice(@_, 0, 4);
   warn "_provision called for $class\n"
@@ -2911,6 +2920,10 @@ sub part_svc_info {
         }
   }
 
+  if ($ret->{'svcdb'} eq 'svc_forward') {
+    $ret->{'forward_emails'} = {$cust_pkg->forward_emails()};
+  }
+
   $ret;
 }
 
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 5859727..3800e94 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -4978,6 +4978,78 @@ sub bulk_change {
   '';
 }
 
+=item forward_emails
+
+Returns a hash of svcnums and corresponding email addresses
+for svc_acct services that can be used as source or dest
+for svc_forward services provisioned in this package.
+
+Accepts options I<svc_forward> OR I<svcnum> for a svc_forward
+service;  if included, will ensure the current values of the
+specified service are included in the list, even if for some
+other reason they wouldn't be.  If called as a class method
+with a specified service, returns only these current values.
+
+Caution: does not actually check if svc_forward services are
+available to be provisioned on this package.
+
+=cut
+
+sub forward_emails {
+  my $self = shift;
+  my %opt = @_;
+
+  #load optional service, thoroughly validated
+  die "Use svcnum or svc_forward, not both"
+    if $opt{'svcnum'} && $opt{'svc_forward'};
+  my $svc_forward = $opt{'svc_forward'};
+  $svc_forward ||= qsearchs('svc_forward',{ 'svcnum' => $opt{'svcnum'} })
+    if $opt{'svcnum'};
+  die "Specified service is not a forward service"
+    if $svc_forward && (ref($svc_forward) ne 'FS::svc_forward');
+  die "Specified service not found"
+    if ($opt{'svcnum'} || $opt{'svc_forward'}) && !$svc_forward;
+
+  my %email;
+
+  ## everything below was basically copied from httemplate/edit/svc_forward.cgi 
+  ## with minimal refactoring, not sure why we can't just load all svc_accts for this custnum
+
+  #add current values from specified service, if there was one
+  if ($svc_forward) {
+    foreach my $method (qw( srcsvc_acct dstsvc_acct )) {
+      my $svc_acct = $svc_forward->$method();
+      $email{$svc_acct->svcnum} = $svc_acct->email if $svc_acct;
+    }
+  }
+
+  if (ref($self) eq 'FS::cust_pkg') {
+
+    #and including the rest for this customer
+    my($u_part_svc, at u_acct_svcparts);
+    foreach $u_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_acct'}) ) {
+      push @u_acct_svcparts,$u_part_svc->getfield('svcpart');
+    }
+
+    my $custnum = $self->getfield('custnum');
+    foreach my $i_cust_pkg ( qsearch('cust_pkg',{'custnum'=>$custnum}) ) {
+      my $cust_pkgnum = $i_cust_pkg->getfield('pkgnum');
+      #now find the corresponding record(s) in cust_svc (for this pkgnum!)
+      foreach my $acct_svcpart (@u_acct_svcparts) {
+        foreach my $i_cust_svc (
+          qsearch( 'cust_svc', { 'pkgnum'  => $cust_pkgnum,
+                                 'svcpart' => $acct_svcpart } )
+        ) {
+          my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $i_cust_svc->svcnum } );
+          $email{$svc_acct->svcnum} = $svc_acct->email;
+        }  
+      }
+    }
+  }
+
+  return %email;
+}
+
 # Used by FS::Upgrade to migrate to a new database.
 sub _upgrade_data {  # class method
   my ($class, %opts) = @_;
diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm
index acf655b..847222d 100644
--- a/fs_selfservice/FS-SelfService/SelfService.pm
+++ b/fs_selfservice/FS-SelfService/SelfService.pm
@@ -83,6 +83,7 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'provision_phone'           => 'MyAccount/provision_phone',
   'provision_pbx'             => 'MyAccount/provision_pbx',
   'provision_external'        => 'MyAccount/provision_external',
+  'provision_forward'         => 'MyAccount/provision_forward',
   'unprovision_svc'           => 'MyAccount/unprovision_svc',
   'myaccount_passwd'          => 'MyAccount/myaccount_passwd',
   'reset_passwd'              => 'MyAccount/reset_passwd',
diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
index 4802178..999c62d 100644
--- a/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
+++ b/fs_selfservice/FS-SelfService/cgi/myaccount_menu.html
@@ -28,7 +28,7 @@ my %payby_mode;
 # $payby_mode{FOO} is true if FOO is thirdparty, false if it's B::OP,
 # nonexistent if it's not supported
 
-if ( $balance > 0 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eventually per-pkg or something really fancy
+if ( ($balance || 0) > 0 ) { #XXXFIXME "enable selfservice prepay features" flag or something, eventually per-pkg or something really fancy
 
   if ( exists( $payby_mode{CARD} ) ) {
     push @menu, { title  => 'Recharge my account with a credit card',
diff --git a/fs_selfservice/FS-SelfService/cgi/provision_list.html b/fs_selfservice/FS-SelfService/cgi/provision_list.html
index b558337..086c79e 100644
--- a/fs_selfservice/FS-SelfService/cgi/provision_list.html
+++ b/fs_selfservice/FS-SelfService/cgi/provision_list.html
@@ -96,7 +96,7 @@ foreach my $pkg (
             '('. $part_svc->{'num_avail'}. ' available)'.
             '</TD></TR>'
       #self-service only supports these services so far
-      if grep { $part_svc->{'svcdb'} eq $_ } qw( svc_acct svc_external );
+      if grep { $part_svc->{'svcdb'} eq $_ } qw( svc_acct svc_external svc_forward );
 
     $col = $col eq $col1 ? $col2 : $col1;
   }
diff --git a/fs_selfservice/FS-SelfService/cgi/provision_svc_forward.html b/fs_selfservice/FS-SelfService/cgi/provision_svc_forward.html
new file mode 100644
index 0000000..4700663
--- /dev/null
+++ b/fs_selfservice/FS-SelfService/cgi/provision_svc_forward.html
@@ -0,0 +1,29 @@
+<%= include('header', 'Setup forward') %>
+
+<FORM name="OneTrueForm" action="<%= $selfurl %>" METHOD="POST">
+<INPUT TYPE="hidden" NAME="action" VALUE="process_svc_forward">
+
+<%= '<P><B>' . $error . '</B></P>' if $error %>
+
+<%=
+my $out = mason_comp(
+  'session_id' => $session_id,
+  'comp'       => '/edit/elements/svc_forward.html',
+  'args'       => [
+    'svcnum'  => $svcnum,
+    'pkgnum'  => $pkgnum,
+    'svcpart' => $svcpart,
+    'srcsvc'  => $srcsvc,
+    'dstsvc'  => $dstsvc,
+    'src'     => $src,
+    'dst'     => $dst,
+    'email'   => \%forward_emails,
+  ]
+);
+$out->{'output'} || $out->{'error'};
+%>
+
+<INPUT TYPE="submit" VALUE="Setup">
+</FORM>
+
+<%= include('footer') %>
diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
index 8fec011..0e60791 100755
--- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
+++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
@@ -15,7 +15,7 @@ use FS::SelfService qw(
   access_info login_info login customer_info edit_info invoice
   payment_info process_payment realtime_collect process_prepay
   list_pkgs order_pkg signup_info order_recharge
-  part_svc_info provision_acct provision_external provision_phone
+  part_svc_info provision_acct provision_external provision_phone provision_forward
   unprovision_svc change_pkg suspend_pkg domainselector
   list_svcs list_svc_usage list_cdr_usage list_support_usage
   myaccount_passwd list_invoices create_ticket get_ticket did_report
@@ -70,6 +70,7 @@ my @actions = ( qw(
   process_svc_acct
   process_svc_phone
   process_svc_external
+  process_svc_forward
   delete_svc
   view_usage
   view_usage_details
@@ -861,7 +862,7 @@ sub provision_svc {
 
   my $result = part_svc_info(
     'session_id' => $session_id,
-    map { $_ => $cgi->param($_) } qw( pkgnum svcpart svcnum ),
+    map { $_ => ($cgi->param($_) || '') } qw( pkgnum svcpart svcnum ),
   );
   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
 
@@ -947,6 +948,33 @@ sub process_svc_external {
   );
 }
 
+sub process_svc_forward {
+
+  my $result = provision_forward (
+    'session_id' => $session_id,
+    map { $_ => $cgi->param($_) || '' } qw(
+      pkgnum svcpart srcsvc src dstsvc dst )
+  );
+
+  if ( exists $result->{'error'} && $result->{'error'} ) { 
+    #warn "$result $result->{'error'}"; 
+    $action = 'provision_svc_forward';
+    return {
+      $cgi->Vars,
+      %{ part_svc_info( 'session_id' => $session_id,
+                        map { $_ => $cgi->param($_) } qw( svcnum pkgnum svcpart )
+                      )
+      },
+      'error' => $result->{'error'},
+    };
+  } else {
+    #just go to setup services page, results will be visible there
+    $action = 'provision';
+    return provision();
+  }
+
+}
+
 sub delete_svc {
   unprovision_svc(
     'session_id' => $session_id,
@@ -1157,7 +1185,7 @@ package FS::SelfService::_selfservicecgi;
 
 use HTML::Entities;
 use FS::SelfService qw(
-    regionselector popselector domainselector location_form didselector
+    regionselector popselector domainselector location_form didselector mason_comp
 );
 
 #false laziness w/agent.cgi
diff --git a/httemplate/edit/elements/svc_forward.html b/httemplate/edit/elements/svc_forward.html
new file mode 100644
index 0000000..e40ebe8
--- /dev/null
+++ b/httemplate/edit/elements/svc_forward.html
@@ -0,0 +1,83 @@
+<INPUT TYPE="hidden" NAME="svcnum" VALUE="<% $opt{'svcnum'} %>">
+<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $opt{'pkgnum'} %>">
+<INPUT TYPE="hidden" NAME="svcpart" VALUE="<% $opt{'svcpart'} %>">
+
+<SCRIPT TYPE="text/javascript">
+function srcchanged(what) {
+  if ( what.options[what.selectedIndex].value == 0 ) {
+    what.form.src.disabled = false;
+    what.form.src.style.backgroundColor = "white";
+  } else {
+    what.form.src.disabled = true;
+    what.form.src.style.backgroundColor = "lightgrey";
+  }
+}
+function dstchanged(what) {
+  if ( what.options[what.selectedIndex].value == 0 ) {
+    what.form.dst.disabled = false;
+    what.form.dst.style.backgroundColor = "white";
+  } else {
+    what.form.dst.disabled = true;
+    what.form.dst.style.backgroundColor = "lightgrey";
+  }
+}
+</SCRIPT>
+
+<% ntable("#cccccc",2) %>
+
+<TR>
+  <TD ALIGN="right">Email to</TD>
+  <TD>
+%   if ( $conf->exists('svc_forward-no_srcsvc') ) {
+      <INPUT NAME="srcsrc" TYPE="hidden" VALUE="0">
+%   } else {
+      <SELECT NAME="srcsvc" SIZE=1 onChange="srcchanged(this)">
+%       foreach my $somesvc (keys %email) { 
+          <OPTION VALUE="<% $somesvc %>"
+                  <% $somesvc eq $opt{'srcsvc'} ? 'SELECTED' : '' %>
+          ><% $email{$somesvc} %></OPTION>
+%       } 
+        <OPTION VALUE="0" <% $opt{'src'} ? 'SELECTED' : '' %>
+        >(other email address)</OPTION>
+      </SELECT>
+%   }
+
+%   my $src_disabled =    $opt{'src'}
+%                      || $conf->exists('svc_forward-no_srcsvc')
+%                      || !scalar(%email);
+    <INPUT NAME  = "src"
+           TYPE  = "text"
+           VALUE = "<% $opt{'src'} %>"
+           <% $src_disabled ? '' : 'DISABLED STYLE="background-color: lightgrey"' %>
+    >
+
+  </TD>
+</TR>
+
+<TR><TD ALIGN="right">Forwards to</TD>
+<TD><SELECT NAME="dstsvc" SIZE=1 onChange="dstchanged(this)">
+% foreach my $somesvc (keys %email) { 
+
+  <OPTION<% $somesvc eq $opt{'dstsvc'} ? " SELECTED" : "" %> VALUE="<% $somesvc %>"><% $email{$somesvc} %></OPTION>
+% } 
+
+<OPTION <% $opt{'dst'} ? 'SELECTED' : '' %> VALUE="0">(other email address)</OPTION>
+</SELECT>
+<INPUT TYPE="text" NAME="dst" VALUE="<% $opt{'dst'} %>" <% ( $opt{'dst'} || !scalar(%email) ) ? '' : 'DISABLED STYLE="background-color: lightgrey"' %>>
+</TD></TR>
+</TABLE>
+
+<%init>
+
+# This is used directly by selfservice, only use what's passed
+# Do not look up sensitive information here
+
+my %opt = @_;
+
+my $conf = $opt{'conf'};
+$conf ||= new FS::Conf;
+
+my %email;
+%email = %{$opt{'email'}} if ref($opt{'email'}) eq 'HASH';
+
+</%init>
diff --git a/httemplate/edit/svc_forward.cgi b/httemplate/edit/svc_forward.cgi
index 73f6465..de56070 100755
--- a/httemplate/edit/svc_forward.cgi
+++ b/httemplate/edit/svc_forward.cgi
@@ -6,74 +6,19 @@ Service #<% $svcnum ? "<B>$svcnum</B>" : " (NEW)" %><BR>
 Service: <B><% $part_svc->svc %></B><BR><BR>
 
 <FORM ACTION="process/svc_forward.cgi" METHOD="POST">
-<INPUT TYPE="hidden" NAME="svcnum" VALUE="<% $svcnum %>">
-<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>">
-<INPUT TYPE="hidden" NAME="svcpart" VALUE="<% $svcpart %>">
-
-<SCRIPT TYPE="text/javascript">
-function srcchanged(what) {
-  if ( what.options[what.selectedIndex].value == 0 ) {
-    what.form.src.disabled = false;
-    what.form.src.style.backgroundColor = "white";
-  } else {
-    what.form.src.disabled = true;
-    what.form.src.style.backgroundColor = "lightgrey";
-  }
-}
-function dstchanged(what) {
-  if ( what.options[what.selectedIndex].value == 0 ) {
-    what.form.dst.disabled = false;
-    what.form.dst.style.backgroundColor = "white";
-  } else {
-    what.form.dst.disabled = true;
-    what.form.dst.style.backgroundColor = "lightgrey";
-  }
-}
-</SCRIPT>
-
-<% ntable("#cccccc",2) %>
-
-<TR>
-  <TD ALIGN="right">Email to</TD>
-  <TD>
-%   if ( $conf->exists('svc_forward-no_srcsvc') ) {
-      <INPUT NAME="srcsrc" TYPE="hidden" VALUE="0">
-%   } else {
-      <SELECT NAME="srcsvc" SIZE=1 onChange="srcchanged(this)">
-%       foreach $_ (keys %email) { 
-          <OPTION VALUE="<% $_ %>"
-                  <% $_ eq $srcsvc ? 'SELECTED' : '' %>
-          ><% $email{$_} %></OPTION>
-%       } 
-        <OPTION VALUE="0" <% $src ? 'SELECTED' : '' %>
-        >(other email address)</OPTION>
-      </SELECT>
-%   }
-
-%   my $src_disabled =    $src
-%                      || $conf->exists('svc_forward-no_srcsvc')
-%                      || !scalar(%email);
-    <INPUT NAME  = "src"
-           TYPE  = "text"
-           VALUE = "<% $src %>"
-           <% $src_disabled ? '' : 'DISABLED STYLE="background-color: lightgrey"' %>
-    >
-
-  </TD>
-</TR>
-
-<TR><TD ALIGN="right">Forwards to</TD>
-<TD><SELECT NAME="dstsvc" SIZE=1 onChange="dstchanged(this)">
-% foreach $_ (keys %email) { 
-
-  <OPTION<% $_ eq $dstsvc ? " SELECTED" : "" %> VALUE="<% $_ %>"><% $email{$_} %></OPTION>
-% } 
-
-<OPTION <% $dst ? 'SELECTED' : '' %> VALUE="0">(other email address)</OPTION>
-</SELECT>
-<INPUT TYPE="text" NAME="dst" VALUE="<% $dst %>" <% ( $dst || !scalar(%email) ) ? '' : 'DISABLED STYLE="background-color: lightgrey"' %>>
-</TD></TR>
-    </TABLE>
+
+<% include('elements/svc_forward.html',
+     'conf'    => $conf,
+     'svcnum'  => $svcnum,
+     'pkgnum'  => $pkgnum,
+     'svcpart' => $svcpart,
+     'srcsvc'  => $srcsvc,
+     'dstsvc'  => $dstsvc,
+     'src'     => $src,
+     'dst'     => $dst,
+     'email'   => \%email,
+   ) %>
+
 <BR><INPUT TYPE="submit" VALUE="Submit">
 </FORM>
 
@@ -136,44 +81,23 @@ my $action = $svc_forward->svcnum ? 'Edit' : 'Add';
 
 my %email;
 
-#starting with those currently attached
-foreach my $method (qw( srcsvc_acct dstsvc_acct )) {
-  my $svc_acct = $svc_forward->$method();
-  $email{$svc_acct->svcnum} = $svc_acct->email if $svc_acct;
-}
-
 if ($pkgnum) {
 
   #find all possible user svcnums (and emails)
 
-  #and including the rest for this customer
-  my($u_part_svc, at u_acct_svcparts);
-  foreach $u_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_acct'}) ) {
-    push @u_acct_svcparts,$u_part_svc->getfield('svcpart');
-  }
-
-  my($cust_pkg)=qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
-  my($custnum)=$cust_pkg->getfield('custnum');
-  my($i_cust_pkg);
-  foreach $i_cust_pkg ( qsearch('cust_pkg',{'custnum'=>$custnum}) ) {
-    my($cust_pkgnum)=$i_cust_pkg->getfield('pkgnum');
-    my($acct_svcpart);
-    foreach $acct_svcpart (@u_acct_svcparts) {   #now find the corresponding 
-                                              #record(s) in cust_svc ( for this
-                                              #pkgnum ! )
-      foreach my $i_cust_svc (
-        qsearch( 'cust_svc', { 'pkgnum'  => $cust_pkgnum,
-                               'svcpart' => $acct_svcpart } )
-      ) {
-        my $svc_acct =
-          qsearchs( 'svc_acct', { 'svcnum' => $i_cust_svc->svcnum } );
-        $email{$svc_acct->svcnum} = $svc_acct->email;
-      }  
-    }
-  }
+  my $cust_pkg = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum});
+  die "Specified package not found" unless $cust_pkg;
+  %email = $cust_pkg->forward_emails('svc_forward' => $svc_forward);
 
 } elsif ( $action eq 'Add' ) {
+
   die "\$action eq Add, but \$pkgnum is null!\n";
+
+} else {
+
+  use FS::cust_pkg;
+  %email = FS::cust_pkg->forward_emails('svc_forward' => $svc_forward);
+
 }
 
 my($srcsvc,$dstsvc,$dst)=(

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

Summary of changes:
 FS/FS/ClientAPI/MasonComponent.pm                  |    1 +
 FS/FS/ClientAPI/MyAccount.pm                       |   13 +++
 FS/FS/cust_pkg.pm                                  |   72 ++++++++++++
 fs_selfservice/FS-SelfService/SelfService.pm       |    1 +
 .../FS-SelfService/cgi/myaccount_menu.html         |    2 +-
 .../FS-SelfService/cgi/provision_list.html         |    2 +-
 .../FS-SelfService/cgi/provision_svc_forward.html  |   29 +++++
 fs_selfservice/FS-SelfService/cgi/selfservice.cgi  |   34 +++++-
 httemplate/edit/elements/svc_forward.html          |   83 +++++++++++++
 httemplate/edit/svc_forward.cgi                    |  122 ++++----------------
 10 files changed, 255 insertions(+), 104 deletions(-)
 create mode 100644 fs_selfservice/FS-SelfService/cgi/provision_svc_forward.html
 create mode 100644 httemplate/edit/elements/svc_forward.html




More information about the freeside-commits mailing list