add customer status column to customer & most other reports. also put the C in ACL...
[freeside.git] / FS / FS / cust_main_Mixin.pm
1 package FS::cust_main_Mixin;
2
3 use strict;
4 use vars qw( $DEBUG );
5 use FS::UID qw(dbh);
6 use FS::cust_main;
7
8 $DEBUG = 1;
9
10 =head1 NAME
11
12 FS::cust_main_Mixin - Mixin class for records that contain fields from cust_main
13
14 =head1 SYNOPSIS
15
16 package FS::some_table;
17 use vars qw(@ISA);
18 @ISA = qw( FS::cust_main_Mixin FS::Record );
19
20 =head1 DESCRIPTION
21
22 This is a mixin class for records that contain fields from the cust_main table,
23 for example, from a JOINed search.  See httemplate/search/ for examples.
24
25 =head1 METHODS
26
27 =over 4
28
29 =item name
30
31 Given an object that contains fields from cust_main (say, from a JOINed
32 search; see httemplate/search/ for examples), returns the equivalent of the
33 FS::cust_main I<name> method, or "(unlinked)" if this object is not linked to
34 a customer.
35
36 =cut
37
38 sub cust_unlinked_msg { '(unlinked)'; }
39 sub cust_linked { $_[0]->custnum; }
40
41 sub name {
42   my $self = shift;
43   $self->cust_linked
44     ? FS::cust_main::name($self)
45     : $self->cust_unlinked_msg;
46 }
47
48 =item ship_name
49
50 Given an object that contains fields from cust_main (say, from a JOINed
51 search; see httemplate/search/ for examples), returns the equivalent of the
52 FS::cust_main I<ship_name> method, or "(unlinked)" if this object is not
53 linked to a customer.
54
55 =cut
56
57 sub ship_name {
58   my $self = shift;
59   $self->cust_linked
60     ? FS::cust_main::ship_name($self)
61     : $self->cust_unlinked_msg;
62 }
63
64 =item contact
65
66 Given an object that contains fields from cust_main (say, from a JOINed
67 search; see httemplate/search/ for examples), returns the equivalent of the
68 FS::cust_main I<contact> method, or "(unlinked)" if this object is not linked
69 to a customer.
70
71 =cut
72
73 sub contact {
74   my $self = shift;
75   $self->cust_linked
76     ? FS::cust_main::contact($self)
77     : $self->cust_unlinked_msg;
78 }
79
80 =item ship_contact
81
82 Given an object that contains fields from cust_main (say, from a JOINed
83 search; see httemplate/search/ for examples), returns the equivalent of the
84 FS::cust_main I<ship_contact> method, or "(unlinked)" if this object is not
85 linked to a customer.
86
87 =cut
88
89 sub ship_contact {
90   my $self = shift;
91   $self->cust_linked
92     ? FS::cust_main::ship_contact($self)
93     : $self->cust_unlinked_msg;
94 }
95
96 =item country_full
97
98 Given an object that contains fields from cust_main (say, from a JOINed
99 search; see httemplate/search/ for examples), returns the equivalent of the
100 FS::cust_main I<country_full> method, or "(unlinked)" if this object is not
101 linked to a customer.
102
103 =cut
104
105 sub country_full {
106   my $self = shift;
107   $self->cust_linked
108     ? FS::cust_main::country_full($self)
109     : $self->cust_unlinked_msg;
110 }
111
112 =item invoicing_list_emailonly
113
114 Given an object that contains fields from cust_main (say, from a JOINed
115 search; see httemplate/search/ for examples), returns the equivalent of the
116 FS::cust_main I<invoicing_list_emailonly> method, or "(unlinked)" if this
117 object is not linked to a customer.
118
119 =cut
120
121 sub invoicing_list_emailonly {
122   my $self = shift;
123   warn "invoicing_list_email only called on $self, ".
124        "custnum ". $self->custnum. "\n"
125     if $DEBUG;
126   $self->cust_linked
127     ? FS::cust_main::invoicing_list_emailonly($self)
128     : $self->cust_unlinked_msg;
129 }
130
131 =item invoicing_list_emailonly_scalar
132
133 Given an object that contains fields from cust_main (say, from a JOINed
134 search; see httemplate/search/ for examples), returns the equivalent of the
135 FS::cust_main I<invoicing_list_emailonly_scalar> method, or "(unlinked)" if
136 this object is not linked to a customer.
137
138 =cut
139
140 sub invoicing_list_emailonly_scalar {
141   my $self = shift;
142   warn "invoicing_list_emailonly called on $self, ".
143        "custnum ". $self->custnum. "\n"
144     if $DEBUG;
145   $self->cust_linked
146     ? FS::cust_main::invoicing_list_emailonly_scalar($self)
147     : $self->cust_unlinked_msg;
148 }
149
150 =item invoicing_list
151
152 Given an object that contains fields from cust_main (say, from a JOINed
153 search; see httemplate/search/ for examples), returns the equivalent of the
154 FS::cust_main I<invoicing_list> method, or "(unlinked)" if this object is not
155 linked to a customer.
156
157 Note: this method is read-only.
158
159 =cut
160
161 #read-only
162 sub invoicing_list {
163   my $self = shift;
164   $self->cust_linked
165     ? FS::cust_main::invoicing_list($self)
166     : ();
167 }
168
169 =item status
170
171 Given an object that contains fields from cust_main (say, from a JOINed
172 search; see httemplate/search/ for examples), returns the equivalent of the
173 FS::cust_main I<status> method, or "(unlinked)" if this object is not linked to
174 a customer.
175
176 =cut
177
178 sub cust_status {
179   my $self = shift;
180   return $self->cust_unlinked_msg unless $self->cust_linked;
181
182   #FS::cust_main::status($self)
183   #false laziness w/actual cust_main::status
184   # (make sure FS::cust_main methods are called)
185   for my $status (qw( prospect active inactive suspended cancelled )) {
186     my $method = $status.'_sql';
187     my $sql = FS::cust_main->$method();;
188     my $numnum = ( $sql =~ s/cust_main\.custnum/?/g );
189     my $sth = dbh->prepare("SELECT $sql") or die dbh->errstr;
190     $sth->execute( ($self->custnum) x $numnum )
191       or die "Error executing 'SELECT $sql': ". $sth->errstr;
192     return $status if $sth->fetchrow_arrayref->[0];
193   }
194 }
195
196 =item ucfirst_cust_status
197
198 Given an object that contains fields from cust_main (say, from a JOINed
199 search; see httemplate/search/ for examples), returns the equivalent of the
200 FS::cust_main I<ucfirst_status> method, or "(unlinked)" if this object is not
201 linked to a customer.
202
203 =cut
204
205 sub ucfirst_cust_status {
206   my $self = shift;
207   $self->cust_linked
208     ? ucfirst( $self->cust_status(@_) ) 
209     : $self->cust_unlinked_msg;
210 }
211
212 =item cust_statuscolor
213
214 Given an object that contains fields from cust_main (say, from a JOINed
215 search; see httemplate/search/ for examples), returns the equivalent of the
216 FS::cust_main I<statuscol> method, or "000000" if this object is not linked to
217 a customer.
218
219 =cut
220
221 sub cust_statuscolor {
222   my $self = shift;
223
224   $self->cust_linked
225     ? FS::cust_main::cust_statuscolor($self)
226     : '000000';
227 }
228
229 =item prospect_sql
230
231 =item active_sql
232
233 =item inactive_sql
234
235 =item suspended_sql
236
237 =item cancelled_sql
238
239 Given an object that contains fields from cust_main (say, from a JOINed
240 search; see httemplate/search/ for examples), returns the equivalent of the
241 corresponding FS::cust_main method, or "0" if this object is not linked to
242 a customer.
243
244 =cut
245
246 foreach my $sub (qw( prospect active inactive suspended cancelled )) {
247   eval "
248     sub ${sub}_sql {
249       my \$self = shift;
250       \$self->cust_linked
251         ? FS::cust_main::${sub}_sql(\$self)
252         : '0';
253       }
254   ";
255   die $@ if $@;
256 }
257
258 =back
259
260 =head1 BUGS
261
262 =head1 SEE ALSO
263
264 L<FS::cust_main>, L<FS::Record>
265
266 =cut
267
268 1;
269