optimize customer list, RT#20173
[freeside.git] / FS / FS / cust_main / Status.pm
1 package FS::cust_main::Status;
2
3 use strict;
4 use vars qw( $conf $module ); #$DEBUG $me );
5 use Tie::IxHash;
6 use FS::UID;
7 use FS::cust_pkg;
8
9 #$DEBUG = 0;
10 #$me = '[FS::cust_main::Status]';
11
12 install_callback FS::UID sub { 
13   $conf = new FS::Conf;
14   $module = $conf->config('cust_main-status_module') || 'Classic';
15 };
16
17 =head1 NAME
18
19 FS::cust_main::Status - Status mixin for cust_main
20
21 =head1 SYNOPSIS
22
23 =head1 DESCRIPTION
24
25 These methods are available on FS::cust_main objects:
26
27 =head1 METHODS
28
29 =over 4
30
31 =item statuscolors
32
33 Returns an (ordered with Tie::IxHash) hash reference of possible status
34 names and colors.
35
36 =cut
37
38 sub statuscolors {
39   #my $self = shift; #i guess i'm a class method
40
41   my %statuscolors;
42
43   if ( $module eq 'Classic' ) {
44     tie %statuscolors, 'Tie::IxHash',
45       'prospect'  => 'FF00F5', #'000000', #black?  naw, purple
46       'active'    => '00CC00', #green
47       'ordered'   => '009999', #teal? cyan?
48       'inactive'  => '0000CC', #blue
49       'suspended' => 'FF9900', #yellow
50       'cancelled' => 'FF0000', #red
51     ;
52   } elsif ( $module eq 'Recurring' ) {
53     tie %statuscolors, 'Tie::IxHash',
54       'prospect'  => 'FF00F5', #'000000', #black?  naw, purple
55       'active'    => '00CC00', #green
56       'ordered'   => '009999', #teal? cyan?
57       'suspended' => 'FF9900', #yellow
58       'cancelled' => 'FF0000', #red
59       'inactive'  => '0000CC', #blue
60     ;
61   } else {
62     die "unknown status module $module";
63   }
64
65   \%statuscolors;
66
67 }
68
69 sub statuslabels {
70   #my $self = shift; #i guess i'm a class method
71
72   my %statuslabels = (
73       'prospect'  => 'No packages',
74       'active'    => 'Active',
75       'ordered'   => 'Ordered',
76       'inactive'  => 'Inactive',
77       'suspended' => 'Suspended',
78       'cancelled' => 'Cancelled',
79   );
80
81   \%statuslabels;
82 }
83
84 =item cancelled_sql
85
86 =cut
87
88 sub cancelled_sql {
89   my $self = shift;
90
91   my $recurring_sql = FS::cust_pkg->recurring_sql;
92   my $cancelled_sql = FS::cust_pkg->cancelled_sql;
93   my $select_count_pkgs = $self->select_count_pkgs_sql;
94
95   my $sql = "
96         0 < ( $select_count_pkgs )
97     AND 0 = ( $select_count_pkgs AND $recurring_sql
98                   AND ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
99             )
100     AND 0 < ( $select_count_pkgs AND $cancelled_sql   )
101   ";
102
103   if ( $module eq 'Classic' ) {
104     $sql .=
105       " AND 0 = (  $select_count_pkgs AND ". FS::cust_pkg->inactive_sql. " ) ";
106   #} elsif ( $module eq 'Recurring' ) {
107   #} else {
108   #  die "unknown status module $module";
109   }
110
111   $sql;
112
113 }
114
115 =back
116
117 =head1 CLASS METHODS
118
119 =over 4
120
121 =item churn_sql START, END
122
123 Returns an SQL statement for the customer churn status query.  The columns
124 returned are the custnum and the number of active, suspended, and cancelled
125 packages (excluding one-time packages) at the start date ("s_active",
126 "s_suspended", and "s_cancelled") and the end date ("e_active", etc.).
127
128 =cut
129
130 # not sure this belongs here...FS::cust_main::Packages?
131
132 sub churn_sql {
133   my $self = shift;
134   my ($speriod, $eperiod) = @_;
135
136   my $s_sql = FS::h_cust_pkg->status_as_of_sql($speriod);
137   my $e_sql = FS::h_cust_pkg->status_as_of_sql($eperiod);
138
139   my @select = (
140     'custnum',
141     'COALESCE(SUM(s.is_active::int),0)     as s_active',
142     'COALESCE(SUM(s.is_suspended::int),0)  as s_suspended',
143     'COALESCE(SUM(s.is_cancelled::int),0)  as s_cancelled',
144     'COALESCE(SUM(e.is_active::int),0)     as e_active',
145     'COALESCE(SUM(e.is_suspended::int),0)  as e_suspended',
146     'COALESCE(SUM(e.is_cancelled::int),0)  as e_cancelled',
147   );
148   my $from = "($s_sql) AS s FULL JOIN ($e_sql) AS e USING (custnum)";
149
150   return "SELECT ".join(',', @select)." FROM $from GROUP BY custnum";
151 }
152
153 =head1 BUGS
154
155 =head1 SEE ALSO
156
157 L<FS::cust_main>
158
159 =cut
160
161 1;
162