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