1 <% $payment. ' '. $info. $desc.
2 $view. $email. $change_pkg. $apply. $refund. $void. $unapply
6 my( $cust_pay, %opt ) = @_;
8 my $date_format = $opt{'date_format'} || '%m/%d/%Y';
10 my @cust_bill_pay = $cust_pay->cust_bill_pay;
11 my @cust_pay_refund = $cust_pay->cust_pay_refund;
12 my $unapplied = $cust_pay->unapplied;
14 my ($payby,$payinfo) = translate_payinfo($cust_pay);
15 my $target = "$payby$payinfo";
16 $payby = translate_payby($payby,$payinfo);
17 my $info = $payby ? "($payby$payinfo)" : '';
20 if ( $opt{'pkg-balances'} && $cust_pay->pkgnum ) {
21 my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cust_pay->pkgnum } );
22 $desc .= ' for '. $cust_pkg->pkg_label_long;
25 my %cust_bill_pay_width = ('width' => 392);
26 my %cust_bill_pay_height = ();
27 if ( $opt{'cust_bill_pay_pkg-manual'} ) {
28 %cust_bill_pay_width = ('width' => 592);
29 %cust_bill_pay_height = ('height' => 436);
34 my $italicize_otaker = 0;
35 my $otaker = $cust_pay->otaker;
36 if ( $otaker eq 'fs_daily' ) {
37 $otaker = 'auto billing';
38 $italicize_otaker = 1;
40 if ( $otaker eq 'fs_selfservice' ) {
41 $otaker = 'customer self-service';
42 $italicize_otaker = 1;
45 my $payment = emt("Payment by [_1]",$otaker);
46 $payment =~ s/$otaker/<i>$otaker<\/i>/ if $italicize_otaker;
48 if ( scalar(@cust_bill_pay) == 0
49 && scalar(@cust_pay_refund) == 0 ) {
51 $payment = emt("Unapplied Payment by [_1]",$otaker);
52 $payment =~ s/$otaker/<i>$otaker<\/i>/ if $italicize_otaker;
53 $payment = '<B><FONT COLOR="#FF0000">'.$payment.'</FONT></B>';
54 } elsif ( scalar(@cust_bill_pay) == 1
55 && scalar(@cust_pay_refund) == 0
56 && $unapplied == 0 ) {
57 #applied to one invoice, the usual situation
58 $desc .= ' '. $cust_bill_pay[0]->applied_to_invoice;
59 } elsif ( scalar(@cust_bill_pay) == 0
60 && scalar(@cust_pay_refund) == 1
61 && $unapplied == 0 ) {
62 #applied to one refund
63 $desc .= emt(" refunded on [_1]", time2str($date_format, $cust_pay_refund[0]->_date) );
67 foreach my $app ( sort { $a->_date <=> $b->_date }
68 ( @cust_bill_pay, @cust_pay_refund ) ) {
69 if ( $app->isa('FS::cust_bill_pay') ) {
70 $desc .= ' ' . $opt{money_char} . $app->amount . ' ' .
71 $app->applied_to_invoice . '<BR>';
72 } elsif ( $app->isa('FS::cust_pay_refund') ) {
73 $desc .= ' ' .
74 emt("[_1][_2] refunded on [_3]", $opt{money_char}, $app->amount,
75 time2str($date_format, $app->_date) ) . '<BR>';
77 die "$app is not a FS::cust_bill_pay or FS::cust_pay_refund";
80 if ( $unapplied > 0 ) {
81 $desc .= ' '.
82 '<B><FONT COLOR="#FF0000">'.
83 emt("[_1][_2] unapplied", $opt{money_char}, $unapplied).
90 if ( $opt{'Apply payment'} ) {
91 if ( $opt{total_owed} > 0 ) {
93 include( '/elements/popup_link.html',
94 'label' => emt('apply'),
95 'action' => "${p}edit/cust_bill_pay.cgi?".
97 'actionlabel' => emt('Apply payment'),
99 %cust_bill_pay_height,
103 if ( $opt{total_unapplied_refunds} > 0 ) {
105 include( '/elements/popup_link.html',
106 'label' => emt('apply refund'),
107 'style' => 'white-space: nowrap',
108 'action' => "${p}edit/cust_pay_refund.cgi?".
110 'actionlabel' => emt('Apply payment to refund'),
115 $apply .= ' (auto‑apply: '
116 . ($cust_pay->no_auto_apply ? 'no' : 'yes')
118 . include( '/elements/popup_link.html',
119 'label' => emt($cust_pay->no_auto_apply ? 'yes' : 'no'),
120 'action' => "${p}edit/process/cust_pay-no_auto_apply.cgi?paynum="
123 . ($cust_pay->no_auto_apply ? '' : 'Y'),
124 'actionlabel' => emt('Toggle Auto-Apply'),
129 } else { # end if $opt('Apply payment')
130 $apply .= ' (no auto-apply)' if $cust_pay->no_auto_apply;
132 } # end if $unapplied > 0
135 ' ('. include('/elements/popup_link.html',
136 'label' => emt('view receipt'),
137 'action' => "${p}view/cust_pay.html?link=popup;paynum=".
139 'actionlabel' => emt('Payment Receipt'),
143 my $email = $opt{'has_email_address'} ?
144 q! (<A HREF="javascript:void(0)" ONCLICK="areyousure_popup('Send email receipt for payment to customer?','!.
145 "${p}view/cust_pay.html?link=email;paynum=".
147 q!','Email Payment Receipt')" TITLE="Send email receipt">email receipt</A>)!
151 if ( $apply && $opt{'pkg-balances'} && $cust_pay->pkgnum ) {
153 ' ('. include('/elements/popup_link.html',
154 'label' => emt('change package'),
155 'action' => "${p}edit/cust_pay-pkgnum.html?paynum=".
157 'actionlabel' => emt('Change payment package'),
164 my $refund_days = $opt{'card_refund-days'} || 120;
165 my @refund_right = grep { $opt{$_} } $FS::CurrentUser::CurrentUser->refund_rights($cust_pay->payby);
166 if ( $cust_pay->closed !~ /^Y/i
167 && $cust_pay->payby =~ /^(CARD|CHEK|BILL)$/
168 && time-$cust_pay->_date < $refund_days*86400
169 && $cust_pay->unrefunded > 0
170 && scalar(@refund_right)
172 my $refundtitle = ($cust_pay->payby =~ /^(CARD|CHEK)$/)
173 ? emt('Send a refund for this payment to the payment gateway')
174 : emt('Record a refund for this payment');
176 $refund = qq! (<A HREF="${p}edit/cust_refund.cgi?payby=$1;!.
177 qq!paynum=!. $cust_pay->paynum. '"'.
178 qq! TITLE="! . $refundtitle
179 . '">' . emt('refund') . '</A>)';
181 $refund = '' if ($cust_pay->batchnum && !FS::pay_batch->can_handle_electronic_refunds);
184 my $voidmsg = $cust_pay->payby =~ /^(CARD|CHEK)$/
185 ? ' (' . emt('do not send anything to the payment gateway').')'
188 include( '/elements/popup_link.html',
189 'label' => emt('void'),
190 'action' => "${p}misc/void-cust_pay.html?".$cust_pay->paynum,
191 'actionlabel' => emt('Void payment'),
192 'title' => emt('Void this payment from the database').
196 if $cust_pay->closed !~ /^Y/i
197 && ( ( $cust_pay->payby eq 'CARD' && $opt{'Credit card void'} )
198 || ( $cust_pay->payby eq 'CHEK' && $opt{'Echeck void'} )
199 || ( $cust_pay->payby !~ /^(CARD|CHEK)$/ && $opt{'Void payments'} )
203 if ($opt{'Unapply payment'} && !$cust_pay->closed) {
204 $unapply = areyousure_link("${p}misc/unapply-cust_pay.cgi?".$cust_pay->paynum,
205 emt('Are you sure you want to unapply this payment from invoices?'),
206 emt('Keep this payment, but dissociate it from the invoices it is currently applied against'),
210 $unapply .= areyousure_link("${p}misc/unapply-cust_pay_refund.cgi?".$cust_pay->paynum,
211 emt('Are you sure you want to unapply this payment from refunds?'),
212 emt('Keep this payment, but dissociate it from the refunds it is currently applied to'),
213 emt('unapply refunds')
215 if $cust_pay->refund_to_unapply;