new event conditions, RT#8896
authormark <mark>
Sat, 21 Aug 2010 00:21:23 +0000 (00:21 +0000)
committermark <mark>
Sat, 21 Aug 2010 00:21:23 +0000 (00:21 +0000)
FS/FS/part_event/Condition/once_every.pm [new file with mode: 0644]
FS/FS/part_event/Condition/once_perinv.pm [new file with mode: 0644]
FS/FS/part_event/Condition/pkg_next_bill_within.pm [new file with mode: 0644]

diff --git a/FS/FS/part_event/Condition/once_every.pm b/FS/FS/part_event/Condition/once_every.pm
new file mode 100644 (file)
index 0000000..a0d9d68
--- /dev/null
@@ -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 (file)
index 0000000..f85a056
--- /dev/null
@@ -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 (file)
index 0000000..dc16ce8
--- /dev/null
@@ -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;
+