service refactor!
[freeside.git] / httemplate / view / cust_main / packages.html
1 %  my( $cust_main ) = @_;
2 %  my $conf = new FS::Conf;
3 %
4 %  my $curuser = $FS::CurrentUser::CurrentUser;
5 %
6 %  my $packages = get_packages($cust_main, $conf);
7
8
9 <A NAME="cust_pkg"><FONT SIZE="+2">Packages</FONT></A>
10 % if ( $curuser->access_right('Order customer package') ) { 
11
12   <% include('order_pkg.html', $cust_main ) %>
13 % } 
14 % if ( $curuser->access_right('One-time charge')
15 %        && $conf->config('payby-default') ne 'HIDE'
16 %      ) {
17 %
18
19   <% include('quick-charge.html', $cust_main ) %>
20 % } 
21 % if ( $curuser->access_right('Bulk change customer packages') ) { 
22
23   <A HREF="<% $p %>edit/cust_pkg.cgi?<% $cust_main->custnum %>">Bulk order and cancel packages</A> (preserves services)
24 % } 
25
26
27 <BR><BR>
28 % if ( @$packages ) { 
29
30 Current packages
31 % } 
32 % if ( $cust_main->num_cancelled_pkgs ) {
33 %     if ( $cgi->param('showcancelledpackages') eq '0' #see if it was set by me
34 %          || ( $conf->exists('hidecancelledpackages')
35 %               && ! $cgi->param('showcancelledpackages')
36 %             )
37 %        )
38 %     {
39 %       $cgi->param('showcancelledpackages', 1);
40 %
41
42   ( <a href="<% $cgi->self_url %>">show
43 %   } else {
44 %       $cgi->param('showcancelledpackages', 0);
45 %
46
47   ( <a href="<% $cgi->self_url %>">hide
48 %   } 
49
50  cancelled packages</a> )
51 % } 
52 % if ( @$packages ) { 
53
54
55 <% include('/elements/table-grid.html') %>
56 % my $bgcolor1 = '#eeeeee';
57 %   my $bgcolor2 = '#ffffff';
58 %   my $bgcolor = '';
59
60 <TR>
61   <TH CLASS="grid" BGCOLOR="#cccccc">Package</TH>
62   <TH CLASS="grid" BGCOLOR="#cccccc">Status</TH>
63   <TH CLASS="grid" BGCOLOR="#cccccc">Services</TH>
64 </TR>
65
66 %foreach my $cust_pkg (@$packages) {
67 %
68 %  my $part_pkg = $cust_pkg->part_pkg;
69 %
70 %  if ( $bgcolor eq $bgcolor1 ) {
71 %    $bgcolor = $bgcolor2;
72 %  } else {
73 %    $bgcolor = $bgcolor1;
74 %  }
75
76
77 <!--pkgnum: <% $cust_pkg->pkgnum %>-->
78 <TR>
79   <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
80     <A NAME="cust_pkg<% $cust_pkg->pkgnum %>"><% $cust_pkg->pkgnum %></A>:
81     <% $part_pkg->pkg %> - <% $part_pkg->comment %><BR>
82     <FONT SIZE=-1>
83 % unless ( $cust_pkg->get('cancel') ) { 
84 % if ( $curuser->access_right('Change customer package') ) { 
85
86             (&nbsp;<%pkg_change_link($cust_pkg)%>&nbsp;)
87 % } 
88 % if ( $curuser->access_right('Edit customer package dates') ) { 
89
90             (&nbsp;<%pkg_dates_link($cust_pkg)%>&nbsp;)
91 % } 
92 % if ( $curuser->access_right('Customize customer package') ) { 
93
94             (&nbsp;<%pkg_customize_link($cust_pkg,$cust_main->custnum)%>&nbsp;)
95 % } 
96 % } 
97
98     </FONT>
99   </TD>
100   <TD CLASS="inv" BGCOLOR="<% $bgcolor %>">
101     <TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">
102 %
103 %  sub myfreq {
104 %    my $part_pkg = shift;
105 %    my $freq = $part_pkg->freq_pretty;
106 %    $freq =~ s/ /&nbsp;/g;
107 %    $freq;
108 %  }
109 %
110 %  #this should use cust_pkg->status and cust_pkg->statuscolor eventually
111 %
112 %  my $colspan = $conf->exists('cust_pkg-display_times') ? 8 : 4;
113 %  my $width = $conf->exists('cust_pkg-display_times') ? '38%' : '56%';
114 %
115 %  #false laziness w/edit/REAL_cust_pkg.cgi
116 %  my( $billed_or_prepaid, $last_bill_or_renewed, $next_bill_or_prepaid_until );
117 %  unless ( $part_pkg->is_prepaid ) {
118 %    $billed_or_prepaid = 'billed';
119 %    $last_bill_or_renewed = 'Last&nbsp;bill';
120 %    $next_bill_or_prepaid_until = 'Next&nbsp;bill';
121 %  } else {
122 %    $billed_or_prepaid = 'prepaid';
123 %    $last_bill_or_renewed = 'Renewed';
124 %    $next_bill_or_prepaid_until = 'Prepaid&nbsp;until';
125 %  }
126 %
127 %
128 % if ( $cust_pkg->get('cancel') ) { 
129  <!-- #status: cancelled -->
130
131   <TR>
132     <TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#ff0000"><B>Cancelled&nbsp;</B></FONT></TD>
133     <% pkg_datestr($cust_pkg, 'cancel', $conf) %>
134   </TR>
135   <TR>
136     <TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#ff0000" SIZE="-2">
137       <% $cust_pkg->last_reason ? $cust_pkg->last_reason->reason : '' %>
138     </FONT></TD>
139   </TR>
140 % unless ( $cust_pkg->get('setup') ) { 
141
142
143     <TR>
144       <TD COLSPAN=<%$colspan%>>Never billed</TD>
145     </TR>
146 % } else { 
147
148
149     <TR>
150       <TD WIDTH="<%$width%>" ALIGN="right">Setup&nbsp;</TD>
151       <% pkg_datestr($cust_pkg, 'setup', $conf) %>
152     </TR>
153 % if ( $cust_pkg->get('last_bill') ) { 
154
155       <TR>
156         <TD WIDTH="<%$width%>" ALIGN="right"><% $last_bill_or_renewed %>&nbsp;</TD>
157         <% pkg_datestr($cust_pkg, 'last_bill',$conf) %>
158       </TR>
159 % } 
160 % if ( $cust_pkg->get('susp') ) { 
161
162       <TR>
163         <TD WIDTH="<%$width%>" ALIGN="right">Suspended&nbsp;</TD>
164         <% pkg_datestr($cust_pkg, 'susp', $conf) %>
165       </TR>
166 % } 
167 % } 
168 % } else { 
169 % if ( $cust_pkg->get('susp') ) { 
170  <!-- #status: suspended -->
171
172     <TR>
173       <TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#FF9900"><B>Suspended</B>&nbsp;</FONT></TD>
174       <% pkg_datestr($cust_pkg, 'susp', $conf) %>
175     </TR>
176     <TR>
177       <TD WIDTH="<%$width%>" ALIGN="right"><FONT COLOR="#FF9900" SIZE="-2">
178         <% $cust_pkg->last_reason ? $cust_pkg->last_reason->reason : '' %>
179       </FONT></TD>
180     </TR>
181 % unless ( $cust_pkg->get('setup') ) { 
182
183
184       <TR>
185         <TD COLSPAN=<%$colspan%>>Never billed</TD>
186       </TR>
187 % } else { 
188
189
190       <TR>
191         <TD WIDTH="<%$width%>" ALIGN="right">Setup&nbsp;</TD>
192         <% pkg_datestr($cust_pkg, 'setup', $conf) %>
193       </TR>
194 % } 
195 % if ( $cust_pkg->get('last_bill') ) { 
196
197       <TR>
198         <TD WIDTH="<%$width%>" ALIGN="right"><% $last_bill_or_renewed %>&nbsp;</TD>
199         <% pkg_datestr($cust_pkg, 'last_bill', $conf) %>
200       </TR>
201 % } 
202
203
204     <!-- # next bill ?? -->
205 % if ( $cust_pkg->get('expire') ) { 
206
207       <TR>
208         <TD WIDTH="<%$width%>" ALIGN="right">Expires&nbsp;</TD>
209         <% pkg_datestr($cust_pkg, 'expire', $conf) %>
210       </TR>
211 % } 
212
213
214     <TR>
215       <TD COLSPAN=<%$colspan%>>
216         <FONT SIZE=-1>
217 % if ( $curuser->access_right('Unsuspend customer package') ) { 
218
219             (&nbsp;<% pkg_unsuspend_link($cust_pkg) %>&nbsp;)
220 % } 
221 % if ( $curuser->access_right('Cancel customer package') ) { 
222
223             (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
224 % } 
225
226         </FONT>
227       </TD>
228     </TR>
229 % } else { 
230  <!-- #status: active -->
231 % unless ( $cust_pkg->get('setup') ) { 
232  <!-- #not setup -->
233 % unless ( $part_pkg->freq ) { 
234
235
236         <TR>
237           <TD COLSPAN=<%$colspan%>>Not&nbsp;yet&nbsp;billed&nbsp;(one-time&nbsp;charge)</TD>
238         </TR>
239
240         <TR>
241           <TD COLSPAN=<%$colspan%>>
242             <FONT SIZE=-1>
243 % if ( $curuser->access_right('Cancel customer package immediately') ) { 
244
245                 (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
246 % } 
247
248             </FONT>
249           </TD>
250         </TR>
251 % } else { 
252
253
254         <TR>
255           <TD COLSPAN=<%$colspan%>>Not&nbsp;yet&nbsp;billed&nbsp;(<% $billed_or_prepaid %>&nbsp;<% myfreq($part_pkg) %>)</TD>
256         </TR>
257 % } 
258 % } else { 
259  <!-- #setup -->
260 % unless ( $part_pkg->freq ) { 
261
262
263         <TR>
264           <TD COLSPAN=<%$colspan%>>One-time&nbsp;charge</TD>
265         </TR>
266
267         <TR>
268           <TD WIDTH="<%$width%>" ALIGN="right">Billed&nbsp;</TD>
269           <% pkg_datestr($cust_pkg, 'setup', $conf) %>
270         </TR>
271 % } else { 
272
273
274         <TR>
275           <TD COLSPAN=<%$colspan%>><FONT COLOR="#00CC00"><B>Active</B></FONT>,&nbsp;<% $billed_or_prepaid %>&nbsp;<% myfreq($part_pkg) %></TD>
276         </TR>
277
278         <TR>
279           <TD WIDTH="<%$width%>" ALIGN="right">Setup&nbsp;</TD>
280           <% pkg_datestr($cust_pkg, 'setup', $conf) %>
281         </TR>
282 % } 
283 % } 
284 % if ( $cust_pkg->get('last_bill') ) { 
285
286       <TR>
287         <TD WIDTH="<%$width%>" ALIGN="right"><% $last_bill_or_renewed %>&nbsp;</TD>
288         <% pkg_datestr($cust_pkg, 'last_bill', $conf) %>
289       </TR>
290 % } 
291 % if ( $cust_pkg->get('bill') ) { #next bill
292
293       <TR>
294         <TD WIDTH="<%$width%>" ALIGN="right"><% $next_bill_or_prepaid_until %>&nbsp;</TD>
295         <% pkg_datestr($cust_pkg, 'bill', $conf) %>
296       </TR>
297 % } 
298 % if ( $cust_pkg->get('expire') ) { 
299
300       <TR>
301         <TD WIDTH="<%$width%>" ALIGN="right">Expires&nbsp;</TD>
302         <% pkg_datestr($cust_pkg, 'expire', $conf) %>
303       </TR>
304 % } 
305 % if ( $part_pkg->freq ) { 
306
307       <TR>
308         <TD COLSPAN=<%$colspan%>>
309           <FONT SIZE=-1>
310 % if ( $curuser->access_right('Suspend customer package') ) { 
311
312               (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
313 % } 
314 % if ( $curuser->access_right('Cancel customer package immediately') ) { 
315
316               (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
317 % } 
318 % if ( $curuser->access_right('Cancel customer package later') ) { 
319
320               (&nbsp;<% pkg_expire_link($cust_pkg) %>&nbsp;)
321 % } 
322
323           <FONT>
324         </TD>
325       </TR>
326 % } 
327 % } 
328 % } 
329
330
331 </TABLE>
332 </TD>
333
334 <TD CLASS="inv" BGCOLOR="<% $bgcolor %>">
335   <TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">
336
337 %  #foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) {
338 %  foreach my $part_svc ( $cust_pkg->part_svc ) {
339
340 %    #foreach my $service (@{$svcpart->{services}}) {
341 %    foreach my $cust_svc ( @{ $part_svc->cust_pkg_svc } ) {
342
343       <TR>
344         <TD ALIGN="right" VALIGN="top"><% FS::UI::Web::svc_link($m, $part_svc, $cust_svc) %></TD>
345         <TD STYLE="padding-bottom:0px"><B><% FS::UI::Web::svc_label_link($m, $part_svc, $cust_svc) %></B></TD>
346       </TR>
347
348       <TR>
349         <TD ALIGN="right" VALIGN="top" STYLE="padding-bottom:5px;padding-top:0px"><FONT SIZE="-2">
350
351 %         if ( $curuser->access_right('Recharge customer service')
352 %              && $cust_svc->svcdb eq 'svc_acct'
353 %              && (    $cust_svc->svc_x->seconds    ne ''
354 %                   || $cust_svc->svc_x->upbytes    ne ''
355 %                   || $cust_svc->svc_x->downbytes  ne ''
356 %                   || $cust_svc->svc_x->totalbytes ne ''
357 %                 )
358 %         ) { 
359             (&nbsp;<%svc_recharge_link($cust_svc)%>&nbsp;)
360 %         } 
361           </FONT></TD>
362
363           <TD ALIGN="right" VALIGN="top" STYLE="padding-bottom:5px;padding-top:0px"><FONT SIZE="-2">
364
365 %         if ( $curuser->access_right('Unprovision customer service') ) { 
366             (&nbsp;<%svc_unprovision_link($cust_svc)%>&nbsp;)
367 %         } 
368           </FONT></TD>
369         </TR>
370 %   } 
371
372 %   if (    ! $cust_pkg->get('cancel')
373 %        && $curuser->access_right('Provision customer service') 
374 %        && $part_svc->num_avail
375 %      ) {
376
377       <TR>
378         <TD COLSPAN=2 ALIGN="center" STYLE="padding-bottom:4px;padding-top:0px">
379           <B><% svc_provision_link($cust_pkg, $part_svc, $conf, $curuser) %></B>
380         </TD>
381       </TR>
382
383 %   } 
384
385 % } 
386
387 </TABLE>
388 </TD>
389 % } #end display packages
390 %
391
392
393 </TABLE>
394 % } else { 
395
396 <BR>
397 % } 
398 %
399 %#subroutines
400 %
401 %sub get_packages {
402 %  my $cust_main = shift or return undef;
403 %  my $conf = shift;
404 %  
405 %  my @packages = ();
406 %  my $method;
407 %  if (  $cgi->param('showcancelledpackages') eq '0' #see if it was set by me
408 %     || ( $conf->exists('hidecancelledpackages')
409 %           && ! $cgi->param('showcancelledpackages') )
410 %     )
411 %  {
412 %    $method = 'ncancelled_pkgs';
413 %  } else {
414 %    $method = 'all_pkgs';
415 %  }
416 %
417 %  [ $cust_main->$method() ];
418 %}
419 %  
420 %sub svc_provision_link {
421 %  my ($cust_pkg, $part_svc, $conf, $curuser) = @_;
422 %  ( my $svc_nbsp = $part_svc->svc ) =~ s/\s+/&nbsp;/g;
423 %  my $num_avail = $part_svc->num_avail;
424 %  my $pkgnum_svcpart = "pkgnum=". $cust_pkg->pkgnum. ';'.
425 %                       "svcpart=". $part_svc->svcpart;
426 %  my $url;
427 %  if ( $part_svc->svcdb eq 'svc_external' #could be generalized
428 %       && $conf->exists('svc_external-skip_manual')
429 %  ) {
430 %    $url = "${p}edit/process/". $part_svc->svcdb. ".cgi?$pkgnum_svcpart";
431 %  } else {
432 %    $url = FS::UI::Web::svc_url(
433 %                                 'm'        => $m,
434 %                                 'action'   => 'edit',
435 %                                 'part_svc' => $part_svc, 
436 %                                 'query'    => $pkgnum_svcpart,
437 %                               );
438 %    #$url = "${p}edit/$svcpart->{svcdb}.cgi?$pkgnum_svcpart";
439 %  }
440 %
441 %  my $link = qq!<A CLASS="provision" HREF="$url">!.
442 %             "Provision&nbsp;$svc_nbsp&nbsp;($num_avail)</A>";
443 %  if ( $conf->exists('legacy_link')
444 %       && $curuser->access_right('View/link unlinked services')
445 %     )
446 %  {
447 %    $link .= '<BR>'.
448 %             qq!<A CLASS="provision" HREF="${p}misc/link.cgi?!.
449 %             qq!$pkgnum_svcpart">!.
450 %            "Link&nbsp;to&nbsp;legacy&nbsp;$svc_nbsp&nbsp;($num_avail)</A>";
451 %  }
452 %  $link;
453 %}
454 %
455 %sub svc_unprovision_link {
456 %  my $cust_svc = shift or return '';
457 %  qq!<A HREF="javascript:areyousure('${p}misc/unprovision.cgi?!. $cust_svc->svcnum.
458 %  qq!', 'Permanently unprovision and delete this service?')">Unprovision</A>!;
459 %}
460 %
461 %sub pkg_datestr {
462 %  my($cust_pkg, $field, $conf) = @_ or return '';
463 %  return '&nbsp;' unless $cust_pkg->get($field);
464 %  my $format = '<TD align="left"><B>%b</B></TD>'.
465 %               '<TD align="right"><B>&nbsp;%o,</B></TD>'.
466 %               '<TD align="right"><B>&nbsp;%Y</B></TD>';
467 %  #$format .= '&nbsp;<FONT SIZE=-3>%l:%M:%S%P&nbsp;%z</FONT>'
468 %  $format .= '<TD ALIGN="right"><B>&nbsp;%l</TD>'.
469 %             '<TD ALIGN="center"><B>:</B></TD>'.
470 %             '<TD ALIGN="left"><B>%M</B></TD>'.
471 %             '<TD ALIGN="left"><B>&nbsp;%P</B></TD>'
472 %    if $conf->exists('cust_pkg-display_times');
473 %  my $strip = time2str($format, $cust_pkg->get($field) );
474 %  $strip =~ s/ (\d)/$1/g;
475 %  $strip;
476 %}
477 %
478 %sub pkg_change_link    { pkg_link('misc/change_pkg',    'Change&nbsp;package', @_ ); }
479 %sub pkg_suspend_link   { pkg_link('misc/susp_pkg',      'Suspend',             @_ ); }
480 %sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg',    'Unsuspend',           @_ ); }
481 %sub pkg_expire_link    { pkg_link('misc/expire_pkg',    'Cancel&nbsp;later',   @_ ); }
482 %sub pkg_dates_link     { pkg_link('edit/REAL_cust_pkg', 'Edit&nbsp;dates',     @_ ); }
483 %
484 %sub pkg_cancel_link    { pkg_popup_link( 'misc/cancel_pkg.html?method=cancel',
485 %                                         'Cancel&nbsp;now',
486 %                                         'Cancel',
487 %                                         @_
488 %                                       );
489 %                       }
490 %sub pkg_expire_link    { pkg_popup_link( 'misc/cancel_pkg.html?method=expire',
491 %                                         'Cancel&nbsp;later',
492 %                                         'Expire', #"Cancel package $num later"
493 %                                         @_
494 %                                       );
495 %                       }
496 %
497 %sub svc_recharge_link  { svc_popup_link( 'misc/recharge_svc.html',
498 %                                         'Recharge',
499 %                                         'Recharge',
500 %                                         @_
501 %                                       );
502 %                       }
503 %
504 %sub pkg_link {
505 %  my($action, $label, $cust_pkg) = @_;
506 %  return '' unless $cust_pkg;
507 %  qq!<a href="${p}misc/$action.cgi?!. $cust_pkg->pkgnum. qq!">$label</a>!;
508 %}
509 %
510 %sub pkg_popup_link {
511 %  my($action, $label, $actionlabel, $cust_pkg) = @_;
512 %  $action .= '&pkgnum='. $cust_pkg->pkgnum;
513 %  $actionlabel .= ' package '. $cust_pkg->pkgnum;
514 %  popup_link($action, $label, $actionlabel);
515 %}
516 %
517 %sub svc_popup_link {
518 %  my($action, $label, $actionlabel, $cust_svc) = @_;
519 %  $action .= '?svcnum='. $cust_svc->svcnum;
520 %  $actionlabel .= ' service '. $cust_svc->svcnum;
521 %  popup_link($action, $label, $actionlabel);
522 %}
523 %
524 %sub popup_link {
525 %  my($action, $label, $actionlabel) = @_;
526 %  qq!<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('$p$action', 392, 336, 'pkg_or_svc_action_popup' ), CAPTION, '$actionlabel', STICKY, AUTOSTATUSCAP, MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK ); return false;">$label</A>!;
527 %}
528 %
529 %sub pkg_customize_link {
530 %  my $cust_pkg = shift or return '';
531 %  my $custnum = $cust_pkg->custnum;
532 %  qq!<A HREF="${p}edit/part_pkg.cgi?!.
533 %    "keywords=$custnum;".
534 %    "clone=". $cust_pkg->part_pkg->pkgpart. ';'.
535 %    "pkgnum=". $cust_pkg->pkgnum.
536 %    qq!">Customize</A>!;
537 %}