X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_bill.pm;h=0906c5dfead87c6807264480b96fdd04345c0e6b;hb=fe16cec1c82f4e1f1c2586c8259cd607fcb14d79;hp=81b874add5ff9dc374bb914b146db9d7190bd052;hpb=8333462f80da553234ef53076a932e9f417e6ad2;p=freeside.git diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 81b874add..0906c5dfe 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -798,6 +798,9 @@ single agent) or an arrayref of agentnums. INVOICE_FROM, if specified, overrides the default email invoice From: address. +AMOUNT, if specified, only sends the invoice if the total amount owed on this +invoice and all older invoices is greater than the specified amount. + =cut sub queueable_send { @@ -828,6 +831,11 @@ sub send { ? shift : ( $self->_agent_invoice_from || $conf->config('invoice_from') ); + my $balance_over = ( scalar(@_) && $_[0] !~ /^\s*$/ ) ? shift : 0; + + return '' + unless $self->cust_main->total_owed_date($self->_date) > $balance_over; + my @invoicing_list = $self->cust_main->invoicing_list; $self->email($template, $invoice_from) @@ -1740,7 +1748,7 @@ sub print_generic { ); my $escape_function = $escape_functions{$format}; - my %date_formats = ( 'latex' => '%b, %o, %Y', + my %date_formats = ( 'latex' => '%b %o, %Y', 'html' => '%b %o, %Y', 'template' => '%s', ); @@ -1785,13 +1793,17 @@ sub print_generic { ); } elsif ( grep /\S/, $conf->config('company_address') ) { - $returnaddress = join( "\n", $conf->config('company_address') ); - - $returnaddress = - join( '\\*'."\n", map s/( {2,})/'~' x length($1)/eg, - $conf->config('company_address') - ) - if $format eq 'latex'; + my $convert_map = $convert_maps{$format}{'returnaddress'}; + $returnaddress = join( "\n", &$convert_map( + map { s/( {2,})/'~' x length($1)/eg; + s/$/\\\\\*/; + $_ + } + ( $conf->config('company_name'), + $conf->config('company_address'), + ) + ) + ); } else { @@ -1939,6 +1951,14 @@ sub print_generic { sprintf('%.2f', $pr_total), }; + my $taxtotal = 0; + my $tax_section = { 'description' => 'Taxes, Surcharges, and Fees', + 'subtotal' => $taxtotal }; # adjusted below + + my $adjusttotal = 0; + my $adjust_section = { 'description' => 'Credits, Payments, and Adjustments', + 'subtotal' => 0 }; # adjusted below + my $multisection = $conf->exists('invoice_sections', $cust_main->agentnum); if ( $multisection ) { push @sections, $self->_items_sections; @@ -1946,7 +1966,11 @@ sub print_generic { push @sections, { 'description' => '', 'subtotal' => '' }; } - foreach my $line_item ( $self->_items_previous ) { + foreach my $line_item ( $conf->exists('disable_previous_balance') + ? () + : $self->_items_previous + ) + { my $detail = { ext_description => [], }; @@ -1971,7 +1995,7 @@ sub print_generic { ]; } - if (@pr_cust_bill) { + if ( @pr_cust_bill && !$conf->exists('disable_previous_balance') ) { push @buf, ['','-----------']; push @buf, [ 'Total Previous Balance', $money_char. sprintf("%10.2f", $pr_total) ]; @@ -1992,6 +2016,7 @@ sub print_generic { my %options = (); $options{'section'} = $section if $multisection; + $options{'format'} = $format; foreach my $line_item ( $self->_items_pkg(%options) ) { my $detail = { @@ -2002,9 +2027,7 @@ sub print_generic { $detail->{'section'} = $section; $detail->{'description'} = &$escape_function($line_item->{'description'}); if ( exists $line_item->{'ext_description'} ) { - @{$detail->{'ext_description'}} = map { - &$escape_function($_); - } @{$line_item->{'ext_description'}}; + @{$detail->{'ext_description'}} = @{$line_item->{'ext_description'}}; } { my $money = $old_latex ? '' : $money_char; @@ -2032,17 +2055,29 @@ sub print_generic { } - if ( $multisection ) { - unshift @sections, $previous_section; + if ( $multisection && !$conf->exists('disable_previous_balance') ) { + unshift @sections, $previous_section if $pr_total; } - my $taxtotal = 0; foreach my $tax ( $self->_items_tax ) { my $total = {}; $total->{'total_item'} = &$escape_function($tax->{'description'}); $taxtotal += $tax->{'amount'}; $total->{'total_amount'} = $other_money_char. $tax->{'amount'}; - push @total_items, $total; + if ( $multisection ) { + my $money = $old_latex ? '' : $money_char; + push @detail_items, { + ext_description => [], + ref => '', + quantity => '', + description => &$escape_function($tax->{'description'}), + amount => $money. $tax->{'amount'}, + product_code => '', + section => $tax_section, + }; + }else{ + push @total_items, $total; + } push @buf,[ $total->{'total_item'}, $money_char. sprintf("%10.2f", $total->{'total_amount'}), ]; @@ -2051,18 +2086,26 @@ sub print_generic { if ( $taxtotal ) { my $total = {}; + $total->{'total_item'} = 'Sub-total'; + $total->{'total_amount'} = + $other_money_char. sprintf('%.2f', $self->charged - $taxtotal ); + if ( $multisection ) { - $total->{'total_item'} = 'New charges sub-total'; + $tax_section->{'subtotal'} = $other_money_char. + sprintf('%.2f', $taxtotal); + $tax_section->{'pretotal'} = 'New charges sub-total '. + $total->{'total_amount'}; + push @sections, $tax_section if $taxtotal; }else{ - $total->{'total_item'} = 'Sub-total'; + unshift @total_items, $total; } - $total->{'total_amount'} = - $other_money_char. sprintf('%.2f', $self->charged - $taxtotal ); - unshift @total_items, $total; } push @buf,['','-----------']; - push @buf,['Total New Charges', + push @buf,[( $conf->exists('disable_previous_balance') + ? 'Total Charges' + : 'Total New Charges' + ), $money_char. sprintf("%10.2f",$self->charged) ]; push @buf,['','']; @@ -2070,66 +2113,123 @@ sub print_generic { my $total = {}; $total->{'total_item'} = &$embolden_function('Total'); $total->{'total_amount'} = - $total->{'total_amount'} = &$embolden_function( - $other_money_char. sprintf('%.2f', $self->charged + $pr_total ) + $other_money_char. + sprintf( '%.2f', + $self->charged + ( $conf->exists('disable_previous_balance') + ? 0 + : $pr_total + ) + ) ); - push @total_items, $total; + if ( $multisection ) { + $adjust_section->{'pretotal'} = 'New charges total '. + $total->{'total_amount'}; + }else{ + push @total_items, $total; + } push @buf,['','-----------']; push @buf,['Total Charges', - $money_char. sprintf("%10.2f",$self->charged + $pr_total) ]; + $money_char. + sprintf( '%10.2f', $self->charged + + ( $conf->exists('disable_previous_balance') + ? 0 + : $pr_total + ) + ) + ]; push @buf,['','']; } - - #foreach my $thing ( sort { $a->_date <=> $b->_date } $self->_items_credits, $self->_items_payments + unless ( $conf->exists('disable_previous_balance') ) { + #foreach my $thing ( sort { $a->_date <=> $b->_date } $self->_items_credits, $self->_items_payments - # credits - foreach my $credit ( $self->_items_credits ) { - my $total; - $total->{'total_item'} = &$escape_function($credit->{'description'}); - #$credittotal - $total->{'total_amount'} = '-'. $other_money_char. $credit->{'amount'}; - push @total_items, $total; - } + # credits + foreach my $credit ( $self->_items_credits ) { + my $total; + $total->{'total_item'} = &$escape_function($credit->{'description'}); + #$credittotal + $total->{'total_amount'} = '-'. $other_money_char. $credit->{'amount'}; + $adjusttotal += $credit->{'amount'}; + if ( $multisection ) { + my $money = $old_latex ? '' : $money_char; + push @detail_items, { + ext_description => [], + ref => '', + quantity => '', + description => &$escape_function($credit->{'description'}), + amount => $money. $credit->{'amount'}, + product_code => '', + section => $adjust_section, + }; + }else{ + push @total_items, $total; + } + } - # credits (again) - foreach ( $self->cust_credited ) { - - #something more elaborate if $_->amount ne $_->cust_credit->credited ? - - my $reason = substr($_->cust_credit->reason,0,32); - $reason .= '...' if length($reason) < length($_->cust_credit->reason); - $reason = " ($reason) " if $reason; - push @buf,[ - "Credit #". $_->crednum. " (". time2str("%x",$_->cust_credit->_date) .")". $reason, - $money_char. sprintf("%10.2f",$_->amount) - ]; - } + # credits (again) + foreach ( $self->cust_credited ) { + + #something more elaborate if $_->amount ne $_->cust_credit->credited ? + + my $reason = substr($_->cust_credit->reason,0,32); + $reason .= '...' if length($reason) < length($_->cust_credit->reason); + $reason = " ($reason) " if $reason; + push @buf,[ + "Credit #". $_->crednum. " (". time2str("%x",$_->cust_credit->_date) .")". $reason, + $money_char. sprintf("%10.2f",$_->amount) + ]; + } - # payments - foreach my $payment ( $self->_items_payments ) { - my $total = {}; - $total->{'total_item'} = &$escape_function($payment->{'description'}); - #$paymenttotal - $total->{'total_amount'} = '-'. $other_money_char. $payment->{'amount'}; - push @total_items, $total; - push @buf, [ $payment->{'description'}, - $money_char. sprintf("%10.2f", $payment->{'amount'}), - ]; - } + # payments + foreach my $payment ( $self->_items_payments ) { + my $total = {}; + $total->{'total_item'} = &$escape_function($payment->{'description'}); + #$paymenttotal + $total->{'total_amount'} = '-'. $other_money_char. $payment->{'amount'}; + $adjusttotal += $payment->{'amount'}; + if ( $multisection ) { + my $money = $old_latex ? '' : $money_char; + push @detail_items, { + ext_description => [], + ref => '', + quantity => '', + description => &$escape_function($payment->{'description'}), + amount => $money. $payment->{'amount'}, + product_code => '', + section => $adjust_section, + }; + }else{ + push @total_items, $total; + } + push @buf, [ $payment->{'description'}, + $money_char. sprintf("%10.2f", $payment->{'amount'}), + ]; + } - { - my $total; - $total->{'total_item'} = &$embolden_function($self->balance_due_msg); - $total->{'total_amount'} = - &$embolden_function( - $other_money_char. sprintf('%.2f', $self->owed + $pr_total ) - ); - push @total_items, $total; - push @buf,['','-----------']; - push @buf,[$self->balance_due_msg, $money_char. - sprintf("%10.2f", $balance_due ) ]; + if ( $multisection ) { + $adjust_section->{'subtotal'} = $other_money_char. + sprintf('%.2f', $adjusttotal); + push @sections, $adjust_section; + } + + { + my $total; + $total->{'total_item'} = &$embolden_function($self->balance_due_msg); + $total->{'total_amount'} = + &$embolden_function( + $other_money_char. sprintf('%.2f', $self->owed + $pr_total ) + ); + if ( $multisection ) { + $adjust_section->{'posttotal'} = $total->{'total_item'}. ' '. + $total->{'total_amount'}; + }else{ + push @total_items, $total; + } + push @buf,['','-----------']; + push @buf,[$self->balance_due_msg, $money_char. + sprintf("%10.2f", $balance_due ) ]; + } } $invoice_data{'logo_file'} = $params{'logo_file'} @@ -2504,6 +2604,9 @@ sub _items_tax { sub _items_cust_bill_pkg { my $self = shift; my $cust_bill_pkg = shift; + my %opt = @_; + my $format = $opt{format} || ''; + my $escape_function = $opt{escape_function} || sub { shift }; my @b = (); foreach my $cust_bill_pkg ( @$cust_bill_pkg ) { @@ -2518,7 +2621,10 @@ sub _items_cust_bill_pkg { my $description = $desc; $description .= ' Setup' if $cust_bill_pkg->recur != 0; my @d = $cust_pkg->h_labels_short($self->_date); - push @d, $cust_bill_pkg->details if $cust_bill_pkg->recur == 0; + push @d, $cust_bill_pkg->details( 'format' => $format, + 'escape_function' => $escape_function, + ) + if $cust_bill_pkg->recur == 0; push @b, { description => $description, #pkgpart => $part_pkg->pkgpart, @@ -2545,7 +2651,8 @@ sub _items_cust_bill_pkg { [ $cust_pkg->h_labels_short( $self->_date ), #$cust_bill_pkg->edate, #$cust_bill_pkg->sdate), - $cust_bill_pkg->details, + $cust_bill_pkg->details( 'format' => $format, + 'escape_function' => $escape_function), ], }; }