ACH support
[freeside.git] / FS / FS / cust_main.pm
index cfa6b8b..344ea72 100644 (file)
@@ -158,7 +158,7 @@ FS::Record.  The following fields are currently supported:
 
 =item ship_fax - phone (optional)
 
-=item payby - `CARD' (credit cards), `BILL' (billing), `COMP' (free), or `PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to BILL)
+=item payby - `CARD' (credit cards), `CHEK' (electronic check), `BILL' (billing), `COMP' (free), or `PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to BILL)
 
 =item payinfo - card number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L<FS::prepay_credit>)
 
@@ -482,7 +482,7 @@ sub replace {
     $self->invoicing_list( $invoicing_list );
   }
 
-  if ( $self->payby eq 'CARD' &&
+  if ( $self->payby =~ /^(CARD|CHEK)$/ &&
        grep { $self->get($_) ne $old->get($_) } qw(payinfo paydate payname) ) {
     # card info has changed, want to retry realtime_card invoice events
     #false laziness w/collect
@@ -664,7 +664,7 @@ sub check {
     }
   }
 
-  $self->payby =~ /^(CARD|BILL|COMP|PREPAY)$/
+  $self->payby =~ /^(CARD|CHEK|BILL|COMP|PREPAY)$/
     or return "Illegal payby: ". $self->payby;
   $self->payby($1);
 
@@ -681,6 +681,14 @@ sub check {
     return gettext('unknown_card_type')
       if cardtype($self->payinfo) eq "Unknown";
 
+  } elsif ( $self->payby eq 'CHEK' ) {
+
+    my $payinfo = $self->payinfo;
+    $payinfo =~ s/[\D\@]//g;
+    $payinfo =~ /^(\d+)\@(\d{9})$/ or return 'invalid echeck account@aba';
+    $payinfo = "$1\@$2";
+    $self->payinfo($payinfo);
+
   } elsif ( $self->payby eq 'BILL' ) {
 
     $error = $self->ut_textn('payinfo');
@@ -705,7 +713,7 @@ sub check {
 
   if ( $self->paydate eq '' || $self->paydate eq '-' ) {
     return "Expriation date required"
-      unless $self->payby eq 'BILL' || $self->payby eq 'PREPAY';
+      unless $self->payby =~ /^(BILL|PREPAY|CHEK)$/;
     $self->paydate('');
   } else {
     $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/
@@ -717,7 +725,7 @@ sub check {
       if !$import && ( $y<$nowy || ( $y==$nowy && $1<$nowm ) );
   }
 
-  if ( $self->payname eq '' &&
+  if ( $self->payname eq '' && $self->payby ne 'CHEK' &&
        ( ! $conf->exists('require_cardname') || $self->payby ne 'CARD' ) ) {
     $self->payname( $self->first. " ". $self->getfield('last') );
   } else {
@@ -1584,7 +1592,6 @@ sub invoicing_list {
     }
     my %seen = map { $_->address => 1 } @cust_main_invoice;
     foreach my $address ( @{$arrayref} ) {
-      #unless ( grep { $address eq $_->address } @cust_main_invoice ) {
       next if exists $seen{$address} && $seen{$address};
       $seen{$address} = 1;
       my $cust_main_invoice = new FS::cust_main_invoice ( {
@@ -1626,24 +1633,36 @@ sub check_invoicing_list {
   '';
 }
 
-=item default_invoicing_list
+=item set_default_invoicing_list
+
+Sets the invoicing list to all accounts associated with this customer,
+overwriting any previous invoicing list.
+
+=cut
+
+sub set_default_invoicing_list {
+  my $self = shift;
+  $self->invoicing_list($self->all_emails);
+}
+
+=item all_emails
 
-Sets the invoicing list to all accounts associated with this customer.
+Returns the email addresses of all accounts provisioned for this customer.
 
 =cut
 
-sub default_invoicing_list {
+sub all_emails {
   my $self = shift;
-  my @list = ();
+  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;
+    $list{$_}=1 foreach map { $_->email } @svc_acct;
   }
-  $self->invoicing_list(\@list);
+  keys %list;
 }
 
 =item invoicing_list_addpost