X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2Fbin%2Ffreeside-ipifony-download;h=1e77c3a757c04d3dc26d65aeba7412e203ad9720;hp=ee1f4bdfe01f99d3e2d040eeee8ddc5aa7d3948e;hb=bb7e827141c9ed68f30765c9ca2ddcd1d760ad2d;hpb=6e33e8af0974d49c1c0cf65b1963846d35f6c156 diff --git a/FS/bin/freeside-ipifony-download b/FS/bin/freeside-ipifony-download index ee1f4bdfe..1e77c3a75 100644 --- a/FS/bin/freeside-ipifony-download +++ b/FS/bin/freeside-ipifony-download @@ -5,15 +5,16 @@ use Getopt::Std; use Date::Format qw(time2str); use File::Temp qw(tempdir); use Net::SFTP::Foreign; +use File::Copy qw(copy); +use Text::CSV; use FS::UID qw(adminsuidsetup); use FS::Record qw(qsearch qsearchs); use FS::cust_main; use FS::Conf; -use File::Copy qw(copy); -use Text::CSV; +use FS::Log; -my %opt; -getopts('vqa:P:C:e:', \%opt); +our %opt; +getopts('vqNa:P:C:e:', \%opt); # Product codes that are subject to flat rate E911 charges. For these # products, the'quantity' field represents the number of lines. @@ -32,6 +33,7 @@ sub HELP_MESSAGE { ' freeside-ipifony-download [ -v ] [ -q ] + [ -N ] [ -a archivedir ] [ -P port ] [ -C category ] @@ -103,24 +105,19 @@ if ( $opt{P} =~ /^(\d+)$/ ) { } # for now assume SFTP download as the only method -print STDERR "Connecting to $sftpuser\@$host...\n" if $opt{v}; - -my $sftp = Net::SFTP::Foreign->new( - host => $host, - user => $sftpuser, - port => $port, - # for now we don't support passwords. use authorized_keys. - timeout => 30, - #more => ($opt{v} ? '-v' : ''), -); -die "failed to connect to '$sftpuser\@$host'\n(".$sftp->error.")\n" - if $sftp->error; +my $sftp = sftp_connect($host, $sftpuser, $port); +if ( $sftp->error ) { + my $error = "Connection failed to $sftpuser\@$host: ". $sftp->error. + ", giving up."; + mylog('critical', $error); + die $error; +} $sftp->setcwd($path) if $path; my $files = $sftp->ls('ready', wanted => qr/\.csv$/, names_only => 1); if (!@$files) { - print STDERR "No charge files found.\n" if $opt{v}; + mylog('warning',"No charge files found."); exit(-1); } @@ -130,7 +127,7 @@ my %e911_qty; # custnum => sum of E911-subject quantity my %is_e911 = map {$_ => 1} @E911_CODES; FILE: foreach my $filename (@$files) { - print STDERR "Retrieving $filename\n" if $opt{v}; + mylog('debug', "Retrieving $filename"); $sftp->get("ready/$filename", "$tmpdir/$filename"); if($sftp->error) { warn "failed to download $filename\n"; @@ -139,7 +136,7 @@ FILE: foreach my $filename (@$files) { # make sure server archive dir exists if ( !$sftp->stat('done') ) { - print STDERR "Creating $path/done\n" if $opt{v}; + mylog('debug',"Creating $path/done"); $sftp->mkdir('done'); if($sftp->error) { # something is seriously wrong @@ -154,9 +151,9 @@ FILE: foreach my $filename (@$files) { #copy to local archive dir if ( $opt{a} ) { - print STDERR "Copying $tmpdir/$filename to archive dir $opt{a}\n" - if $opt{v}; + mylog('debug', "Copying $tmpdir/$filename to archive dir $opt{a}"); copy("$tmpdir/$filename", $opt{a}); + #log too? what's -a all about anyway? warn "failed to copy $tmpdir/$filename to $opt{a}: $!" if $!; } @@ -171,7 +168,7 @@ FILE: foreach my $filename (@$files) { @hash{@fields} = $csv->fields(); if ( $hash{custnum} =~ /^cust/ ) { # there appears to be a header row - print STDERR "skipping header row\n" if $opt{v}; + mylog('debug', "skipping header row"); next; } my $cust_main = @@ -180,8 +177,7 @@ FILE: foreach my $filename (@$files) { warn "customer #$hash{custnum} not found\n"; next; } - print STDERR "Found customer #$hash{custnum}: ".$cust_main->name."\n" - if $opt{v}; + mylog('debug',"Found customer #$hash{custnum}: ".$cust_main->name); my $amount = sprintf('%.2f',$hash{quantity} * $hash{unit_price}); @@ -192,7 +188,8 @@ FILE: foreach my $filename (@$files) { if ( $next_bill_date ) { my ($bill_month, $bill_year) = (localtime($next_bill_date))[4, 5]; my ($this_month, $this_year) = (localtime(time))[4, 5]; - if ( $this_month == $bill_month and $this_year == $bill_year ) { + if ( $opt{N} or + $this_month == $bill_month and $this_year == $bill_year ) { $cust_main->set('charge_date', $next_bill_date); } } @@ -231,8 +228,7 @@ FILE: foreach my $filename (@$files) { } $charge_opt{classnum} = $classnum_of{$classname}; } - print STDERR " Charging $hash{unit_price} * $hash{quantity}\n" - if $opt{v}; + mylog('debug', " Charging $hash{unit_price} * $hash{quantity}"); my $error = $cust_main->charge(\%charge_opt); if ($error) { warn "Error creating charge: $error" if $error; @@ -275,8 +271,7 @@ foreach my $custnum ( keys (%e911_qty) ) { $dbh->commit; -if ($opt{v}) { - print STDERR " +mylog('debug', " Finished! Processed files: @$files Created charges: $num_charges @@ -284,7 +279,43 @@ Finished! E911 charges: $num_e911 E911 lines: $num_lines Errors: $num_errors -"; +"); + +sub sftp_connect { + my ($host, $sftpuser, $port) = @_; + my $sftp; + my $connection_tries = 1; + + while (1) { + mylog('info', "Connecting to $sftpuser\@$host try number $connection_tries..."); + $sftp = Net::SFTP::Foreign->new( + host => $host, + user => $sftpuser, + port => $port, + # for now we don't support passwords. use authorized_keys. + timeout => 30, + #more => ($opt{v} ? '-v' : ''), + ); + + if ($sftp->error && $connection_tries < 1200) { + $connection_tries++; + mylog('error', "Connection failed to $sftpuser\@$host: ". $sftp->error. + ", trying again in 60 sec..."); + sleep 60; + } + else { last; } + } + + return $sftp; +} + +our $log; +sub mylog { + my( $level, $message ) = @_; + #warn "$message\n" if $opt{v}; + print STDERR "$message\n" if $opt{v}; + $log ||= FS::Log->new('freeside-ipifony-download'); + $log->log(level=>$level, message=>$message); } =head1 NAME @@ -296,6 +327,7 @@ freeside-ipifony-download - Download and import invoice items from IPifony. freeside-ipifony-download [ -v ] [ -q ] + [ -N ] [ -a archivedir ] [ -P port ] [ -C category ] @@ -312,12 +344,20 @@ have an authorization key to connect as that user. I: the SFTP server. +I: the path on the server to the working directory. The working +directory is the one containing the "ready/" and "done/" subdirectories. + =head1 OPTIONAL PARAMETERS --v: Be verbose. +-v: Be verbose; send debugging information to STDERR in addition to the +internal log.. -q: Include the quantity and unit price in the charge description. +-N: Always bill the charges on the customer's next bill date, if they have +one. Otherwise, charges will be billed on the next bill date only if it's +within the current calendar month. + -a I: Save a copy of the downloaded file to I. -P I: Connect to that TCP port.