summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorivan <ivan>2003-09-19 10:07:15 +0000
committerivan <ivan>2003-09-19 10:07:15 +0000
commit9ea86c8ef0ee70baf043632d81e0d148d5f5853c (patch)
treed068a6df8c65faa1bf5870a87af2f1b57bb57f2a /FS
parentedeb527abccf4dd345550c5eb5ee0823cca3c87d (diff)
move signup server functions to self-service server. fix provisioning &
immediate suspension of declined signups.
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/ClientAPI/Signup.pm183
-rw-r--r--FS/FS/Conf.pm17
-rw-r--r--FS/FS/cust_main.pm46
-rw-r--r--FS/FS/cust_pkg.pm35
4 files changed, 277 insertions, 4 deletions
diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm
new file mode 100644
index 000000000..0bb9f7b6a
--- /dev/null
+++ b/FS/FS/ClientAPI/Signup.pm
@@ -0,0 +1,183 @@
+package FS::ClientAPI::Signup;
+
+use strict;
+use Tie::RefHash;
+use FS::Conf;
+use FS::Record qw(qsearch qsearchs);
+use FS::agent;
+use FS::cust_main_county;
+use FS::part_pkg;
+use FS::svc_acct_pop;
+use FS::cust_main;
+use FS::cust_pkg;
+use FS::Msgcat qw(gettext);
+
+use FS::ClientAPI; #hmm
+FS::ClientAPI->register_handlers(
+ 'Signup/signup_info' => \&signup_info,
+ 'Signup/new_customer' => \&new_customer,
+);
+
+sub signup_info {
+ #my $packet = shift;
+
+ my $conf = new FS::Conf;
+
+ my $signup_info = {
+
+ 'cust_main_county' =>
+ [ map { $_->hashref } qsearch('cust_main_county', {}) ],
+
+ 'agentnum2part_pkg' =>
+ {
+ map {
+ my $href = $_->pkgpart_hashref;
+ $_->agentnum =>
+ [
+ map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
+ grep { $_->svcpart('svc_acct') && $href->{ $_->pkgpart } }
+ qsearch( 'part_pkg', { 'disabled' => '' } )
+ ];
+ } qsearch('agent', {} )
+ },
+
+ 'svc_acct_pop' => [ map { $_->hashref } qsearch('svc_acct_pop',{} ) ],
+
+ 'security_phrase' => $conf->exists('security_phrase'),
+
+ 'payby' => [ $conf->config('signup_server-payby') ],
+
+ 'msgcat' => { map { $_=>gettext($_) } qw(
+ passwords_dont_match invalid_card unknown_card_type not_a
+ ) },
+
+ 'statedefault' => $conf->config('statedefault') || 'CA',
+
+ 'countrydefault' => $conf->config('countrydefault') || 'US',
+
+ };
+
+ if ( $conf->config('signup_server-default_agentnum') ) {
+ my $agentnum = $conf->config('signup_server-default_agentnum');
+ my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } )
+ or die "fatal: signup_server-default_agentnum $agentnum not found\n";
+ my $pkgpart_href = $agent->pkgpart_hashref;
+
+ $signup_info->{'part_pkg'} = [
+ #map { $_->hashref }
+ map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
+ grep { $_->svcpart('svc_acct') && $pkgpart_href->{ $_->pkgpart } }
+ qsearch( 'part_pkg', { 'disabled' => '' } )
+ ];
+ }
+
+ $signup_info;
+
+}
+
+sub new_customer {
+ my $packet = shift;
+
+ my $conf = new FS::Conf;
+ my $error = '';
+
+ #things that aren't necessary in base class, but are for signup server
+ #return "Passwords don't match"
+ # if $hashref->{'_password'} ne $hashref->{'_password2'}
+ $error ||= gettext('empty_password') unless $packet->{'_password'};
+ # a bit inefficient for large numbers of pops
+ $error ||= gettext('no_access_number_selected')
+ unless $packet->{'popnum'} || !scalar(qsearch('svc_acct_pop',{} ));
+
+ #shares some stuff with htdocs/edit/process/cust_main.cgi... take any
+ # common that are still here and library them.
+ my $cust_main = new FS::cust_main ( {
+ #'custnum' => '',
+ 'agentnum' => $packet->{agentnum}
+ || $conf->config('signup_server-default_agentnum'),
+ 'refnum' => $packet->{refnum}
+ || $conf->config('signup_server-default_refnum'),
+
+ map { $_ => $packet->{$_} } qw(
+ last first ss company address1 address2 city county state zip country
+ daytime night fax payby payinfo paydate payname referral_custnum comments
+ ),
+
+ } );
+
+ $error ||= "Illegal payment type"
+ unless grep { $_ eq $packet->{'payby'} }
+ $conf->config('signup_server-payby');
+
+ $cust_main->payinfo($cust_main->daytime)
+ if $cust_main->payby eq 'LECB' && ! $cust_main->payinfo;
+
+ my @invoicing_list = split( /\s*\,\s*/, $packet->{'invoicing_list'} );
+
+ $packet->{'pkgpart'} =~ /^(\d+)$/ or '' =~ /^()$/;
+ my $pkgpart = $1;
+
+ my $part_pkg =
+ qsearchs( 'part_pkg', { 'pkgpart' => $pkgpart } )
+ or $error ||= "WARNING: unknown pkgpart: $pkgpart";
+ my $svcpart = $part_pkg->svcpart('svc_acct') unless $error;
+
+ my $cust_pkg = new FS::cust_pkg ( {
+ #later#'custnum' => $custnum,
+ 'pkgpart' => $packet->{'pkgpart'},
+ } );
+ $error ||= $cust_pkg->check;
+
+ my $svc_acct = new FS::svc_acct ( {
+ 'svcpart' => $svcpart,
+ map { $_ => $packet->{$_} }
+ qw( username _password sec_phrase popnum ),
+ } );
+
+ my $y = $svc_acct->setdefault; # arguably should be in new method
+ $error ||= $y unless ref($y);
+
+ $error ||= $svc_acct->check;
+
+ use Tie::RefHash;
+ tie my %hash, 'Tie::RefHash';
+ %hash = ( $cust_pkg => [ $svc_acct ] );
+ #msgcat
+ $error ||= $cust_main->insert( \%hash, \@invoicing_list, 'noexport' => 1 );
+
+ if ( ! $error && $conf->exists('signup_server-realtime') ) {
+
+ #warn "[fs_signup_server] Billing customer...\n" if $Debug;
+
+ my $bill_error = $cust_main->bill;
+ #warn "[fs_signup_server] error billing new customer: $bill_error"
+ # if $bill_error;
+
+ $cust_main->apply_payments;
+ $cust_main->apply_credits;
+
+ $bill_error = $cust_main->collect;
+ #warn "[fs_signup_server] error collecting from new customer: $bill_error"
+ # if $bill_error;
+
+ if ( $cust_main->balance > 0 ) {
+
+ #this makes sense. credit is "un-doing" the invoice
+ $cust_main->credit( $cust_main->balance, 'signup server decline' );
+ $cust_main->apply_credits;
+
+ #should check list for errors...
+ #$cust_main->suspend;
+ local $FS::svc_Common::noexport_hack = 1;
+ $cust_main->cancel;
+
+ $error = '_decline';
+ }
+
+ }
+ $cust_main->reexport unless $error;
+
+ return { error => $error };
+
+}
+
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index 88def81fe..253df9057 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -903,7 +903,7 @@ httemplate/docs/config.html
{
'key' => 'signup_server-quiet',
'section' => 'deprecated',
- 'description' => ''<b>DEPRECATED</b>, the signup server is now part of the self-service server and no longer sends superfluous decline and cancel emails. Used to disable decline and cancel emails generated by transactions initiated by the signup server. Does not disable welcome emails.',
+ 'description' => '<b>DEPRECATED</b>, the signup server is now part of the self-service server and no longer sends superfluous decline and cancel emails. Used to disable decline and cancel emails generated by transactions initiated by the signup server. Does not disable welcome emails.',
'type' => 'checkbox',
},
@@ -917,11 +917,24 @@ httemplate/docs/config.html
{
'key' => 'signup_server-email',
+ 'section' => 'deprecated',
+ 'description' => '<b>DEPRECATED</b>, this feature is no longer available. See the ***fill me in*** report instead. Used to contain a comma-separated list of email addresses to receive notification of signups via the signup server.',
+ 'type' => 'text',
+ },
+
+ {
+ 'key' => 'signup_server-default_agentnum',
'section' => '',
- 'description' => 'Comma-separated list of email addresses to receive notification of signups via the signup server.',
+ 'description' => 'Default agentnum for the signup server',
'type' => 'text',
},
+ {
+ 'key' => 'signup_server-default_refnum',
+ 'section' => '',
+ 'description' => 'Default advertising source number for the signup server',
+ 'type' => 'text',
+ },
{
'key' => 'show-msgcat-codes',
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index b8c7ddff1..3064be322 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -6,7 +6,7 @@ use Safe;
use Carp;
BEGIN {
eval "use Time::Local;";
- die "Time::Local version 1.05 required with Perl versions before 5.6"
+ 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 timelocal_nocheck);";
}
@@ -194,7 +194,7 @@ points to. You can ask the object for a copy with the I<hash> method.
sub table { 'cust_main'; }
-=item insert [ CUST_PKG_HASHREF [ , INVOICING_LIST_ARYREF ] ]
+=item insert [ CUST_PKG_HASHREF [ , INVOICING_LIST_ARYREF ] [ , OPTION => VALUE ... ] ]
Adds this customer to the database. If there is an error, returns the error,
otherwise returns false.
@@ -222,12 +222,18 @@ invoicing_list destination to the newly-created svc_acct. Here's an example:
$cust_main->insert( {}, [ $email, 'POST' ] );
+Currently available options are: I<noexport>
+
+If I<noexport> is set true, no provisioning jobs (exports) are scheduled.
+(You can schedule them later with the B<reexport> method.)
+
=cut
sub insert {
my $self = shift;
my $cust_pkgs = @_ ? shift : {};
my $invoicing_list = @_ ? shift : '';
+ my %options = @_;
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
@@ -279,6 +285,7 @@ sub insert {
}
# packages
+ local $FS::svc_Common::noexport_hack = 1 if $options{'noexport'};
foreach my $cust_pkg ( keys %$cust_pkgs ) {
$cust_pkg->custnum( $self->custnum );
$error = $cust_pkg->insert;
@@ -1213,6 +1220,41 @@ sub bill {
''; #no error
}
+=item reexport
+
+document me. Re-schedules all exports by calling the B<reexport> method
+of all associated packages (see L<FS::cust_pkg>). If there is an error,
+returns the error; otherwise returns false.
+
+=cut
+
+sub reexport {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ foreach my $cust_pkg ( $self->ncancelled_pkgs ) {
+ my $error = $cust_pkg->reexport;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+
+}
+
=item collect OPTIONS
(Attempt to) collect money for this customer's outstanding invoices (see
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 6b6d55572..ad5eb8e59 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -631,6 +631,41 @@ sub attribute_since_sqlradacct {
}
+=item reexport
+
+=cut
+
+sub reexport {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ foreach my $cust_svc ( $self->cust_svc ) {
+ #false laziness w/svc_Common::insert
+ my $svc_x = $cust_svc->svc_x;
+ foreach my $part_export ( $cust_svc->part_svc->part_export ) {
+ my $error = $part_export->export_insert($svc_x);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+
+}
+
=back
=head1 SUBROUTINES