my $self = shift;
my $total = 0;
my @cust_bill = sort { $a->_date <=> $b->_date }
- grep { $_->owed != 0 && $_->_date < $self->_date }
- qsearch( 'cust_bill', { 'custnum' => $self->custnum } )
+ grep { $_->owed != 0 }
+ qsearch( 'cust_bill', { 'custnum' => $self->custnum,
+ #'_date' => { op=>'<', value=>$self->_date },
+ 'invnum' => { op=>'<', value=>$self->invnum },
+ } )
;
foreach ( @cust_bill ) { $total += $_->owed; }
$total, @cust_bill;
}
+=item enable_previous
+
+Whether to show the 'Previous Charges' section when printing this invoice.
+The negation of the 'disable_previous_balance' config setting.
+
+=cut
+
+sub enable_previous {
+ my $self = shift;
+ my $agentnum = $self->cust_main->agentnum;
+ !$self->conf->exists('disable_previous_balance', $agentnum);
+}
+
=item cust_bill_pkg
Returns the line items (see L<FS::cust_bill_pkg>) for this invoice.
$balance_over = shift if scalar(@_) && $_[0] !~ /^\s*$/;
}
+ my $cust_main = $self->cust_main;
+
return 'N/A' unless ! $agentnums
- or grep { $_ == $self->cust_main->agentnum } @$agentnums;
+ or grep { $_ == $cust_main->agentnum } @$agentnums;
return ''
- unless $self->cust_main->total_owed_date($self->_date) > $balance_over;
+ unless $cust_main->total_owed_date($self->_date) > $balance_over;
$invoice_from ||= $self->_agent_invoice_from || #XXX should go away
- $conf->config('invoice_from', $self->cust_main->agentnum );
+ $conf->config('invoice_from', $cust_main->agentnum );
my %opt = (
'template' => $template,
'notice_name' => ( $notice_name || 'Invoice' ),
);
- my @invoicing_list = $self->cust_main->invoicing_list;
+ my @invoicing_list = $cust_main->invoicing_list;
#$self->email_invoice(\%opt)
$self->email(\%opt)
- if grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list or !@invoicing_list;
+ if ( grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list or !@invoicing_list )
+ && ! $self->invoice_noemail;
#$self->print_invoice(\%opt)
$self->print(\%opt)
} elsif ( lc($opt{'format'}) eq 'oneline' ) { #name?
my ($previous_balance) = $self->previous;
+ $previous_balance = sprintf('%.2f', $previous_balance);
my $totaldue = sprintf('%.2f', $self->owed + $previous_balance);
my @items = map {
($_->{pkgnum} || ''),
$self->invnum,
$self->charged,
$totaldue,
+ $previous_balance,
+ $self->due_date2str("%x"),
@items,
);
my $late_sections = [];
my $extra_sections = [];
my $extra_lines = ();
+
+ my $default_section = { 'description' => '',
+ 'subtotal' => '',
+ 'no_subtotal' => 1,
+ };
+
if ( $multisection ) {
($extra_sections, $extra_lines) =
$self->_items_extra_usage_sections($escape_function_nonbsp, $format)
}
} else {# not multisection
# make a default section
- push @sections, { 'description' => '', 'subtotal' => '',
- 'no_subtotal' => 1 };
+ push @sections, $default_section;
# and calculate the finance charge total, since it won't get done otherwise.
# XXX possibly other totals?
# XXX possibly finance_pkgclass should not be used in this manner?
}
}
- unless ( $conf->exists('disable_previous_balance', $agentnum)
- || $conf->exists('previous_balance-summary_only')
- )
- {
+ # 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;
ext_description => [],
};
$detail->{'ref'} = $line_item->{'pkgnum'};
+ $detail->{'pkgpart'} = $line_item->{'pkgpart'};
$detail->{'quantity'} = 1;
- $detail->{'section'} = $previous_section;
+ $detail->{'section'} = $multisection ? $previous_section
+ : $default_section;
$detail->{'description'} = &$escape_function($line_item->{'description'});
if ( exists $line_item->{'ext_description'} ) {
@{$detail->{'ext_description'}} = map {
}
}
-
- 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) ];
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'});
$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;
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 ) );
];
push @buf,['',''];
}
-
- unless ( $conf->exists('disable_previous_balance', $agentnum) ) {
+
+ # 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
if ( $display->post_total && !$summarypage ) {
if (! $type || $type eq 'S') {
$late_subtotal{$section} += $cust_bill_pkg->setup
- if $cust_bill_pkg->setup != 0;
+ if $cust_bill_pkg->setup != 0
+ || $cust_bill_pkg->setup_show_zero;
}
if (! $type) {
$late_subtotal{$section} += $cust_bill_pkg->recur
- if $cust_bill_pkg->recur != 0;
+ if $cust_bill_pkg->recur != 0
+ || $cust_bill_pkg->recur_show_zero;
}
if ($type && $type eq 'R') {
$late_subtotal{$section} += $cust_bill_pkg->recur - $usage
- if $cust_bill_pkg->recur != 0;
+ if $cust_bill_pkg->recur != 0
+ || $cust_bill_pkg->recur_show_zero;
}
if ($type && $type eq 'U') {
if (! $type || $type eq 'S') {
$subtotal{$section} += $cust_bill_pkg->setup
- if $cust_bill_pkg->setup != 0;
+ if $cust_bill_pkg->setup != 0
+ || $cust_bill_pkg->setup_show_zero;
}
if (! $type) {
$subtotal{$section} += $cust_bill_pkg->recur
- if $cust_bill_pkg->recur != 0;
+ if $cust_bill_pkg->recur != 0
+ || $cust_bill_pkg->recur_show_zero;
}
if ($type && $type eq 'R') {
$subtotal{$section} += $cust_bill_pkg->recur - $usage
- if $cust_bill_pkg->recur != 0;
+ if $cust_bill_pkg->recur != 0
+ || $cust_bill_pkg->recur_show_zero;
}
if ($type && $type eq 'U') {
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
+
my @b = ();
my ($s, $r, $u) = ( undef, undef, undef );
foreach my $cust_bill_pkg ( @$cust_bill_pkgs )
}
}
+ my @cust_bill_pkg_display = $cust_bill_pkg->cust_bill_pkg_display;
+
warn "$me _items_cust_bill_pkg considering cust_bill_pkg ".
$cust_bill_pkg->billpkgnum. ", pkgnum ". $cust_bill_pkg->pkgnum. "\n"
if $DEBUG > 1;
}
#grep { !$_->summary || !$summary_page } # bunk!
grep { !$_->summary || $multisection }
- $cust_bill_pkg->cust_bill_pkg_display
+ @cust_bill_pkg_display
)
{
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');
$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,
my $description = ($is_summary && $type && $type eq 'U')
? "Usage charges" : $desc;
+ #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)
) {
my $time_period;
- my $date_style = $conf->config('cust_bill-line_item-date_style');
+ my $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' ) {
+ my $desc = $conf->config( 'cust_bill-line_item-date_description',
+ $cust_main->agentnum
+ );
+ $desc .= ' ' unless $desc =~ /\s$/;
+ $time_period = $desc. time2str('%B', $cust_bill_pkg->sdate);
} else {
$time_period = time2str($date_format, $cust_bill_pkg->sdate).
" - ". time2str($date_format, $cust_bill_pkg->edate);
} 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,
} 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,
push @search, "cust_main.agentnum = $1";
}
- #agentnum
+ #refnum
+ if ( $param->{'refnum'} =~ /^(\d+)$/ ) {
+ push @search, "cust_main.refnum = $1";
+ }
+
+ #custnum
if ( $param->{'custnum'} =~ /^(\d+)$/ ) {
push @search, "cust_bill.custnum = $1";
}