%#display payment history %my $money_char = $conf->config('money_char') || '$'; % %sub balance_forward_row { % my( $b, $date, $money_char ) = @_; % ( my $balance_forward = $money_char. $b ) =~ s/^\$\-/- \$/; %} % %my $balance = 0; %my %target = (); % %my $years = $conf->config('payment_history-years') || 2; %my $older_than = time - $years * 31556926; #60*60*24*365.2422 %my $hidden = 0; %my $seen = 0; %my $old_history = 0; %my $lastdate = 0; % %foreach my $item ( sort { $a->{'date'} <=> $b->{'date'} } @history ) { % % $lastdate = $item->{'date'}; % % my $display; % if ( $item->{'date'} < $older_than ) { % $display = ' STYLE="display:none" '; % $hidden = 1; % } else { % % $display = ''; % % if ( $hidden && ! $seen++ ) { % balance_forward_row($balance, $item->{'date'}, $money_char); % } % % } % % if ( $bgcolor eq $bgcolor1 ) { % $bgcolor = $bgcolor2; % } else { % $bgcolor = $bgcolor1; % } % % my $charge = exists($item->{'charge'}) % ? sprintf("$money_char\%.2f", $item->{'charge'}) % : exists($item->{'charge_nobal'}) % ? sprintf("$money_char\%.2f", $item->{'charge_nobal'}) % : ''; % % my $payment = exists($item->{'payment'}) % ? sprintf("- $money_char\%.2f", $item->{'payment'}) % : ''; % % $payment ||= sprintf( "- $money_char\%.2f", % $item->{'void_payment'} % ) % if exists($item->{'void_payment'}); % % my $credit = exists($item->{'credit'}) % ? sprintf("- $money_char\%.2f", $item->{'credit'}) % : ''; % % my $refund = exists($item->{'refund'}) % ? sprintf("$money_char\%.2f", $item->{'refund'}) % : ''; % % my $target = exists($item->{'target'}) ? $item->{'target'} : ''; % % $balance += $item->{'charge'} if exists $item->{'charge'}; % $balance -= $item->{'payment'} if exists $item->{'payment'}; % $balance -= $item->{'credit'} if exists $item->{'credit'}; % $balance += $item->{'refund'} if exists $item->{'refund'}; % $balance = sprintf("%.2f", $balance); % $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp % ( my $showbalance = $money_char. $balance ) =~ s/^\$\-/- \$/; % % > % } %if ( scalar(@history) && $hidden && ! $seen++ ) { % balance_forward_row($balance, $lastdate, $money_char); %}
%# payment links % my $s = 0; % if ( $payby{'BILL'} && $curuser->access_right(['Post payment', 'Post check payment' ]) ) { <% $s++ ? ' | ' : '' %> <& /elements/popup_link-cust_main.html, 'label' => emt('Enter check payment'), 'action' => "${p}edit/cust_pay.cgi?popup=1;payby=BILL", 'cust_main' => $cust_main, 'actionlabel' => emt('Enter check payment'), 'width' => 392, &> % } % if ( $payby{'CASH'} && $curuser->access_right(['Post payment', 'Post cash payment']) ) { <% $s++ ? ' | ' : '' %> <& /elements/popup_link-cust_main.html, 'label' => emt('Enter cash payment'), 'action' => "${p}edit/cust_pay.cgi?popup=1;payby=CASH", 'cust_main' => $cust_main, 'actionlabel' => emt('Enter cash payment'), 'width' => 392, &> % } % if ( $payby{'WEST'} && $curuser->access_right('Post payment') ) { <% $s++ ? ' | ' : '' %> <% mt('Enter Western Union payment') |h %> % }
% $s=0; % if ( ( $payby{'CARD'} || $payby{'DCRD'} ) % && $curuser->access_right(['Process payment', 'Process credit card payment']) % && ! $cust_main->is_encrypted($cust_main->payinfo) % ) { <% $s++ ? ' | ' : '' %> <% mt('Process credit card payment') |h %> % } % if ( ( $payby{'CHEK'} || $payby{'DCHK'} ) % && $curuser->access_right(['Process payment', 'Process Echeck payment']) % && ! $cust_main->is_encrypted($cust_main->payinfo) % ) { <% $s++ ? ' | ' : '' %> <% mt('Process electronic check (ACH) payment') |h %> % } % if ( $payby{'MCRD'} && $curuser->access_right('Post payment') ) { <% $s++ ? ' | ' : '' %> <% mt('Post manual (offline/POS) credit card payment') |h %> % }
%# credit link % if ( $curuser->access_right('Post credit') ) { <& /elements/popup_link-cust_main.html, 'label' => emt('Enter credit'), 'action' => "${p}edit/cust_credit.cgi", 'cust_main' => $cust_main, 'actionlabel' => emt('Enter credit'), 'width' => 616, #make room for reasons #540 default &>
% } %# refund links % $s = 0; % if ( $payby{'BILL'} && $curuser->access_right(['Post refund', 'Post check refund']) ) { <% $s++ ? ' | ' : '' %> <& /elements/popup_link-cust_main.html, 'label' => emt('Enter check refund'), 'action' => "${p}edit/cust_refund.cgi?popup=1;payby=BILL", 'cust_main' => $cust_main, 'actionlabel' => emt('Enter check refund'), 'width' => 392, &> % } % if ( $payby{'CASH'} && $curuser->access_right(['Post refund', 'Post cash refund']) ) { <% $s++ ? ' | ' : '' %> <& /elements/popup_link-cust_main.html, 'label' => emt('Enter cash refund'), 'action' => "${p}edit/cust_refund.cgi?popup=1;payby=CASH", 'cust_main' => $cust_main, 'actionlabel' => emt('Enter cash refund'), 'width' => 392, &> % } %# someday, perhaps. very few gateways let you do unlinked refunds at all. %# Authorize.net makes you sign a special form %# %# % if ( ( $payby{'CARD'} || $payby{'DCRD'} ) %# % && $curuser->access_right('Process refund') %# % && ! $cust_main->is_encrypted($cust_main->payinfo) %# % ) { %# <% $s++ ? ' | ' : '' %> %# Process credit card refund %# % } %# %# % if ( ( $payby{'CHEK'} || $payby{'DCHK'} ) %# % && $curuser->access_right('Process refund') %# % && ! $cust_main->is_encrypted($cust_main->payinfo) %# % ) { %# <% $s++ ? ' | ' : '' %> %# Process electronic check (ACH) refund %# % } % if ( $payby{'MCRD'} && $curuser->access_right('Post refund') ) { <% $s++ ? ' | ' : '' %> <% mt('Post manual (offline/POS) credit card refund') |h %> % }
%# invoice reports % if ( $curuser->access_right('List invoices') ) { <% mt('Invoice reports') |h %> % }
%# XXX payments, credits, refund reports %# tax exemption link % my $view_exemptions = $curuser->access_right('View customer tax exemptions'); % my $add_adjustment = ( $conf->exists('enable_tax_adjustments') % && $curuser->access_right('Add customer tax adjustment') % ); % if ( $view_exemptions || $add_adjustment ) { % if ( $view_exemptions ) { <% mt('View tax exemptions') |h %> <% $add_adjustment ? '|' : '' %> % } % if ( $add_adjustment ) { <& /elements/popup_link.html, { 'action' => $p.'edit/cust_tax_adjustment.html?custnum='. $cust_main->custnum, 'label' => emt('Add tax adjustment'), 'actionlabel' => emt('Add tax adjustment'), 'height' => 200, } &> | <% mt('View tax adjustments') |h %> % }
% } %# batched payment links % if ( ( $conf->exists('batch-enable') || $conf->config('batch-enable_payby') ) % && $curuser->access_right('View customer batched payments') % ) % { <% mt('View batched payments:') |h %> % foreach my $status (qw( Queued In-transit Complete All )) { <% mt($status) |h %> <% $status ne 'All' ? '|' : '' %> % }
% } %# pending payment links % if ( $curuser->access_right('View customer pending payments') % && scalar($cust_main->cust_pay_pending) % ) % { <% mt('View pending payments') |h %>
% }
%# and now the table <& /elements/table-grid.html &> % my $bgcolor1 = '#eeeeee'; % my $bgcolor2 = '#ffffff'; % my $bgcolor = '';
<% mt('Date') |h %> <% mt('Description') |h %> <% mt('Invoice') |h %> <% mt('Payment') |h %> <% mt('In-house Credit') |h %> <% mt('Refund') |h %> <% mt('Balance') |h %>
<% time2str($date_format, $date) %> <% mt("Starting balance on [_1]", time2str($date_format, $date) ) |h %> (<% mt('show prior history') |h %>) <% $balance_forward %>
% unless ( !$target || $target{$target}++ ) { % } <% time2str($date_format, $item->{'date'}) %> % if ( $target && $target{$target} == 1 ) { % } <% $item->{'desc'} %> <% $charge %> <% $payment %> <% $credit %> <% $refund %> <% $showbalance %>
<%init> my( $cust_main ) = @_; my $custnum = $cust_main->custnum; my $conf = new FS::Conf; my $date_format = $conf->config('date_format') || '%m/%d/%Y'; my $curuser = $FS::CurrentUser::CurrentUser; my @payby = grep /\w/, $conf->config('payby'); #@payby = (qw( CARD DCRD CHEK DCHK LECB BILL CASH WEST COMP )) @payby = (qw( CARD DCRD CHEK DCHK LECB BILL CASH COMP )) unless @payby; my %payby = map { $_=>1 } @payby; my %status = ( 'Queued' => 'O', #Open 'In-transit' => 'I', 'Complete' => 'R', #Resolved 'All' => '', ); #get payment history my @history = (); my %opt = ( ( map { $_ => scalar($conf->config($_)) } qw( card_refund-days date_format ) ), ( map { $_ => $conf->exists($_) } qw( deleteinvoices deletepayments deleterefunds pkg-balances ) ) ); $opt{'date_format'} ||= '%m/%d/%Y'; #legacy invoices foreach my $legacy_cust_bill ($cust_main->legacy_cust_bill) { push @history, { 'date' => $legacy_cust_bill->_date, 'desc' => include('payment_history/legacy_invoice.html', $legacy_cust_bill, %opt ), 'charge_nobal' => $legacy_cust_bill->charged, }; } #invoices foreach my $cust_bill ($cust_main->cust_bill) { push @history, { 'date' => $cust_bill->_date, 'desc' => include('payment_history/invoice.html', $cust_bill, %opt ), 'charge' => $cust_bill->charged, }; } #statements foreach my $cust_statement ($cust_main->cust_statement) { push @history, { 'date' => $cust_statement->_date, 'desc' => include('payment_history/statement.html', $cust_statement, %opt ), #'charge' => $cust_bill->charged, }; } #payments (some false laziness w/credits) foreach my $cust_pay ($cust_main->cust_pay) { push @history, { 'date' => $cust_pay->_date, 'desc' => include('payment_history/payment.html', $cust_pay, %opt ), 'payment' => $cust_pay->paid, #'target' => $target, #XXX }; } #pending payments foreach my $cust_pay_pending ($cust_main->cust_pay_pending) { push @history, { 'date' => $cust_pay_pending->_date, 'desc' => include('payment_history/pending_payment.html', $cust_pay_pending, %opt ), 'void_payment' => $cust_pay_pending->paid, }; } #voided payments foreach my $cust_pay_void ($cust_main->cust_pay_void) { push @history, { 'date' => $cust_pay_void->_date, 'desc' => include('payment_history/voided_payment.html', $cust_pay_void, %opt ), 'void_payment' => $cust_pay_void->paid, }; } #declined payments foreach my $cust_pay_pending ($cust_main->cust_pay_pending_attempt) { push @history, { 'date' => $cust_pay_pending->_date, 'desc' => include('payment_history/attempted_payment.html', $cust_pay_pending, %opt ), 'void_payment' => $cust_pay_pending->paid, #?? #'target' => $target, #XXX }; } #credits (some false laziness w/payments) foreach my $cust_credit ($cust_main->cust_credit) { push @history, { 'date' => $cust_credit->_date, 'desc' => include('payment_history/credit.html', $cust_credit, %opt ), 'credit' => $cust_credit->amount, }; } #refunds foreach my $cust_refund ($cust_main->cust_refund) { push @history, { 'date' => $cust_refund->_date, 'desc' => include('payment_history/refund.html', $cust_refund), 'refund' => $cust_refund->refund, }; } sub translate_payby { my ($payby,$payinfo) = (shift,shift); my %payby = ( BILL => $payinfo ? emt('Check #') : '', CHEK => emt('Electronic check '), PREP => emt('Prepaid card '), CARD => emt('Credit card #'), COMP => emt('Complimentary by '), CASH => emt('Cash'), WEST => emt('Western Union'), MCRD => emt('Manual credit card'), ); $payby = (exists $payby{$payby}) ? $payby{$payby} : $payby; $payby; }; sub translate_payby_refund { my ($payby,$payinfo) = (shift,shift); my %payby = ( BILL => $payinfo ? emt('Check #') : emt('Check'), CHEK => emt('Electronic check '), CARD => emt('Credit card #'), COMP => emt('Complimentary by '), ); $payby = (exists $payby{$payby}) ? $payby{$payby} : $payby; $payby; }; sub translate_payinfo { my $object = shift; my $payby = $object->payby; my $payinfo = $object->payinfo; my $conf = new FS::Conf; if ( $payby eq 'CARD' ) { $payinfo = $object->paymask; } elsif ( $payby eq 'CHEK' ) { my( $account, $aba ) = split('@', $object->paymask ); $payinfo = emt("ABA [_1], Acct #[_2]",$aba,$account); } ($payby,$payinfo); } sub areyousure_link { my ($url,$msg,$title,$label) = (shift,shift,shift,shift); ' ('.$label.')'; }