add part_pop_local table
[freeside.git] / FS / FS / cust_main.pm
index b29e385..0a7f1f7 100644 (file)
@@ -1,7 +1,3 @@
-#this is so kludgy i'd be embarassed if it wasn't cybercash's fault
-package main;
-use vars qw($paymentserversecret $paymentserverport $paymentserverhost);
-
 package FS::cust_main;
 
 use strict;
@@ -31,6 +27,7 @@ use FS::cust_main_invoice;
 use FS::cust_credit_bill;
 use FS::cust_bill_pay;
 use FS::prepay_credit;
+use FS::queue;
 
 @ISA = qw( FS::Record );
 
@@ -65,15 +62,6 @@ $FS::UID::callback{'FS::cust_main'} = sub {
       die "CCMckLib3_2::InitConfig fatal error: $errmsg\n";
     }
     $processor='cybercash3.2';
-  } elsif ( $conf->exists('cybercash2') ) {
-    require CCLib;
-      #qw(sendmserver);
-    ( $main::paymentserverhost, 
-      $main::paymentserverport, 
-      $main::paymentserversecret,
-      $xaction,
-    ) = $conf->config('cybercash2');
-    $processor='cybercash2';
   } elsif ( $conf->exists('business-onlinepayment') ) {
     ( $bop_processor,
       $bop_login,
@@ -343,6 +331,22 @@ sub insert {
     }
   }
 
+  my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
+  $error = $queue->insert($self->getfield('last'), $self->company);
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return "queueing job (transaction rolled back): $error";
+  }
+
+  if ( defined $self->dbdef_table->column('ship_last') && $self->ship_last ) {
+    $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
+    $error = $queue->insert($self->getfield('last'), $self->company);
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "queueing job (transaction rolled back): $error";
+    }
+  }
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   '';
 
@@ -936,7 +940,7 @@ invoice_time - Use this time when deciding when to print invoices and
 late notices on those invoices.  The default is now.  It is specified as a UNIX timestamp; see L<perlfunc/"time">).  Also see L<Time::Local> and L<Date::Parse>
 for conversion functions.
 
-batch_card - Set this true to batch cards (see L<cust_pay_batch>).  By
+batch_card - Set this true to batch cards (see L<FS::cust_pay_batch>).  By
 default, cards are processed immediately, which will generate an error if
 CyberCash is not installed.
 
@@ -1065,7 +1069,7 @@ sub collect {
         $self->paydate =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/;
         my $exp = "$2/$1";
 
-        if ( $processor =~ /^cybercash/ ) {
+        if ( $processor eq 'cybercash3.2' ) {
 
           #fix exp. date for cybercash
           #$self->paydate =~ /^(\d+)\/\d*(\d{2})$/;
@@ -1095,16 +1099,7 @@ sub collect {
           );
 
           my %result;
-          if ( $processor eq 'cybercash2' ) {
-            $^W=0; #CCLib isn't -w safe, ugh!
-            %result = &CCLib::sendmserver(@full_xaction);
-            $^W=1;
-          } elsif ( $processor eq 'cybercash3.2' ) {
-            %result = &CCMckDirectLib3_2::SendCC2_1Server(@full_xaction);
-          } else {
-            $dbh->rollback if $oldAutoCommit;
-            return "Unknown real-time processor $processor";
-          }
+          %result = &CCMckDirectLib3_2::SendCC2_1Server(@full_xaction);
          
           #if ( $result{'MActionCode'} == 7 ) { #cybercash smps v.1.1.3
           #if ( $result{'action-code'} == 7 ) { #cybercash smps v.2.1
@@ -1155,6 +1150,15 @@ sub collect {
             $paylast = $self->getfield('first');
             $payname =  "$payfirst $paylast";
           }
+
+          my @invoicing_list = grep { $_ ne 'POST' } $self->invoicing_list;
+          if ( $conf->exists('emailinvoiceonly') ) {
+            @invoicing_list = $self->default_invoicing_list
+              unless @invoicing_list;
+          }
+          my $email = $invoicing_list[0];
+
+          my( $action1, $action2 ) = split(/\s*\,\s*/, $bop_action );
         
           my $transaction =
             new Business::OnlinePayment( $bop_processor, @bop_options );
@@ -1162,7 +1166,8 @@ sub collect {
             'type'           => 'CC',
             'login'          => $bop_login,
             'password'       => $bop_password,
-            'action'         => $bop_action,
+            'action'         => $action1,
+            'description'    => 'Internet Services',
             'amount'         => $amount,
             'invoice_number' => $cust_bill->invnum,
             'customer_id'    => $self->custnum,
@@ -1176,10 +1181,43 @@ sub collect {
             'country'        => $self->country,
             'card_number'    => $self->payinfo,
             'expiration'     => $exp,
+            'referer'        => 'http://cleanwhisker.420.am/',
+            'email'          => $email,
           );
           $transaction->submit();
 
-          if ( $transaction->is_success()) {
+          if ( $transaction->is_success() && $action2 ) {
+            my $auth = $transaction->authorization;
+            my $ordernum = $transaction->order_number;
+            #warn "********* $auth ***********\n";
+            #warn "********* $ordernum ***********\n";
+            my $capture =
+              new Business::OnlinePayment( $bop_processor, @bop_options );
+
+            $capture->content(
+              action         => $action2,
+              login          => $bop_login,
+              password       => $bop_password,
+              order_number   => $ordernum,
+              amount         => $amount,
+              authorization  => $auth,
+              description    => 'Internet Services',
+            );
+
+            $capture->submit();
+
+            unless ( $capture->is_success ) {
+              my $e = "Authorization sucessful but capture failed, invnum #".
+                      $cust_bill->invnum. ': '.  $capture->result_code.
+                      ": ". $capture->error_message;
+              warn $e;
+              return $e;
+            }
+
+          }
+
+          if ( $transaction->is_success() ) {
+
             my $cust_pay = new FS::cust_pay ( {
                'invnum'   => $cust_bill->invnum,
                'paid'     => $amount,
@@ -1499,6 +1537,24 @@ sub check_invoicing_list {
   '';
 }
 
+=item default_invoicing_list
+
+=cut
+
+sub default_invoicing_list {
+  my $self = shift;
+  my @list = ();
+  foreach my $cust_pkg ( $self->all_pkgs ) {
+    my @cust_svc = qsearch('cust_svc', { 'pkgnum' => $cust_pkg->pkgnum } );
+    my @svc_acct =
+      map { qsearchs('svc_acct', { 'svcnum' => $_->svcnum } ) }
+        grep { qsearchs('svc_acct', { 'svcnum' => $_->svcnum } ) }
+          @cust_svc;
+    push @list, map { $_->email } @svc_acct;
+  }
+  $self->invoicing_list(\@list);
+}
+
 =item referral_cust_main [ DEPTH [ EXCLUDE_HASHREF ] ]
 
 Returns an array of customers referred by this customer (referral_custnum set
@@ -1533,24 +1589,142 @@ sub referral_cust_main {
 
 =over 4
 
-=item rebuild_fuzzyfile
+=item check_and_rebuild_fuzzyfiles
+
+=cut
+
+sub check_and_rebuild_fuzzyfiles {
+  my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+  -e "$dir/cust_main.last" && -e "$dir/cust_main.company"
+    or &rebuild_fuzzyfiles;
+}
+
+=item rebuild_fuzzyfiles
 
 =cut
 
 sub rebuild_fuzzyfiles {
+
+  use Fcntl qw(:flock);
+
+  my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+
+  #last
+
+  open(LASTLOCK,">>$dir/cust_main.last")
+    or die "can't open $dir/cust_main.last: $!";
+  flock(LASTLOCK,LOCK_EX)
+    or die "can't lock $dir/cust_main.last: $!";
+
   my @all_last = map $_->getfield('last'), qsearch('cust_main', {});
   push @all_last,
                  grep $_, map $_->getfield('ship_last'), qsearch('cust_main',{})
-      if defined dbdef->table('cust_main')->column('ship_last');
-#  open(
+    if defined dbdef->table('cust_main')->column('ship_last');
+
+  open (LASTCACHE,">$dir/cust_main.last.tmp")
+    or die "can't open $dir/cust_main.last.tmp: $!";
+  print LASTCACHE join("\n", @all_last), "\n";
+  close LASTCACHE or die "can't close $dir/cust_main.last.tmp: $!";
+
+  rename "$dir/cust_main.last.tmp", "$dir/cust_main.last";
+  close LASTLOCK;
+
+  #company
+
+  open(COMPANYLOCK,">>$dir/cust_main.company")
+    or die "can't open $dir/cust_main.company: $!";
+  flock(COMPANYLOCK,LOCK_EX)
+    or die "can't lock $dir/cust_main.company: $!";
+
+  my @all_company = grep $_ ne '', map $_->company, qsearch('cust_main',{});
+  push @all_company,
+       grep $_ ne '', map $_->ship_company, qsearch('cust_main', {})
+    if defined dbdef->table('cust_main')->column('ship_last');
+
+  open (COMPANYCACHE,">$dir/cust_main.company.tmp")
+    or die "can't open $dir/cust_main.company.tmp: $!";
+  print COMPANYCACHE join("\n", @all_company), "\n";
+  close COMPANYCACHE or die "can't close $dir/cust_main.company.tmp: $!";
+
+  rename "$dir/cust_main.company.tmp", "$dir/cust_main.company";
+  close COMPANYLOCK;
 
 }
 
-=back
+=item all_last
+
+=cut
+
+sub all_last {
+  my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+  open(LASTCACHE,"<$dir/cust_main.last")
+    or die "can't open $dir/cust_main.last: $!";
+  my @array = map { chomp; $_; } <LASTCACHE>;
+  close LASTCACHE;
+  \@array;
+}
+
+=item all_company
+
+=cut
+
+sub all_company {
+  my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+  open(COMPANYCACHE,"<$dir/cust_main.company")
+    or die "can't open $dir/cust_main.last: $!";
+  my @array = map { chomp; $_; } <COMPANYCACHE>;
+  close COMPANYCACHE;
+  \@array;
+}
+
+=item append_fuzzyfiles LASTNAME COMPANY
+
+=cut
+
+sub append_fuzzyfiles {
+  my( $last, $company ) = @_;
+
+  &check_and_rebuild_fuzzyfiles;
+
+  use Fcntl qw(:flock);
+
+  my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+
+  if ( $last ) {
+
+    open(LAST,">>$dir/cust_main.last")
+      or die "can't open $dir/cust_main.last: $!";
+    flock(LAST,LOCK_EX)
+      or die "can't lock $dir/cust_main.last: $!";
+
+    print LAST "$last\n";
+
+    flock(LAST,LOCK_UN)
+      or die "can't unlock $dir/cust_main.last: $!";
+    close LAST;
+  }
+
+  if ( $company ) {
+
+    open(COMPANY,">>$dir/cust_main.company")
+      or die "can't open $dir/cust_main.company: $!";
+    flock(COMPANY,LOCK_EX)
+      or die "can't lock $dir/cust_main.company: $!";
+
+    print COMPANY "$company\n";
+
+    flock(COMPANY,LOCK_UN)
+      or die "can't unlock $dir/cust_main.company: $!";
+
+    close COMPANY;
+  }
+
+  1;
+}
 
 =head1 VERSION
 
-$Id: cust_main.pm,v 1.29 2001-09-03 22:07:38 ivan Exp $
+$Id: cust_main.pm,v 1.38 2001-09-26 09:17:06 ivan Exp $
 
 =head1 BUGS