big update for customer self-service: add provisioning/unprovisioning of purchased...
[freeside.git] / fs_selfservice / FS-SelfService / cgi / agent.cgi
1 #!/usr/bin/perl -Tw
2
3 #some false laziness w/selfservice.cgi
4
5 use strict;
6 use vars qw($DEBUG $me $cgi $session_id $form_max $template_dir);
7 use subs qw(do_template);
8 use CGI;
9 use CGI::Carp qw(fatalsToBrowser);
10 use Business::CreditCard;
11 use Text::Template;
12 use FS::SelfService qw( agent_login agent_info
13                         agent_list_customers
14                         signup_info new_customer
15                         customer_info order_pkg
16                       );
17
18 $DEBUG = 0;
19 $me = 'agent.cgi:';
20
21 $template_dir = '.';
22
23 $form_max = 255;
24
25 warn "$me starting\n" if $DEBUG;
26
27 warn "$me initializing CGI\n" if $DEBUG;
28 $cgi = new CGI;
29
30 unless ( defined $cgi->param('session') ) {
31   warn "$me no session defined, sending login page\n" if $DEBUG;
32   do_template('agent_login',{});
33   exit;
34 }
35
36 if ( $cgi->param('session') eq 'login' ) {
37
38   warn "$me processing login\n" if $DEBUG;
39
40   $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i
41     or die "illegal username";
42   my $username = $1;
43
44   $cgi->param('password') =~ /^(.{0,$form_max})$/
45     or die "illegal password";
46   my $password = $1;
47
48   my $rv = agent_login(
49     'username' => $username,
50     'password' => $password,
51   );
52   if ( $rv->{error} ) {
53     do_template('agent_login', {
54       'error'    => $rv->{error},
55       'username' => $username,
56     } );
57     exit;
58   } else {
59     $cgi->param('session' => $rv->{session_id} );
60     $cgi->param('action'  => 'agent_main' );
61   }
62 }
63
64 $session_id = $cgi->param('session');
65
66 warn "$me checking action\n" if $DEBUG;
67 $cgi->param('action') =~
68    /^(agent_main|signup|process_signup|list_customers|view_customer|process_order_pkg)$/
69   or die "unknown action ". $cgi->param('action');
70 my $action = $1;
71
72 warn "$me running $action\n" if $DEBUG;
73 my $result = eval "&$action();";
74 die $@ if $@;
75
76 if ( $result->{error} eq "Can't resume session" ) { #ick
77   do_template('agent_login',{});
78   exit;
79 }
80
81 warn "$me processing template $action\n" if $DEBUG;
82 do_template($action, {
83   'session_id' => $session_id,
84   %{$result}
85 });
86 warn "$me done processing template $action\n" if $DEBUG;
87
88 #-- 
89
90 sub agent_main { agent_info( 'session_id' => $session_id ); }
91
92 sub signup { signup_info( 'session_id' => $session_id ); }
93
94 sub process_signup {
95
96   my $init_data = signup_info( 'session_id' => $session_id );
97   if ( $init_data->{'error'} ) {
98     if ( $init_data->{'error'} eq "Can't resume session" ) { #ick
99       do_template('agent_login',{});
100       exit;
101     } else { #?
102       die $init_data->{'error'};
103     }
104   }
105
106   my $error = '';
107
108   #some false laziness w/signup.cgi
109   my $payby = $cgi->param('payby');
110   if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) {
111     #$payinfo = join('@', map { $cgi->param( $payby. "_payinfo$_" ) } (1,2) );
112     $cgi->param('payinfo' => $cgi->param($payby. '_payinfo1'). '@'. 
113                              $cgi->param($payby. '_payinfo2')
114                );
115   } else {
116     $cgi->param('payinfo' => $cgi->param( $payby. '_payinfo' ) );
117   }
118   $cgi->param('paydate' => $cgi->param( $payby. '_month' ). '-'.
119                            $cgi->param( $payby. '_year' )
120              );
121   $cgi->param('payname' => $cgi->param( $payby. '_payname' ) );
122   $cgi->param('paycvv' => defined $cgi->param( $payby. '_paycvv' )
123                             ? $cgi->param( $payby. '_paycvv' )
124                             : ''
125              );
126
127   if ( $cgi->param('invoicing_list') ) {
128     $cgi->param('invoicing_list' => $cgi->param('invoicing_list'). ', POST')
129       if $cgi->param('invoicing_list_POST');
130   } else {
131     $cgi->param('invoicing_list' => 'POST' );
132   }
133
134   if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
135     $error = $init_data->{msgcat}{passwords_dont_match}; #msgcat
136     $cgi->param('_password', '');
137     $cgi->param('_password2', '');
138   }
139
140   if ( $payby =~ /^(CARD|DCRD)$/ && $cgi->param('CARD_type') ) {
141     my $payinfo = $cgi->param('payinfo');
142     $payinfo =~ s/\D//g;
143
144     $payinfo =~ /^(\d{13,16})$/
145       or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
146     $payinfo = $1;
147     validate($payinfo)
148       or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
149     cardtype($payinfo) eq $cgi->param('CARD_type')
150       or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type');
151   }
152
153   unless ( $error ) {
154     my $rv = new_customer ( {
155       'session_id'       => $session_id,
156       map { $_ => $cgi->param($_) }
157         qw( last first ss company
158             address1 address2 city county state zip country
159             daytime night fax
160             payby payinfo paycvv paydate payname invoicing_list
161             pkgpart username sec_phrase _password popnum refnum
162           ),
163         grep { /^snarf_/ } $cgi->param
164     } );
165     $error = $rv->{'error'};
166   }
167
168   if ( $error ) { 
169     $action = 'signup';
170     my $r = { 
171       $cgi->Vars,
172       %{$init_data},
173       'error' => $error,
174     };
175     #warn join('\n', map "$_ => $r->{$_}", keys %$r )."\n";
176     $r;
177   } else {
178     $action = 'agent_main';
179     my $agent_info = agent_info( 'session_id' => $session_id );
180     $agent_info->{'message'} = 'Signup sucessful';
181     $agent_info;
182   }
183
184 }
185
186 sub list_customers {
187   agent_list_customers( 'session_id' => $session_id,
188                         map { $_ => $cgi->param($_) }
189                           grep defined($cgi->param($_)),
190                                qw(prospect active susp cancel)
191                       );
192 }
193
194 sub view_customer {
195
196   my $init_data = signup_info( 'session_id' => $session_id );
197   if ( $init_data->{'error'} ) {
198     if ( $init_data->{'error'} eq "Can't resume session" ) { #ick
199       do_template('agent_login',{});
200       exit;
201     } else { #?
202       die $init_data->{'error'};
203     }
204   }
205
206   my $customer_info = customer_info (
207     'agent_session_id' => $session_id,
208     'custnum'          => $cgi->param('custnum')
209   );
210
211
212   return {
213     ( map { $_ => $init_data->{$_} }
214           qw( part_pkg security_phrase svc_acct_pop ),
215     ),
216     %$customer_info,
217   };
218 }
219
220 sub process_order_pkg {
221
222   my $results = '';
223
224   unless ( length($cgi->param('_password')) ) {
225     my $init_data = signup_info( 'session_id' => $session_id );
226     $results = { 'error' => $init_data->{msgcat}{empty_password} }
227   }
228   if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
229     my $init_data = signup_info( 'session_id' => $session_id );
230     $results = { error => $init_data->{msgcat}{passwords_dont_match} };
231     $cgi->param('_password', '');
232     $cgi->param('_password2', '');
233   }
234
235   $results ||= order_pkg (
236     'agent_session_id' => $session_id,
237     map { $_ => $cgi->param($_) }
238         qw( custnum pkgpart username _password _password2 sec_phrase popnum )
239   );
240
241   $action = 'view_customer';
242   $cgi->delete( grep { $_ ne 'custnum' } $cgi->param )
243     unless $results->{'error'};
244
245   return {
246     $cgi->Vars,
247     %{view_customer()},
248     'message' => $results->{'error'}
249                    ? '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>'
250                    : 'Package order sucessful.'
251   };
252
253 }
254
255 #--
256
257 sub do_template {
258   my $name = shift;
259   my $fill_in = shift;
260   #warn join(' / ', map { "$_=>".$fill_in->{$_} } keys %$fill_in). "\n";
261
262   $cgi->delete_all();
263   $fill_in->{'selfurl'} = $cgi->self_url;
264   $fill_in->{'cgi'} = \$cgi;
265
266   my $template = new Text::Template( TYPE    => 'FILE',
267                                      SOURCE  => "$template_dir/$name.html",
268                                      DELIMITERS => [ '<%=', '%>' ],
269                                      UNTAINT => 1,                    )
270     or die $Text::Template::ERROR;
271
272   local $^W = 0;
273   print $cgi->header( '-expires' => 'now' ),
274         $template->fill_in( PACKAGE => 'FS::SelfService::_agentcgi',
275                             HASH    => $fill_in
276                           );
277 }
278
279 package FS::SelfService::_agentcgi;
280 use FS::SelfService qw(regionselector expselect popselector);
281