%#this should use cust_pkg->status and cust_pkg->statuscolor eventually % if ( $cust_pkg->order_date ) { <% pkg_status_row($cust_pkg, emt('Ordered'), 'order_date', %opt ) %> % } % if ( $cust_pkg->get('cancel') ) { #status: cancelled % my $cpr = $cust_pkg->last_cust_pkg_reason('cancel'); <% pkg_status_row($cust_pkg, emt('Cancelled'), 'cancel', 'color'=>'FF0000', %opt ) %> <% pkg_status_row_colspan( $cust_pkg, ( $cpr ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '', 'align'=>'right', 'color'=>'ff0000', 'size'=>'-2', 'colspan'=>$colspan, %opt ) %> % unless ( $cust_pkg->get('setup') ) { <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', 'colspan'=>$colspan, %opt, ) %> % } else { <% pkg_status_row( $cust_pkg, emt('Setup'), 'setup', %opt ) %> <% pkg_status_row_changed( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %> <% pkg_status_row_if( $cust_pkg, emt('Suspended'), 'susp', %opt, curuser=>$curuser ) %> % } % % if ( $part_pkg->freq ) { #? % } % % } else { % % if ( $cust_pkg->get('susp') ) { #status: suspended % my $cpr = $cust_pkg->last_cust_pkg_reason('susp'); <% pkg_status_row( $cust_pkg, emt('Suspended'), 'susp', 'color'=>'FF9900', %opt ) %> <% pkg_status_row_colspan( $cust_pkg, ( $cpr ? $cpr->reasontext. ' by '. $cpr->otaker : '' ), '', 'align'=>'right', 'color'=>'FF9900', 'size'=>'-2', 'colspan'=>$colspan, %opt, ) %> <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %> % unless ( $cust_pkg->get('setup') ) { <% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', 'colspan'=>$colspan, %opt ) %> % } else { <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %> % } <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %> <% pkg_status_row_changed( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %> % if ( $cust_pkg->option('suspend_bill', 1) % || ( $part_pkg->option('suspend_bill', 1) % && ! $cust_pkg->option('no_suspend_bill',1) % ) % ) % { <% pkg_status_row_if( $cust_pkg, emt('Next bill'), 'bill', %opt, curuser=>$curuser ) %> % } <% pkg_status_row_if( $cust_pkg, emt('Will resume'), 'resume', %opt, curuser=>$curuser ) %> <% pkg_status_row_if( $cust_pkg, emt('Expires'), 'expire', %opt, curuser=>$curuser ) %> <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %> % } else { #status: active % % unless ( $cust_pkg->get('setup') ) { #not setup % % unless ( $part_pkg->freq ) { <% pkg_status_row_colspan( $cust_pkg, emt('Not yet billed (one-time charge)'), '', 'colspan'=>$colspan, %opt ) %> <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_if( $cust_pkg, ( $part_pkg->freq ? emt('Start billing') : emt('Bill on') ), 'start_date', %opt ) %> <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %> % } else { <% pkg_status_row_colspan($cust_pkg, emt("Not yet billed ($billed_or_prepaid [_1])", myfreq($part_pkg) ), '', 'colspan'=>$colspan, %opt ) %> <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_if($cust_pkg, emt('Start billing'), 'start_date', %opt) %> <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %> % } % % } else { #setup % % unless ( $part_pkg->freq ) { <% pkg_status_row_colspan($cust_pkg, emt('One-time charge'), '', 'colspan'=>$colspan, %opt ) %> <% pkg_status_row($cust_pkg, emt('Billed'), 'setup', %opt) %> <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %> % } else { % % my $num_cust_svc = $cust_pkg->num_cust_svc; % my $summarize = $opt{'cust_pkg-large_pkg_size'} > 0 % && $opt{'cust_pkg-large_pkg_size'} <= $num_cust_svc; % % #overlimit process is expensive with many services, so skip w/summary % if ( !$summarize && scalar($cust_pkg->overlimit) ) { <% pkg_status_row_colspan( $cust_pkg, emt('Overlimit'), $billed_or_prepaid. ' '. myfreq($part_pkg), 'color'=>'FFD000', 'colspan'=>$colspan, %opt ) %> % } else { <% pkg_status_row_colspan( $cust_pkg, emt('Active'), $billed_or_prepaid. ' '. myfreq($part_pkg), 'color'=>'00CC00', 'colspan'=>$colspan, %opt ) %> % } <% pkg_status_row_noauto( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_discount( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt) %> <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %> % } % % } % % if ( $opt{'cust_pkg-show_autosuspend'} ) { % my $autosuspend = pkg_autosuspend_time( $cust_pkg ); % $cust_pkg->set('autosuspend', $autosuspend) if $autosuspend; % } <% pkg_status_row_changed( $cust_pkg, %opt, 'colspan'=>$colspan ) %> <% pkg_status_row_if( $cust_pkg, $last_bill_or_renewed, 'last_bill', %opt, curuser=>$curuser ) %> <% pkg_status_row_if( $cust_pkg, $next_bill_or_prepaid_until, 'bill', %opt, curuser=>$curuser ) %> <% pkg_status_row_if($cust_pkg, emt('Will automatically suspend by'), 'autosuspend', %opt) %> <% pkg_status_row_if($cust_pkg, emt('Automatic suspension delayed until'), 'dundate', %opt) %> <% pkg_status_row_if( $cust_pkg, emt('Will suspend on'), 'adjourn', %opt, curuser=>$curuser ) %> <% pkg_status_row_if( $cust_pkg, emt('Will resume on'), 'resume', %opt, curuser=>$curuser ) %> <% pkg_status_row_if( $cust_pkg, emt('Expires'), 'expire', %opt, curuser=>$curuser ) %> <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %> % if ( $part_pkg->freq ) { % } % % } % }
> % if ( $curuser->access_right('Un-cancel customer package') ) { ( <% pkg_uncancel_link($cust_pkg) %> ) % }
> % if ( $curuser->access_right('Unsuspend customer package') ) { ( <% pkg_unsuspend_link($cust_pkg) %> ) ( <% pkg_resume_link($cust_pkg) %> ) % } % if ( $curuser->access_right('Cancel customer package immediately') ) { ( <% pkg_cancel_link($cust_pkg) %> ) % }
> % if ( $curuser->access_right('Cancel customer package immediately') ) { ( <% pkg_cancel_link($cust_pkg) %> ) % }
> % if ( $curuser->access_right('Suspend customer package') ) { ( <% pkg_suspend_link($cust_pkg) %> ) % } % if ( $curuser->access_right('Suspend customer package later') ) { ( <% pkg_adjourn_link($cust_pkg) %> ) % } % if ( $curuser->access_right('Delay suspension events') ) { ( <% pkg_delay_link($cust_pkg) %> ) % } % if ( $curuser->access_right('Cancel customer package immediately') ) { ( <% pkg_cancel_link($cust_pkg) %> ) % } % if ( $curuser->access_right('Cancel customer package later') ) { ( <% pkg_expire_link($cust_pkg) %> ) % }
<%init> my %opt = @_; my $bgcolor = $opt{'bgcolor'}; my $cust_pkg = $opt{'cust_pkg'}; my $part_pkg = $opt{'part_pkg'}; my $curuser = $FS::CurrentUser::CurrentUser; my $colspan = $opt{'cust_pkg-display_times'} ? 8 : 4; my $width = $opt{'cust_pkg-display_times'} ? '38%' : '56%'; #false laziness w/edit/REAL_cust_pkg.cgi my( $billed_or_prepaid, $last_bill_or_renewed, $next_bill_or_prepaid_until ); unless ( $part_pkg->is_prepaid ) { $billed_or_prepaid = 'billed'; $last_bill_or_renewed = 'Last bill'; $next_bill_or_prepaid_until = 'Next bill'; } else { $billed_or_prepaid = 'prepaid'; $last_bill_or_renewed = 'Renewed'; $next_bill_or_prepaid_until = 'Prepaid until'; } #subroutines sub myfreq { my $part_pkg = shift; my $freq = $part_pkg->freq_pretty; #$freq =~ s/ / /g; $freq; } #false laziness w/package.html sub pkg_link { my($action, $label, $cust_pkg) = @_; return '' unless $cust_pkg; qq!$label!; } sub pkg_status_row { my( $cust_pkg, $title, $field, %opt ) = @_; my $color = $opt{'color'}; my $html = qq(); $html .= qq() if length($color); $html .= qq($title ); $html .= qq() if length($color); if ( $opt{'pkg_balances'} && ! $cust_pkg->{_printed_balance}++ ) { #kludge $html .= ' (Balance: '. $opt{'money_char'}. $cust_pkg->cust_main->balance_pkgnum($cust_pkg->pkgnum). ')'; } $html .= qq(); $html .= pkg_datestr($cust_pkg, $field, %opt). ''; $html; } sub pkg_status_row_if { my( $cust_pkg, $title, $field, %opt ) = @_; $title = '( '. pkg_unadjourn_link($cust_pkg). ' ) '. $title if ( $field eq 'adjourn' && $opt{curuser}->access_right('Suspend customer package later') ); $title = '( '. pkg_unexpire_link($cust_pkg). ' ) '. $title if ( $field eq 'expire' && $opt{curuser}->access_right('Cancel customer package later') ); $cust_pkg->get($field) ? pkg_status_row($cust_pkg, $title, $field, %opt) : ''; } sub pkg_status_row_changed { my( $cust_pkg, %opt ) = @_; return '' unless $cust_pkg->change_date; my $html = pkg_status_row( $cust_pkg, emt('Package changed'), 'change_date', %opt ); my $old = $cust_pkg->old_cust_pkg; if ( $old ) { my $part_pkg = $old->part_pkg; $html .= pkg_status_row_colspan( $cust_pkg, emt("Changed from [_1]: [_2]", $cust_pkg->change_pkgnum, $part_pkg->pkg_comment(nopartpkg => 1) ), '', 'size' => '-1', 'align' => 'right', 'colspan' => $opt{'colspan'}, ); } $html; } sub pkg_status_row_noauto { my( $cust_pkg, %opt ) = @_; my $part_pkg = $opt{'part_pkg'}; return '' unless $cust_pkg->no_auto || $part_pkg->no_auto; #inefficient, should be passed in my $cust_main = $cust_pkg->cust_main; return '' unless $cust_main->payby =~ /^(CARD|CHEK)$/; my $what = lc(FS::payby->shortname($cust_main->payby)); pkg_status_row_colspan( $cust_pkg, emt("No automatic $what charge"), '', 'colspan' => $opt{'colspan'}, ); } sub pkg_status_row_discount { my( $cust_pkg, %opt ) = @_; my $html; foreach my $cust_pkg_discount ( $cust_pkg->cust_pkg_discount_active ) { my $discount = $cust_pkg_discount->discount; my $label = ''.emt('Discount').': '. $discount->description; if ( $discount->months ) { my $remaining = $discount->months - $cust_pkg_discount->months_used; $remaining = sprintf('%.2f', $remaining) if $remaining =~ /\./; $label .= emt("([_1] months remaining)",$remaining); } $label .= ' ('. ''.emt('remove discount').')'; $html .= pkg_status_row_colspan( $cust_pkg, $label, '', 'colspan' => $opt{'colspan'}, ); } $html; } sub pkg_status_row_colspan { my($cust_pkg, $title, $addl, %opt) = @_; my $colspan = $opt{'colspan'}; my $align = $opt{'align'} ? 'ALIGN="'. $opt{'align'}.'"' : ''; my $color = $opt{'color'} ? 'COLOR="#'.$opt{'color'}.'"' : ''; my $size = $opt{'size'} ? 'SIZE="'. $opt{'size'}. '"' : ''; my $html = qq(); $html .= qq() if length($color) || $size; $html .= qq() if $color && !$size; $html .= $title; $html .= qq() if $color && !$size; $html .= qq() if length($color) || $size; $html .= ", $addl" if length($addl); if ( $opt{'pkg-balances'} && ! $cust_pkg->{_printed_balance}++ ) { #kludge $html .= ' (Balance: '. $opt{'money_char'}. $cust_pkg->cust_main->balance_pkgnum($cust_pkg->pkgnum). ')'; } $html .= qq(); $html; } sub pkg_datestr { my($cust_pkg, $field, %opt) = @_ or return ''; return ' ' unless $cust_pkg->get($field); my $format = '%b'. ' %o,'. ' %Y'; #$format .= ' %l:%M:%S%P %z' $format .= ' %l'. ':'. '%M'. ' %P' if $opt{'cust_pkg-display_times'}; my $strip = time2str($format, $cust_pkg->get($field) ); $strip =~ s/ (\d)/$1/g; $strip; } sub pkg_suspend_link { include( '/elements/popup_link-cust_pkg.html', 'action' => $p. 'misc/cancel_pkg.html?method=suspend', 'label' => emt('Suspend now'), 'actionlabel' => emt('Suspend'), 'color' => '#FF9900', 'cust_pkg' => shift, ) } sub pkg_adjourn_link { include( '/elements/popup_link-cust_pkg.html', 'action' => $p. 'misc/cancel_pkg.html?method=adjourn', 'label' => emt('Suspend later'), 'actionlabel' => emt('Adjourn'), 'color' => '#CC6600', 'cust_pkg' => shift, ) } sub pkg_delay_link { my($cust_pkg) = shift; include( '/elements/popup_link-cust_pkg.html', 'action' => $p. 'misc/delay_susp_pkg.html', 'label' => ( $cust_pkg->dundate ? emt('Edit suspension delay') : emt('Delay suspend') ), 'actionlabel' => emt('Delay suspend for'), 'cust_pkg' => $cust_pkg, ) } sub pkg_resume_link { include( '/elements/popup_link-cust_pkg.html', 'action' => $p. 'misc/cancel_pkg.html?method=resume', 'label' => emt('Unsuspend later'), 'actionlabel' => emt('Resume'), 'color' => '#00CC00', 'cust_pkg' => shift, ) } sub pkg_unsuspend_link { pkg_link('misc/unsusp_pkg', emt('Unsuspend now'), @_ ); } sub pkg_unadjourn_link { pkg_link('misc/unadjourn_pkg', emt('Abort'), @_ ); } sub pkg_unexpire_link { pkg_link('misc/unexpire_pkg', emt('Abort'), @_ ); } sub pkg_cancel_link { include( '/elements/popup_link-cust_pkg.html', 'action' => $p. 'misc/cancel_pkg.html?method=cancel', 'label' => emt('Cancel now'), 'actionlabel' => emt('Cancel'), 'color' => '#ff0000', 'cust_pkg' => shift, ) } sub pkg_uncancel_link { include( '/elements/popup_link-cust_pkg.html', 'action' => $p. 'misc/cancel_pkg.html?method=uncancel', 'label' => emt('Un-cancel'), 'actionlabel' => emt('Un-cancel'), #'color' => #? 'cust_pkg' => shift, ) } sub pkg_expire_link { include( '/elements/popup_link-cust_pkg.html', 'action' => $p. 'misc/cancel_pkg.html?method=expire', 'label' => emt('Cancel later'), 'actionlabel' => emt('Expire'), 'color' => '#CC0000', 'cust_pkg' => shift, ) } sub svc_recharge_link { include( '/elements/popup_link-cust_svc.html', 'action' => $p. 'misc/recharge_svc.html', 'label' => emt('Recharge'), 'actionlabel' => emt('Recharge'), 'color' => '#333399', 'cust_svc' => shift, ) } sub pkg_autosuspend_time { my $cust_pkg = shift or return ''; my $days = 7; my $time = time; my $pending_suspend = 0; #this seems to be extremely inefficient... and is slowing down all customer #views while ( $days > 0 && scalar( grep { $_->part_event->action eq 'suspend' } @{$cust_pkg->cust_main->due_cust_event( time => $time + 86400*$days, testonly => 1, ) } ) ) { $pending_suspend = 1; $days--; } $pending_suspend ? time + ($days + 1) * 86400 : ''; }