From f9d1cb1d57375470c969ef6e00d48f6a91a72874 Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 21 Aug 2010 00:21:23 +0000 Subject: [PATCH] new event conditions, RT#8896 --- FS/FS/part_event/Condition/once_every.pm | 46 +++++++++++++++++ FS/FS/part_event/Condition/once_perinv.pm | 57 ++++++++++++++++++++++ FS/FS/part_event/Condition/pkg_next_bill_within.pm | 51 +++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 FS/FS/part_event/Condition/once_every.pm create mode 100644 FS/FS/part_event/Condition/once_perinv.pm create mode 100644 FS/FS/part_event/Condition/pkg_next_bill_within.pm diff --git a/FS/FS/part_event/Condition/once_every.pm b/FS/FS/part_event/Condition/once_every.pm new file mode 100644 index 000000000..a0d9d6802 --- /dev/null +++ b/FS/FS/part_event/Condition/once_every.pm @@ -0,0 +1,46 @@ +package FS::part_event::Condition::once_every; + +use strict; +use FS::Record qw( qsearch ); +use FS::part_event; +use FS::cust_event; + +use base qw( FS::part_event::Condition ); + +sub description { "Don't run this event more than once in interval"; } + +# Runs the event at most "once every X". + +sub option_fields { + ( + 'run_delay' => { label=>'Interval', type=>'freq', value=>'1m', }, + ); +} + +sub condition { + my($self, $object, %opt) = @_; + + my $obj_pkey = $object->primary_key; + my $tablenum = $object->$obj_pkey(); + + my $max_date = $self->option_age_from('run_delay',$opt{'time'}); + + my @existing = qsearch( { + 'table' => 'cust_event', + 'hashref' => { + 'eventpart' => $self->eventpart, + 'tablenum' => $tablenum, + 'status' => { op=>'!=', value=>'failed' }, + '_date' => { op=>'>=', value=>$max_date }, + }, + 'extra_sql' => ( $opt{'cust_event'}->eventnum =~ /^(\d+)$/ + ? " AND eventnum != $1 " + : '' + ), + } ); + + ! scalar(@existing); + +} + +1; diff --git a/FS/FS/part_event/Condition/once_perinv.pm b/FS/FS/part_event/Condition/once_perinv.pm new file mode 100644 index 000000000..f85a05665 --- /dev/null +++ b/FS/FS/part_event/Condition/once_perinv.pm @@ -0,0 +1,57 @@ +package FS::part_event::Condition::once_perinv; + +use strict; +use FS::Record qw( qsearch ); +use FS::part_event; +use FS::cust_event; + +use base qw( FS::part_event::Condition ); + +sub description { "Run only once for each time the package has been billed"; } + +# Run the event, at most, a number of times equal to the number of +# distinct invoices that contain line items from this package. + +sub eventtable_hashref { + { 'cust_main' => 0, + 'cust_bill' => 0, + 'cust_pkg' => 1, + }; +} + +sub condition { + my($self, $cust_pkg, %opt) = @_; + + my %invnum; + $invnum{$_->invnum} = 1 + foreach ( qsearch('cust_bill_pkg', { 'pkgnum' => $cust_pkg->pkgnum }) ); + my @events = qsearch( { + 'table' => 'cust_event', + 'hashref' => { 'eventpart' => $self->eventpart, + 'status' => { op=>'!=', value=>'failed' }, + 'tablenum' => $cust_pkg->pkgnum, + }, + 'extra_sql' => ( $opt{'cust_event'}->eventnum =~ /^(\d+)$/ + ? " AND eventnum != $1 " : '' ), + } ); + scalar(@events) < scalar(keys %invnum); +} + +sub condition_sql { + my( $self, $table ) = @_; + + "( + ( SELECT COUNT(distinct(invnum)) + FROM cust_bill_pkg + WHERE cust_bill_pkg.pkgnum = cust_pkg.pkgnum ) + > + ( SELECT COUNT(*) + FROM cust_event + WHERE cust_event.eventpart = part_event.eventpart + AND cust_event.tablenum = cust_pkg.pkgnum + AND status != 'failed' ) + )" + +} + +1; diff --git a/FS/FS/part_event/Condition/pkg_next_bill_within.pm b/FS/FS/part_event/Condition/pkg_next_bill_within.pm new file mode 100644 index 000000000..dc16ce843 --- /dev/null +++ b/FS/FS/part_event/Condition/pkg_next_bill_within.pm @@ -0,0 +1,51 @@ +package FS::part_event::Condition::pkg_next_bill_within; + +use strict; +use base qw( FS::part_event::Condition ); +use FS::Record qw( qsearch ); + +sub description { + 'Next bill date within interval'; +} + +# Run the event when the next bill date is within X days. +# To clarify, that's within X days _after_ the current date, +# not before. +# Combine this with a "once_every" condition so that the event +# won't repeat every day until the bill date. + +sub eventtable_hashref { + { 'cust_main' => 0, + 'cust_bill' => 0, + 'cust_pkg' => 1, + }; +} + +sub option_fields { + ( + 'within' => { 'label' => 'Bill date within', + 'type' => 'freq', + }, + # possibly "field" to allow date fields besides 'bill'? + ); +} + +sub condition { + my( $self, $cust_pkg, %opt ) = @_; + + my $pkg_date = $cust_pkg->get('bill') or return 0; + $pkg_date = $self->option_age_from('within', $pkg_date ); + + $opt{'time'} >= $pkg_date; + +} + +#XXX write me for efficiency +sub condition_sql { + my ($self, $table, %opt) = @_; + $opt{'time'}.' >= '. + $self->condition_sql_option_age_from('within', 'cust_pkg.bill') +} + +1; + -- 2.11.0