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>)';
183 my $voidmsg = $cust_pay->payby =~ /^(CARD|CHEK)$/
184 ? ' (' . emt('do not send anything to the payment gateway').')'
187 include( '/elements/popup_link.html',
188 'label' => emt('void'),
189 'action' => "${p}misc/void-cust_pay.html?".$cust_pay->paynum,
190 'actionlabel' => emt('Void payment'),
191 'title' => emt('Void this payment from the database').
195 if $cust_pay->closed !~ /^Y/i
196 && ( ( $cust_pay->payby eq 'CARD' && $opt{'Credit card void'} )
197 || ( $cust_pay->payby eq 'CHEK' && $opt{'Echeck void'} )
198 || ( $cust_pay->payby !~ /^(CARD|CHEK)$/ && $opt{'Void payments'} )
202 if ($opt{'Unapply payment'} && !$cust_pay->closed) {
203 $unapply = areyousure_link("${p}misc/unapply-cust_pay.cgi?".$cust_pay->paynum,
204 emt('Are you sure you want to unapply this payment from invoices?'),
205 emt('Keep this payment, but dissociate it from the invoices it is currently applied against'),
209 $unapply .= areyousure_link("${p}misc/unapply-cust_pay_refund.cgi?".$cust_pay->paynum,
210 emt('Are you sure you want to unapply this payment from refunds?'),
211 emt('Keep this payment, but dissociate it from the refunds it is currently applied to'),
212 emt('unapply refunds')
214 if $cust_pay->refund_to_unapply;