X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FClientAPI%2FMyAccount.pm;h=213f6b45b64c9708f18f1f8fa819c244625b6820;hb=3034abf97db1bcabb0fc81e565f3f6cccd9de827;hp=2d39510065006725aa31712bc0adcd3bdc6d01ba;hpb=5e05724a635a22776f1b973f5d7e77989da4e048;p=freeside.git diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 2d3951006..213f6b45b 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -1,13 +1,14 @@ package FS::ClientAPI::MyAccount; use strict; -use vars qw($cache); -use subs qw(_cache); +use vars qw( $cache $DEBUG ); +use subs qw( _cache _provision ); +use Data::Dumper; use Digest::MD5 qw(md5_hex); use Date::Format; use Business::CreditCard; use Time::Duration; -use FS::CGI qw(small_custview); #doh +use FS::UI::Web::small_custview qw(small_custview); #less doh use FS::UI::Web; use FS::UI::bytecount; use FS::Conf; @@ -17,6 +18,7 @@ use FS::Misc qw(card_types); use FS::ClientAPI_SessionCache; use FS::svc_acct; use FS::svc_domain; +use FS::svc_phone; use FS::svc_external; use FS::part_svc; use FS::cust_main; @@ -27,6 +29,8 @@ use FS::payby; use FS::acct_rt_transaction; use HTML::Entities; +$DEBUG = 0; + #false laziness with FS::cust_main BEGIN { eval "use Time::Local;"; @@ -45,40 +49,82 @@ use vars qw( @cust_main_editable_fields ); ss paytype paystate stateid stateid_state ); -use subs qw(_provision); - sub _cache { $cache ||= new FS::ClientAPI_SessionCache( { 'namespace' => 'FS::ClientAPI::MyAccount', } ); } +sub login_info { + my $p = shift; + + my $conf = new FS::Conf; + + my %info = ( + 'phone_login' => $conf->exists('selfservice_server-phone_login'), + 'single_domain'=> scalar($conf->config('selfservice_server-single_domain')), + ); + + return \%info; + +} + #false laziness w/FS::ClientAPI::passwd::passwd sub login { my $p = shift; - my $svc_domain = qsearchs('svc_domain', { 'domain' => $p->{'domain'} } ) - or return { error => 'Domain '. $p->{'domain'}. ' not found' }; + my $conf = new FS::Conf; - my $svc_acct = qsearchs( 'svc_acct', { 'username' => $p->{'username'}, - 'domsvc' => $svc_domain->svcnum, } - ); - return { error => 'User not found.' } unless $svc_acct; + my $svc_x = ''; + if ( $p->{'domain'} eq 'svc_phone' + && $conf->exists('selfservice_server-phone_login') ) { - my $conf = new FS::Conf; - my $pkg_svc = $svc_acct->cust_svc->pkg_svc; - return { error => 'Only primary user may log in.' } - if $conf->exists('selfservice_server-primary_only') - && ( ! $pkg_svc || $pkg_svc->primary_svc ne 'Y' ); + my $svc_phone = qsearchs( 'svc_phone', { 'phonenum' => $p->{'username'} } ); + return { error => 'Number not found.' } unless $svc_phone; + + #XXX? + #my $pkg_svc = $svc_acct->cust_svc->pkg_svc; + #return { error => 'Only primary user may log in.' } + # if $conf->exists('selfservice_server-primary_only') + # && ( ! $pkg_svc || $pkg_svc->primary_svc ne 'Y' ); + + return { error => 'Incorrect PIN.' } + unless $svc_phone->check_pin($p->{'password'}); + + $svc_x = $svc_phone; + + } else { - return { error => 'Incorrect password.' } - unless $svc_acct->check_password($p->{'password'}); + my $svc_domain = qsearchs('svc_domain', { 'domain' => $p->{'domain'} } ) + or return { error => 'Domain '. $p->{'domain'}. ' not found' }; + + my $svc_acct = qsearchs( 'svc_acct', { 'username' => $p->{'username'}, + 'domsvc' => $svc_domain->svcnum, } + ); + return { error => 'User not found.' } unless $svc_acct; + + #my $pkg_svc = $svc_acct->cust_svc->pkg_svc; + #return { error => 'Only primary user may log in.' } + # if $conf->exists('selfservice_server-primary_only') + # && ( ! $pkg_svc || $pkg_svc->primary_svc ne 'Y' ); + my $cust_svc = $svc_acct->cust_svc; + my $part_pkg = $cust_svc->cust_pkg->part_pkg; + return { error => 'Only primary user may log in.' } + if $conf->exists('selfservice_server-primary_only') + && $cust_svc->svcpart != $part_pkg->svcpart('svc_acct'); + + return { error => 'Incorrect password.' } + unless $svc_acct->check_password($p->{'password'}); + + $svc_x = $svc_acct; + + } my $session = { - 'svcnum' => $svc_acct->svcnum, + 'svcnum' => $svc_x->svcnum, }; - my $cust_pkg = $svc_acct->cust_svc->cust_pkg; + my $cust_pkg = $svc_x->cust_svc->cust_pkg; if ( $cust_pkg ) { my $cust_main = $cust_pkg->cust_main; $session->{'custnum'} = $cust_main->custnum; @@ -394,6 +440,7 @@ sub process_payment { or return { 'error' => "illegal_payby " . $p->{'payby'} }; my $payby = $1; + #false laziness w/process/payment.cgi my $payinfo; my $paycvv = ''; if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) { @@ -412,14 +459,15 @@ sub process_payment { } elsif ( $payby eq 'CARD' || $payby eq 'DCRD' ) { $payinfo = $p->{'payinfo'}; - $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; + $payinfo =~ s/\D//g; + $payinfo =~ /^(\d{13,16})$/ + or return { 'error' => gettext('invalid_card') }; # . ": ". $self->payinfo + $payinfo = $1; + validate($payinfo) or return { 'error' => gettext('invalid_card') }; # . ": ". $self->payinfo return { 'error' => gettext('unknown_card_type') } @@ -492,6 +540,15 @@ sub process_payment_order_pkg { order_pkg($p); } +sub process_payment_order_renew { + my $p = shift; + + my $hr = process_payment($p); + return $hr if $hr->{'error'}; + + order_renew($p); +} + sub process_prepay { my $p = shift; @@ -549,7 +606,7 @@ sub invoice { return { 'error' => '', 'invnum' => $invnum, 'invoice_text' => join('', $cust_bill->print_text ), - 'invoice_html' => $cust_bill->print_html, + 'invoice_html' => $cust_bill->print_html( { unsquelch_cdr => 1 } ), }; } @@ -1048,6 +1105,64 @@ sub _do_bop_realtime { ''; } +sub renew_info { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) + or return { 'error' => "unknown custnum $custnum" }; + + my @cust_pkg = sort { $a->bill <=> $b->bill } + grep { $_->part_pkg->freq ne '0' } + $cust_main->ncancelled_pkgs; + + #return { 'error' => 'No active packages to renew.' } unless @cust_pkg; + + my $total = 0; + + my @array = map { + $total += $_->part_pkg->base_recur; + my $renew_date = $_->part_pkg->add_freq($_->bill); + { + 'bill_date' => $_->bill, + 'bill_date_pretty' => time2str('%x', $_->bill), + 'renew_date' => $renew_date, + 'renew_date_pretty' => time2str('%x', $renew_date), + 'amount' => sprintf('%.2f', $total), + }; + } + @cust_pkg; + + return { 'dates' => \@array }; + +} + +sub order_renew { + my $p = shift; + + my($context, $session, $custnum) = _custoragent_session_custnum($p); + return { 'error' => $session } if $context eq 'error'; + + my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) + or return { 'error' => "unknown custnum $custnum" }; + + my $date = $p->{'date'}; + + my $now = time; + + #freeside-daily -n -d $date fs_daily $custnum + $cust_main->bill_and_collect( 'time' => $date, + 'invoice_time' => $now, + 'actual_time' => $now, + 'check_freq' => '1d', + ); + + return { 'error' => '' }; + +} + sub cancel_pkg { my $p = shift; my $session = _cache->get($p->{'session_id'}) @@ -1071,6 +1186,8 @@ sub cancel_pkg { sub provision_acct { my $p = shift; + warn "provision_acct called\n" + if $DEBUG; return { 'error' => gettext('passwords_dont_match') } if $p->{'_password'} ne $p->{'_password2'}; @@ -1084,6 +1201,8 @@ sub provision_acct { unless ($domains{$p->{'domsvc'}}); } + warn "provision_acct calling _provision\n" + if $DEBUG; _provision( 'FS::svc_acct', [qw(username _password domsvc)], [qw(username _password domsvc)], @@ -1105,6 +1224,8 @@ sub provision_external { sub _provision { my( $class, $fields, $return_fields, $p ) = splice(@_, 0, 4); + warn "_provision called for $class\n" + if $DEBUG; my($context, $session, $custnum) = _custoragent_session_custnum($p); return { 'error' => $session } if $context eq 'error'; @@ -1116,27 +1237,42 @@ sub _provision { my $pkgnum = $p->{'pkgnum'}; + warn "searching for custnum $custnum pkgnum $pkgnum\n" + if $DEBUG; my $cust_pkg = qsearchs('cust_pkg', { 'custnum' => $custnum, 'pkgnum' => $pkgnum, } ) or return { 'error' => "unknown pkgnum $pkgnum" }; + warn "searching for svcpart ". $p->{'svcpart'}. "\n" + if $DEBUG; my $part_svc = qsearchs('part_svc', { 'svcpart' => $p->{'svcpart'} } ) or return { 'error' => "unknown svcpart $p->{'svcpart'}" }; + warn "creating $class record\n" + if $DEBUG; my $svc_x = $class->new( { 'pkgnum' => $p->{'pkgnum'}, 'svcpart' => $p->{'svcpart'}, map { $_ => $p->{$_} } @$fields } ); + warn "inserting $class record\n" + if $DEBUG; my $error = $svc_x->insert; - $svc_x = qsearchs($svc_x->table, { 'svcnum' => $svc_x->svcnum }) - unless $error; - return { 'svc' => $part_svc->svc, - 'error' => $error, - map { $_ => $svc_x->get($_) } @$return_fields - }; + unless ( $error ) { + warn "finding inserted record for svcnum ". $svc_x->svcnum. "\n" + if $DEBUG; + $svc_x = qsearchs($svc_x->table, { 'svcnum' => $svc_x->svcnum }) + } + + my $return = { 'svc' => $part_svc->svc, + 'error' => $error, + map { $_ => $svc_x->get($_) } @$return_fields + }; + warn "_provision returning ". Dumper($return). "\n" + if $DEBUG; + return $return; }