1 <% $payment. ' '. $info. $desc.
2 $view. $email. $change_pkg. $apply. $refund. $void. $delete. $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');
175 $refund = qq! (<A HREF="${p}edit/cust_refund.cgi?payby=$1;!.
176 qq!paynum=!. $cust_pay->paynum. '"'.
177 qq! TITLE="! . $refundtitle
178 . '">' . emt('refund') . '</A>)';
180 $refund = '' if ($cust_pay->batchnum && !FS::pay_batch->can_handle_electronic_refunds);
183 my $voidmsg = $cust_pay->payby =~ /^(CARD|CHEK)$/
184 ? ' (' . emt('do not send anything to the payment gateway').')'
186 $void = areyousure_link("${p}misc/void-cust_pay.cgi?".$cust_pay->paynum,
187 emt('Are you sure you want to void this payment?'),
188 emt('Void this payment from the database') . $voidmsg,
191 if $cust_pay->closed !~ /^Y/i
192 && ( ( $cust_pay->payby eq 'CARD' && $opt{'Credit card void'} )
193 || ( $cust_pay->payby eq 'CHEK' && $opt{'Echeck void'} )
194 || ( $cust_pay->payby !~ /^(CARD|CHEK)$/ && $opt{'Void payments'} )
198 $delete = areyousure_link("${p}misc/delete-cust_pay.cgi?".$cust_pay->paynum,
199 emt('Are you sure you want to delete this payment?'),
200 emt('Delete this payment from the database completely - not recommended'),
203 if $cust_pay->closed !~ /^Y/i
204 && $opt{'deletepayments'}
205 && $opt{'Delete payment'};
208 if ($opt{'Unapply payment'} && !$cust_pay->closed) {
209 $unapply = areyousure_link("${p}misc/unapply-cust_pay.cgi?".$cust_pay->paynum,
210 emt('Are you sure you want to unapply this payment from invoices?'),
211 emt('Keep this payment, but dissociate it from the invoices it is currently applied against'),
215 $unapply .= areyousure_link("${p}misc/unapply-cust_pay_refund.cgi?".$cust_pay->paynum,
216 emt('Are you sure you want to unapply this payment from refunds?'),
217 emt('Keep this payment, but dissociate it from the refunds it is currently applied to'),
218 emt('unapply refunds')
220 if $cust_pay->refund_to_unapply;