diff options
author | cvs2git <cvs2git> | 2010-11-05 19:05:57 +0000 |
---|---|---|
committer | cvs2git <cvs2git> | 2010-11-05 19:05:57 +0000 |
commit | aaf8baf3662e16e9414de236a39f8801a8c41b01 (patch) | |
tree | 2cda603e4311b3e80f79b93d9bcce3a7c7c2d053 /FS/FS/part_event | |
parent | 995a145c931164347683071c95c6754379d36604 (diff) | |
parent | 9b2de4257b6a2877434008188e52b8ef71ff339d (diff) |
This commit was manufactured by cvs2svn to create branch
'FREESIDE_2_1_BRANCH'.
Diffstat (limited to 'FS/FS/part_event')
-rw-r--r-- | FS/FS/part_event/Action/notice.pm | 2 | ||||
-rw-r--r-- | FS/FS/part_event/Action/notice_to.pm | 55 | ||||
-rw-r--r-- | FS/FS/part_event/Condition.pm | 22 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/balance_age.pm | 2 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/balance_credit_limit.pm | 32 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/cust_bill_past_due.pm | 41 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/cust_status.pm | 8 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/has_referral_custnum.pm | 10 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/once_every.pm | 46 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/once_perinv.pm | 57 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/payby.pm | 16 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/pkg_age.pm | 16 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/pkg_next_bill_within.pm | 51 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/pkg_recurring.pm | 9 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/pkg_status.pm | 7 |
15 files changed, 346 insertions, 28 deletions
diff --git a/FS/FS/part_event/Action/notice.pm b/FS/FS/part_event/Action/notice.pm index 1269653..8e22c68 100644 --- a/FS/FS/part_event/Action/notice.pm +++ b/FS/FS/part_event/Action/notice.pm @@ -5,7 +5,7 @@ use base qw( FS::part_event::Action ); use FS::Record qw( qsearchs ); use FS::msg_template; -sub description { 'Send a notice from a message template'; } +sub description { 'Email a notice to the customer\'s billing address'; } #sub eventtable_hashref { # { 'cust_main' => 1, diff --git a/FS/FS/part_event/Action/notice_to.pm b/FS/FS/part_event/Action/notice_to.pm new file mode 100644 index 0000000..194aeb8 --- /dev/null +++ b/FS/FS/part_event/Action/notice_to.pm @@ -0,0 +1,55 @@ +package FS::part_event::Action::notice_to; + +use strict; +use base qw( FS::part_event::Action ); +use FS::Record qw( qsearchs ); +use FS::msg_template; + +sub description { 'Email a notice to a specific address'; } + +#sub eventtable_hashref { +# { 'cust_main' => 1, +# 'cust_bill' => 1, +# 'cust_pkg' => 1, +# }; +#} + +sub option_fields { + ( + 'to' => { 'label' => 'Destination', + 'type' => 'text', + 'size' => 30, + }, + 'msgnum' => { 'label' => 'Template', + 'type' => 'select-table', + 'table' => 'msg_template', + 'name_col' => 'msgname', + 'disable_empty' => 1, + }, + ); +} + +sub default_weight { 56; } #? + +sub do_action { + my( $self, $object ) = @_; + + my $cust_main = $self->cust_main($object); + + my $msgnum = $self->option('msgnum'); + + my $msg_template = qsearchs('msg_template', { 'msgnum' => $msgnum } ) + or die "Template $msgnum not found"; + + my $to = $self->option('to') + or die "Can't send notice without a destination address"; + + $msg_template->send( + 'to' => $to, + 'cust_main' => $cust_main, + 'object' => $object, + ); + +} + +1; diff --git a/FS/FS/part_event/Condition.pm b/FS/FS/part_event/Condition.pm index ddd8a61..90b8385 100644 --- a/FS/FS/part_event/Condition.pm +++ b/FS/FS/part_event/Condition.pm @@ -306,6 +306,28 @@ sub condition_sql_option { )"; } +#c.f. part_event_condition_option.pm / part_event_condition_option_option +#used for part_event/Condition/payby.pm +sub condition_sql_option_option { + my( $class, $option ) = @_; + + ( my $condname = $class ) =~ s/^.*:://; + + my $optionnum = + "( SELECT optionnum FROM part_event_condition_option + WHERE part_event_condition_option.eventconditionnum = + cond_$condname.eventconditionnum + AND part_event_condition_option.optionname = '$option' + AND part_event_condition_option.optionvalue = 'HASH' + )"; + + "( SELECT optionname FROM part_event_condition_option_option + WHERE optionnum = $optionnum + )"; + +} + + =item condition_sql_option_age_from OPTION FROM_TIMESTAMP This is a class method that returns an SQL fragment that will retreive a diff --git a/FS/FS/part_event/Condition/balance_age.pm b/FS/FS/part_event/Condition/balance_age.pm index fc34612..8480659 100644 --- a/FS/FS/part_event/Condition/balance_age.pm +++ b/FS/FS/part_event/Condition/balance_age.pm @@ -45,8 +45,6 @@ sub order_sql { shift->condition_sql_option_age('age'); } -use FS::UID qw( driver_name ); - sub order_sql_weight { 10; } diff --git a/FS/FS/part_event/Condition/balance_credit_limit.pm b/FS/FS/part_event/Condition/balance_credit_limit.pm new file mode 100644 index 0000000..1bc2aa1 --- /dev/null +++ b/FS/FS/part_event/Condition/balance_credit_limit.pm @@ -0,0 +1,32 @@ +package FS::part_event::Condition::balance_credit_limit; + +use strict; +use FS::cust_main; + +use base qw( FS::part_event::Condition ); + +sub description { 'Customer is over credit limit'; } + +sub condition { + my($self, $object) = @_; + + my $cust_main = $self->cust_main($object); + + my $over = $cust_main->credit_limit; + return 0 if !length($over); # if credit limit is null, no limit + + $cust_main->balance > $over; +} + +sub condition_sql { + my( $class, $table ) = @_; + + my $balance_sql = FS::cust_main->balance_sql; + + "(cust_main.credit_limit IS NULL OR + $balance_sql - cust_main.credit_limit > 0 )"; + +} + +1; + diff --git a/FS/FS/part_event/Condition/cust_bill_past_due.pm b/FS/FS/part_event/Condition/cust_bill_past_due.pm new file mode 100644 index 0000000..a889a00 --- /dev/null +++ b/FS/FS/part_event/Condition/cust_bill_past_due.pm @@ -0,0 +1,41 @@ +package FS::part_event::Condition::cust_bill_past_due; + +use strict; +use FS::cust_bill; +use Time::Local 'timelocal'; + +use base qw( FS::part_event::Condition ); + +sub description { + 'Invoice due date has passed'; +} + +sub eventtable_hashref { + { 'cust_main' => 0, + 'cust_bill' => 1, + 'cust_pkg' => 0, + }; +} + +sub condition { + my($self, $cust_bill, %opt) = @_; + + # If the invoice date is 1/1 at noon and the terms are Net 15, + # the due_date will be 1/16 at noon. Past due events will not + # trigger until after the start of 1/17. + my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($opt{'time'}))[0..5]; + my $start_of_today = timelocal(0,0,0,$mday,$mon,$year)+1; + ($cust_bill->due_date || $cust_bill->_date) < $start_of_today; +} + +sub condition_sql { + return 'true' if $FS::UID::driver_name ne 'Pg'; + my( $class, $table, %opt ) = @_; + my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($opt{'time'}))[0..5]; + my $start_of_today = timelocal(0,0,0,$mday,$mon,$year)+1; + + FS::cust_bill->due_date_sql . " < $start_of_today"; + +} + +1; diff --git a/FS/FS/part_event/Condition/cust_status.pm b/FS/FS/part_event/Condition/cust_status.pm index fbdff25..066ee48 100644 --- a/FS/FS/part_event/Condition/cust_status.pm +++ b/FS/FS/part_event/Condition/cust_status.pm @@ -29,4 +29,12 @@ sub condition { $hashref->{ $cust_main->status }; } +sub condition_sql { + my( $self, $table ) = @_; + + '('.FS::cust_main->cust_status_sql . ') IN '. + $self->condition_sql_option_option('status'); +} + + 1; diff --git a/FS/FS/part_event/Condition/has_referral_custnum.pm b/FS/FS/part_event/Condition/has_referral_custnum.pm index 61a8155..70c9c7f 100644 --- a/FS/FS/part_event/Condition/has_referral_custnum.pm +++ b/FS/FS/part_event/Condition/has_referral_custnum.pm @@ -38,11 +38,13 @@ sub condition { } sub condition_sql { - #my( $class, $table ) = @_; + my( $class, $table ) = @_; - "cust_main.referral_custnum IS NOT NULL"; - - #XXX a bit harder to check active status here + my $sql = FS::cust_main->active_sql; + $sql =~ s/cust_main.custnum/cust_main.referral_custnum/; + $sql = 'cust_main.referral_custnum IS NOT NULL AND ('. + $class->condition_sql_option('active') . ' IS NULL OR '.$sql.')'; + return $sql; } 1; 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 0000000..2921b3a --- /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 the specified 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 0000000..f85a056 --- /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/payby.pm b/FS/FS/part_event/Condition/payby.pm index d931568..16bf480 100644 --- a/FS/FS/part_event/Condition/payby.pm +++ b/FS/FS/part_event/Condition/payby.pm @@ -30,21 +30,15 @@ sub condition { my $cust_main = $self->cust_main($object); - #uuh.. all right? test this. my $hashref = $self->option('payby') || {}; $hashref->{ $cust_main->payby }; } -#sub condition_sql { -# my( $self, $table ) = @_; -# -# #uuh... yeah... something like this. test it for sure. -# -# my @payby = keys %{ $self->option('payby') }; -# -# ' ( '. join(' OR ', map { "cust_main.payby = '$_'" } @payby ). ' ) '; -# -#} +sub condition_sql { + my( $self, $table ) = @_; + + 'cust_main.payby IN '. $self->condition_sql_option_option('payby'); +} 1; diff --git a/FS/FS/part_event/Condition/pkg_age.pm b/FS/FS/part_event/Condition/pkg_age.pm index 8b3b4c9..4a85387 100644 --- a/FS/FS/part_event/Condition/pkg_age.pm +++ b/FS/FS/part_event/Condition/pkg_age.pm @@ -49,10 +49,18 @@ sub condition { } -#XXX write me for efficiency -#sub condition_sql { -# -#} +sub condition_sql { + my( $class, $table, %opt ) = @_; + my $age = $class->condition_sql_option_age_from('age', $opt{'time'}); + my $field = $class->condition_sql_option('field'); +#amazingly, this is actually faster + my $sql = '( CASE'; + foreach( qw(setup last_bill bill adjourn susp expire cancel) ) { + $sql .= " WHEN $field = '$_' THEN (cust_pkg.$_ IS NOT NULL AND cust_pkg.$_ <= $age)"; + } + $sql .= ' END )'; + return $sql; +} 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 0000000..90c4c6a --- /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 upcoming 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; + diff --git a/FS/FS/part_event/Condition/pkg_recurring.pm b/FS/FS/part_event/Condition/pkg_recurring.pm index 1b66821..1a08869 100644 --- a/FS/FS/part_event/Condition/pkg_recurring.pm +++ b/FS/FS/part_event/Condition/pkg_recurring.pm @@ -20,12 +20,9 @@ sub condition { } - -#XXX join part_pkg USING (pkgpart) -# part_pkg.freq != '0' -#sub condition_sql { -# -#} +sub condition_sql { + FS::cust_pkg->recurring_sql() +} 1; diff --git a/FS/FS/part_event/Condition/pkg_status.pm b/FS/FS/part_event/Condition/pkg_status.pm index 6c1c9cc..3fb374e 100644 --- a/FS/FS/part_event/Condition/pkg_status.pm +++ b/FS/FS/part_event/Condition/pkg_status.pm @@ -34,4 +34,11 @@ sub condition { $hashref->{ $cust_pkg->status }; } +sub condition_sql { + my( $self, $table ) = @_; + + '('.FS::cust_pkg->status_sql . ') IN '. + $self->condition_sql_option_option('status'); +} + 1; |