diff options
author | ivan <ivan> | 2007-08-01 22:26:52 +0000 |
---|---|---|
committer | ivan <ivan> | 2007-08-01 22:26:52 +0000 |
commit | eb4ff7f73c5d4bdf74a3472448b5a195598ff4cd (patch) | |
tree | bb38241e8c865c3bca861da7749071feeadd2b5b /FS/FS/part_event.pm | |
parent | 32b5d3a31f112a381f0a15ac5e3a2204242f3405 (diff) |
event refactor, landing on HEAD!
Diffstat (limited to 'FS/FS/part_event.pm')
-rw-r--r-- | FS/FS/part_event.pm | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/FS/FS/part_event.pm b/FS/FS/part_event.pm new file mode 100644 index 0000000..09104cd --- /dev/null +++ b/FS/FS/part_event.pm @@ -0,0 +1,427 @@ +package FS::part_event; + +use strict; +use vars qw( @ISA $DEBUG ); +use Carp qw(confess); +use FS::Record qw( dbh qsearch qsearchs ); +use FS::option_Common; +use FS::m2name_Common; +use FS::Conf; +use FS::part_event_option; +use FS::part_event_condition; +use FS::cust_event; +use FS::agent; + +@ISA = qw( FS::m2name_Common FS::option_Common ); # FS::Record ); +$DEBUG = 0; + +=head1 NAME + +FS::part_event - Object methods for part_event records + +=head1 SYNOPSIS + + use FS::part_event; + + $record = new FS::part_event \%hash; + $record = new FS::part_event { 'column' => 'value' }; + + $error = $record->insert( { 'option' => 'value' } ); + $error = $record->insert( \%options ); + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + + $error = $record->do_event( $direct_object ); + +=head1 DESCRIPTION + +An FS::part_event object represents an event definition - a billing, collection +or other callback which is triggered when certain customer, invoice, package or +other conditions are met. FS::part_event inherits from FS::Record. The +following fields are currently supported: + +=over 4 + +=item eventpart - primary key + +=item agentnum - Optional agentnum (see L<FS::agent>) + +=item event - event name + +=item eventtable - table name against which this event is triggered; currently "cust_bill" (the traditional invoice events), "cust_main" (customer events) or "cust_pkg (package events) + +=item check_freq - how often events of this type are checked; currently "1d" (daily) and "1m" (monthly) are recognized. Note that the apprioriate freeside-daily and/or freeside-monthly cron job needs to be in place. + +=item weight - ordering for events + +=item action - event action (like part_bill_event.plan - eventcode plan) + +=item disabled - Disabled flag, empty or `Y' + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new invoice event definition. To add the invoice event definition to +the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I<hash> method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'part_event'; } + +=item insert [ HASHREF ] + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +If a list or hash reference of options is supplied, part_export_option records +are created (see L<FS::part_event_option>). + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD [ HASHREF | OPTION => VALUE ... ] + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +If a list or hash reference of options is supplied, part_event_option +records are created or modified (see L<FS::part_event_option>). + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid invoice event definition. If +there is an error, returns the error, otherwise returns false. Called by the +insert and replace methods. + +=cut + +# the check method should currently be supplied - FS::Record contains some +# data checking routines + +sub check { + my $self = shift; + + $self->weight(0) unless $self->weight; + + my $error = + $self->ut_numbern('eventpart') + || $self->ut_text('event') + || $self->ut_enum('eventtable', [ 'cust_bill', 'cust_main', 'cust_pkg' ] ) + || $self->ut_enum('check_freq', [ '1d', '1m' ]) + || $self->ut_number('weight') + || $self->ut_alpha('action') + || $self->ut_enum('disabled', [ '', 'Y' ] ) + ; + return $error if $error; + + #XXX check action to make sure a module exists? + # well it'll die in _rebless... + + $self->SUPER::check; +} + +=item _rebless + +Reblesses the object into the FS::part_event::Action::ACTION class, where +ACTION is the object's I<action> field. + +=cut + +sub _rebless { + my $self = shift; + my $action = $self->action or return $self; + #my $class = ref($self). "::$action"; + my $class = "FS::part_event::Action::$action"; + eval "use $class"; + die $@ if $@; + bless($self, $class); # unless $@; + $self; +} + +=item part_event_condition + +Returns the conditions associated with this event, as FS::part_event_condition +objects (see L<FS::part_event_condition>) + +=cut + +sub part_event_condition { + my $self = shift; + qsearch( 'part_event_condition', { 'eventpart' => $self->eventpart } ); +} + +=item new_cust_event OBJECT + +Creates a new customer event (see L<FS::cust_event>) for the provided object. + +=cut + +sub new_cust_event { + my( $self, $object ) = @_; + + confess "**** $object is not a ". $self->eventtable + if ref($object) ne "FS::". $self->eventtable; + + my $pkey = $object->primary_key; + + new FS::cust_event { + 'eventpart' => $self->eventpart, + 'tablenum' => $object->$pkey(), + '_date' => time, #i think we always want the real "now" here. + 'status' => 'new', + }; +} + +#surely this doesn't work +sub reasontext { confess "part_event->reasontext deprecated"; } +#=item reasontext +# +#Returns the text of any reason associated with this event. +# +#=cut +# +#sub reasontext { +# my $self = shift; +# my $r = qsearchs('reason', { 'reasonnum' => $self->reason }); +# if ($r){ +# $r->reason; +# }else{ +# ''; +# } +#} + +=item agent + +Returns the associated agent for this event, if any, as an FS::agent object. + +=cut + +sub agent { + my $self = shift; + qsearchs('agent', { 'agentnum' => $self->agentnum } ); +} + +=item templatename + +Returns the alternate invoice template name, if any, or false if there is +no alternate template for this event. + +=cut + +sub templatename { + + my $self = shift; + if ( $self->action =~ /^cust_bill_send_(alternate|agent)$/ + && ( $self->option('agent_templatename') + || $self->option('templatename') ) + ) + { + $self->option('agent_templatename') + || $self->option('templatename'); + + } else { + ''; + } +} + +=back + +=head1 CLASS METHODS + +=over 4 + +=item eventtable_labels + +Returns a hash reference of labels for eventtable values, +i.e. 'cust_main'=>'Customer' + +=cut + +sub eventtable_labels { + #my $class = shift; + + tie my %hash, 'Tie::IxHash', + 'cust_pkg' => 'Package', + 'cust_bill' => 'Invoice', + 'cust_main' => 'Customer', + 'cust_pay_batch' => 'Batch payment', + ; + + \%hash +} + +=item eventtable_pkey_sql + +Returns a hash reference of full SQL primary key names for eventtable values, +i.e. 'cust_main'=>'cust_main.custnum' + +=cut + +sub eventtable_pkey_sql { + #my $class = shift; + + my %hash = ( + 'cust_main' => 'cust_main.custnum', + 'cust_bill' => 'cust_bill.invnum', + 'cust_pkg' => 'cust_pkg.pkgnum', + 'cust_pay_batch' => 'cust_pay_batch.paybatchnum', + ); + + \%hash; +} + + +=item eventtables + +Returns a list of eventtable values (default ordering; suited for display). + +=cut + +sub eventtables { + my $class = shift; + my $eventtables = $class->eventtable_labels; + keys %$eventtables; +} + +=item eventtables_runorder + +Returns a list of eventtable values (run order). + +=cut + +sub eventtables_runorder { + shift->eventtables; #same for now +} + +=item check_freq_labels + +Returns a hash reference of labels for check_freq values, +i.e. '1d'=>'daily' + +=cut + +sub check_freq_labels { + #my $class = shift; + + #Tie::IxHash?? + { + '1d' => 'daily', + '1m' => 'monthly', + }; +} + +=item actions [ EVENTTABLE ] + +Return information about the available actions. If an eventtable is specified, +only return information about actions available for that eventtable. + +Information is returned as key-value pairs. Keys are event names. Values are +hashrefs with the following keys: + +=over 4 + +=item description + +=item eventtable_hashref + +=item option_fields + +=item default_weight + +=item deprecated + +=back + +See L<FS::part_event::Action> for more information. + +=cut + +#false laziness w/part_event_condition.pm +#some false laziness w/part_export & part_pkg +my %actions; +foreach my $INC ( @INC ) { + foreach my $file ( glob("$INC/FS/part_event/Action/*.pm") ) { + warn "attempting to load Action from $file\n" if $DEBUG; + $file =~ /\/(\w+)\.pm$/ or do { + warn "unrecognized file in $INC/FS/part_event/Action/: $file\n"; + next; + }; + my $mod = $1; + eval "use FS::part_event::Action::$mod;"; + if ( $@ ) { + die "error using FS::part_event::Action::$mod (skipping): $@\n" if $@; + #warn "error using FS::part_event::Action::$mod (skipping): $@\n" if $@; + #next; + } + $actions{$mod} = { + ( map { $_ => "FS::part_event::Action::$mod"->$_() } + qw( description eventtable_hashref default_weight deprecated ) + #option_fields_hashref + ), + 'option_fields' => [ "FS::part_event::Action::$mod"->option_fields() ], + }; + } +} + +sub actions { + my( $class, $eventtable ) = @_; + ( + map { $_ => $actions{$_} } + sort { $actions{$a}->{'default_weight'}<=>$actions{$b}->{'default_weight'} } + $class->all_actions( $eventtable ) + ); + +} + +=item all_actions [ EVENTTABLE ] + +Returns a list of just the action names + +=cut + +sub all_actions { + my ( $class, $eventtable ) = @_; + + grep { !$eventtable || $actions{$_}->{'eventtable_hashref'}{$eventtable} } + keys %actions +} + +=back + +=head1 SEE ALSO + +L<FS::part_event_option>, L<FS::part_event_condition>, L<FS::cust_main>, +L<FS::cust_pkg>, L<FS::cust_bill>, L<FS::cust_bill_event>, L<FS::Record>, +schema.html from the base documentation. + +=cut + +1; + |