b887098621ac78c5be59729043c028ddd9c8cbae
[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 HTML::Entities;
13 use FS::SelfService qw( agent_login agent_logout agent_info
14                         agent_list_customers
15                         signup_info new_customer
16                         customer_info list_pkgs order_pkg
17                         part_svc_info provision_acct unprovision_svc
18                       );
19
20 $DEBUG = 0;
21 $me = 'agent.cgi:';
22
23 $template_dir = '.';
24
25 $form_max = 255;
26
27 warn "$me starting\n" if $DEBUG;
28
29 warn "$me initializing CGI\n" if $DEBUG;
30 $cgi = new CGI;
31
32 unless ( defined $cgi->param('session') ) {
33   warn "$me no session defined, sending login page\n" if $DEBUG;
34   do_template('agent_login',{});
35   exit;
36 }
37
38 if ( $cgi->param('session') eq 'login' ) {
39
40   warn "$me processing login\n" if $DEBUG;
41
42   $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i
43     or die "illegal username";
44   my $username = $1;
45
46   $cgi->param('password') =~ /^(.{0,$form_max})$/
47     or die "illegal password";
48   my $password = $1;
49
50   my $rv = agent_login(
51     'username' => $username,
52     'password' => $password,
53   );
54   if ( $rv->{error} ) {
55     do_template('agent_login', {
56       'error'    => $rv->{error},
57       'username' => $username,
58     } );
59     exit;
60   } else {
61     $cgi->param('session' => $rv->{session_id} );
62     $cgi->param('action'  => 'agent_main' );
63   }
64 }
65
66 $session_id = $cgi->param('session');
67
68 warn "$me checking action\n" if $DEBUG;
69 $cgi->param('action') =~
70    /^(agent_main|signup|process_signup|list_customers|view_customer|agent_provision|provision_svc|process_svc_acct|delete_svc|agent_order_pkg|process_order_pkg|logout)$/
71   or die "unknown action ". $cgi->param('action');
72 my $action = $1;
73
74 warn "$me running $action\n" if $DEBUG;
75 my $result = eval "&$action();";
76 die $@ if $@;
77
78 if ( $result->{error} eq "Can't resume session" ) { #ick
79   do_template('agent_login',{});
80   exit;
81 }
82
83 warn "$me processing template $action\n" if $DEBUG;
84 do_template($action, {
85   'session_id' => $session_id,
86   %{$result}
87 });
88 warn "$me done processing template $action\n" if $DEBUG;
89
90 #-- 
91
92 sub logout {
93   $action = 'agent_logout';
94   agent_logout( 'session_id' => $session_id );
95 }
96
97 sub agent_main { agent_info( 'session_id' => $session_id ); }
98
99 sub signup { signup_info( 'session_id' => $session_id ); }
100
101 sub process_signup {
102
103   my $init_data = signup_info( 'session_id' => $session_id );
104   if ( $init_data->{'error'} ) {
105     if ( $init_data->{'error'} eq "Can't resume session" ) { #ick
106       do_template('agent_login',{});
107       exit;
108     } else { #?
109       die $init_data->{'error'};
110     }
111   }
112
113   my $error = '';
114
115   #some false laziness w/signup.cgi
116   my $payby = $cgi->param('payby');
117   if ( $payby eq 'CHEK' || $payby eq 'DCHK' ) {
118     #$payinfo = join('@', map { $cgi->param( $payby. "_payinfo$_" ) } (1,2) );
119     $cgi->param('payinfo' => $cgi->param($payby. '_payinfo1'). '@'. 
120                              $cgi->param($payby. '_payinfo2')
121                );
122   } else {
123     $cgi->param('payinfo' => $cgi->param( $payby. '_payinfo' ) );
124   }
125   $cgi->param('paydate' => $cgi->param( $payby. '_month' ). '-'.
126                            $cgi->param( $payby. '_year' )
127              );
128   $cgi->param('payname' => $cgi->param( $payby. '_payname' ) );
129   $cgi->param('paycvv' => defined $cgi->param( $payby. '_paycvv' )
130                             ? $cgi->param( $payby. '_paycvv' )
131                             : ''
132              );
133
134   if ( $cgi->param('invoicing_list') ) {
135     $cgi->param('invoicing_list' => $cgi->param('invoicing_list'). ', POST')
136       if $cgi->param('invoicing_list_POST');
137   } else {
138     $cgi->param('invoicing_list' => 'POST' );
139   }
140
141   if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
142     $error = $init_data->{msgcat}{passwords_dont_match}; #msgcat
143     $cgi->param('_password', '');
144     $cgi->param('_password2', '');
145   }
146
147   if ( $payby =~ /^(CARD|DCRD)$/ && $cgi->param('CARD_type') ) {
148     my $payinfo = $cgi->param('payinfo');
149     $payinfo =~ s/\D//g;
150
151     $payinfo =~ /^(\d{13,16})$/
152       or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
153     $payinfo = $1;
154     validate($payinfo)
155       or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
156     cardtype($payinfo) eq $cgi->param('CARD_type')
157       or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type');
158   }
159
160   unless ( $error ) {
161     my $rv = new_customer ( {
162       'session_id'       => $session_id,
163       map { $_ => $cgi->param($_) }
164         qw( last first ss company
165             address1 address2 city county state zip country
166             daytime night fax
167             payby payinfo paycvv paydate payname invoicing_list
168             pkgpart username sec_phrase _password popnum refnum
169           ),
170         grep { /^snarf_/ } $cgi->param
171     } );
172     $error = $rv->{'error'};
173   }
174
175   if ( $error ) { 
176     $action = 'signup';
177     my $r = { 
178       $cgi->Vars,
179       %{$init_data},
180       'error' => $error,
181     };
182     #warn join('\n', map "$_ => $r->{$_}", keys %$r )."\n";
183     $r;
184   } else {
185     $action = 'agent_main';
186     my $agent_info = agent_info( 'session_id' => $session_id );
187     $agent_info->{'message'} = 'Signup sucessful';
188     $agent_info;
189   }
190
191 }
192
193 sub list_customers {
194
195   my $results = 
196     agent_list_customers( 'session_id' => $session_id,
197                           map { $_ => $cgi->param($_) }
198                             grep defined($cgi->param($_)),
199                                  qw(prospect active susp cancel),
200                                  'search',
201                         );
202
203   if ( scalar( @{$results->{'customers'}} ) == 1 ) {
204     $action = 'view_customer';
205     customer_info (
206       'agent_session_id' => $session_id,
207       'custnum'          => $results->{'customers'}[0]{'custnum'},
208     );
209   } else {
210     $results;
211   }
212
213 }
214
215 sub view_customer {
216
217   #my $init_data = signup_info( 'session_id' => $session_id );
218   #if ( $init_data->{'error'} ) {
219   #  if ( $init_data->{'error'} eq "Can't resume session" ) { #ick
220   #    do_template('agent_login',{});
221   #    exit;
222   #  } else { #?
223   #    die $init_data->{'error'};
224   #  }
225   #}
226   #
227   #my $customer_info =
228   customer_info (
229     'agent_session_id' => $session_id,
230     'custnum'          => $cgi->param('custnum'),
231   );
232   #
233   #return {
234   #  ( map { $_ => $init_data->{$_} }
235   #        qw( part_pkg security_phrase svc_acct_pop ),
236   #  ),
237   #  %$customer_info,
238   #};
239 }
240
241 sub agent_order_pkg {
242
243   my $init_data = signup_info( 'session_id' => $session_id );
244   if ( $init_data->{'error'} ) {
245     if ( $init_data->{'error'} eq "Can't resume session" ) { #ick
246       do_template('agent_login',{});
247       exit;
248     } else { #?
249       die $init_data->{'error'};
250     }
251   }
252
253   my $customer_info = customer_info (
254     'agent_session_id' => $session_id,
255     'custnum'          => $cgi->param('custnum'),
256   );
257
258   return {
259     ( map { $_ => $init_data->{$_} }
260           qw( part_pkg security_phrase svc_acct_pop ),
261     ),
262     %$customer_info,
263   };
264
265 }
266
267 sub agent_provision {
268   my $result = list_pkgs(
269     'agent_session_id' => $session_id,
270     'custnum'          => $cgi->param('custnum'),
271   );
272   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
273   $result;
274 }
275
276 sub provision_svc {
277
278   my $result = part_svc_info(
279     'agent_session_id' => $session_id,
280     map { $_ => $cgi->param($_) } qw( pkgnum svcpart custnum ),
281   );
282   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
283
284   $result->{'svcdb'} =~ /^svc_(.*)$/
285     #or return { 'error' => 'Unknown svcdb '. $result->{'svcdb'} };
286     or die 'Unknown svcdb '. $result->{'svcdb'};
287   $action .= "_$1";
288   $action = "agent_$action";
289
290   $result;
291 }
292
293 sub process_svc_acct {
294
295   my $result = provision_acct (
296     'agent_session_id' => $session_id,
297     map { $_ => $cgi->param($_) } qw(
298       custnum pkgnum svcpart username _password _password2 sec_phrase popnum )
299   );
300
301   if ( exists $result->{'error'} && $result->{'error'} ) { 
302     #warn "$result $result->{'error'}"; 
303     $action = 'provision_svc_acct';
304     $action = "agent_$action";
305     return {
306       $cgi->Vars,
307       %{ part_svc_info( 'agent_session_id' => $session_id,
308                         map { $_ => $cgi->param($_) } qw(pkgnum svcpart custnum)
309                       )
310       },
311       'error' => $result->{'error'},
312     };
313   } else {
314     #warn "$result $result->{'error'}"; 
315     $action = 'agent_provision';
316     return {
317       %{agent_provision()},
318       'message' => $result->{'svc'}. ' setup sucessfully.',
319     };
320   }
321
322 }
323
324 sub delete_svc {
325   my $result = unprovision_svc(
326     'agent_session_id' => $session_id,
327     'custnum'          => $cgi->param('custnum'),
328     'svcnum'           => $cgi->param('svcnum'),
329   );
330
331   $action = 'agent_provision';
332
333   return {
334     %{agent_provision()},
335     'message' => $result->{'error'}
336                    ? '<FONT COLOR="#FF0000">'. $result->{'error'}. '</FONT>'
337                    : $result->{'svc'}. ' removed.'
338   };
339
340 }
341
342 sub process_order_pkg {
343
344   my $results = '';
345
346   unless ( length($cgi->param('_password')) ) {
347     my $init_data = signup_info( 'session_id' => $session_id );
348     #die $init_data->{'error'} if $init_data->{'error'};
349     $results = { 'error' => $init_data->{msgcat}{empty_password} };
350   }
351   if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
352     my $init_data = signup_info( 'session_id' => $session_id );
353     $results = { 'error' => $init_data->{msgcat}{passwords_dont_match} };
354     $cgi->param('_password', '');
355     $cgi->param('_password2', '');
356   }
357
358   $results ||= order_pkg (
359     'agent_session_id' => $session_id,
360     map { $_ => $cgi->param($_) }
361         qw( custnum pkgpart username _password _password2 sec_phrase popnum )
362   );
363
364   if ( $results->{'error'} ) {
365     $action = 'agent_order_pkg';
366     return {
367       $cgi->Vars,
368       %{agent_order_pkg()},
369       #'message' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
370       'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
371     };
372   } else {
373     $action = 'view_customer';
374     #$cgi->delete( grep { $_ ne 'custnum' } $cgi->param );
375     return {
376       %{view_customer()},
377       'message' => 'Package order sucessful.',
378     };
379   }
380
381 }
382
383 #--
384
385 sub do_template {
386   my $name = shift;
387   my $fill_in = shift;
388   #warn join(' / ', map { "$_=>".$fill_in->{$_} } keys %$fill_in). "\n";
389
390   $cgi->delete_all();
391   $fill_in->{'selfurl'} = $cgi->self_url;
392   $fill_in->{'cgi'} = \$cgi;
393
394   my $template = new Text::Template( TYPE    => 'FILE',
395                                      SOURCE  => "$template_dir/$name.html",
396                                      DELIMITERS => [ '<%=', '%>' ],
397                                      UNTAINT => 1,                    )
398     or die $Text::Template::ERROR;
399
400   local $^W = 0;
401   print $cgi->header( '-expires' => 'now' ),
402         $template->fill_in( PACKAGE => 'FS::SelfService::_agentcgi',
403                             HASH    => $fill_in
404                           );
405 }
406
407 package FS::SelfService::_agentcgi;
408
409 use HTML::Entities;
410 use FS::SelfService qw(regionselector expselect popselector);
411
412 #false laziness w/selfservice.cgi
413 sub include {
414   my $name = shift;
415   my $template = new Text::Template( TYPE   => 'FILE',
416                                      SOURCE => "$main::template_dir/$name.html",
417                                      DELIMITERS => [ '<%=', '%>' ],
418                                      UNTAINT => 1,                   
419                                    )
420     or die $Text::Template::ERROR;
421
422   $template->fill_in( PACKAGE => 'FS::SelfService::_agentcgi',
423                       #HASH    => $fill_in
424                     );
425
426 }
427