torrus various changes, RT10574
[freeside.git] / fs_selfservice / FS-SelfService / cgi / selfservice.cgi
1 #!/usr/bin/perl -Tw
2
3 use strict;
4 use vars qw($DEBUG $cgi $session_id $form_max $template_dir);
5 use subs qw(do_template);
6 use CGI;
7 use CGI::Carp qw(fatalsToBrowser);
8 use Text::Template;
9 use HTML::Entities;
10 use Date::Format;
11 use Date::Parse 'str2time';
12 use Number::Format 1.50;
13 use FS::SelfService qw(
14   access_info login_info login customer_info edit_info invoice
15   payment_info process_payment realtime_collect process_prepay
16   list_pkgs order_pkg signup_info order_recharge
17   part_svc_info provision_acct provision_external provision_phone
18   unprovision_svc change_pkg suspend_pkg domainselector
19   list_svcs list_svc_usage list_cdr_usage list_support_usage
20   myaccount_passwd list_invoices create_ticket get_ticket did_report
21   mason_comp port_graph
22 );
23
24 $template_dir = '.';
25
26 $DEBUG = 0;
27
28 $form_max = 255;
29
30 $cgi = new CGI;
31
32 unless ( defined $cgi->param('session') ) {
33   my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) );
34
35   do_template('login', $login_info );
36   exit;
37 }
38
39 if ( $cgi->param('session') eq 'login' ) {
40
41   $cgi->param('username') =~ /^\s*([a-z0-9_\-\.\&]{0,$form_max})\s*$/i
42     or die "illegal username";
43   my $username = $1;
44
45   $cgi->param('domain') =~ /^\s*([\w\-\.]{0,$form_max})\s*$/
46     or die "illegal domain";
47   my $domain = $1;
48
49   $cgi->param('password') =~ /^(.{0,$form_max})$/
50     or die "illegal password";
51   my $password = $1;
52
53   my $rv = login(
54     'username' => $username,
55     'domain'   => $domain,
56     'password' => $password,
57   );
58   if ( $rv->{error} ) {
59     my $login_info = login_info( 'agentnum' => $cgi->param('agentnum') );
60     do_template('login', {
61       'error'    => $rv->{error},
62       'username' => $username,
63       'domain'   => $domain,
64       %$login_info,
65     } );
66     exit;
67   } else {
68     $cgi->param('session' => $rv->{session_id} );
69     $cgi->param('action'  => 'myaccount' );
70   }
71 }
72
73 $session_id = $cgi->param('session');
74
75 #order|pw_list XXX ???
76 my @actions = ( qw(
77   myaccount
78   tktcreate
79   tktview
80   didreport
81   invoices
82   view_invoice
83   make_payment
84   make_ach_payment
85   make_term_payment
86   make_thirdparty_payment
87   post_thirdparty_payment
88   payment_results
89   ach_payment_results
90   recharge_prepay
91   recharge_results
92   logout
93   change_bill
94   change_ship
95   change_pay
96   process_change_bill
97   process_change_ship
98   process_change_pay
99   customer_order_pkg
100   process_order_pkg
101   customer_change_pkg
102   process_change_pkg
103   process_order_recharge
104   provision
105   provision_svc
106   process_svc_acct
107   process_svc_phone
108   process_svc_external
109   delete_svc
110   view_usage
111   view_usage_details
112   view_cdr_details
113   view_support_details
114   change_password
115   process_change_password
116   customer_suspend_pkg
117   process_suspend_pkg
118 ));
119  
120 $cgi->param('action') =~ ( '^(' . join('|', @actions) . ')$' )
121   or die "unknown action ". $cgi->param('action');
122 my $action = $1;
123
124 warn "calling $action sub\n"
125   if $DEBUG;
126 $FS::SelfService::DEBUG = $DEBUG;
127 my $result = eval "&$action();";
128 die $@ if $@;
129
130 warn Dumper($result) if $DEBUG;
131
132 if ( $result->{error} && ( $result->{error} eq "Can't resume session"
133   || $result->{error} eq "Expired session") ) { #ick
134
135   my $login_info = login_info();
136   do_template('login', $login_info);
137   exit;
138 }
139
140 #warn $result->{'open_invoices'};
141 #warn scalar(@{$result->{'open_invoices'}});
142
143 warn "processing template $action\n"
144   if $DEBUG;
145 do_template($action, {
146   'session_id' => $session_id,
147   'action'     => $action, #so the menu knows what tab we're on...
148   #%{ payment_info( 'session_id' => $session_id ) },  # cust_paybys for the menu
149   %{$result}
150 });
151
152 #--
153
154 use Data::Dumper;
155 sub myaccount { 
156   customer_info( 'session_id' => $session_id ); 
157 }
158
159 sub change_bill { my $payment_info =
160                     payment_info( 'session_id' => $session_id );
161                   return $payment_info if ( $payment_info->{'error'} );
162                   my $customer_info =
163                     customer_info( 'session_id' => $session_id );
164                   return { 
165                     %$payment_info,
166                     %$customer_info,
167                   };
168                 }
169 sub change_ship { change_bill(@_); }
170 sub change_pay { change_bill(@_); }
171
172 sub _process_change_info { 
173   my ($erroraction, @fields) = @_;
174
175   my $results = '';
176
177   $results ||= edit_info (
178     'session_id' => $session_id,
179     map { ($_ => $cgi->param($_)) } grep { defined($cgi->param($_)) } @fields,
180   );
181
182
183   if ( $results->{'error'} ) {
184     no strict 'refs';
185     $action = $erroraction;
186     return {
187       $cgi->Vars,
188       %{&$action()},
189       'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
190     };
191   } else {
192     return $results;
193   }
194 }
195
196 sub process_change_bill {
197         _process_change_info( 'change_bill', 
198           qw( first last company address1 address2 city state
199               county zip country daytime night fax )
200         );
201 }
202
203 sub process_change_ship {
204         my @list = map { "ship_$_" }
205                      qw( first last company address1 address2 city state
206                          county zip country daytime night fax 
207                        );
208         if ($cgi->param('same') eq 'Y') {
209           foreach (@list) { $cgi->param($_, '') }
210         }
211
212         _process_change_info( 'change_ship', @list );
213 }
214
215 sub process_change_pay {
216         my $postal = $cgi->param( 'postal_invoicing' );
217         my $payby  = $cgi->param( 'payby' );
218         my @list =
219           qw( payby payinfo payinfo1 payinfo2 month year payname
220               address1 address2 city county state zip country auto paytype
221               paystate ss stateid stateid_state invoicing_list
222             );
223         push @list, 'postal_invoicing' if $postal;
224         unless (    $payby ne 'BILL'
225                  || $postal
226                  || $cgi->param( 'invoicing_list' )
227                )
228         {
229           $action = 'change_pay';
230           return {
231             %{&change_pay()},
232             $cgi->Vars,
233             'error' => '<FONT COLOR="#FF0000">Postal or email required.</FONT>',
234           };
235         }
236         _process_change_info( 'change_pay', @list );
237 }
238
239 sub view_invoice {
240
241   $cgi->param('invnum') =~ /^(\d+)$/ or die "illegal invnum";
242   my $invnum = $1;
243
244   invoice( 'session_id' => $session_id,
245            'invnum'     => $invnum,
246          );
247
248 }
249
250 sub invoices {
251   list_invoices( 'session_id' => $session_id, );
252 }
253
254 sub tktcreate {
255   my $customer_info = customer_info( 'session_id' => $session_id );
256   return $customer_info if ( $customer_info->{'error'} );
257
258   my $requestor = "";
259   if ( $customer_info->{'invoicing_list'} ) {
260     my @requestor = split( /\s*\,\s*/, $customer_info->{'invoicing_list'} );
261     $requestor = $requestor[0] if scalar(@requestor);
262   }
263
264   return { 'requestor' => $requestor }
265     unless ($cgi->param('subject') && $cgi->param('message') &&
266         length($cgi->param('subject')) && length($cgi->param('message')));
267     
268  create_ticket( 'session_id' => $session_id,
269                         'subject' => $cgi->param('subject'),
270                         'message' => $cgi->param('message'), 
271                         'requestor' => $requestor,
272             );
273 }
274
275 sub tktview {
276  get_ticket(    'session_id' => $session_id,
277                 'ticket_id' => $cgi->param('ticket_id'),
278                 'reply' => $cgi->param('reply'),
279             );
280 }
281
282 sub customer_order_pkg {
283   my $init_data = signup_info( 'customer_session_id' => $session_id );
284   return $init_data if ( $init_data->{'error'} );
285
286   my $customer_info = customer_info( 'session_id' => $session_id );
287   return $customer_info if ( $customer_info->{'error'} );
288
289   my $pkgselect = mason_comp(
290     'session_id' => $session_id,
291     'comp'       => '/edit/cust_main/first_pkg/select-part_pkg.html',
292     'args'       => [ 'password_verify' => 1,
293                       'onchange'        => 'enable_order_pkg()',
294                       'relurls'         => 1,
295                       'empty_label'     => 'Select package',
296                     ],
297   );
298
299   $pkgselect = $pkgselect->{'error'} || $pkgselect->{'output'};
300
301   return {
302     ( map { $_ => $init_data->{$_} }
303           qw( part_pkg security_phrase svc_acct_pop ),
304     ),
305     %$customer_info,
306     'pkg_selector' => $pkgselect,
307   };
308 }
309
310 sub customer_change_pkg {
311   my $init_data = signup_info( 'customer_session_id' => $session_id );
312   return $init_data if ( $init_data->{'error'} );
313
314   my $customer_info = customer_info( 'session_id' => $session_id );
315   return $customer_info if ( $customer_info->{'error'} );
316
317   return {
318     ( map { $_ => $init_data->{$_} }
319           qw( part_pkg security_phrase svc_acct_pop ),
320     ),
321     ( map { $_ => $cgi->param($_) }
322         qw( pkgnum pkg )
323     ),
324     %$customer_info,
325   };
326 }
327
328 sub process_order_pkg {
329
330   my $results = '';
331
332   my @params = (qw( custnum pkgpart ));
333   my $svcdb = '';
334   if ( $cgi->param('pkgpart_svcpart') =~ /^(\d+)_(\d+)$/ ) {
335     $cgi->param('pkgpart', $1);
336     $cgi->param('svcpart', $2);
337     push @params, 'svcpart';
338     $svcdb = $cgi->param('svcdb');
339     push @params, 'domsvc' if $svcdb eq 'svc_acct';
340   } else {
341     $svcdb = 'svc_acct';
342   }
343
344   if ( $svcdb eq 'svc_acct' ) {
345
346     push @params, qw( username _password _password2 sec_phrase popnum );
347
348     unless ( length($cgi->param('_password')) ) {
349       my $init_data = signup_info( 'customer_session_id' => $session_id );
350       $results = { 'error' => $init_data->{msgcat}{empty_password} };
351       $results = { 'error' => $init_data->{error} } if($init_data->{error});
352     }
353     if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
354       my $init_data = signup_info( 'customer_session_id' => $session_id );
355       $results = { 'error' => $init_data->{msgcat}{passwords_dont_match} };
356       $results = { 'error' => $init_data->{error} } if($init_data->{error});
357       $cgi->param('_password', '');
358       $cgi->param('_password2', '');
359     }
360
361   } elsif ( $svcdb eq 'svc_phone' ) {
362
363     push @params, qw( phonenum sip_password pin phone_name );
364
365   } else {
366     die "$svcdb not handled on process_order_pkg yet";
367   }
368
369   $results ||= order_pkg (
370     'session_id' => $session_id,
371     map { $_ => $cgi->param($_) } @params
372   );
373
374
375   if ( $results->{'error'} ) {
376     $action = 'customer_order_pkg';
377     return {
378       $cgi->Vars,
379       %{customer_order_pkg()},
380       'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
381     };
382   } else {
383     return $results;
384   }
385
386 }
387
388 sub process_change_pkg {
389
390   my $results = '';
391
392   $results ||= change_pkg (
393     'session_id' => $session_id,
394     map { $_ => $cgi->param($_) }
395         qw( pkgpart pkgnum )
396   );
397
398
399   if ( $results->{'error'} ) {
400     $action = 'customer_change_pkg';
401     return {
402       $cgi->Vars,
403       %{customer_change_pkg()},
404       'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
405     };
406   } else {
407     return $results;
408   }
409
410 }
411
412 sub process_suspend_pkg {
413   my $results = '';
414   $results = suspend_pkg (
415     'session_id' => $session_id,
416     map { $_ => $cgi->param($_) } 
417       qw( pkgnum )
418     );
419   if ( $results->{'error'} ) {
420     $action = 'provision';
421     return {
422       'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
423     }
424   }
425   else {
426     return $results;
427   }
428 }
429
430 sub process_order_recharge {
431
432   my $results = '';
433
434   $results ||= order_recharge (
435     'session_id' => $session_id,
436     map { $_ => $cgi->param($_) }
437         qw( svcnum )
438   );
439
440
441   if ( $results->{'error'} ) {
442     $action = 'view_usage';
443     if ($results->{'error'} eq '_decline') {
444       $results->{'error'} = "There has been an error processing your account.  Please contact customer support."
445     }
446     return {
447       $cgi->Vars,
448       %{view_usage()},
449       'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
450     };
451   } else {
452     return $results;
453   }
454
455 }
456
457 sub make_payment {
458   payment_info( 'session_id' => $session_id );
459 }
460
461 sub payment_results {
462
463   use Business::CreditCard 0.30;
464
465   #we should only do basic checking here for DoS attacks and things
466   #that couldn't be constructed by the web form...  let process_payment() do
467   #the rest, it gives better error messages
468
469   $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/
470     or die "Illegal amount: ". $cgi->param('amount'); #!!!
471   my $amount = $1;
472
473   my $payinfo = $cgi->param('payinfo');
474   $payinfo =~ s/[^\dx]//g;
475   $payinfo =~ /^([\dx]{13,16})$/
476     #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
477     or die "illegal card"; #!!!
478   $payinfo = $1;
479   unless ( $payinfo =~ /x/ ) {
480     validate($payinfo)
481       #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
482       or die "invalid card"; #!!!
483   }
484
485   if ( $cgi->param('card_type') ) {
486     cardtype($payinfo) eq $cgi->param('card_type')
487       #or $error ||= $init_data->{msgcat}{not_a}. $cgi->param('CARD_type');
488       or die "not a ". $cgi->param('card_type');
489   }
490
491   $cgi->param('paycvv') =~ /^\s*(.{0,4})\s*$/ or die "illegal CVV2";
492   my $paycvv = $1;
493
494   $cgi->param('month') =~ /^(\d{2})$/ or die "illegal month";
495   my $month = $1;
496   $cgi->param('year') =~ /^(\d{4})$/ or die "illegal year";
497   my $year = $1;
498
499   $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname";
500   my $payname = $1;
501
502   $cgi->param('address1') =~ /^(.{0,80})$/ or die "illegal address1";
503   my $address1 = $1;
504
505   $cgi->param('address2') =~ /^(.{0,80})$/ or die "illegal address2";
506   my $address2 = $1;
507
508   $cgi->param('city') =~ /^(.{0,80})$/ or die "illegal city";
509   my $city = $1;
510
511   $cgi->param('state') =~ /^(.{0,80})$/ or die "illegal state";
512   my $state = $1;
513
514   $cgi->param('zip') =~ /^(.{0,10})$/ or die "illegal zip";
515   my $zip = $1;
516
517   $cgi->param('country') =~ /^(.{0,2})$/ or die "illegal country";
518   my $country = $1;
519
520   my $save = 0;
521   $save = 1 if $cgi->param('save');
522
523   my $auto = 0;
524   $auto = 1 if $cgi->param('auto');
525
526   $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch";
527   my $paybatch = $1;
528
529   $cgi->param('discount_term') =~ /^(\d*)$/ or die "illegal discount_term";
530   my $discount_term = $1;
531
532
533   process_payment(
534     'session_id' => $session_id,
535     'payby'      => 'CARD',
536     'amount'     => $amount,
537     'payinfo'    => $payinfo,
538     'paycvv'     => $paycvv,
539     'month'      => $month,
540     'year'       => $year,
541     'payname'    => $payname,
542     'address1'   => $address1,
543     'address2'   => $address2,
544     'city'       => $city,
545     'state'      => $state,
546     'zip'        => $zip,
547     'country'    => $country,
548     'save'       => $save,
549     'auto'       => $auto,
550     'paybatch'   => $paybatch,
551     'discount_term' => $discount_term,
552   );
553
554 }
555
556 sub make_ach_payment {
557   payment_info( 'session_id' => $session_id );
558 }
559
560 sub ach_payment_results {
561
562   #we should only do basic checking here for DoS attacks and things
563   #that couldn't be constructed by the web form...  let process_payment() do
564   #the rest, it gives better error messages
565
566   $cgi->param('amount') =~ /^\s*(\d+(\.\d{2})?)\s*$/
567     or die "illegal amount"; #!!!
568   my $amount = $1;
569
570   my $payinfo1 = $cgi->param('payinfo1');
571   $payinfo1 =~ s/[^\dx]//g;
572   $payinfo1 =~ /^([\dx]+)$/
573     or die "illegal account"; #!!!
574   $payinfo1 = $1;
575
576   my $payinfo2 = $cgi->param('payinfo2');
577   $payinfo2 =~ s/[^\dx]//g;
578   $payinfo2 =~ /^([\dx]+)$/
579     or die "illegal ABA/routing code"; #!!!
580   $payinfo2 = $1;
581
582   $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname";
583   my $payname = $1;
584
585   $cgi->param('paystate') =~ /^(.{0,2})$/ or die "illegal paystate";
586   my $paystate = $1;
587
588   $cgi->param('paytype') =~ /^(.{0,80})$/ or die "illegal paytype";
589   my $paytype = $1;
590
591   $cgi->param('ss') =~ /^(.{0,80})$/ or die "illegal ss";
592   my $ss = $1;
593
594   $cgi->param('stateid') =~ /^(.{0,80})$/ or die "illegal stateid";
595   my $stateid = $1;
596
597   $cgi->param('stateid_state') =~ /^(.{0,2})$/ or die "illegal stateid_state";
598   my $stateid_state = $1;
599
600   my $save = 0;
601   $save = 1 if $cgi->param('save');
602
603   my $auto = 0;
604   $auto = 1 if $cgi->param('auto');
605
606   $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch";
607   my $paybatch = $1;
608
609   process_payment(
610     'session_id' => $session_id,
611     'payby'      => 'CHEK',
612     'amount'     => $amount,
613     'payinfo1'   => $payinfo1,
614     'payinfo2'   => $payinfo2,
615     'month'      => '12',
616     'year'       => '2037',
617     'payname'    => $payname,
618     'paytype'    => $paytype,
619     'paystate'   => $paystate,
620     'ss'         => $ss,
621     'stateid'    => $stateid,
622     'stateid_state' => $stateid_state,
623     'save'       => $save,
624     'auto'       => $auto,
625     'paybatch'   => $paybatch,
626   );
627
628 }
629
630 sub make_thirdparty_payment {
631   payment_info('session_id' => $session_id);
632 }
633
634 sub post_thirdparty_payment {
635   $cgi->param('payby_method') =~ /^(CC|ECHECK)$/
636     or die "illegal payby method";
637   my $method = $1;
638   $cgi->param('amount') =~ /^(\d+(\.\d*)?)$/
639     or die "illegal amount";
640   my $amount = $1;
641   my $result = realtime_collect( 
642     'session_id' => $session_id,
643     'method' => $method, 
644     'amount' => $amount,
645   );
646   $result;
647 }
648
649 sub make_term_payment {
650   $cgi->param('amount') =~ /^(\d+\.\d{2})$/
651     or die "illegal payment amount";
652   my $balance = $1;
653   $cgi->param('discount_term') =~ /^(\d+)$/
654     or die "illegal discount term";
655   my $discount_term = $1;
656   $action = 'make_payment';
657   ({ %{payment_info( 'session_id' => $session_id )},
658     'balance' => $balance,
659     'discount_term' => $discount_term,
660   })
661 }
662
663 sub recharge_prepay {
664   customer_info( 'session_id' => $session_id );
665 }
666
667 sub recharge_results {
668
669   my $prepaid_cardnum = $cgi->param('prepaid_cardnum');
670   $prepaid_cardnum =~ s/\W//g;
671   $prepaid_cardnum =~ /^(\w*)$/ or die "illegal prepaid card number";
672   $prepaid_cardnum = $1;
673
674   process_prepay ( 'session_id'     => $session_id,
675                    'prepaid_cardnum' => $prepaid_cardnum,
676                  );
677 }
678
679 sub logout {
680   FS::SelfService::logout( 'session_id' => $session_id );
681 }
682
683 sub didreport {
684   my $result = did_report( 'session_id' => $session_id, 
685             'format' => $cgi->param('type'),
686             'recentonly' => $cgi->param('recentonly'),
687         );
688   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
689   $result;
690 }
691
692 sub provision {
693   my $result = list_pkgs( 'session_id' => $session_id );
694   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
695   $result->{'pkgpart'} = $cgi->param('pkgpart') if $cgi->param('pkgpart');
696   $result->{'filter'} = $cgi->param('filter') if $cgi->param('filter');
697   $result;
698 }
699
700 sub provision_svc {
701
702   my $result = part_svc_info(
703     'session_id' => $session_id,
704     map { $_ => $cgi->param($_) } qw( pkgnum svcpart ),
705   );
706   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
707
708   $result->{'svcdb'} =~ /^svc_(.*)$/
709     #or return { 'error' => 'Unknown svcdb '. $result->{'svcdb'} };
710     or die 'Unknown svcdb '. $result->{'svcdb'};
711   $action .= "_$1";
712
713   $result->{'numavail'} = $cgi->param('numavail');
714   $result->{'lnp'} = $cgi->param('lnp');
715
716   $result;
717 }
718
719 sub process_svc_phone {
720     my @bulkdid = $cgi->param('bulkdid');
721     my $phonenum = $cgi->param('phonenum');
722     my $lnp = $cgi->param('lnp');
723
724     my $result;
725     if($lnp) {
726         $result = provision_phone (
727             'session_id' => $session_id,
728             'countrycode' => '1',
729              map { $_ => $cgi->param($_) } qw( pkgnum svcpart phonenum 
730                 lnp_desired_due_date lnp_other_provider 
731                 lnp_other_provider_account )
732         );
733     } else {
734         $result = provision_phone (
735             'session_id' => $session_id,
736             'bulkdid' => [ @bulkdid ],
737             'countrycode' => '1',
738              map { $_ => $cgi->param($_) } qw( pkgnum svcpart phonenum )
739         );
740     }
741
742     if ( exists $result->{'error'} && $result->{'error'} ) { 
743         $action = 'provision_svc_phone';
744         return {
745           $cgi->Vars,
746           %{ part_svc_info( 'session_id' => $session_id,
747                         map { $_ => $cgi->param($_) } qw( pkgnum svcpart )
748               )
749           },
750           'error' => $result->{'error'},
751         };
752   }
753
754   $result;
755 }
756
757 sub process_svc_acct {
758
759   my $result = provision_acct (
760     'session_id' => $session_id,
761     map { $_ => $cgi->param($_) } qw(
762       pkgnum svcpart username domsvc _password _password2 sec_phrase popnum )
763   );
764
765   if ( exists $result->{'error'} && $result->{'error'} ) { 
766     #warn "$result $result->{'error'}"; 
767     $action = 'provision_svc_acct';
768     return {
769       $cgi->Vars,
770       %{ part_svc_info( 'session_id' => $session_id,
771                         map { $_ => $cgi->param($_) } qw( pkgnum svcpart )
772                       )
773       },
774       'error' => $result->{'error'},
775     };
776   } else {
777     #warn "$result $result->{'error'}"; 
778     return $result;
779   }
780
781 }
782
783 sub process_svc_external {
784   provision_external (
785     'session_id' => $session_id,
786     map { $_ => $cgi->param($_) } qw( pkgnum svcpart )
787   );
788 }
789
790 sub delete_svc {
791   unprovision_svc(
792     'session_id' => $session_id,
793     'svcnum'     => $cgi->param('svcnum'),
794   );
795 }
796
797 sub view_usage {
798   list_svcs(
799     'session_id'  => $session_id,
800     'svcdb'       => [ 'svc_acct', 'svc_phone', 'svc_port', ],
801     'ncancelled'  => 1,
802   );
803 }
804
805 sub view_usage_details {
806    my $svcnum = $cgi->param('svcnum');
807
808     # for svc_port graphs
809     if($cgi->param($svcnum.'_start') && $cgi->param($svcnum.'_end')) {
810         return port_graph(
811             'session_id'  => $session_id,
812             'svcnum'      => $svcnum,
813             'start'       => str2time($cgi->param($svcnum.'_start')),
814             'end'       => str2time($cgi->param($svcnum.'_end')),
815             );
816     }
817     else {
818       return list_svc_usage(
819         'session_id'  => $session_id,
820         'svcnum'      => $svcnum,
821         'beginning'   => $cgi->param('beginning') || '',
822         'ending'      => $cgi->param('ending') || '',
823       );
824     }
825 }
826
827 sub view_cdr_details {
828   list_cdr_usage(
829     'session_id'  => $session_id,
830     'svcnum'      => $cgi->param('svcnum'),
831     'beginning'   => $cgi->param('beginning') || '',
832     'ending'      => $cgi->param('ending') || '',
833   );
834 }
835
836 sub view_support_details {
837   list_support_usage(
838     'session_id'  => $session_id,
839     'svcnum'      => $cgi->param('svcnum'),
840     'beginning'   => $cgi->param('beginning') || '',
841     'ending'      => $cgi->param('ending') || '',
842   );
843 }
844
845 sub change_password {
846   list_svcs(
847     'session_id' => $session_id,
848     'svcdb'      => 'svc_acct',
849   );
850 };
851
852 sub process_change_password {
853
854   my $result = myaccount_passwd(
855     'session_id'    => $session_id,
856     map { $_ => $cgi->param($_) } qw( svcnum new_password new_password2 )
857   );
858
859   if ( exists $result->{'error'} && $result->{'error'} ) { 
860
861     $action = 'change_password';
862     return {
863       $cgi->Vars,
864       %{ list_svcs( 'session_id' => $session_id,
865                     'svcdb'      => 'svc_acct',
866                   )
867        },
868       #'svcnum' => $cgi->param('svcnum'),
869       'error'  => $result->{'error'}
870     };
871
872  } else {
873
874    return $result;
875
876  }
877
878 }
879
880 #--
881
882 sub do_template {
883   my $name = shift;
884   my $fill_in = shift;
885
886   $cgi->delete_all();
887   $fill_in->{'selfurl'} = $cgi->self_url;
888   $fill_in->{'cgi'} = \$cgi;
889
890   my $access_info = $session_id
891                       ? access_info( 'session_id' => $session_id )
892                       : {};
893   $fill_in->{$_} = $access_info->{$_} foreach keys %$access_info;
894
895   my $source = "$template_dir/$name.html";
896   #warn "creating template for $source\n";
897   my $template = new Text::Template( TYPE       => 'FILE',
898                                      SOURCE     => $source,
899                                      DELIMITERS => [ '<%=', '%>' ],
900                                      UNTAINT    => 1,
901                                    )
902     or die $Text::Template::ERROR;
903
904     if($result && ref($result) && $result->{'format'} && $result->{'content'}
905         && $result->{'format'} eq 'csv') {
906         print $cgi->header('-expires' => 'now',
907                 '-Content-Type' => 'text/csv',
908                 '-Content-Disposition' => "attachment;filename=output.csv",
909                 ),
910             $result->{'content'};
911     }
912     elsif($result && ref($result) && $result->{'format'} && $result->{'content'}
913          && $result->{'format'} eq 'xls') {
914         print $cgi->header('-expires' => 'now',
915                     '-Content-Type' => 'application/vnd.ms-excel',
916                     '-Content-Disposition' => "attachment;filename=output.xls",
917                     '-Content-Length' => length($result->{'content'}),
918                     ),
919                     $result->{'content'};
920     }
921     else {
922         my $data = $template->fill_in( 
923             PACKAGE => 'FS::SelfService::_selfservicecgi',
924             HASH    => $fill_in,
925           ) || "Error processing template $source"; # at least print _something_
926           print $cgi->header( '-expires' => 'now' );
927           print $data;
928     }
929  }
930
931 #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file;
932
933 package FS::SelfService::_selfservicecgi;
934
935 use HTML::Entities;
936 use FS::SelfService qw(
937     regionselector popselector domainselector location_form didselector
938 );
939
940 #false laziness w/agent.cgi
941 use vars qw(@INCLUDE_ARGS);
942 sub include {
943   my $name = shift;
944
945   @INCLUDE_ARGS = @_;
946
947   my $template = new Text::Template( TYPE   => 'FILE',
948                                      SOURCE => "$main::template_dir/$name.html",
949                                      DELIMITERS => [ '<%=', '%>' ],
950                                      UNTAINT => 1,                   
951                                    )
952     or die $Text::Template::ERROR;
953
954   $template->fill_in( PACKAGE => 'FS::SelfService::_selfservicecgi',
955                       #HASH    => $fill_in
956                     );
957
958 }
959
960 1;