future package unsuspend date, #14144
[freeside.git] / FS / FS / Cron / bill.pm
index 7388733..8d1223b 100644 (file)
@@ -7,6 +7,7 @@ use Date::Parse;
 use DBI 1.33; #The "clone" method was added in DBI 1.33. 
 use FS::UID qw( dbh driver_name );
 use FS::Record qw( qsearch qsearchs );
+use FS::Misc::DateTime qw( day_end );
 use FS::queue;
 use FS::cust_main;
 use FS::part_event;
@@ -92,6 +93,7 @@ sub bill {
           'check_freq'   => $check_freq,
           'resetup'      => ( $opt{'s'} ? $opt{'s'} : 0 ),
           'not_pkgpart'  => $opt{'g'}, #$not_pkgpart,
+          'one_recur'    => $opt{'o'},
       );
 
       if ( $opt{'m'} ) {
@@ -144,7 +146,7 @@ sub bill {
 #      (or now, if no -d switch was given).
 #
 #  -n: When used with "-d" and/or "-y", specifies that invoices should be dated
-#      with today's date, irregardless of the pretend date used to pre-generate
+#      with today's date, regardless of the pretend date used to pre-generate
 #      the invoices.
 #
 #  -p: Only process customers with the specified payby (I<CARD>, I<DCRD>, I<CHEK>, I<DCHK>, I<BILL>, I<COMP>, I<LECB>)
@@ -155,6 +157,15 @@ sub bill {
 #
 #  -l: debugging level
 
+=item bill_where
+
+Internal function.  Returns a WHERE clause to select the set of customers who 
+have actionable packages (no setup date, or bill date in the past, or expire 
+or adjourn dates in the past) or events (does a complete where_conditions_sql 
+scan).
+
+=cut
+
 sub bill_where {
   my( %opt ) = @_;
 
@@ -184,6 +195,8 @@ sub bill_where {
   # generate where_pkg/where_event search clause
   ###
 
+  my $billtime = day_end($time);
+
   # select * from cust_main where
   my $where_pkg = <<"END";
     EXISTS(
@@ -195,9 +208,10 @@ sub bill_where {
                            OR ( start_date IS NOT NULL AND start_date <= $^T )
                          )
                    )
-                OR bill  IS NULL OR bill  <= $time 
+                OR bill  IS NULL OR bill  <= $billtime 
                 OR ( expire  IS NOT NULL AND expire  <= $^T )
                 OR ( adjourn IS NOT NULL AND adjourn <= $^T )
+                OR ( resume  IS NOT NULL AND resume  <= $^T )
               )
     )
 END
@@ -206,12 +220,15 @@ END
   my $where_event = join(' OR ', map {
     my $eventtable = $_;
 
+    # joins and where clauses to test event conditions
     my $join  = FS::part_event_condition->join_conditions_sql(  $eventtable );
     my $where = FS::part_event_condition->where_conditions_sql( $eventtable,
                                                                 'time'=>$time,
                                                               );
     $where = $where ? "AND $where" : '';
 
+    # test to return all applicable part_events (defined on this eventtable,
+    # not disabled, check_freq correct, and all event conditions true)
     my $are_part_event = 
       "EXISTS ( SELECT 1 FROM part_event $join
                   WHERE check_freq = '$check_freq'
@@ -224,8 +241,11 @@ END
     if ( $eventtable eq 'cust_main' ) { 
       $are_part_event;
     } else {
-      "EXISTS ( SELECT 1 FROM $eventtable
-                  WHERE cust_main.custnum = $eventtable.custnum
+      my $cust_join = FS::part_event->eventtables_cust_join->{$eventtable}
+                      || '';
+      my $custnum = FS::part_event->eventtables_custnum->{$eventtable};
+      "EXISTS ( SELECT 1 FROM $eventtable $cust_join
+                  WHERE cust_main.custnum = $custnum
                     AND $are_part_event
               )
       ";