new bill script,
[freeside.git] / FS / bin / freeside-bill
diff --git a/FS/bin/freeside-bill b/FS/bin/freeside-bill
new file mode 100755 (executable)
index 0000000..8f2c32f
--- /dev/null
@@ -0,0 +1,122 @@
+#!/usr/bin/perl -Tw
+
+use strict;
+use Fcntl qw(:flock);
+use Date::Parse;
+use Getopt::Std;
+use FS::UID qw(adminsuidsetup swapuid);
+use FS::Record qw(qsearch qsearchs);
+use FS::cust_main;
+
+&untaint_argv; #what it sounds like  (eww)
+use vars qw($opt_a $opt_c $opt_i $opt_d);
+getopts("acid:");
+my $user = shift or die &usage;
+
+adminsuidsetup $user;
+
+my %bill_only = map { $_ => 1 } (
+  @ARGV ? @ARGV : ( map $_->custnum, qsearch('cust_main', {} ) )
+);
+
+#we're at now now (and later).
+my($time)= $main::opt_d ? str2time($main::opt_d) : $^T;
+
+# find packages w/ bill < time && cancel != '', and create corresponding
+# customer objects
+
+my($cust_main,%saw);
+foreach $cust_main (
+  map {
+    if (
+      ( $main::opt_a || ( ( $_->getfield('bill') || 0 ) <= $time ) )
+      && $bill_only{ $_->custnum }
+      && !$saw{ $_->custnum }++
+    ) {
+      qsearchs('cust_main',{'custnum'=> $_->custnum } );
+    } else {
+      ();
+    }
+  } ( qsearch('cust_pkg', { 'cancel' => '' }),
+      qsearch('cust_pkg', { 'cancel' => 0  }),
+    )
+) {
+
+  # and bill them
+
+  print "Billing customer #" . $cust_main->getfield('custnum') . "\n";
+  next;
+
+  my($error);
+
+  $error=$cust_main->bill('time'=>$time);
+  warn "Error billing,  customer #" . $cust_main->getfield('custnum') . 
+    ":" . $error if $error;
+
+  if ($main::opt_c) {
+    $error=$cust_main->collect('invoice_time'=>$time,
+                               'batch_card' => $main::opt_i ? 'no' : 'yes',
+                              );
+    warn "Error collecting customer #" . $cust_main->getfield('custnum') .
+      ":" . $error if $error;
+
+  #sleep 1;
+
+  }
+
+}
+
+# subroutines
+
+sub untaint_argv {
+  foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
+    $ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
+    $ARGV[$_]=$1;
+  }
+}
+
+sub usage {
+  die "Usage:\n\n  bill [ -c [ i ] ] [ -d 'date' ] [ -b ] user\n";
+}
+
+=head1 NAME
+
+freeside-bill - Command line (crontab, script) interface to customer billing.
+
+=head1 SYNOPSIS
+
+  freeside-bill [ -c [ -a ] [ -i ] ] [ -d 'date' ] user [ custnum custnum ... ]
+
+=head1 DESCRIPTION
+
+Bills customers.  Searches for customers who are due for billing and calls
+the bill and collect methods of a cust_main object.  See L<FS::cust_main>.
+
+  -c: Turn on collecting (you probably want this).
+
+  -a: Call collect even if there isn't a new invoice (probably a bad idea for
+      daily use)
+
+  -i: real-time billing (as opposed to batch billing).  only relevant
+      for credit cards.
+
+  -d: Pretent it's 'date'.  Date is in any format Date::Parse is happy with,
+      but be careful.
+
+user: From the mapsecrets file - see config.html from the base documentation
+
+custnum: if one or more customer numbers are specified, only bills those
+customers.  Otherwise, bills all customers.
+
+=head1 VERSION
+
+$Id: freeside-bill,v 1.1 1999-08-11 20:41:27 ivan Exp $
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::cust_main>, config.html from the base documentation
+
+=cut
+