move signup server functions to self-service server. fix provisioning &
authorivan <ivan>
Fri, 19 Sep 2003 10:07:15 +0000 (10:07 +0000)
committerivan <ivan>
Fri, 19 Sep 2003 10:07:15 +0000 (10:07 +0000)
immediate suspension of declined signups.

FS/FS/ClientAPI/Signup.pm [new file with mode: 0644]
FS/FS/Conf.pm
FS/FS/cust_main.pm
FS/FS/cust_pkg.pm
Makefile
fs_signup/FS-SignupClient/SignupClient.pm
httemplate/docs/index.html

diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm
new file mode 100644 (file)
index 0000000..0bb9f7b
--- /dev/null
@@ -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 };
+
+}
+
index 88def81..253df90 100644 (file)
@@ -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',
index b8c7ddf..3064be3 100644 (file)
@@ -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
index 6b6d555..ad5eb8e 100644 (file)
@@ -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
index a47f80d..d43c204 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -46,14 +46,6 @@ QUEUED_USER=fs_queue
 #eventually this shouldn't be needed
 FREESIDE_PATH = `pwd`
 
-PASSWD_USER = nostart
-PASSWD_MACHINE = localhost
-
-SIGNUP_USER = nostart
-SIGNUP_MACHINE = localhost
-SIGNUP_AGENTNUM = 2
-SIGNUP_REFNUM = 2
-
 SELFSERVICE_USER = nostart
 SELFSERVICE_MACHINE = localhost
 
@@ -140,12 +132,6 @@ install-init:
        perl -p -i -e "\
          s/%%%QUEUED_USER%%%/${QUEUED_USER}/g;\
          s'%%%FREESIDE_PATH%%%'${FREESIDE_PATH}'g;\
-         s/%%%PASSWD_USER%%%/${PASSWD_USER}/g;\
-         s/%%%PASSWD_MACHINE%%%/${PASSWD_MACHINE}/g;\
-         s/%%%SIGNUP_USER%%%/${SIGNUP_USER}/g;\
-         s/%%%SIGNUP_MACHINE%%%/${SIGNUP_MACHINE}/g;\
-         s/%%%SIGNUP_AGENTNUM%%%/${SIGNUP_AGENTNUM}/g;\
-         s/%%%SIGNUP_REFNUM%%%/${SIGNUP_REFNUM}/g;\
          s/%%%SELFSERVICE_USER%%%/${SELFSERVICE_USER}/g;\
          s/%%%SELFSERVICE_MACHINE%%%/${SELFSERVICE_MACHINE}/g;\
        " ${INIT_FILE}
index 842064d..e17c461 100644 (file)
@@ -1,30 +1,19 @@
 package FS::SignupClient;
 
 use strict;
-use vars qw($VERSION @ISA @EXPORT_OK $fs_signupd_socket);
+use vars qw($VERSION @ISA @EXPORT_OK); # $fs_signupd_socket);
 use Exporter;
-use Socket;
-use FileHandle;
-use IO::Handle;
-use Storable qw(nstore_fd fd_retrieve);
+#use Socket;
+#use FileHandle;
+#use IO::Handle;
+#use Storable qw(nstore_fd fd_retrieve);
+use FS::SelfService qw( new_customer ); #qw( signup_info );
 
-$VERSION = '0.03';
+$VERSION = '0.04';
 
 @ISA = qw( Exporter );
 @EXPORT_OK = qw( signup_info new_customer );
 
-$fs_signupd_socket = "/usr/local/freeside/fs_signupd_socket";
-
-$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin';
-$ENV{'SHELL'} = '/bin/sh';
-$ENV{'IFS'} = " \t\n";
-$ENV{'CDPATH'} = '';
-$ENV{'ENV'} = '';
-$ENV{'BASH_ENV'} = '';
-
-my $freeside_uid = scalar(getpwnam('freeside'));
-die "not running as the freeside user\n" if $> != $freeside_uid;
-
 =head1 NAME
 
 FS::SignupClient - Freeside signup client API
@@ -33,8 +22,10 @@ FS::SignupClient - Freeside signup client API
 
   use FS::SignupClient qw( signup_info new_customer );
 
-  ( $locales, $packages, $pops ) = signup_info;
+  #this is the backwards-compatibility bit
+  ( $locales, $packages, $pops, $real_signup_info ) = signup_info;
 
+  #this is compatible with FS::SelfService::new_customer
   $error = new_customer ( {
     'first'            => $first,
     'last'             => $last,
@@ -104,14 +95,10 @@ Each hash reference has the following keys:
 
 =cut
 
+#compatibility bit
 sub signup_info {
-  socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
-  connect(SOCK, sockaddr_un($fs_signupd_socket)) or die "connect: $!";
-  print SOCK "signup_info\n";
-  SOCK->flush;
 
-  my $init_data = fd_retrieve(\*SOCK);
-  close SOCK;
+  my $init_data = FS::SelfService::signup_info();
 
   (map { $init_data->{$_} } qw( cust_main_county part_pkg svc_acct_pop ) ),
   $init_data;
@@ -151,30 +138,6 @@ a paramater with the following keys:
 
 Returns a scalar error message, or the empty string for success.
 
-=cut
-
-sub new_customer {
-  my $hashref = shift;
-
-  socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
-  connect(SOCK, sockaddr_un($fs_signupd_socket)) or die "connect: $!";
-  print SOCK "new_customer\n";
-
-  my $signup_data = { map { $_ => $hashref->{$_} } qw(
-    first last ss company address1 address2 city county state zip country
-    daytime night fax payby payinfo paydate payname invoicing_list
-    referral_custnum comments pkgpart username _password sec_phrase popnum
-  ) };
-
-  $signup_data->{agentnum} = $hashref->{agentnum} if $hashref->{agentnum};
-
-  nstore_fd($signup_data, \*SOCK) or die "can't send customer signup: $!";
-  SOCK->flush;
-
-  chop( my $error = <SOCK> );
-  $error;
-}
-
 =back
 
 =head1 BUGS
index eaa5b9b..1ed0285 100644 (file)
@@ -12,6 +12,7 @@
   <li><a href="upgrade7.html">Upgrading from 1.3.0 to 1.3.1</a>
   <li><a href="upgrade8.html">Upgrading from 1.3.1 to 1.4.0</a>
   <li><a href="upgrade9.html">Upgrading from 1.4.0 to 1.4.1</a>
+  <li><a href="upgrade-1.4.2.html">Upgrading from 1.4.1 to 1.4.2</a>
 <!--
   <li><a href="config.html">Configuration files</a>
 !-->