summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2012-10-27 16:09:24 -0700
committerMark Wells <mark@freeside.biz>2012-10-27 16:09:24 -0700
commitdbae615569712c6f392dfd6cc1930f9d93340e31 (patch)
treee502e86cebfb49e2d5f735e21d3083c0e56756a2 /FS
parenteccc8de2366e2e004a37761b8da2b447ec861ecb (diff)
pkgpart in invoice templates, #19907
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/Template_Mixin.pm36
-rw-r--r--FS/FS/cust_bill_pkg.pm23
-rw-r--r--FS/FS/cust_bill_pkg_display.pm48
3 files changed, 72 insertions, 35 deletions
diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm
index 146e95f..025e0d1 100644
--- a/FS/FS/Template_Mixin.pm
+++ b/FS/FS/Template_Mixin.pm
@@ -821,6 +821,7 @@ sub print_generic {
ext_description => [],
};
$detail->{'ref'} = $line_item->{'pkgnum'};
+ $detail->{'pkgpart'} = $line_item->{'pkgpart'};
$detail->{'quantity'} = 1;
$detail->{'section'} = $multisection ? $previous_section
: $default_section;
@@ -917,6 +918,7 @@ sub print_generic {
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'});
@@ -1224,6 +1226,10 @@ sub print_generic {
} } @discounts_avail;
}
+ # debugging hook: call this with 'diag' => 1 to just get a hash of
+ # the invoice variables
+ return \%invoice_data if ( $params{'diag'} );
+
# All sections and items are built; now fill in templates.
my @includelist = ();
push @includelist, 'summary' if $summarypage;
@@ -1662,6 +1668,13 @@ sub _items_sections {
$not_tax{$section} = 1
unless $cust_bill_pkg->pkgnum == 0;
+ # there's actually a very important piece of logic buried in here:
+ # incrementing $late_subtotal{$section} CREATES
+ # $late_subtotal{$section}. keys(%late_subtotal) is later used
+ # to define the list of late sections, and likewise keys(%subtotal).
+ # When _items_cust_bill_pkg is called to generate line items for
+ # real, it will be called with 'section' => $section for each
+ # of these.
if ( $display->post_total && !$summarypage ) {
if (! $type || $type eq 'S') {
$late_subtotal{$section} += $cust_bill_pkg->setup
@@ -2111,7 +2124,7 @@ which does something complicated.
Returns a list of hashrefs, each of which may contain:
-pkgnum, description, amount, unit_amount, quantity, _is_setup, and
+pkgnum, description, amount, unit_amount, quantity, pkgpart, _is_setup, and
ext_description, which is an arrayref of detail lines to show below
the package line.
@@ -2167,14 +2180,13 @@ sub _items_cust_bill_pkg {
if $DEBUG > 1;
foreach my $display ( grep { defined($section)
- ? $_->section eq $section
- : 1
- }
- #grep { !$_->summary || !$summary_page } # bunk!
+ ? $_->section eq $section
+ : 1
+ }
grep { !$_->summary || $multisection }
@cust_bill_pkg_display
)
- {
+ {
warn "$me _items_cust_bill_pkg considering cust_bill_pkg_display ".
$display->billpkgdisplaynum. "\n"
@@ -2222,6 +2234,9 @@ sub _items_cust_bill_pkg {
my $cust_pkg = $cust_bill_pkg->cust_pkg;
+ # which pkgpart to show for display purposes?
+ my $pkgpart = $cust_bill_pkg->pkgpart_override || $cust_pkg->pkgpart;
+
# start/end dates for invoice formats that do nonstandard
# things with them
my %item_dates = map { $_ => $cust_bill_pkg->$_ } ('sdate', 'edate');
@@ -2272,7 +2287,7 @@ sub _items_cust_bill_pkg {
$s = {
_is_setup => 1,
description => $description,
- #pkgpart => $part_pkg->pkgpart,
+ pkgpart => $pkgpart,
pkgnum => $cust_bill_pkg->pkgnum,
amount => $cust_bill_pkg->setup,
setup_show_zero => $cust_bill_pkg->setup_show_zero,
@@ -2339,7 +2354,8 @@ sub _items_cust_bill_pkg {
unless ( $cust_pkg->part_pkg->hide_svc_detail
|| $cust_bill_pkg->itemdesc
|| $cust_bill_pkg->hidden
- || $is_summary && $type && $type eq 'U' )
+ || $is_summary && $type && $type eq 'U'
+ )
{
warn "$me _items_cust_bill_pkg adding service details\n"
@@ -2424,7 +2440,7 @@ sub _items_cust_bill_pkg {
} else {
$r = {
description => $description,
- #pkgpart => $part_pkg->pkgpart,
+ pkgpart => $pkgpart,
pkgnum => $cust_bill_pkg->pkgnum,
amount => $amount,
recur_show_zero => $cust_bill_pkg->recur_show_zero,
@@ -2448,7 +2464,7 @@ sub _items_cust_bill_pkg {
} else {
$u = {
description => $description,
- #pkgpart => $part_pkg->pkgpart,
+ pkgpart => $pkgpart,
pkgnum => $cust_bill_pkg->pkgnum,
amount => $amount,
recur_show_zero => $cust_bill_pkg->recur_show_zero,
diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm
index 15750b2..826569b 100644
--- a/FS/FS/cust_bill_pkg.pm
+++ b/FS/FS/cust_bill_pkg.pm
@@ -581,9 +581,10 @@ appropriate FS::cust_bill_pkg_display objects.
Options are passed as a list of name/value pairs. Options are:
-part_pkg: FS::part_pkg object from the
+part_pkg: FS::part_pkg object from this line item's package.
-real_pkgpart: if this line item comes from a bundled package, the pkgpart of the owning package. Otherwise the same as the part_pkg's pkgpart above.
+real_pkgpart: if this line item comes from a bundled package, the pkgpart
+of the owning package. Otherwise the same as the part_pkg's pkgpart above.
=cut
@@ -594,13 +595,19 @@ sub set_display {
my $conf = new FS::Conf;
+ # whether to break this down into setup/recur/usage
my $separate = $conf->exists('separate_usage');
+
my $usage_mandate = $part_pkg->option('usage_mandate', 'Hush!')
|| $cust_pkg->part_pkg->option('usage_mandate', 'Hush!');
# or use the category from $opt{'part_pkg'} if its not bundled?
my $categoryname = $cust_pkg->part_pkg->categoryname;
+ # if we don't have to separate setup/recur/usage, or put this in a
+ # package-specific section, or display a usage summary, then don't
+ # even create one of these. The item will just display in the unnamed
+ # section as a single line plus details.
return $self->set('display', [])
unless $separate || $categoryname || $usage_mandate;
@@ -608,34 +615,46 @@ sub set_display {
my %hash = ( 'section' => $categoryname );
+ # whether to put usage details in a separate section, and if so, which one
my $usage_section = $part_pkg->option('usage_section', 'Hush!')
|| $cust_pkg->part_pkg->option('usage_section', 'Hush!');
+ # whether to show a usage summary line (total usage charges, no details)
my $summary = $part_pkg->option('summarize_usage', 'Hush!')
|| $cust_pkg->part_pkg->option('summarize_usage', 'Hush!');
if ( $separate ) {
+ # create lines for setup and (non-usage) recur, in the main section
push @display, new FS::cust_bill_pkg_display { type => 'S', %hash };
push @display, new FS::cust_bill_pkg_display { type => 'R', %hash };
} else {
+ # display everything in a single line
push @display, new FS::cust_bill_pkg_display
{ type => '',
%hash,
+ # and if usage_mandate is enabled, hide details
+ # (this only works on multisection invoices...)
( ( $usage_mandate ) ? ( 'summary' => 'Y' ) : () ),
};
}
if ($separate && $usage_section && $summary) {
+ # create a line for the usage summary in the main section
push @display, new FS::cust_bill_pkg_display { type => 'U',
summary => 'Y',
%hash,
};
}
+
if ($usage_mandate || ($usage_section && $summary) ) {
$hash{post_total} = 'Y';
}
if ($separate || $usage_mandate) {
+ # show call details for this line item in the usage section.
+ # if usage_mandate is on, this will display below the section subtotal.
+ # this also happens if usage is in a separate section and there's a
+ # summary in the main section, though I'm not sure why.
$hash{section} = $usage_section if $usage_section;
push @display, new FS::cust_bill_pkg_display { type => 'U', %hash };
}
diff --git a/FS/FS/cust_bill_pkg_display.pm b/FS/FS/cust_bill_pkg_display.pm
index a864ec1..d7c1472 100644
--- a/FS/FS/cust_bill_pkg_display.pm
+++ b/FS/FS/cust_bill_pkg_display.pm
@@ -27,26 +27,26 @@ FS::cust_bill_pkg_display - Object methods for cust_bill_pkg_display records
=head1 DESCRIPTION
-An FS::cust_bill_pkg_display object represents line item display information.
-FS::cust_bill_pkg_display inherits from FS::Record. The following fields are
-currently supported:
+An FS::cust_bill_pkg_display object represents an instruction to display a
+line item in a specific invoice section. FS::cust_bill_pkg_display inherits
+from FS::Record and is many-to-one with FS::cust_bill_pkg (invoice line
+items).
-=over 4
-
-=item billpkgdisplaynum
+The following fields are currently supported:
-primary key
-
-=item billpkgnum
+=over 4
-billpkgnum
+=item billpkgdisplaynum - primary key
-=item section
+=item billpkgnum - the line item number (L<FS::cust_bill_pkg> foreign key)
-section
+=item section - the section name where this item should be shown. Defaults
+to the package category name, if there is one.
=cut
+# actually it defaults to null, but then calling ->section will return the
+# category name.
sub section {
my ( $self, $value ) = @_;
if ( defined($value) ) {
@@ -64,17 +64,19 @@ sub section {
}
}
-=item post_total
+=item post_total - 'Y' to have this item shown in a "late" section (below
+the invoice totals).
-post_total
+=item type - Which portion of the item's charges to show in the specified
+position. 'S' to show setup fees (including tax and one-time charge),
+'R' to show the non-usage recurring charge, 'U' to show the usage charge,
+null to show all three as a single amount.
-=item type
-
-type
-
-=item summary
-
-summary
+=item summary - 'Y' to show a usage summary of this line item. This has
+the following effects if type = 'U':
+- The description will always be "Usage charges" rather than the package name.
+- Service labels and usage details (CDRs) are hidden.
+- It will only display on multisection invoices.
=back
@@ -84,7 +86,8 @@ summary
=item new HASHREF
-Creates a new line item display object. To add the record to the database, see L<"insert">.
+Creates a new line item display object. To add the record to the database,
+see L<"insert">.
Note that this stores the hash reference, not a distinct copy of the hash it
points to. You can ask the object for a copy with the I<hash> method.
@@ -155,7 +158,6 @@ sub cust_bill_pkg {
=head1 BUGS
-
=head1 SEE ALSO
L<FS::Record>, L<FS::cust_bill_pkg>, schema.html from the base documentation.