1 package FS::part_event_condition;
4 use vars qw( @ISA $DEBUG );
6 use FS::Record qw( qsearch qsearchs );
8 use FS::part_event; #for order_conditions_sql...
10 @ISA = qw( FS::option_Common ); # FS::Record );
15 FS::part_event_condition - Object methods for part_event_condition records
19 use FS::part_event_condition;
21 $record = new FS::part_event_condition \%hash;
22 $record = new FS::part_event_condition { 'column' => 'value' };
24 $error = $record->insert;
26 $error = $new_record->replace($old_record);
28 $error = $record->delete;
30 $error = $record->check;
34 An FS::part_event_condition object represents an event condition.
35 FS::part_event_condition inherits from FS::Record. The following fields are
40 =item eventconditionnum - primary key
42 =item eventpart - Event definition (see L<FS::part_event>)
44 =item conditionname - Condition name - defines which FS::part_event::Condition::I<conditionname> evaluates this condition
54 Creates a new event. To add the example to the database, see L<"insert">.
56 Note that this stores the hash reference, not a distinct copy of the hash it
57 points to. You can ask the object for a copy with the I<hash> method.
61 # the new method can be inherited from FS::Record, if a table method is defined
63 sub table { 'part_event_condition'; }
65 =item insert [ HASHREF | OPTION => VALUE ... ]
67 Adds this record to the database. If there is an error, returns the error,
68 otherwise returns false.
70 If a list or hash reference of options is supplied, part_event_condition_option
71 records are created (see L<FS::part_event_condition_option>).
75 # the insert method can be inherited from FS::Record
79 Delete this record from the database.
83 # the delete method can be inherited from FS::Record
85 =item replace OLD_RECORD [ HASHREF | OPTION => VALUE ... ]
87 Replaces the OLD_RECORD with this one in the database. If there is an error,
88 returns the error, otherwise returns false.
90 If a list or hash reference of options is supplied, part_event_condition_option
91 records are created or modified (see L<FS::part_event_condition_option>).
95 # the replace method can be inherited from FS::Record
99 Checks all fields to make sure this is a valid example. If there is
100 an error, returns the error, otherwise returns false. Called by the insert
105 # the check method should currently be supplied - FS::Record contains some
106 # data checking routines
112 $self->ut_numbern('eventconditionnum')
113 || $self->ut_foreign_key('eventpart', 'part_event', 'eventpart')
114 || $self->ut_alpha('conditionname')
116 return $error if $error;
118 #XXX check conditionname to make sure a module exists?
119 # well it'll die in _rebless...
127 Reblesses the object into the FS::part_event::Condition::CONDITIONNAME class,
128 where CONDITIONNAME is the object's I<conditionname> field.
134 my $conditionname = $self->conditionname;
135 #my $class = ref($self). "::$conditionname";
136 my $class = "FS::part_event::Condition::$conditionname";
139 bless($self, $class); #unless $@;
149 =item conditions [ EVENTTABLE ]
151 Return information about the available conditions. If an eventtable is
152 specified, only return information about conditions available for that
155 Information is returned as key-value pairs. Keys are condition names. Values
156 are hashrefs with the following keys:
164 # =item default_weight
170 See L<FS::part_event::Condition> for more information.
174 #false laziness w/part_event.pm
175 #some false laziness w/part_export & part_pkg
177 foreach my $INC ( @INC ) {
178 foreach my $file ( glob("$INC/FS/part_event/Condition/*.pm") ) {
179 warn "attempting to load Condition from $file\n" if $DEBUG;
180 $file =~ /\/(\w+)\.pm$/ or do {
181 warn "unrecognized file in $INC/FS/part_event/Condition/: $file\n";
185 my $fullmod = "FS::part_event::Condition::$mod";
186 eval "use $fullmod;";
188 die "error using $fullmod (skipping): $@\n" if $@;
189 #warn "error using $fullmod (skipping): $@\n" if $@;
192 #my $full_condition_sql = $fullmod. '::condition_sql';
193 my $condition_sql_coderef = sub { $fullmod->condition_sql(@_) };
194 my $order_sql_coderef = $fullmod->can('order_sql')
195 ? sub { $fullmod->order_sql(@_) }
197 $conditions{$mod} = {
198 ( map { $_ => $fullmod->$_() }
199 qw( description eventtable_hashref
200 implicit_flag remove_warning
204 #option_fields_hashref
206 'option_fields' => [ $fullmod->option_fields() ],
207 'condition_sql' => $condition_sql_coderef,
208 'order_sql' => $order_sql_coderef,
214 my( $class, $eventtable ) = @_;
216 map { $_ => $conditions{$_} }
217 # sort { $conditions{$a}->{'default_weight'}<=>$conditions{$b}->{'default_weight'} }
219 $class->all_conditionnames( $eventtable )
224 =item all_conditionnames [ EVENTTABLE ]
226 Returns a list of just the condition names
230 sub all_conditionnames {
231 my ( $class, $eventtable ) = @_;
233 grep { !$eventtable || $conditions{$_}->{'eventtable_hashref'}{$eventtable} }
237 =item join_conditions_sql [ EVENTTABLE ]
239 Returns an SQL fragment selecting joining all condition options for an event as
240 tables titled "cond_I<conditionname>". Typically used in conjunction with
241 B<where_conditions_sql>.
245 sub join_conditions_sql {
246 my ( $class, $eventtable ) = @_;
247 my %conditions = $class->conditions( $eventtable );
251 "LEFT JOIN part_event_condition AS cond_$_".
252 " ON ( part_event.eventpart = cond_$_.eventpart".
253 " AND cond_$_.conditionname = ". dbh->quote($_).
261 =item where_conditions_sql [ EVENTTABLE [ , OPTION => VALUE, ... ] ]
263 Returns an SQL fragment to select events which have unsatisfied conditions.
264 Must be used in conjunction with B<join_conditions_sql>.
266 The only current option is "time", the current time (or "pretend" current time
267 as passed to freeside-daily), as a UNIX timestamp.
271 sub where_conditions_sql {
272 my ( $class, $eventtable, %options ) = @_;
274 my $time = $options{'time'};
276 my %conditions = $class->conditions( $eventtable );
278 my $where = join(' AND ',
280 my $conditionname = $_;
281 my $coderef = $conditions{$conditionname}->{condition_sql};
282 my $sql = &$coderef( $eventtable, 'time'=>$time );
283 die "$coderef is not a CODEREF" unless ref($coderef) eq 'CODE';
284 "( cond_$conditionname.conditionname IS NULL OR $sql )";
292 =item order_conditions_sql [ EVENTTABLE ]
294 Returns an SQL fragment to order selected events. Must be used in conjunction
295 with B<join_conditions_sql>.
299 sub order_conditions_sql {
300 my( $class, $eventtable ) = @_;
302 my %conditions = $class->conditions( $eventtable );
304 my $eventtables = join(' ', FS::part_event->eventtables_runorder);
306 my $order_by = join(', ',
307 "position( part_event.eventtable in ' $eventtables ')",
309 my $conditionname = $_;
310 my $coderef = $conditions{$conditionname}->{order_sql};
311 my $sql = &$coderef( $eventtable );
312 "CASE WHEN cond_$conditionname.conditionname IS NULL
318 sort { $conditions{$a}->{order_sql_weight}
319 <=> $conditions{$b}->{order_sql_weight}
321 grep { $conditions{$_}->{order_sql} }
327 "ORDER BY $order_by";
337 L<FS::part_event::Condition>, L<FS::part_event>, L<FS::Record>, schema.html from
338 the base documentation.