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 'action' => "${p}edit/cust_pay_refund.cgi?".
109 'actionlabel' => emt('Apply payment to refund'),
114 $apply .= ' (auto‑apply: '
115 . ($cust_pay->no_auto_apply ? 'no' : 'yes')
117 . include( '/elements/popup_link.html',
118 'label' => emt($cust_pay->no_auto_apply ? 'yes' : 'no'),
119 'action' => "${p}edit/process/cust_pay-no_auto_apply.cgi?paynum="
122 . ($cust_pay->no_auto_apply ? '' : 'Y'),
123 'actionlabel' => emt('Toggle Auto-Apply'),
128 } else { # end if $opt('Apply payment')
129 $apply .= ' (no auto-apply)' if $cust_pay->no_auto_apply;
131 } # end if $unapplied > 0
134 ' ('. include('/elements/popup_link.html',
135 'label' => emt('view receipt'),
136 'action' => "${p}view/cust_pay.html?link=popup;paynum=".
138 'actionlabel' => emt('Payment Receipt'),
142 my $email = $opt{'has_email_address'} ?
143 q! (<A HREF="javascript:void(0)" ONCLICK="areyousure_popup('Send email receipt for payment to customer?','!.
144 "${p}view/cust_pay.html?link=email;paynum=".
146 q!','Email Payment Receipt')" TITLE="Send email receipt">email receipt</A>)!
150 if ( $apply && $opt{'pkg-balances'} && $cust_pay->pkgnum ) {
152 ' ('. include('/elements/popup_link.html',
153 'label' => emt('change package'),
154 'action' => "${p}edit/cust_pay-pkgnum.html?paynum=".
156 'actionlabel' => emt('Change payment package'),
163 my $refund_days = $opt{'card_refund-days'} || 120;
164 my @refund_right = grep { $opt{$_} } $FS::CurrentUser::CurrentUser->refund_rights($cust_pay->payby);
165 if ( $cust_pay->closed !~ /^Y/i
166 && $cust_pay->payby =~ /^(CARD|CHEK|BILL)$/
167 && time-$cust_pay->_date < $refund_days*86400
168 && $cust_pay->unrefunded > 0
169 && scalar(@refund_right)
171 my $refundtitle = ($cust_pay->payby =~ /^(CARD|CHEK)$/)
172 ? emt('Send a refund for this payment to the payment gateway')
173 : emt('Record a refund for this payment');
174 $refund = qq! (<A HREF="${p}edit/cust_refund.cgi?payby=$1;!.
175 qq!paynum=!. $cust_pay->paynum. '"'.
176 qq! TITLE="! . $refundtitle
177 . '">' . emt('refund') . '</A>)';
181 my $voidmsg = $cust_pay->payby =~ /^(CARD|CHEK)$/
182 ? ' (' . emt('do not send anything to the payment gateway').')'
184 $void = areyousure_link("${p}misc/void-cust_pay.cgi?".$cust_pay->paynum,
185 emt('Are you sure you want to void this payment?'),
186 emt('Void this payment from the database') . $voidmsg,
189 if $cust_pay->closed !~ /^Y/i
190 && ( ( $cust_pay->payby eq 'CARD' && $opt{'Credit card void'} )
191 || ( $cust_pay->payby eq 'CHEK' && $opt{'Echeck void'} )
192 || ( $cust_pay->payby !~ /^(CARD|CHEK)$/ && $opt{'Void payments'} )
196 $delete = areyousure_link("${p}misc/delete-cust_pay.cgi?".$cust_pay->paynum,
197 emt('Are you sure you want to delete this payment?'),
198 emt('Delete this payment from the database completely - not recommended'),
201 if $cust_pay->closed !~ /^Y/i
202 && $opt{'deletepayments'}
203 && $opt{'Delete payment'};
206 if ($opt{'Unapply payment'} && !$cust_pay->closed) {
207 $unapply = areyousure_link("${p}misc/unapply-cust_pay.cgi?".$cust_pay->paynum,
208 emt('Are you sure you want to unapply this payment from invoices?'),
209 emt('Keep this payment, but dissociate it from the invoices it is currently applied against'),
213 $unapply .= areyousure_link("${p}misc/unapply-cust_pay_refund.cgi?".$cust_pay->paynum,
214 emt('Are you sure you want to unapply this payment from refunds?'),
215 emt('Keep this payment, but dissociate it from the refunds it is currently applied to'),
216 emt('unapply refunds')
218 if $cust_pay->refund_to_unapply;