my $info = $import_info{$format}
     or die "unknown format $format";
 
+  my $job = $param->{'job'};
+  $job->update_statustext(0) if $job;
+
   my $filetype            = $info->{'filetype'};      # CSV or fixed
   my @fields              = @{ $info->{'fields'}};
   my $formatre            = $info->{'formatre'};      # for fixed
     }
   }
 
+  my $num = 0;
   foreach (@all_values) {
+    if($job) {
+      $num++;
+      $job->update_statustext(int(100 * $num/scalar(@all_values)));
+    }
     my @values = @$_;
 
     my %hash;
 
 }
 
+use MIME::Base64;
+use Storable 'thaw';
+use Data::Dumper;
+sub process_import_results {
+  my $job = shift;
+  my $param = thaw(decode_base64(shift));
+  $param->{'job'} = $job;
+  warn Dumper($param) if $DEBUG;
+  my $batchnum = delete $param->{'batchnum'} or die "no batchnum specified\n";
+  my $batch = FS::pay_batch->by_key($batchnum) or die "batchnum '$batchnum' not found\n";
+
+  my $file = $param->{'uploaded_files'} or die "no files provided\n";
+  $file =~ s/^(\w+):([\.\w]+)$/$2/;
+  my $dir = '%%%FREESIDE_CACHE%%%/cache.' . $FS::UID::datasrc;
+  open( $param->{'filehandle'}, 
+        '<',
+        "$dir/$file" )
+      or die "unable to open '$file'.\n";
+  my $error = $batch->import_results($param);
+  unlink $file;
+  die $error if $error;
+}
+
 # Formerly httemplate/misc/download-batch.cgi
 sub export_batch {
   my $self = shift;
 
-% if ( $error ) {
-%   errorpage($error);
-% } else {
-    <% include('/elements/header.html','Batch results upload successful') %> 
-    <% include('/elements/footer.html') %> 
-% }
+<% $server->process %>
 <%init>
 
 die "access denied"
   unless $FS::CurrentUser::CurrentUser->access_right('Process batches');
 
-my $error;
-
-my $fh = $cgi->upload('batch_results');
-$error = 'No file uploaded' unless defined($fh);
-
-unless ( $error ) {
-
-  $cgi->param('batchnum') =~ /^(\d+)$/;
-  my $batchnum = $1;
-
-  my $pay_batch = qsearchs( 'pay_batch', { 'batchnum' => $batchnum } );
-  if ( ! $pay_batch ) {
-    $error = "batchnum $batchnum not found";
-  } elsif ( $pay_batch->status ne 'I' ) {
-    $error = "batch $batchnum is not in transit";
-  } else {
-    $error = $pay_batch->import_results(
-                                         'filehandle' => $fh,
-                                         'format'     => $cgi->param('format'),
-                                       );
-  }
-
-}
+my $server =
+  new FS::UI::Web::JSRPC 'FS::pay_batch::process_import_results', $cgi;
 
 </%init>
 
              'LEFT JOIN pay_batch USING ( batchnum ) ' .
              "$search ORDER BY $orderby";
 
-my $html_init = '';
+my $html_init = '<TABLE>';
 if ( $pay_batch ) {
   my $fixed = $conf->config('batch-fixed_format-'. $pay_batch->payby);
   if (
             && $FS::CurrentUser::CurrentUser->access_right('Redownload resolved batches')
           ) 
   ) {
-    $html_init .= qq!<FORM ACTION="$p/misc/download-batch.cgi" METHOD="POST">!;
+    $html_init .= qq!<TR><FORM ACTION="$p/misc/download-batch.cgi" METHOD="POST">!;
     if ( $fixed ) {
       $html_init .= qq!<INPUT TYPE="hidden" NAME="format" VALUE="$fixed">!;
     } else {
-      $html_init .= qq!Download batch in format <SELECT NAME="format">!.
+      $html_init .= qq!Download batch in format !.
+                    qq!<SELECT NAME="format">!.
                     qq!<OPTION VALUE="">Default batch mode</OPTION>!.
                     qq!<OPTION VALUE="csv-td_canada_trust-merchant_pc_batch">CSV file for TD Canada Trust Merchant PC Batch</OPTION>!.
                     qq!<OPTION VALUE="csv-chase_canada-E-xactBatch">CSV file for Chase Canada E-xactBatch</OPTION>!.
                     qq!<OPTION VALUE="RBC">Royal Bank of Canada PDS</OPTION>!.
                     qq!</SELECT>!;
     }
-    $html_init .= qq!<INPUT TYPE="hidden" NAME="batchnum" VALUE="$batchnum"><INPUT TYPE="submit" VALUE="Download"></FORM><BR>!;
+    $html_init .= qq!<INPUT TYPE="hidden" NAME="batchnum" VALUE="$batchnum"><INPUT TYPE="submit" VALUE="Download"></FORM><BR><BR></TR>!;
   }
 
   if (
             && $FS::CurrentUser::CurrentUser->access_right('Reprocess batches')
           ) 
   ) {
-    $html_init .= qq!<FORM ACTION="$p/misc/upload-batch.cgi" METHOD="POST" ENCTYPE="multipart/form-data">!.
-                  qq!Upload results<BR>!.
-                  qq!Filename <INPUT TYPE="file" NAME="batch_results"><BR>!;
+    $html_init .= '<TR>'.
+                  include('/elements/form-file_upload.html',
+                            'name'      => 'FileUpload',
+                            'action'    => "$p/misc/upload-batch.cgi",
+                            'num_files' => 1,
+                            'fields'    => [ 'batchnum', 'format' ],
+                            'message'   => 'Batch results uploaded.',
+                            ) .
+                  'Upload results<BR></TR><TR>'.
+                  include('/elements/file-upload.html',
+                            'field'   => 'file',
+                            'label'   => 'Filename',
+                            'no_table'=> 1
+                         ).
+                  '<BR></TR>'
+                  ;
     if ( $fixed ) {
       $html_init .= qq!<INPUT TYPE="hidden" NAME="format" VALUE="$fixed">!;
     } else {
-      $html_init .= qq!Format <SELECT NAME="format">!.
+      # should pull this from %import_info
+      $html_init .= qq!<TR>Format !.
+                    qq!<SELECT NAME="format">!.
                     qq!<OPTION VALUE="">Default batch mode</OPTION>!.
                     qq!<OPTION VALUE="csv-td_canada_trust-merchant_pc_batch">CSV results from TD Canada Trust Merchant PC Batch</OPTION>!.
                     qq!<OPTION VALUE="csv-chase_canada-E-xactBatch">CSV file for Chase Canada E-xactBatch</OPTION>!.
                     qq!<OPTION VALUE="ach-spiritone">Spiritone ACH batch</OPTION>!.
                     qq!<OPTION VALUE="paymentech">Chase Paymentech</OPTION>!.
                     qq!<OPTION VALUE="RBC">Royal Bank of Canada PDS</OPTION>!.
-                    qq!</SELECT><BR>!;
+                    qq!</SELECT><BR></TR>!;
     }
     $html_init .= qq!<INPUT TYPE="hidden" NAME="batchnum" VALUE="$batchnum">!;
-    $html_init .= '<INPUT TYPE="submit" VALUE="Upload"></FORM><BR>';
+    $html_init .= '<TR> <INPUT TYPE="submit" VALUE="Upload"></FORM><BR> </TR>';
   }
-
+  $html_init .= '</TABLE>'
 }
 
 if ($pay_batch) {