X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_bill.pm;h=2cf5b99f3468643e2876d28e52b6f2946a1f78e6;hb=44b5d849d7fb3af5ea1e2812097126633add0fd4;hp=c404b8b01f7a3d756e8f71dd09fde360470eae4b;hpb=3014ab2fcc6acb37892a43539b304c931a118942;p=freeside.git diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index c404b8b01..2cf5b99f3 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -226,7 +226,12 @@ Returns the line items (see L) for this invoice. sub cust_bill_pkg { my $self = shift; - qsearch( 'cust_bill_pkg', { 'invnum' => $self->invnum } ); + qsearch( + { 'table' => 'cust_bill_pkg', + 'hashref' => { 'invnum' => $self->invnum }, + 'order_by' => 'ORDER BY billpkgnum', + } + ); } =item cust_pkg @@ -1626,6 +1631,8 @@ L and L for conversion functions. cid - +unsquelch_cdr - overrides any per customer cdr squelching when true + =cut sub print_generic { @@ -1992,9 +1999,11 @@ sub print_generic { my $adjust_section = { 'description' => 'Credits, Payments, and Adjustments', 'subtotal' => 0 }; # adjusted below + my $unsquelched = $params{unsquelch_cdr} || $cust_main->squelch_cdr ne 'Y'; my $multisection = $conf->exists('invoice_sections', $cust_main->agentnum); + my $late_sections = []; if ( $multisection ) { - push @sections, $self->_items_sections; + push @sections, $self->_items_sections( $late_sections ); }else{ push @sections, { 'description' => '', 'subtotal' => '' }; } @@ -2033,7 +2042,7 @@ sub print_generic { push @buf, ['','']; } - foreach my $section (@sections) { + foreach my $section (@sections, @$late_sections) { $section->{'subtotal'} = $other_money_char. sprintf('%.2f', $section->{'subtotal'}) @@ -2049,6 +2058,8 @@ sub print_generic { $options{'section'} = $section if $multisection; $options{'format'} = $format; $options{'escape_function'} = $escape_function; + $options{'format_function'} = sub { () } unless $unsquelched; + $options{'unsquelched'} = $unsquelched; foreach my $line_item ( $self->_items_pkg(%options) ) { my $detail = { @@ -2156,8 +2167,8 @@ sub print_generic { ) ); if ( $multisection ) { - $adjust_section->{'pretotal'} = 'New charges total '. - $total->{'total_amount'}; + $adjust_section->{'pretotal'} = 'New charges total '. $other_money_char. + sprintf('%.2f', $self->charged ); }else{ push @total_items, $total; } @@ -2269,6 +2280,11 @@ sub print_generic { } } + if ( $multisection ) { + push @sections, @$late_sections + if $unsquelched; + } + $invoice_lines = 0; my $wasfunc = 0; foreach ( grep /invoice_lines\(\d*\)/, @invoice_template ) { #kludgy @@ -2376,12 +2392,17 @@ when emailing the invoice as part of a multipart/related MIME email. =cut sub print_html { - my( $self, $today, $template, $cid ) = @_; + my $self = shift; + my %params; + if ( ref $_[0] ) { + %params = %{ shift() }; + }else{ + $params{'time'} = shift; + $params{'template'} = shift; + $params{'cid'} = shift; + } - my %params = ( 'format' => 'html' ); - $params{'time'} = $today if $today; - $params{'template'} = $template if $template; - $params{'cid'} = $cid if $cid; + $params{'format'} = 'html'; $self->print_generic( %params ); } @@ -2528,24 +2549,51 @@ sub invnum_date_pretty { sub _items_sections { my $self = shift; + my $late = shift; my %s = (); - foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) { + my %l = (); + + foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) + { if ( $cust_bill_pkg->pkgnum > 0 ) { - my $desc = $cust_bill_pkg->part_pkg->categoryname; + my $desc = $cust_bill_pkg->section; + my $dup_desc = $cust_bill_pkg->duplicate_section; + + if ($cust_bill_pkg->duplicate) { + $s{$dup_desc} += $cust_bill_pkg->setup + if ( $cust_bill_pkg->setup != 0 ); - $s{$desc} += $cust_bill_pkg->setup - if ( $cust_bill_pkg->setup != 0 ); + $s{$dup_desc} += $cust_bill_pkg->recur + if ( $cust_bill_pkg->recur != 0 ); + } + + if ( $cust_bill_pkg->post_total ) { + $l{$desc} += $cust_bill_pkg->setup + if ( $cust_bill_pkg->setup != 0 ); - $s{$desc} += $cust_bill_pkg->recur - if ( $cust_bill_pkg->recur != 0 ); + $l{$desc} += $cust_bill_pkg->recur + if ( $cust_bill_pkg->recur != 0 ); + + } else { + $s{$desc} += $cust_bill_pkg->setup + if ( $cust_bill_pkg->setup != 0 ); + + $s{$desc} += $cust_bill_pkg->recur + if ( $cust_bill_pkg->recur != 0 ); + } } } + push @$late, map { { 'description' => $_, + 'subtotal' => $l{$_}, + 'post_total' => 1, + } } sort keys %l; + map { {'description' => $_, 'subtotal' => $s{$_}} } sort keys %s; } @@ -2600,11 +2648,12 @@ sub _items_previous { sub _items_pkg { my $self = shift; my %options = @_; - my $section = delete $options{'section'}; + my $section = $options{'section'}; + my $desc = $section->{'description'}; my @cust_bill_pkg = grep { $_->pkgnum && ( defined($section) - ? $_->part_pkg->categoryname eq $section->{'description'} + ? ( $_->section eq $desc || $_->duplicate_section eq $desc ) : 1 ) } $self->cust_bill_pkg; @@ -2633,9 +2682,13 @@ sub _items_cust_bill_pkg { my $format = $opt{format} || ''; my $escape_function = $opt{escape_function} || sub { shift }; + my $format_function = $opt{format_function} || ''; + my $unsquelched = $opt{unsquelched} || ''; my @b = (); - foreach my $cust_bill_pkg ( @$cust_bill_pkg ) { + my $last_pkgnum = ''; + foreach my $cust_bill_pkg ( @$cust_bill_pkg ) + { my $cust_pkg = $cust_bill_pkg->cust_pkg; @@ -2643,6 +2696,7 @@ sub _items_cust_bill_pkg { my %details_opt = ( 'format' => $format, 'escape_function' => $escape_function, + 'format_function' => $format_function, ); if ( $cust_bill_pkg->pkgnum > 0 ) { @@ -2666,34 +2720,62 @@ sub _items_cust_bill_pkg { quantity => $cust_bill_pkg->quantity, ext_description => \@d, }; + + $last_pkgnum = ''; + } if ( $cust_bill_pkg->recur != 0 ) { - my $description = $desc; + my $is_summary = + ( $cust_bill_pkg->duplicate && + $opt{section}->{description} ne $cust_bill_pkg->section + ); + my $description = $is_summary ? "Usage charges" : $desc; + unless ( $conf->exists('disable_line_item_date_ranges') ) { - $desc .= " (" . time2str("%x", $cust_bill_pkg->sdate). - " - ". time2str("%x", $cust_bill_pkg->edate). ")"; + $description .= " (" . time2str("%x", $cust_bill_pkg->sdate). + " - ". time2str("%x", $cust_bill_pkg->edate). ")"; } #at least until cust_bill_pkg has "past" ranges in addition to #the "future" sdate/edate ones... see #3032 - my @d = map &{$escape_function}($_), - $cust_pkg->h_labels_short($self->_date); + my @d = (); + push @d, map &{$escape_function}($_), + $cust_pkg->h_labels_short($self->_date) #$cust_bill_pkg->edate, #$cust_bill_pkg->sdate), - push @d, $cust_bill_pkg->details(%details_opt); + unless ($cust_bill_pkg->pkgnum eq $last_pkgnum); - push @b, { - description => $description, - #pkgpart => $part_pkg->pkgpart, - pkgnum => $cust_bill_pkg->pkgnum, - amount => sprintf("%.2f", $cust_bill_pkg->recur), - unit_amount => sprintf("%.2f", $cust_bill_pkg->unitrecur), - quantity => $cust_bill_pkg->quantity, - ext_description => \@d, - }; + @d = () if ($cust_bill_pkg->itemdesc || $is_summary); + push @d, $cust_bill_pkg->details(%details_opt) + unless $is_summary; + + if ($cust_bill_pkg->pkgnum eq $last_pkgnum) { + + $b[$#b]->{amount} = + sprintf("%.2f", $b[$#b]->{amount} + $cust_bill_pkg->recur); + push @{$b[$#b]->{ext_description}}, @d; + + }else{ + push @b, { + description => $description, + #pkgpart => $part_pkg->pkgpart, + pkgnum => $cust_bill_pkg->pkgnum, + amount => sprintf("%.2f", $cust_bill_pkg->recur), + unit_amount => sprintf("%.2f", $cust_bill_pkg->unitrecur), + quantity => $cust_bill_pkg->quantity, + ext_description => \@d, + }; + + } + + if ($conf->exists('separate_usage') && $cust_bill_pkg->type ne 'U') { + $last_pkgnum = ''; + }else{ + $last_pkgnum = $cust_bill_pkg->pkgnum; + } } } else { #pkgnum tax or one-shot line item (??) @@ -2713,6 +2795,8 @@ sub _items_cust_bill_pkg { }; } + $last_pkgnum = ''; + } }