35f57e8d6dd9498d4b38fd93d9f05de586b9b069
[freeside.git] / httemplate / misc / payment.cgi
1 <& /elements/header-cust_main.html, view=>'payment_history', cust_main=>$cust_main &>
2
3 <h2><% emt("Process [_1] payment",$type{$payby}) %></h2>
4
5 <FORM NAME="OneTrueForm" ACTION="process/payment.cgi" METHOD="POST" onSubmit="document.OneTrueForm.process.disabled=true">
6 <INPUT TYPE="hidden" NAME="custnum"   VALUE="<% $custnum %>">
7 <INPUT TYPE="hidden" NAME="payby"     VALUE="<% $payby %>">
8 <INPUT TYPE="hidden" NAME="payunique" VALUE="<% $payunique %>">
9 <INPUT TYPE="hidden" NAME="balance"   VALUE="<% $balance %>">
10
11 <& /elements/init_overlib.html &>
12
13 <TABLE class="fsinnerbox">
14
15   <& /elements/tr-amount_fee.html,
16        'amount'             => $amount,
17        'process-pkgpart'    => 
18           scalar($conf->config('manual_process-pkgpart', $cust_main->agentnum)),
19        'process-display'    => scalar($conf->config('manual_process-display')),
20        'process-skip_first' => $conf->exists('manual_process-skip_first'),
21        'num_payments'       => scalar($cust_main->cust_pay), 
22        'surcharge_percentage' =>
23          ( $payby eq 'CARD'
24              ? scalar($conf->config('credit-card-surcharge-percentage', $cust_main->agentnum))
25              : 0
26          ),
27   &>
28
29 % if ( $conf->exists('part_pkg-term_discounts') ) {
30     <& /elements/tr-select-discount_term.html,
31          'custnum'   => $custnum,
32          'amount_id' => 'amount',
33     &>
34 % }
35
36 % my $disallow_no_auto_apply = 0;
37 % if ( $conf->exists("batch-enable")
38 %      || grep $payby eq $_, $conf->config('batch-enable_payby')
39 %    ) {
40 %
41 %     if ( grep $payby eq $_, $conf->config('realtime-disable_payby') ) {
42 %       $disallow_no_auto_apply = 1;
43
44           <INPUT TYPE="hidden" NAME="batch" VALUE="1">
45
46 %     } else {
47
48           <TR>
49             <TH ALIGN="right">&nbsp;&nbsp;&nbsp;<% mt('Add to current batch') |h %></TH>
50             <TD>
51               <INPUT TYPE="checkbox" NAME="batch" VALUE="1" ID="batch_checkbox" ONCHANGE="change_batch_checkbox()">
52             </TD>
53           </TR>
54
55 %     }
56 % }
57
58 % unless ($disallow_no_auto_apply) {
59 %   # false laziness with edit/cust_pay.cgi
60
61 <TR ID="apply_box_row">
62   <TH ALIGN="right"><% mt('Auto-apply to invoices') |h %></TH>
63   <TD>
64     <SELECT NAME="apply" ID="apply_box">
65       <OPTION VALUE="yes" SELECTED><% mt('yes') |h %></OPTION> 
66       <OPTION VALUE=""><% mt('not now') |h %></OPTION>
67       <OPTION VALUE="never"><% mt('never') |h %></OPTION>
68     </SELECT>
69   </TD>
70 </TR>
71
72 % # this can go away if no_auto_apply handling gets added to batch payment processing
73 <SCRIPT>
74 function change_batch_checkbox () {
75   if (document.getElementById('batch_checkbox').checked) {
76     document.getElementById('apply_box').disabled = true;
77     document.getElementById('apply_box_row').style.display = 'none';
78   } else {
79     document.getElementById('apply_box').disabled = false;
80     document.getElementById('apply_box_row').style.display = '';
81   }
82 }
83 </SCRIPT>
84
85 % }
86
87 <SCRIPT TYPE="text/javascript">
88   function cust_payby_changed (what) {
89     var custpaybynum = what.options[what.selectedIndex].value
90     if ( custpaybynum == '' || custpaybynum == '0' ) {
91        //what.form.payinfo.disabled = false;
92        $('#cust_payby').slideDown();
93     } else {
94        //what.form.payinfo.value = '';
95        //what.form.payinfo.disabled = true;
96        $('#cust_payby').slideUp();
97     }
98   }
99 </SCRIPT>
100
101 % #can't quite handle CARD/CHEK on the same page yet, but very close
102 % #does it make sense from a UI/usability perspective?
103 %
104 % my @cust_payby = ();
105 % if ( $payby eq 'CARD' ) {
106 %   @cust_payby = $cust_main->cust_payby('CARD','DCRD');
107 % } elsif ( $payby eq 'CHEK' ) {
108 %   @cust_payby = $cust_main->cust_payby('CHEK','DCHK');
109 % } else {
110 %   die "unknown payby $payby";
111 % }
112 %
113 % my $custpaybynum = length(scalar($cgi->param('custpaybynum')))
114 %                      ? scalar($cgi->param('custpaybynum'))
115 %                      : scalar(@cust_payby) && $cust_payby[0]->custpaybynum;
116
117 <& /elements/tr-select-cust_payby.html,
118      'cust_payby' => \@cust_payby,
119      'curr_value' => $custpaybynum,
120      'onchange'   => 'cust_payby_changed(this)',
121 &>
122
123 </TABLE>
124 <BR>
125 <DIV ID="cust_payby"
126   <% $custpaybynum ? 'STYLE="display:none"'
127                    : ''
128   %>
129 >
130 <TABLE class="fsinnerbox">
131
132 % my $auto = 0;
133 % if ( $payby eq 'CARD' ) {
134 %
135 %   my( $payinfo, $paycvv, $month, $year ) = ( '', '', '', '' );
136 %   my $payname = $cust_main->first. ' '. $cust_main->getfield('last');
137 %   my $location = $cust_main->bill_location;
138
139     <TR>
140       <TH ALIGN="right"><% mt('Card number') |h %></TH>
141       <TD COLSPAN=7>
142         <TABLE>
143           <TR>
144             <TD>
145               <INPUT TYPE="text" NAME="payinfo" SIZE=20 MAXLENGTH=19 VALUE="<%$payinfo%>"> </TD>
146             <TH><% mt('Exp.') |h %></TH>
147             <TD>
148               <SELECT NAME="month">
149 % for ( ( map "0$_", 1 .. 9 ), 10 .. 12 ) { 
150
151                   <OPTION<% $_ == $month ? ' SELECTED' : '' %>><% $_ %>
152 % } 
153
154               </SELECT>
155             </TD>
156             <TD> / </TD>
157             <TD>
158               <SELECT NAME="year">
159 % my @a = localtime; for ( $a[5]+1900 .. $a[5]+1915 ) { 
160
161                   <OPTION<% $_ == $year ? ' SELECTED' : '' %>><% $_ %>
162 % } 
163
164               </SELECT>
165             </TD>
166           </TR>
167         </TABLE>
168       </TD>
169     </TR>
170     <TR>
171       <TH ALIGN="right"><% mt('CVV2') |h %></TH>
172       <TD><INPUT TYPE="text" NAME="paycvv" VALUE="<% $paycvv %>" SIZE=4 MAXLENGTH=4>
173           (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('../docs/cvv2.html', 480, 352, 'cvv2_popup' ), CAPTION, 'CVV2 Help', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE ); return false;"><% mt('help') |h %></A>)
174       </TD>
175     </TR>
176     <TR>
177       <TH ALIGN="right"><% mt('Exact name on card') |h %></TH>
178       <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%$payname%>"></TD>
179     </TR>
180
181     <& /elements/location.html,
182                   'object'         => $location,
183                   'no_asterisks'   => 1,
184                   'address1_label' => emt('Card billing address'),
185     &>
186
187 % } elsif ( $payby eq 'CHEK' ) {
188 %
189 %   my( $account, $aba, $branch, $payname, $ss, $paytype, $paystate,
190 %       $stateid, $stateid_state )
191 %     = ( '', '', '', '', '', '', '', '', '' );
192 %
193 %  #false laziness w/{edit,view}/cust_main/billing.html
194 %  my $routing_label = $conf->config('echeck-country') eq 'US'
195 %                        ? 'ABA/Routing number'
196 %                        : 'Routing number';
197 %  my $routing_size      = $conf->config('echeck-country') eq 'CA' ? 4 : 10;
198 %  my $routing_maxlength = $conf->config('echeck-country') eq 'CA' ? 3 : 9;
199
200     <INPUT TYPE="hidden" NAME="month" VALUE="12">
201     <INPUT TYPE="hidden" NAME="year" VALUE="2037">
202     <TR>
203       <TD ALIGN="right"><% mt('Account number') |h %></TD>
204       <TD><INPUT TYPE="text" SIZE=10 NAME="payinfo1" VALUE="<%$account%>"></TD>
205       <TD ALIGN="right"><% mt('Type') |h %></TD>
206       <TD><SELECT NAME="paytype"><% join('', map { qq!<OPTION VALUE="$_" !.($paytype eq $_ ? 'SELECTED' : '').">$_</OPTION>" } FS::cust_payby->paytypes) %></SELECT></TD>
207     </TR>
208     <TR>
209       <TD ALIGN="right"><% mt($routing_label) |h %></TD>
210       <TD>
211         <INPUT TYPE="text" SIZE="<% $routing_size %>" MAXLENGTH="<% $routing_maxlength %>" NAME="payinfo2" VALUE="<%$aba%>">
212         (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('../docs/ach.html', 380, 240, 'ach_popup' ), CAPTION, 'ACH Help', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE ); return false;"><% mt('help') |h %></A>)
213       </TD>
214     </TR>
215 %   if ( $conf->config('echeck-country') eq 'CA' ) {
216       <TR>
217         <TD ALIGN="right"><% mt('Branch number') |h %></TD>
218         <TD>
219           <INPUT TYPE="text" NAME="payinfo3" VALUE="<%$branch%>" SIZE=6 MAXLENGTH=5>
220         </TD>
221       </TR>
222 %   }
223     <TR>
224       <TD ALIGN="right"><% mt('Bank name') |h %></TD>
225       <TD><INPUT TYPE="text" NAME="payname" VALUE="<%$payname%>"></TD>
226     </TR>
227
228 %   if ( $conf->exists('show_bankstate') ) {
229       <TR>
230         <TD ALIGN="right"><% mt('Bank state') |h %></TD>
231         <TD><& /elements/select-state.html,
232                          'disable_empty' => 0,
233                          'empty_label'   => emt('(choose)'),
234                          'state'         => $paystate,
235                          'country'       => $cust_main->country,
236                          'prefix'        => 'pay',
237             &>
238         </TD>
239       </TR>
240 %   } else {
241       <INPUT TYPE="hidden" NAME="paystate" VALUE="<% $paystate %>">
242 %   }
243
244 %   if ( $conf->exists('show_ss') ) {
245       <TR>
246         <TD ALIGN="right">
247           <% mt('Account holder') |h %><BR>
248           <% mt('Social security or tax ID #') |h %> 
249         </TD>
250         <TD><INPUT TYPE="text" NAME="ss" VALUE="<% $ss %>"></TD>
251       </TR>
252 %   } else {
253       <INPUT TYPE="hidden" NAME="ss" VALUE="<% $ss %>"></TD>
254 %   }
255
256 %   if ( $conf->exists('show_stateid') ) {
257       <TR>
258         <TD ALIGN="right">
259           <% mt('Account holder') |h %><BR>
260           <% mt("Driver's license or state ID #") |h %> 
261         </TD>
262         <TD><INPUT TYPE="text" NAME="stateid" VALUE="<% $stateid %>"></TD>
263         <TD ALIGN="right"><% mt('State') |h %></TD>
264         <TD><& /elements/select-state.html,
265                          'disable_empty' => 0,
266                          'empty_label'   => emt('(choose)'),
267                          'state'         => $stateid_state,
268                          'country'       => $cust_main->country,
269                          'prefix'        => 'stateid_',
270             &>
271         </TD>
272       </TR>
273 %   } else {
274       <INPUT TYPE="hidden" NAME="stateid" VALUE="<% $stateid %>">
275       <INPUT TYPE="hidden" NAME="stateid_state" VALUE="<% $stateid_state %>">
276 %   }
277
278 % } #end CARD/CHEK-specific section
279
280
281 <TR>
282   <TD COLSPAN=8>
283     <INPUT TYPE="checkbox" CHECKED NAME="save" VALUE="1">
284     <% mt('Remember this information') |h %>
285   </TD>
286 </TR>
287
288 <TR>
289   <TD COLSPAN=8>
290     <INPUT TYPE="checkbox"<% $auto ? ' CHECKED' : '' %> NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }">
291     <% mt("Charge future payments to this [_1] automatically",$type{$payby}) |h %> 
292 % if ( @cust_payby ) {
293     <% mt('as') |h %>
294     <SELECT NAME="weight">
295 %     for ( 1 .. 1+scalar(grep { $_->payby =~ /^(CARD|CHEK)$/ } @cust_payby) ) {
296         <OPTION VALUE="<%$_%>"><% mt( $weight{$_} ) |h %>
297 %     }
298     </SELECT>
299 % } else {
300     <INPUT TYPE="hidden" NAME="weight" VALUE="1">
301 % }
302   </TD>
303 </TR>
304
305 </TABLE>
306 </DIV>
307
308 <BR>
309 <INPUT TYPE="submit" NAME="process" VALUE="<% mt('Process payment') |h %>">
310 </FORM>
311
312 <& /elements/footer-cust_main.html &>
313 <%once>
314
315 my %weight = (
316   1 => 'Primary',
317   2 => 'Secondary',
318   3 => 'Tertiary',
319   4 => 'Fourth',
320   5 => 'Fifth',
321   6 => 'Sixth',
322   7 => 'Seventh',
323 );
324
325 </%once>
326 <%init>
327
328 die "access denied"
329   unless $FS::CurrentUser::CurrentUser->access_right('Process payment');
330
331 my %type = ( 'CARD' => 'credit card',
332              'CHEK' => 'electronic check (ACH)',
333            );
334
335 $cgi->param('payby') =~ /^(CARD|CHEK)$/
336   or die "unknown payby ". $cgi->param('payby');
337 my $payby = $1;
338
339 $cgi->param('custnum') =~ /^(\d+)$/
340   or die "illegal custnum ". $cgi->param('custnum');
341 my $custnum = $1;
342
343 my $cust_main = qsearchs( 'cust_main', { 'custnum'=>$custnum } );
344 die "unknown custnum $custnum" unless $cust_main;
345
346 my $balance = $cust_main->balance;
347
348 my $payinfo = '';
349
350 my $conf = new FS::Conf;
351
352 #false laziness w/selfservice make_payment.html shortcut for one-country
353 my %states = map { $_->state => 1 }
354                qsearch('cust_main_county', {
355                  'country' => $conf->config('countrydefault') || 'US'
356                } );
357 my @states = sort { $a cmp $b } keys %states;
358
359 my $amount = '';
360 if ( $balance > 0 ) {
361   # when configured to do so, amount will only auto-fill with balance
362   # if balance represents a single invoice
363   $amount = $balance
364     unless $conf->exists('manual_process-single_invoice_amount')
365       && ($cust_main->open_cust_bill != 1);
366 }
367
368 my $payunique = "webui-payment-". time. "-$$-". rand() * 2**32;
369
370 </%init>