From 1ff526055d1c14c45f1eab0c29e4ac47f350b32b Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 6 Apr 2016 14:09:42 -0700 Subject: [PATCH] add cust_event.no_action flag for events that conditionally execute, #36741 --- FS/FS/Schema.pm | 3 +- FS/FS/cust_event.pm | 53 +++++++++++++++++++++++++++--- FS/FS/part_event/Action/cust_bill_email.pm | 10 ++++-- FS/FS/part_event/Action/cust_bill_print.pm | 14 ++++++-- httemplate/search/cust_event.html | 8 ++++- httemplate/search/report_cust_event.html | 32 ++++++++++++++++-- 6 files changed, 106 insertions(+), 14 deletions(-) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 316ec4843..73b94d410 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -771,12 +771,13 @@ sub tables_hashref { '_date', @date_type, '', '', 'status', 'varchar', '', $char_d, '', '', 'statustext', 'text', 'NULL', '', '', '', + 'no_action', 'char', 'NULL', 1, '', '', ], 'primary_key' => 'eventnum', #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ], 'unique' => [], 'index' => [ ['eventpart'], ['tablenum'], ['status'], - ['statustext'], ['_date'], + ['statustext'], ['_date'], ['no_action'], ], }, diff --git a/FS/FS/cust_event.pm b/FS/FS/cust_event.pm index 1ef511a3d..57fb52ed2 100644 --- a/FS/FS/cust_event.pm +++ b/FS/FS/cust_event.pm @@ -55,6 +55,13 @@ L and L 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 @@ -142,6 +149,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; @@ -384,11 +392,46 @@ 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? + + if ( $param->{'event_status'} ) { + + my @status; + my ($done_Y, $done_N); + foreach (@{ $param->{'event_status'} }) { + if ($_ eq 'done_Y') { + $done_Y = 1; + } elsif ( $_ eq 'done_N' ) { + $done_N = 1; + } else { + push @status, $_; + } + } + if ( $done_Y or $done_N ) { + push @status, 'done'; + } + if ( @status ) { + push @search, "cust_event.status IN(" . + join(',', map "'$_'", @status) . + ')'; + } + + if ( $done_Y and not $done_N ) { + push @search, "cust_event.no_action IS NULL"; + } elsif ( $done_N and not $done_Y ) { + push @search, "cust_event.no_action = 'Y'"; + } # else they're both true, so don't add a constraint, or both false, + # and it doesn't matter. + + } # event_status + + # always hide initialization + push @search, 'cust_event.status != \'initial\''; if ( $param->{'custnum'} =~ /^(\d+)$/ ) { push @search, "cust_main.custnum = '$1'"; diff --git a/FS/FS/part_event/Action/cust_bill_email.pm b/FS/FS/part_event/Action/cust_bill_email.pm index 3331a4cb6..80bcaa1a7 100644 --- a/FS/FS/part_event/Action/cust_bill_email.pm +++ b/FS/FS/part_event/Action/cust_bill_email.pm @@ -20,12 +20,18 @@ sub option_fields { sub default_weight { 51; } sub do_action { - my( $self, $cust_bill ) = @_; + my( $self, $cust_bill, $cust_event ) = @_; my $cust_main = $cust_bill->cust_main; $cust_bill->set('mode' => $self->option('modenum')); - $cust_bill->email unless $cust_main->invoice_noemail; + if ( $cust_main->invoice_noemail ) { + # what about if the customer has no email dest? + $cust_event->set('no_action', 'Y'); + return "customer has invoice_noemail flag"; + } else { + $cust_bill->email; + } } 1; diff --git a/FS/FS/part_event/Action/cust_bill_print.pm b/FS/FS/part_event/Action/cust_bill_print.pm index b94e882ff..e6a27a34e 100644 --- a/FS/FS/part_event/Action/cust_bill_print.pm +++ b/FS/FS/part_event/Action/cust_bill_print.pm @@ -24,14 +24,22 @@ sub option_fields { sub default_weight { 51; } sub do_action { - my( $self, $cust_bill ) = @_; + my( $self, $cust_bill, $cust_event ) = @_; #my $cust_main = $self->cust_main($cust_bill); my $cust_main = $cust_bill->cust_main; $cust_bill->set('mode' => $self->option('modenum')); - $cust_bill->print unless $self->option('skip_nopost') - && ! grep { $_ eq 'POST' } $cust_main->invoicing_list; + if ( $self->option('skip_nopost') + && ! grep { $_ eq 'POST' } $cust_main->invoicing_list + ) { + # then skip customers + $cust_event->set('no_action', 'Y'); + return "customer doesn't receive postal invoices"; # as statustext + + } else { + $cust_bill->print; + } } 1; diff --git a/httemplate/search/cust_event.html b/httemplate/search/cust_event.html index f1b99510a..95e46d7a8 100644 --- a/httemplate/search/cust_event.html +++ b/httemplate/search/cust_event.html @@ -152,7 +152,12 @@ die "access denied" || $cgi->param('pkgnum') =~ /^(\d+)$/ ); -my $title = $cgi->param('failed') ? 'Failed billing events' : 'Billing events'; +my @statuses = $cgi->param('event_status'); +my $title = 'Billing events'; +if ( $statuses[0] eq 'failed' and !defined($statuses[1]) ) { + # tweak the title if we're showing only failed events + $title = 'Failed billing events'; +} my %search = (); @@ -161,6 +166,7 @@ for my $param (@scalars) { $search{$param} = scalar( $cgi->param($param) ) if $cgi->param($param); } +$search{event_status} = \@statuses; #lists my @lists = qw( payby eventpart ); diff --git a/httemplate/search/report_cust_event.html b/httemplate/search/report_cust_event.html index e0d6242b2..b09e66a6c 100644 --- a/httemplate/search/report_cust_event.html +++ b/httemplate/search/report_cust_event.html @@ -5,7 +5,6 @@ %>
- @@ -15,7 +14,8 @@ <% include( '/elements/tr-select-agent.html', 'disable_empty'=>0 ) %> <% include( '/elements/tr-select-cust_main-status.html', - 'label' => 'Status' + 'label' => 'Customer status', + # this field is just called 'status' ) %> @@ -34,6 +34,34 @@ ) %> +% if ( $cgi->param('failed') ) { + <& /elements/tr-fixed.html, + 'label' => 'Event status', + 'field' => 'event_status', + 'curr_value' => 'failed', + 'formatted_value' => 'Failed', + &> +% } else { + + % # 'initial' is not on here, since nobody needs to see it. also, + % # 'done_Y' and 'done_N' are shorthand for "done, and no_action + % # is null" and "done, and no_action = 'Y'". + <& /elements/tr-select.html, + 'label' => 'Event status', + 'field' => 'event_status', + 'multiple' => 1, + 'all_selected' => 1, + 'size' => 5, + 'options' => [ qw( done_Y done_N failed new locked ) ], + 'option_labels' => { done_Y => 'Completed', + done_N => 'Completed, no action taken', + failed => 'Failed', + new => 'Not yet processed', + locked => 'Running', + }, + &> +% } + <% include( '/elements/tr-input-beginning_ending.html' ) %>
-- 2.11.0