remove "failed billing events" report, and add "completed with an error" status searc...
[freeside.git] / FS / FS / cust_event.pm
index b5436d0..094c4fa 100644 (file)
@@ -9,9 +9,10 @@ use FS::Record qw( qsearch qsearchs dbdef );
 use FS::cust_main;
 use FS::cust_pkg;
 use FS::cust_bill;
+use FS::cust_pay;
 use FS::svc_acct;
 
-$DEBUG = 0;
+$DEBUG = 1;
 $me = '[FS::cust_event]';
 
 =head1 NAME
@@ -53,6 +54,13 @@ L<Time::Local> and L<Date::Parse> for conversion functions.
 
 =item statustext - additional status detail (i.e. error or progress message)
 
+=item no_action - 'Y' if the event action wasn't performed. Some actions
+contain an internal check to see if the action is going to be impossible (for
+example, emailing a notice to a customer who has no email address), and if so,
+won't attempt the action. It shouldn't be reported as a failure because
+there's no need to retry it. However, the action should set no_action = 'Y'
+so that there's a record.
+
 =back
 
 =head1 METHODS
@@ -140,6 +148,7 @@ sub check {
     || $self->ut_number('_date')
     || $self->ut_enum('status', [qw( new locked done failed initial)])
     || $self->ut_anything('statustext')
+    || $self->ut_flag('no_action')
   ;
   return $error if $error;
 
@@ -236,7 +245,13 @@ sub do_event {
     $statustext = "Error running ". $part_event->action. " action: $@";
   } elsif ( $error ) {
     $status = 'done';
-    $statustext = $error;
+    if ( $error eq 'N/A' ) {
+      # archaic way to indicate no-op completion of spool_csv (and maybe
+      # other events)?
+      $self->no_action('Y');
+    } else {
+      $statustext = $error;
+    }
   } else {
     $status = 'done';
   }
@@ -302,14 +317,16 @@ sub join_sql {
        JOIN part_event USING ( eventpart )
   LEFT JOIN cust_bill ON ( eventtable = 'cust_bill' AND tablenum = invnum  )
   LEFT JOIN cust_pkg  ON ( eventtable = 'cust_pkg'  AND tablenum = pkgnum  )
-
+  LEFT JOIN cust_pay  ON ( eventtable = 'cust_pay'  AND tablenum = paynum  )
   LEFT JOIN cust_svc  ON ( eventtable = 'svc_acct'  AND tablenum = svcnum  )
   LEFT JOIN cust_pkg AS cust_pkg_for_svc ON ( cust_svc.pkgnum = cust_pkg_for_svc.pkgnum )
-  LEFT JOIN cust_main ON (    ( eventtable = 'cust_main' AND tablenum = cust_main.custnum )
-                           OR ( eventtable = 'cust_bill' AND cust_bill.custnum = cust_main.custnum )
-                           OR ( eventtable = 'cust_pkg'  AND cust_pkg.custnum  = cust_main.custnum )
-                           OR ( eventtable = 'svc_acct'  AND cust_pkg_for_svc.custnum  = cust_main.custnum )
-                         )
+  LEFT JOIN cust_main ON (
+       ( eventtable = 'cust_main' AND tablenum = cust_main.custnum )
+    OR ( eventtable = 'cust_bill' AND cust_bill.custnum = cust_main.custnum )
+    OR ( eventtable = 'cust_pkg'  AND cust_pkg.custnum  = cust_main.custnum )
+    OR ( eventtable = 'cust_pay'  AND cust_pay.custnum  = cust_main.custnum )
+    OR ( eventtable = 'svc_acct'  AND cust_pkg_for_svc.custnum  = cust_main.custnum )
+  )
   ";
 
 }
@@ -337,10 +354,6 @@ specified in HASHREF.  Valid parameters are
 
 =item ending
 
-=item payby
-
-=item 
-
 =back
 
 =cut
@@ -373,11 +386,65 @@ sub search_sql_where {
     push @search, "cust_event._date <= $1";
   }
 
-  if ( $param->{'failed'} ) {
-    push @search, "statustext != ''",
-                  "statustext IS NOT NULL",
-                  "statustext != 'N/A'";
-  }
+  #if ( $param->{'failed'} ) {
+  #  push @search, "statustext != ''",
+  #                "statustext IS NOT NULL",
+  #                "statustext != 'N/A'";
+  #}
+  # huh?
+
+  my @event_status = ref($param->{'event_status'})
+                    ? @{ $param->{'event_status'} }
+                    : split(',', $param->{'event_status'});
+  if ( @event_status ) {
+    my @status;
+
+    my ($done_Y, $done_N, $done_S);
+    # done_Y: action was taken
+    # done_N: action was not taken
+    # done_S: status message returned
+    foreach (@event_status) {
+      if ($_ eq 'done_Y') {
+        $done_Y = 1;
+      } elsif ( $_ eq 'done_N' ) {
+        $done_N = 1;
+      } elsif ( $_ eq 'done_S' ) {
+        $done_S = 1;
+      } else {
+        push @status, $_;
+      }
+    }
+    if ( $done_Y or $done_N or $done_S ) {
+      push @status, 'done';
+    }
+    if ( @status ) {
+      push @search, "cust_event.status IN(" .
+                    join(',', map "'$_'", @status) .
+                    ')';
+    }
+
+    # done_S status should include only those where statustext is not null,
+    # and done_Y should include only those where it is.
+    if ( $done_Y and $done_N and $done_S ) {
+      # then not necessary
+    } else {
+      my @done_status;
+      if ( $done_Y ) {
+        push @done_status, "(cust_event.no_action IS NULL AND cust_event.statustext IS NULL)";
+      }
+      if ( $done_N ) {
+        push @done_status, "(cust_event.no_action = 'Y')";
+      }
+      if ( $done_S ) {
+        push @done_status, "(cust_event.no_action IS NULL AND cust_event.statustext IS NOT NULL)";
+      }
+      push @search, join(' OR ', @done_status) if @done_status;
+    }
+
+  } # event_status
+
+  # always hide initialization
+  push @search, 'cust_event.status != \'initial\'';
 
   if ( $param->{'custnum'} =~ /^(\d+)$/ ) {
     push @search, "cust_main.custnum = '$1'";
@@ -393,6 +460,11 @@ sub search_sql_where {
                   "tablenum = '$1'";
   }
 
+  if ( $param->{'paynum'} =~ /^(\d+)$/ ) {
+    push @search, "part_event.eventtable = 'cust_pay'",
+                  "tablenum = '$1'";
+  }
+
   if ( $param->{'svcnum'} =~ /^(\d+)$/ ) {
     push @search, "part_event.eventtable = 'svc_acct'",
                   "tablenum = '$1'";
@@ -481,9 +553,10 @@ sub re_X {
     my $modenum = $part_event->option('modenum') || '';
     my $invoice_from = $part_event->option('agent_invoice_from') || '';
     $cust_X->set('mode' => $modenum);
-    $cust_X->$method( { template      => $template,
-                        modenum       => $modenum,
-                        invoice_from  => $invoice_from } );
+    $cust_X->$method( { template => $template,
+                        modenum  => $modenum,
+                        from     => $invoice_from,
+                    } );
 
     if ( $job ) { #progressbar foo
       $num++;