send commission reports by email, #33101
[freeside.git] / httemplate / search / sqlradius.cgi
1 <% include( '/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     <% include( '/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   if ( $svc ) { 
249
250     #i should use svc_link, but that's expensive per-user
251     my $svcnum = $svc->svcnum;
252     my $table = $svc->table;
253     qq(<A HREF="${p}view/$table.cgi?$svcnum"><B>$user</B></A>);
254
255   } else {
256     "<B>$user</B>";
257   }
258
259 };
260
261 my $customer_format = sub {
262   my( $unused, $session ) = @_;
263   return '&nbsp;' unless exists $user2svc{$session->{'username'}};
264   my $svc = $user2svc{$session->{'username'}};
265   my $cust_pkg = $svc->cust_svc->cust_pkg;
266   return '&nbsp;' unless $cust_pkg;
267   my $cust_main = $cust_pkg->cust_main;
268
269   qq!<A HREF="${p}view/cust_main.cgi?!. $cust_main->custnum. '">'.
270     $cust_pkg->cust_main->name. '</A>';
271 };
272
273 my $time_format = sub {
274   my $time = shift;
275   return '&nbsp;' if $time == 0;
276   my $pretty = time2str('%T%P %a&nbsp;%b&nbsp;%o&nbsp;%Y', $time );
277   $pretty =~ s/ (\d)(st|dn|rd|th)/$1$2/;
278   $pretty;
279 };
280
281 my $time_format_or_open = sub {
282   my $time = shift;
283   return '<CENTER>OPEN</CENTER>' if $time == 0;
284   &{$time_format}($time);
285 };
286
287 my $duration_format = sub {
288   my $seconds = shift;
289   return '' if $seconds eq ''; # open session
290   my $hour = int($seconds/3600);
291   my $min = int( ($seconds%3600) / 60 );
292   my $sec = $seconds%60;
293   '<TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0>'.
294   '<TR><TD CLASS="inv" ALIGN="right">'.
295      ( $hour ? "<B>$hour</B>h" : '&nbsp;' ).
296    '</TD><TD CLASS="inv" ALIGN="right">'.
297      ( ( $hour || $min ) ? "<B>$min</B>m" : '&nbsp;' ).
298    '</TD><TD CLASS="inv" ALIGN="right">'.
299      "<B>$sec</B>s".
300   '</TD></TR></TABLE>';
301 };
302
303 my $octets_format = sub {
304   my $octets = shift;
305   #my $megs = $octets / 1048576;
306   #sprintf('<B>%.3f</B>&nbsp;megs', $megs);
307   my $gigs = $octets / 1073741824;
308   sprintf('<B>%.3f</B>&nbsp;gigs', $gigs);
309 };
310
311 ###
312 # the fields
313 ###
314
315 my %fields;
316 if ( $summarize ) {
317 tie %fields, 'Tie::IxHash', 
318   'username'          => {
319                            name    => 'User',
320                            attrib  => 'UserName',
321                            fmt     => $user_format,
322                            align   => 'left',
323                          },
324   'dummy'             => {
325                            name    => 'Customer',
326                            attrib  => '',
327                            fmt     => $customer_format,
328                            align   => 'left',
329                          },
330   'acctsessiontime'   => {
331                            name    => 'Duration',
332                            attrib  => 'Acct-Session-Time',
333                            fmt     => $duration_format,
334                            align   => 'right',
335                          },
336   'acctinputoctets'   => {
337                            name    => 'Upload', # (from user)',
338                            attrib  => 'Acct-Input-Octets',
339                            fmt     => $octets_format,
340                            align   => 'right',
341                          },
342   'acctoutputoctets'  => {
343                            name    => 'Download', # (to user)',
344                            attrib  => 'Acct-Output-Octets',
345                            fmt     => $octets_format,
346                            align   => 'right',
347                          },
348 ;
349 } else {
350 tie %fields, 'Tie::IxHash',
351   'username'          => {
352                            name    => 'User',
353                            attrib  => 'UserName',
354                            fmt     => $user_format,
355                            align   => 'left',
356                          },
357   'realm'             => {
358                            name    => 'Realm',
359                            attrib  => 'Realm',
360                            align   => 'left',
361                          },
362   'dummy'             => {
363                            name    => 'Customer',
364                            attrib  => '',
365                            fmt     => $customer_format,
366                            align   => 'left',
367                          },
368   'framedipaddress'   => {
369                            name    => 'IP&nbsp;Address',
370                            attrib  => 'Framed-IP-Address',
371                            fmt     => sub { my $ip = shift;
372                                             length($ip) ? $ip : '&nbsp';
373                                           },
374                            align   => 'right',
375                          },
376   'callingstationid'  => {
377                            name    => 'Source&nbsp;or&nbsp;MAC',
378                            attrib  => 'Calling-Station-Id',
379                            fmt     => sub {
380                              my $src = shift;
381                              if ( $src =~
382                                     /^\s*(([\dA-F]{2}[\-:]){5}[\dA-F]{2})/i ) {
383                                return $src. ' <span style="white-space: nowrap">('.
384                                         (Net::MAC::Vendor::lookup($1))->[0].
385                                       ')</span>';
386
387                              }
388                              length($src) ? $src : '&nbsp';
389                            },
390                            align   => 'right',
391                          },
392   'calledstationid'   => {
393                            name    => 'Destination',
394                            attrib  => 'Called-Station-ID',
395                            fmt     => sub {
396                              my $dst = shift;
397                              if ( $dst =~
398                                     /^\s*(([\dA-F]{2}[\-:]){5}[\dA-F]{2})/i ) {
399                                return $dst. ' <span style="white-space: nowrap">('.
400                                         (Net::MAC::Vendor::lookup($1))->[0].
401                                       ')</span>';
402                              }
403                              length($dst) ? $dst : '&nbsp';
404                            },
405                            align   => 'left',
406                        },
407   'acctstarttime'     => {
408                            name    => 'Start&nbsp;time',
409                            attrib  => 'Acct-Start-Time',
410                            fmt     => $time_format,
411                            align   => 'left',
412                          },
413   'acctstoptime'      => {
414                            name    => 'End&nbsp;time',
415                            attrib  => 'Acct-Stop-Time',
416                            fmt     => $time_format_or_open,
417                            align   => 'left',
418                          },
419   'acctsessiontime'   => {
420                            name    => 'Duration',
421                            attrib  => 'Acct-Session-Time',
422                            fmt     => $duration_format,
423                            align   => 'right',
424                          },
425   'acctinputoctets'   => {
426                            name    => 'Upload', # (from user)',
427                            attrib  => 'Acct-Input-Octets',
428                            fmt     => $octets_format,
429                            align   => 'right',
430                          },
431   'acctoutputoctets'  => {
432                            name    => 'Download', # (to user)',
433                            attrib  => 'Acct-Output-Octets',
434                            fmt     => $octets_format,
435                            align   => 'right',
436                          },
437 ;
438 }
439 $fields{$_}->{fmt} ||= sub { length($_[0]) ? shift : '&nbsp'; }
440   foreach keys %fields;
441
442 </%init>