3f629e12f6905ff652321803c175fa85f9b88359
[freeside.git] / httemplate / view / cust_main / packages / status.html
1 <TD CLASS="inv" BGCOLOR="<% $bgcolor %>" VALIGN="top">
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 ( $supplemental ) {
7     <% pkg_status_row_colspan($cust_pkg, emt('Supplemental'), '', 'color' => '7777FF', %opt) %>
8 % } elsif ( $cust_pkg->order_date ) {
9     <% pkg_status_row($cust_pkg, emt('Ordered'), 'order_date', %opt ) %>
10 % }
11
12 % if ( $cust_pkg->get('cancel') ) { #status: cancelled
13 %   my $cpr = $cust_pkg->last_cust_pkg_reason('cancel');
14
15     <% pkg_status_row($cust_pkg, emt('Cancelled'), 'cancel', 'color'=>'FF0000', %opt ) %>
16
17     <% pkg_status_row_detached($cust_pkg, %opt) %>
18
19     <% pkg_reason_row($cust_pkg, $cpr, color => 'ff0000', %opt) %>
20
21 %   unless ( $cust_pkg->get('setup') ) { 
22
23         <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', %opt, ) %>
24
25 %   } else { 
26
27        <% pkg_status_row( $cust_pkg, emt('Setup'), 'setup', %opt ) %>
28        <% pkg_status_row_changed( $cust_pkg, %opt ) %>
29        <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %>
30        <% pkg_status_row_if( $cust_pkg, emt('Suspended'), 'susp', %opt, curuser=>$curuser ) %>
31
32 %   } 
33 %
34 %   if ( $part_pkg->freq && !$supplemental && !$cust_pkg->change_custnum ) { #?
35
36       <TR>
37         <TD COLSPAN=<%$opt{colspan}%>>
38           <FONT SIZE=-1>
39 %           if ( $curuser->access_right('Un-cancel customer package') && ! $opt{no_links} ) { 
40               (&nbsp;<% pkg_uncancel_link($cust_pkg) %>&nbsp;)
41 %           } 
42           <FONT>
43         </TD>
44       </TR>
45 %   }
46 %
47 % } else { # not canceled
48 %
49 %   if ( $cust_pkg->get('susp') ) { #suspended or on hold
50 %
51 %     #if ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) # inconsistent with FS::cust_pkg::status
52 %     if ( ! $cust_pkg->setup ) { #status: on hold
53
54         <% pkg_status_row( $cust_pkg, emt('On Hold'), '', 'color'=>'7E0079', %opt ) %>
55
56 %     } else { #status: suspended
57 %       my ($cpr,$susplabel);
58 %       if ($cust_pkg->is_status_delay_cancel(%opt)) {
59 %         $cpr = $cust_pkg->last_cust_pkg_reason('expire');
60 %         $susplabel = 'Suspended (Cancelled)';
61 %       } else {
62 %         $cpr = $cust_pkg->last_cust_pkg_reason('susp');
63 %         $susplabel = 'Suspended';
64 %       }
65         <% pkg_status_row( $cust_pkg, emt($susplabel), 'susp', 'color'=>'FF9900', %opt ) %>
66         <% pkg_reason_row( $cust_pkg, $cpr, 'color' => 'FF9900', %opt ) %>
67
68 %     }
69
70     <% pkg_status_row_noauto( $cust_pkg, %opt ) %>
71
72     <% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
73
74     <% pkg_status_row_discount( $cust_pkg, %opt ) %>
75
76 %   if ( $cust_pkg->order_date ne $cust_pkg->get('susp') ) { # not on hold
77 %     if ( $cust_pkg->get('setup') ) {
78         <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %>
79 %     } else {
80         <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', %opt ) %>
81 %     }
82 %   }
83
84     <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
85
86     <% pkg_status_row_changed( $cust_pkg, %opt ) %>
87     <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %>
88 %   if ( $cust_pkg->option('suspend_bill', 1)
89 %        || ( $part_pkg->option('suspend_bill', 1)
90 %               && ! $cust_pkg->option('no_suspend_bill',1)
91 %           )
92 %      )
93 %   {
94       <% pkg_status_row_if( $cust_pkg, emt('Next bill'), 'bill', %opt, curuser=>$curuser ) %>
95 %   }
96     <% pkg_status_row_if( $cust_pkg, emt('Will resume'), 'resume', %opt, curuser=>$curuser ) %>
97     <% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %>
98     <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
99
100 %   # Status changes for suspended packages: can unsuspend, future-unsuspend,
101 %   # or future-change. If this package is a future change or is supplemental
102 %   # disable them all.
103 %   if ( !$supplemental && ! $opt{no_links} && !$change_from ) {
104       <TR>
105         <TD COLSPAN=<%$opt{colspan}%>>
106           <FONT SIZE=-1>
107 %           if ( !$cust_pkg->change_to_pkgnum # because on a technical level, change won't propagate,
108 %                                             # and there's not really a use case worth making that work
109 %                 and $part_pkg->freq # technically possible to have contract_end w/o freq, but nonsensical
110 %                 and $curuser->access_right('Change package contract end date')
111 %           ) {
112                 (&nbsp;<% pkg_change_contract_end_link($cust_pkg) %>&nbsp;)
113                 <BR>
114 %           }
115 %           if ( $cust_pkg->change_to_pkgnum ) {
116 %               # then you can modify the package change
117 %               if ( $curuser->access_right('Change customer package') ) {
118                 (&nbsp;<% pkg_change_now_link($cust_pkg) %>&nbsp;)
119                 (&nbsp;<% pkg_change_later_link($cust_pkg) %>&nbsp;)
120                 (&nbsp;<% pkg_unchange_link($cust_pkg) %>&nbsp;)
121                 <BR>
122 %               }
123 %           }
124 %           if ( $curuser->access_right('Unsuspend customer package') ) { 
125 %             if ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) { #on hold
126                 (&nbsp;<% pkg_unhold_link($cust_pkg) %>&nbsp;)
127 %             } else {
128                 (&nbsp;<% pkg_unsuspend_link($cust_pkg) %>&nbsp;)
129                 (&nbsp;<% pkg_resume_link($cust_pkg) %>&nbsp;)
130 %             }
131 %           }
132 %           if ( !$cust_pkg->change_to_pkgnum and
133 %                $curuser->access_right('Cancel customer package immediately')
134 %           ) {
135               (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
136 %           } 
137           </FONT>
138         </TD>
139       </TR>
140 %     }
141 %
142 %   } else { #status: active
143 %
144 %     if ( $change_from ) { # future change
145 %
146           <% pkg_status_row_colspan( $cust_pkg, emt('Waiting for package change'), '', %opt ) %>
147           <% pkg_status_row_if( $cust_pkg,
148                              emt('Will be activated on'),
149                              'start_date',
150                              %opt ) %>
151 %
152 %     } elsif ( ! $cust_pkg->get('setup') ) { # not setup
153 %
154 %       unless ( $part_pkg->freq ) { # one-time charge
155
156           <% pkg_status_row_colspan( $cust_pkg, emt('Not yet billed (one-time charge)'), '', %opt ) %>
157
158           <% pkg_status_row_noauto( $cust_pkg, %opt ) %>
159
160           <% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
161
162           <% pkg_status_row_discount( $cust_pkg, %opt ) %>
163
164           <% pkg_status_row_if(
165                $cust_pkg,
166                ( $part_pkg->freq ? emt('Start billing') : emt('Bill on') ),
167                'start_date',
168                %opt
169              )
170           %>
171
172           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
173
174 %         if ( !$supplemental && ! $opt{no_links} ) {
175           <TR>
176             <TD COLSPAN=<%$opt{colspan}%>>
177               <FONT SIZE=-1>
178 %               if ( $curuser->access_right('Cancel customer package immediately') ) { 
179                   (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
180 %               } 
181               </FONT>
182             </TD>
183           </TR>
184 %         }
185
186 %       } else { # recurring package, not yet billed
187
188           <% pkg_status_row_colspan($cust_pkg, emt("Not yet billed ($billed_or_prepaid [_1])", myfreq($part_pkg) ), '', %opt ) %>
189
190           <% pkg_status_row_noauto( $cust_pkg, %opt ) %>
191
192           <% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
193
194           <% pkg_status_row_discount( $cust_pkg, %opt ) %>
195
196           <% pkg_status_row_if($cust_pkg, emt('Start billing'), 'start_date', %opt) %>
197           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
198
199 %       } 
200 %
201 %     } else { #setup
202 %
203 %       unless ( $part_pkg->freq ) { 
204
205           <% pkg_status_row_colspan($cust_pkg, emt('One-time charge'), '', %opt ) %>
206
207           <% pkg_status_row($cust_pkg, emt('Billed'), 'setup', %opt) %>
208
209           <% pkg_status_row_noauto( $cust_pkg, %opt ) %>
210
211           <% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
212
213           <% pkg_status_row_discount( $cust_pkg, %opt ) %>
214
215           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
216
217 %       } else { # recurring package
218 %
219 %         my $num_cust_svc = $cust_pkg->num_cust_svc;
220 %         my $summarize = $opt{'cust_pkg-large_pkg_size'} > 0
221 %                           && $opt{'cust_pkg-large_pkg_size'} <= $num_cust_svc;
222 %
223 %         #overlimit process is expensive with many services, so skip w/summary
224 %         if ( !$summarize && scalar($cust_pkg->overlimit) ) {
225
226             <% pkg_status_row_colspan( $cust_pkg,
227                  emt('Overlimit'),
228                  $billed_or_prepaid. '&nbsp;'. myfreq($part_pkg),
229                  'color'=>'FFD000',
230                  %opt
231                )
232             %>
233
234 %         } else {
235             <% pkg_status_row_colspan( $cust_pkg,
236                  emt('Active'),
237                  $billed_or_prepaid. '&nbsp;'. myfreq($part_pkg),
238                  'color'=>'00CC00',
239                  %opt
240                )
241             %>
242 %         } 
243
244           <% pkg_status_row_noauto( $cust_pkg, %opt ) %>
245
246           <% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
247
248           <% pkg_status_row_discount( $cust_pkg, %opt ) %>
249
250           <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt) %>
251
252           <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
253
254 %       } 
255 %
256 %     }
257 %
258 %     if ( $opt{'cust_pkg-show_autosuspend'} ) {
259 %       my $autosuspend = pkg_autosuspend_time( $cust_pkg );
260 %       $cust_pkg->set('autosuspend', $autosuspend) if $autosuspend;
261 %     }
262
263       <% pkg_status_row_changed( $cust_pkg, %opt ) %>
264       <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %>
265       <% pkg_status_row_if( $cust_pkg, $next_bill_or_prepaid_until, 'bill', %opt, curuser=>$curuser ) %>
266       <% pkg_status_row_if($cust_pkg, emt('Will automatically suspend by'), 'autosuspend', %opt) %>
267       <% pkg_status_row_if($cust_pkg, emt('Automatic suspension delayed until'), 'dundate', %opt) %>
268       <% pkg_status_row_if( $cust_pkg, emt('Will suspend on'), 'adjourn', %opt, curuser=>$curuser ) %>
269       <% pkg_status_row_if( $cust_pkg, emt('Will resume on'), 'resume', %opt, curuser=>$curuser ) %>
270       <% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %>
271       <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
272
273 %     # Status changes for active recurring packages. If it has a future
274 %     # package change scheduled, let that be modified. If it's supplemental,
275 %     # then that's the only allowed action. Otherwise allow suspend, future
276 %     # suspend, do-not-suspend, and immediate and future cancel.
277 %     if ( $part_pkg->freq and ! $opt{no_links} ) { 
278
279         <TR>
280           <TD COLSPAN=<%$opt{colspan}%>>
281             <FONT SIZE=-1>
282
283 % #change date links
284 %           if ( !$change_from and !$supplemental ) {
285 %             my $has_date_links = 0;
286 %             if ( !$cust_pkg->get('setup')
287 %                   and $curuser->access_right('Change package start date')
288 %             ) {
289             (&nbsp;<% pkg_change_start_link($cust_pkg) %>&nbsp;)
290 %               $has_date_links = 1;
291 %             }
292 %             if ( !$cust_pkg->change_to_pkgnum # because on a technical level, change won't propagate,
293 %                                               # and there's not really a use case worth making that work
294 %                   and $curuser->access_right('Change package contract end date')
295 %             ) {
296             (&nbsp;<% pkg_change_contract_end_link($cust_pkg) %>&nbsp;)
297 %               $has_date_links = 1;
298 %             }
299 %             if ($has_date_links) {
300             <BR>
301 %             }
302 %           }
303
304 % # action links
305 %           if ( $change_from ) {
306 %               # nothing
307 %           } elsif ( $cust_pkg->change_to_pkgnum ) {
308 %               # then you can modify the package change
309 %               if ( $curuser->access_right('Change customer package') ) {
310                 (&nbsp;<% pkg_change_now_link($cust_pkg) %>&nbsp;)
311                 (&nbsp;<% pkg_change_later_link($cust_pkg) %>&nbsp;)
312                 (&nbsp;<% pkg_unchange_link($cust_pkg) %>&nbsp;)
313                 <BR>
314 %               }
315 %           }
316
317 %           if ( !$supplemental ) {
318 %           # suspension actions--always available
319 %             if ( $curuser->access_right('Suspend customer package') ) {
320                 (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
321 %             }
322 %             if ( $curuser->access_right('Suspend customer package later') ) {
323                 (&nbsp;<% pkg_adjourn_link($cust_pkg) %>&nbsp;)
324 %             }
325 %             if ( $curuser->access_right('Delay suspension events') ) { 
326                 (&nbsp;<% pkg_delay_link($cust_pkg) %>&nbsp;)
327 %             }
328 %
329 %             if ( $change_from or $cust_pkg->change_to_pkgnum ) {
330 %                 # you can't cancel the package while in this state
331 %             } else { # the normal case: links to cancel the package
332                 <BR>
333 %               if ( $curuser->access_right('Cancel customer package immediately') ) {
334                   (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
335 %               }
336 %               if ( $curuser->access_right('Cancel customer package later') ) {
337                   (&nbsp;<% pkg_expire_link($cust_pkg) %>&nbsp;)
338 %               }
339 %             }
340 %           }
341
342             <FONT>
343           </TD>
344         </TR>
345 %     }
346 %
347 %   } 
348 % } 
349
350   </TABLE>
351 </TD>
352 <%init>
353
354 my %opt = @_;
355
356 my $bgcolor  = $opt{'bgcolor'};
357 my $cust_pkg = $opt{'cust_pkg'};
358 my $part_pkg = $opt{'part_pkg'};
359 my $curuser  = $FS::CurrentUser::CurrentUser;
360 my $width    = $opt{'cust_pkg-display_times'} ? '38%' : '56%';
361 my $supplemental = $opt{'supplemental'};
362 my $change_from  = $opt{'change_from'};
363
364 $opt{colspan}  = $opt{'cust_pkg-display_times'} ? 8 : 4;
365
366 #false laziness w/edit/REAL_cust_pkg.cgi
367 my( $billed_or_prepaid, $last_bill_or_renewed, $next_bill_or_prepaid_until );
368 unless ( $part_pkg->is_prepaid ) {
369   $billed_or_prepaid = 'billed';
370   $last_bill_or_renewed = 'Last&nbsp;bill';
371   $next_bill_or_prepaid_until = 'Next&nbsp;bill';
372 } else {
373   $billed_or_prepaid = 'prepaid';
374   $last_bill_or_renewed = 'Renewed';
375   $next_bill_or_prepaid_until = 'Prepaid&nbsp;until';
376 }
377
378 #subroutines
379
380 sub myfreq {
381   my $part_pkg = shift;
382   my $freq = $part_pkg->freq_pretty;
383   #$freq =~ s/ /&nbsp;/g;
384   $freq;
385 }
386
387 #false laziness w/package.html
388 sub pkg_link {
389   my($action, $label, $cust_pkg) = @_;
390   return '' unless $cust_pkg;
391   qq!<a href="$p$action.cgi?!. $cust_pkg->pkgnum. qq!">$label</a>!;
392 }
393
394 sub pkg_status_row {
395   my( $cust_pkg, $title, $field, %opt ) = @_;
396
397   if ( $field and $cust_pkg->main_pkgnum ) {
398     # for supplemental packages, we mostly only show these if they're 
399     # different from the main package
400     my $main_pkg = $cust_pkg-> main_pkg;
401     if (    $main_pkg->get($field) ne $cust_pkg->get($field)
402         # with some exceptions
403         or  $field eq 'bill'
404         or  $field eq 'last_bill'
405         or  $field eq 'setup'
406         or  $field eq 'susp'
407         or  $field eq 'cancel'
408       ) {
409       # handle it normally
410     } else {
411       return '';
412     }
413   }
414
415   my $color = $opt{'color'};
416
417   my $html = qq(<TR><TD WIDTH="$width" ALIGN="right">);
418   $html   .= qq(<FONT COLOR="#$color"><B>) if length($color);
419   $html   .= qq($title&nbsp;);
420   $html   .= qq(</B></FONT>) if length($color);
421
422   if ( $opt{'pkg_balances'} && ! $cust_pkg->{_printed_balance}++ ) { #kludge
423     $html .= ' (Balance:&nbsp;<B>'. $opt{'money_char'}.
424              $cust_pkg->cust_main->balance_pkgnum($cust_pkg->pkgnum).
425              '</B>)';
426   }
427
428   $html   .= qq(</TD>);
429   $html   .= pkg_datestr($cust_pkg, $field, %opt). '</TR>';
430
431   $html;
432 }
433
434 sub pkg_status_row_if {
435   my( $cust_pkg, $title, $field, %opt ) = @_;
436   
437   $title = '<FONT SIZE=-1>(&nbsp;'. pkg_unadjourn_link($cust_pkg). '&nbsp;)&nbsp;</FONT>'. $title
438     if ( $field eq 'adjourn' &&
439          $opt{curuser}->access_right('Suspend customer package later')
440        );
441
442   $cust_pkg->get($field) ? pkg_status_row($cust_pkg, $title, $field, %opt) : '';
443 }
444
445 sub pkg_status_row_expire {
446   my $cust_pkg = shift;
447   my %opt = @_;
448   return unless $cust_pkg->get('expire');
449
450   my $title;
451
452   if ( $cust_pkg->get('change_to_pkg') ) {
453     if ( $cust_pkg->change_to_pkg->pkgpart != $cust_pkg->pkgpart ) {
454       $title = mt('Will change to <b>[_1]</b> on',
455                  $cust_pkg->change_to_pkg->part_pkg->pkg);
456     } elsif ( $cust_pkg->change_to_pkg->locationnum != $cust_pkg->locationnum )
457     {
458       $title = mt('Will <b>change location</b> on');
459     } elsif (( $cust_pkg->change_to_pkg->quantity != $cust_pkg->quantity ) ||
460              ( $cust_pkg->change_to_pkg->contract_end != $cust_pkg->contract_end ))
461     {
462       $title = mt('Will change on');
463     } else {
464       # FS::cust_pkg->change_later should have prevented this, but 
465       # just so that we can display _something_
466       $title = '<font color="#ff0000">Unknown package change</font>';
467     }
468
469   } else {
470
471     $title = emt('Expires');
472     if ( $opt{curuser}->access_right('Cancel customer package later')) {
473       $title = '<FONT SIZE=-1>(&nbsp;'. pkg_unexpire_link($cust_pkg). '&nbsp;)&nbsp;</FONT>'. $title;
474     }
475
476   }
477
478   pkg_status_row( $cust_pkg, $title, 'expire', %opt );
479 }
480
481 sub pkg_status_row_changed {
482   my( $cust_pkg, %opt ) = @_;
483
484   return '' unless $cust_pkg->change_date;
485
486   my $html =
487     pkg_status_row( $cust_pkg, emt('Package changed'), 'change_date', %opt );
488
489   my $old = $cust_pkg->old_cust_pkg;
490   if ( $old ) {
491     my $part_pkg = $old->part_pkg;
492     $html .= pkg_status_row_colspan(
493       $cust_pkg, 
494 #      emt("Changed from [_1]: [_2]",
495 #             $cust_pkg->change_pkgnum,
496 #             $part_pkg->pkg_comment(cust_pkg=>$old, nopartpkg=>1)
497 #         ),
498       '',
499       '',
500       'size'    => '-1',
501       'align'   => 'right',
502     );
503   }
504
505   $html;
506 }
507
508 sub pkg_status_row_detached {
509   my( $cust_pkg, %opt ) = @_;
510
511   return '' unless $cust_pkg->change_custnum;
512
513   my $html = '';
514
515   my $cust_main = $cust_pkg->change_cust_main;
516   if ( $cust_main ) {
517
518     my $cust_link = '<A HREF="cust_main.cgi?'.  $cust_pkg->change_custnum. '">'.
519                       encode_entities( $cust_main->name ).
520                     '</A>';
521
522     my $what = $opt{'pkg_attached'} ? 'Attached' : 'Detached';
523
524     $html .= pkg_status_row_colspan( $cust_pkg, 
525                                      emt("$what to customer #[_1]: ",
526                                             $cust_pkg->change_custnum
527                                         ).
528                                        $cust_link,
529                                      '',
530                                      'size'    => '-1',
531                                      'align'   => 'right',
532                                      'colspan' => 4,
533                                    );
534   }
535
536   $html;
537 }
538
539 sub pkg_status_row_noauto {
540   my( $cust_pkg, %opt ) = @_;
541
542   return '' unless ( $cust_pkg->no_auto || $opt{'part_pkg'}->no_auto )
543                 && $opt{'has_cust_payby_auto'};
544
545   pkg_status_row_colspan( $cust_pkg, emt("No automatic charge"), '');
546 }
547
548 sub pkg_status_row_separate_bill {
549   my $cust_pkg = shift;
550   return '' unless $cust_pkg->separate_bill;
551   pkg_status_row_colspan( $cust_pkg, emt("Invoiced separately") );
552 }
553
554 sub pkg_status_row_discount {
555   my( $cust_pkg, %opt ) = @_;
556
557   my $html;
558
559   if ( $cust_pkg->waive_setup ) {
560     my $label = '<SPAN STYLE="font-size: small;font-weight: bold">' .
561                  emt('Setup fee waived') .
562                  '</SPAN>';
563     $html .= pkg_status_row_colspan( $cust_pkg, $label, '', %opt );
564   }
565
566   foreach my $cust_pkg_discount (@{ $cust_pkg->{_cust_pkg_discount_active} }) {
567
568     my $discount = $cust_pkg_discount->discount;
569
570     my $label = '<SPAN STYLE="font-size: small"><B>';
571     if ( $cust_pkg_discount->setuprecur eq 'setup' ) {
572       $label .= emt('Setup Discount');
573     } else {
574       $label .= emt('Recurring Discount');
575     }
576     $label .= '</B>: '. $discount->description;
577     if ( $discount->months > 0 and $cust_pkg_discount->months_used > 0 ) {
578       my $remaining = $discount->months - $cust_pkg_discount->months_used;
579       $remaining = sprintf('%.2f', $remaining) if $remaining =~ /\./;
580       $label .= <br> . emt(" ([quant,_1,month,months] remaining)",$remaining);
581     }
582     $label .= '</SPAN>';
583
584     #$label .= ' <FONT SIZE="-1">('.
585     #            '<A HREF="../misc/delete-cust_pkg_discount.html?'.
586     #              $cust_pkg_discount->pkgdiscountnum.
587     #            '">'.emt('remove discount').'</A>)</FONT>';
588
589     $html .= pkg_status_row_colspan( $cust_pkg, $label, '', %opt );
590
591   }
592
593   $html;
594 }
595
596 sub pkg_reason_row {
597   my ($cust_pkg, $cpr, %opt) = @_;
598   return '' if $cust_pkg->main_pkgnum;
599
600   my $reasontext = '';
601   $reasontext = $cpr->reasontext . ' by ' . $cpr->otaker if $cpr;
602   pkg_status_row_colspan( $cust_pkg, $reasontext, '',
603     'align'=>'right', 'size'=>'-2', %opt
604   );
605 }
606
607 sub pkg_status_row_colspan {
608   my($cust_pkg, $title, $addl, %opt) = @_;
609
610   my $colspan  = $opt{'colspan'};
611
612   my $align = $opt{'align'} ? 'ALIGN="'. $opt{'align'}.'"' : '';
613   my $color = $opt{'color'} ? 'COLOR="#'.$opt{'color'}.'"' : '';
614   my $size  = $opt{'size'}  ? 'SIZE="'.  $opt{'size'}. '"' : '';
615
616   my $html = qq(<TR><TD COLSPAN=$colspan $align>);
617   $html   .= qq(<FONT $color $size>) if length($color) || $size;
618   $html   .= qq(<B>) if $color && !$size;
619   $html   .= $title;
620   $html   .= qq(</B>) if $color && !$size;
621   $html   .= qq(</FONT>) if length($color) || $size;
622   $html   .= ",&nbsp;$addl" if length($addl);
623
624   if ( $opt{'pkg-balances'} && ! $cust_pkg->{_printed_balance}++ ) { #kludge
625     $html .= ' (Balance:&nbsp;<B>'. $opt{'money_char'}.
626              $cust_pkg->cust_main->balance_pkgnum($cust_pkg->pkgnum).
627              '</B>)';
628   }
629
630   $html   .= qq(</TD></TR>);
631
632   $html;
633
634 }
635
636 sub pkg_datestr {
637   my($cust_pkg, $field, %opt) = @_ or return '';
638   return '&nbsp;' unless $cust_pkg->get($field);
639   my $format = '<TD align="left"><B>%b</B></TD>'.
640                '<TD align="right"><B>&nbsp;%o,</B></TD>'.
641                '<TD align="right"><B>&nbsp;%Y</B></TD>';
642   #$format .= '&nbsp;<FONT SIZE=-3>%l:%M:%S%P&nbsp;%z</FONT>'
643   $format .= '<TD ALIGN="right"><B>&nbsp;%l</TD>'.
644              '<TD ALIGN="center"><B>:</B></TD>'.
645              '<TD ALIGN="left"><B>%M</B></TD>'.
646              '<TD ALIGN="left"><B>&nbsp;%P</B></TD>'
647     if $opt{'cust_pkg-display_times'};
648   my $strip = time2str($format, $cust_pkg->get($field) );
649   $strip =~ s/ (\d)/$1/g;
650   $strip;
651 }
652
653 sub pkg_suspend_link {
654   include( '/elements/popup_link-cust_pkg.html',
655              'action'      => $p. 'misc/cancel_pkg.html?method=suspend',
656              'label'       => emt('Suspend now'),
657              'actionlabel' => emt('Suspend'),
658              'color'       => '#FF9900',
659              'cust_pkg'    => shift,
660              'height'      => 420,
661          )
662 }
663
664 sub pkg_adjourn_link {
665   include( '/elements/popup_link-cust_pkg.html',
666              'action'      => $p. 'misc/cancel_pkg.html?method=adjourn',
667              'label'       => emt('Suspend later'),
668              'actionlabel' => emt('Adjourn'),
669              'color'       => '#CC6600',
670              'cust_pkg'    => shift,
671              'height'      => 445,
672          )
673 }
674
675 sub pkg_delay_link  {
676   my($cust_pkg) = shift;
677   include( '/elements/popup_link-cust_pkg.html',
678              'action'      => $p. 'misc/delay_susp_pkg.html',
679              'label'       => ( $cust_pkg->dundate
680                                   ? emt('Edit suspension delay')
681                                   : emt('Delay suspend')
682                               ),
683              'actionlabel' => emt('Delay suspend for'),
684              'cust_pkg'    => $cust_pkg,
685          )
686 }
687
688 sub pkg_resume_link {
689   include( '/elements/popup_link-cust_pkg.html',
690              'action'      => $p. 'misc/cancel_pkg.html?method=resume',
691              'label'       => emt('Unsuspend later'),
692              'actionlabel' => emt('Resume'),
693              'color'       => '#00CC00',
694              'cust_pkg'    => shift,
695          )
696 }
697
698 sub pkg_unhold_link {
699   include( '/elements/popup_link-cust_pkg.html',
700              'action'      => $p. 'misc/unhold_pkg.html',
701              'label'       => emt('Start billing'),
702              'actionlabel' => emt('Start billing'),
703              'color'       => '#00CC00',
704              'width'       => 510,
705              'height'      => 310,
706              'cust_pkg'    => shift,
707          )
708 }
709
710 sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg',    emt('Unsuspend now'), @_ ); }
711 sub pkg_unadjourn_link { pkg_link('misc/unadjourn_pkg', emt('Abort'),     @_ ); }
712 sub pkg_unexpire_link  { pkg_link('misc/unexpire_pkg',  emt('Abort'),     @_ ); }
713 sub pkg_unchange_link  { pkg_link('misc/do_not_change_pkg',  emt('Abort change'),     @_ ); }
714 sub pkg_change_now_link  { pkg_link('misc/change_pkg_now',  emt('Change now'),     @_ ); }
715
716 sub pkg_cancel_link {
717   include( '/elements/popup_link-cust_pkg.html',
718              'action'      => $p. 'misc/cancel_pkg.html?method=cancel',
719              'label'       => emt('Cancel now'),
720              'actionlabel' => emt('Cancel'),
721              'color'       => '#ff0000',
722              'cust_pkg'    => shift,
723          )
724 }
725
726 sub pkg_uncancel_link {
727   include( '/elements/popup_link-cust_pkg.html',
728              'action'      => $p. 'misc/cancel_pkg.html?method=uncancel',
729              'label'       => emt('Un-cancel'),
730              'actionlabel' => emt('Un-cancel'),
731              #'color'       =>  #?
732              'cust_pkg'    => shift,
733              'width'       => 960,
734              'height'      => 740,
735          )
736 }
737
738 sub pkg_expire_link {
739   include( '/elements/popup_link-cust_pkg.html',
740              'action'      => $p. 'misc/cancel_pkg.html?method=expire',
741              'label'       => emt('Cancel later'),
742              'actionlabel' => emt('Expire'),
743              'color'       => '#CC0000',
744              'cust_pkg'    => shift,
745          )
746 }
747
748 sub pkg_change_later_link {
749   my $cust_pkg = shift;
750   include( '/elements/popup_link-cust_pkg.html',
751     'action'      => $p . 'misc/change_pkg.cgi',
752     'label'       => emt('Reschedule'),
753     'actionlabel' => emt('Edit scheduled change for'),
754     'cust_pkg'    => $cust_pkg,
755     'width'       => 960,
756     'height'      => 490,
757   )
758 }
759
760 sub pkg_change_start_link {
761   my $cust_pkg = shift;
762   include( '/elements/popup_link-cust_pkg.html',
763     'action'      => $p . 'misc/change_pkg_date.html?field=start_date',
764     'label'       => emt('Set start date'),
765     'actionlabel' => emt('Set start of billing for'),
766     'cust_pkg'    => $cust_pkg,
767     'width'       => 510,
768     'height'      => 310,
769   )
770 }
771
772 sub pkg_change_contract_end_link {
773   my $cust_pkg = shift;
774   include( '/elements/popup_link-cust_pkg.html',
775     'action'      => $p . 'misc/change_pkg_date.html?field=contract_end',
776     'label'       => emt('Set contract end'),
777     'actionlabel' => emt('Set contract end for'),
778     'cust_pkg'    => $cust_pkg,
779     'width'       => 510,
780     'height'      => 310,
781   )
782 }
783
784 sub svc_recharge_link {
785   include( '/elements/popup_link-cust_svc.html',
786              'action'      => $p. 'misc/recharge_svc.html',
787              'label'       => emt('Recharge'),
788              'actionlabel' => emt('Recharge'),
789              'color'       => '#333399',
790              'cust_svc'    => shift,
791          )
792 }
793
794 sub pkg_autosuspend_time {
795   my $cust_pkg = shift or return '';
796   my $days = 7;
797   my $time = time;
798   my $pending_suspend = 0;
799   #this seems to be extremely inefficient...  and is slowing down all customer
800   #views
801   while ( $days > 0 &&
802           scalar(
803             grep { $_->part_event->action eq 'suspend' }
804             @{$cust_pkg->cust_main->due_cust_event( time => $time + 86400*$days,
805                                                     testonly => 1,
806                                                   ) }
807           )
808         )
809   {
810     $pending_suspend = 1;
811     $days--;
812   }
813
814   $pending_suspend ? time + ($days + 1) * 86400 : '';
815
816 }
817
818 </%init>