link to customer from manual payment screen (ticket 1414)
[freeside.git] / httemplate / view / svc_acct.cgi
1 %
2 %
3 %my $conf = new FS::Conf;
4 %
5 %my($query) = $cgi->keywords;
6 %$query =~ /^(\d+)$/;
7 %my $svcnum = $1;
8 %my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$svcnum});
9 %die "Unknown svcnum" unless $svc_acct;
10 %
11 %#false laziness w/all svc_*.cgi
12 %my $cust_svc = qsearchs( 'cust_svc' , { 'svcnum' => $svcnum } );
13 %my $pkgnum = $cust_svc->getfield('pkgnum');
14 %my($cust_pkg, $custnum);
15 %if ($pkgnum) {
16 %  $cust_pkg = qsearchs( 'cust_pkg', { 'pkgnum' => $pkgnum } );
17 %  $custnum = $cust_pkg->custnum;
18 %} else {
19 %  $cust_pkg = '';
20 %  $custnum = '';
21 %}
22 %#eofalse
23 %
24 %my $part_svc = qsearchs('part_svc',{'svcpart'=> $cust_svc->svcpart } );
25 %die "Unknown svcpart" unless $part_svc;
26 %my $svc = $part_svc->svc;
27 %
28 %die 'Empty domsvc for svc_acct.svcnum '. $svc_acct->svcnum
29 %  unless $svc_acct->domsvc;
30 %my $svc_domain = qsearchs('svc_domain', { 'svcnum' => $svc_acct->domsvc } );
31 %die 'Unknown domain (domsvc '. $svc_acct->domsvc.
32 %    ' for svc_acct.svcnum '. $svc_acct->svcnum. ')'
33 %  unless $svc_domain;
34 %my $domain = $svc_domain->domain;
35 %
36 %
37 % if ( $custnum ) { 
38
39
40   <% include("/elements/header.html","View $svc account") %>
41
42   <% include( '/elements/small_custview.html', $custnum, '', 1,
43      "${p}view/cust_main.cgi") %>
44   <BR>
45 % } else { 
46
47
48   <SCRIPT>
49   function areyousure(href) {
50       if (confirm("Permanently delete this account?") == true)
51           window.location.href = href;
52   }
53   </SCRIPT>
54   
55   <% include("/elements/header.html",'Account View', menubar(
56     "Cancel this (unaudited) account" =>
57             "javascript:areyousure(\'${p}misc/cancel-unaudited.cgi?$svcnum\')",
58     "Main menu" => $p,
59   )) %>
60 % } 
61 % if ( $part_svc->part_export_usage ) {
62 %
63 %  my $last_bill;
64 %  my %plandata;
65 %  if ( $cust_pkg ) {
66 %    #false laziness w/httemplate/edit/part_pkg... this stuff doesn't really
67 %    #belong in plan data
68 %    %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); }
69 %                    split("\n", $cust_pkg->part_pkg->plandata );
70 %
71 %    $last_bill = $cust_pkg->last_bill;
72 %  } else {
73 %    $last_bill = 0;
74 %    %plandata = ();
75 %  }
76 %
77 %  my $seconds = $svc_acct->seconds_since_sqlradacct( $last_bill, time );
78 %  my $hour = int($seconds/3600);
79 %  my $min = int( ($seconds%3600) / 60 );
80 %  my $sec = $seconds%60;
81 %
82 %  my $input = $svc_acct->attribute_since_sqlradacct(
83 %    $last_bill, time, 'AcctInputOctets'
84 %  ) / 1048576;
85 %  my $output = $svc_acct->attribute_since_sqlradacct(
86 %    $last_bill, time, 'AcctOutputOctets'
87 %  ) / 1048576;
88 %
89 %
90
91
92   RADIUS session information<BR>
93   <% ntable('#cccccc',2) %>
94   <TR><TD BGCOLOR="#ffffff">
95 % if ( $seconds ) { 
96
97     Online <B><% $hour %></B>h <B><% $min %></B>m <B><% $sec %></B>s
98 % } else { 
99
100     Has not logged on
101 % } 
102 % if ( $cust_pkg ) { 
103
104     since last bill (<% time2str('%a %b %o %Y', $last_bill) %>)
105 % if ( length($plandata{recur_included_hours}) ) { 
106
107     - <% $plandata{recur_included_hours} %> total hours in plan
108 % } 
109
110     <BR>
111 % } else { 
112
113     (no billing cycle available for unaudited account)<BR>
114 % } 
115
116
117   Upload: <B><% sprintf("%.3f", $input) %></B> megabytes<BR>
118   Download: <B><% sprintf("%.3f", $output) %></B> megabytes<BR>
119 % my $href = qq!<A HREF="${p}search/sqlradius.cgi?svcnum=$svcnum!; 
120
121   View session detail:
122       <% $href %>;begin=<% $last_bill %>">this billing cycle</A>
123     | <% $href %>;begin=<% time-15552000 %>">past six months</A>
124     | <% $href %>">all sessions</A>
125
126   </TD></TR></TABLE><BR>
127 % } 
128
129
130 <SCRIPT TYPE="text/javascript">
131 function enable_change () {
132   if ( document.OneTrueForm.svcpart.selectedIndex > 1 ) {
133     document.OneTrueForm.submit.disabled = false;
134   } else {
135     document.OneTrueForm.submit.disabled = true;
136   }
137 }
138 </SCRIPT>
139 <FORM NAME="OneTrueForm" ACTION="<%$p%>edit/process/cust_svc.cgi">
140 <INPUT TYPE="hidden" NAME="svcnum" VALUE="<% $svcnum %>">
141 <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>">
142 % #print qq!<BR><A HREF="../misc/sendconfig.cgi?$svcnum">Send account information</A>!; 
143
144 %  my @part_svc = ();
145 %  if ( $pkgnum ) { 
146 %    @part_svc = grep {    $_->svcdb   eq 'svc_acct'
147 %                       && $_->svcpart != $part_svc->svcpart }
148 %                $cust_pkg->available_part_svc;
149 %  } else {
150 %    @part_svc = qsearch('part_svc', {
151 %      svcdb    => 'svc_acct',
152 %      disabled => '',
153 %      svcpart  => { op=>'!=', value=>$part_svc->svcpart },
154 %    } );
155 %  }
156 %
157
158
159 Service #<B><% $svcnum %></B>
160 | <A HREF="<%$p%>edit/svc_acct.cgi?<%$svcnum%>">Edit this service</A>
161 % if ( @part_svc ) { 
162
163 | <SELECT NAME="svcpart" onChange="enable_change()">
164     <OPTION VALUE="">Change service</OPTION>
165     <OPTION VALUE="">--------------</OPTION>
166 % foreach my $opt_part_svc ( @part_svc ) { 
167
168       <OPTION VALUE="<% $opt_part_svc->svcpart %>"><% $opt_part_svc->svc %></OPTION>
169 % } 
170
171   </SELECT>
172   <INPUT NAME="submit" TYPE="submit" VALUE="Change" disabled>
173 % } 
174
175
176 <% &ntable("#cccccc") %><TR><TD><% &ntable("#cccccc",2) %>
177
178 <TR>
179   <TD ALIGN="right">Service</TD>
180   <TD BGCOLOR="#ffffff"><% $part_svc->svc %></TD>
181 </TR>
182 <TR>
183   <TD ALIGN="right">Username</TD>
184   <TD BGCOLOR="#ffffff"><% $svc_acct->username %></TD>
185 </TR>
186 <TR>
187   <TD ALIGN="right">Domain</TD>
188   <TD BGCOLOR="#ffffff"><% $domain %></TD>
189 </TR>
190
191 <TR>
192   <TD ALIGN="right">Password</TD>
193   <TD BGCOLOR="#ffffff">
194 % my $password = $svc_acct->_password; 
195 % if ( $password =~ /^\*\w+\* (.*)$/ ) {
196 %         $password = $1;
197 %    
198
199       <I>(login disabled)</I>
200 % } 
201 % if ( $conf->exists('showpasswords') ) { 
202
203       <PRE><% encode_entities($password) %></PRE>
204 % } else { 
205
206       <I>(hidden)</I>
207 % } 
208
209
210   </TD>
211 </TR>
212 % $password = ''; 
213 % if ( $conf->exists('security_phrase') ) {
214 %     my $sec_phrase = $svc_acct->sec_phrase;
215 %
216
217   <TR>
218     <TD ALIGN="right">Security phrase</TD>
219     <TD BGCOLOR="#ffffff"><% $svc_acct->sec_phrase %></TD>
220   </TR>
221 % } 
222 % if ( $svc_acct->popnum ) {
223 %    my $svc_acct_pop = qsearchs('svc_acct_pop',{'popnum'=>$svc_acct->popnum});
224 %
225
226   <TR>
227     <TD ALIGN="right">Access number</TD>
228     <TD BGCOLOR="#ffffff"><% $svc_acct_pop->text %></TD>
229   </TR>
230 % } 
231 % if ($svc_acct->uid ne '') { 
232
233   <TR>
234     <TD ALIGN="right">UID</TD>
235     <TD BGCOLOR="#ffffff"><% $svc_acct->uid %></TD>
236   </TR>
237 % } 
238 % if ($svc_acct->gid ne '') { 
239
240   <TR>
241     <TD ALIGN="right">GID</TD>
242     <TD BGCOLOR="#ffffff"><% $svc_acct->gid %></TD>
243   </TR>
244 % } 
245 % if ($svc_acct->finger ne '') { 
246
247   <TR>
248     <TD ALIGN="right">GECOS</TD>
249     <TD BGCOLOR="#ffffff"><% $svc_acct->finger %></TD>
250   </TR>
251 % } 
252 % if ($svc_acct->dir ne '') { 
253
254   <TR>
255     <TD ALIGN="right">Home directory</TD>
256     <TD BGCOLOR="#ffffff"><% $svc_acct->dir %></TD>
257   </TR>
258 % } 
259 % if ($svc_acct->shell ne '') { 
260
261   <TR>
262     <TD ALIGN="right">Shell</TD>
263     <TD BGCOLOR="#ffffff"><% $svc_acct->shell %></TD>
264   </TR>
265 % } 
266 % if ($svc_acct->quota ne '') { 
267
268   <TR>
269     <TD ALIGN="right">Quota</TD>
270     <TD BGCOLOR="#ffffff"><% $svc_acct->quota %></TD>
271   </TR>
272 % } 
273 % if ($svc_acct->slipip) { 
274
275   <TR>
276     <TD ALIGN="right">IP address</TD>
277     <TD BGCOLOR="#ffffff">
278       <% ( $svc_acct->slipip eq "0.0.0.0" || $svc_acct->slipip eq '0e0' )
279             ? "<I>(Dynamic)</I>"
280             : $svc_acct->slipip
281       %>
282     </TD>
283   </TR>
284 % } 
285 % my %ulabel = ( seconds    => 'Seconds',
286 %                upbytes    => 'Upload bytes',
287 %                downbytes  => 'Download bytes',
288 %                totalbytes => 'Total bytes',
289 %              );
290 % foreach my $uf ( keys %ulabel ) {
291 %   my $tf = $uf . "_threshold";
292 %   if ( $svc_acct->$tf ne '' ) {
293     <TR>
294       <TD ALIGN="right"><% $ulabel{$uf} %> remaining</TD>
295       <TD BGCOLOR="#ffffff"><% $svc_acct->$uf %></TD>
296     </TR>
297
298 %   }
299 % }
300 % foreach my $attribute ( grep /^radius_/, $svc_acct->fields ) {
301 %  $attribute =~ /^radius_(.*)$/;
302 %  my $pattribute = $FS::raddb::attrib{$1};
303 %
304
305   <TR>
306     <TD ALIGN="right">Radius (reply) <% $pattribute %></TD>
307     <TD BGCOLOR="#ffffff"><% $svc_acct->getfield($attribute) %></TD>
308   </TR>
309 % } 
310 % foreach my $attribute ( grep /^rc_/, $svc_acct->fields ) {
311 %  $attribute =~ /^rc_(.*)$/;
312 %  my $pattribute = $FS::raddb::attrib{$1};
313 %
314
315   <TR>
316     <TD ALIGN="right">Radius (check) <% $pattribute %></TD>
317     <TD BGCOLOR="#ffffff"><% $svc_acct->getfield($attribute) %></TD>
318   </TR>
319 % } 
320
321
322 <TR>
323   <TD ALIGN="right">RADIUS groups</TD>
324   <TD BGCOLOR="#ffffff"><% join('<BR>', $svc_acct->radius_groups) %></TD>
325 </TR>
326 % if ( $svc_acct->seconds =~ /^\d+$/ ) { 
327
328   <TR>
329     <TD ALIGN="right">Prepaid time</TD>
330     <TD BGCOLOR="#ffffff"><% duration_exact($svc_acct->seconds) %></TD>
331   </TR>
332 % } 
333 %
334 %# Can this be abstracted further?  Maybe a library function like
335 %# widget('HTML', 'view', $svc_acct) ?  It would definitely make UI 
336 %# style management easier.
337 %
338 % foreach (sort { $a cmp $b } $svc_acct->virtual_fields) { 
339
340   <% $svc_acct->pvf($_)->widget('HTML', 'view', $svc_acct->getfield($_)) %>
341 % } 
342
343
344 </TABLE></TD></TR></TABLE>
345 </FORM>
346 <BR><BR>
347
348 <% join("<BR>", $conf->config('svc_acct-notes') ) %>
349 <BR><BR>
350
351 <% joblisting({'svcnum'=>$svcnum}, 1) %>
352
353 </BODY>
354 </HTML>