X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_bill.pm;h=165bb1a913e8fc54e243e20cf7384127c9b66016;hb=48fc9f425ec3454f4346089318994ae6c1e080a8;hp=a61adde459ea841bb074cdbd6d1d784ddb370ea8;hpb=54db570dc261f7cde343fa78ef92855f6d576570;p=freeside.git diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index a61adde45..165bb1a91 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -15,7 +15,6 @@ use GD::Barcode; use FS::UID qw( datasrc ); use FS::Misc qw( send_email send_fax do_print ); use FS::Record qw( qsearch qsearchs dbh ); -use FS::cust_main; use FS::cust_statement; use FS::cust_bill_pkg; use FS::cust_bill_pkg_display; @@ -25,12 +24,10 @@ use FS::cust_pay; use FS::cust_pkg; use FS::cust_credit_bill; use FS::pay_batch; -use FS::cust_pay_batch; use FS::cust_bill_event; use FS::cust_event; use FS::part_pkg; use FS::cust_bill_pay; -use FS::cust_bill_pay_batch; use FS::part_bill_event; use FS::payby; use FS::bill_batch; @@ -161,7 +158,7 @@ sub notice_name { $self->conf->config('notice_name') || 'Invoice' } -sub cust_linked { $_[0]->cust_main_custnum; } +sub cust_linked { $_[0]->cust_main_custnum || $_[0]->custnum } sub cust_unlinked_msg { my $self = shift; "WARNING: can't find cust_main.custnum ". $self->custnum. @@ -492,7 +489,9 @@ sub cust_bill_pkg { qsearch( { 'table' => 'cust_bill_pkg', 'hashref' => { 'invnum' => $self->invnum }, - 'order_by' => 'ORDER BY billpkgnum', + 'order_by' => 'ORDER BY billpkgnum', #important? otherwise we could use + # the AUTLOADED FK search. or should + # that default to ORDER by the pkey? } ); } @@ -634,13 +633,6 @@ sub num_cust_event { Returns the customer (see L) for this invoice. -=cut - -sub cust_main { - my $self = shift; - qsearchs( 'cust_main', { 'custnum' => $self->custnum } ); -} - =item cust_suspend_if_balance_over AMOUNT Suspends the customer associated with this invoice if the total amount owed on @@ -701,16 +693,6 @@ sub cust_pay { #; } -sub cust_pay_batch { - my $self = shift; - qsearch('cust_pay_batch', { 'invnum' => $self->invnum } ); -} - -sub cust_bill_pay_batch { - my $self = shift; - qsearch('cust_bill_pay_batch', { 'invnum' => $self->invnum } ); -} - =item cust_bill_pay Returns all payment applications (see L) for this invoice. @@ -1414,7 +1396,7 @@ sub email { 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"; } @@ -1489,7 +1471,7 @@ I, if specified, overrides "Invoice" as the name of the sent docume 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"; @@ -1515,7 +1497,7 @@ sub print { 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"; } @@ -1550,7 +1532,7 @@ sub fax_invoice { 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"; } @@ -1677,6 +1659,7 @@ sub send_csv { 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"; @@ -1970,14 +1953,15 @@ sub print_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; @@ -1988,7 +1972,7 @@ sub print_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); @@ -2232,7 +2216,7 @@ sub print_csv { $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 @@ -2269,7 +2253,7 @@ sub print_csv { ? time2str("%x", $cust_bill_pkg->sdate) : '' ), ($cust_bill_pkg->edate - ?time2str("%x", $cust_bill_pkg->edate) + ? time2str("%x", $cust_bill_pkg->edate) : '' ), ); @@ -2983,7 +2967,7 @@ sub _items_previous { 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', @@ -3015,14 +2999,22 @@ sub _items_credits { #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; } @@ -3039,7 +3031,7 @@ sub _items_credits { # " (". 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), }; } @@ -3050,18 +3042,32 @@ sub _items_credits { 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; } @@ -3069,8 +3075,9 @@ sub _items_payments { 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($date_format, $cust_pay->_date ); + $desc .= $self->mt(' via ') . + $cust_pay->payby_payinfo_pretty( $self->cust_main->locale ) if $detailed; push @b, { @@ -3379,13 +3386,25 @@ sub search_sql_where { 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