- add init file installation to Makefile, add unified init file
[freeside.git] / FS / FS / cust_main.pm
index 5cc6cfd..445c695 100644 (file)
@@ -26,6 +26,7 @@ use FS::queue;
 use FS::part_pkg;
 use FS::part_bill_event;
 use FS::cust_bill_event;
+use FS::Msgcat qw(gettext);
 
 @ISA = qw( FS::Record );
 
@@ -99,7 +100,7 @@ FS::Record.  The following fields are currently supported:
 
 =item agentnum - agent (see L<FS::agent>)
 
-=item refnum - referral (see L<FS::part_referral>)
+=item refnum - Advertising source (see L<FS::part_referral>)
 
 =item first - name
 
@@ -512,6 +513,8 @@ and repalce methods.
 sub check {
   my $self = shift;
 
+  #warn "BEFORE: \n". $self->_dump;
+
   my $error =
     $self->ut_numbern('custnum')
     || $self->ut_number('agentnum')
@@ -529,14 +532,14 @@ sub check {
     || $self->ut_numbern('referral_custnum')
   ;
   #barf.  need message catalogs.  i18n.  etc.
-  $error .= "Please select a referral."
+  $error .= "Please select a advertising source."
     if $error =~ /^Illegal or empty \(numeric\) refnum: /;
   return $error if $error;
 
   return "Unknown agent"
     unless qsearchs( 'agent', { 'agentnum' => $self->agentnum } );
 
-  return "Unknown referral"
+  return "Unknown refnum"
     unless qsearchs( 'part_referral', { 'refnum' => $self->refnum } );
 
   return "Unknown referring custnum ". $self->referral_custnum
@@ -553,7 +556,9 @@ sub check {
     $self->ss("$1-$2-$3");
   }
 
-  unless ( $import ) {
+
+# bad idea to disable, causes billing to fail because of no tax rates later
+#  unless ( $import ) {
     unless ( qsearchs('cust_main_county', {
       'country' => $self->country,
       'state'   => '',
@@ -566,7 +571,7 @@ sub check {
           'country' => $self->country,
         } );
     }
-  }
+#  }
 
   $error =
     $self->ut_phonen('daytime', $self->country)
@@ -582,8 +587,9 @@ sub check {
   );
 
   if ( defined $self->dbdef_table->column('ship_last') ) {
-    if ( grep { $self->getfield($_) ne $self->getfield("ship_$_") } @addfields
-         && grep $self->getfield("ship_$_"), grep $_ ne 'state', @addfields
+    if ( scalar ( grep { $self->getfield($_) ne $self->getfield("ship_$_") }
+                       @addfields )
+         && scalar ( grep { $self->getfield("ship_$_") ne '' } @addfields )
        )
     {
       my $error =
@@ -638,12 +644,13 @@ sub check {
     my $payinfo = $self->payinfo;
     $payinfo =~ s/\D//g;
     $payinfo =~ /^(\d{13,16})$/
-      or return "Illegal credit card number: ". $self->payinfo;
+      or return gettext('invalid_card'); # . ": ". $self->payinfo;
     $payinfo = $1;
     $self->payinfo($payinfo);
     validate($payinfo)
-      or return "Illegal credit card number: ". $self->payinfo;
-    return "Unknown card type" if cardtype($self->payinfo) eq "Unknown";
+      or return gettext('invalid_card'); # . ": ". $self->payinfo;
+    return gettext('unknown_card_type')
+      if cardtype($self->payinfo) eq "Unknown";
 
   } elsif ( $self->payby eq 'BILL' ) {
 
@@ -685,7 +692,7 @@ sub check {
     $self->payname( $self->first. " ". $self->getfield('last') );
   } else {
     $self->payname =~ /^([\w \,\.\-\']+)$/
-      or return "Illegal billing name: ". $self->payname;
+      or return gettext('illegal_name'). " payname: ". $self->payname;
     $self->payname($1);
   }
 
@@ -694,6 +701,8 @@ sub check {
 
   $self->otaker(getotaker);
 
+  #warn "AFTER: \n". $self->_dump;
+
   ''; #no error
 }
 
@@ -810,6 +819,17 @@ sub cancel {
   grep { $_->cancel } $self->ncancelled_pkgs;
 }
 
+=item agent
+
+Returns the agent (see L<FS::agent>) for this customer.
+
+=cut
+
+sub agent {
+  my $self = shift;
+  qsearchs( 'agent', { 'agentnum' => $self->agentnum } );
+}
+
 =item bill OPTIONS
 
 Generates invoices (see L<FS::cust_bill>) for this customer.  Usually used in
@@ -976,10 +996,10 @@ sub bill {
         $total_recur += $recur;
         $taxable_setup += $setup
           unless $part_pkg->dbdef_table->column('setuptax')
-                 || $part_pkg->setuptax =~ /^Y$/i;
+                 && $part_pkg->setuptax =~ /^Y$/i;
         $taxable_recur += $recur
           unless $part_pkg->dbdef_table->column('recurtax')
-                 || $part_pkg->recurtax =~ /^Y$/i;
+                 && $part_pkg->recurtax =~ /^Y$/i;
       }
     }
 
@@ -1000,7 +1020,8 @@ sub bill {
         'state'   => $self->state,
         'county'  => $self->county,
         'country' => $self->country,
-    } );
+    } ) or die "fatal: can't find tax rate for state/county/country ".
+               $self->state. "/". $self->county. "/". $self->country. "\n";
     my $tax = sprintf( "%.2f",
       $taxable_charged * ( $cust_main_county->getfield('tax') / 100 )
     );
@@ -1094,7 +1115,7 @@ sub collect {
   my $dbh = dbh;
 
   my $balance = $self->balance;
-  warn "collect: balance $balance" if $Debug;
+  warn "collect customer". $self->custnum. ": balance $balance" if $Debug;
   unless ( $balance > 0 ) { #redundant?????
     $dbh->rollback if $oldAutoCommit; #hmm
     return '';
@@ -1127,45 +1148,57 @@ sub collect {
         grep { $_->seconds <= ( $invoice_time - $cust_bill->_date )
                && ! qsearchs( 'cust_bill_event', {
                                 'invnum'    => $cust_bill->invnum,
-                                'eventpart' => $_->eventpart       } )
+                                'eventpart' => $_->eventpart,
+                                'status'    => 'done',
+                                                                   } )
              }
           qsearch('part_bill_event', { 'payby'    => $self->payby,
                                        'disabled' => '',           } )
     ) {
-      #run callback
-      my $cust_main = $self; #for callback
-      my $error = eval $part_bill_event->eventcode;
 
-      if ( $error ) {
+      last unless $cust_bill->owed > 0; #don't run subsequent events if owed=0
 
-        warn "Error running invoice event (". $part_bill_event->eventcode.
-             "): $error";
+      warn "calling invoice event (". $part_bill_event->eventcode. ")\n"
+        if $Debug;
+      my $cust_main = $self; #for callback
+      my $error = eval $part_bill_event->eventcode;
 
+      my $status = '';
+      my $statustext = '';
+      if ( $@ ) {
+        $status = 'failed';
+        $statustext = $@;
+      } elsif ( $error ) {
+        $status = 'done';
+        $statustext = $error;
       } else {
+        $status = 'done'
+      }
 
-        #add cust_bill_event
-        my $cust_bill_event = new FS::cust_bill_event {
-          'invnum'    => $cust_bill->invnum,
-          'eventpart' => $part_bill_event->eventpart,
-          '_date'     => $invoice_time,
-        };
-        $cust_bill_event->insert;
-        if ( $error ) {
-          #$dbh->rollback if $oldAutoCommit;
-          #return "error: $error";
-
-          # gah, even with transactions.
-          $dbh->commit if $oldAutoCommit; #well.
-          my $e = 'WARNING: Event run but database not updated - '.
-                  'error inserting cust_bill_event, invnum #'. $cust_bill->invnum.
-                  ', eventpart '. $part_bill_event->eventpart.
-                  ": $error";
-          warn $e;
-          return $e;
-        }
-
+      #add cust_bill_event
+      my $cust_bill_event = new FS::cust_bill_event {
+        'invnum'     => $cust_bill->invnum,
+        'eventpart'  => $part_bill_event->eventpart,
+        '_date'      => $invoice_time,
+        'status'     => $status,
+        'statustext' => $statustext,
+      };
+      $error = $cust_bill_event->insert;
+      if ( $error ) {
+        #$dbh->rollback if $oldAutoCommit;
+        #return "error: $error";
+
+        # gah, even with transactions.
+        $dbh->commit if $oldAutoCommit; #well.
+        my $e = 'WARNING: Event run but database not updated - '.
+                'error inserting cust_bill_event, invnum #'. $cust_bill->invnum.
+                ', eventpart '. $part_bill_event->eventpart.
+                ": $error";
+        warn $e;
+        return $e;
       }
 
+
     }
 
   }
@@ -1582,7 +1615,7 @@ sub charge {
 
   my $part_pkg = new FS::part_pkg ( {
     'pkg'      => $pkg || 'One-time charge',
-    'comment'  => $comment,
+    'comment'  => $comment || '$'. sprintf("%.2f".$amount),
     'setup'    => $amount,
     'freq'     => 0,
     'recur'    => '0',