da51f49e2fc041541a4a3dbe7140ae921e1bc0ce
[freeside.git] / FS / FS / ClientAPI / Signup.pm
1 package FS::ClientAPI::Signup;
2
3 use strict;
4 use Tie::RefHash;
5 use FS::Conf;
6 use FS::Record qw(qsearch qsearchs);
7 use FS::agent;
8 use FS::cust_main_county;
9 use FS::part_pkg;
10 use FS::svc_acct_pop;
11 use FS::cust_main;
12 use FS::cust_pkg;
13 use FS::Msgcat qw(gettext);
14
15 use FS::ClientAPI; #hmm
16 FS::ClientAPI->register_handlers(
17   'Signup/signup_info'  => \&signup_info,
18   'Signup/new_customer' => \&new_customer,
19 );
20
21 sub signup_info {
22   #my $packet = shift;
23
24   my $conf = new FS::Conf;
25
26   my $signup_info = {
27
28     'cust_main_county' =>
29       [ map { $_->hashref } qsearch('cust_main_county', {}) ],
30
31     'agentnum2part_pkg' =>
32       {
33         map {
34           my $href = $_->pkgpart_hashref;
35           $_->agentnum =>
36             [
37               map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
38                 grep { $_->svcpart('svc_acct') && $href->{ $_->pkgpart } }
39                   qsearch( 'part_pkg', { 'disabled' => '' } )
40             ];
41         } qsearch('agent', {} )
42       },
43
44     'svc_acct_pop' => [ map { $_->hashref } qsearch('svc_acct_pop',{} ) ],
45
46     'security_phrase' => $conf->exists('security_phrase'),
47
48     'payby' => [ $conf->config('signup_server-payby') ],
49
50     'msgcat' => { map { $_=>gettext($_) } qw(
51       passwords_dont_match invalid_card unknown_card_type not_a
52     ) },
53
54     'statedefault' => $conf->config('statedefault') || 'CA',
55
56     'countrydefault' => $conf->config('countrydefault') || 'US',
57
58   };
59
60   if ( $conf->config('signup_server-default_agentnum') ) {
61     my $agentnum = $conf->config('signup_server-default_agentnum');
62     my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } )
63       or die "fatal: signup_server-default_agentnum $agentnum not found\n";
64     my $pkgpart_href = $agent->pkgpart_hashref;
65
66     $signup_info->{'part_pkg'} = [
67       #map { $_->hashref }
68       map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
69         grep { $_->svcpart('svc_acct') && $pkgpart_href->{ $_->pkgpart } }
70           qsearch( 'part_pkg', { 'disabled' => '' } )
71     ];
72   }
73
74   $signup_info;
75
76 }
77
78 sub new_customer {
79   my $packet = shift;
80
81   my $conf = new FS::Conf;
82   my $error = '';
83   
84   #things that aren't necessary in base class, but are for signup server
85     #return "Passwords don't match"
86     #  if $hashref->{'_password'} ne $hashref->{'_password2'}
87   $error ||= gettext('empty_password') unless $packet->{'_password'};
88   # a bit inefficient for large numbers of pops
89   $error ||= gettext('no_access_number_selected')
90     unless $packet->{'popnum'} || !scalar(qsearch('svc_acct_pop',{} ));
91
92   #shares some stuff with htdocs/edit/process/cust_main.cgi... take any
93   # common that are still here and library them.
94   my $cust_main = new FS::cust_main ( {
95     #'custnum'          => '',
96     'agentnum'      => $packet->{agentnum}
97                        || $conf->config('signup_server-default_agentnum'),
98     'refnum'        => $packet->{refnum}
99                        || $conf->config('signup_server-default_refnum'),
100
101     map { $_ => $packet->{$_} } qw(
102       last first ss company address1 address2 city county state zip country
103       daytime night fax payby payinfo paydate payname referral_custnum comments
104     ),
105
106   } );
107
108   $error ||= "Illegal payment type"
109     unless grep { $_ eq $packet->{'payby'} }
110                 $conf->config('signup_server-payby');
111
112   $cust_main->payinfo($cust_main->daytime)
113     if $cust_main->payby eq 'LECB' && ! $cust_main->payinfo;
114
115   my @invoicing_list = split( /\s*\,\s*/, $packet->{'invoicing_list'} );
116
117   $packet->{'pkgpart'} =~ /^(\d+)$/ or '' =~ /^()$/;
118   my $pkgpart = $1;
119
120   my $part_pkg =
121     qsearchs( 'part_pkg', { 'pkgpart' => $pkgpart } )
122       or $error ||= "WARNING: unknown pkgpart: $pkgpart";
123   my $svcpart = $part_pkg->svcpart('svc_acct') unless $error;
124
125   my $cust_pkg = new FS::cust_pkg ( {
126     #later#'custnum' => $custnum,
127     'pkgpart' => $packet->{'pkgpart'},
128   } );
129   $error ||= $cust_pkg->check;
130
131   my $svc_acct = new FS::svc_acct ( {
132     'svcpart'   => $svcpart,
133     map { $_ => $packet->{$_} }
134       qw( username _password sec_phrase popnum ),
135   } );
136
137   my $y = $svc_acct->setdefault; # arguably should be in new method
138   $error ||= $y unless ref($y);
139
140   $error ||= $svc_acct->check;
141
142   use Tie::RefHash;
143   tie my %hash, 'Tie::RefHash';
144   %hash = ( $cust_pkg => [ $svc_acct ] );
145   #msgcat
146   $error ||= $cust_main->insert( \%hash, \@invoicing_list, 'noexport' => 1 );
147
148   if ( ! $error && $conf->exists('signup_server-realtime') ) {
149
150     #warn "[fs_signup_server] Billing customer...\n" if $Debug;
151
152     my $bill_error = $cust_main->bill;
153     #warn "[fs_signup_server] error billing new customer: $bill_error"
154     #  if $bill_error;
155
156     $cust_main->apply_payments;
157     $cust_main->apply_credits;
158
159     $bill_error = $cust_main->collect;
160     #warn "[fs_signup_server] error collecting from new customer: $bill_error"
161     #  if $bill_error;
162
163     if ( $cust_main->balance > 0 ) {
164
165       #this makes sense.  credit is "un-doing" the invoice
166       $cust_main->credit( $cust_main->balance, 'signup server decline' );
167       $cust_main->apply_credits;
168
169       #should check list for errors...
170       #$cust_main->suspend;
171       local $FS::svc_Common::noexport_hack = 1;
172       $cust_main->cancel('quiet'=>1);
173
174       $error = '_decline';
175     }
176
177   }
178   $cust_main->reexport unless $error;
179
180   return { error => $error };
181
182 }
183
184 1;