summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorChristopher Burger <burgerc@freeside.biz>2017-11-01 12:56:48 -0400
committerChristopher Burger <burgerc@freeside.biz>2018-02-08 08:37:30 -0500
commit1050e60086386799dbba6e5bbcfc5a29e78eddb5 (patch)
treee5a002c4c6941f45b1cd974d758439423c62ddc6 /FS
parent51766e3b6bb6188c121d3829614738a927c23a2c (diff)
RT# 75095 - Added Ooma integration to one time charges
Conflicts: FS/FS/cust_main/Import_Charges.pm httemplate/misc/process/cust_main-import_charges.cgi
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/cust_main/Import_Charges.pm256
1 files changed, 256 insertions, 0 deletions
diff --git a/FS/FS/cust_main/Import_Charges.pm b/FS/FS/cust_main/Import_Charges.pm
new file mode 100644
index 000000000..64fcb5ccf
--- /dev/null
+++ b/FS/FS/cust_main/Import_Charges.pm
@@ -0,0 +1,256 @@
+package FS::cust_main::Import_Charges;
+#actually no specific reason it lives under FS::cust_main:: othan than it calls
+# a thing on cust_main objects. not part of the inheritence, just providess a
+# subroutine for misc/process/cust_main-import_charges.cgi
+
+use strict;
+use FS::UID qw( dbh );
+use FS::CurrentUser;
+use FS::Record qw( qsearchs );
+use FS::cust_main;
+
+=head1 NAME
+
+FS::cust_main::Import_Charges - Batch charge importing
+
+=head1 SYNOPSIS
+
+ use FS::cust_main::Import_Charges;
+
+ my $error =
+ FS::cust_main::Import_charges::batch_charge( {
+ filehandle => $fh,
+ 'agentnum' => scalar($cgi->param('agentnum')),
+ 'format' => scalar($cgi->param('format')),
+ } );
+
+=head1 DESCRIPTION
+
+Batch customer charging.
+
+
+=head1 SUBROUTINES
+
+=over 4
+
+=item batch_charge
+
+=cut
+
+sub batch_charge {
+ my $job = shift;
+ my $param = shift;
+ #warn join('-',keys %$param);
+ my $agentnum = $param->{agentnum};
+ my $format = $param->{format};
+
+ my $files = $param->{'uploaded_files'}
+ or die "No files provided.\n";
+
+ my (%files) = map { /^(\w+):([\.\w]+)$/ ? ($1,$2):() } split /,/, $files;
+
+ my $dir = '%%%FREESIDE_CACHE%%%/cache.'. $FS::UID::datasrc. '/';
+ my $filename = $dir. $files{'file'};
+
+ my $type;
+ if ( $filename =~ /\.(\w+)$/i ) {
+ $type = lc($1);
+ } else {
+ #or error out???
+ warn "can't parse file type from filename $filename; defaulting to CSV";
+ $type = 'csv';
+ }
+
+ my $extra_sql = ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql;
+
+ my @fields;
+ my %charges;
+ if ( $format eq 'simple' ) {
+ @fields = qw( custnum agent_custid amount pkg );
+ } elsif ( $format eq 'ooma' ) {
+ @fields = ( 'userfield1', 'userfield2', 'userfield3', 'userfield4', 'userfield5', 'userfield6', 'userfield7', 'userfield8', 'userfield9', 'userfield10', 'amount', 'userfield12', 'userfield13', 'userfield14', 'userfield15', 'userfield16', 'userfield17', 'userfield18', 'pkg', 'userfield20', 'custnum', 'userfield22', 'userfield23', 'userfield24', 'userfield25', );
+ ##should charges to charge be a config option?
+ %charges = (
+ 'DISABILITY ACCESS/ENHANCED 911 SERVICES SURCHARGE' => '1',
+ 'FEDERAL TRS FUND' => '1',
+ 'FEDERAL UNIVERSAL SERVICE FUND' => '1',
+ 'STATE SALES TAX' => '1',
+ );
+ } else {
+ die "unknown format $format";
+ }
+
+ my $count;
+ my $parser;
+ my @buffer = ();
+
+ if ( $type eq 'csv' ) {
+
+ eval "use Text::CSV_XS;";
+ eval "use File::Slurp qw( slurp );";
+ die $@ if $@;
+
+ $parser = new Text::CSV_XS;
+
+ @buffer = split(/\r?\n/, slurp($filename) );
+ $count = scalar(@buffer);
+
+ } elsif ( $type eq 'xls' ) {
+ eval "use Spreadsheet::ParseExcel;";
+ die $@ if $@;
+
+ my $excel = Spreadsheet::ParseExcel::Workbook->new->Parse($filename);
+ $parser = $excel->{Worksheet}[0]; #first sheet
+
+ $count = $parser->{MaxRow} || $parser->{MinRow};
+ $count++;
+
+ } else {
+ die "Unknown file type $type\n";
+ }
+
+ my $imported = 0;
+ #my $columns;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my $line;
+ my $row = 0;
+ my %data = ();
+ my( $last, $min_sec ) = ( time, 5 ); #progressbar foo
+ while (1) {
+ my @columns = ();
+
+ if ( $type eq 'csv' ) {
+
+ last unless scalar(@buffer);
+ $line = shift(@buffer);
+
+ $parser->parse($line) or do {
+ $dbh->rollback if $oldAutoCommit;
+ return "can't parse: ". $parser->error_input();
+ };
+ @columns = $parser->fields();
+
+ } elsif ( $type eq 'xls' ) {
+ last if $row > ($parser->{MaxRow} || $parser->{MinRow})
+ || ! $parser->{Cells}[$row];
+
+ my @row = @{ $parser->{Cells}[$row] };
+ @columns = map $_->{Val}, @row;
+
+ } else {
+ die "Unknown file type $type\n";
+ }
+
+ #warn join('-',@columns);
+
+ my %row = ();
+ foreach my $field ( @fields ) {
+ $row{$field} = shift @columns;
+ }
+
+ if ( $row{custnum} && $row{agent_custid} ) {
+ dbh->rollback if $oldAutoCommit;
+ return "can't specify custnum with agent_custid $row{agent_custid}";
+ }
+
+ my $id;
+ my %hash = ();
+
+ if ( $row{agent_custid} && $agentnum ) {
+ $id = $row{agent_custid};
+ $data{$id}{cust} = (
+ 'agent_custid' => $row{agent_custid},
+ 'agentnum' => $agentnum,
+ );
+ %hash = ( 'agent_custid' => $row{agent_custid},
+ 'agentnum' => $agentnum,
+ );
+ }
+
+ if ( $row{custnum} ) {
+ $id = $row{custnum};
+ $data{$id}{cust} = {
+ 'custnum' => $row{custnum},
+ 'testnum' => 'test',
+ };
+ %hash = ( 'custnum' => $row{custnum} );
+ }
+
+ unless ( scalar(keys %hash) ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "can't find customer without custnum or agent_custid and agentnum";
+ }
+
+ ## add new pkg data or upate existing by adding new amount for custnum
+ $data{$id}{pkg}{$row{pkg}} = $data{$id}{pkg}{$row{pkg}} ? $data{$id}{pkg}{$row{pkg}} + $row{'amount'} : $row{'amount'};
+
+ $row++;
+
+ if ( $job && time - $min_sec > $last ) { #progress bar
+ $job->update_statustext( int(100 * $row / $count) );
+ $last = time;
+ }
+
+ }
+
+ ### run through data hash to post all charges.
+ foreach my $k (keys %data) {
+ my %pkg_hash = %{$data{$k}{pkg}};
+ my %cust_hash = %{$data{$k}{cust}};
+
+ my $cust_main = qsearchs('cust_main', { %cust_hash } );
+ unless ( $cust_main ) {
+ $dbh->rollback if $oldAutoCommit;
+ my $custnum = $cust_hash{custnum} || $cust_hash{agent_custid};
+ return "unknown custnum $custnum";
+ }
+
+ foreach my $pkg_key (keys %pkg_hash) {
+ my $pkg = $pkg_key;
+ my $amount = $pkg_hash{$pkg_key};
+
+ if (%charges) { next unless $charges{$pkg}; }
+
+ if ( $amount > 0 ) {
+ my $error = $cust_main->charge($amount, $pkg);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ $imported++;
+ } elsif ( $amount < 0 ) {
+ my $error = $cust_main->credit( sprintf( "%.2f", 0-$amount ), $pkg );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ $imported++;
+ } else {
+ #hmm?
+ }
+ }
+
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+ unlink $filename;
+
+ return "Empty file!" unless $imported;
+
+ ''; #no error
+
+}
+
+1; \ No newline at end of file