price plans web gui 1st pass, oh my
[freeside.git] / FS / FS / cust_main.pm
index d791c13..f99a15e 100644 (file)
@@ -98,6 +98,8 @@ FS::cust_main - Object methods for cust_main records
 
   @cust_pkg = $record->ncancelled_pkgs;
 
+  @cust_pkg = $record->suspended_pkgs;
+
   $error = $record->bill;
   $error = $record->bill %options;
   $error = $record->bill 'time' => $time;
@@ -214,10 +216,9 @@ otherwise returns false.
 
 CUST_PKG_HASHREF: If you pass a Tie::RefHash data structure to the insert
 method containing FS::cust_pkg and FS::svc_I<tablename> objects, all records
-are inserted atomicly, or the transaction is rolled back (this requries a 
-transactional database).  Passing an empty hash reference is equivalent to
-not supplying this parameter.  There should be a better explanation of this,
-but until then, here's an example:
+are inserted atomicly, or the transaction is rolled back.  Passing an empty
+hash reference is equivalent to not supplying this parameter.  There should be
+a better explanation of this, but until then, here's an example:
 
   use Tie::RefHash;
   tie %hash, 'Tie::RefHash'; #this part is important
@@ -231,7 +232,7 @@ INVOICING_LIST_ARYREF: If you pass an arrarref to the insert method, it will
 be set as the invoicing list (see L<"invoicing_list">).  Errors return as
 expected and rollback the entire transaction; it is not necessary to call 
 check_invoicing_list first.  The invoicing_list is set after the records in the
-CUST_PKG_HASHREF above are inserted, so it is now possible set set an
+CUST_PKG_HASHREF above are inserted, so it is now possible to set an
 invoicing_list destination to the newly-created svc_acct.  Here's an example:
 
   $cust_main->insert( {}, [ $email, 'POST' ] );
@@ -708,6 +709,68 @@ sub ncancelled_pkgs {
   ] };
 }
 
+=item suspended_pkgs
+
+Returns all suspended packages (see L<FS::cust_pkg>) for this customer.
+
+=cut
+
+sub suspended_pkgs {
+  my $self = shift;
+  grep { $_->susp } $self->ncancelled_pkgs;
+}
+
+=item unflagged_suspended_pkgs
+
+Returns all unflagged suspended packages (see L<FS::cust_pkg>) for this
+customer (thouse packages without the `manual_flag' set).
+
+=cut
+
+sub unflagged_suspended_pkgs {
+  my $self = shift;
+  return $self->suspended_pkgs
+    unless dbdef->table('cust_pkg')->column('manual_flag');
+  grep { ! $_->manual_flag } $self->suspended_pkgs;
+}
+
+=item unsuspended_pkgs
+
+Returns all unsuspended (and uncancelled) packages (see L<FS::cust_pkg>) for
+this customer.
+
+=cut
+
+sub unsuspended_pkgs {
+  my $self = shift;
+  grep { ! $_->susp } $self->ncancelled_pkgs;
+}
+
+=item unsuspend
+
+Unsuspends all unflagged suspended packages (see L</unflagged_suspended_pkgs>
+and L<FS::cust_pkg>) for this customer.  Always returns a list: an empty list
+on success or a list of errors.
+
+=cut
+
+sub unsuspend {
+  my $self = shift;
+  grep { $_->unsuspend } $self->suspended_pkgs;
+}
+
+=item suspend
+
+Suspends all unsuspended packages (see L<FS::cust_pkg>) for this customer.
+Always returns a list: an empty list on success or a list of errors.
+
+=cut
+
+sub suspend {
+  my $self = shift;
+  grep { $_->suspend } $self->unsuspended_pkgs;
+}
+
 =item bill OPTIONS
 
 Generates invoices (see L<FS::cust_bill>) for this customer.  Usually used in
@@ -940,7 +1003,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.
 
@@ -1152,9 +1215,9 @@ sub collect {
           }
 
           my @invoicing_list = grep { $_ ne 'POST' } $self->invoicing_list;
-          if ( $conf->exists('emailinvoiceonly') ) {
-            @invoicing_list = $self->default_invoicing_list
-              unless @invoicing_list;
+          if ( $conf->exists('emailinvoiceauto')
+               || ( $conf->exists('emailinvoiceonly') && ! @invoicing_list ) ) {
+            push @invoicing_list, $self->default_invoicing_list;
           }
           my $email = $invoicing_list[0];
 
@@ -1403,7 +1466,7 @@ sub apply_payments {
 
   }
 
-  # return 0; 
+  return $self->total_unapplied_payments;
 }
 
 =item total_credited
@@ -1495,15 +1558,17 @@ sub invoicing_list {
     } else {
       @cust_main_invoice = ();
     }
+    my %seen = map { $_->address => 1 } @cust_main_invoice;
     foreach my $address ( @{$arrayref} ) {
-      unless ( grep { $address eq $_->address } @cust_main_invoice ) {
-        my $cust_main_invoice = new FS::cust_main_invoice ( {
-          'custnum' => $self->custnum,
-          'dest'    => $address,
-        } );
-        my $error = $cust_main_invoice->insert;
-        warn $error if $error;
-      } 
+      #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 ( {
+        'custnum' => $self->custnum,
+        'dest'    => $address,
+      } );
+      my $error = $cust_main_invoice->insert;
+      warn $error if $error;
     }
   }
   if ( $self->custnum ) {
@@ -1539,6 +1604,8 @@ sub check_invoicing_list {
 
 =item default_invoicing_list
 
+Returns the email addresses of any 
+
 =cut
 
 sub default_invoicing_list {
@@ -1583,6 +1650,40 @@ sub referral_cust_main {
   @cust_main;
 }
 
+=item referral_cust_pkg [ DEPTH ]
+
+Like referral_cust_main, except returns a flat list of all unsuspended packages
+for each customer.  The number of items in this list may be useful for
+comission calculations (perhaps after a grep).
+
+=cut
+
+sub referral_cust_pkg {
+  my $self = shift;
+  my $depth = @_ ? shift : 1;
+
+  map { $_->unsuspended_pkgs }
+    grep { $_->unsuspended_pkgs }
+      $self->referral_cust_main($depth);
+}
+
+=item credit AMOUNT, REASON
+
+Applies a credit to this customer.  If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+sub credit {
+  my( $self, $amount, $reason ) = @_;
+  my $cust_credit = new FS::cust_credit {
+    'custnum' => $self->custnum,
+    'amount'  => $amount,
+    'reason'  => $reason,
+  };
+  $cust_credit->insert;
+}
+
 =back
 
 =head1 SUBROUTINES
@@ -1724,7 +1825,7 @@ sub append_fuzzyfiles {
 
 =head1 VERSION
 
-$Id: cust_main.pm,v 1.37 2001-09-25 18:03:04 ivan Exp $
+$Id: cust_main.pm,v 1.40 2001-10-15 10:42:28 ivan Exp $
 
 =head1 BUGS