From fdd00d4549faaa9de8952402f77fa86d0b8b22ee Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Mon, 12 Mar 2012 20:24:22 -0700 Subject: [PATCH] "day-of-month of customer signup" condition, #16827 --- FS/FS/part_event.pm | 9 ++--- FS/FS/part_event/Condition/signupdate_day.pm | 54 ++++++++++++++++++++++++++++ httemplate/browse/part_event.html | 3 +- httemplate/view/part_event-targets.html | 18 ++++++++-- 4 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 FS/FS/part_event/Condition/signupdate_day.pm diff --git a/FS/FS/part_event.pm b/FS/FS/part_event.pm index 31d2afd23..62f16fa1c 100644 --- a/FS/FS/part_event.pm +++ b/FS/FS/part_event.pm @@ -253,7 +253,7 @@ sub templatename { } } -=item targets +=item targets OPTIONS Returns all objects (of type C, for this object's C) eligible for processing under this event, as of right now. @@ -268,7 +268,8 @@ but can be useful when configuring events. sub targets { my $self = shift; - my $time = time; # $opt{'time'}? + my %opt = @_; + my $time = $opt{'time'} || time; my $eventpart = $self->eventpart; $eventpart =~ /^\d+$/ or die "bad eventpart $eventpart"; @@ -305,8 +306,8 @@ sub targets { }); my @tested_objects; foreach my $object ( @objects ) { - my $cust_event = $self->new_cust_event($object, 'time' => $time); - next unless $cust_event->test_conditions; + my $cust_event = $self->new_cust_event($object); + next unless $cust_event->test_conditions('time' => $time); $object->set('cust_event', $cust_event); push @tested_objects, $object; diff --git a/FS/FS/part_event/Condition/signupdate_day.pm b/FS/FS/part_event/Condition/signupdate_day.pm new file mode 100644 index 000000000..dbe9e60a1 --- /dev/null +++ b/FS/FS/part_event/Condition/signupdate_day.pm @@ -0,0 +1,54 @@ +package FS::part_event::Condition::signupdate_day; + +use strict; +use Tie::IxHash; + +use base qw( FS::part_event::Condition ); + +sub description { + "Customer signed up on the same day of month as today"; +} + +sub option_fields { + ( + 'delay' => { label => 'Delay additional days', + type => 'text', + value => '0', + }, + ); +} + +sub condition { + my( $self, $object, %opt ) = @_; + + my $cust_main = $self->cust_main($object); + + my ($today) = (localtime($opt{'time'}))[3]; + + my $delay = $self->option('delay') || 0; + my $signupday = ((localtime($cust_main->signupdate + $delay * 86400))[3] - 1) + % 28 + 1; + + $today == $signupday; +} + +sub condition_sql { + my( $class, $table, %opt ) = @_; + my $mday; + if ( $opt{'driver_name'} eq 'Pg' ) { + $mday = sub{ "EXTRACT( DAY FROM TO_TIMESTAMP($_[0]) )::INTEGER" }; + } + elsif ( $opt{'driver_name'} eq 'mysql' ) { + $mday = sub{ "DAY( FROM_UNIXTIME($_[0]) )" }; + } + else { + return 'true'; + } + + my $delay = $class->condition_sql_option_integer('delay', + $opt{'driver_name'}); # returns 0 for null + $mday->($opt{'time'}) . ' = '. + '(' . $mday->("cust_main.signupdate + $delay * 86400") . ' - 1) % 28 + 1'; +} + +1; diff --git a/httemplate/browse/part_event.html b/httemplate/browse/part_event.html index 6be28602d..03996435e 100644 --- a/httemplate/browse/part_event.html +++ b/httemplate/browse/part_event.html @@ -45,7 +45,8 @@ my $link = [ $p.'edit/part_event.html?', 'eventpart' ]; my $event_sub = sub { my $part_event = shift; my $onclick = include('/elements/popup_link_onclick.html', - action => $p.'view/part_event-targets.html?'.$part_event->eventpart, + action => $p.'view/part_event-targets.html?eventpart='. + $part_event->eventpart, actionlabel => 'Event query - '.$part_event->event, width => 650, height => 420, diff --git a/httemplate/view/part_event-targets.html b/httemplate/view/part_event-targets.html index c5faccfd6..2029fd4bc 100644 --- a/httemplate/view/part_event-targets.html +++ b/httemplate/view/part_event-targets.html @@ -3,6 +3,16 @@ 'title' => 'Event query - '.$part_event->event, } &> +
url%> METHOD="GET"> +When event is run on <& /elements/input-date-field.html, { + 'name' => 'date', + 'value' => $time, + 'format' => FS::Conf->new->config('date_format') || '%m/%d/%Y', +} &> + + +
+

% if ( $objects > 0 ) { <% emt("[quant,_1,$label]", $objects) %> % if ( $part_event->eventtable ne 'cust_main' ) { @@ -18,8 +28,8 @@ % my @rowcolors = ('ffffff','eeeeee'); % my $row = 0; - % foreach my $object (@targets) { + % # now works for all eventtables, including cust_pkg % my $link = $p . 'view/' . $part_event->eventtable . '.cgi?' . % $object->$pkey; @@ -65,12 +75,14 @@ die "access denied" unless $curuser->access_right('Edit billing events') || $curuser->access_right('Edit global billing events'); -my ($eventpart) = $cgi->keywords; +my ($eventpart) = $cgi->param('eventpart'); $eventpart =~ /^\d+$/ or die 'illegal eventpart'; +my $time = parse_datetime($cgi->param('date')) || time; + my $part_event = FS::part_event->by_key($eventpart) or die "Event definition $eventpart not found.\n"; -my @targets = $part_event->targets; +my @targets = $part_event->targets('time' => $time); my $total = @targets; # in imitation of search/elements/search-html.html -- 2.11.0