time/data detail on invoices
[freeside.git] / FS / FS / cust_main.pm
index f9f473d..807fadb 100644 (file)
@@ -158,7 +158,7 @@ FS::Record.  The following fields are currently supported:
 
 =item ship_fax - phone (optional)
 
-=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 payby - `CARD' (credit cards), `CHEK' (electronic check), `LECB' (Phone bill billing), `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>)
 
@@ -484,14 +484,15 @@ sub replace {
     $self->invoicing_list( $invoicing_list );
   }
 
-  if ( $self->payby =~ /^(CARD|CHEK)$/ &&
+  if ( $self->payby =~ /^(CARD|CHEK|LECB)$/ &&
        grep { $self->get($_) ne $old->get($_) } qw(payinfo paydate payname) ) {
     # card/check info has changed, want to retry realtime_card invoice events
     #false laziness w/collect
     foreach my $cust_bill_event (
       grep {
              #$_->part_bill_event->plan eq 'realtime-card'
-             $_->part_bill_event->eventcode eq '$cust_bill->realtime_card();'
+             $_->part_bill_event->eventcode =~
+                 /^\$cust_bill\->realtime_(card|ach|lec)\(\);$/
                && $_->status eq 'done'
                && $_->statustext
            }
@@ -590,13 +591,13 @@ sub check {
 
 # bad idea to disable, causes billing to fail because of no tax rates later
 #  unless ( $import ) {
-    unless ( qsearchs('cust_main_county', {
+    unless ( qsearch('cust_main_county', {
       'country' => $self->country,
       'state'   => '',
      } ) ) {
       return "Unknown state/county/country: ".
         $self->state. "/". $self->county. "/". $self->country
-        unless qsearchs('cust_main_county',{
+        unless qsearch('cust_main_county',{
           'state'   => $self->state,
           'county'  => $self->county,
           'country' => $self->country,
@@ -666,7 +667,7 @@ sub check {
     }
   }
 
-  $self->payby =~ /^(CARD|CHEK|BILL|COMP|PREPAY)$/
+  $self->payby =~ /^(CARD|CHEK|LECB|BILL|COMP|PREPAY)$/
     or return "Illegal payby: ". $self->payby;
   $self->payby($1);
 
@@ -686,11 +687,19 @@ sub check {
   } elsif ( $self->payby eq 'CHEK' ) {
 
     my $payinfo = $self->payinfo;
-    $payinfo =~ s/[\D\@]//g;
+    $payinfo =~ s/[^\d\@]//g;
     $payinfo =~ /^(\d+)\@(\d{9})$/ or return 'invalid echeck account@aba';
     $payinfo = "$1\@$2";
     $self->payinfo($payinfo);
 
+  } elsif ( $self->payby eq 'LECB' ) {
+
+    my $payinfo = $self->payinfo;
+    $payinfo =~ s/\D//g;
+    $payinfo =~ /^1?(\d{10})$/ or return 'invalid btn billing telephone number';
+    $payinfo = $1;
+    $self->payinfo($payinfo);
+
   } elsif ( $self->payby eq 'BILL' ) {
 
     $error = $self->ut_textn('payinfo');
@@ -715,7 +724,7 @@ sub check {
 
   if ( $self->paydate eq '' || $self->paydate eq '-' ) {
     return "Expriation date required"
-      unless $self->payby =~ /^(BILL|PREPAY|CHEK)$/;
+      unless $self->payby =~ /^(BILL|PREPAY|CHEK|LECB)$/;
     $self->paydate('');
   } else {
     $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/
@@ -938,6 +947,8 @@ sub bill {
     my %hash = $cust_pkg->hash;
     my $old_cust_pkg = new FS::cust_pkg \%hash;
 
+    my @details = ();
+
     # bill setup
     my $setup = 0;
     unless ( $cust_pkg->setup ) {
@@ -1031,11 +1042,12 @@ sub bill {
       }
       if ( $setup > 0 || $recur > 0 ) {
         my $cust_bill_pkg = new FS::cust_bill_pkg ({
-          'pkgnum' => $cust_pkg->pkgnum,
-          'setup'  => $setup,
-          'recur'  => $recur,
-          'sdate'  => $sdate,
-          'edate'  => $cust_pkg->bill,
+          'pkgnum'  => $cust_pkg->pkgnum,
+          'setup'   => $setup,
+          'recur'   => $recur,
+          'sdate'   => $sdate,
+          'edate'   => $cust_pkg->bill,
+          'details' => \@details,
         });
         push @cust_bill_pkg, $cust_bill_pkg;
         $total_setup += $setup;
@@ -1049,26 +1061,25 @@ sub bill {
                  || $self->payby eq 'COMP'
                  || $taxable_charged == 0 ) {
 
-          my $cust_main_county =
-            qsearchs('cust_main_county',{
+          my $cust_main_county = qsearchs('cust_main_county',{
               'state'    => $self->state,
               'county'   => $self->county,
               'country'  => $self->country,
               'taxclass' => $part_pkg->taxclass,
-            } )
-            or qsearchs('cust_main_county',{
+          } );
+          $cust_main_county ||= qsearchs('cust_main_county',{
               'state'    => $self->state,
               'county'   => $self->county,
               'country'  => $self->country,
               'taxclass' => '',
-            } )
-            or do {
-              $dbh->rollback if $oldAutoCommit;
-              return
-                "fatal: can't find tax rate for state/county/country/taxclass ".
-                join('/', ( map $self->$_(), qw(state county country) ),
-                          $part_pkg->taxclass ).  "\n";
-            };
+          } );
+          unless ( $cust_main_county ) {
+            $dbh->rollback if $oldAutoCommit;
+            return
+              "fatal: can't find tax rate for state/county/country/taxclass ".
+              join('/', ( map $self->$_(), qw(state county country) ),
+                        $part_pkg->taxclass ).  "\n";
+          }
 
           if ( $cust_main_county->exempt_amount ) {
             my ($mon,$year) = (localtime($sdate) )[4,5];
@@ -1327,7 +1338,8 @@ sub collect {
       my $cust_bill_event = new FS::cust_bill_event {
         'invnum'     => $cust_bill->invnum,
         'eventpart'  => $part_bill_event->eventpart,
-        '_date'      => $invoice_time,
+        #'_date'      => $invoice_time,
+        '_date'      => time,
         'status'     => $status,
         'statustext' => $statustext,
       };