[freeside-commits] branch master updated. cf0188f03b566ba9ae95294e211ea788ac9b050c

Mark Wells mark at 420.am
Tue May 22 00:24:39 PDT 2012


The branch, master has been updated
       via  cf0188f03b566ba9ae95294e211ea788ac9b050c (commit)
      from  1c71ab4b81802a8ee9074917306d35a582349766 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit cf0188f03b566ba9ae95294e211ea788ac9b050c
Author: Mark Wells <mark at freeside.biz>
Date:   Tue May 22 00:24:30 2012 -0700

    non-billco FTP invoice spool upload, #16382

diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index 2acbf0a..e9cdafb 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -3087,7 +3087,14 @@ and customer address. Include units.',
     'type'        => 'checkbox',
   },
 
-  {
+    {
+    'key'         => 'cust_bill-ftp_spool',
+    'section'     => 'invoicing',
+    'description' => 'Enable FTP upload of the invoice spool during daily processing',
+    'type'        => 'checkbox',
+  },
+
+{
     'key'         => 'svc_acct-usage_suspend',
     'section'     => 'billing',
     'description' => 'Suspends the package an account belongs to when svc_acct.seconds or a bytecount is decremented to 0 or below (accounts with an empty seconds and up|down|totalbytes value are ignored).  Typically used in conjunction with prepaid packages and freeside-sqlradius-radacctd.',
diff --git a/FS/FS/Cron/upload.pm b/FS/FS/Cron/upload.pm
index dceead6..5fe8131 100644
--- a/FS/FS/Cron/upload.pm
+++ b/FS/FS/Cron/upload.pm
@@ -39,42 +39,98 @@ sub upload {
 
   warn "$me upload called\n" if $DEBUG;
 
-  my $conf = new FS::Conf;
-  my @agent = grep { $conf->config( 'billco-username', $_->agentnum, 1 ) }
-              grep { $conf->config( 'billco-password', $_->agentnum, 1 ) }
-              qsearch( 'agent', {} );
+  my @tasks;
 
   my $date =  time2str('%Y%m%d%H%M%S', $^T); # more?
 
-  @agent = grep { $_ == $opt{'a'} } @agent if $opt{'a'};
+  my $conf = new FS::Conf;
 
-  foreach my $agent ( @agent ) {
+  my @agents = $opt{'a'} ? FS::agent->by_key($opt{'a'}) : qsearch('agent', {});
+
+  if ( $conf->exists('cust_bill-ftp_spool') ) {
+    my $url = $conf->config('cust_bill-ftpdir');
+    $url = "/$url" unless $url =~ m[^/];
+    $url = 'ftp://' . $conf->config('cust_bill-ftpserver') . $url;
+
+    my $format = $conf->config('cust_bill-ftpformat');
+    my $username = $conf->config('cust_bill-ftpusername');
+    my $password = $conf->config('cust_bill-ftppassword');
+
+    my %task = (
+      'date'      => $date,
+      'l'         => $opt{'l'},
+      'm'         => $opt{'m'},
+      'v'         => $opt{'v'},
+      'username'  => $username,
+      'password'  => $password,
+      'url'       => $url,
+      'format'    => $format,
+    );
+
+    if ( $conf->exists('cust_bill-spoolagent') ) {
+      # then push each agent's spool separately
+      foreach ( @agents ) {
+        push @tasks, { %task, 'agentnum' => $_->agentnum };
+      }
+    }
+    elsif ( $opt{'a'} ) {
+      warn "Per-agent processing, but cust_bill-spoolagent is not enabled.\nSkipped invoice upload.\n";
+    }
+    else {
+      push @tasks, \%task;
+    }
+  }
 
-    my $agentnum = $agent->agentnum;
+  else { #check each agent for billco upload settings
+
+    my %task = (
+      'date'      => $date,
+      'l'         => $opt{'l'},
+      'm'         => $opt{'m'},
+      'v'         => $opt{'v'},
+    );
+
+    foreach (@agents) {
+      my $agentnum = $_->agentnum;
+
+      if ( $conf->config( 'billco-username', $agentnum, 1 ) ) {
+        my $username = $conf->config('billco-username', $agentnum, 1);
+        my $password = $conf->config('billco-password', $agentnum, 1);
+        my $clicode  = $conf->config('billco-clicode',  $agentnum, 1);
+        my $url      = $conf->config('billco-url',      $agentnum);
+        push @tasks, {
+          %task,
+          'agentnum' => $agentnum,
+          'username' => $username,
+          'password' => $password,
+          'url'      => $url,
+          'clicode'  => $clicode,
+          'format'   => 'billco',
+        };
+      }
+    } # foreach @agents
+
+  } #!if cust_bill-ftp_spool
+
+  foreach (@tasks) {
+
+    my $agentnum = $_->{agentnum};
 
     if ( $opt{'m'} ) {
 
       if ( $opt{'r'} ) {
         warn "DRY RUN: would add agent $agentnum for queued upload\n";
       } else {
-
         my $queue = new FS::queue {
-          'job'      => 'FS::Cron::upload::billco_upload',
+          'job'      => 'FS::Cron::upload::spool_upload',
         };
-        my $error = $queue->insert(
-                                    'agentnum' => $agentnum,
-                                    'date'     => $date,
-                                    'l'        => $opt{'l'} || '',
-                                    'm'        => $opt{'m'} || '',
-                                    'v'        => $opt{'v'} || '',
-                                  );
-
+        my $error = $queue->insert( %$_ );
       }
 
     } else {
 
-      eval "&billco_upload( 'agentnum' => $agentnum, 'date' => $date );";
-      warn "billco_upload failed: $@\n"
+      eval { spool_upload(%$_) };
+      warn "spool_upload failed: $@\n"
         if $@;
 
     }
@@ -83,26 +139,21 @@ sub upload {
 
 }
 
-sub billco_upload {
+sub spool_upload {
   my %opt = @_;
 
-  warn "$me billco_upload called\n" if $DEBUG;
+  warn "$me spool_upload called\n" if $DEBUG;
   my $conf = new FS::Conf;
   my $dir = '%%%FREESIDE_EXPORT%%%/export.'. $FS::UID::datasrc. '/cust_bill';
 
   my $agentnum = $opt{agentnum} or die "no agentnum provided\n";
-  my $url      = $conf->config( 'billco-url', $agentnum )
-    or die "no url for agent $agentnum\n";
+  my $url      = $opt{url} or die "no url for agent $agentnum\n";
   $url =~ s/^\s+//; $url =~ s/\s+$//;
-  my $username = $conf->config( 'billco-username', $agentnum, 1 )
-    or die "no username for agent $agentnum\n";
-  my $password = $conf->config( 'billco-password', $agentnum, 1 )
-    or die "no password for agent $agentnum\n";
-  my $clicode  = $conf->config( 'billco-clicode', $agentnum, 1 );
-    #or die "no clicode for agent $agentnum\n";
+
+  my $username = $opt{username} or die "no username for agent $agentnum\n";
+  my $password = $opt{password} or die "no password for agent $agentnum\n";
 
   die "no date provided\n" unless $opt{date};
-  my $zipfile  = "$dir/agentnum$agentnum-$opt{date}.zip";
 
   local $SIG{HUP} = 'IGNORE';
   local $SIG{INT} = 'IGNORE';
@@ -119,82 +170,119 @@ sub billco_upload {
     or die "no such agent: $agentnum";
   $agent->select_for_update; #mutex 
 
-  unless ( -f "$dir/agentnum$agentnum-header.csv" ||
-           -f "$dir/agentnum$agentnum-detail.csv" )
-  {
-    warn "$me neither $dir/agentnum$agentnum-header.csv nor ".
-         "$dir/agentnum$agentnum-detail.csv found\n" if $DEBUG;
-    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-    return;
-  }
+  if ( $opt{'format'} eq 'billco' ) {
+
+    my $zipfile  = "$dir/agentnum$agentnum-$opt{date}.zip";
 
-  # a better way?
-  if ($opt{m}) {
-    my $sql = "SELECT count(*) FROM queue LEFT JOIN cust_main USING(custnum) ".
-      "WHERE queue.job='FS::cust_main::queued_bill' AND cust_main.agentnum = ?";
-    my $sth = $dbh->prepare($sql) or die $dbh->errstr;
-    while (1) {
-      $sth->execute( $agentnum )
-        or die "Unexpected error executing statement $sql: ". $sth->errstr;
-      last if $sth->fetchow_arrayref->[0];
-      sleep 300;
+    unless ( -f "$dir/agentnum$agentnum-header.csv" ||
+             -f "$dir/agentnum$agentnum-detail.csv" )
+    {
+      warn "$me neither $dir/agentnum$agentnum-header.csv nor ".
+           "$dir/agentnum$agentnum-detail.csv found\n" if $DEBUG;
+      $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+      return;
     }
-  }
 
-  foreach ( qw ( header detail ) ) {
-    rename "$dir/agentnum$agentnum-$_.csv",
-           "$dir/agentnum$agentnum-$opt{date}-$_.csv";
-  }
+    # a better way?
+    if ($opt{m}) {
+      my $sql = "SELECT count(*) FROM queue LEFT JOIN cust_main USING(custnum) ".
+        "WHERE queue.job='FS::cust_main::queued_bill' AND cust_main.agentnum = ?";
+      my $sth = $dbh->prepare($sql) or die $dbh->errstr;
+      while (1) {
+        $sth->execute( $agentnum )
+          or die "Unexpected error executing statement $sql: ". $sth->errstr;
+        last if $sth->fetchrow_arrayref->[0];
+        sleep 300;
+      }
+    }
+
+    foreach ( qw ( header detail ) ) {
+      rename "$dir/agentnum$agentnum-$_.csv",
+             "$dir/agentnum$agentnum-$opt{date}-$_.csv";
+    }
+
+    my $command = "cd $dir; zip $zipfile ".
+                  "agentnum$agentnum-$opt{date}-header.csv ".
+                  "agentnum$agentnum-$opt{date}-detail.csv";
+
+    system($command) and die "$command failed\n";
 
-  my $command = "cd $dir; zip $zipfile ".
-                "agentnum$agentnum-$opt{date}-header.csv ".
-                "agentnum$agentnum-$opt{date}-detail.csv";
+    unlink "agentnum$agentnum-$opt{date}-header.csv",
+           "agentnum$agentnum-$opt{date}-detail.csv";
 
-  system($command) and die "$command failed\n";
+    if ( $url =~ /^http/i ) {
 
-  unlink "agentnum$agentnum-$opt{date}-header.csv",
-         "agentnum$agentnum-$opt{date}-detail.csv";
+      my $ua = new LWP::UserAgent;
+      my $res = $ua->request( POST( $url,
+                                    'Content_Type' => 'form-data',
+                                    'Content' => [ 'username' => $username,
+                                                   'pass'     => $password,
+                                                   'custid'   => $username,
+                                                   'clicode'  => $opt{clicode},
+                                                   'file1'    => [ $zipfile ],
+                                                 ],
+                                  )
+                            );
 
-  if ( $url =~ /^http/i ) {
+      die "upload failed: ". $res->status_line. "\n"
+        unless $res->is_success;
 
-    my $ua = new LWP::UserAgent;
-    my $res = $ua->request( POST( $url,
-                                  'Content_Type' => 'form-data',
-                                  'Content' => [ 'username' => $username,
-                                                 'pass'     => $password,
-                                                 'custid'   => $username,
-                                                 'clicode'  => $clicode,
-                                                 'file1'    => [ $zipfile ],
-                                               ],
-                                )
-                          );
+    } elsif ( $url =~ /^ftp:\/\/([\w\.]+)(\/.*)$/i ) {
 
-    die "upload failed: ". $res->status_line. "\n"
-      unless $res->is_success;
+      my($hostname, $path) = ($1, $2);
 
-  } elsif ( $url =~ /^ftp:\/\/([\w\.]+)(\/.*)$/i ) {
+      my $ftp = new Net::FTP($hostname)
+        or die "can't connect to $hostname: $@\n";
+      $ftp->login($username, $password)
+        or die "can't login to $hostname: ". $ftp->message."\n";
+      unless ( $ftp->cwd($path) ) {
+        my $msg = "can't cd $path on $hostname: ". $ftp->message. "\n";
+        ( $path eq '/' ) ? warn $msg : die $msg;
+      }
+      $ftp->binary
+        or die "can't set binary mode on $hostname\n";
+
+      $ftp->put($zipfile)
+        or die "can't put $zipfile: ". $ftp->message. "\n";
 
-    my($hostname, $path) = ($1, $2);
+      $ftp->quit;
 
-    my $ftp = new Net::FTP($hostname) #, Passive=>1 )
-      or die "can't connect to $hostname: $@\n";
-    $ftp->login($username, $password)
-      or die "can't login to $hostname: ". $ftp->message."\n";
-    unless ( $ftp->cwd($path) ) {
-      my $msg = "can't cd $path on $hostname: ". $ftp->message. "\n";
-      ( $path eq '/' ) ? warn $msg : die $msg;
+    } else {
+      die "unknown scheme in URL $url\n";
     }
-    $ftp->binary
-      or die "can't set binary mode on $hostname\n";
 
-    $ftp->put($zipfile)
-      or die "can't put $zipfile: ". $ftp->message. "\n";
+  } else { #$opt{format} ne 'billco'
 
-    $ftp->quit;
+    my $date = $opt{date};
+    my $file = $opt{agentnum} ? "agentnum$opt{agentnum}" : 'spool'; #.csv
+    unless ( -f "$dir/$file.csv" ) {
+      warn "$me $dir/$file.csv not found\n" if $DEBUG;
+      $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+      return;
+    }
+    rename "$dir/$file.csv", "$dir/$file-$date.csv";
+
+    #ftp only for now
+    if ( $url =~ m{^ftp://([\w\.]+)(/.*)$}i ) {
+
+      my ($hostname, $path) = ($1, $2);
+      my $ftp = new Net::FTP ($hostname)
+        or die "can't connect to $hostname: $@\n";
+      $ftp->login($username, $password)
+        or die "can't login to $hostname: ".$ftp->message."\n";
+      unless ( $ftp->cwd($path) ) {
+        my $msg = "can't cd $path on $hostname: ".$ftp->message."\n";
+        ( $path eq '/' ) ? warn $msg : die $msg;
+      }
+      chdir($dir);
+      $ftp->put("$file-$date.csv")
+        or die "can't put $file-$date.csv: ".$ftp->message."\n";
+      $ftp->quit;
 
-  } else {
-    die "unknown scheme in URL $url\n";
-  }
+    } else {
+      die "malformed FTP URL $url\n";
+    }
+  } #opt{format}
 
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   '';

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Conf.pm        |    9 ++-
 FS/FS/Cron/upload.pm |  268 +++++++++++++++++++++++++++++++++-----------------
 2 files changed, 186 insertions(+), 91 deletions(-)




More information about the freeside-commits mailing list