default to a session cookie instead of setting an explicit timeout, weird timezone...
[freeside.git] / FS / FS / part_event / Condition / once_perinv.pm
1 package FS::part_event::Condition::once_perinv;
2
3 use strict;
4 use FS::Record qw( qsearch );
5 use FS::part_event;
6 use FS::cust_event;
7
8 use base qw( FS::part_event::Condition );
9
10 sub description { "Run only once for each time the package has been billed"; }
11
12 # Run the event, at most, a number of times equal to the number of 
13 # distinct invoices that contain line items from this package.
14
15 sub option_fields {
16   (
17     'paid' => { 'label' => 'Only count paid bills',
18                 'type'  => 'checkbox',
19                 'value' => 'Y',
20               },
21     'no_late' => { 'label' => "But don't consider paid bills which were late.",
22                    'type'  => 'checkbox',
23                    'value' => 'Y',
24                  },
25   )
26 }
27
28 sub eventtable_hashref {
29     { 'cust_main' => 0,
30       'cust_bill' => 0,
31       'cust_pkg'  => 1,
32     };
33 }
34
35 sub condition {
36   my($self, $cust_pkg, %opt) = @_;
37
38   my @cust_bill_pkg = qsearch('cust_bill_pkg', { pkgnum=>$cust_pkg->pkgnum });
39
40   if ( $self->option('paid') ) {
41     @cust_bill_pkg = grep { ($_->owed_setup + $_->owed_recur) == 0 }
42                        @cust_bill_pkg;
43
44     if ( $self->option('no_late') ) {
45       @cust_bill_pkg = grep {
46         my $cust_bill_pkg = $_;
47
48         my @cust_bill_pay_pkg = ();
49         push @cust_bill_pay_pkg, $cust_bill_pkg->cust_bill_pay_pkg($_)
50           for qw( setup recur );
51         return 1 unless @cust_bill_pay_pkg; #no payments?  must be credits then
52                                             #not considering those "late"
53
54         my @cust_pay = sort { $a->_date <=> $b->_date }
55                          map { $_->cust_bill_pay->cust_pay }
56                            @cust_bill_pay_pkg;
57
58         #most recent payment less than due date?  okay, we were paid on time
59         $cust_pay[-1] <= $cust_bill_pkg->cust_bill->due_date;
60                  
61       } @cust_bill_pkg;
62     }
63
64   }
65
66   my %invnum = ();
67   $invnum{$_->invnum} = 1 foreach @cust_bill_pkg;
68
69   my @events = qsearch( {
70       'table'     => 'cust_event', 
71       'hashref'   => { 'eventpart' => $self->eventpart,
72                        'status'    => { op=>'!=', value=>'failed' },
73                        'tablenum'  => $cust_pkg->pkgnum,
74                      },
75       'extra_sql' => ( $opt{'cust_event'}->eventnum =~ /^(\d+)$/
76                        ? " AND eventnum != $1 " : '' ),
77   } );
78   scalar(@events) < scalar(keys %invnum);
79 }
80
81 sub condition_sql {
82   my( $self, $table ) = @_;
83
84   #paid flag not yet implemented here, but that's okay, a partial optimization
85   # is better than none
86
87   "( 
88     ( SELECT COUNT(distinct(invnum)) 
89       FROM cust_bill_pkg
90       WHERE cust_bill_pkg.pkgnum = cust_pkg.pkgnum )
91     >
92     ( SELECT COUNT(*)
93       FROM cust_event
94       WHERE cust_event.eventpart = part_event.eventpart
95         AND cust_event.tablenum = cust_pkg.pkgnum
96         AND status != 'failed' )
97   )"
98
99 }
100
101 1;