summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorjeff <jeff>2009-07-20 14:26:12 +0000
committerjeff <jeff>2009-07-20 14:26:12 +0000
commit87a986f35b347affed5f1e1ff5c5c7c59ccd4ad1 (patch)
tree00971fb15325dadfa0ddf7030fab4912810f6d0c /FS
parent52d81f0b1f3bc092da71e7f5919d332c4fa012d5 (diff)
bundle bill linked packages into top line total when desired #5724
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/Schema.pm14
-rw-r--r--FS/FS/cust_bill.pm93
-rw-r--r--FS/FS/cust_bill_pkg.pm3
-rw-r--r--FS/FS/cust_main.pm34
-rw-r--r--FS/FS/part_pkg.pm26
-rw-r--r--FS/FS/part_pkg_link.pm8
6 files changed, 134 insertions, 44 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 8b5318421..419e9ac20 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -518,6 +518,7 @@ sub tables_hashref {
'quantity', 'int', 'NULL', '', '', '',
'unitsetup', @money_typen, '', '',
'unitrecur', @money_typen, '', '',
+ 'hidden', 'char', 'NULL', 1, '', '',
],
'primary_key' => 'billpkgnum',
'unique' => [],
@@ -1240,15 +1241,18 @@ sub tables_hashref {
'part_pkg_link' => {
'columns' => [
- 'pkglinknum', 'serial', '', '', '', '',
- 'src_pkgpart', 'int', '', '', '', '',
- 'dst_pkgpart', 'int', '', '', '', '',
- 'link_type', 'varchar', '', $char_d, '', '',
+ 'pkglinknum', 'serial', '', '', '', '',
+ 'src_pkgpart', 'int', '', '', '', '',
+ 'dst_pkgpart', 'int', '', '', '', '',
+ 'link_type', 'varchar', '', $char_d, '', '',
+ 'hidden', 'char', 'NULL', 1, '', '',
],
'primary_key' => 'pkglinknum',
- 'unique' => [ [ 'src_pkgpart', 'dst_pkgpart', 'link_type' ] ],
+ 'unique' => [ [ 'src_pkgpart', 'dst_pkgpart', 'link_type', 'hidden' ] ],
'index' => [ [ 'src_pkgpart' ] ],
},
+ # XXX somewhat borked unique: we don't really want a hidden and unhidden
+ # it turns out we'd prefer to use svc, bill, and invisibill (or something)
'part_pkg_taxclass' => {
'columns' => [
diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm
index 17b88c540..ac0280842 100644
--- a/FS/FS/cust_bill.pm
+++ b/FS/FS/cust_bill.pm
@@ -2793,8 +2793,19 @@ sub _items_cust_bill_pkg {
my $section = $opt{section}->{description} if $opt{section};
my @b = ();
+ my ($s, $r, $u) = ( undef, undef, undef );
foreach my $cust_bill_pkg ( @$cust_bill_pkg )
{
+
+ foreach ( $s, $r, $u ) {
+ if ( $_ && !$cust_bill_pkg->hidden ) {
+ $_->{amount} = sprintf( "%.2f", $_->{amount} ),
+ $_->{unit_amount} = sprintf( "%.2f", $_->{unit_amount} ),
+ push @b, { %$_ };
+ $_ = undef;
+ }
+ }
+
foreach my $display ( grep { defined($section)
? $_->section eq $section
: 1
@@ -2826,18 +2837,25 @@ sub _items_cust_bill_pkg {
my @d = ();
push @d, map &{$escape_function}($_),
$cust_pkg->h_labels_short($self->_date)
- unless $cust_pkg->part_pkg->hide_svc_detail;
+ unless $cust_pkg->part_pkg->hide_svc_detail
+ || $cust_bill_pkg->hidden;
push @d, $cust_bill_pkg->details(%details_opt)
if $cust_bill_pkg->recur == 0;
- push @b, {
- description => $description,
- #pkgpart => $part_pkg->pkgpart,
- pkgnum => $cust_bill_pkg->pkgnum,
- amount => sprintf("%.2f", $cust_bill_pkg->setup),
- unit_amount => sprintf("%.2f", $cust_bill_pkg->unitsetup),
- quantity => $cust_bill_pkg->quantity,
- ext_description => \@d,
+ if ( $cust_bill_pkg->hidden ) {
+ $s->{amount} += $cust_bill_pkg->setup;
+ $s->{unit_amount} += $cust_bill_pkg->unitsetup;
+ push @{ $s->{ext_description} }, @d;
+ } else {
+ $s = {
+ description => $description,
+ #pkgpart => $part_pkg->pkgpart,
+ pkgnum => $cust_bill_pkg->pkgnum,
+ amount => $cust_bill_pkg->setup,
+ unit_amount => $cust_bill_pkg->unitsetup,
+ quantity => $cust_bill_pkg->quantity,
+ ext_description => \@d,
+ };
};
}
@@ -2869,6 +2887,7 @@ sub _items_cust_bill_pkg {
#$cust_bill_pkg->sdate)
unless $cust_pkg->part_pkg->hide_svc_detail
|| $cust_bill_pkg->itemdesc
+ || $cust_bill_pkg->hidden
|| $is_summary;
push @d, $cust_bill_pkg->details(%details_opt)
@@ -2883,17 +2902,45 @@ sub _items_cust_bill_pkg {
$amount = $cust_bill_pkg->usage;
}
- push @b, {
- description => $description,
- #pkgpart => $part_pkg->pkgpart,
- pkgnum => $cust_bill_pkg->pkgnum,
- amount => sprintf("%.2f", $amount),
- unit_amount => sprintf("%.2f", $cust_bill_pkg->unitrecur),
- quantity => $cust_bill_pkg->quantity,
- ext_description => \@d,
- } unless ( $type eq 'U' && ! $amount );
+ if ( !$type || $type eq 'R' ) {
+
+ if ( $cust_bill_pkg->hidden ) {
+ $r->{amount} += $amount;
+ $r->{unit_amount} += $cust_bill_pkg->unitrecur;
+ push @{ $r->{ext_description} }, @d;
+ } else {
+ $r = {
+ description => $description,
+ #pkgpart => $part_pkg->pkgpart,
+ pkgnum => $cust_bill_pkg->pkgnum,
+ amount => $amount,
+ unit_amount => $cust_bill_pkg->unitrecur,
+ quantity => $cust_bill_pkg->quantity,
+ ext_description => \@d,
+ };
+ }
+
+ } elsif ( $amount ) { # && $type eq 'U'
+
+ if ( $cust_bill_pkg->hidden ) {
+ $u->{amount} += $amount;
+ $u->{unit_amount} += $cust_bill_pkg->unitrecur;
+ push @{ $u->{ext_description} }, @d;
+ } else {
+ $u = {
+ description => $description,
+ #pkgpart => $part_pkg->pkgpart,
+ pkgnum => $cust_bill_pkg->pkgnum,
+ amount => $amount,
+ unit_amount => $cust_bill_pkg->unitrecur,
+ quantity => $cust_bill_pkg->quantity,
+ ext_description => \@d,
+ };
+ }
- }
+ }
+
+ } # recurring or usage with recurring charge
} else { #pkgnum tax or one-shot line item (??)
@@ -2918,6 +2965,14 @@ sub _items_cust_bill_pkg {
}
+ foreach ( $s, $r, $u ) {
+ if ( $_ ) {
+ $_->{amount} = sprintf( "%.2f", $_->{amount} ),
+ $_->{unit_amount} = sprintf( "%.2f", $_->{unit_amount} ),
+ push @b, { %$_ };
+ }
+ }
+
@b;
}
diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm
index fbc67c542..abf021845 100644
--- a/FS/FS/cust_bill_pkg.pm
+++ b/FS/FS/cust_bill_pkg.pm
@@ -63,6 +63,8 @@ supported:
=item unitrecur - If not set, defaults to recur
+=item hidden - If set to Y, indicates data should not appear as separate line item on invoice
+
=back
sdate and edate are specified as UNIX timestamps; see L<perlfunc/"time">. Also
@@ -236,6 +238,7 @@ sub check {
|| $self->ut_numbern('edate')
|| $self->ut_textn('itemdesc')
|| $self->ut_textn('itemcomment')
+ || $self->ut_enum('hidden', [ '', 'Y' ])
;
return $error if $error;
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 2957579d7..9d41c4bdf 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -2535,6 +2535,7 @@ sub bill {
'recur' => \$total_recur,
'tax_matrix' => \%taxlisthash,
'time' => $time,
+ 'real_pkgpart' => $real_pkgpart,
'options' => \%options,
);
if ($error) {
@@ -2566,6 +2567,7 @@ sub bill {
} elsif ( $postal_pkg ) {
+ my $real_pkgpart = $postal_pkg->pkgpart;
foreach my $part_pkg ( $postal_pkg->part_pkg->self_and_bill_linked ) {
my %postal_options = %options;
delete $postal_options{cancel};
@@ -2578,6 +2580,7 @@ sub bill {
'recur' => \$total_recur,
'tax_matrix' => \%taxlisthash,
'time' => $time,
+ 'real_pkgpart' => $real_pkgpart,
'options' => \%postal_options,
);
if ($error) {
@@ -2790,7 +2793,7 @@ sub _make_lines {
my (%options) = %{$params{options}};
my $dbh = dbh;
- my $real_pkgpart = $cust_pkg->pkgpart;
+ my $real_pkgpart = $params{real_pkgpart};
my %hash = $cust_pkg->hash;
my $old_cust_pkg = new FS::cust_pkg \%hash;
@@ -2958,6 +2961,7 @@ sub _make_lines {
'unitrecur' => $unitrecur,
'quantity' => $cust_pkg->quantity,
'details' => \@details,
+ 'hidden' => $part_pkg->hidden,
};
if ( $part_pkg->option('recur_temporality', 1) eq 'preceding' ) {
@@ -2981,7 +2985,7 @@ sub _make_lines {
###
my $error =
- $self->_handle_taxes($part_pkg, $taxlisthash, $cust_bill_pkg, $cust_pkg, $options{invoice_time});
+ $self->_handle_taxes($part_pkg, $taxlisthash, $cust_bill_pkg, $cust_pkg, $options{invoice_time}, $real_pkgpart);
return $error if $error;
push @$cust_bill_pkgs, $cust_bill_pkg;
@@ -3001,6 +3005,7 @@ sub _handle_taxes {
my $cust_bill_pkg = shift;
my $cust_pkg = shift;
my $invoice_time = shift;
+ my $real_pkgpart = shift;
my %cust_bill_pkg = ();
my %taxes = ();
@@ -3091,20 +3096,29 @@ sub _handle_taxes {
}
my @display = ();
- if ( $conf->exists('separate_usage') ) {
+ if ( $conf->exists('separate_usage') || $cust_bill_pkg->hidden ) {
+
+ my $temp_pkg = new FS::cust_pkg { pkgpart => $real_pkgpart };
+ my %hash = $cust_bill_pkg->hidden # maybe for all bill linked?
+ ? ( 'section' => $temp_pkg->part_pkg->categoryname )
+ : ();
+
my $section = $cust_pkg->part_pkg->option('usage_section', 'Hush!');
my $summary = $cust_pkg->part_pkg->option('summarize_usage', 'Hush!');
- push @display, new FS::cust_bill_pkg_display { type => 'S' };
- push @display, new FS::cust_bill_pkg_display { type => 'R' };
- push @display, new FS::cust_bill_pkg_display { type => 'U',
- section => $section
- };
+ push @display, new FS::cust_bill_pkg_display { type => 'S', %hash };
+ push @display, new FS::cust_bill_pkg_display { type => 'R', %hash };
+
if ($section && $summary) {
- $display[2]->post_total('Y');
push @display, new FS::cust_bill_pkg_display { type => 'U',
summary => 'Y',
- }
+ %hash,
+ };
+ $hash{post_total} = 'Y';
}
+
+ $hash{section} = $section if $conf->exists('separate_usage');
+ push @display, new FS::cust_bill_pkg_display { type => 'U', %hash };
+
}
$cust_bill_pkg->set('display', \@display);
diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm
index ba80475eb..3ee9e7f01 100644
--- a/FS/FS/part_pkg.pm
+++ b/FS/FS/part_pkg.pm
@@ -917,10 +917,12 @@ sub svc_part_pkg_link {
sub _part_pkg_link {
my( $self, $type ) = @_;
- qsearch('part_pkg_link', { 'src_pkgpart' => $self->pkgpart,
- 'link_type' => $type,
- }
- );
+ qsearch({ table => 'part_pkg_link',
+ hashref => { 'src_pkgpart' => $self->pkgpart,
+ 'link_type' => $type,
+ },
+ order_by => "ORDER BY hidden",
+ });
}
sub self_and_bill_linked {
@@ -928,12 +930,18 @@ sub self_and_bill_linked {
}
sub _self_and_linked {
- my( $self, $type ) = @_;
+ my( $self, $type, $hidden ) = @_;
+ $hidden ||= '';
+
+ my @result = ();
+ foreach ( ( $self, map { $_->dst_pkg->_self_and_linked($type, $_->hidden) }
+ $self->_part_pkg_link($type) ) )
+ {
+ $_->hidden($hidden) if $hidden;
+ push @result, $_;
+ }
- ( $self,
- map { $_->dst_pkg->_self_and_linked($type) }
- $self->_part_pkg_link($type)
- );
+ (@result);
}
=item part_pkg_taxoverride [ CLASS ]
diff --git a/FS/FS/part_pkg_link.pm b/FS/FS/part_pkg_link.pm
index f51736055..fb7a8d387 100644
--- a/FS/FS/part_pkg_link.pm
+++ b/FS/FS/part_pkg_link.pm
@@ -51,6 +51,11 @@ Destination package (see L<FS::part_pkg>)
Link type - currently, "bill" (source package bills a line item from target
package), or "svc" (source package includes services from target package).
+=item hidden
+
+Flag indicating that this subpackage should be felt, but not seen as an invoice
+line item when set to 'Y'
+
=back
=head1 METHODS
@@ -114,7 +119,8 @@ sub check {
$self->ut_numbern('pkglinknum')
|| $self->ut_foreign_key('src_pkgpart', 'part_pkg', 'pkgpart')
|| $self->ut_foreign_key('dst_pkgpart', 'part_pkg', 'pkgpart')
- || $self->ut_text('link_type', [ 'bill', 'svc' ] )
+ || $self->ut_enum('link_type', [ 'bill', 'svc' ] )
+ || $self->ut_enum('hidden', [ '', 'Y' ] )
;
return $error if $error;