From: jeff Date: Fri, 5 Jan 2007 05:19:35 +0000 (+0000) Subject: more self-servicey stuff (change package, detailed usage) X-Git-Tag: TRIXBOX_2_6~776 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=66bf9d2b3998894588d73a10a459aa1453283ef1 more self-servicey stuff (change package, detailed usage) --- diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index dc4ae7804..8b6a466be 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -24,6 +24,14 @@ use FS::cust_main_county; use FS::cust_pkg; use HTML::Entities; +#false laziness with FS::cust_main +BEGIN { + eval "use Time::Local;"; + die "Time::Local minimum version 1.05 required with Perl versions before 5.6" + if $] < 5.006 && !defined($Time::Local::VERSION); + eval "use Time::Local qw(timelocal_nocheck);"; +} + use vars qw( @cust_main_editable_fields ); @cust_main_editable_fields = qw( first last company address1 address2 city @@ -538,8 +546,6 @@ sub list_pkgs { sub list_svcs { my $p = shift; - use Data::Dumper; - my($context, $session, $custnum) = _custoragent_session_custnum($p); return { 'error' => $session } if $context eq 'error'; @@ -592,6 +598,85 @@ sub list_svcs { } +sub list_svc_usage { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $search = { 'svcnum' => $p->{'svcnum'} }; + $search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent'; + my $svc_acct = qsearchs ( 'svc_acct', $search ); + return { 'error' => 'No service selected in list_svc_usage' } + unless $svc_acct; + + my $freq = $svc_acct->cust_svc->cust_pkg->part_pkg->freq; + my $start = $svc_acct->cust_svc->cust_pkg->setup; + my $end = $svc_acct->cust_svc->cust_pkg->bill; # or time? + + unless($p->{beginning}){ + $p->{beginning} = $svc_acct->cust_svc->cust_pkg->last_bill; + $p->{ending} = $end; + } + my @usage = (); + + foreach my $part_export ( + map { qsearch ( 'part_export', { 'exporttype' => $_ } ) } + qw (sqlradius sqlradius_withdomain') + ) { + + push @usage, @ { $part_export->usage_sessions($p->{beginning}, + $p->{ending}, + $svc_acct) + }; + } + + #kinda false laziness with FS::cust_main::bill, but perhaps + #we should really change this bit to DateTime and DateTime::Duration + # + #change this bit to use Date::Manip? CAREFUL with timezones (see + # mailing list archive) + my ($nsec,$nmin,$nhour,$nmday,$nmon,$nyear) = + (localtime($p->{ending}) )[0,1,2,3,4,5]; + my ($psec,$pmin,$phour,$pmday,$pmon,$pyear) = + (localtime($p->{beginning}) )[0,1,2,3,4,5]; + + if ( $freq =~ /^\d+$/ ) { + $nmon += $freq; + until ( $nmon < 12 ) { $nmon -= 12; $nyear++; } + $pmon -= $freq; + until ( $pmon >= 0 ) { $pmon += 12; $pyear--; } + } elsif ( $freq =~ /^(\d+)w$/ ) { + my $weeks = $1; + $nmday += $weeks * 7; + $pmday -= $weeks * 7; + } elsif ( $freq =~ /^(\d+)d$/ ) { + my $days = $1; + $nmday += $days; + $pmday -= $days; + } elsif ( $freq =~ /^(\d+)h$/ ) { + my $hours = $1; + $nhour += $hours; + $phour -= $hours; + } else { + return { 'error' => "unparsable frequency: ". $freq }; + } + + my $previous = timelocal_nocheck($psec,$pmin,$phour,$pmday,$pmon,$pyear); + my $next = timelocal_nocheck($nsec,$nmin,$nhour,$nmday,$nmon,$nyear); + + + { + 'error' => '', + 'svcnum' => $p->{svcnum}, + 'beginning' => $p->{beginning}, + 'ending' => $p->{ending}, + 'previous' => ($previous > $start) ? $previous : $start, + 'next' => ($next < $end) ? $next : $end, + 'usage' => \@usage, + }; +} + sub order_pkg { my $p = shift; @@ -674,23 +759,11 @@ sub order_pkg { my $conf = new FS::Conf; if ( $conf->exists('signup_server-realtime') ) { - my $old_balance = $cust_main->balance; - - my $bill_error = $cust_main->bill; - $cust_main->apply_payments; - $cust_main->apply_credits; - $bill_error = $cust_main->collect('realtime' => 1); - - if ( $cust_main->balance > $old_balance - && $cust_main->balance > 0 - && $cust_main->payby !~ /^(BILL|DCRD|DCHK)$/ ) { - #this makes sense. credit is "un-doing" the invoice - $cust_main->credit( sprintf("%.2f", $cust_main->balance - $old_balance ), - 'self-service decline' ); - $cust_main->apply_credits( 'order' => 'newest' ); + my $bill_error = _do_bop_realtime( $cust_main ); + if ($bill_error) { $cust_pkg->cancel('quiet'=>1); - return { 'error' => '_decline', 'bill_error' => $bill_error }; + return $bill_error; } else { $cust_pkg->reexport; } @@ -703,6 +776,47 @@ sub order_pkg { } +sub change_pkg { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $search = { 'custnum' => $custnum }; + $search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent'; + my $cust_main = qsearchs('cust_main', $search ) + or return { 'error' => "unknown custnum $custnum" }; + + my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $p->{pkgnum} } ) + or return { 'error' => "unknown package $p->{pkgnum}" }; + + my @newpkg; + my $error = FS::cust_pkg::order( $custnum, + [$p->{pkgpart}], + [$p->{pkgnum}], + \@newpkg, + ); + + my $conf = new FS::Conf; + if ( $conf->exists('signup_server-realtime') ) { + + my $bill_error = _do_bop_realtime( $cust_main ); + + if ($bill_error) { + $newpkg[0]->suspend; + return $bill_error; + } else { + $newpkg[0]->reexport; + } + + } else { + $newpkg[0]->reexport; + } + + return { error => '', pkgnum => $cust_pkg->pkgnum }; + +} + sub order_recharge { my $p = shift; @@ -726,8 +840,6 @@ sub order_recharge { recharge_totalbytes ); my $amount = $part_pkg->option('recharge_amount', 1); - my $old_balance = $cust_main->balance; - my ($l, $v, $d) = $cust_svc->label; # blah my $pkg = "Recharge $v"; @@ -739,13 +851,36 @@ sub order_recharge { my $conf = new FS::Conf; if ( $conf->exists('signup_server-realtime') && !$bill_error ) { - $bill_error = $cust_main->bill; + $bill_error = _do_bop_realtime( $cust_main ); + + if ('bill_error') { + return $bill_error; + } else { + my $error = $svc_x->recharge (\%vhash); + return { 'error' => $error } if $error; + } + + } else { + my $error = $bill_error; + $error ||= $svc_x->recharge (\%vhash); + return { 'error' => $error } if $error; + } + + return { error => '', svc => $cust_svc->part_svc->svc }; + +} + +sub _do_bop_realtime { + my ($cust_main) = @_; + + my $old_balance = $cust_main->balance; + + my $bill_error = $cust_main->bill; $cust_main->apply_payments; $cust_main->apply_credits; $bill_error = $cust_main->collect('realtime' => 1); - #false laziness with order_pkg if ( $cust_main->balance > $old_balance && $cust_main->balance > 0 && $cust_main->payby !~ /^(BILL|DCRD|DCHK)$/ ) { @@ -754,20 +889,10 @@ sub order_recharge { 'self-service decline' ); $cust_main->apply_credits( 'order' => 'newest' ); - return { 'error' => '_decline', 'bill_error' => encode_entities($bill_error) }; - } else { - my $error = $svc_x->recharge (\%vhash); - return { 'error' => $error } if $error; + return { 'error' => '_decline', 'bill_error' => $bill_error }; } - } else { - my $error = $bill_error; - $error ||= $svc_x->recharge (\%vhash); - return { 'error' => $error } if $error; - } - - return { error => '', svc => $cust_svc->part_svc->svc }; - + ''; } sub cancel_pkg { diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm index 980c899c5..fe17fae5d 100644 --- a/fs_selfservice/FS-SelfService/SelfService.pm +++ b/fs_selfservice/FS-SelfService/SelfService.pm @@ -37,7 +37,9 @@ $socket .= '.'.$tag if defined $tag && length($tag); 'process_prepay' => 'MyAccount/process_prepay', 'list_pkgs' => 'MyAccount/list_pkgs', #add to ss cgi (added?) 'list_svcs' => 'MyAccount/list_svcs', #add to ss cgi (added?) + 'list_svc_usage' => 'MyAccount/list_svc_usage', 'order_pkg' => 'MyAccount/order_pkg', #add to ss cgi! + 'change_pkg' => 'MyAccount/change_pkg', 'order_recharge' => 'MyAccount/order_recharge', 'cancel_pkg' => 'MyAccount/cancel_pkg', #add to ss cgi! 'charge' => 'MyAccount/charge', #? diff --git a/fs_selfservice/FS-SelfService/cgi/change_pkg.html b/fs_selfservice/FS-SelfService/cgi/change_pkg.html new file mode 100644 index 000000000..a841308a5 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/change_pkg.html @@ -0,0 +1,37 @@ + +Purchase replacement package for "<%= $pkg; %>"

+<%= if ( $error ) { + $OUT .= qq!$error

!; +} ''; %> +
+ + + + + + + + +
+ +
+ diff --git a/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html b/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html new file mode 100644 index 000000000..d08ab9679 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/customer_change_pkg.html @@ -0,0 +1,10 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('myaccount_menu') %> + +<%= include('change_pkg') %> + +
+powered by freeside + diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html b/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html new file mode 100644 index 000000000..9347434ba --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/process_change_pkg.html @@ -0,0 +1,13 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('myaccount_menu') %> + + +Package change successful. + + +
+powered by freeside + + diff --git a/fs_selfservice/FS-SelfService/cgi/provision_list.html b/fs_selfservice/FS-SelfService/cgi/provision_list.html index cd587f072..88d1c848b 100644 --- a/fs_selfservice/FS-SelfService/cgi/provision_list.html +++ b/fs_selfservice/FS-SelfService/cgi/provision_list.html @@ -16,9 +16,11 @@ function areyousure(href, message) { ) { $OUT .= #''. - ''; + ''; my $col1 = "ffffff"; my $col2 = "dddddd"; diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi index e2fd7f6a4..1fc2e5f8b 100644 --- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi +++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi @@ -7,13 +7,14 @@ use CGI; use CGI::Carp qw(fatalsToBrowser); use Text::Template; use HTML::Entities; +use Date::Format; use FS::SelfService qw( login customer_info invoice payment_info process_payment process_prepay list_pkgs order_pkg signup_info order_recharge part_svc_info provision_acct provision_external - unprovision_svc - list_svcs myaccount_passwd + unprovision_svc change_pkg + list_svcs list_svc_usage myaccount_passwd ); $template_dir = '.'; @@ -65,7 +66,7 @@ $session_id = $cgi->param('session'); #order|pw_list XXX ??? $cgi->param('action') =~ - /^(myaccount|view_invoice|make_payment|payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|customer_order_pkg|process_order_pkg|process_order_recharge|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|view_usage||change_password|process_change_password)$/ + /^(myaccount|view_invoice|make_payment|payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|customer_order_pkg|process_order_pkg|customer_change_pkg|process_change_pkg|process_order_recharge|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|view_usage|view_usage_details|change_password|process_change_password)$/ or die "unknown action ". $cgi->param('action'); my $action = $1; @@ -123,6 +124,24 @@ sub customer_order_pkg { }; } +sub customer_change_pkg { + my $init_data = signup_info( 'customer_session_id' => $session_id ); + return $init_data if ( $init_data->{'error'} ); + + my $customer_info = customer_info( 'session_id' => $session_id ); + return $customer_info if ( $customer_info->{'error'} ); + + return { + ( map { $_ => $init_data->{$_} } + qw( part_pkg security_phrase svc_acct_pop ), + ), + ( map { $_ => $cgi->param($_) } + qw( pkgnum pkg ) + ), + %$customer_info, + }; +} + sub process_order_pkg { my $results = ''; @@ -160,6 +179,30 @@ sub process_order_pkg { } +sub process_change_pkg { + + my $results = ''; + + $results ||= change_pkg ( + 'session_id' => $session_id, + map { $_ => $cgi->param($_) } + qw( pkgpart pkgnum ) + ); + + + if ( $results->{'error'} ) { + $action = 'customer_change_pkg'; + return { + $cgi->Vars, + %{customer_change_pkg()}, + 'error' => ''. $results->{'error'}. '', + }; + } else { + return $results; + } + +} + sub process_order_recharge { my $results = ''; @@ -356,6 +399,15 @@ sub view_usage { ); } +sub view_usage_details { + list_svc_usage( + 'session_id' => $session_id, + 'svcnum' => $cgi->param('svcnum'), + 'beginning' => $cgi->param('beginning') || '', + 'ending' => $cgi->param('ending') || '', + ); +} + sub change_password { list_svcs( 'session_id' => $session_id, diff --git a/fs_selfservice/FS-SelfService/cgi/view_usage.html b/fs_selfservice/FS-SelfService/cgi/view_usage.html index 73ad1e4af..79d07d4df 100644 --- a/fs_selfservice/FS-SelfService/cgi/view_usage.html +++ b/fs_selfservice/FS-SelfService/cgi/view_usage.html @@ -19,8 +19,10 @@ <%= foreach my $svc ( @svcs ) { + my $link = "${url}view_usage_details;". + "svcnum=$svc->{'svcnum'};beginning=0;ending=0"; $OUT .= '
'. - $pkg->{'pkg'}. - '
'. + $pkg->{'pkg'}. '' . + qq!(! . + 'change)
Total remaining
'; - $OUT .= $svc->{'label'}. ': '. $svc->{'value'}; + $OUT .= qq!!. $svc->{'label'}. ': '. $svc->{'value'}.''; $OUT .= ''; $OUT .= $svc->{'seconds'}; $OUT .= ''; diff --git a/fs_selfservice/FS-SelfService/cgi/view_usage_details.html b/fs_selfservice/FS-SelfService/cgi/view_usage_details.html new file mode 100644 index 000000000..9067755b0 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/view_usage_details.html @@ -0,0 +1,66 @@ +MyAccount +MyAccount

+<%= $url = "$selfurl?session=$session_id;action="; ''; %> +<%= include('myaccount_menu') %> +
+ +Service usage details

+ +<%= if ( $error ) { + $OUT .= qq!$error

!; +} ''; %> + + + + + + +
+<%= if ($previous < $beginning) { + $OUT .= qq!Previous period!; + }else{ + ''; + } %> + +<%= if ($next > $ending) { + $OUT .= qq!Next period!; + }else{ + ''; + }%> +
+ + + + + + +<%= my $total = 0; + foreach my $usage ( @usage ) { + $OUT .= ''; + } + my $h = int($total/3600); + my $m = sprintf("%02d", int(($total % 3600) / 60)); + my $s = sprintf("%02d", $total % 60); + $OUT .= qq!!; + $OUT .= qq!!; %> + +
AccountStart TimeDuration
'; + $OUT .= $usage->{'username'}; + $OUT .= ''; + $OUT .= Date::Format::time2str('%T%P %a %b %o %Y', $usage->{'acctstarttime'}); + $OUT .= ''; + my $duration = $usage->{'acctstoptime'} - $usage->{'acctstarttime'}; + $total += $duration; + my $h = int($duration/3600); + my $m = sprintf("%02d", int(($duration % 3600) / 60)); + my $s = sprintf("%02d", $duration % 60); + $OUT .= "$h:$m:$s"; + $OUT .= '
========
$h:$m:$s
+
+ +
+
+powered by freeside +