diff options
author | Mark Wells <mark@freeside.biz> | 2015-07-13 17:26:48 -0700 |
---|---|---|
committer | Mark Wells <mark@freeside.biz> | 2015-07-14 13:25:05 -0700 |
commit | 98f6d91ec7eaa907204afbfeb90ede1e3bff656d (patch) | |
tree | e5d7b870c4965f9a2b580e3cad5aed82d300e5c8 /httemplate | |
parent | 57e3a0e08b81d52851314c60f37115a05b9be79e (diff) |
automatic package changes for supplemental packages, #37102
Diffstat (limited to 'httemplate')
-rwxr-xr-x | httemplate/browse/part_pkg.cgi | 72 | ||||
-rwxr-xr-x | httemplate/edit/part_pkg.cgi | 47 | ||||
-rw-r--r-- | httemplate/elements/freeside.css | 12 | ||||
-rw-r--r-- | httemplate/elements/select.html | 26 | ||||
-rw-r--r-- | httemplate/elements/tr-select-expire_months.html | 10 | ||||
-rw-r--r-- | httemplate/elements/tr-select-months.html | 12 | ||||
-rwxr-xr-x | httemplate/view/cust_main/packages.html | 26 | ||||
-rw-r--r-- | httemplate/view/cust_main/packages/package.html | 24 | ||||
-rwxr-xr-x | httemplate/view/cust_main/packages/section.html | 8 | ||||
-rw-r--r-- | httemplate/view/cust_main/packages/status.html | 57 |
10 files changed, 223 insertions, 71 deletions
diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi index f8de620a7..c2f1430d7 100755 --- a/httemplate/browse/part_pkg.cgi +++ b/httemplate/browse/part_pkg.cgi @@ -247,6 +247,7 @@ push @fields, sub { $part_pkg->part_pkg_discount; [ + # Line 0: Family package link (if applicable) ( !$family_pkgpart && $part_pkg->pkgpart == $part_pkg->family_pkgpart ? () : [ { @@ -257,13 +258,13 @@ push @fields, sub { 'link' => $p.'browse/part_pkg.cgi?family='.$part_pkg->family_pkgpart, } ] ), - [ + [ # Line 1: Plan type (Anniversary, Prorate, Call Rating, etc.) { data =>$plan, align=>'center', colspan=>2, }, ], - [ + [ # Line 2: Setup fee { data =>$money_char. sprintf('%.2f ', $part_pkg->option('setup_fee') ), align=>'right' @@ -278,7 +279,7 @@ push @fields, sub { align=>'left', }, ], - [ + [ # Line 3: Recurring fee { data=>( $is_recur ? $money_char. sprintf('%.2f', $part_pkg->option('recur_fee')) @@ -288,20 +289,56 @@ push @fields, sub { colspan=> ( $is_recur ? 1 : 2 ), }, ( $is_recur - ? { data => ( $is_recur - ? ' '. $part_pkg->freq_pretty. - ( $part_pkg->option('recur_fee') == 0 - && $part_pkg->recur_show_zero - ? ' (printed on invoices)' - : '' - ) - : '' ), + ? { data => ' '. $part_pkg->freq_pretty. + ( $part_pkg->option('recur_fee') == 0 + && $part_pkg->recur_show_zero + ? ' (printed on invoices)' + : '' + ), align=>'left', } : () ), ], - ( + [ { data => ' ' }, ], # Line 4: empty + ( $part_pkg->adjourn_months ? + [ # Line 5: Adjourn months + { data => mt('After [quant,_1,month], <strong>suspend</strong> the package.', + $part_pkg->adjourn_months), + align => 'left', + size => -1, + colspan => 2, + } + ] : () + ), + ( $part_pkg->contract_end_months ? + [ # Line 6: Contract end months + { data => mt('After [quant,_1,month], <strong>contract ends</strong>.', + $part_pkg->contract_end_months), + align => 'left', + size => -1, + colspan => 2, + } + ] : () + ), + ( $part_pkg->expire_months ? + [ # Line 7: Expire months and automatic transfer + { data => $part_pkg->change_to_pkgpart ? + mt('After [quant,_1,month], <strong>change to</strong> ', + $part_pkg->expire_months) . + qq(<a href="${p}edit/part_pkg.cgi?) . + $part_pkg->change_to_pkgpart . + qq(">) . $part_pkg->change_to_pkg->pkg . qq(</a>) . '.' + : mt('After [quant,_1,month], <strong>cancel</strong> the package.', + $part_pkg->expire_months) + , + align => 'left', + size => -1, + colspan => 2, + } + ] : () + ), + ( # Usage prices map { my $amount = $_->amount / ($_->target_info->{multiplier} || 1); my $label = $_->target_info->{label}; [ @@ -315,7 +352,8 @@ push @fields, sub { } $part_pkg->part_pkg_usageprice ), - ( map { my $dst_pkg = $_->dst_pkg; + ( # Supplementals + map { my $dst_pkg = $_->dst_pkg; [ { data => 'Supplemental: '. '<A HREF="#'. $dst_pkg->pkgpart . '">' . @@ -327,7 +365,8 @@ push @fields, sub { } $part_pkg->supp_part_pkg_link ), - ( map { + ( # Billing add-ons/bundle packages + map { my $dst_pkg = $_->dst_pkg; [ { data => 'Add-on: '.$dst_pkg->pkg_comment, @@ -338,7 +377,8 @@ push @fields, sub { } $part_pkg->bill_part_pkg_link ), - ( scalar(@discounts) + ( # Discounts available + scalar(@discounts) ? [ { data => '<b>Discounts</b>', align=>'center', #? @@ -360,7 +400,7 @@ push @fields, sub { @discounts : () ), - ]; + ]; # end of "middle column" # $plan_labels{$part_pkg->plan}.'<BR>'. # $money_char.sprintf('%.2f setup<BR>', $part_pkg->option('setup_fee') ). diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index a90a62508..9f5510d65 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -28,7 +28,7 @@ 'onsubmit' => 'confirm_submit', - 'labels' => { + 'labels' => { 'pkgpart' => 'Package Definition', 'pkg' => 'Package', %locale_field_labels, @@ -69,6 +69,10 @@ 'supp_dst_pkgpart' => 'When ordering package, also order', 'report_option' => 'Report classes', 'delay_start' => 'Default delay (days)', + 'adjourn_months' => 'Suspend the package after ', + 'contract_end_months' => 'Contract ends after ', + 'expire_months' => 'Cancel the package after ', + 'change_to_pkgpart'=> 'and replace it with ', }, 'fields' => [ @@ -164,6 +168,37 @@ sort $conf->config('currencies') ), + ( $conf->exists('part_pkg-delay_start') + ? ( { type => 'tablebreak-tr-title', + value => 'Delayed start', + }, + { field => 'delay_start', + type => 'text', size => 6 }, + ) + : () + ), + + { type => 'tablebreak-tr-title', + value => 'Limited duration', + }, + { field => 'adjourn_months', + type => 'select-months', + }, + { field => 'contract_end_months', + type => 'select-months', + }, + { field => 'expire_months', + type => 'select-expire_months', + }, + { field => 'change_to_pkgpart', + type => 'select-part_pkg', + extra_sql => sub { $pkgpart + ? "AND pkgpart != $pkgpart" + : '' + }, + empty_label => 'no package', + }, + #price plan #setup fee #recurring frequency @@ -219,16 +254,6 @@ ) ), - ( $conf->exists('part_pkg-delay_start') - ? ( { type => 'tablebreak-tr-title', - value => 'Delayed start', - }, - { field => 'delay_start', - type => 'text', size => 6 }, - ) - : () - ), - { type => 'columnnext' }, {type=>'justtitle', value=>'Agent (reseller) types' }, diff --git a/httemplate/elements/freeside.css b/httemplate/elements/freeside.css index d4e155aa1..dbd27cbaa 100644 --- a/httemplate/elements/freeside.css +++ b/httemplate/elements/freeside.css @@ -323,3 +323,15 @@ div#overDiv { box-shadow: #333333 1px 1px 2px; } +/* view/cust_main/packages/package.html */ +div.package-marker-supplemental { + height: 100%; + border-left: solid #bbbbff 30px; + display: inline-block; +} + +div.package-marker-change_from { + height: 100%; + border-left: solid #bbffbb 30px; + display: inline-block; +} diff --git a/httemplate/elements/select.html b/httemplate/elements/select.html index 4492681de..42cd89504 100644 --- a/httemplate/elements/select.html +++ b/httemplate/elements/select.html @@ -1,3 +1,29 @@ +<%doc> +<& select.html, + # required + field => 'myfield', # NAME property + curr_value => 'foo', + labels => { # or 'option_labels' + 'AL' => 'Alabama', + 'AK' => 'Alaska', + 'AR' => 'Arkansas', + }, + options => [ 'AL', 'AK', 'AR' ], + curr_value => $cgi->param('myfield'), + + # recommended + id => 'myid', # DOM id + + # optional + size => 1, # to show multiple rows at once + style => '', # STYLE property + multiple => 0, + disabled => 0, + onchange => 'do_something()', + js_only => 0, # disables the whole thing +&> +</%doc> + % unless ( $opt{'js_only'} ) { <SELECT NAME = "<% $opt{field} %>" diff --git a/httemplate/elements/tr-select-expire_months.html b/httemplate/elements/tr-select-expire_months.html new file mode 100644 index 000000000..ced96603d --- /dev/null +++ b/httemplate/elements/tr-select-expire_months.html @@ -0,0 +1,10 @@ +<& tr-select-months.html, @_ &> +<script> +// disable the pkgpart selector if it's set to zero months +$().ready(function() { + $('#expire_months').on('change', function() { + $('#change_to_pkgpart').prop('disabled', this.value == 0); + }) + .trigger('change'); +}); +</script> diff --git a/httemplate/elements/tr-select-months.html b/httemplate/elements/tr-select-months.html new file mode 100644 index 000000000..3ff28f99b --- /dev/null +++ b/httemplate/elements/tr-select-months.html @@ -0,0 +1,12 @@ +<%init> +my %opt = @_; +$opt{id} ||= $opt{field}; # should be the default everywhere +my $max = $opt{max} || 36; +$opt{options} = [ '', 1 .. $max ]; +$opt{labels} = { '' => '', + map { $_ => emt('[quant,_1,month]', $_) } 1 .. $max + }; + +warn Dumper(\%opt); +</%init> +<& tr-select.html, %opt &> diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html index 41315701f..4903e185b 100755 --- a/httemplate/view/cust_main/packages.html +++ b/httemplate/view/cust_main/packages.html @@ -180,8 +180,11 @@ my @packages = $cust_main->all_pkgs( { }, } ); +my $is_anything_hidden = 0; # optimization + my %change_to_from; # target pkgnum => current cust_pkg, for future changes my %changed_from; # old pkgnum => new cust_pkg, for past changes +my %supplementals_of; # main pkgnum => arrayref of supplementals foreach my $cust_pkg ( @packages ) { my %hash = $cust_pkg->hash; @@ -190,18 +193,33 @@ foreach my $cust_pkg ( @packages ) { $cust_pkg->{'_pkgpart'} = new FS::part_pkg \%part_pkg; if ( $cust_pkg->change_to_pkgnum ) { $change_to_from{$cust_pkg->change_to_pkgnum} = $cust_pkg; + $is_anything_hidden = 1; } if ( $cust_pkg->change_pkgnum ) { $changed_from{$cust_pkg->change_pkgnum} = $cust_pkg; + $is_anything_hidden = 1; + } + if ( $cust_pkg->main_pkgnum ) { + $supplementals_of{$cust_pkg->main_pkgnum} ||= []; + push @{ $supplementals_of{$cust_pkg->main_pkgnum} }, $cust_pkg; + $is_anything_hidden = 1; } } # filter out hidden package changes -if ( keys %change_to_from or keys %changed_from ) { +if ( $is_anything_hidden ) { my @displayable_packages; foreach my $cust_pkg (@packages) { - if ( exists( $change_to_from{$cust_pkg->pkgnum} ) ) { + # if this package has any supplemental packages, it should remember them + $cust_pkg->set('_supplemental', $supplementals_of{$cust_pkg->pkgnum}); + + if ( $cust_pkg->main_pkgnum ) { + + # it's a supplemental package of something else, and shouldn't be on the + # root list + + } elsif ( exists( $change_to_from{$cust_pkg->pkgnum} ) ) { # $cust_pkg is an ordered, not-yet-active package change target my $change_from = $change_to_from{ $cust_pkg->pkgnum }; @@ -217,7 +235,9 @@ if ( keys %change_to_from or keys %changed_from ) { $changed_to->set('changed_from_pkg', $cust_pkg); } else { + push @displayable_packages, $cust_pkg; + } } @@ -252,7 +272,7 @@ $num_old_packages -= scalar(@packages); # don't include supplemental packages in this list; they'll be found from # their main packages # (as will change-target packages) -@packages = grep !$_->main_pkgnum, @packages; +####@packages = grep !$_->main_pkgnum, @packages; foreach my $cust_pkg ( @packages ) { $cust_pkg->{'_cust_pkg_discount_active'} = diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html index 4b56e6fc4..8aa64039c 100644 --- a/httemplate/view/cust_main/packages/package.html +++ b/httemplate/view/cust_main/packages/package.html @@ -1,7 +1,6 @@ -<TD CLASS="inv package" BGCOLOR="<% $bgcolor %>" VALIGN="top" <%$style%>> +<TD CLASS="inv package" BGCOLOR="<% $bgcolor %>" VALIGN="top"> + <% join('', @marker ) %> <TABLE CLASS="inv package"> - - <TR> <TD COLSPAN=2> <% $opt{before_pkg_callback} @@ -107,7 +106,7 @@ % ) { ( <%pkg_event_link($cust_pkg)%> ) % } -% } #!$supplemental +% } # a canceled recurring package, or else no_links is in effect </FONT> </TD> @@ -297,6 +296,7 @@ </TABLE> % } + <% join('', map '</DIV>', @marker ) %> </TD> <%init> @@ -317,16 +317,12 @@ my $statedefault = $opt{'statedefault'} # if this package is somehow special my $supplemental = $opt{'supplemental'} || 0; my $change_from = $opt{'change_from'} || 0; -my $style = ''; -if ( $supplemental or $change_from ) { - $style = 'border-left-width: '.($supplemental + $change_from)*30 . 'px; '. - 'border-color: '; - if ( $supplemental ) { - $style .= '#bbbbff'; - } elsif ( $change_from ) { - $style .= '#bbffbb'; - } - $style = qq!STYLE="$style"!; +my @marker; +if ( $supplemental ) { + push @marker, '<DIV CLASS="package-marker-supplemental">'; +} +if ( $change_from ) { + push @marker, '<DIV CLASS="package-marker-change_from">'; } $cust_pkg->pkgnum =~ /^(\d+)$/; diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html index fe9f283c7..490f09c12 100755 --- a/httemplate/view/cust_main/packages/section.html +++ b/httemplate/view/cust_main/packages/section.html @@ -71,9 +71,11 @@ <& .packagerow, $cust_pkg->change_to_pkg, %iopt, 'change_from' => 1 &> % } % # include supplemental packages if any -% $iopt{'supplemental'} = ($iopt{'supplemental'} || 0) + 1; -% foreach my $supp_pkg ($cust_pkg->supplemental_pkgs) { - <& .packagerow, $supp_pkg, %iopt &> +% if ( $cust_pkg->_supplemental ) { +% $iopt{'supplemental'} = ($iopt{'supplemental'} || 0) + 1; +% foreach my $supp_pkg (@{ $cust_pkg->_supplemental }) { + <& .packagerow, $supp_pkg, %iopt &> +% } % } </%def> <%shared> diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html index 81156c927..7e125f72e 100644 --- a/httemplate/view/cust_main/packages/status.html +++ b/httemplate/view/cust_main/packages/status.html @@ -44,11 +44,11 @@ </TR> % } % -% } else { +% } 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->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 ) %> @@ -79,7 +79,7 @@ % } else { <% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %> % } -% } +% } <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %> @@ -97,7 +97,10 @@ <% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %> <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %> -% if ( !$supplemental && ! $opt{no_links} && !$change_from ) { +% # Status changes for suspended packages: can unsuspend, future-unsuspend, +% # or future-change. If this package is a future change or is supplemental +% # disable them all. +% if ( !$supplemental && ! $opt{no_links} && !$change_from ) { <TR> <TD COLSPAN=<%$opt{colspan}%>> <FONT SIZE=-1> @@ -203,7 +206,7 @@ <% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %> -% } else { +% } else { # recurring package % % my $num_cust_svc = $cust_pkg->num_cust_svc; % my $summarize = $opt{'cust_pkg-large_pkg_size'} > 0 @@ -259,7 +262,11 @@ <% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %> <% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %> -% if ( $part_pkg->freq and !$supplemental && ! $opt{no_links} ) { +% # Status changes for active recurring packages. If it has a future +% # package change scheduled, let that be modified. If it's supplemental, +% # then that's the only allowed action. Otherwise allow suspend, future +% # suspend, do-not-suspend, and immediate and future cancel. +% if ( $part_pkg->freq and ! $opt{no_links} ) { <TR> <TD COLSPAN=<%$opt{colspan}%>> @@ -277,27 +284,29 @@ % } % } +% if ( !$supplemental ) { % # suspension actions--always available -% 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('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 ( $change_from or $cust_pkg->change_to_pkgnum ) { -% # you can't cancel the package while in this state -% } else { # the normal case: links to cancel the package - <BR> -% if ( $curuser->access_right('Cancel customer package immediately') ) { - ( <% pkg_cancel_link($cust_pkg) %> ) +% if ( $change_from or $cust_pkg->change_to_pkgnum ) { +% # you can't cancel the package while in this state +% } else { # the normal case: links to cancel the package + <BR> +% 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) %> ) +% } % } -% if ( $curuser->access_right('Cancel customer package later') ) { - ( <% pkg_expire_link($cust_pkg) %> ) -% } % } <FONT> |