X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_bill.pm;h=0ba6cdfed7be6cd5a9e3e85f88279affa259c335;hb=f6036d1338eb1df0fa5c58d358e52d770a7e0330;hp=e318de1efc278bad7345ea2def824942c86650e6;hpb=c3d3ee8e73fe9e7ffdbaa2dcc6a908ed55b8d259;p=freeside.git diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index e318de1ef..0ba6cdfed 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -5,6 +5,7 @@ use vars qw( @ISA $DEBUG $me $conf $money_char $date_format $rdate_format $date_format_long ); use vars qw( $invoice_lines @buf ); #yuck use Fcntl qw(:flock); #for spool_csv +use Cwd; use List::Util qw(min max); use Date::Format; use Text::Template 1.20; @@ -38,7 +39,8 @@ use FS::part_bill_event; use FS::payby; use FS::bill_batch; use FS::cust_bill_batch; -use Cwd; +use FS::cust_bill_pay_pkg; +use FS::cust_credit_bill_pkg; @ISA = qw( FS::cust_main_Mixin FS::Record ); @@ -649,44 +651,86 @@ sub cust_credit_bill { shift->cust_credited(@_); } -=item cust_bill_pay_pkgnum PKGNUM +#=item cust_bill_pay_pkgnum PKGNUM +# +#Returns all payment applications (see L) for this invoice +#with matching pkgnum. +# +#=cut +# +#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, +# } +# ); +#} + +=item cust_bill_pay_pkg PKGNUM Returns all payment applications (see L) for this invoice -with matching pkgnum. +applied against the matching pkgnum. =cut -sub cust_bill_pay_pkgnum { +sub cust_bill_pay_pkg { 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, - } - ); + + qsearch({ + 'select' => 'cust_bill_pay_pkg.*', + 'table' => 'cust_bill_pay_pkg', + 'addl_from' => ' LEFT JOIN cust_bill_pay USING ( billpaynum ) '. + ' LEFT JOIN cust_bill_pkg USING ( billpkgnum ) ', + 'extra_sql' => ' WHERE cust_bill_pkg.invnum = '. $self->invnum. + " AND cust_bill_pkg.pkgnum = $pkgnum", + }); + } -=item cust_credited_pkgnum PKGNUM +#=item cust_credited_pkgnum PKGNUM +# +#=item cust_credit_bill_pkgnum PKGNUM +# +#Returns all applied credits (see L) for this invoice +#with matching pkgnum. +# +#=cut +# +#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, +# } +# ); +#} +# +#sub cust_credit_bill_pkgnum { +# shift->cust_credited_pkgnum(@_); +#} -=item cust_credit_bill_pkgnum PKGNUM +=item cust_credit_bill_pkg PKGNUM -Returns all applied credits (see L) for this invoice -with matching pkgnum. +Returns all credit applications (see L) for this invoice +applied against the matching pkgnum. =cut -sub cust_credited_pkgnum { +sub cust_credit_bill_pkg { 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, - } - ); -} -sub cust_credit_bill_pkgnum { - shift->cust_credited_pkgnum(@_); + qsearch({ + 'select' => 'cust_credit_bill_pkg.*', + 'table' => 'cust_credit_bill_pkg', + 'addl_from' => ' LEFT JOIN cust_credit_bill USING ( creditbillnum ) '. + ' LEFT JOIN cust_bill_pkg USING ( billpkgnum ) ', + 'extra_sql' => ' WHERE cust_bill_pkg.invnum = '. $self->invnum. + " AND cust_bill_pkg.pkgnum = $pkgnum", + }); + } =item tax @@ -729,8 +773,8 @@ sub owed_pkgnum { my $balance = 0; $balance += $_->setup + $_->recur for $self->cust_bill_pkg_pkgnum($pkgnum); - $balance -= $_->amount for $self->cust_bill_pay_pkgnum($pkgnum); - $balance -= $_->amount for $self->cust_credited_pkgnum($pkgnum); + $balance -= $_->amount for $self->cust_bill_pay_pkg($pkgnum); + $balance -= $_->amount for $self->cust_credit_bill_pkg($pkgnum); $balance = sprintf( "%.2f", $balance); $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp @@ -2509,6 +2553,7 @@ sub print_generic { #invoice from info 'company_name' => scalar( $conf->config('company_name', $agentnum) ), 'company_address' => join("\n", $conf->config('company_address', $agentnum) ). "\n", + 'company_phonenum'=> scalar( $conf->config('company_phonenum', $agentnum) ), 'returnaddress' => $returnaddress, 'agent' => &$escape_function($cust_main->agent->agent), @@ -2784,6 +2829,14 @@ sub print_generic { push @{$late_sections}, @$phone_sections; push @detail_items, @$phone_lines; } + if ($conf->exists('voip-cust_accountcode_cdr') && $cust_main->accountcode_cdr) { + my ($accountcode_section, $accountcode_lines) = + $self->_items_accountcode_cdr($escape_function_nonbsp,$format); + if ( scalar(@$accountcode_lines) ) { + push @{$late_sections}, $accountcode_section; + push @detail_items, @$accountcode_lines; + } + } }else{ push @sections, { 'description' => '', 'subtotal' => '' }; } @@ -2821,7 +2874,7 @@ sub print_generic { } } - + if ( @pr_cust_bill && !$conf->exists('disable_previous_balance') ) { push @buf, ['','-----------']; push @buf, [ 'Total Previous Balance', @@ -2834,7 +2887,7 @@ sub print_generic { if $DEBUG > 1; my ($didsummary,$minutes) = $self->_did_summary; - my $didsummary_desc = 'DID Activity Summary (Past 30 days)'; + my $didsummary_desc = 'DID Activity Summary (since last invoice)'; push @detail_items, { 'description' => $didsummary_desc, 'ext_description' => [ $didsummary, $minutes ], @@ -3300,7 +3353,7 @@ sub print_ps { my ($file, $logofile, $barcodefile) = $self->print_latex(@_); my $ps = generate_ps($file); unlink($logofile); - unlink($barcodefile); + unlink($barcodefile) if $barcodefile; $ps; } @@ -3329,7 +3382,7 @@ sub print_pdf { my ($file, $logofile, $barcodefile) = $self->print_latex(@_); my $pdf = generate_pdf($file); unlink($logofile); - unlink($barcodefile); + unlink($barcodefile) if $barcodefile; $pdf; } @@ -3652,7 +3705,7 @@ sub _items_sections { } } @sections; push @early, @$extra_sections if $extra_sections; - + sort { $a->{sort_weight} <=> $b->{sort_weight} } @early; } @@ -4017,7 +4070,12 @@ sub _items_extra_usage_sections { sub _did_summary { my $self = shift; my $end = $self->_date; - my $start = $end - 2592000; # 30 days + + # start at date of previous invoice + 1 second or 0 if no previous invoice + my $start = $self->scalar_sql("SELECT max(_date) FROM cust_bill WHERE custnum = ? and invnum != ?",$self->custnum,$self->invnum); + $start = 0 if !$start; + $start++; + my $cust_main = $self->cust_main; my @pkgs = $cust_main->all_pkgs; my($num_activated,$num_deactivated,$num_portedin,$num_portedout,$minutes) @@ -4080,6 +4138,75 @@ sub _did_summary { "Total Minutes: $minutes"); } +sub _items_accountcode_cdr { + my $self = shift; + my $escape = shift; + my $format = shift; + + my $section = { 'amount' => 0, + 'calls' => 0, + 'duration' => 0, + 'sort_weight' => '', + 'phonenum' => '', + 'description' => 'Usage by Account Code', + 'post_total' => '', + 'summarized' => '', + 'header' => '', + }; + my @lines; + my %accountcodes = (); + + foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) { + next unless $cust_bill_pkg->pkgnum > 0; + + my @header = $cust_bill_pkg->details_header; + next unless scalar(@header); + $section->{'header'} = join(',',@header); + + foreach my $detail ( $cust_bill_pkg->cust_bill_pkg_detail ) { + + $section->{'header'} = $detail->formatted('format' => $format) + if($detail->detail eq $section->{'header'}); + + my $accountcode = $detail->accountcode; + next unless $accountcode; + + my $amount = $detail->amount; + next unless $amount && $amount > 0; + + $accountcodes{$accountcode} ||= { + description => $accountcode, + pkgnum => '', + ref => '', + amount => 0, + calls => 0, + duration => 0, + quantity => '', + product_code => 'N/A', + section => $section, + ext_description => [], + }; + + $section->{'amount'} += $amount; + $accountcodes{$accountcode}{'amount'} += $amount; + $accountcodes{$accountcode}{calls}++; + $accountcodes{$accountcode}{duration} += $detail->duration; + push @{$accountcodes{$accountcode}{ext_description}}, + $detail->formatted('format' => $format); + } + } + + foreach my $l ( values %accountcodes ) { + $l->{amount} = sprintf( "%.2f", $l->{amount} ); + unshift @{$l->{ext_description}}, $section->{'header'}; + push @lines, $l; + } + + my @sorted_lines = sort { $a->{'description'} <=> $b->{'description'} } @lines; + + return ($section,\@sorted_lines); +} + sub _items_svc_phone_sections { my $self = shift; my $escape = shift; @@ -4650,7 +4777,6 @@ sub _items_cust_bill_pkg { ext_description => \@d, }; } - } } # recurring or usage with recurring charge