From: ivan Date: Fri, 30 Aug 2002 23:42:47 +0000 (+0000) Subject: new invoice event: upload a CSV file X-Git-Tag: freeside_1_4_1beta1~18 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=10adfb99055cc684f96cf446da34a7423cac3459 new invoice event: upload a CSV file --- diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 5a9fdd09b..a10a6c41a 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -11,6 +11,7 @@ use Date::Format; use Mail::Internet 1.44; use Mail::Header; use Text::Template; +use FS::UID qw( datasrc ); use FS::Record qw( qsearch qsearchs ); use FS::cust_main; use FS::cust_bill_pkg; @@ -410,6 +411,153 @@ sub send { } +=item send_csv OPTIONS + +Sends invoice as a CSV data-file to a remote host with the specified protocol. + +Options are: + +protocol - currently only "ftp" +server +username +password +dir + +The file will be named "N-YYYYMMDDHHMMSS.csv" where N is the invoice number +and YYMMDDHHMMSS is a timestamp. + +The fields of the CSV file is as follows: + +record_type, invnum, custnum, _date, charged, first, last, company, address1, address2, city, state, zip, country, pkg, setup, recur, sdate, edate + +=over 4 + +=item record type - B is either C or C + +If B is C, this is a primary invoice record. The +last five fields (B through B) are irrelevant, and all other +fields are filled in. + +If B is C, this is a line item record. Only the +first two fields (B and B) and the last five fields +(B through B) are filled in. + +=item invnum - invoice number +=item custnum - customer number +=item _date - invoice date +=item charged - total invoice amount +=item first - customer first name +=item last - customer first name +=item company - company name +=item address1 - address line 1 +=item address2 - address line 1 +=item city +=item state +=item zip +=item country + +=item pkg - line item description +=item setup - line item setup fee (only or both of B and B will be defined) +=item recur - line item recurring fee (only or both of B and B will be defined) +=item sdate - start date for recurring fee +=item edate - end date for recurring fee + +=back + +=cut + +sub send_csv { + my($self, %opt) = @_; + + #part one: create file + + my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/cust_bill"; + mkdir $spooldir, 0700 unless -d $spooldir; + + my $file = $spooldir. '/'. $self->invnum. time2str('-%Y%m%d%H%M%S.csv', time); + + open(CSV, ">$file") or die "can't open $file: $!"; + + eval "use Text::CSV_XS"; + die $@ if $@; + + my $csv = Text::CSV_XS->new({'always_quote'=>1}); + + my $cust_main = $self->cust_main; + + $csv->combine( + 'cust_bill', + $self->invnum, + $self->custnum, + time2str("%x", $self->_date), + ( map { $cust_main->getfield($_) } + qw( first last company address1 address2 city state zip country ) ), + map { '' } (1..5), + ) or die "can't create csv"; + print CSV $csv->string. "\n"; + + #new charges (false laziness w/print_text) + foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) { + + my($pkg, $setup, $recur, $sdate, $edate); + if ( $cust_bill_pkg->pkgnum ) { + + ($pkg, $setup, $recur, $sdate, $edate) = ( + $cust_bill_pkg->cust_pkg->part_pkg->pkg, + ( $cust_bill_pkg->setup != 0 + ? sprintf("%.2f", $cust_bill_pkg->setup ) + : '' ), + ( $cust_bill_pkg->recur != 0 + ? sprintf("%.2f", $cust_bill_pkg->recur ) + : '' ), + time2str("%x", $cust_bill_pkg->sdate), + time2str("%x", $cust_bill_pkg->edate), + ); + + } else { #pkgnum Tax + next unless $cust_bill_pkg->setup != 0; + ($pkg, $setup, $recur, $sdate, $edate) = + ( 'Tax', sprintf("%10.2f",$cust_bill_pkg->setup), '', '', '' ); + } + + $csv->combine( + 'cust_bill_pkg', + $self->invnum, + ( map { '' } (1..11) ), + ($pkg, $setup, $recur, $sdate, $edate) + ) or die "can't create csv"; + print CSV $csv->string. "\n"; + + } + + close CSV or die "can't close CSV: $!"; + + #part two: upload it + + my $net; + if ( $opt{protocol} eq 'ftp' ) { + eval "use Net::FTP;"; + die $@ if $@; + $net = Net::FTP->new($opt{server}) or die @$; + } else { + die "unknown protocol: $opt{protocol}"; + } + + $net->login( $opt{username}, $opt{password} ) + or die "can't FTP to $opt{username}\@$opt{server}: login error: $@"; + + $net->binary or die "can't set binary mode"; + + $net->cwd($opt{dir}) or die "can't cwd to $opt{dir}"; + + $net->put($file) or die "can't put $file: $!"; + + $net->quit; + + unlink $file; + +} + =item comp Pays this invoice with a compliemntary payment. If there is an error, @@ -952,7 +1100,7 @@ sub print_text { =head1 VERSION -$Id: cust_bill.pm,v 1.38 2002-06-26 02:37:48 ivan Exp $ +$Id: cust_bill.pm,v 1.39 2002-08-30 23:42:47 ivan Exp $ =head1 BUGS diff --git a/httemplate/edit/part_bill_event.cgi b/httemplate/edit/part_bill_event.cgi index 324daeb90..a10a186a9 100755 --- a/httemplate/edit/part_bill_event.cgi +++ b/httemplate/edit/part_bill_event.cgi @@ -134,6 +134,30 @@ tie my %events, 'Tie::IxHash', 'weight' => 50, }, + 'send_csv_ftp' => { + 'name' => 'Upload CSV invoice data to an FTP server', + 'code' => '$cust_bill->send_csv( protocol => \'ftp\', + server => \'%%%ftpserver%%%\', + username => \'%%%ftpusername%%%\', + password => \'%%%ftppassword%%%\', + dir => \'%%%ftpdir%%%\' );', + 'html' => + ''. + ''. + ''. + ''. + ''. + ''. + '
FTP server: '. + '
FTP username: '. + ''. + '
FTP password: '. + ''. + '
FTP directory: '. + '
', + 'weight' => 50, + }, + 'bill' => { 'name' => 'Generate invoices (normally only used with a Late Fee event)', 'code' => '$cust_main->bill();', diff --git a/httemplate/edit/process/part_bill_event.cgi b/httemplate/edit/process/part_bill_event.cgi index 4049ade80..e224bf634 100755 --- a/httemplate/edit/process/part_bill_event.cgi +++ b/httemplate/edit/process/part_bill_event.cgi @@ -12,7 +12,7 @@ if ( ! $cgi->param('plan_weight_eventcode') ) { $error = "Must select an action"; } else { - $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/ + $cgi->param('plan_weight_eventcode') =~ /^([\w\-]+):(\d+):(.*)$/s or die "illegal plan_weight_eventcode:". $cgi->param('plan_weight_eventcode'); $cgi->param('plan', $1);