v4 style
[freeside.git] / httemplate / search / sqlradius.cgi
1 <& /elements/header.html, 'RADIUS Sessions' &>
2
3 % ###
4 % # and finally, display the thing
5 % ### 
6 %
7 % foreach my $part_export ( @part_export ) {
8 %
9 %   %user2svc = ();
10 %
11 %   my $efields = tie my %efields, 'Tie::IxHash', %fields;
12 %   delete $efields{'framedipaddress'} if $part_export->option('hide_ip');
13 %   if ( $part_export->option('hide_data') ) {
14 %     delete $efields{$_} foreach qw(acctinputoctets acctoutputoctets);
15 %   }
16
17     <FONT CLASS="fsinnerbox-title">
18       <% $part_export->exportname || $part_export->exporttype |h %>
19       <% $part_export->machine ? ' to '. $part_export->machine : '' |h %>
20     </FONT><BR>
21
22     <& /elements/table-grid.html &>
23 %   my $bgcolor1 = '#eeeeee';
24 %   my $bgcolor2 = '#ffffff';
25 %   my $bgcolor;
26
27     <TR>
28 %   foreach my $field ( keys %efields ) { 
29
30       <TH CLASS="grid" BGCOLOR="#cccccc">
31         <% $efields{$field}->{name} %><BR>
32         <FONT SIZE=-2><% $efields{$field}->{attrib} %></FONT>
33       </TH>
34
35 %   } 
36   </TR>
37
38 %   foreach my $session (
39 %       @{ $part_export->usage_sessions( {
40 %            'stoptime_start'  => $beginning,
41 %            'stoptime_end'    => $ending,
42 %            'session_status'  => $status,
43 %            'starttime_start' => $starttime_beginning,
44 %            'starttime_end'   => $starttime_ending,
45 %            'svc'             => $cgi_svc,
46 %            'ip'              => $ip,
47 %            'prefix'          => $prefix, 
48 %            'summarize'       => $summarize,
49 %          } )
50 %       }
51 %   ) {
52 %     if ( $bgcolor eq $bgcolor1 ) {
53 %       $bgcolor = $bgcolor2;
54 %     } else {
55 %       $bgcolor = $bgcolor1;
56 %     }
57
58       <TR>
59 %     foreach my $field ( keys %efields ) { 
60 %       my $html = &{ $efields{$field}->{fmt} }( $session->{$field},
61 %                                                $session,
62 %                                                $part_export,
63 %                                              );
64 %       my $class = ( $html =~ /<TABLE/ ? 'inv' : 'grid' );
65
66         <TD CLASS="<%$class%>" BGCOLOR="<% $bgcolor %>" ALIGN="<% $efields{$field}->{align} %>">
67           <% $html %>
68         </TD>
69 %     } 
70   </TR>
71
72 %   } 
73
74 </TABLE>
75 <BR><BR>
76
77 % } 
78
79 <%init>
80
81 die "access denied"
82   unless $FS::CurrentUser::CurrentUser->access_right('List rating data');
83
84 ###
85 # parse cgi params
86 ###
87
88 my $summarize = 0;
89 $summarize = 1 if $cgi->param('summarize') eq 'Y';
90
91 #sort of false laziness w/cust_pay.cgi
92 my( $beginning, $ending ) = ( '', '' );
93 if ( $cgi->param('stoptime_beginning')
94      && $cgi->param('stoptime_beginning') =~ /^([ 0-9\-\/\:\w]{0,54})$/ ) {
95   $beginning = parse_datetime($1);
96 }
97 if ( $cgi->param('stoptime_ending')
98      && $cgi->param('stoptime_ending') =~ /^([ 0-9\-\/\:\w]{0,54})$/ ) {
99   $ending = parse_datetime($1); # + 86399;
100 }
101 if ( $cgi->param('begin') && $cgi->param('begin') =~ /^(\d+)$/ ) {
102   $beginning = $1;
103 }
104 if ( $cgi->param('end') && $cgi->param('end') =~ /^(\d+)$/ ) {
105   $ending = $1;
106 }
107
108 my $status = '';
109 if ( $cgi->param('session_status') =~ /^(closed|open)$/ ) {
110   $status = $1;
111 }
112
113 my( $starttime_beginning, $starttime_ending ) = ( '', '' );
114 if ( $cgi->param('starttime_beginning')
115      && $cgi->param('starttime_beginning') =~ /^([ 0-9\-\/\:\w]{0,54})$/ ) {
116   $starttime_beginning = parse_datetime($1);
117 }
118 if ( $cgi->param('starttime_ending')
119      && $cgi->param('starttime_ending') =~ /^([ 0-9\-\/\:\w]{0,54})$/ ) {
120   $starttime_ending = parse_datetime($1); # + 86399;
121 }
122
123 my $cgi_svc = '';
124 if ( $cgi->param('svcnum') =~ /^(\d+)$/ ) {
125   $cgi_svc =  qsearchs( 'svc_acct',      { 'svcnum' => $1 } )
126            || qsearchs( 'svc_broadband', { 'svcnum' => $1 } );
127 } elsif ( $cgi->param('username') =~ /^([^@]+)\@([^@]+)$/ ) {
128   my %search = { 'username' => $1 };
129   my $svc_domain = qsearchs('svc_domain', { 'domain' => $2 } );
130   if ( $svc_domain ) {
131     $search{'domsvc'} = $svc_domain->svcnum;
132   } else {
133     delete $search{'username'};
134   }
135   $cgi_svc = qsearchs( 'svc_acct', \%search )
136     if keys %search;
137 } elsif ( $cgi->param('username') =~ /^(.+)$/ ) {
138   $cgi_svc = qsearchs( 'svc_acct', { 'username' => $1 } );
139 }
140
141 my @part_export = ();
142 if ( $cgi_svc ) {
143   my $part_svc = $cgi_svc->cust_svc->part_svc;
144   @part_export = (
145     $part_svc->part_export('sqlradius'),
146     $part_svc->part_export('sqlradius_withdomain'),
147     $part_svc->part_export('broadband_sqlradius'),
148   );
149 } else {
150   @part_export = (
151     #grep $_->can('usage_sessions'), qsearch( 'part_export' )
152     qsearch( 'part_export', { 'exporttype' => 'sqlradius' } ),
153     qsearch( 'part_export', { 'exporttype' => 'sqlradius_withdomain' } ),
154     qsearch( 'part_export', { 'exporttype' => 'broadband_sqlradius' } ),
155   );
156 }
157
158 my $ip = '';
159 if ( $cgi->param('ip') =~ /^((\d+\.){3}\d+)$/ ) {
160   $ip = $1;
161 }
162
163 my $prefix = $cgi->param('prefix');
164 $prefix =~ s/\D//g;
165 if ( $prefix =~ /^(\d+)$/ ) {
166   $prefix = $1;
167   $prefix = "011$prefix" unless $prefix =~ /^1/;
168 } else {
169   $prefix = '';
170 }
171
172 ###
173 # field formatting subroutines
174 ###
175
176 my %user2svc = ();
177 my $user_format = sub {
178   my ( $user, $session, $part_export ) = @_;
179
180   my $svc = '';
181   if ( exists $user2svc{$user} ) {
182     $svc = $user2svc{$user};
183   } else {
184
185     if ( $part_export->exporttype eq 'broadband_sqlradius' ) {
186
187       ( my $mac = $user ) =~ s/[^0-9a-f]//ig;
188
189       my @svc_broadband =
190         grep { qsearchs( 'export_svc', {
191                  'exportnum' => $part_export->exportnum,
192                  'svcpart'   => $_->cust_svc->svcpart,
193                } )
194              } qsearch( 'svc_broadband', {
195                           mac_addr => { op=>'ILIKE', value=>$mac }
196                       });
197
198       if ( @svc_broadband ) {
199         warn 'multiple svc_broadband records for user $user found; '.
200              'using first arbitrarily'
201           if scalar(@svc_broadband) > 1;
202         $user2svc{$user} = $svc = shift @svc_broadband;
203       }
204
205     } else {
206
207       my %search = ();
208       if ( $part_export->exporttype eq 'sqlradius_withdomain' ) {
209         my $domain;
210         if ( $user =~ /^([^@]+)\@([^@]+)$/ ) {
211          $search{'username'} = $1;
212          $domain = $2;
213        } else {
214          $search{'username'} = $user;
215          $domain = $session->{'realm'};
216        }
217        my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } );
218        if ( $svc_domain ) {
219          $search{'domsvc'} = $svc_domain->svcnum;
220        } else {
221          delete $search{'username'};
222        }
223       } elsif ( $part_export->exporttype eq 'sqlradius' ) {
224         $search{'username'} = $user;
225       } else {
226         die 'unknown export type '. $part_export->exporttype.
227             " for $part_export\n";
228       }
229       if ( keys %search ) {
230         my @svc_acct =
231           grep { qsearchs( 'export_svc', {
232                    'exportnum' => $part_export->exportnum,
233                    'svcpart'   => $_->cust_svc->svcpart,
234                  } )
235                } qsearch( 'svc_acct', \%search );
236         if ( @svc_acct ) {
237           warn 'multiple svc_acct records for user $user found; '.
238                'using first arbitrarily'
239             if scalar(@svc_acct) > 1;
240           $user2svc{$user} = $svc = shift @svc_acct;
241         }
242       } 
243
244     }
245
246   }
247
248   $user = encode_entities($user);
249
250   if ( $svc ) { 
251
252     #i should use svc_link, but that's expensive per-user
253     my $svcnum = $svc->svcnum;
254     my $table = $svc->table;
255     qq(<A HREF="${p}view/$table.cgi?$svcnum"><B>$user</B></A>);
256
257   } else {
258     "<B>$user</B>";
259   }
260
261 };
262
263 my $customer_format = sub {
264   my( $unused, $session ) = @_;
265   return '&nbsp;' unless exists $user2svc{$session->{'username'}};
266   my $svc = $user2svc{$session->{'username'}};
267   my $cust_pkg = $svc->cust_svc->cust_pkg;
268   return '&nbsp;' unless $cust_pkg;
269   my $cust_main = $cust_pkg->cust_main;
270
271   qq!<A HREF="${p}view/cust_main.cgi?!. $cust_main->custnum. '">'.
272     encode_entities($cust_pkg->cust_main->name). '</A>';
273 };
274
275 my $time_format = sub {
276   my $time = shift;
277   return '&nbsp;' if $time == 0;
278   my $pretty = time2str('%T%P %a&nbsp;%b&nbsp;%o&nbsp;%Y', $time );
279   $pretty =~ s/ (\d)(st|dn|rd|th)/$1$2/;
280   $pretty;
281 };
282
283 my $time_format_or_open = sub {
284   my $time = shift;
285   return '<CENTER>OPEN</CENTER>' if $time == 0;
286   &{$time_format}($time);
287 };
288
289 my $duration_format = sub {
290   my $seconds = shift;
291   return '' if $seconds eq ''; # open session
292   my $hour = int($seconds/3600);
293   my $min = int( ($seconds%3600) / 60 );
294   my $sec = $seconds%60;
295   '<TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0>'.
296   '<TR><TD CLASS="inv" ALIGN="right">'.
297      ( $hour ? "<B>$hour</B>h" : '&nbsp;' ).
298    '</TD><TD CLASS="inv" ALIGN="right">'.
299      ( ( $hour || $min ) ? "<B>$min</B>m" : '&nbsp;' ).
300    '</TD><TD CLASS="inv" ALIGN="right">'.
301      "<B>$sec</B>s".
302   '</TD></TR></TABLE>';
303 };
304
305 my $octets_format = sub {
306   my $octets = shift;
307   #my $megs = $octets / 1048576;
308   #sprintf('<B>%.3f</B>&nbsp;megs', $megs);
309   my $gigs = $octets / 1073741824;
310   sprintf('<B>%.3f</B>&nbsp;gigs', $gigs);
311 };
312
313 my $mac_format = sub {
314   my $value = shift;
315   if (     $value =~ /^\s*(([\dA-F]{2}[\-:]){5}[\dA-F]{2})/i
316        and my $vendor = Net::MAC::Vendor::lookup($1)
317      )
318   {
319     return encode_entities($value).
320            ' <span style="white-space: nowrap">('.
321              encode_entities($vendor->[0]).
322            ')</span>';
323   }
324   length($value) ? encode_entities($value) : '&nbsp';
325 };
326
327
328 ###
329 # the fields
330 ###
331
332 my %fields;
333 if ( $summarize ) {
334
335   tie %fields, 'Tie::IxHash', 
336     'username'          => {
337                              name    => 'User',
338                              attrib  => 'UserName',
339                              fmt     => $user_format,
340                              align   => 'left',
341                            },
342     'dummy'             => {
343                              name    => 'Customer',
344                              attrib  => '',
345                              fmt     => $customer_format,
346                              align   => 'left',
347                            },
348     'acctsessiontime'   => {
349                              name    => 'Duration',
350                              attrib  => 'Acct-Session-Time',
351                              fmt     => $duration_format,
352                              align   => 'right',
353                            },
354     'acctinputoctets'   => {
355                              name    => 'Upload', # (from user)',
356                              attrib  => 'Acct-Input-Octets',
357                              fmt     => $octets_format,
358                              align   => 'right',
359                            },
360     'acctoutputoctets'  => {
361                              name    => 'Download', # (to user)',
362                              attrib  => 'Acct-Output-Octets',
363                              fmt     => $octets_format,
364                              align   => 'right',
365                            },
366   ;
367
368 } else {
369
370   tie %fields, 'Tie::IxHash',
371     'username'          => {
372                              name    => 'User',
373                              attrib  => 'UserName',
374                              fmt     => $user_format,
375                              align   => 'left',
376                            },
377     'realm'             => {
378                              name    => 'Realm',
379                              attrib  => 'Realm',
380                              align   => 'left',
381                            },
382     'dummy'             => {
383                              name    => 'Customer',
384                              attrib  => '',
385                              fmt     => $customer_format,
386                              align   => 'left',
387                            },
388     'framedipaddress'   => {
389                              name    => 'IP&nbsp;Address',
390                              attrib  => 'Framed-IP-Address',
391                              fmt     => sub { my $ip = shift;
392                                               length($ip) ? $ip : '&nbsp';
393                                             },
394                              align   => 'right',
395                            },
396     'callingstationid'  => {
397                              name    => 'Source&nbsp;or&nbsp;MAC',
398                              attrib  => 'Calling-Station-Id',
399                              fmt     => $mac_format,
400                              align   => 'right',
401                            },
402     'calledstationid'   => {
403                              name    => 'Destination',
404                              attrib  => 'Called-Station-ID',
405                              fmt     => $mac_format,
406                              align   => 'left',
407                          },
408     'acctstarttime'     => {
409                              name    => 'Start&nbsp;time',
410                              attrib  => 'Acct-Start-Time',
411                              fmt     => $time_format,
412                              align   => 'left',
413                            },
414     'acctstoptime'      => {
415                              name    => 'End&nbsp;time',
416                              attrib  => 'Acct-Stop-Time',
417                              fmt     => $time_format_or_open,
418                              align   => 'left',
419                            },
420     'acctsessiontime'   => {
421                              name    => 'Duration',
422                              attrib  => 'Acct-Session-Time',
423                              fmt     => $duration_format,
424                              align   => 'right',
425                            },
426     'acctinputoctets'   => {
427                              name    => 'Upload', # (from user)',
428                              attrib  => 'Acct-Input-Octets',
429                              fmt     => $octets_format,
430                              align   => 'right',
431                            },
432     'acctoutputoctets'  => {
433                              name    => 'Download', # (to user)',
434                              attrib  => 'Acct-Output-Octets',
435                              fmt     => $octets_format,
436                              align   => 'right',
437                            },
438   ;
439 }
440 $fields{$_}->{fmt} ||= sub { length($_[0]) ? encode_entities(shift) : '&nbsp'; }
441   foreach keys %fields;
442
443 </%init>