use base qw( FS::Template_Mixin FS::cust_main_Mixin FS::Record );
use strict;
-use vars qw( $DEBUG $me $date_format );
+use vars qw( $DEBUG $me );
# but NOT $conf
use Fcntl qw(:flock); #for spool_csv
use Cwd;
#ask FS::UID to run this stuff for us later
FS::UID->install_callback( sub {
my $conf = new FS::Conf; #global
- $date_format = $conf->config('date_format') || '%x'; #/YY
} );
=head1 NAME
my $self = shift;
return if $self->hide;
my $conf = $self->conf;
- my $opt = shift;
+ my $opt = shift || {};
if ($opt and !ref($opt)) {
die "FS::cust_bill::email called with positional parameters";
}
sub lpr_data {
my $self = shift;
my $conf = $self->conf;
- my $opt = shift;
+ my $opt = shift || {};
if ($opt and !ref($opt)) {
# nobody does this anyway
die "FS::cust_bill::lpr_data called with positional parameters";
my $self = shift;
return if $self->hide;
my $conf = $self->conf;
- my $opt = shift;
+ my $opt = shift || {};
if ($opt and !ref($opt)) {
die "FS::cust_bill::print called with positional parameters";
}
my $self = shift;
return if $self->hide;
my $conf = $self->conf;
- my $opt = shift;
+ my $opt = shift || {};
if ($opt and !ref($opt)) {
die "FS::cust_bill::fax_invoice called with positional parameters";
}
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 $time = $opt{'time'} || time;
+ my $tracctnum = ''; #leaking out from billco-specific sections :/
if ( $format eq 'billco' ) {
my $account_num =
$self->conf->config('billco-account_num', $cust_main->agentnum);
- my $tracctnum = $account_num eq 'display_custnum'
- ? $cust_main->display_custnum
- : $opt{'tracctnum'};
+ $tracctnum = $account_num eq 'display_custnum'
+ ? $cust_main->display_custnum
+ : $opt{'tracctnum'};
my $taxtotal = 0;
$taxtotal += $_->{'amount'} foreach $self->_items_tax;
- my $duedate = $self->due_date2str('%m/%d/%Y'); #date_format?
+ my $duedate = $self->due_date2str('%m/%d/%Y'); # hardcoded, NOT date_format
my( $previous_balance, @unused ) = $self->previous; #previous balance
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);
$csv->combine(
'', # 1 | N/A-Leave Empty CHAR 2
'', # 2 | N/A-Leave Empty CHAR 15
- $opt{'tracctnum'}, # 3 | Account Number CHAR 15
+ $tracctnum, # 3 | Account Number CHAR 15
$self->invnum, # 4 | Invoice Number CHAR 15
$lineseq++, # 5 | Line Sequence (sort order) NUM 6
$item->{'description'}, # 6 | Transaction Detail CHAR 100
? time2str("%x", $cust_bill_pkg->sdate)
: '' ),
($cust_bill_pkg->edate
- ?time2str("%x", $cust_bill_pkg->edate)
+ ? time2str("%x", $cust_bill_pkg->edate)
: '' ),
);
my @b = ();
foreach ( @pr_cust_bill ) {
my $date = $conf->exists('invoice_show_prior_due_date')
- ? 'due '. $_->due_date2str($date_format)
- : time2str($date_format, $_->_date);
+ ? 'due '. $_->due_date2str('short')
+ : $self->time2str_local('short', $_->_date);
push @b, {
'description' => $self->mt('Previous Balance, Invoice #'). $_->invnum. " ($date)",
#'pkgpart' => 'N/A',
#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},
+ });
+ } else {
+ my $date = 0;
+ $date = $self->previous_bill->_date if $self->previous_bill;
+ @objects = qsearch('cust_credit', {
+ 'custnum' => $self->custnum,
+ '_date' => {op => '>=', value => $date},
});
- # hard to do this in the qsearch...
- @objects = grep { $_->_date < $self->_date } @objects;
+ }
} 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('short', $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 );
- $desc .= $self->mt(' via ' . $cust_pay->payby_payinfo_pretty)
+ $self->time2str_local('short', $cust_pay->_date );
+ $desc .= $self->mt(' via ') .
+ $cust_pay->payby_payinfo_pretty( $self->cust_main->locale )
if $detailed;
push @b, {
push @search, "cust_bill.custnum = $1";
}
- #customer classnum
+ #customer classnum (false laziness w/ cust_main/Search.pm)
if ( $param->{'cust_classnum'} ) {
- my $classnums = $param->{'cust_classnum'};
- $classnums = [ $classnums ] if !ref($classnums);
- $classnums = [ grep /^\d+$/, @$classnums ];
- push @search, 'cust_main.classnum in ('.join(',',@$classnums).')'
- if @$classnums;
+
+ my @classnum = ref( $param->{'cust_classnum'} )
+ ? @{ $param->{'cust_classnum'} }
+ : ( $param->{'cust_classnum'} );
+
+ @classnum = grep /^(\d*)$/, @classnum;
+
+ if ( @classnum ) {
+ push @search, '( '. join(' OR ', map {
+ $_ ? "cust_main.classnum = $_"
+ : "cust_main.classnum IS NULL"
+ }
+ @classnum
+ ).
+ ' )';
+ }
+
}
#_date