RT# 77532 - Updated customer contact reports to display contact phone numers
[freeside.git] / httemplate / search / contact.html
1 <& elements/search.html,
2   title            => 'Contacts',
3   name_singular    => 'contact',
4
5   query => {
6     select    => $select,
7     table     => 'contact',
8     addl_from => $addl_from,
9     hashref   => {},
10     extra_sql => $extra_sql,
11   },
12   count_query => "SELECT COUNT(*) FROM contact $addl_from $extra_sql",
13
14   header           => \@header,
15   fields           => \@fields,
16   links            => \@links,
17
18   agent_virt       => 1,
19   agent_column     => $agentnum_coalesce,
20   agent_pos        => 10,
21   agent_null_right => 'View customers of all agents',
22   agent_null_right_link => 'View customer',
23
24 &>
25
26 % if ( $DEBUG ) {
27   <pre>
28   SELECT <% $select %>
29   FROM contact
30   <% $addl_from %>
31   <% $extra_sql %>
32   ---
33   SELECT COUNT(*) FROM contact <% $addl_from %> <% $extra_sql %>
34   </pre>
35 % }
36
37 <%init>
38
39 die "access denied"
40   unless $FS::CurrentUser::CurrentUser->access_right('List contacts');
41
42 use FS::UID 'dbh';
43 my $dbh = dbh;
44
45 my $DEBUG = 0;
46
47 my $work_phone_sub = sub {
48   my $contact = shift;
49   #can't because contactnum is in the wrong field
50   my @contact_workphone = qsearch('contact_phone', { 'contactnum' => $contact->contact_contactnum, 'phonetypenum' => '1' } );
51   join(', ', map $_->phonenum, @contact_workphone);
52 };
53
54 my $mobile_phone_sub = sub {
55   my $contact = shift;
56   #can't because contactnum is in the wrong field
57   my @contact_mobilephone = qsearch('contact_phone', { 'contactnum' => $contact->contact_contactnum, 'phonetypenum' => '3' } );
58   join(', ', map $_->phonenum, @contact_mobilephone);
59 };
60
61 my $home_phone_sub = sub {
62   my $contact = shift;
63   #can't because contactnum is in the wrong field
64   my @contact_homephone = qsearch('contact_phone', { 'contactnum' => $contact->contact_contactnum, 'phonetypenum' => '2' } );
65   join(', ', map $_->phonenum, @contact_homephone);
66 };
67
68 my $link; #for closure in this sub, we'll define it later
69 my $contact_classname_sub = sub {
70   my $contact = shift;
71   my %hash = ( 'contactnum' => $contact->contact_contactnum );
72   my $X_contact;
73   if ( $link eq 'cust_main' ) {
74     $X_contact = qsearchs('cust_contact', { %hash, 'custnum' => $contact->custnum } );
75   } elsif ( $link eq 'prospect_main' ) {
76     $X_contact = qsearchs('prospect_contact', { %hash, 'prospectnum' => $contact->prospectnum } );
77   } else {
78     die 'guru meditation #5555';
79   }
80   $X_contact->contact_classname;
81 };
82
83 my @header = ( 'First', 'Last', 'Title', 'Email', 'Work Phone', 'Mobile Phone', 'Home Phone', 'Type' );
84 my @fields = ( 'first', 'last', 'title', $email_sub, $work_phone_sub, $mobile_phone_sub, $home_phone_sub, $contact_classname_sub );
85 my @links = ( '', '', '', '', '', '', '', '', );
86
87 my @report = (
88
89   { # Column: First
90     select => 'contact.first',
91     fields => 'first',
92     header => 'First',
93     links  => undef,
94   },
95
96   { # Column: Last
97     select => 'contact.last',
98     fields => 'last',
99     header => 'Last',
100     links  => undef,
101   },
102
103   { # Column: Title
104     select => 'contact.title',
105     fields => 'title',
106     header => 'Title',
107     links  => undef,
108   },
109
110   { # Column: E-Mail
111     select => 'contact_email.emailaddress',
112     fields => 'emailaddress',
113     header => 'E-Mail',
114     links  => undef,
115   },
116
117   { # Column: Work Phone
118     select => '
119       ( SELECT contact_phone.phonenum
120         FROM contact_phone
121         WHERE contact.contactnum = contact_phone.contactnum
122           AND phonetypenum = 1
123       ) AS work_phone
124     ',
125     fields => sub { $format_phone_sub->( shift->work_phone ) },
126     header => 'Work Phone',
127     links  => undef,
128   },
129
130   { # Column: Mobile Phone
131     select => '
132       ( SELECT contact_phone.phonenum
133         FROM contact_phone
134         WHERE contact.contactnum = contact_phone.contactnum
135           AND phonetypenum = 3
136       ) AS mobile_phone
137     ',
138     fields => sub { $format_phone_sub->( shift->mobile_phone ) },
139     header => 'Mobile Phone',
140     links  => undef,
141   },
142
143   # Column: Home Phone
144   #  ( skipped, contact edit screen does not include this )
145
146   { # Column: Contact Type (contact_class)
147     select => 'contact_class.classname',
148     fields => 'classname',
149     header => 'Type',
150     links  => undef,
151   },
152
153   { # Column: Send invoices
154     select => 'cust_main.invoice_noemail',
155     fields => sub {
156       # Prospects cannot opt out (not implemented)
157       # Contacts cannot opt out, but the attached cust_main records can.
158       # Therefore, always YES unless cust_main record is opt-out
159       my $row = shift;
160       return 'No' if $row->invoice_noemail && $row->invoice_noemail eq 'Y';
161       'Yes';
162     },
163     header => 'Receive Invoices',
164     links  => undef,
165   },
166
167   { # Column: Send messages
168     select => 'cust_main.message_noemail',
169     fields => sub {
170       # Same as invoice_noemail, see above
171       my $row = shift;
172       return 'No' if $row->message_noemail && $row->message_noemail eq 'Y';
173       'Yes';
174     },
175     header => 'Receive Messages',
176     links  => undef,
177   },
178
179   { # Column: Customer
180     # The first of these with a value will be displayed:
181     #   1) cust_main.company
182     #   2) cust_main.first + cust_main.last
183     #   3) prospect_main.company
184     #   4) contact.first + contact.last
185     select => q{
186       cust_main.custnum,
187       prospect_main.prospectnum,
188       COALESCE (
189         cust_main.company,
190         prospect_main.company,
191         cust_main.first||' '||cust_main.last,
192         contact.first||' '||contact.last
193       ) as customer_name
194     },
195     fields => 'customer_name',
196     header => 'Customer',
197     links  => [
198       "${fsurl}view/",
199       sub {
200         my $row = shift;
201         $row->custnum
202         ? 'cust_main.cgi?'.$row->custnum
203         : 'prospect_main.html?'.$row->prospectnum
204       }
205     ],
206   },
207
208   # Column: Agent
209   # Inserted by search.html (hopefully)
210
211   { # Column: Self-service
212     select => 'contact.selfservice_access',
213     fields => sub { shift->selfservice_access eq 'Y' ? 'Yes' : 'No' },
214     header => 'Self-Service',
215     links  => undef,
216   },
217
218   { # Column: Comments
219     select => 'contact.comment',
220     fields => 'comment',
221     header => 'Comment',
222     links  => undef,
223   },
224 );
225
226 my $agentnum_coalesce = 'COALESCE( cust_main.agentnum, prospect_main.agentnum )';
227 my @where;
228
229 if ( scalar $cgi->param('agentnum') =~ /^(\d+)$/ ) {
230   push @where, "$agentnum_coalesce = $1";
231 }
232
233 if ( my $contact_source = scalar $cgi->param('contact_source') ) {
234   my $col = $contact_source eq 'prospect_main'
235           ? 'prospect_main.prospectnum'
236           : 'cust_main.custnum';
237   push @where, "$col IS NOT NULL"
238 }
239
240 # SQL to filter classnums is only invoked if at least one classnum
241 # checkbox is selected
242 if (
243   my @classnums = 
244     map{ /^contact_classnum_(null|\d+)$/ ? $1 : () }
245     $cgi->param
246 ) {
247   my @where_classnum;
248   for my $classnum ( @classnums ) {
249     push @where_classnum,
250       $classnum eq 'null'
251       ? ' contact.classnum IS NULL '
252       : sprintf( ' contact.classnum = %s ', $dbh->quote( $classnum ));
253   }
254   push( @where,
255     sprintf(
256       ' ( %s ) ',
257       join( ' OR ', @where_classnum )
258     )
259   );
260 }
261
262 my $select = join ', ', ( map{ $_->{select} } @report );
263 my $addl_from = '
264   LEFT JOIN contact_email USING (contactnum)
265   LEFT JOIN cust_main USING (custnum)
266   LEFT JOIN prospect_main USING (prospectnum)
267   LEFT JOIN contact_class ON contact.classnum = contact_class.classnum
268 ';
269 my $extra_sql = '';
270 my @header = map{ $_->{header} } @report;
271 my @fields = map{ $_->{fields} } @report;
272 my @links  = map{ $_->{links}  } @report;
273 my $extra_sql = 'WHERE ( ' . join( ' AND ', @where ) . ' ) '
274   if @where;
275
276 </%init>