advanced account reports (RT#2954)
[freeside.git] / httemplate / search / svc_acct.cgi
1 <% include( 'elements/search.html',
2                  'title'       => 'Account Search Results',
3                  'name'        => 'accounts',
4                  'query'       => $sql_query,
5                  'count_query' => $count_query,
6                  'redirect'    => $link,
7                  'header'      => [ '#',
8                                     'Service',
9                                     'Account',
10                                     'UID',
11                                     'Last Login',
12                                     FS::UI::Web::cust_header(
13                                       $cgi->param('cust_fields')
14                                     ),
15                                   ],
16                  'fields'      => [ 'svcnum',
17                                     'svc',
18                                     'email',
19                                     'uid',
20                                     'last_login_text',
21                                     \&FS::UI::Web::cust_fields,
22                                   ],
23                  'links'       => [ $link,
24                                     $link,
25                                     $link,
26                                     $link,
27                                     $link,
28                                     ( map { $_ ne 'Cust. Status' ? $link_cust : '' }
29                                           FS::UI::Web::cust_header(
30                                             $cgi->param('cust_fields')
31                                           )
32                                     ),
33                                   ],
34                  'align' => 'rlllr'. FS::UI::Web::cust_aligns(),
35                  'color' => [ 
36                               '',
37                               '',
38                               '',
39                               '',
40                               '',
41                               FS::UI::Web::cust_colors(),
42                             ],
43                  'style' => [ 
44                               '',
45                               '',
46                               '',
47                               '',
48                               '',
49                               FS::UI::Web::cust_styles(),
50                             ],
51              )
52 %>
53 <%init>
54
55 die "access denied"
56   unless $FS::CurrentUser::CurrentUser->access_right('List services');
57
58 my @extra_sql = ();
59
60  if ( $cgi->param('domain') ) { 
61    my $svc_domain =
62      qsearchs('svc_domain', { 'domain' => $cgi->param('domain') } );
63    unless ( $svc_domain ) {
64      #it would be nice if this looked more like the other "not found"
65      #errors, but this will do for now.
66      errorpage("Domain ". $cgi->param('domain'). " not found at all");
67    } else {
68      push @extra_sql, 'domsvc = '. $svc_domain->svcnum;
69    }
70  }
71
72 my $orderby = 'ORDER BY svcnum';
73 if ( $cgi->param('magic') =~ /^(all|unlinked)$/ ) {
74
75   push @extra_sql, 'pkgnum IS NULL'
76     if $cgi->param('magic') eq 'unlinked';
77
78   if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
79     my $sortby = $1;
80     $sortby = "LOWER($sortby)"
81       if $sortby eq 'username';
82     push @extra_sql, "$sortby IS NOT NULL"
83       if ($sortby eq 'uid' or $sortby eq 'last_login');
84     $orderby = "ORDER BY $sortby";
85   }
86
87 } elsif ( $cgi->param('magic') =~ /^nologin$/ ) {
88
89   if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
90     my $sortby = $1;
91     $sortby = "LOWER($sortby)"
92       if $sortby eq 'username';
93     push @extra_sql, "last_login IS NULL";
94     $orderby = "ORDER BY $sortby";
95   }
96
97 } elsif ( $cgi->param('magic') =~ /^advanced$/ ) {
98   $orderby = "";
99
100   if ( $cgi->param('agentnum') =~ /^(\d+)$/ and $1 ) {
101     push @extra_sql, "agentnum = $1";
102   }
103
104   my $pkgpart = join (' OR cust_pkg.pkgpart=',
105                       grep {$_} map { /^(\d+)$/; } ($cgi->param('pkgpart')));
106   push @extra_sql,  '(cust_pkg.pkgpart=' . $pkgpart . ')' if $pkgpart;
107                       
108   foreach my $field (qw( last_login last_logout )) {
109
110     my($beginning, $ending) = FS::UI::Web::parse_beginning_ending($cgi, $field);
111
112     next if $beginning == 0 && $ending == 4294967295;
113
114     if ($cgi->param($field."_invert")) {
115       push @extra_sql,
116         "(svc_acct.$field IS NULL OR ".
117         "svc_acct.$field < $beginning AND ".
118         "svc_acct.$field > $ending)";
119     } else {
120       push @extra_sql,
121         "svc_acct.$field IS NOT NULL",
122         "svc_acct.$field >= $beginning",
123         "svc_acct.$field <= $ending";
124     }
125   
126     $orderby ||= "ORDER BY svc_acct.$field" .
127       ($cgi->param($field."_invert") ? ' DESC' : '');
128
129   }
130
131   $orderby ||= "ORDER BY svcnum";
132
133 } elsif ( $cgi->param('popnum') =~ /^(\d+)$/ ) {
134   push @extra_sql, "popnum = $1";
135   $orderby = "ORDER BY LOWER(username)";
136 } elsif ( $cgi->param('svcpart') =~ /^(\d+)$/ ) {
137   push @extra_sql, "svcpart = $1";
138   $orderby = "ORDER BY uid";
139   #$orderby = "ORDER BY svcnum";
140 } else {
141   $orderby = "ORDER BY uid";
142
143   my @username_sql;
144
145   my %username_type;
146   foreach ( $cgi->param('username_type') ) {
147     $username_type{$_}++;
148   }
149
150   $cgi->param('username') =~ /^([\w\-\.\&]+)$/; #untaint username_text
151   my $username = $1;
152
153   push @username_sql, "username ILIKE '$username'"
154     if $username_type{'Exact'}
155     || $username_type{'Fuzzy'};
156
157   push @username_sql, "username ILIKE '\%$username\%'"
158     if $username_type{'Substring'}
159     || $username_type{'All'};
160
161   if ( $username_type{'Fuzzy'} || $username_type{'All'} ) {
162     &FS::svc_acct::check_and_rebuild_fuzzyfiles;
163     my $all_username = &FS::svc_acct::all_username;
164
165     my %username;
166     if ( $username_type{'Fuzzy'} || $username_type{'All'} ) { 
167       foreach ( amatch($username, [ qw(i) ], @$all_username) ) {
168         $username{$_}++; 
169       }
170     }
171
172     #if ($username_type{'Sound-alike'}) {
173     #}
174
175     push @username_sql, "username = '$_'"
176       foreach (keys %username);
177
178   }
179
180   push @extra_sql, '( '. join( ' OR ', @username_sql). ' )';
181
182 }
183
184 my $addl_from = ' LEFT JOIN cust_svc  USING ( svcnum  ) '.
185                 ' LEFT JOIN part_svc  USING ( svcpart ) '.
186                 ' LEFT JOIN cust_pkg  USING ( pkgnum  ) '.
187                 ' LEFT JOIN cust_main USING ( custnum ) ';
188
189 #here is the agent virtualization
190 push @extra_sql, $FS::CurrentUser::CurrentUser->agentnums_sql;
191
192 my $extra_sql = 
193   scalar(@extra_sql)
194     ? ' WHERE '. join(' AND ', @extra_sql )
195     : '';
196
197 my $count_query = "SELECT COUNT(*) FROM svc_acct $addl_from $extra_sql";
198 #if ( keys %svc_acct ) {
199 #  $count_query .= ' WHERE '.
200 #                    join(' AND ', map "$_ = ". dbh->quote($svc_acct{$_}),
201 #                                      keys %svc_acct
202 #                        );
203 #}
204
205 my $sql_query = {
206   'table' => 'svc_acct',
207   'hashref'   => {}, # \%svc_acct,
208   'select'    => join(', ',
209                     'svc_acct.*',
210                     'part_svc.svc',
211                     'cust_main.custnum',
212                     FS::UI::Web::cust_sql_fields(),
213                   ),
214   'extra_sql' => "$extra_sql $orderby",
215   'addl_from' => $addl_from,
216 };
217
218 my $link      = [ "${p}view/svc_acct.cgi?",   'svcnum'  ];
219 my $link_cust = sub {
220   my $svc_acct = shift;
221   if ( $svc_acct->custnum ) {
222     [ "${p}view/cust_main.cgi?", 'custnum' ];
223   } else {
224     '';
225   }
226 };
227
228 </%init>
229