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