merging RT 4.0.6
[freeside.git] / httemplate / view / cust_main / packages / status.html
1 <TD CLASS="inv" BGCOLOR="<% $bgcolor %>">
2   <TABLE CLASS="inv" BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%">
3
4 %#this should use cust_pkg->status and cust_pkg->statuscolor eventually
5
6 % if ( $cust_pkg->order_date ) {
7     <% pkg_status_row($cust_pkg, emt('Ordered'), 'order_date', %opt ) %>
8 % }
9
10 % if ( $cust_pkg->get('cancel') ) { #status: cancelled
11 %   my $cpr = $cust_pkg->last_cust_pkg_reason('cancel');
12
13     <% pkg_status_row($cust_pkg, emt('Cancelled'), 'cancel', 'color'=>'FF0000', %opt ) %>
14
15     <% pkg_status_row_colspan( $cust_pkg,
16          ( $cpr ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '',
17          'align'=>'right', 'color'=>'ff0000', 'size'=>'-2', 'colspan'=>$colspan,
18          %opt
19        )
20     %>
21
22 %   unless ( $cust_pkg->get('setup') ) { 
23
24         <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', 'colspan'=>$colspan, %opt, ) %>
25
26 %   } else { 
27
28        <% pkg_status_row( $cust_pkg, emt('Setup'), 'setup', %opt ) %>
29        <% pkg_status_row_changed( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
30        <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %>
31        <% pkg_status_row_if( $cust_pkg, emt('Suspended'), 'susp', %opt, curuser=>$curuser ) %>
32
33 %   } 
34 %
35 %   if ( $part_pkg->freq ) { #?
36
37       <TR>
38         <TD COLSPAN=<%$colspan%>>
39           <FONT SIZE=-1>
40 %           if ( $curuser->access_right('Un-cancel customer package') ) { 
41               (&nbsp;<% pkg_uncancel_link($cust_pkg) %>&nbsp;)
42 %           } 
43           <FONT>
44         </TD>
45       </TR>
46 %   }
47 %
48 % } else {
49 %
50 %   if ( $cust_pkg->get('susp') ) { #status: suspended
51 %     my $cpr = $cust_pkg->last_cust_pkg_reason('susp');
52
53     <% pkg_status_row( $cust_pkg, emt('Suspended'), 'susp', 'color'=>'FF9900', %opt ) %>
54
55     <% pkg_status_row_colspan( $cust_pkg,
56          ( $cpr ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '',
57          'align'=>'right', 'color'=>'FF9900', 'size'=>'-2', 'colspan'=>$colspan,
58          %opt,
59        )
60     %>
61
62     <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
63
64     <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
65
66 %   unless ( $cust_pkg->get('setup') ) { 
67       <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', 'colspan'=>$colspan, %opt ) %>
68 %   } else { 
69       <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %>
70 %   } 
71
72     <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
73
74     <% pkg_status_row_changed( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
75     <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %>
76 %   if ( $part_pkg->option('suspend_bill', 1) ) {
77       <% pkg_status_row_if( $cust_pkg, emt('Next bill'), 'bill', %opt, curuser=>$curuser ) %>
78 %   }
79     <% pkg_status_row_if( $cust_pkg, emt('Will resume'), 'resume', %opt, curuser=>$curuser ) %>
80     <% pkg_status_row_if( $cust_pkg, emt('Expires'), 'expire', %opt, curuser=>$curuser ) %>
81     <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
82
83     <TR>
84       <TD COLSPAN=<%$colspan%>>
85         <FONT SIZE=-1>
86 %         if ( $curuser->access_right('Unsuspend customer package') ) { 
87             (&nbsp;<% pkg_unsuspend_link($cust_pkg) %>&nbsp;)
88             (&nbsp;<% pkg_resume_link($cust_pkg) %>&nbsp;)
89 %         }
90 %         if ( $curuser->access_right('Cancel customer package immediately') ) {
91             (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
92 %         } 
93         </FONT>
94       </TD>
95     </TR>
96
97 %   } else { #status: active
98 %
99 %     unless ( $cust_pkg->get('setup') ) { #not setup
100 %
101 %       unless ( $part_pkg->freq ) {
102
103           <% pkg_status_row_colspan( $cust_pkg, emt('Not yet billed (one-time charge)'), '', 'colspan'=>$colspan, %opt ) %>
104
105           <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
106
107           <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
108
109           <% pkg_status_row_if(
110                $cust_pkg,
111                ( $part_pkg->freq ? emt('Start billing') : emt('Bill on') ),
112                'start_date',
113                %opt
114              )
115           %>
116
117           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
118
119           <TR>
120             <TD COLSPAN=<%$colspan%>>
121               <FONT SIZE=-1>
122 %               if ( $curuser->access_right('Cancel customer package immediately') ) { 
123                   (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
124 %               } 
125               </FONT>
126             </TD>
127           </TR>
128
129 %       } else { 
130
131           <% pkg_status_row_colspan($cust_pkg, emt("Not yet billed ($billed_or_prepaid [_1])", myfreq($part_pkg) ), '', 'colspan'=>$colspan, %opt ) %>
132
133           <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
134
135           <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
136
137           <% pkg_status_row_if($cust_pkg, emt('Start billing'), 'start_date', %opt) %>
138           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
139
140 %       } 
141 %
142 %     } else { #setup
143 %
144 %       unless ( $part_pkg->freq ) { 
145
146           <% pkg_status_row_colspan($cust_pkg, emt('One-time charge'), '', 'colspan'=>$colspan, %opt ) %>
147
148           <% pkg_status_row($cust_pkg, emt('Billed'), 'setup', %opt) %>
149
150           <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
151
152           <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
153
154           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
155
156 %       } else { 
157 %
158 %         my $num_cust_svc = $cust_pkg->num_cust_svc;
159 %         my $summarize = $opt{'cust_pkg-large_pkg_size'} > 0
160 %                           && $opt{'cust_pkg-large_pkg_size'} <= $num_cust_svc;
161 %
162 %         #overlimit process is expensive with many services, so skip w/summary
163 %         if ( !$summarize && scalar($cust_pkg->overlimit) ) {
164
165             <% pkg_status_row_colspan( $cust_pkg,
166                  emt('Overlimit'),
167                  $billed_or_prepaid. '&nbsp;'. myfreq($part_pkg),
168                  'color'=>'FFD000', 'colspan'=>$colspan,
169                  %opt
170                )
171             %>
172
173 %         } else {
174             <% pkg_status_row_colspan( $cust_pkg,
175                  emt('Active'),
176                  $billed_or_prepaid. '&nbsp;'. myfreq($part_pkg),
177                  'color'=>'00CC00', 'colspan'=>$colspan,
178                  %opt
179                )
180             %>
181 %         } 
182
183           <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
184
185           <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
186
187           <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt) %>
188
189           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
190
191 %       } 
192 %
193 %     } 
194 %
195 %     if ( $opt{'cust_pkg-show_autosuspend'} ) {
196 %       my $autosuspend = pkg_autosuspend_time( $cust_pkg );
197 %       $cust_pkg->set('autosuspend', $autosuspend) if $autosuspend;
198 %     }
199
200       <% pkg_status_row_changed( $cust_pkg, %opt, 'colspan'=>$colspan ) %>
201       <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %>
202       <% pkg_status_row_if( $cust_pkg, $next_bill_or_prepaid_until, 'bill', %opt, curuser=>$curuser ) %>
203       <% pkg_status_row_if($cust_pkg, emt('Will automatically suspend by'), 'autosuspend', %opt) %>
204       <% pkg_status_row_if($cust_pkg, emt('Automatic suspension delayed until'), 'dundate', %opt) %>
205       <% pkg_status_row_if( $cust_pkg, emt('Will suspend on'), 'adjourn', %opt, curuser=>$curuser ) %>
206       <% pkg_status_row_if( $cust_pkg, emt('Will resume on'), 'resume', %opt, curuser=>$curuser ) %>
207       <% pkg_status_row_if( $cust_pkg, emt('Expires'), 'expire', %opt, curuser=>$curuser ) %>
208       <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
209
210 %     if ( $part_pkg->freq ) { 
211
212         <TR>
213           <TD COLSPAN=<%$colspan%>>
214             <FONT SIZE=-1>
215 %             if ( $curuser->access_right('Suspend customer package') ) { 
216                 (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
217 %             } 
218 %             if ( $curuser->access_right('Suspend customer package later') ) { 
219                 (&nbsp;<% pkg_adjourn_link($cust_pkg) %>&nbsp;)
220 %             } 
221 %             if ( $curuser->access_right('Delay suspension events') ) { 
222                 (&nbsp;<% pkg_delay_link($cust_pkg) %>&nbsp;)
223 %             } 
224 %             if ( $curuser->access_right('Cancel customer package immediately') ) { 
225                 (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
226 %             } 
227 %             if ( $curuser->access_right('Cancel customer package later') ) { 
228                 (&nbsp;<% pkg_expire_link($cust_pkg) %>&nbsp;)
229 %             } 
230
231             <FONT>
232           </TD>
233         </TR>
234 %     }
235 %
236 %   } 
237 % } 
238
239   </TABLE>
240 </TD>
241 <%init>
242
243 my %opt = @_;
244
245 my $bgcolor  = $opt{'bgcolor'};
246 my $cust_pkg = $opt{'cust_pkg'};
247 my $part_pkg = $opt{'part_pkg'};
248 my $curuser  = $FS::CurrentUser::CurrentUser;
249 my $colspan  = $opt{'cust_pkg-display_times'} ? 8 : 4;
250 my $width    = $opt{'cust_pkg-display_times'} ? '38%' : '56%';
251
252 #false laziness w/edit/REAL_cust_pkg.cgi
253 my( $billed_or_prepaid, $last_bill_or_renewed, $next_bill_or_prepaid_until );
254 unless ( $part_pkg->is_prepaid ) {
255   $billed_or_prepaid = 'billed';
256   $last_bill_or_renewed = 'Last&nbsp;bill';
257   $next_bill_or_prepaid_until = 'Next&nbsp;bill';
258 } else {
259   $billed_or_prepaid = 'prepaid';
260   $last_bill_or_renewed = 'Renewed';
261   $next_bill_or_prepaid_until = 'Prepaid&nbsp;until';
262 }
263
264 #subroutines
265
266 sub myfreq {
267   my $part_pkg = shift;
268   my $freq = $part_pkg->freq_pretty;
269   #$freq =~ s/ /&nbsp;/g;
270   $freq;
271 }
272
273 #false laziness w/package.html
274 sub pkg_link {
275   my($action, $label, $cust_pkg) = @_;
276   return '' unless $cust_pkg;
277   qq!<a href="$p$action.cgi?!. $cust_pkg->pkgnum. qq!">$label</a>!;
278 }
279
280 sub pkg_status_row {
281   my( $cust_pkg, $title, $field, %opt ) = @_;
282
283   my $color = $opt{'color'};
284
285   my $html = qq(<TR><TD WIDTH="<%$width%>" ALIGN="right">);
286   $html   .= qq(<FONT COLOR="#$color"><B>) if length($color);
287   $html   .= qq($title&nbsp;);
288   $html   .= qq(</B></FONT>) if length($color);
289
290   if ( $opt{'pkg_balances'} && ! $cust_pkg->{_printed_balance}++ ) { #kludge
291     $html .= ' (Balance:&nbsp;<B>'. $opt{'money_char'}.
292              $cust_pkg->cust_main->balance_pkgnum($cust_pkg->pkgnum).
293              '</B>)';
294   }
295
296   $html   .= qq(</TD>);
297   $html   .= pkg_datestr($cust_pkg, $field, %opt). '</TR>';
298
299   $html;
300 }
301
302 sub pkg_status_row_if {
303   my( $cust_pkg, $title, $field, %opt ) = @_;
304   
305   $title = '<FONT SIZE=-1>(&nbsp;'. pkg_unadjourn_link($cust_pkg). '&nbsp;)&nbsp;</FONT>'. $title
306     if ( $field eq 'adjourn' &&
307          $opt{curuser}->access_right('Suspend customer package later')
308        );
309
310   $title = '<FONT SIZE=-1>(&nbsp;'. pkg_unexpire_link($cust_pkg). '&nbsp;)&nbsp;</FONT>'. $title
311     if ( $field eq 'expire' &&
312          $opt{curuser}->access_right('Cancel customer package later')
313        );
314
315   $cust_pkg->get($field) ? pkg_status_row($cust_pkg, $title, $field, %opt) : '';
316 }
317
318 sub pkg_status_row_changed {
319   my( $cust_pkg, %opt ) = @_;
320
321   return '' unless $cust_pkg->change_date;
322
323   my $html =
324     pkg_status_row( $cust_pkg, emt('Package changed'), 'change_date', %opt );
325
326   my $old = $cust_pkg->old_cust_pkg;
327   if ( $old ) {
328     my $part_pkg = $old->part_pkg;
329     $html .= pkg_status_row_colspan( $cust_pkg, 
330                                      emt("Changed from [_1]: [_2]",
331                                             $cust_pkg->change_pkgnum,
332                                             $part_pkg->pkg_comment(nopartpkg => 1) ),
333                                      '',
334                                      'size'    => '-1',
335                                      'align'   => 'right',
336                                      'colspan' => $opt{'colspan'},
337                                    );
338   }
339
340   $html;
341 }
342
343 sub pkg_status_row_noauto {
344   my( $cust_pkg, %opt ) = @_;
345   my $part_pkg = $opt{'part_pkg'};
346   return '' unless $cust_pkg->no_auto || $part_pkg->no_auto;
347
348   #inefficient, should be passed in
349   my $cust_main = $cust_pkg->cust_main;
350
351   return '' unless $cust_main->payby =~ /^(CARD|CHEK)$/;
352   my $what = lc(FS::payby->shortname($cust_main->payby));
353
354   pkg_status_row_colspan( $cust_pkg, emt("No automatic $what charge"), '',
355                           'colspan' => $opt{'colspan'},
356                         );
357 }
358
359 sub pkg_status_row_discount {
360   my( $cust_pkg, %opt ) = @_;
361
362   my $html;
363
364   foreach my $cust_pkg_discount ( $cust_pkg->cust_pkg_discount_active ) {
365
366     my $discount = $cust_pkg_discount->discount;
367
368     my $label = '<B>'.emt('Discount').'</B>: '. $discount->description;
369     if ( $discount->months ) {
370       my $remaining = $discount->months - $cust_pkg_discount->months_used;
371       $remaining = sprintf('%.2f', $remaining) if $remaining =~ /\./;
372       $label .= emt("([_1] months remaining)",$remaining);
373     }
374
375     $label .= ' <FONT SIZE="-1">('.
376                 '<A HREF="../misc/delete-cust_pkg_discount.html?'.
377                   $cust_pkg_discount->pkgdiscountnum.
378                 '">'.emt('remove discount').'</A>)</FONT>';
379
380     $html .= pkg_status_row_colspan( $cust_pkg, $label, '',
381                                      'colspan' => $opt{'colspan'},
382                                    );
383
384   }
385
386   $html;
387 }
388
389 sub pkg_status_row_colspan {
390   my($cust_pkg, $title, $addl, %opt) = @_;
391
392   my $colspan  = $opt{'colspan'};
393
394   my $align = $opt{'align'} ? 'ALIGN="'. $opt{'align'}.'"' : '';
395   my $color = $opt{'color'} ? 'COLOR="#'.$opt{'color'}.'"' : '';
396   my $size  = $opt{'size'}  ? 'SIZE="'.  $opt{'size'}. '"' : '';
397
398   my $html = qq(<TR><TD COLSPAN=$colspan $align>);
399   $html   .= qq(<FONT $color $size>) if length($color) || $size;
400   $html   .= qq(<B>) if $color && !$size;
401   $html   .= $title;
402   $html   .= qq(</B>) if $color && !$size;
403   $html   .= qq(</FONT>) if length($color) || $size;
404   $html   .= ",&nbsp;$addl" if length($addl);
405
406   if ( $opt{'pkg-balances'} && ! $cust_pkg->{_printed_balance}++ ) { #kludge
407     $html .= ' (Balance:&nbsp;<B>'. $opt{'money_char'}.
408              $cust_pkg->cust_main->balance_pkgnum($cust_pkg->pkgnum).
409              '</B>)';
410   }
411
412   $html   .= qq(</TD></TR>);
413
414   $html;
415
416 }
417
418 sub pkg_datestr {
419   my($cust_pkg, $field, %opt) = @_ or return '';
420   return '&nbsp;' unless $cust_pkg->get($field);
421   my $format = '<TD align="left"><B>%b</B></TD>'.
422                '<TD align="right"><B>&nbsp;%o,</B></TD>'.
423                '<TD align="right"><B>&nbsp;%Y</B></TD>';
424   #$format .= '&nbsp;<FONT SIZE=-3>%l:%M:%S%P&nbsp;%z</FONT>'
425   $format .= '<TD ALIGN="right"><B>&nbsp;%l</TD>'.
426              '<TD ALIGN="center"><B>:</B></TD>'.
427              '<TD ALIGN="left"><B>%M</B></TD>'.
428              '<TD ALIGN="left"><B>&nbsp;%P</B></TD>'
429     if $opt{'cust_pkg-display_times'};
430   my $strip = time2str($format, $cust_pkg->get($field) );
431   $strip =~ s/ (\d)/$1/g;
432   $strip;
433 }
434
435 sub pkg_suspend_link {
436   include( '/elements/popup_link-cust_pkg.html',
437              'action'      => $p. 'misc/cancel_pkg.html?method=suspend',
438              'label'       => emt('Suspend now'),
439              'actionlabel' => emt('Suspend'),
440              'color'       => '#FF9900',
441              'cust_pkg'    => shift,
442          )
443 }
444
445 sub pkg_adjourn_link {
446   include( '/elements/popup_link-cust_pkg.html',
447              'action'      => $p. 'misc/cancel_pkg.html?method=adjourn',
448              'label'       => emt('Suspend later'),
449              'actionlabel' => emt('Adjourn'),
450              'color'       => '#CC6600',
451              'cust_pkg'    => shift,
452          )
453 }
454
455 sub pkg_delay_link  {
456   my($cust_pkg) = shift;
457   include( '/elements/popup_link-cust_pkg.html',
458              'action'      => $p. 'misc/delay_susp_pkg.html',
459              'label'       => ( $cust_pkg->dundate
460                                   ? emt('Edit suspension delay')
461                                   : emt('Delay suspend')
462                               ),
463              'actionlabel' => emt('Delay suspend for'),
464              'cust_pkg'    => $cust_pkg,
465          )
466 }
467
468 sub pkg_resume_link {
469   include( '/elements/popup_link-cust_pkg.html',
470              'action'      => $p. 'misc/cancel_pkg.html?method=resume',
471              'label'       => emt('Unsuspend later'),
472              'actionlabel' => emt('Resume'),
473              'color'       => '#00CC00',
474              'cust_pkg'    => shift,
475          )
476 }
477
478 sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg',    emt('Unsuspend now'), @_ ); }
479 sub pkg_unadjourn_link { pkg_link('misc/unadjourn_pkg', emt('Abort'),     @_ ); }
480 sub pkg_unexpire_link  { pkg_link('misc/unexpire_pkg',  emt('Abort'),     @_ ); }
481
482 sub pkg_cancel_link {
483   include( '/elements/popup_link-cust_pkg.html',
484              'action'      => $p. 'misc/cancel_pkg.html?method=cancel',
485              'label'       => emt('Cancel now'),
486              'actionlabel' => emt('Cancel'),
487              'color'       => '#ff0000',
488              'cust_pkg'    => shift,
489          )
490 }
491
492 sub pkg_uncancel_link {
493   include( '/elements/popup_link-cust_pkg.html',
494              'action'      => $p. 'misc/cancel_pkg.html?method=uncancel',
495              'label'       => emt('Un-cancel'),
496              'actionlabel' => emt('Un-cancel'),
497              #'color'       =>  #?
498              'cust_pkg'    => shift,
499          )
500 }
501
502 sub pkg_expire_link {
503   include( '/elements/popup_link-cust_pkg.html',
504              'action'      => $p. 'misc/cancel_pkg.html?method=expire',
505              'label'       => emt('Cancel later'),
506              'actionlabel' => emt('Expire'),
507              'color'       => '#CC0000',
508              'cust_pkg'    => shift,
509          )
510 }
511
512 sub svc_recharge_link {
513   include( '/elements/popup_link-cust_svc.html',
514              'action'      => $p. 'misc/recharge_svc.html',
515              'label'       => emt('Recharge'),
516              'actionlabel' => emt('Recharge'),
517              'color'       => '#333399',
518              'cust_svc'    => shift,
519          )
520 }
521
522 sub pkg_autosuspend_time {
523   my $cust_pkg = shift or return '';
524   my $days = 7;
525   my $time = time;
526   my $pending_suspend = 0;
527   #this seems to be extremely inefficient...  and is slowing down all customer
528   #views
529   while ( $days > 0 &&
530           scalar(
531             grep { $_->part_event->action eq 'suspend' }
532             @{$cust_pkg->cust_main->due_cust_event( time => $time + 86400*$days,
533                                                     testonly => 1,
534                                                   ) }
535           )
536         )
537   {
538     $pending_suspend = 1;
539     $days--;
540   }
541
542   $pending_suspend ? time + ($days + 1) * 86400 : '';
543
544 }
545
546 </%init>