my $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/cust_bill";
mkdir $spooldir, 0700 unless -d $spooldir;
+ # don't localize dates here, they're a defined format
my $tracctnum = $self->invnum. time2str('-%Y%m%d%H%M%S', time);
my $file = "$spooldir/$tracctnum.csv";
my $pmt_cr_applied = 0;
$pmt_cr_applied += $_->{'amount'}
- foreach ( $self->_items_payments, $self->_items_credits ) ;
+ foreach ( $self->_items_payments(%opt), $self->_items_credits(%opt) ) ;
my $totaldue = sprintf('%.2f', $self->owed + $previous_balance);
? time2str("%x", $cust_bill_pkg->sdate)
: '' ),
($cust_bill_pkg->edate
- ?time2str("%x", $cust_bill_pkg->edate)
+ ? time2str("%x", $cust_bill_pkg->edate)
: '' ),
);
#invoice info
'invnum' => $self->invnum,
'_date' => $self->_date,
- 'date' => time2str($date_format, $self->_date),
- 'today' => time2str($date_format_long, $today),
+ 'date' => $self->time2str_local($date_format, $self->_date),
+ 'today' => $self->time2str_local($date_format_long, $today),
'terms' => $self->terms,
'template' => $template, #params{'template'},
'notice_name' => ($params{'notice_name'} || 'Invoice'),#escape_function?
);
- #localization
- my $lh = FS::L10N->get_handle( $params{'locale'} || $cust_main->locale );
+ #localization (see FS::cust_main_Mixin)
$invoice_data{'emt'} = sub { &$escape_function($self->mt(@_)) };
- my %info = FS::Locales->locale_info($cust_main->locale || 'en_US');
- # eval to avoid death for unimplemented languages
- my $dh = eval { Date::Language->new($info{'name'}) } ||
- Date::Language->new(); # fall back to English
# prototype here to silence warnings
- $invoice_data{'time2str'} = sub ($;$$) { $dh->time2str(@_) };
- # eventually use this date handle everywhere in here, too
+ $invoice_data{'time2str'} = sub ($;$$) { $self->time2str_local(@_) };
my $min_sdate = 999999999999;
my $max_edate = 0;
}
$invoice_data{'bill_period'} = '';
- $invoice_data{'bill_period'} = time2str('%e %h', $min_sdate)
- . " to " . time2str('%e %h', $max_edate)
+ $invoice_data{'bill_period'} = $self->time2str_local('%e %h', $min_sdate)
+ . " to " .
+ $self->time2str_local('%e %h', $max_edate)
if ($max_edate != 0 && $min_sdate != 999999999999);
$invoice_data{finance_section} = '';
# credits
my $credittotal = 0;
- foreach my $credit ( $self->_items_credits('trim_len'=>60) ) {
+ foreach my $credit (
+ $self->_items_credits( 'template' => $template, 'trim_len' => 60)
+ ) {
my $total;
$total->{'total_item'} = &$escape_function($credit->{'description'});
$invoice_data{'credittotal'} = sprintf('%.2f', $credittotal);
#credits (again)
- foreach my $credit ( $self->_items_credits('trim_len'=>32) ) {
+ foreach my $credit (
+ $self->_items_credits( 'template' => $template, 'trim_len' => 32)
+ ) {
push @buf, [ $credit->{'description'}, $money_char.$credit->{'amount'} ];
}
# payments
my $paymenttotal = 0;
- foreach my $payment ( $self->_items_payments ) {
+ foreach my $payment (
+ $self->_items_payments( 'template' => $template )
+ ) {
my $total = {};
$total->{'total_item'} = &$escape_function($payment->{'description'});
$paymenttotal += $payment->{'amount'};
sub due_date2str {
my $self = shift;
- $self->due_date ? time2str(shift, $self->due_date) : '';
+ $self->due_date ? $self->time2str_local(shift, $self->due_date) : '';
}
sub balance_due_msg {
my $duedate = '';
if ( $conf->exists('invoice_default_terms')
&& $conf->config('invoice_default_terms')=~ /^\s*Net\s*(\d+)\s*$/ ) {
- $duedate = time2str($rdate_format, $self->_date + ($1*86400) );
+ $duedate = $self->time2str_local($rdate_format, $self->_date + ($1*86400) );
}
$duedate;
}
sub _date_pretty {
my $self = shift;
- time2str($date_format, $self->_date);
+ $self->time2str_local($date_format, $self->_date);
}
=item _items_sections LATE SUMMARYPAGE ESCAPE EXTRA_SECTIONS FORMAT
foreach ( @pr_cust_bill ) {
my $date = $conf->exists('invoice_show_prior_due_date')
? 'due '. $_->due_date2str($date_format)
- : time2str($date_format, $_->_date);
+ : $self->time2str_local($date_format, $_->_date);
push @b, {
'description' => $self->mt('Previous Balance, Invoice #'). $_->invnum. " ($date)",
#'pkgpart' => 'N/A',
$cust_main->agentnum
);
if ( defined($date_style) && $date_style eq 'month_of' ) {
- $time_period = time2str('The month of %B', $cust_bill_pkg->sdate);
+ $time_period = $self->mt('The month of [_1]',
+ $self->time2str_local('%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);
+ $time_period = $desc. $self->time2str_local('%B', $cust_bill_pkg->sdate);
} else {
- $time_period = time2str($date_format, $cust_bill_pkg->sdate).
- " - ". time2str($date_format, $cust_bill_pkg->edate);
+ $time_period = $self->time2str_local($date_format, $cust_bill_pkg->sdate).
+ " - ". $self->time2str_local($date_format, $cust_bill_pkg->edate);
}
$description .= " ($time_period)";
}
if ( $cust_bill_pkg->recur != 0 ) {
push @b, {
'description' => "$desc (".
- time2str($date_format, $cust_bill_pkg->sdate). ' - '.
- time2str($date_format, $cust_bill_pkg->edate). ')',
+ $self->time2str_local($date_format, $cust_bill_pkg->sdate). ' - '.
+ $self->time2str_local($date_format, $cust_bill_pkg->edate). ')',
'amount' => sprintf("%.2f", $cust_bill_pkg->recur),
};
}
#credits
my @objects;
if ( $self->conf->exists('previous_balance-payments_since') ) {
- my $date = 0;
- $date = $self->previous_bill->_date if $self->previous_bill;
- @objects = qsearch('cust_credit', {
- 'custnum' => $self->custnum,
- '_date' => {op => '>=', value => $date},
+ if ( $opt{'template'} eq 'statement' ) {
+ # then the current bill is a "statement" (i.e. an invoice sent as
+ # a payment receipt)
+ # and in that case we want to see payments on or after THIS invoice
+ @objects = qsearch('cust_credit', {
+ 'custnum' => $self->custnum,
+ '_date' => {op => '>=', value => $self->_date},
});
- # hard to do this in the qsearch...
- @objects = grep { $_->_date < $self->_date } @objects;
+ } else {
+ my $date = 0;
+ $date = $self->previous_bill->_date if $self->previous_bill;
+ @objects = qsearch('cust_credit', {
+ 'custnum' => $self->custnum,
+ '_date' => {op => '>=', value => $date},
+ });
+ }
} else {
@objects = $self->cust_credited;
}
# " (". time2str("%x",$_->cust_credit->_date) .")".
# $reason,
'description' => $self->mt('Credit applied').' '.
- time2str($date_format,$obj->_date). $reason,
+ $self->time2str_local($date_format,$obj->_date). $reason,
'amount' => sprintf("%.2f",$obj->amount),
};
}
sub _items_payments {
my $self = shift;
+ my %opt = @_;
my @b;
my $detailed = $self->conf->exists('invoice_payment_details');
my @objects;
if ( $self->conf->exists('previous_balance-payments_since') ) {
- my $date = 0;
- $date = $self->previous_bill->_date if $self->previous_bill;
- @objects = qsearch('cust_pay', {
+ # then show payments dated on/after the previous bill...
+ if ( $opt{'template'} eq 'statement' ) {
+ # then the current bill is a "statement" (i.e. an invoice sent as
+ # a payment receipt)
+ # and in that case we want to see payments on or after THIS invoice
+ @objects = qsearch('cust_pay', {
+ 'custnum' => $self->custnum,
+ '_date' => {op => '>=', value => $self->_date},
+ });
+ } else {
+ # the normal case: payments on or after the previous invoice
+ my $date = 0;
+ $date = $self->previous_bill->_date if $self->previous_bill;
+ @objects = qsearch('cust_pay', {
'custnum' => $self->custnum,
'_date' => {op => '>=', value => $date},
});
- @objects = grep { $_->_date < $self->_date } @objects;
+ # and before the current bill...
+ @objects = grep { $_->_date < $self->_date } @objects;
+ }
} else {
@objects = $self->cust_bill_pay;
}
foreach my $obj (@objects) {
my $cust_pay = $obj->isa('FS::cust_pay') ? $obj : $obj->cust_pay;
my $desc = $self->mt('Payment received').' '.
- time2str($date_format, $cust_pay->_date );
+ $self->time2str_local($date_format, $cust_pay->_date );
$desc .= $self->mt(' via ') .
$cust_pay->payby_payinfo_pretty( $self->cust_main->locale )
if $detailed;