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