X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FTemplate_Mixin.pm;h=2bf96ae3548fed4307889d4d031216ec051f090a;hb=c1bc17318fff6d7636601ef8de7fbce3734a785a;hp=64b9db5606af178931c162022e0db283c9c9ad40;hpb=36f114fa4084bfcfb52ed4673d54d1a0a7e33d15;p=freeside.git diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm index 64b9db560..2bf96ae35 100644 --- a/FS/FS/Template_Mixin.pm +++ b/FS/FS/Template_Mixin.pm @@ -12,6 +12,7 @@ use Text::Template 1.20; use File::Temp 0.14; use HTML::Entities; use Locale::Country; +use Cwd; use FS::UID; use FS::Record qw( qsearch qsearchs ); use FS::Misc qw( generate_ps generate_pdf ); @@ -133,7 +134,9 @@ sub print_latex { close $lh; $params{'logo_file'} = $lh->filename; - if( $conf->exists('invoice-barcode') && $self->can('invoice_barcode') ) { + if( $conf->exists('invoice-barcode') + && $self->can('invoice_barcode') + && $self->invnum ) { # don't try to barcode statements my $png_file = $self->invoice_barcode($dir); my $eps_file = $png_file; $eps_file =~ s/\.png$/.eps/g; @@ -581,16 +584,20 @@ sub print_generic { #my $balance_due = $self->owed + $pr_total - $cr_total; my $balance_due = $self->owed + $pr_total; - # the customer's current balance as shown on the invoice before this one - $invoice_data{'true_previous_balance'} = sprintf("%.2f", ($self->previous_balance || 0) ); + #these are used on the summary page only - # the change in balance from that invoice to this one - $invoice_data{'balance_adjustments'} = sprintf("%.2f", ($self->previous_balance || 0) - ($self->billing_balance || 0) ); + # the customer's current balance as shown on the invoice before this one + $invoice_data{'true_previous_balance'} = sprintf("%.2f", ($self->previous_balance || 0) ); - # the sum of amount owed on all previous invoices - $invoice_data{'previous_balance'} = sprintf("%.2f", $pr_total); + # the change in balance from that invoice to this one + $invoice_data{'balance_adjustments'} = sprintf("%.2f", ($self->previous_balance || 0) - ($self->billing_balance || 0) ); + + # the sum of amount owed on all previous invoices + # ($pr_total is used elsewhere but not as $previous_balance) + $invoice_data{'previous_balance'} = sprintf("%.2f", $pr_total); # the sum of amount owed on all invoices + # (this is used in the summary & on the payment coupon) $invoice_data{'balance'} = sprintf("%.2f", $balance_due); # info from customer's last invoice before this one, for some @@ -699,6 +706,8 @@ sub print_generic { warn "$me generating sections\n" if $DEBUG > 1; + # Previous Charges section + # subtotal is the first return value from $self->previous my $previous_section = { 'description' => $self->mt('Previous Charges'), 'subtotal' => $other_money_char. sprintf('%.2f', $pr_total), @@ -722,10 +731,11 @@ sub print_generic { my $adjusttotal = 0; - my $adjust_section = { 'description' => - $self->mt('Credits, Payments, and Adjustments'), - 'subtotal' => 0, # adjusted below - }; + my $adjust_section = { + 'description' => $self->mt('Credits, Payments, and Adjustments'), + 'adjust_section' => 1, + 'subtotal' => 0, # adjusted below + }; my $adjust_weight = _pkg_category($adjust_section->{description}) ? _pkg_category($adjust_section->{description})->weight : 0; @@ -801,11 +811,11 @@ sub print_generic { } } - unless ( $conf->exists('disable_previous_balance', $agentnum) - || $conf->exists('previous_balance-summary_only') - || ! $self->can('_items_previous') - ) - { + # previous invoice balances in the Previous Charges section if there + # is one, otherwise in the main detail section + if ( $self->can('_items_previous') && + $self->enable_previous && + ! $conf->exists('previous_balance-summary_only') ) { warn "$me adding previous balances\n" if $DEBUG > 1; @@ -816,6 +826,7 @@ sub print_generic { ext_description => [], }; $detail->{'ref'} = $line_item->{'pkgnum'}; + $detail->{'pkgpart'} = $line_item->{'pkgpart'}; $detail->{'quantity'} = 1; $detail->{'section'} = $multisection ? $previous_section : $default_section; @@ -836,9 +847,8 @@ sub print_generic { } } - - if ( @pr_cust_bill && !$conf->exists('disable_previous_balance', $agentnum) ) - { + + if ( @pr_cust_bill && $self->enable_previous ) { push @buf, ['','-----------']; push @buf, [ $self->mt('Total Previous Balance'), $money_char. sprintf("%10.2f", $pr_total) ]; @@ -890,7 +900,6 @@ sub print_generic { warn "$me setting options\n" if $DEBUG > 1; - my $multilocation = scalar($cust_main->cust_location); #too expensive? my %options = (); $options{'section'} = $section if $multisection; $options{'format'} = $format; @@ -900,7 +909,6 @@ sub print_generic { $options{'summary_page'} = $summarypage; $options{'skip_usage'} = scalar(@$extra_sections) && !grep{$section == $_} @$extra_sections; - $options{'multilocation'} = $multilocation; $options{'multisection'} = $multisection; warn "$me searching for line items\n" @@ -915,6 +923,7 @@ sub print_generic { ext_description => [], }; $detail->{'ref'} = $line_item->{'pkgnum'}; + $detail->{'pkgpart'} = $line_item->{'pkgpart'}; $detail->{'quantity'} = $line_item->{'quantity'}; $detail->{'section'} = $section; $detail->{'description'} = &$escape_function($line_item->{'description'}); @@ -923,8 +932,10 @@ sub print_generic { } $detail->{'amount'} = ( $old_latex ? '' : $money_char ). $line_item->{'amount'}; - $detail->{'unit_amount'} = ( $old_latex ? '' : $money_char ). - $line_item->{'unit_amount'}; + if ( exists $line_item->{'unit_amount'} ) { + $detail->{'unit_amount'} = ( $old_latex ? '' : $money_char ). + $line_item->{'unit_amount'}; + } $detail->{'product_code'} = $line_item->{'pkgpart'} || 'N/A'; $detail->{'sdate'} = $line_item->{'sdate'}; @@ -954,7 +965,9 @@ sub print_generic { $invoice_data{current_less_finance} = sprintf('%.2f', $self->charged - $invoice_data{finance_amount} ); - if ( $multisection && !$conf->exists('disable_previous_balance', $agentnum) + # create a major section for previous balance if we have major sections, + # or if previous_section is in summary form + if ( ( $multisection && $self->enable_previous ) || $conf->exists('previous_balance-summary_only') ) { unshift @sections, $previous_section if $pr_total; @@ -1018,25 +1031,26 @@ sub print_generic { push @buf,['','-----------']; push @buf,[$self->mt( - $conf->exists('disable_previous_balance', $agentnum) + (!$self->enable_previous) ? 'Total Charges' : 'Total New Charges' ), $money_char. sprintf("%10.2f",$self->charged) ]; push @buf,['','']; + # calculate total, possibly including total owed on previous + # invoices { my $total = {}; my $item = 'Total'; $item = $conf->config('previous_balance-exclude_from_total') || 'Total New Charges' if $conf->exists('previous_balance-exclude_from_total'); - my $amount = $self->charged + - ( $conf->exists('disable_previous_balance', $agentnum) || - $conf->exists('previous_balance-exclude_from_total') - ? 0 - : $pr_total - ); + my $amount = $self->charged; + if ( $self->enable_previous and !$conf->exists('previous_balance-exclude_from_total') ) { + $amount += $pr_total; + } + $total->{'total_item'} = &$embolden_function($self->mt($item)); $total->{'total_amount'} = &$embolden_function( $other_money_char. sprintf( '%.2f', $amount ) ); @@ -1058,12 +1072,13 @@ sub print_generic { ]; push @buf,['','']; } - - unless ( $conf->exists('disable_previous_balance', $agentnum) - || ! $self->can('_items_credits') - || ! $self->can('_items_payments') - ) - { + + # if we're showing previous invoices, also show previous + # credits and payments + if ( $self->enable_previous + and $self->can('_items_credits') + and $self->can('_items_payments') ) + { #foreach my $thing ( sort { $a->_date <=> $b->_date } $self->_items_credits, $self->_items_payments # credits @@ -1139,10 +1154,11 @@ sub print_generic { $total->{'total_item'} = &$embolden_function($self->balance_due_msg); $total->{'total_amount'} = &$embolden_function( - $other_money_char. sprintf('%.2f', $summarypage - ? $self->charged + - $self->billing_balance - : $self->owed + $pr_total + $other_money_char. sprintf('%.2f', #why? $summarypage + # ? $self->charged + + # $self->billing_balance + # : + $self->owed + $pr_total ) ); if ( $multisection && !$adjust_section->{sort_weight} ) { @@ -1216,6 +1232,10 @@ sub print_generic { } } @discounts_avail; } + # debugging hook: call this with 'diag' => 1 to just get a hash of + # the invoice variables + return \%invoice_data if ( $params{'diag'} ); + # All sections and items are built; now fill in templates. my @includelist = (); push @includelist, 'summary' if $summarypage; @@ -1654,6 +1674,13 @@ sub _items_sections { $not_tax{$section} = 1 unless $cust_bill_pkg->pkgnum == 0; + # there's actually a very important piece of logic buried in here: + # incrementing $late_subtotal{$section} CREATES + # $late_subtotal{$section}. keys(%late_subtotal) is later used + # to define the list of late sections, and likewise keys(%subtotal). + # When _items_cust_bill_pkg is called to generate line items for + # real, it will be called with 'section' => $section for each + # of these. if ( $display->post_total && !$summarypage ) { if (! $type || $type eq 'S') { $late_subtotal{$section} += $cust_bill_pkg->setup @@ -2101,11 +2128,9 @@ ignored. multisection: a flag indicating that this is a multisection invoice, which does something complicated. -multilocation: a flag to display the location label for the package. - Returns a list of hashrefs, each of which may contain: -pkgnum, description, amount, unit_amount, quantity, _is_setup, and +pkgnum, description, amount, unit_amount, quantity, pkgpart, _is_setup, and ext_description, which is an arrayref of detail lines to show below the package line. @@ -2124,13 +2149,13 @@ sub _items_cust_bill_pkg { my $unsquelched = $opt{unsquelched} || ''; #unused my $section = $opt{section}->{description} if $opt{section}; my $summary_page = $opt{summary_page} || ''; #unused - my $multilocation = $opt{multilocation} || ''; my $multisection = $opt{multisection} || ''; my $discount_show_always = 0; my $maxlength = $conf->config('cust_bill-latex_lineitem_maxlength') || 50; my $cust_main = $self->cust_main;#for per-agent cust_bill-line_item-ate_style + # and location labels my @b = (); my ($s, $r, $u) = ( undef, undef, undef ); @@ -2161,14 +2186,13 @@ sub _items_cust_bill_pkg { if $DEBUG > 1; foreach my $display ( grep { defined($section) - ? $_->section eq $section - : 1 - } - #grep { !$_->summary || !$summary_page } # bunk! + ? $_->section eq $section + : 1 + } grep { !$_->summary || $multisection } @cust_bill_pkg_display ) - { + { warn "$me _items_cust_bill_pkg considering cust_bill_pkg_display ". $display->billpkgdisplaynum. "\n" @@ -2186,16 +2210,44 @@ sub _items_cust_bill_pkg { 'no_usage' => $opt{'no_usage'}, ); - if ( $cust_bill_pkg->pkgnum > 0 ) { + if ( ref($cust_bill_pkg) eq 'FS::quotation_pkg' ) { + + warn "$me _items_cust_bill_pkg cust_bill_pkg is quotation_pkg\n" + if $DEBUG > 1; + + if ( $cust_bill_pkg->setup != 0 ) { + my $description = $desc; + $description .= ' Setup' + if $cust_bill_pkg->recur != 0 + || $discount_show_always + || $cust_bill_pkg->recur_show_zero; + push @b, { + 'description' => $description, + 'amount' => sprintf("%.2f", $cust_bill_pkg->setup), + }; + } + if ( $cust_bill_pkg->recur != 0 ) { + push @b, { + 'description' => "$desc (". $cust_bill_pkg->part_pkg->freq_pretty.")", + 'amount' => sprintf("%.2f", $cust_bill_pkg->recur), + }; + } + + } elsif ( $cust_bill_pkg->pkgnum > 0 ) { warn "$me _items_cust_bill_pkg cust_bill_pkg is non-tax\n" if $DEBUG > 1; my $cust_pkg = $cust_bill_pkg->cust_pkg; + # which pkgpart to show for display purposes? + my $pkgpart = $cust_bill_pkg->pkgpart_override || $cust_pkg->pkgpart; + # start/end dates for invoice formats that do nonstandard # things with them - my %item_dates = map { $_ => $cust_bill_pkg->$_ } ('sdate', 'edate'); + my %item_dates = (); + %item_dates = map { $_ => $cust_bill_pkg->$_ } ('sdate', 'edate') + unless $cust_pkg->part_pkg->option('disable_line_item_date_ranges',1); if ( (!$type || $type eq 'S') && ( $cust_bill_pkg->setup != 0 @@ -2222,7 +2274,8 @@ sub _items_cust_bill_pkg { $cust_pkg->h_labels_short($self->_date, undef, 'I') unless $cust_bill_pkg->pkgpart_override; #don't redisplay services - if ( $multilocation ) { + if ( ! $cust_pkg->locationnum or + $cust_pkg->locationnum != $cust_main->ship_locationnum ) { my $loc = $cust_pkg->location_label; $loc = substr($loc, 0, $maxlength). '...' if $format eq 'latex' && length($loc) > $maxlength; @@ -2242,7 +2295,7 @@ sub _items_cust_bill_pkg { $s = { _is_setup => 1, description => $description, - #pkgpart => $part_pkg->pkgpart, + pkgpart => $pkgpart, pkgnum => $cust_bill_pkg->pkgnum, amount => $cust_bill_pkg->setup, setup_show_zero => $cust_bill_pkg->setup_show_zero, @@ -2271,16 +2324,25 @@ sub _items_cust_bill_pkg { my $description = ($is_summary && $type && $type eq 'U') ? "Usage charges" : $desc; + my $part_pkg = $cust_pkg->part_pkg; + #pry be a bit more efficient to look some of this conf stuff up # outside the loop unless ( $conf->exists('disable_line_item_date_ranges') - || $cust_pkg->part_pkg->option('disable_line_item_date_ranges',1) + || $part_pkg->option('disable_line_item_date_ranges',1) + || ! $cust_bill_pkg->sdate + || ! $cust_bill_pkg->edate ) { my $time_period; - my $date_style = $conf->config( 'cust_bill-line_item-date_style', + my $date_style = ''; + $date_style = $conf->config( 'cust_bill-line_item-date_style-non_monhtly', + $cust_main->agentnum + ) + if $part_pkg && $part_pkg->freq !~ /^1m?$/; + $date_style ||= $conf->config( 'cust_bill-line_item-date_style', $cust_main->agentnum - ); + ); if ( defined($date_style) && $date_style eq 'month_of' ) { $time_period = time2str('The month of %B', $cust_bill_pkg->sdate); } elsif ( defined($date_style) && $date_style eq 'X_month' ) { @@ -2306,10 +2368,11 @@ sub _items_cust_bill_pkg { push @dates, $prev->sdate if $prev; push @dates, undef if !$prev; - unless ( $cust_pkg->part_pkg->hide_svc_detail + unless ( $part_pkg->hide_svc_detail || $cust_bill_pkg->itemdesc || $cust_bill_pkg->hidden - || $is_summary && $type && $type eq 'U' ) + || $is_summary && $type && $type eq 'U' + ) { warn "$me _items_cust_bill_pkg adding service details\n" @@ -2324,7 +2387,7 @@ sub _items_cust_bill_pkg { warn "$me _items_cust_bill_pkg done adding service details\n" if $DEBUG > 1; - if ( $multilocation ) { + if ( $cust_pkg->locationnum != $cust_main->ship_locationnum ) { my $loc = $cust_pkg->location_label; $loc = substr($loc, 0, $maxlength). '...' if $format eq 'latex' && length($loc) > $maxlength; @@ -2378,6 +2441,10 @@ sub _items_cust_bill_pkg { $amount = $cust_bill_pkg->usage; } + my $unit_amount = + ( $cust_bill_pkg->unitrecur > 0 ) ? $cust_bill_pkg->unitrecur + : $amount; + if ( !$type || $type eq 'R' ) { warn "$me _items_cust_bill_pkg adding recur\n" @@ -2385,16 +2452,16 @@ sub _items_cust_bill_pkg { if ( $cust_bill_pkg->hidden ) { $r->{amount} += $amount; - $r->{unit_amount} += $cust_bill_pkg->unitrecur; + $r->{unit_amount} += $unit_amount; push @{ $r->{ext_description} }, @d; } else { $r = { description => $description, - #pkgpart => $part_pkg->pkgpart, + pkgpart => $pkgpart, pkgnum => $cust_bill_pkg->pkgnum, amount => $amount, recur_show_zero => $cust_bill_pkg->recur_show_zero, - unit_amount => $cust_bill_pkg->unitrecur, + unit_amount => $unit_amount, quantity => $cust_bill_pkg->quantity, %item_dates, ext_description => \@d, @@ -2409,16 +2476,16 @@ sub _items_cust_bill_pkg { if ( $cust_bill_pkg->hidden ) { $u->{amount} += $amount; - $u->{unit_amount} += $cust_bill_pkg->unitrecur; + $u->{unit_amount} += $unit_amount, push @{ $u->{ext_description} }, @d; } else { $u = { description => $description, - #pkgpart => $part_pkg->pkgpart, + pkgpart => $pkgpart, pkgnum => $cust_bill_pkg->pkgnum, amount => $amount, recur_show_zero => $cust_bill_pkg->recur_show_zero, - unit_amount => $cust_bill_pkg->unitrecur, + unit_amount => $unit_amount, quantity => $cust_bill_pkg->quantity, %item_dates, ext_description => \@d,