fix tyops
[freeside.git] / FS / FS / cust_main.pm
index 25b6b9f..e50ea71 100644 (file)
@@ -6,12 +6,12 @@ package FS::cust_main;
 
 use strict;
 use vars qw( @ISA $conf $lpr $processor $xaction $E_NoErr $invoice_from
 
 use strict;
 use vars qw( @ISA $conf $lpr $processor $xaction $E_NoErr $invoice_from
-             $smtpmachine );
+             $smtpmachine $Debug );
 use Safe;
 use Carp;
 use Time::Local;
 use Date::Format;
 use Safe;
 use Carp;
 use Time::Local;
 use Date::Format;
-use Date::Manip;
+#use Date::Manip;
 use Mail::Internet;
 use Mail::Header;
 use Business::CreditCard;
 use Mail::Internet;
 use Mail::Header;
 use Business::CreditCard;
@@ -27,9 +27,13 @@ use FS::part_referral;
 use FS::cust_main_county;
 use FS::agent;
 use FS::cust_main_invoice;
 use FS::cust_main_county;
 use FS::agent;
 use FS::cust_main_invoice;
+use FS::prepay_credit;
 
 @ISA = qw( FS::Record );
 
 
 @ISA = qw( FS::Record );
 
+$Debug = 0;
+#$Debug = 1;
+
 #ask FS::UID to run this stuff for us later
 $FS::UID::callback{'FS::cust_main'} = sub { 
   $conf = new FS::Conf;
 #ask FS::UID to run this stuff for us later
 $FS::UID::callback{'FS::cust_main'} = sub { 
   $conf = new FS::Conf;
@@ -145,9 +149,9 @@ FS::Record.  The following fields are currently supported:
 
 =item fax - phone (optional)
 
 
 =item fax - phone (optional)
 
-=item payby - `CARD' (credit cards), `BILL' (billing), or `COMP' (free)
+=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 payinfo - card number, P.O.#, or comp issuer (4-8 lowercase alphanumerics; think username)
+=item payinfo - card number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L<FS::prepay_credit>)
 
 =item paydate - expiration date, mm/yyyy, m/yyyy, mm/yy or m/yy
 
 
 =item paydate - expiration date, mm/yyyy, m/yyyy, mm/yy or m/yy
 
@@ -179,6 +183,52 @@ sub table { 'cust_main'; }
 Adds this customer to the database.  If there is an error, returns the error,
 otherwise returns false.
 
 Adds this customer to the database.  If there is an error, returns the error,
 otherwise returns false.
 
+=cut
+
+sub insert {
+  my $self = shift;
+
+  my $flag = 0;
+  if ( $self->payby eq 'PREPAY' ) {
+    $self->payby('BILL');
+    $flag = 1;
+  }
+
+  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 $error = $self->SUPER::insert;
+  return $error if $error;
+
+  if ( $flag ) {
+    my $prepay_credit =
+      qsearchs('prepay_credit', { 'identifier' => $self->payinfo } );
+    warn "WARNING: can't find pre-found prepay_credit: ". $self->payinfo
+      unless $prepay_credit;
+    my $amount = $prepay_credit->amount;
+    my $error = $prepay_credit->delete;
+    if ( $error ) {
+      warn "WARNING: can't delete prepay_credit: ". $self->payinfo;
+    } else {
+      my $cust_credit = new FS::cust_credit {
+        'custnum' => $self->custnum,
+        'amount'  => $amount,
+      };
+      my $error = $cust_credit->insert;
+      warn "WARNING: error inserting cust_credit for prepay_credit: $error"
+        if $error;
+    }
+
+  }
+
+  '';
+
+}
+
 =item delete NEW_CUSTNUM
 
 This deletes the customer.  If there is an error, returns the error, otherwise
 =item delete NEW_CUSTNUM
 
 This deletes the customer.  If there is an error, returns the error, otherwise
@@ -262,9 +312,6 @@ sub check {
     || $self->ut_text('city')
     || $self->ut_textn('county')
     || $self->ut_textn('state')
     || $self->ut_text('city')
     || $self->ut_textn('county')
     || $self->ut_textn('state')
-    || $self->ut_phonen('daytime')
-    || $self->ut_phonen('night')
-    || $self->ut_phonen('fax')
   ;
   return $error if $error;
 
   ;
   return $error if $error;
 
@@ -307,11 +354,18 @@ sub check {
       } );
   }
 
       } );
   }
 
-  $self->zip =~ /^\s*(\w[\w\-\s]{3,8}\w)\s*$/
+  $error =
+    $self->ut_phonen('daytime', $self->country)
+    || $self->ut_phonen('night', $self->country)
+    || $self->ut_phonen('fax', $self->country)
+  ;
+  return $error if $error;
+
+  $self->zip =~ /^\s*(\w[\w\-\s]{2,8}\w)\s*$/
     or return "Illegal zip: ". $self->zip;
   $self->zip($1);
 
     or return "Illegal zip: ". $self->zip;
   $self->zip($1);
 
-  $self->payby =~ /^(CARD|BILL|COMP)$/
+  $self->payby =~ /^(CARD|BILL|COMP|PREPAY)$/
     or return "Illegal payby: ". $self->payby;
   $self->payby($1);
 
     or return "Illegal payby: ". $self->payby;
   $self->payby($1);
 
@@ -337,10 +391,21 @@ sub check {
     $error = $self->ut_textn('payinfo');
     return "Illegal comp account issuer: ". $self->payinfo if $error;
 
     $error = $self->ut_textn('payinfo');
     return "Illegal comp account issuer: ". $self->payinfo if $error;
 
+  } elsif ( $self->payby eq 'PREPAY' ) {
+
+    my $payinfo = $self->payinfo;
+    $payinfo =~ s/\W//g; #anything else would just confuse things
+    $self->payinfo($payinfo);
+    $error = $self->ut_alpha('payinfo');
+    return "Illegal prepayment identifier: ". $self->payinfo if $error;
+    return "Unknown prepayment identifier"
+      unless qsearchs('prepay_credit', { 'identifier' => $self->payinfo } );
+
   }
 
   }
 
-  if ( $self->paydate eq '' ) {
-    return "Expriation date required" unless $self->payby eq 'BILL';
+  if ( $self->paydate eq '' || $self->paydate eq '-' ) {
+    return "Expriation date required"
+      unless $self->payby eq 'BILL' || $self->payby eq 'PREPAY';
     $self->paydate('');
   } else {
     $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/
     $self->paydate('');
   } else {
     $self->paydate =~ /^(\d{1,2})[\/\-](\d{2}(\d{2})?)$/
@@ -389,10 +454,16 @@ Returns all non-cancelled packages (see L<FS::cust_pkg>) for this customer.
 
 sub ncancelled_pkgs {
   my $self = shift;
 
 sub ncancelled_pkgs {
   my $self = shift;
-  qsearch( 'cust_pkg', {
-    'custnum' => $self->custnum,
-    'cancel'  => '',
-  });
+  @{ [ # force list context
+    qsearch( 'cust_pkg', {
+      'custnum' => $self->custnum,
+      'cancel'  => '',
+    }),
+    qsearch( 'cust_pkg', {
+      'custnum' => $self->custnum,
+      'cancel'  => 0,
+    }),
+  ] };
 }
 
 =item bill OPTIONS
 }
 
 =item bill OPTIONS
@@ -479,7 +550,8 @@ sub bill {
         warn "Error reval-ing part_pkg->recur pkgpart ",
              $part_pkg->pkgpart, ": $@";
       } else {
         warn "Error reval-ing part_pkg->recur pkgpart ",
              $part_pkg->pkgpart, ": $@";
       } else {
-        #change this bit to use Date::Manip?
+        #change this bit to use Date::Manip? CAREFUL with timezones (see
+        # mailing list archive)
         #$sdate=$cust_pkg->bill || time;
         #$sdate=$cust_pkg->bill || $time;
         $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
         #$sdate=$cust_pkg->bill || time;
         #$sdate=$cust_pkg->bill || $time;
         $sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
@@ -493,9 +565,9 @@ sub bill {
       }
     }
 
       }
     }
 
-    warn "setup is undefinded" unless defined($setup);
-    warn "recur is undefinded" unless defined($recur);
-    warn "cust_pkg bill is undefinded" unless defined($cust_pkg->bill);
+    warn "setup is undefined" unless defined($setup);
+    warn "recur is undefined" unless defined($recur);
+    warn "cust_pkg bill is undefined" unless defined($cust_pkg->bill);
 
     if ( $cust_pkg_mod_flag ) {
       $error=$cust_pkg->replace($old_cust_pkg);
 
     if ( $cust_pkg_mod_flag ) {
       $error=$cust_pkg->replace($old_cust_pkg);
@@ -602,6 +674,7 @@ sub collect {
   my $invoice_time = $options{'invoice_time'} || time;
 
   my $total_owed = $self->balance;
   my $invoice_time = $options{'invoice_time'} || time;
 
   my $total_owed = $self->balance;
+  warn "collect: total owed $total_owed " if $Debug;
   return '' unless $total_owed > 0; #redundant?????
 
   #put below somehow?
   return '' unless $total_owed > 0; #redundant?????
 
   #put below somehow?
@@ -627,7 +700,7 @@ sub collect {
 
     next if qsearchs( 'cust_pay_batch', { 'invnum' => $cust_bill->invnum } );
 
 
     next if qsearchs( 'cust_pay_batch', { 'invnum' => $cust_bill->invnum } );
 
-    #warn "invnum ". $cust_bill->invnum. " (owed ". $cust_bill->owed. ", amount $amount, total_owed $total_owed)";
+    warn "invnum ". $cust_bill->invnum. " (owed ". $cust_bill->owed. ", amount $amount, total_owed $total_owed)" if $Debug;
 
     next unless $amount > 0;
 
 
     next unless $amount > 0;
 
@@ -733,7 +806,7 @@ sub collect {
           } elsif ( $processor eq 'cybercash3.2' ) {
             %result = &CCMckDirectLib3_2::SendCC2_1Server(@full_xaction);
           } else {
           } elsif ( $processor eq 'cybercash3.2' ) {
             %result = &CCMckDirectLib3_2::SendCC2_1Server(@full_xaction);
           } else {
-            return "Unkonwn real-time processor $processor\n";
+            return "Unknown real-time processor $processor\n";
           }
          
           #if ( $result{'MActionCode'} == 7 ) { #cybercash smps v.1.1.3
           }
          
           #if ( $result{'MActionCode'} == 7 ) { #cybercash smps v.1.1.3
@@ -759,7 +832,7 @@ sub collect {
           }
 
         } else {
           }
 
         } else {
-          return "Unkonwn real-time processor $processor\n";
+          return "Unknown real-time processor $processor\n";
         }
 
       } else { #batch card
         }
 
       } else { #batch card
@@ -790,10 +863,6 @@ sub collect {
       return "Unknown payment type ". $self->payby;
     }
 
       return "Unknown payment type ". $self->payby;
     }
 
-
-
-
-
   }
   '';
 
   }
   '';
 
@@ -930,7 +999,7 @@ sub check_invoicing_list {
 
 =head1 VERSION
 
 
 =head1 VERSION
 
-$Id: cust_main.pm,v 1.1 1999-08-04 09:03:53 ivan Exp $
+$Id: cust_main.pm,v 1.9 2001-01-31 07:21:00 ivan Exp $
 
 =head1 BUGS
 
 
 =head1 BUGS