diff options
author | mark <mark> | 2011-09-01 05:13:09 +0000 |
---|---|---|
committer | mark <mark> | 2011-09-01 05:13:09 +0000 |
commit | 53ea5a72067a9b0ebcd3417692c3884d6f91f74a (patch) | |
tree | 1fcf7144305e5ab821ab9d0f04ebfd91a88a91cb /FS/FS/part_event | |
parent | 81d973916db8389df760f4055b3eb3825b3ed262 (diff) |
svc_acct events for usage limits, #13202
Diffstat (limited to 'FS/FS/part_event')
-rw-r--r-- | FS/FS/part_event/Action.pm | 15 | ||||
-rw-r--r-- | FS/FS/part_event/Action/pkg_cancel.pm | 3 | ||||
-rw-r--r-- | FS/FS/part_event/Action/pkg_suspend.pm | 6 | ||||
-rw-r--r-- | FS/FS/part_event/Action/svc_acct_notice.pm | 51 | ||||
-rw-r--r-- | FS/FS/part_event/Condition.pm | 15 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/pkg_status.pm | 4 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/svc_acct_overlimit.pm | 57 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/svc_acct_threshold.pm | 63 |
8 files changed, 210 insertions, 4 deletions
diff --git a/FS/FS/part_event/Action.pm b/FS/FS/part_event/Action.pm index 094cf7d3a..c0c70b1c3 100644 --- a/FS/FS/part_event/Action.pm +++ b/FS/FS/part_event/Action.pm @@ -192,6 +192,21 @@ sub cust_main { } +=item cust_pkg OBJECT + +Return the package object (L<FS::cust_pkg>) associated with the provided +object. The object must be either a service (L<FS::svc_Common>) or a +package. + +=cut + +sub cust_pkg { + my( $self, $object ) = @_; + $object->isa('FS::cust_pkg') ? $object : + $object->isa('FS::svc_Common') ? $object->cust_svc->cust_pkg : + undef; +} + =item option_label OPTIONNAME Returns the label for the specified option name. diff --git a/FS/FS/part_event/Action/pkg_cancel.pm b/FS/FS/part_event/Action/pkg_cancel.pm index 2bfd35cad..1eeb4a8ff 100644 --- a/FS/FS/part_event/Action/pkg_cancel.pm +++ b/FS/FS/part_event/Action/pkg_cancel.pm @@ -21,7 +21,8 @@ sub option_fields { sub default_weight { 20; } sub do_action { - my( $self, $cust_pkg, $cust_event ) = @_; + my( $self, $object, $cust_event ) = @_; + my $cust_pkg = $self->cust_pkg($object); my $error = $cust_pkg->cancel( 'reason' => $self->option('reasonnum') ); die $error if $error; diff --git a/FS/FS/part_event/Action/pkg_suspend.pm b/FS/FS/part_event/Action/pkg_suspend.pm index e12616c54..23ab13e14 100644 --- a/FS/FS/part_event/Action/pkg_suspend.pm +++ b/FS/FS/part_event/Action/pkg_suspend.pm @@ -6,7 +6,8 @@ use base qw( FS::part_event::Action ); sub description { 'Suspend this package'; } sub eventtable_hashref { - { 'cust_pkg' => 1 }; + { 'cust_pkg' => 1, + 'svc_acct' => 1, }; } sub option_fields { @@ -21,7 +22,8 @@ sub option_fields { sub default_weight { 20; } sub do_action { - my( $self, $cust_pkg, $cust_event ) = @_; + my( $self, $object, $cust_event ) = @_; + my $cust_pkg = $self->cust_pkg($object); my $error = $cust_pkg->suspend( 'reason' => $self->option('reasonnum') ); die $error if $error; diff --git a/FS/FS/part_event/Action/svc_acct_notice.pm b/FS/FS/part_event/Action/svc_acct_notice.pm new file mode 100644 index 000000000..d71a1371a --- /dev/null +++ b/FS/FS/part_event/Action/svc_acct_notice.pm @@ -0,0 +1,51 @@ +package FS::part_event::Action::svc_acct_notice; + +use strict; +use base qw( FS::part_event::Action ); +use FS::Record qw( qsearchs ); +use FS::svc_acct; +use FS::msg_template; + +sub description { 'Email a notice to this account'; } + +sub eventtable_hashref { + { 'svc_acct' => 1 } +}; + +sub option_fields { + ( + 'msgnum' => { 'label' => 'Template', + 'type' => 'select-table', + 'table' => 'msg_template', + 'name_col' => 'msgname', + 'disable_empty' => 1, + }, + ); +} + +sub default_weight { 56; } #? + +sub do_action { + my( $self, $svc_acct ) = @_; + + my $cust_main = $self->cust_main($svc_acct) + or die "No customer found for svcnum ".$svc_acct->svcnum; + # this will never be run for unlinked services, for several reasons + + my $msgnum = $self->option('msgnum'); + + my $msg_template = qsearchs('msg_template', { 'msgnum' => $msgnum } ) + or die "Template $msgnum not found"; + + my $email = $svc_acct->email + or die "No email associated with svcnum ".$svc_acct->svcnum; + + $msg_template->send( + 'cust_main' => $cust_main, + 'object' => $svc_acct, + 'to' => $email, + ); + +} + +1; diff --git a/FS/FS/part_event/Condition.pm b/FS/FS/part_event/Condition.pm index 5c581b498..914256f45 100644 --- a/FS/FS/part_event/Condition.pm +++ b/FS/FS/part_event/Condition.pm @@ -235,6 +235,21 @@ sub cust_main { } +=item cust_pkg OBJECT + +Return the package object (L<FS::cust_pkg>) associated with the provided +object. The object must be either a service (L<FS::svc_Common>) or a +package. + +=cut + +sub cust_pkg { + my( $self, $object ) = @_; + $object->isa('FS::cust_pkg') ? $object : + $object->isa('FS::svc_Common') ? $object->cust_svc->cust_pkg : + undef; +} + =item option_label OPTIONNAME Returns the label for the specified option name. diff --git a/FS/FS/part_event/Condition/pkg_status.pm b/FS/FS/part_event/Condition/pkg_status.pm index 3fb374e9a..0d99f3bbc 100644 --- a/FS/FS/part_event/Condition/pkg_status.pm +++ b/FS/FS/part_event/Condition/pkg_status.pm @@ -13,6 +13,7 @@ sub eventtable_hashref { { 'cust_main' => 0, 'cust_bill' => 0, 'cust_pkg' => 1, + 'svc_acct' => 1, }; } @@ -27,8 +28,9 @@ sub option_fields { } sub condition { - my( $self, $cust_pkg ) = @_; + my( $self, $object ) = @_; + my $cust_pkg = $self->cust_pkg($object); #XXX test my $hashref = $self->option('status') || {}; $hashref->{ $cust_pkg->status }; diff --git a/FS/FS/part_event/Condition/svc_acct_overlimit.pm b/FS/FS/part_event/Condition/svc_acct_overlimit.pm new file mode 100644 index 000000000..404743c45 --- /dev/null +++ b/FS/FS/part_event/Condition/svc_acct_overlimit.pm @@ -0,0 +1,57 @@ +package FS::part_event::Condition::svc_acct_overlimit; + +use strict; +use FS::svc_acct; + +use base qw( FS::part_event::Condition ); + +sub description { 'Service is over its usage limit' }; + +sub eventtable_hashref { + { 'svc_acct' => 1 } +} + +tie my %usage_types, 'Tie::IxHash', ( + 'seconds' => 'Time', + 'upbytes' => 'Upload', + 'downbytes' => 'Download', + 'totalbytes'=> 'Total transfer', +); + +sub option_fields { + ( + 'usage_types' => { + type => 'checkbox-multiple', + options => [ keys %usage_types ], + option_labels => \%usage_types, + }, + ); +} + + +sub condition { + my($self, $svc_acct) = @_; + + my $types = $self->option('usage_types') || {}; + foreach my $column (keys %$types) { + # don't trigger if this type of usage isn't tracked on the service + next if $svc_acct->$column eq ''; + + return 1 if ( $svc_acct->$column <= 0 ); + } + return 0; +} + +sub condition_sql { + my($self) = @_; + + # not an exact condition_sql--ignores the usage_types option + '(' . join(' OR ', + map { + "( svc_acct.$_ IS NOT NULL AND svc_acct.$_ <= 0 )" + } keys %usage_types + ) . ')' +} + +1; + diff --git a/FS/FS/part_event/Condition/svc_acct_threshold.pm b/FS/FS/part_event/Condition/svc_acct_threshold.pm new file mode 100644 index 000000000..85d57119d --- /dev/null +++ b/FS/FS/part_event/Condition/svc_acct_threshold.pm @@ -0,0 +1,63 @@ +package FS::part_event::Condition::svc_acct_threshold; + +use strict; +use FS::svc_acct; + +use base qw( FS::part_event::Condition ); + +sub description { 'Service is over its usage warning threshold' }; + +sub eventtable_hashref { + { 'svc_acct' => 1 } +} + +tie my %usage_types, 'Tie::IxHash', ( + 'seconds' => 'Time', + 'upbytes' => 'Upload', + 'downbytes' => 'Download', + 'totalbytes'=> 'Total transfer', +); + +sub option_fields { + ( + 'usage_types' => { + type => 'checkbox-multiple', + options => [ keys %usage_types ], + option_labels => \%usage_types, + }, + ); +} + +sub condition { + my($self, $svc_acct) = @_; + + my $types = $self->option('usage_types') || {}; + foreach my $column (keys %$types) { + # don't trigger if this type of usage isn't tracked on the service + next if $svc_acct->$column eq ''; + my $threshold; + my $method = $column.'_threshold'; + $threshold = $svc_acct->$method; + # don't trigger if seconds = 0 and seconds_threshold is null + next if $threshold eq ''; + + return 1 if ( $svc_acct->$column <= $threshold ); + } + return 0; +} + +sub condition_sql { + my($self) = @_; + + # not an exact condition_sql--ignores the usage_types option + '(' . join(' OR ', + map { + my $threshold = $_.'_threshold'; + "( svc_acct.$_ IS NOT NULL AND svc_acct.$threshold IS NOT NULL AND ". + "svc_acct.$_ <= svc_acct.$threshold )" + } keys %usage_types + ) . ')' +} + +1; + |