X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_bill.pm;h=a0885f1d43a56876e7f56e63cf47fe6bcfc741d8;hb=f274814c7cde3681578ca594a2b00475370e4c92;hp=961d86e9efbb7bfcb4dbac21bbb96d49a5a0c3ae;hpb=e3e8d316738336108b9b9af65d9adeb2ed085696;p=freeside.git diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 961d86e9e..a0885f1d4 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -96,6 +96,18 @@ L and L for conversion functions. =item charged - amount of this invoice +=item invoice_terms - optional terms override for this specific invoice + +=back + +Customer info at invoice generation time + +=over 4 + +=item previous_balance + +=item billing_balance + =back Deprecated @@ -521,6 +533,7 @@ Returns all payment applications (see L) for this invoice. sub cust_bill_pay { my $self = shift; + map { $_ } #return $self->num_cust_bill_pay unless wantarray; sort { $a->_date <=> $b->_date } qsearch( 'cust_bill_pay', { 'invnum' => $self->invnum } ); } @@ -535,6 +548,7 @@ Returns all applied credits (see L) for this invoice. sub cust_credited { my $self = shift; + map { $_ } #return $self->num_cust_credit_bill unless wantarray; sort { $a->_date <=> $b->_date } qsearch( 'cust_credit_bill', { 'invnum' => $self->invnum } ) ; @@ -553,6 +567,7 @@ with matching pkgnum. sub cust_bill_pay_pkgnum { my( $self, $pkgnum ) = @_; + map { $_ } #return $self->num_cust_bill_pay_pkgnum($pkgnum) unless wantarray; sort { $a->_date <=> $b->_date } qsearch( 'cust_bill_pay', { 'invnum' => $self->invnum, 'pkgnum' => $pkgnum, @@ -562,6 +577,8 @@ sub cust_bill_pay_pkgnum { =item cust_credited_pkgnum PKGNUM +=item cust_credit_bill_pkgnum PKGNUM + Returns all applied credits (see L) for this invoice with matching pkgnum. @@ -569,6 +586,7 @@ with matching pkgnum. sub cust_credited_pkgnum { my( $self, $pkgnum ) = @_; + map { $_ } #return $self->num_cust_credit_bill_pkgnum($pkgnum) unless wantarray; sort { $a->_date <=> $b->_date } qsearch( 'cust_credit_bill', { 'invnum' => $self->invnum, 'pkgnum' => $pkgnum, @@ -576,6 +594,10 @@ sub cust_credited_pkgnum { ); } +sub cust_credit_bill_pkgnum { + shift->cust_credited_pkgnum(@_); +} + =item tax Returns the tax amount (see L) for this invoice. @@ -1065,7 +1087,7 @@ sub send { } $invoice_from = $opt->{'invoice_from'}; $balance_over = $opt->{'balance_over'} if $opt->{'balance_over'}; - $notice_name = $opt=>{'notice_name'}; + $notice_name = $opt->{'notice_name'}; } else { $template = scalar(@_) ? shift : ''; if ( scalar(@_) && $_[0] ) { @@ -2345,8 +2367,8 @@ sub print_generic { # my( $cr_total, @cr_cust_credit ) = $self->cust_credit; #credits #my $balance_due = $self->owed + $pr_total - $cr_total; my $balance_due = $self->owed + $pr_total; - $invoice_data{'true_previous_balance'} = sprintf("%.2f", $self->previous_balance); - $invoice_data{'balance_adjustments'} = sprintf("%.2f", $self->previous_balance - $self->billing_balance); + $invoice_data{'true_previous_balance'} = sprintf("%.2f", ($self->previous_balance || 0) ); + $invoice_data{'balance_adjustments'} = sprintf("%.2f", ($self->previous_balance || 0) - ($self->billing_balance || 0) ); $invoice_data{'previous_balance'} = sprintf("%.2f", $pr_total); $invoice_data{'balance'} = sprintf("%.2f", $balance_due); @@ -2979,10 +3001,10 @@ sub _translate_old_latex_format { $line_item_line =~ s/\$(\w+)/'. \$_tr_line->{$1}. '/g; push @template, " \$OUT .= '$line_item_line';"; } - + push @template, '}', '--@]'; - + #' doh, gvim } elsif ( $line =~ /^%%TotalDetails\s*$/ ) { push @template, '[@--', @@ -3016,11 +3038,12 @@ sub _translate_old_latex_format { sub terms { my $self = shift; - #check for an invoice- specific override (eventually) + #check for an invoice-specific override + return $self->invoice_terms if $self->invoice_terms; #check for a customer- specific override - return $self->cust_main->invoice_terms - if $self->cust_main->invoice_terms; + my $cust_main = $self->cust_main; + return $cust_main->invoice_terms if $cust_main->invoice_terms; #use configured default $conf->config('invoice_default_terms') || ''; @@ -3085,70 +3108,72 @@ sub _date_pretty { time2str('%x', $self->_date); } +use vars qw(%pkg_category_cache); sub _items_sections { my $self = shift; my $late = shift; my $summarypage = shift; my $escape = shift; - my %s = (); - my %l = (); + my %subtotal = (); + my %late_subtotal = (); my %not_tax = (); foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) { - my $usage = $cust_bill_pkg->usage; foreach my $display ($cust_bill_pkg->cust_bill_pkg_display) { next if ( $display->summary && $summarypage ); - my $desc = $display->section; - my $type = $display->type; + my $section = $display->section; + my $type = $display->type; - if ( $cust_bill_pkg->pkgnum > 0 ) { - $not_tax{$desc} = 1; - } + $not_tax{$section} = 1 + unless $cust_bill_pkg->pkgnum == 0; if ( $display->post_total && !$summarypage ) { if (! $type || $type eq 'S') { - $l{$desc} += $cust_bill_pkg->setup - if ( $cust_bill_pkg->setup != 0 ); + $late_subtotal{$section} += $cust_bill_pkg->setup + if $cust_bill_pkg->setup != 0; } if (! $type) { - $l{$desc} += $cust_bill_pkg->recur - if ( $cust_bill_pkg->recur != 0 ); + $late_subtotal{$section} += $cust_bill_pkg->recur + if $cust_bill_pkg->recur != 0; } if ($type && $type eq 'R') { - $l{$desc} += $cust_bill_pkg->recur - $usage - if ( $cust_bill_pkg->recur != 0 ); + $late_subtotal{$section} += $cust_bill_pkg->recur - $usage + if $cust_bill_pkg->recur != 0; } if ($type && $type eq 'U') { - $l{$desc} += $usage; + $late_subtotal{$section} += $usage; } } else { + + next if $cust_bill_pkg->pkgnum == 0 && ! $section; + if (! $type || $type eq 'S') { - $s{$desc} += $cust_bill_pkg->setup - if ( $cust_bill_pkg->setup != 0 ); + $subtotal{$section} += $cust_bill_pkg->setup + if $cust_bill_pkg->setup != 0; } if (! $type) { - $s{$desc} += $cust_bill_pkg->recur - if ( $cust_bill_pkg->recur != 0 ); + $subtotal{$section} += $cust_bill_pkg->recur + if $cust_bill_pkg->recur != 0; } if ($type && $type eq 'R') { - $s{$desc} += $cust_bill_pkg->recur - $usage - if ( $cust_bill_pkg->recur != 0 ); + $subtotal{$section} += $cust_bill_pkg->recur - $usage + if $cust_bill_pkg->recur != 0; } if ($type && $type eq 'U') { - $s{$desc} += $usage; + $subtotal{$section} += $usage; } } @@ -3157,28 +3182,42 @@ sub _items_sections { } - my %cache = map { $_->categoryname => $_ } - qsearch( 'pkg_category', {disabled => 'Y'} ); - $cache{$_->categoryname} = $_ - foreach qsearch( 'pkg_category', {disabled => ''} ); + %pkg_category_cache = (); push @$late, map { { 'description' => &{$escape}($_), - 'subtotal' => $l{$_}, + 'subtotal' => $late_subtotal{$_}, 'post_total' => 1, } } - sort { $cache{$a}->weight <=> $cache{$b}->weight } keys %l; + sort _categorysort keys %late_subtotal; + + my @sections; + if ( $summarypage ) { + @sections = grep { exists($subtotal{$_}) || ! _pkg_category{$_}->disabled } + keys %pkg_category_cache; + } else { + @sections = keys %subtotal; + } map { { 'description' => &{$escape}($_), - 'subtotal' => $s{$_}, + 'subtotal' => $subtotal{$_}, 'summarized' => $not_tax{$_} ? '' : 'Y', 'tax_section' => $not_tax{$_} ? '' : 'Y', - } } - sort { $cache{$a}->weight <=> $cache{$b}->weight } - ( $summarypage - ? ( grep { exists($s{$_}) || !$cache{$_}->disabled } keys %cache ) - : ( keys %s ) - ); + } + } + sort _categorysort @sections; + +} + +#helper subs for above + +sub _categorysort { + _pkg_category($a)->weight <=> _pkg_category($b)->weight; +} +sub _pkg_category { + my $categoryname = shift; + $pkg_category_cache{$categoryname} ||= + qsearchs( 'pkg_category', { 'categoryname' => $categoryname } ); } sub _items {