summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/Conf.pm16
-rw-r--r--FS/FS/Template_Mixin.pm91
-rw-r--r--FS/FS/Upgrade.pm12
3 files changed, 68 insertions, 51 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index c0955b115..8f4d05b3c 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -1561,11 +1561,19 @@ and customer address. Include units.',
},
{
- 'key' => 'invoice_sections_by_location',
+ 'key' => 'invoice_sections_method',
'section' => 'invoicing',
- 'description' => 'Divide invoice into sections according to service location. Currently, this overrides sectioning by package category.',
- 'type' => 'checkbox',
- 'per_agent' => 1,
+ 'description' => 'How to group line items on multi-section invoices.',
+ 'type' => 'select',
+ 'select_enum' => [ qw(category location) ],
+ },
+
+ {
+ 'key' => 'summary_subtotals_method',
+ 'section' => 'invoicing',
+ 'description' => 'How to group line items when calculating summary subtotals. By default, it will be the same method used for grouping invoice sections.',
+ 'type' => 'select',
+ 'select_enum' => [ qw(category location) ],
},
#quotations seem broken-ish with sections ATM?
diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm
index 07d203036..06b3d9e7b 100644
--- a/FS/FS/Template_Mixin.pm
+++ b/FS/FS/Template_Mixin.pm
@@ -668,6 +668,8 @@ sub print_generic {
$last_bill_balance += $delta;
}
+ $last_bill_balance = sprintf("%.2f", $last_bill_balance);
+
warn sprintf("LAST BILL: INVNUM %d, DATE %s, BALANCE %.2f\n\n",
$last_bill->invnum,
$self->time2str_local('%D', $last_bill->_date),
@@ -924,7 +926,7 @@ sub print_generic {
# we haven't yet changed the template to take advantage of that, so for
# now, treat them as mutually exclusive.
my %section_method = ( by_category => 1 );
- if ( $conf->exists($tc.'sections_by_location') ) {
+ if ( $conf->config($tc.'sections_method') eq 'location' ) {
%section_method = ( by_location => 1 );
}
my ($early, $late) =
@@ -982,6 +984,36 @@ sub print_generic {
sprintf('%.2f', sum( @charges ) || 0);
}
+ # start setting up summary subtotals
+ my @summary_subtotals;
+ my $method = $conf->config('summary_subtotals_method');
+ if ( $method and $method ne $conf->config($tc.'sections_method') ) {
+ # then re-section them by the correct method
+ my %section_method = ( by_category => 1 );
+ if ( $conf->config('summary_subtotals_method') eq 'location' ) {
+ %section_method = ( by_location => 1 );
+ }
+ my ($early, $late) =
+ $self->_items_sections( 'summary' => $summarypage,
+ 'escape' => $escape_function_nonbsp,
+ 'extra_sections' => $extra_sections,
+ 'format' => $format,
+ %section_method
+ );
+ foreach ( @$early ) {
+ next if $_->{subtotal} == 0;
+ $_->{subtotal} = $other_money_char.sprintf('%.2f', $_->{subtotal});
+ push @summary_subtotals, $_;
+ }
+ } else {
+ # subtotal sectioning is the same as for the actual invoice sections
+ @summary_subtotals = @sections;
+ }
+
+ # Hereafter, push sections to both @sections and @summary_subtotals
+ # if they belong in both places (e.g. tax section). Late sections are
+ # never in @summary_subtotals.
+
# previous invoice balances in the Previous Charges section if there
# is one, otherwise in the main detail section
# (except if summary_only is enabled, don't show them at all)
@@ -1084,31 +1116,6 @@ sub print_generic {
warn "$me adding line item $line_item\n"
if $DEBUG > 1;
- # this is silly
- #my $detail = {
- # ext_description => [],
- #};
- #$detail->{'ref'} = $line_item->{'pkgnum'};
- #$detail->{'pkgpart'} = $line_item->{'pkgpart'};
- #$detail->{'quantity'} = $line_item->{'quantity'};
- #$detail->{'section'} = $section;
- #$detail->{'description'} = &$escape_function($line_item->{'description'});
- #if ( exists $line_item->{'ext_description'} ) {
- # @{$detail->{'ext_description'}} = @{$line_item->{'ext_description'}};
- #}
- #$detail->{'amount'} = ( $old_latex ? '' : $money_char ).
- # $line_item->{'amount'};
- #if ( exists $line_item->{'unit_amount'} ) {
- # $detail->{'unit_amount'} = ( $old_latex ? '' : $money_char ).
- # $line_item->{'unit_amount'};
- #}
- #$detail->{'product_code'} = $line_item->{'pkgpart'} || 'N/A';
-
- #$detail->{'sdate'} = $line_item->{'sdate'};
- #$detail->{'edate'} = $line_item->{'edate'};
- #$detail->{'seconds'} = $line_item->{'seconds'};
- #$detail->{'svc_label'} = $line_item->{'svc_label'};
- #$detail->{'usage_item'} = $line_item->{'usage_item'};
$line_item->{'ref'} = $line_item->{'pkgnum'};
$line_item->{'product_code'} = $line_item->{'pkgpart'} || 'N/A'; # mt()?
$line_item->{'section'} = $section;
@@ -1145,6 +1152,7 @@ sub print_generic {
# if there's anything in the Previous Charges section, prepend it to the list
if ( $pr_total and $previous_section ne $default_section ) {
unshift @sections, $previous_section;
+ # but not @summary_subtotals
}
warn "$me adding taxes\n"
@@ -1197,8 +1205,11 @@ sub print_generic {
sprintf('%.2f', $taxtotal);
$tax_section->{'pretotal'} = 'New charges sub-total '.
$total->{'total_amount'};
- push @sections, $tax_section if $taxtotal;
- }else{
+ if ( $taxtotal ) {
+ push @sections, $tax_section;
+ push @summary_subtotals, $tax_section;
+ }
+ } else {
unshift @total_items, $total;
}
}
@@ -1350,6 +1361,8 @@ sub print_generic {
sprintf('%.2f', $adjusttotal);
push @sections, $adjust_section
unless $adjust_section->{sort_weight};
+ # do not summarize; adjustments there are shown according to
+ # different rules
}
# create Balance Due message
@@ -1428,7 +1441,7 @@ sub print_generic {
'no_subtotal' => 1,
};
- push @sections, $discount_section;
+ push @sections, $discount_section; # do not summarize
push @detail_items, map { +{
'ref' => '', #should this be something else?
'section' => $discount_section,
@@ -1438,23 +1451,7 @@ sub print_generic {
} } @discounts_avail;
}
- my @summary_subtotals;
- # the templates say "$_->{tax_section} || !$_->{summarized}"
- # except 'summarized' is only true when tax_section is true, so this
- # is always true, so what's the deal?
- foreach my $s (@sections) {
- # not to include in the "summary of new charges" block:
- # finance charges, adjustments, previous charges,
- # and itemized phone usage sections
- if ( $s eq $adjust_section or
- ($s eq $previous_section and $s ne $default_section) or
- ($invoice_data{'finance_section'} and
- $invoice_data{'finance_section'} eq $s->{description}) or
- $s->{'description'} =~ /^\d+ $/ ) {
- next;
- }
- push @summary_subtotals, $s;
- }
+ # not adding any more sections after this
$invoice_data{summary_subtotals} = \@summary_subtotals;
# usage subtotals
@@ -1462,7 +1459,7 @@ sub print_generic {
and $self->can('_items_usage_class_summary') ) {
my @usage_subtotals = $self->_items_usage_class_summary(escape => $escape_function);
if ( @usage_subtotals ) {
- unshift @sections, $usage_subtotals[0]->{section};
+ unshift @sections, $usage_subtotals[0]->{section}; # do not summarize
unshift @detail_items, @usage_subtotals;
}
}
diff --git a/FS/FS/Upgrade.pm b/FS/FS/Upgrade.pm
index ce0e328fd..cb16ead80 100644
--- a/FS/FS/Upgrade.pm
+++ b/FS/FS/Upgrade.pm
@@ -113,6 +113,18 @@ If you need to continue using the old Form 477 report, turn on the
'old_fcc_report' configuration option.
";
}
+
+ # boolean invoice_sections_by_location option is now
+ # invoice_sections_method = 'location'
+ my @invoice_sections_confs =
+ qsearch('conf', { 'name' => { op=>'LIKE', value=>'%sections_by_location' } });
+ foreach my $c (@invoice_sections_confs) {
+ $c->name =~ /^(\w+)sections_by_location$/;
+ $conf->delete($c->name);
+ my $newname = $1.'sections_method';
+ $conf->set($newname, 'location');
+ }
+
}
sub upgrade_overlimit_groups {