X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FClientAPI%2FMyAccount.pm;h=2d39510065006725aa31712bc0adcd3bdc6d01ba;hb=c0fdb0884f3e5fb72e83e0b65d52b5a593bd670a;hp=4d24a52634bc810b07c91d9a2a00cde4195eb09c;hpb=67080890d17639954dac3131fe11f49717ef303d;p=freeside.git diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 4d24a5263..2d3951006 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -24,6 +24,7 @@ use FS::cust_bill; use FS::cust_main_county; use FS::cust_pkg; use FS::payby; +use FS::acct_rt_transaction; use HTML::Entities; #false laziness with FS::cust_main @@ -41,6 +42,7 @@ use vars qw( @cust_main_editable_fields ); ship_first ship_last ship_company ship_address1 ship_address2 ship_city ship_state ship_zip ship_country ship_daytime ship_night ship_fax payby payinfo payname paystart_month paystart_year payissue payip + ss paytype paystate stateid stateid_state ); use subs qw(_provision); @@ -87,7 +89,8 @@ sub login { $session_id = md5_hex(md5_hex(time(). {}. rand(). $$)) } until ( ! defined _cache->get($session_id) ); #just in case - _cache->set( $session_id, $session, '1 hour' ); + my $timeout = $conf->config('selfservice-session_timeout') || '1 hour'; + _cache->set( $session_id, $session, $timeout ); return { 'error' => '', 'session_id' => $session_id, @@ -111,6 +114,14 @@ sub customer_info { return { 'error' => $session } if $context eq 'error'; my %return; + + my $conf = new FS::Conf; + if ($conf->exists('cust_main-require_address2')) { + $return{'require_address2'} = '1'; + }else{ + $return{'require_address2'} = ''; + } + if ( $custnum ) { #customer record my $search = { 'custnum' => $custnum }; @@ -131,7 +142,6 @@ sub customer_info { } $cust_main->open_cust_bill; $return{open_invoices} = \@open; - my $conf = new FS::Conf; $return{small_custview} = small_custview( $cust_main, $conf->config('countrydefault') ); @@ -152,11 +162,24 @@ sub customer_info { 0 < ( grep { $_ eq 'POST' } $cust_main->invoicing_list ); if (scalar($conf->config('support_packages'))) { - my $support = 0; + my @support_services = (); foreach ($cust_main->support_services) { - $support += $_->svc_x->seconds; + my $seconds = $_->svc_x->seconds; + my $time_remaining = (($seconds < 0) ? '-' : '' ). + int(abs($seconds)/3600)."h". + sprintf("%02d",(abs($seconds)%3600)/60)."m"; + my $cust_pkg = $_->cust_pkg; + my $pkgnum = ''; + my $pkg = ''; + $pkgnum = $cust_pkg->pkgnum if $cust_pkg; + $pkg = $cust_pkg->part_pkg->pkg if $cust_pkg; + push @support_services, { svcnum => $_->svcnum, + time => $time_remaining, + pkgnum => $pkgnum, + pkg => $pkg, + }; } - $return{support_time} = (($support < 0) ? '-' : '' ). int(abs($support)/3600)."h".sprintf("%02d",(abs($support)%3600)/60)."m"; + $return{support_services} = \@support_services; } } elsif ( $session->{'svcnum'} ) { #no customer record @@ -193,13 +216,46 @@ sub edit_info { $new->set( $_ => $p->{$_} ) foreach grep { exists $p->{$_} } @cust_main_editable_fields; - if ( $p->{'payby'} =~ /^(CARD|DCRD)$/ ) { + my $payby = ''; + if (exists($p->{'payby'})) { + $p->{'payby'} =~ /^([A-Z]{4})$/ + or return { 'error' => "illegal_payby " . $p->{'payby'} }; + $payby = $1; + } + + if ( $payby =~ /^(CARD|DCRD)$/ ) { + $new->paydate($p->{'year'}. '-'. $p->{'month'}. '-01'); + if ( $new->payinfo eq $cust_main->paymask ) { $new->payinfo($cust_main->payinfo); } else { - $new->paycvv($p->{'paycvv'}); + $new->payinfo($p->{'payinfo'}); } + + $new->set( 'payby' => $p->{'auto'} ? 'CARD' : 'DCRD' ); + + }elsif ( $payby =~ /^(CHEK|DCHK)$/ ) { + my $payinfo; + $p->{'payinfo1'} =~ /^([\dx]+)$/ + or return { 'error' => "illegal account number ". $p->{'payinfo1'} }; + my $payinfo1 = $1; + $p->{'payinfo2'} =~ /^([\dx]+)$/ + or return { 'error' => "illegal ABA/routing number ". $p->{'payinfo2'} }; + my $payinfo2 = $1; + $payinfo = $payinfo1. '@'. $payinfo2; + + if ( $payinfo eq $cust_main->paymask ) { + $new->payinfo($cust_main->payinfo); + } else { + $new->payinfo($payinfo); + } + + $new->set( 'payby' => $p->{'auto'} ? 'CHEK' : 'DCHK' ); + + }elsif ( $payby =~ /^(BILL)$/ ) { + } elsif ( $payby ) { #notyet ready + return { 'error' => "unknown payby $payby" }; } my @invoicing_list; @@ -250,6 +306,8 @@ sub payment_info { 'paytypes' => [ @FS::cust_main::paytypes ], + 'paybys' => [ $conf->config('signup_server-payby') ], + 'stateid_label' => FS::Msgcat::_gettext('stateid'), 'stateid_state_label' => FS::Msgcat::_gettext('stateid_state'), @@ -283,14 +341,14 @@ sub payment_info { if ( $cust_main->payby =~ /^(CARD|DCRD)$/ ) { $return{card_type} = cardtype($cust_main->payinfo); - $return{payinfo} = $cust_main->payinfo; + $return{payinfo} = $cust_main->paymask; @return{'month', 'year'} = $cust_main->paydate_monthyear; } if ( $cust_main->payby =~ /^(CHEK|DCHK)$/ ) { - my ($payinfo1, $payinfo2) = split '@', $cust_main->payinfo; + my ($payinfo1, $payinfo2) = split '@', $cust_main->paymask; $return{payinfo1} = $payinfo1; $return{payinfo2} = $payinfo2; $return{paytype} = $cust_main->paytype; @@ -340,21 +398,28 @@ sub process_payment { my $paycvv = ''; if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) { - $p->{'payinfo1'} =~ /^(\d+)$/ + $p->{'payinfo1'} =~ /^([\dx]+)$/ or return { 'error' => "illegal account number ". $p->{'payinfo1'} }; my $payinfo1 = $1; - $p->{'payinfo2'} =~ /^(\d+)$/ + $p->{'payinfo2'} =~ /^([\dx]+)$/ or return { 'error' => "illegal ABA/routing number ". $p->{'payinfo2'} }; my $payinfo2 = $1; $payinfo = $payinfo1. '@'. $payinfo2; + + $payinfo = $cust_main->payinfo + if $cust_main->paymask eq $payinfo; } elsif ( $payby eq 'CARD' || $payby eq 'DCRD' ) { $payinfo = $p->{'payinfo'}; - $payinfo =~ s/\D//g; + $payinfo =~ s/[^\dx]//g; $payinfo =~ /^(\d{13,16})$/ or return { 'error' => gettext('invalid_card') }; # . ": ". $self->payinfo $payinfo = $1; + + $payinfo = $cust_main->payinfo + if $cust_main->paymask eq $payinfo; + validate($payinfo) or return { 'error' => gettext('invalid_card') }; # . ": ". $self->payinfo return { 'error' => gettext('unknown_card_type') } @@ -418,6 +483,15 @@ sub process_payment { } +sub process_payment_order_pkg { + my $p = shift; + + my $hr = process_payment($p); + return $hr if $hr->{'error'}; + + order_pkg($p); +} + sub process_prepay { my $p = shift; @@ -642,8 +716,48 @@ sub list_svcs { } +sub _list_svc_usage { + my($svc_acct, $begin, $end) = @_; + my @usage = (); + foreach my $part_export ( + map { qsearch ( 'part_export', { 'exporttype' => $_ } ) } + qw (sqlradius sqlradius_withdomain') + ) { + + push @usage, @ { $part_export->usage_sessions($begin, $end, $svc_acct) }; + } + (@usage); +} + sub list_svc_usage { - my $p = shift; + _usage_details(\&_list_svc_usage, @_); +} + +sub _list_support_usage { + my($svc_acct, $begin, $end) = @_; + my @usage = (); + foreach ( grep { $begin <= $_->_date && $_->_date <= $end } + qsearch('acct_rt_transaction', { 'svcnum' => $svc_acct->svcnum }) + ) { + push @usage, { 'seconds' => $_->seconds, + 'support' => $_->support, + '_date' => $_->_date, + 'id' => $_->transaction_id, + 'creator' => $_->creator, + 'subject' => $_->subject, + 'status' => $_->status, + 'ticketid' => $_->ticketid, + }; + } + (@usage); +} + +sub list_support_usage { + _usage_details(\&_list_support_usage, @_); +} + +sub _usage_details { + my ($callback, $p) = (shift,shift); my($context, $session, $custnum) = _custoragent_session_custnum($p); return { 'error' => $session } if $context eq 'error'; @@ -663,18 +777,8 @@ sub list_svc_usage { $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) - }; - } + my (@usage) = &$callback($svc_acct,$p->{beginning},$p->{ending}); #kinda false laziness with FS::cust_main::bill, but perhaps #we should really change this bit to DateTime and DateTime::Duration @@ -710,7 +814,6 @@ sub list_svc_usage { my $previous = timelocal_nocheck($psec,$pmin,$phour,$pmday,$pmon,$pyear); my $next = timelocal_nocheck($nsec,$nmin,$nhour,$nmday,$nmon,$nyear); - { 'error' => '', 'svcnum' => $p->{svcnum}, @@ -733,6 +836,7 @@ sub order_pkg { my $cust_main = qsearchs('cust_main', $search ) or return { 'error' => "unknown custnum $custnum" }; + my $status = $cust_main->status; #false laziness w/ClientAPI/Signup.pm my $cust_pkg = new FS::cust_pkg ( { @@ -804,7 +908,7 @@ sub order_pkg { my $conf = new FS::Conf; if ( $conf->exists('signup_server-realtime') ) { - my $bill_error = _do_bop_realtime( $cust_main ); + my $bill_error = _do_bop_realtime( $cust_main, $status ); if ($bill_error) { $cust_pkg->cancel('quiet'=>1); @@ -832,6 +936,7 @@ sub change_pkg { my $cust_main = qsearchs('cust_main', $search ) or return { 'error' => "unknown custnum $custnum" }; + my $status = $cust_main->status; my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $p->{pkgnum} } ) or return { 'error' => "unknown package $p->{pkgnum}" }; @@ -845,7 +950,7 @@ sub change_pkg { my $conf = new FS::Conf; if ( $conf->exists('signup_server-realtime') ) { - my $bill_error = _do_bop_realtime( $cust_main ); + my $bill_error = _do_bop_realtime( $cust_main, $status ); if ($bill_error) { $newpkg[0]->suspend; @@ -873,6 +978,7 @@ sub order_recharge { my $cust_main = qsearchs('cust_main', $search ) or return { 'error' => "unknown custnum $custnum" }; + my $status = $cust_main->status; my $cust_svc = qsearchs( 'cust_svc', { 'svcnum' => $p->{'svcnum'} } ) or return { 'error' => "unknown service " . $p->{'svcnum'} }; @@ -896,7 +1002,7 @@ sub order_recharge { my $conf = new FS::Conf; if ( $conf->exists('signup_server-realtime') && !$bill_error ) { - $bill_error = _do_bop_realtime( $cust_main ); + $bill_error = _do_bop_realtime( $cust_main, $status ); if ($bill_error) { return $bill_error; @@ -916,7 +1022,7 @@ sub order_recharge { } sub _do_bop_realtime { - my ($cust_main) = @_; + my ($cust_main, $status) = (shift, shift); my $old_balance = $cust_main->balance; @@ -926,10 +1032,14 @@ sub _do_bop_realtime { if ( $cust_main->balance > $old_balance && $cust_main->balance > 0 - && $cust_main->payby !~ /^(BILL|DCRD|DCHK)$/ ) { + && ( $cust_main->payby !~ /^(BILL|DCRD|DCHK)$/ ? + 1 : $status eq 'suspended' ) ) { #this makes sense. credit is "un-doing" the invoice + my $conf = new FS::Conf; $cust_main->credit( sprintf("%.2f", $cust_main->balance - $old_balance ), - 'self-service decline' ); + 'self-service decline', + 'reason_type' => $conf->config('signup_credit_type'), + ); $cust_main->apply_credits( 'order' => 'newest' ); return { 'error' => '_decline', 'bill_error' => $bill_error }; @@ -966,10 +1076,17 @@ sub provision_acct { if $p->{'_password'} ne $p->{'_password2'}; return { 'error' => gettext('empty_password') } unless length($p->{'_password'}); + + if ($p->{'domsvc'}) { + my %domains = domain_select_hash FS::svc_acct(map { $_ => $p->{$_} } + qw ( svcpart pkgnum ) ); + return { 'error' => gettext('invalid_domain') } + unless ($domains{$p->{'domsvc'}}); + } _provision( 'FS::svc_acct', - [qw(username _password)], - [qw(username _password)], + [qw(username _password domsvc)], + [qw(username _password domsvc)], $p, @_ );