%#this should use cust_pkg->status and cust_pkg->statuscolor eventually
% if ( $supplemental ) {
<% pkg_status_row_colspan($cust_pkg, emt('Supplemental'), '', 'color' => '7777FF', %opt) %>
% } elsif ( $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_detached($cust_pkg, %opt) %>
<% pkg_reason_row($cust_pkg, $cpr, color => 'ff0000', %opt) %>
% unless ( $cust_pkg->get('setup') ) {
<% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', %opt, ) %>
% } else {
<% pkg_status_row( $cust_pkg, emt('Setup'), 'setup', %opt ) %>
<% pkg_status_row_changed( $cust_pkg, %opt ) %>
<% 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 ) %>
% }
%
%
% } else { # not canceled
%
% if ( $cust_pkg->get('susp') ) { #suspended or on hold
%
% #if ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) # inconsistent with FS::cust_pkg::status
% if ( ! $cust_pkg->setup ) { #status: on hold
<% pkg_status_row( $cust_pkg, emt('On Hold'), '', 'color'=>'7E0079', %opt ) %>
% } else { #status: suspended
% my ($cpr,$susplabel);
% if ($cust_pkg->is_status_delay_cancel(%opt)) {
% $cpr = $cust_pkg->last_cust_pkg_reason('expire');
% $susplabel = 'Suspended (Cancelled)';
% } else {
% $cpr = $cust_pkg->last_cust_pkg_reason('susp');
% $susplabel = 'Suspended';
% }
<% pkg_status_row( $cust_pkg, emt($susplabel), 'susp', 'color'=>'FF9900', %opt ) %>
<% pkg_reason_row( $cust_pkg, $cpr, 'color' => 'FF9900', %opt ) %>
% }
<% pkg_status_row_noauto( $cust_pkg, %opt ) %>
<% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
<% pkg_status_row_discount( $cust_pkg, %opt ) %>
% if ( $cust_pkg->order_date ne $cust_pkg->get('susp') ) { # not on hold
% if ( $cust_pkg->get('setup') ) {
<% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %>
% } else {
<% pkg_status_row_colspan( $cust_pkg, emt('Never billed'), '', %opt ) %>
% }
% }
<% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
<% pkg_status_row_changed( $cust_pkg, %opt ) %>
<% 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_expire($cust_pkg, %opt, curuser=>$curuser) %>
<% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
% } else { #status: active
%
% if ( $change_from ) { # future change
%
<% pkg_status_row_colspan( $cust_pkg, emt('Waiting for package change'), '', %opt ) %>
<% pkg_status_row_if( $cust_pkg,
emt('Will be activated on'),
'start_date',
%opt ) %>
%
% } elsif ( ! $cust_pkg->get('setup') ) { # not setup
%
% unless ( $part_pkg->freq ) { # one-time charge
<% pkg_status_row_colspan( $cust_pkg, emt('Not yet billed (one-time charge)'), '', %opt ) %>
<% pkg_status_row_noauto( $cust_pkg, %opt ) %>
<% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
<% pkg_status_row_discount( $cust_pkg, %opt ) %>
<% 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 { # recurring package, not yet billed
<% pkg_status_row_colspan($cust_pkg, emt("Not yet billed ($billed_or_prepaid [_1])", myfreq($part_pkg) ), '', %opt ) %>
<% pkg_status_row_noauto( $cust_pkg, %opt ) %>
<% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
<% pkg_status_row_discount( $cust_pkg, %opt ) %>
<% 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'), '', %opt ) %>
<% pkg_status_row($cust_pkg, emt('Billed'), 'setup', %opt) %>
<% pkg_status_row_noauto( $cust_pkg, %opt ) %>
<% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
<% pkg_status_row_discount( $cust_pkg, %opt ) %>
<% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
% } else { # recurring package
%
% 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',
%opt
)
%>
% } else {
<% pkg_status_row_colspan( $cust_pkg,
emt('Active'),
$billed_or_prepaid. ' '. myfreq($part_pkg),
'color'=>'00CC00',
%opt
)
%>
% }
<% pkg_status_row_noauto( $cust_pkg, %opt ) %>
<% pkg_status_row_separate_bill( $cust_pkg, %opt ) %>
<% pkg_status_row_discount( $cust_pkg, %opt ) %>
<% 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 ) %>
<% 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_expire($cust_pkg, %opt, curuser=>$curuser) %>
<% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
% }
% }
|
<%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 $width = $opt{'cust_pkg-display_times'} ? '38%' : '56%';
my $supplemental = $opt{'supplemental'};
my $change_from = $opt{'change_from'};
$opt{colspan} = $opt{'cust_pkg-display_times'} ? 8 : 4;
#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 ) = @_;
if ( $field and $cust_pkg->main_pkgnum ) {
# for supplemental packages, we mostly only show these if they're
# different from the main package
my $main_pkg = $cust_pkg-> main_pkg;
if ( $main_pkg->get($field) ne $cust_pkg->get($field)
# with some exceptions
or $field eq 'bill'
or $field eq 'last_bill'
or $field eq 'setup'
or $field eq 'susp'
or $field eq 'cancel'
) {
# handle it normally
} else {
return '';
}
}
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')
);
$cust_pkg->get($field) ? pkg_status_row($cust_pkg, $title, $field, %opt) : '';
}
sub pkg_status_row_expire {
my $cust_pkg = shift;
my %opt = @_;
return unless $cust_pkg->get('expire');
my $title;
if ( $cust_pkg->get('change_to_pkg') ) {
if ( $cust_pkg->change_to_pkg->pkgpart != $cust_pkg->pkgpart ) {
$title = mt('Will change to [_1] on',
$cust_pkg->change_to_pkg->part_pkg->pkg);
} elsif ( $cust_pkg->change_to_pkg->locationnum != $cust_pkg->locationnum )
{
$title = mt('Will change location on');
} elsif (( $cust_pkg->change_to_pkg->quantity != $cust_pkg->quantity ) ||
( $cust_pkg->change_to_pkg->contract_end != $cust_pkg->contract_end ))
{
$title = mt('Will change on');
} else {
# FS::cust_pkg->change_later should have prevented this, but
# just so that we can display _something_
$title = 'Unknown package change';
}
} else {
$title = emt('Expires');
if ( $opt{curuser}->access_right('Cancel customer package later')) {
$title = '( '. pkg_unexpire_link($cust_pkg). ' ) '. $title;
}
}
pkg_status_row( $cust_pkg, $title, 'expire', %opt );
}
sub pkg_status_row_changed {
my( $cust_pkg, %opt ) = @_;
return '' unless $cust_pkg->change_date;
my $html =
pkg_status_row( $cust_pkg, emt('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(cust_pkg=>$old, nopartpkg=>1)
# ),
'',
'',
'size' => '-1',
'align' => 'right',
);
}
$html;
}
sub pkg_status_row_detached {
my( $cust_pkg, %opt ) = @_;
return '' unless $cust_pkg->change_custnum;
my $html = '';
my $cust_main = $cust_pkg->change_cust_main;
if ( $cust_main ) {
my $cust_link = ''.
encode_entities( $cust_main->name ).
'';
my $what = $opt{'pkg_attached'} ? 'Attached' : 'Detached';
$html .= pkg_status_row_colspan( $cust_pkg,
emt("$what to customer #[_1]: ",
$cust_pkg->change_custnum
).
$cust_link,
'',
'size' => '-1',
'align' => 'right',
'colspan' => 4,
);
}
$html;
}
sub pkg_status_row_noauto {
my( $cust_pkg, %opt ) = @_;
return '' unless ( $cust_pkg->no_auto || $opt{'part_pkg'}->no_auto )
&& $opt{'has_cust_payby_auto'};
pkg_status_row_colspan( $cust_pkg, emt("No automatic charge"), '');
}
sub pkg_status_row_separate_bill {
my $cust_pkg = shift;
return '' unless $cust_pkg->separate_bill;
pkg_status_row_colspan( $cust_pkg, emt("Invoiced separately") );
}
sub pkg_status_row_discount {
my( $cust_pkg, %opt ) = @_;
my $html;
if ( $cust_pkg->waive_setup ) {
my $label = '' .
emt('Setup fee waived') .
'';
$html .= pkg_status_row_colspan( $cust_pkg, $label, '', %opt );
}
foreach my $cust_pkg_discount (@{ $cust_pkg->{_cust_pkg_discount_active} }) {
my $discount = $cust_pkg_discount->discount;
my $label = '';
if ( $cust_pkg_discount->setuprecur eq 'setup' ) {
$label .= emt('Setup Discount');
} else {
$label .= emt('Recurring Discount');
}
$label .= ': '. $discount->description;
if ( $discount->months > 0 and $cust_pkg_discount->months_used > 0 ) {
my $remaining = $discount->months - $cust_pkg_discount->months_used;
$remaining = sprintf('%.2f', $remaining) if $remaining =~ /\./;
$label .=
. emt(" ([quant,_1,month,months] remaining)",$remaining);
}
$label .= '';
#$label .= ' ('.
# ''.emt('remove discount').')';
$html .= pkg_status_row_colspan( $cust_pkg, $label, '', %opt );
}
$html;
}
sub pkg_reason_row {
my ($cust_pkg, $cpr, %opt) = @_;
return '' if $cust_pkg->main_pkgnum;
my $reasontext = '';
$reasontext = $cpr->reasontext . ' by ' . $cpr->otaker if $cpr;
pkg_status_row_colspan( $cust_pkg, $reasontext, '',
'align'=>'right', 'size'=>'-2', %opt
);
}
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_unadjourn_link { pkg_link('misc/unadjourn_pkg', emt('Abort'), @_ ); }
sub pkg_unexpire_link { pkg_link('misc/unexpire_pkg', emt('Abort'), @_ ); }
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 : '';
}
%init>