diff options
author | Jonathan Prykop <jonathan@freeside.biz> | 2015-05-29 23:05:00 -0500 |
---|---|---|
committer | Jonathan Prykop <jonathan@freeside.biz> | 2015-05-29 23:05:00 -0500 |
commit | 3846acae1c2a7ecb275e400cf3802ada6bc89ed2 (patch) | |
tree | c576ed2f5e3b2eb58ff64ac55721706186d25ed7 | |
parent | d0ba32be1771276ed7f54c987c0e23cf496108bd (diff) |
RT#25929: Customer self-service forward editing
-rw-r--r-- | FS/FS/ClientAPI/MasonComponent.pm | 1 | ||||
-rw-r--r-- | FS/FS/ClientAPI/MyAccount.pm | 13 | ||||
-rw-r--r-- | FS/FS/cust_pkg.pm | 72 | ||||
-rw-r--r-- | fs_selfservice/FS-SelfService/SelfService.pm | 1 | ||||
-rw-r--r-- | fs_selfservice/FS-SelfService/cgi/myaccount_menu.html | 2 | ||||
-rw-r--r-- | fs_selfservice/FS-SelfService/cgi/provision_list.html | 2 | ||||
-rw-r--r-- | fs_selfservice/FS-SelfService/cgi/provision_svc_forward.html | 29 | ||||
-rwxr-xr-x | fs_selfservice/FS-SelfService/cgi/selfservice.cgi | 34 | ||||
-rw-r--r-- | httemplate/edit/elements/svc_forward.html | 83 | ||||
-rwxr-xr-x | httemplate/edit/svc_forward.cgi | 122 |
10 files changed, 255 insertions, 104 deletions
diff --git a/FS/FS/ClientAPI/MasonComponent.pm b/FS/FS/ClientAPI/MasonComponent.pm index b6f8aa4c6..50597e2cb 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 dfa90e2f2..c57584e6e 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 5859727b1..3800e9469 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,@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 acf655b8c..847222d72 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 4802178d0..999c62da0 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 b558337de..086c79e57 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 000000000..470066323 --- /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 8fec01121..0e60791ba 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 000000000..e40ebe807 --- /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 73f6465b9..de56070ec 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,@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)=( |