view/set svc_phone forwardst and email from self-service, RT13622
[freeside.git] / fs_selfservice / FS-SelfService / cgi / selfservice.cgi
index 36557b6..8f1c4a5 100644 (file)
@@ -8,27 +8,32 @@ use CGI::Carp qw(fatalsToBrowser);
 use Text::Template;
 use HTML::Entities;
 use Date::Format;
 use Text::Template;
 use HTML::Entities;
 use Date::Format;
+use Date::Parse 'str2time';
 use Number::Format 1.50;
 use Number::Format 1.50;
-use FS::SelfService qw( login customer_info edit_info invoice
-                        payment_info process_payment 
-                        process_prepay
-                        list_pkgs order_pkg signup_info order_recharge
-                        part_svc_info provision_acct provision_external
-                        unprovision_svc change_pkg domainselector
-                        list_svcs list_svc_usage list_support_usage
-                        myaccount_passwd
-                      );
+use FS::SelfService qw(
+  access_info login_info login customer_info edit_info invoice
+  payment_info process_payment realtime_collect process_prepay
+  list_pkgs order_pkg signup_info order_recharge
+  part_svc_info provision_acct provision_external provision_phone
+  unprovision_svc change_pkg suspend_pkg domainselector
+  list_svcs list_svc_usage list_cdr_usage list_support_usage
+  myaccount_passwd list_invoices create_ticket get_ticket did_report
+  adjust_ticket_priority
+  mason_comp port_graph
+);
 
 $template_dir = '.';
 
 
 $template_dir = '.';
 
-$DEBUG = 1;
+$DEBUG = 0;
 
 $form_max = 255;
 
 $cgi = new CGI;
 
 unless ( defined $cgi->param('session') ) {
 
 $form_max = 255;
 
 $cgi = new CGI;
 
 unless ( defined $cgi->param('session') ) {
-  do_template('login',{});
+  my $login_info = login_info( 'agentnum' => scalar($cgi->param('agentnum')) );
+
+  do_template('login', $login_info );
   exit;
 }
 
   exit;
 }
 
@@ -52,10 +57,12 @@ if ( $cgi->param('session') eq 'login' ) {
     'password' => $password,
   );
   if ( $rv->{error} ) {
     'password' => $password,
   );
   if ( $rv->{error} ) {
+    my $login_info = login_info( 'agentnum' => $cgi->param('agentnum') );
     do_template('login', {
       'error'    => $rv->{error},
       'username' => $username,
       'domain'   => $domain,
     do_template('login', {
       'error'    => $rv->{error},
       'username' => $username,
       'domain'   => $domain,
+      %$login_info,
     } );
     exit;
   } else {
     } );
     exit;
   } else {
@@ -67,8 +74,54 @@ if ( $cgi->param('session') eq 'login' ) {
 $session_id = $cgi->param('session');
 
 #order|pw_list XXX ???
 $session_id = $cgi->param('session');
 
 #order|pw_list XXX ???
-$cgi->param('action') =~
-    /^(myaccount|view_invoice|make_payment|make_ach_payment|payment_results|ach_payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|change_pay|process_change_bill|process_change_ship|process_change_pay|customer_order_pkg|process_order_pkg|customer_change_pkg|process_change_pkg|process_order_recharge|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|view_usage|view_usage_details|view_support_details|change_password|process_change_password)$/
+my @actions = ( qw(
+  myaccount
+  tktcreate
+  tktview
+  ticket_priority
+  didreport
+  invoices
+  view_invoice
+  make_payment
+  make_ach_payment
+  make_term_payment
+  make_thirdparty_payment
+  post_thirdparty_payment
+  payment_results
+  ach_payment_results
+  recharge_prepay
+  recharge_results
+  logout
+  change_bill
+  change_ship
+  change_pay
+  process_change_bill
+  process_change_ship
+  process_change_pay
+  customer_order_pkg
+  process_order_pkg
+  customer_change_pkg
+  process_change_pkg
+  process_order_recharge
+  provision
+  provision_svc
+  process_svc_acct
+  process_svc_phone
+  process_svc_external
+  delete_svc
+  view_usage
+  view_usage_details
+  view_cdr_details
+  view_support_details
+  view_port_graph
+  real_port_graph
+  change_password
+  process_change_password
+  customer_suspend_pkg
+  process_suspend_pkg
+));
+$cgi->param('action') =~ ( '^(' . join('|', @actions) . ')$' )
   or die "unknown action ". $cgi->param('action');
 my $action = $1;
 
   or die "unknown action ". $cgi->param('action');
 my $action = $1;
 
@@ -78,10 +131,13 @@ $FS::SelfService::DEBUG = $DEBUG;
 my $result = eval "&$action();";
 die $@ if $@;
 
 my $result = eval "&$action();";
 die $@ if $@;
 
-if ( $result->{error} eq "Can't resume session"
-  || $result->{error} eq "Expired session" ) { #ick
+warn Dumper($result) if $DEBUG;
+
+if ( $result->{error} && ( $result->{error} eq "Can't resume session"
+  || $result->{error} eq "Expired session") ) { #ick
 
 
-  do_template('login',{});
+  my $login_info = login_info();
+  do_template('login', $login_info);
   exit;
 }
 
   exit;
 }
 
@@ -93,12 +149,16 @@ warn "processing template $action\n"
 do_template($action, {
   'session_id' => $session_id,
   'action'     => $action, #so the menu knows what tab we're on...
 do_template($action, {
   'session_id' => $session_id,
   'action'     => $action, #so the menu knows what tab we're on...
+  #%{ payment_info( 'session_id' => $session_id ) },  # cust_paybys for the menu
   %{$result}
 });
 
 #--
 
   %{$result}
 });
 
 #--
 
-sub myaccount { customer_info( 'session_id' => $session_id ); }
+use Data::Dumper;
+sub myaccount { 
+  customer_info( 'session_id' => $session_id ); 
+}
 
 sub change_bill { my $payment_info =
                     payment_info( 'session_id' => $session_id );
 
 sub change_bill { my $payment_info =
                     payment_info( 'session_id' => $session_id );
@@ -140,7 +200,7 @@ sub _process_change_info {
 sub process_change_bill {
         _process_change_info( 'change_bill', 
           qw( first last company address1 address2 city state
 sub process_change_bill {
         _process_change_info( 'change_bill', 
           qw( first last company address1 address2 city state
-              county state zip country daytime night fax )
+              county zip country daytime night fax )
         );
 }
 
         );
 }
 
@@ -157,11 +217,27 @@ sub process_change_ship {
 }
 
 sub process_change_pay {
 }
 
 sub process_change_pay {
-        _process_change_info( 'change_pay', 
+        my $postal = $cgi->param( 'postal_invoicing' );
+        my $payby  = $cgi->param( 'payby' );
+        my @list =
           qw( payby payinfo payinfo1 payinfo2 month year payname
               address1 address2 city county state zip country auto paytype
           qw( payby payinfo payinfo1 payinfo2 month year payname
               address1 address2 city county state zip country auto paytype
-              paystate ss stateid stateid_state )
-        );
+              paystate ss stateid stateid_state invoicing_list
+            );
+        push @list, 'postal_invoicing' if $postal;
+        unless (    $payby ne 'BILL'
+                 || $postal
+                 || $cgi->param( 'invoicing_list' )
+               )
+        {
+          $action = 'change_pay';
+          return {
+            %{&change_pay()},
+            $cgi->Vars,
+            'error' => '<FONT COLOR="#FF0000">Postal or email required.</FONT>',
+          };
+        }
+        _process_change_info( 'change_pay', @list );
 }
 
 sub view_invoice {
 }
 
 sub view_invoice {
@@ -175,6 +251,55 @@ sub view_invoice {
 
 }
 
 
 }
 
+sub invoices {
+  list_invoices( 'session_id' => $session_id, );
+}
+
+sub tktcreate {
+  my $customer_info = customer_info( 'session_id' => $session_id );
+  return $customer_info if ( $customer_info->{'error'} );
+
+  my $requestor = "";
+  if ( $customer_info->{'invoicing_list'} ) {
+    my @requestor = split( /\s*\,\s*/, $customer_info->{'invoicing_list'} );
+    $requestor = $requestor[0] if scalar(@requestor);
+  }
+
+  return { 'requestor' => $requestor }
+    unless ($cgi->param('subject') && $cgi->param('message') &&
+       length($cgi->param('subject')) && length($cgi->param('message')));
+    
+ create_ticket(        'session_id' => $session_id,
+                       'subject' => $cgi->param('subject'),
+                       'message' => $cgi->param('message'), 
+                       'requestor' => $requestor,
+           );
+}
+
+sub tktview {
+ get_ticket(   'session_id' => $session_id,
+               'ticket_id' => ($cgi->param('ticket_id') || ''),
+                'subject'   => ($cgi->param('subject') || ''),
+               'reply'     => ($cgi->param('reply') || ''),
+           );
+}
+
+sub ticket_priority {
+  my %values;
+  foreach ( $cgi->param ) {
+    if ( /^ticket(\d+)$/ ) {
+      # a 'ticket1001' param implies the existence of a 'priority1001' param
+      # but if that's empty, we need to send it as empty rather than forget
+      # it.
+      $values{$1} = $cgi->param("priority$1") || '';
+    }
+  }
+  $action = 'myaccount';
+  # this returns an updated customer_info for myaccount
+  adjust_ticket_priority( 'session_id' => $session_id,
+                          'values'     => \%values );
+}
+
 sub customer_order_pkg {
   my $init_data = signup_info( 'customer_session_id' => $session_id );
   return $init_data if ( $init_data->{'error'} );
 sub customer_order_pkg {
   my $init_data = signup_info( 'customer_session_id' => $session_id );
   return $init_data if ( $init_data->{'error'} );
@@ -182,11 +307,24 @@ sub customer_order_pkg {
   my $customer_info = customer_info( 'session_id' => $session_id );
   return $customer_info if ( $customer_info->{'error'} );
 
   my $customer_info = customer_info( 'session_id' => $session_id );
   return $customer_info if ( $customer_info->{'error'} );
 
+  my $pkgselect = mason_comp(
+    'session_id' => $session_id,
+    'comp'       => '/edit/cust_main/first_pkg/select-part_pkg.html',
+    'args'       => [ 'password_verify' => 1,
+                      'onchange'        => 'enable_order_pkg()',
+                      'relurls'         => 1,
+                      'empty_label'     => 'Select package',
+                    ],
+  );
+
+  $pkgselect = $pkgselect->{'error'} || $pkgselect->{'output'};
+
   return {
     ( map { $_ => $init_data->{$_} }
           qw( part_pkg security_phrase svc_acct_pop ),
     ),
     %$customer_info,
   return {
     ( map { $_ => $init_data->{$_} }
           qw( part_pkg security_phrase svc_acct_pop ),
     ),
     %$customer_info,
+    'pkg_selector' => $pkgselect,
   };
 }
 
   };
 }
 
@@ -212,23 +350,46 @@ sub process_order_pkg {
 
   my $results = '';
 
 
   my $results = '';
 
-  unless ( length($cgi->param('_password')) ) {
-    my $init_data = signup_info( 'customer_session_id' => $session_id );
-    $results = { 'error' => $init_data->{msgcat}{empty_password} };
-    $results = { 'error' => $init_data->{error} } if($init_data->{error});
+  my @params = (qw( custnum pkgpart ));
+  my $svcdb = '';
+  if ( $cgi->param('pkgpart_svcpart') =~ /^(\d+)_(\d+)$/ ) {
+    $cgi->param('pkgpart', $1);
+    $cgi->param('svcpart', $2);
+    push @params, 'svcpart';
+    $svcdb = $cgi->param('svcdb');
+    push @params, 'domsvc' if $svcdb eq 'svc_acct';
+  } else {
+    $svcdb = 'svc_acct';
   }
   }
-  if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
-    my $init_data = signup_info( 'customer_session_id' => $session_id );
-    $results = { 'error' => $init_data->{msgcat}{passwords_dont_match} };
-    $results = { 'error' => $init_data->{error} } if($init_data->{error});
-    $cgi->param('_password', '');
-    $cgi->param('_password2', '');
+
+  if ( $svcdb eq 'svc_acct' ) {
+
+    push @params, qw( username _password _password2 sec_phrase popnum );
+
+    unless ( length($cgi->param('_password')) ) {
+      my $init_data = signup_info( 'customer_session_id' => $session_id );
+      $results = { 'error' => $init_data->{msgcat}{empty_password} };
+      $results = { 'error' => $init_data->{error} } if($init_data->{error});
+    }
+    if ( $cgi->param('_password') ne $cgi->param('_password2') ) {
+      my $init_data = signup_info( 'customer_session_id' => $session_id );
+      $results = { 'error' => $init_data->{msgcat}{passwords_dont_match} };
+      $results = { 'error' => $init_data->{error} } if($init_data->{error});
+      $cgi->param('_password', '');
+      $cgi->param('_password2', '');
+    }
+
+  } elsif ( $svcdb eq 'svc_phone' ) {
+
+    push @params, qw( phonenum sip_password pin phone_name );
+
+  } else {
+    die "$svcdb not handled on process_order_pkg yet";
   }
 
   $results ||= order_pkg (
     'session_id' => $session_id,
   }
 
   $results ||= order_pkg (
     'session_id' => $session_id,
-    map { $_ => $cgi->param($_) }
-        qw( custnum pkgpart username _password _password2 sec_phrase popnum )
+    map { $_ => $cgi->param($_) } @params
   );
 
 
   );
 
 
@@ -269,6 +430,24 @@ sub process_change_pkg {
 
 }
 
 
 }
 
+sub process_suspend_pkg {
+  my $results = '';
+  $results = suspend_pkg (
+    'session_id' => $session_id,
+    map { $_ => $cgi->param($_) } 
+      qw( pkgnum )
+    );
+  if ( $results->{'error'} ) {
+    $action = 'provision';
+    return {
+      'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
+    }
+  }
+  else {
+    return $results;
+  }
+}
+
 sub process_order_recharge {
 
   my $results = '';
 sub process_order_recharge {
 
   my $results = '';
@@ -302,7 +481,7 @@ sub make_payment {
 
 sub payment_results {
 
 
 sub payment_results {
 
-  use Business::CreditCard;
+  use Business::CreditCard 0.30;
 
   #we should only do basic checking here for DoS attacks and things
   #that couldn't be constructed by the web form...  let process_payment() do
 
   #we should only do basic checking here for DoS attacks and things
   #that couldn't be constructed by the web form...  let process_payment() do
@@ -313,14 +492,16 @@ sub payment_results {
   my $amount = $1;
 
   my $payinfo = $cgi->param('payinfo');
   my $amount = $1;
 
   my $payinfo = $cgi->param('payinfo');
-  $payinfo =~ s/\D//g;
-  $payinfo =~ /^(\d{13,16})$/
+  $payinfo =~ s/[^\dx]//g;
+  $payinfo =~ /^([\dx]{13,16})$/
     #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
     or die "illegal card"; #!!!
   $payinfo = $1;
     #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
     or die "illegal card"; #!!!
   $payinfo = $1;
-  validate($payinfo)
-    #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
-    or die "invalid card"; #!!!
+  unless ( $payinfo =~ /x/ ) {
+    validate($payinfo)
+      #or $error ||= $init_data->{msgcat}{invalid_card}; #. $self->payinfo;
+      or die "invalid card"; #!!!
+  }
 
   if ( $cgi->param('card_type') ) {
     cardtype($payinfo) eq $cgi->param('card_type')
 
   if ( $cgi->param('card_type') ) {
     cardtype($payinfo) eq $cgi->param('card_type')
@@ -348,12 +529,15 @@ sub payment_results {
   $cgi->param('city') =~ /^(.{0,80})$/ or die "illegal city";
   my $city = $1;
 
   $cgi->param('city') =~ /^(.{0,80})$/ or die "illegal city";
   my $city = $1;
 
-  $cgi->param('state') =~ /^(.{2})$/ or die "illegal state";
+  $cgi->param('state') =~ /^(.{0,80})$/ or die "illegal state";
   my $state = $1;
 
   $cgi->param('zip') =~ /^(.{0,10})$/ or die "illegal zip";
   my $zip = $1;
 
   my $state = $1;
 
   $cgi->param('zip') =~ /^(.{0,10})$/ or die "illegal zip";
   my $zip = $1;
 
+  $cgi->param('country') =~ /^(.{0,2})$/ or die "illegal country";
+  my $country = $1;
+
   my $save = 0;
   $save = 1 if $cgi->param('save');
 
   my $save = 0;
   $save = 1 if $cgi->param('save');
 
@@ -363,6 +547,10 @@ sub payment_results {
   $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch";
   my $paybatch = $1;
 
   $cgi->param('paybatch') =~ /^([\w\-\.]+)$/ or die "illegal paybatch";
   my $paybatch = $1;
 
+  $cgi->param('discount_term') =~ /^(\d*)$/ or die "illegal discount_term";
+  my $discount_term = $1;
+
+
   process_payment(
     'session_id' => $session_id,
     'payby'      => 'CARD',
   process_payment(
     'session_id' => $session_id,
     'payby'      => 'CARD',
@@ -377,9 +565,11 @@ sub payment_results {
     'city'       => $city,
     'state'      => $state,
     'zip'        => $zip,
     'city'       => $city,
     'state'      => $state,
     'zip'        => $zip,
+    'country'    => $country,
     'save'       => $save,
     'auto'       => $auto,
     'paybatch'   => $paybatch,
     'save'       => $save,
     'auto'       => $auto,
     'paybatch'   => $paybatch,
+    'discount_term' => $discount_term,
   );
 
 }
   );
 
 }
@@ -399,14 +589,16 @@ sub ach_payment_results {
   my $amount = $1;
 
   my $payinfo1 = $cgi->param('payinfo1');
   my $amount = $1;
 
   my $payinfo1 = $cgi->param('payinfo1');
-  $payinfo1=~ /^(\d+)$/
+  $payinfo1 =~ s/[^\dx]//g;
+  $payinfo1 =~ /^([\dx]+)$/
     or die "illegal account"; #!!!
     or die "illegal account"; #!!!
-  $payinfo1= $1;
+  $payinfo1 = $1;
 
   my $payinfo2 = $cgi->param('payinfo2');
 
   my $payinfo2 = $cgi->param('payinfo2');
-  $payinfo2=~ /^(\d+)$/
+  $payinfo2 =~ s/[^\dx]//g;
+  $payinfo2 =~ /^([\dx]+)$/
     or die "illegal ABA/routing code"; #!!!
     or die "illegal ABA/routing code"; #!!!
-  $payinfo2= $1;
+  $payinfo2 = $1;
 
   $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname";
   my $payname = $1;
 
   $cgi->param('payname') =~ /^(.{0,80})$/ or die "illegal payname";
   my $payname = $1;
@@ -456,6 +648,39 @@ sub ach_payment_results {
 
 }
 
 
 }
 
+sub make_thirdparty_payment {
+  payment_info('session_id' => $session_id);
+}
+
+sub post_thirdparty_payment {
+  $cgi->param('payby_method') =~ /^(CC|ECHECK)$/
+    or die "illegal payby method";
+  my $method = $1;
+  $cgi->param('amount') =~ /^(\d+(\.\d*)?)$/
+    or die "illegal amount";
+  my $amount = $1;
+  my $result = realtime_collect( 
+    'session_id' => $session_id,
+    'method' => $method, 
+    'amount' => $amount,
+  );
+  $result;
+}
+
+sub make_term_payment {
+  $cgi->param('amount') =~ /^(\d+\.\d{2})$/
+    or die "illegal payment amount";
+  my $balance = $1;
+  $cgi->param('discount_term') =~ /^(\d+)$/
+    or die "illegal discount term";
+  my $discount_term = $1;
+  $action = 'make_payment';
+  ({ %{payment_info( 'session_id' => $session_id )},
+    'balance' => $balance,
+    'discount_term' => $discount_term,
+  })
+}
+
 sub recharge_prepay {
   customer_info( 'session_id' => $session_id );
 }
 sub recharge_prepay {
   customer_info( 'session_id' => $session_id );
 }
@@ -476,9 +701,20 @@ sub logout {
   FS::SelfService::logout( 'session_id' => $session_id );
 }
 
   FS::SelfService::logout( 'session_id' => $session_id );
 }
 
+sub didreport {
+  my $result = did_report( 'session_id' => $session_id, 
+           'format' => $cgi->param('type'),
+           'recentonly' => $cgi->param('recentonly'),
+       );
+  die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
+  $result;
+}
+
 sub provision {
   my $result = list_pkgs( 'session_id' => $session_id );
   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
 sub provision {
   my $result = list_pkgs( 'session_id' => $session_id );
   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
+  $result->{'pkgpart'} = $cgi->param('pkgpart') if $cgi->param('pkgpart');
+  $result->{'filter'} = $cgi->param('filter') if $cgi->param('filter');
   $result;
 }
 
   $result;
 }
 
@@ -486,7 +722,7 @@ sub provision_svc {
 
   my $result = part_svc_info(
     'session_id' => $session_id,
 
   my $result = part_svc_info(
     'session_id' => $session_id,
-    map { $_ => $cgi->param($_) } qw( pkgnum svcpart ),
+    map { $_ => $cgi->param($_) } qw( pkgnum svcpart svcnum ),
   );
   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
 
   );
   die $result->{'error'} if exists $result->{'error'} && $result->{'error'};
 
@@ -495,6 +731,47 @@ sub provision_svc {
     or die 'Unknown svcdb '. $result->{'svcdb'};
   $action .= "_$1";
 
     or die 'Unknown svcdb '. $result->{'svcdb'};
   $action .= "_$1";
 
+  $result->{'numavail'} = $cgi->param('numavail');
+  $result->{'lnp'} = $cgi->param('lnp');
+
+  $result;
+}
+
+sub process_svc_phone {
+    my @bulkdid = $cgi->param('bulkdid');
+    my $phonenum = $cgi->param('phonenum');
+    my $lnp = $cgi->param('lnp');
+
+    my $result;
+    if($lnp) {
+       $result = provision_phone (
+           'session_id' => $session_id,
+           'countrycode' => '1',
+            map { $_ => $cgi->param($_) } qw( pkgnum svcpart phonenum 
+               lnp_desired_due_date lnp_other_provider 
+               lnp_other_provider_account )
+       );
+    } else {
+       $result = provision_phone (
+           'session_id' => $session_id,
+           'bulkdid' => [ @bulkdid ],
+           'countrycode' => '1',
+            map { $_ => $cgi->param($_) } qw( pkgnum svcpart phonenum svcnum email forwarddst )
+       );
+    }
+
+    if ( exists $result->{'error'} && $result->{'error'} ) { 
+       $action = 'provision_svc_phone';
+       return {
+         $cgi->Vars,
+         %{ part_svc_info( 'session_id' => $session_id,
+                        map { $_ => $cgi->param($_) } qw( pkgnum svcpart svcnum )
+             )
+         },
+         'error' => $result->{'error'},
+       };
+  }
+
   $result;
 }
 
   $result;
 }
 
@@ -541,13 +818,43 @@ sub delete_svc {
 sub view_usage {
   list_svcs(
     'session_id'  => $session_id,
 sub view_usage {
   list_svcs(
     'session_id'  => $session_id,
-    'svcdb'       => 'svc_acct',
+    'svcdb'       => [ 'svc_acct', 'svc_phone', 'svc_port', ],
     'ncancelled'  => 1,
   );
 }
 
     'ncancelled'  => 1,
   );
 }
 
+sub real_port_graph {
+    my $svcnum = $cgi->param('svcnum');
+    my $res = port_graph(
+           'session_id'  => $session_id,
+           'svcnum'      => $svcnum,
+           'beginning'   => str2time($cgi->param('start')." 00:00:00"),
+           'ending'    => str2time($cgi->param('end')." 23:59:59"),
+           );
+    my @usage = @{$res->{'usage'}};
+    my $png = $usage[0]->{'png'};
+    { 'content' => $png, 'format' => 'png' };
+}
+
+sub view_port_graph {
+    my $svcnum = $cgi->param('svcnum');
+    { 'svcnum' => $svcnum,
+      'start' => $cgi->param($svcnum.'_start'),
+      'end' => $cgi->param($svcnum.'_end'),
+    }
+}
+
 sub view_usage_details {
 sub view_usage_details {
-  list_svc_usage(
+      list_svc_usage(
+       'session_id'  => $session_id,
+       'svcnum'      => $cgi->param('svcnum'),
+       'beginning'   => $cgi->param('beginning') || '',
+       'ending'      => $cgi->param('ending') || '',
+      );
+}
+
+sub view_cdr_details {
+  list_cdr_usage(
     'session_id'  => $session_id,
     'svcnum'      => $cgi->param('svcnum'),
     'beginning'   => $cgi->param('beginning') || '',
     'session_id'  => $session_id,
     'svcnum'      => $cgi->param('svcnum'),
     'beginning'   => $cgi->param('beginning') || '',
@@ -609,29 +916,70 @@ sub do_template {
   $fill_in->{'selfurl'} = $cgi->self_url;
   $fill_in->{'cgi'} = \$cgi;
 
   $fill_in->{'selfurl'} = $cgi->self_url;
   $fill_in->{'cgi'} = \$cgi;
 
-  my $template = new Text::Template( TYPE    => 'FILE',
-                                     SOURCE  => "$template_dir/$name.html",
-                                     DELIMITERS => [ '<%=', '%>' ],
-                                     UNTAINT => 1,                    )
-    or die $Text::Template::ERROR;
-
-  print $cgi->header( '-expires' => 'now' ),
-        $template->fill_in( PACKAGE => 'FS::SelfService::_selfservicecgi',
-                            HASH    => $fill_in
-                          );
-}
+  my $access_info = $session_id
+                      ? access_info( 'session_id' => $session_id )
+                      : {};
+  $fill_in->{$_} = $access_info->{$_} foreach keys %$access_info;
+
+  
+    if($result && ref($result) && $result->{'format'} && $result->{'content'}
+       && $result->{'format'} eq 'csv') {
+       print $cgi->header('-expires' => 'now',
+               '-Content-Type' => 'text/csv',
+               '-Content-Disposition' => "attachment;filename=output.csv",
+               ),
+           $result->{'content'};
+    }
+    elsif($result && ref($result) && $result->{'format'} && $result->{'content'}
+        && $result->{'format'} eq 'xls') {
+       print $cgi->header('-expires' => 'now',
+                   '-Content-Type' => 'application/vnd.ms-excel',
+                   '-Content-Disposition' => "attachment;filename=output.xls",
+                   '-Content-Length' => length($result->{'content'}),
+                   ),
+                   $result->{'content'};
+    }
+    elsif($result && ref($result) && $result->{'format'} && $result->{'content'}
+        && $result->{'format'} eq 'png') {
+       print $cgi->header('-expires' => 'now',
+                   '-Content-Type' => 'image/png',
+                   ),
+                   $result->{'content'};
+    }
+    else {
+       my $source = "$template_dir/$name.html";
+        my $template = new Text::Template( TYPE       => 'FILE',
+                                        SOURCE     => $source,
+                                        DELIMITERS => [ '<%=', '%>' ],
+                                        UNTAINT    => 1,
+                                      )
+       or die $Text::Template::ERROR;
+
+       my $data = $template->fill_in( 
+           PACKAGE => 'FS::SelfService::_selfservicecgi',
+           HASH    => $fill_in,
+         ) || "Error processing template $source"; # at least print _something_
+         print $cgi->header( '-expires' => 'now' );
+         print $data;
+    }
+ }
 
 #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file;
 
 package FS::SelfService::_selfservicecgi;
 
 
 #*FS::SelfService::_selfservicecgi::include = \&Text::Template::fill_in_file;
 
 package FS::SelfService::_selfservicecgi;
 
-#use FS::SelfService qw(regionselector expselect popselector);
 use HTML::Entities;
 use HTML::Entities;
-use FS::SelfService qw(regionselector popselector domainselector);
+use FS::SelfService qw(
+    regionselector popselector domainselector location_form didselector
+);
 
 #false laziness w/agent.cgi
 
 #false laziness w/agent.cgi
+use vars qw(@INCLUDE_ARGS);
 sub include {
   my $name = shift;
 sub include {
   my $name = shift;
+
+  @INCLUDE_ARGS = @_;
+
   my $template = new Text::Template( TYPE   => 'FILE',
                                      SOURCE => "$main::template_dir/$name.html",
                                      DELIMITERS => [ '<%=', '%>' ],
   my $template = new Text::Template( TYPE   => 'FILE',
                                      SOURCE => "$main::template_dir/$name.html",
                                      DELIMITERS => [ '<%=', '%>' ],
@@ -645,3 +993,4 @@ sub include {
 
 }
 
 
 }
 
+1;