international self-service payments, RT#1592
authorivan <ivan>
Mon, 25 May 2009 01:49:34 +0000 (01:49 +0000)
committerivan <ivan>
Mon, 25 May 2009 01:49:34 +0000 (01:49 +0000)
FS/FS/ClientAPI/MasonComponent.pm
FS/FS/ClientAPI/MyAccount.pm
fs_selfservice/FS-SelfService/SelfService.pm
fs_selfservice/FS-SelfService/cgi/card.html
fs_selfservice/FS-SelfService/cgi/make_payment.html
fs_selfservice/FS-SelfService/cgi/misc/counties.cgi [new file with mode: 0755]
fs_selfservice/FS-SelfService/cgi/misc/states.cgi [new file with mode: 0755]
fs_selfservice/FS-SelfService/cgi/selfservice.cgi
httemplate/elements/location.html
httemplate/elements/select-county.html

index 78ea9bd..d158ce8 100644 (file)
@@ -1,9 +1,13 @@
 package FS::ClientAPI::MasonComponent;
 
 use strict;
-use vars qw($DEBUG $me);
+use vars qw( $cache $DEBUG $me );
+use subs qw( _cache );
 use FS::Mason qw( mason_interps );
 use FS::Conf;
+use FS::ClientAPI_SessionCache;
+use FS::Record qw(qsearchs);
+use FS::cust_main;
 
 $DEBUG = 0;
 $me = '[FS::ClientAPI::MasonComponent]';
@@ -13,6 +17,24 @@ my %allowed_comps = map { $_=>1 } qw(
   /misc/areacodes.cgi
   /misc/exchanges.cgi
   /misc/phonenums.cgi
+  /misc/states.cgi
+  /misc/counties.cgi
+);
+
+my %session_comps = map { $_=>1 } qw(
+  /elements/location.html
+);
+
+my %session_callbacks = (
+  '/elements/location.html' => sub {
+    my( $custnum, $argsref ) = @_;
+    my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+      or return "unknown custnum $custnum";
+    my %args = @$argsref;
+    $args{object} = $cust_main;
+    @$argsref = ( %args );
+    return ''; #no error
+  },
 );
 
 my $outbuf;
@@ -24,12 +46,23 @@ sub mason_comp {
   warn "$me mason_comp called on $packet\n" if $DEBUG;
 
   my $comp = $packet->{'comp'};
-  unless ( $allowed_comps{$comp} ) {
+  unless ( $allowed_comps{$comp} || $session_comps{$comp} ) {
     return { 'error' => 'Illegal component' };
   }
 
   my @args = $packet->{'args'} ? @{ $packet->{'args'} } : ();
 
+  if ( $session_comps{$comp} ) {
+
+    my $session = _cache->get($packet->{'session_id'})
+      or return ( 'error' => "Can't resume session" ); #better error message
+    my $custnum = $session->{'custnum'};
+
+    my $error = &{ $session_callbacks{$comp} }( $custnum, \@args );
+    return { 'error' => $error } if $error;
+
+  }
+
   my $conf = new FS::Conf;
   $FS::Mason::Request::FSURL = $conf->config('selfservice_server-base_url');
   $FS::Mason::Request::QUERY_STRING = $packet->{'query_string'} || '';
@@ -43,4 +76,11 @@ sub mason_comp {
 
 }
 
+#hmm
+sub _cache {
+  $cache ||= new FS::ClientAPI_SessionCache( {
+               'namespace' => 'FS::ClientAPI::MyAccount',
+             } );
+}
+
 1;
index ab50968..48a6ba9 100644 (file)
@@ -506,7 +506,8 @@ sub process_payment {
   }
 
   my %payby2fields = (
-    'CARD' => [ qw( paystart_month paystart_year payissue address1 address2 city state zip payip ) ],
+    'CARD' => [ qw( paystart_month paystart_year payissue payip
+                    address1 address2 city state zip country    ) ],
     'CHEK' => [ qw( ss paytype paystate stateid stateid_state payip ) ],
   );
 
@@ -527,8 +528,8 @@ sub process_payment {
     my $new = new FS::cust_main { $cust_main->hash };
     if ($payby eq 'CARD' || $payby eq 'DCRD') {
       $new->set( $_ => $p->{$_} )
-        foreach qw( payname paystart_month paystart_year payissue payip
-                    address1 address2 city state zip payinfo );
+        foreach qw( payinfo payname paystart_month paystart_year payissue payip
+                    address1 address2 city state zip country );
       $new->set( 'payby' => $p->{'auto'} ? 'CARD' : 'DCRD' );
     } elsif ($payby eq 'CHEK' || $payby eq 'DCHK') {
       $new->set( $_ => $p->{$_} )
index 47f312a..0589550 100644 (file)
@@ -86,8 +86,9 @@ $socket .= '.'.$tag if defined $tag && length($tag);
 );
 @EXPORT_OK = (
   keys(%autoload),
-  qw( regionselector regionselector_hashref
-      expselect popselector domainselector didselector )
+  qw( regionselector regionselector_hashref location_form
+      expselect popselector domainselector didselector
+    )
 );
 
 $ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin';
@@ -550,6 +551,10 @@ State
 
 Zip or postal code
 
+=item country
+
+Two-letter country code
+
 =item payinfo
 
 Card number
@@ -1436,6 +1441,52 @@ sub regionselector_hashref {
   };
 }
 
+=item location_form HASHREF | LIST
+
+Takes as input a hashref or list of key/value pairs with the following keys:
+
+=over 4
+
+=item session_id
+
+Current customer session_id
+
+=item no_asterisks
+
+Omit red asterisks from required fields.
+
+=item address1_label
+
+Label for first address line.
+
+=back
+
+Returns an HTML fragment for a location form (address, city, state, zip,
+country)
+
+=cut
+
+sub location_form {
+  my $param;
+  if ( ref($_[0]) ) {
+    $param = shift;
+  } else {
+    $param = { @_ };
+  }
+
+  my $session_id = delete $param->{'session_id'};
+
+  my $rv = mason_comp( 'session_id' => $session_id,
+                       'comp'       => '/elements/location.html',
+                       'args'       => [ %$param ],
+                     );
+
+  #hmm.
+  $rv->{'error'} || $rv->{'output'};
+
+}
+
+
 #=item expselect HASHREF | LIST
 #
 #Takes as input a hashref or list of key/value pairs with the following keys:
index cf6d20d..c7db2b3 100644 (file)
@@ -1,11 +1,11 @@
 <TR>
-  <TD ALIGN="right">Card&nbsp;number</TD>
-  <TD>
+  <TH ALIGN="right">Card&nbsp;number</TH>
+  <TD COLSPAN=6>
     <TABLE>
       <TR>
         <TD>
           <INPUT TYPE="text" NAME="payinfo" SIZE=20 MAXLENGTH=19 VALUE="<%=$payinfo%>"> </TD>
-        <TD>Exp.</TD>
+        <TH>Exp.</TH>
         <TD>
           <SELECT NAME="month">
             <%= for ( ( map "0$_", 1 .. 9 ), 10 .. 12 ) {
   '';
 %>
 <TR>
-  <TD ALIGN="right">Exact&nbsp;name&nbsp;on&nbsp;card</TD>
-  <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%=$payname%>"></TD>
-</TR><TR>
-  <TD ALIGN="right">Card&nbsp;billing&nbsp;address</TD>
-  <TD>
-    <INPUT TYPE="text" SIZE=40 MAXLENGTH=80 NAME="address1" VALUE="<%=$address1%>">
-  </TD>
-</TR><TR>
-  <TD ALIGN="right">Address&nbsp;line&nbsp;2</TD>
-  <TD>
-    <INPUT TYPE="text" SIZE=40 MAXLENGTH=80 NAME="address2" VALUE="<%=$address2%>">
-  </TD>
-</TR><TR>
-  <TD ALIGN="right">City</TD>
-  <TD>
-    <TABLE>
-      <TR>
-        <TD>
-          <INPUT TYPE="text" NAME="city" SIZE="12" MAXLENGTH=80 VALUE="<%=$city%>">
-        </TD>
-        <TD>State</TD>
-        <TD>
-          <SELECT NAME="state">
-            <%= for ( @states ) {
-              $OUT .= '<OPTION'. ($_ eq $state ? ' SELECTED' : '' ). ">$_\n";
-            } %>
-          </SELECT>
-        </TD>
-        <TD>Zip</TD>
-        <TD>
-          <INPUT TYPE="text" NAME="zip" SIZE=11 MAXLENGTH=10 VALUE="<%=$zip%>">
-        </TD>
-      </TR>
-    </TABLE>
-  </TD>
+  <TH ALIGN="right">Exact&nbsp;name&nbsp;on&nbsp;card</TH>
+  <TD COLSPAN=6><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%=$payname%>"></TD>
 </TR>
+
+<%= location_form( 'session_id'     => $session_id,
+                   'no_asterisks'   => 1,
+                   #'address1_label' => 'Card billing address',
+                   'address1_label' => 'Card&nbsp;billing&nbsp;address',
+                 )
+%>
index a468d99..da6e67e 100644 (file)
 <INPUT TYPE="hidden" NAME="action" VALUE="payment_results">
 <TABLE BGCOLOR="#cccccc">
 <TR>
-  <TD ALIGN="right">Amount&nbsp;Due</TD>
-  <TD>
+  <TH ALIGN="right">Amount&nbsp;Due</TH>
+  <TD COLSPAN=7>
     <TABLE><TR><TD BGCOLOR="#ffffff">
       $<%=sprintf("%.2f",$balance)%>
     </TD></TR></TABLE>
   </TD>
 </TR>
 <TR>
-  <TD ALIGN="right">Payment&nbsp;amount</TD>
-  <TD>
+  <TH ALIGN="right">Payment&nbsp;amount</TH>
+  <TD COLSPAN=7>
     <TABLE><TR><TD BGCOLOR="#ffffff">
       $<INPUT TYPE="text" NAME="amount" SIZE=8 VALUE="<%=sprintf("%.2f",$balance)%>">
     </TD></TR></TABLE>
   </TD>
 </TR><TR>
-  <TD ALIGN="right">Card&nbsp;type</TD>
-  <TD>
+  <TH ALIGN="right">Card&nbsp;type</TH>
+  <TD COLSPAN=7>
     <SELECT NAME="card_type"><OPTION></OPTION>
       <%= foreach ( keys %card_types ) {
             $selected = $card_type eq $card_types{$_} ? ' SELECTED' : '';
 </TR>
 <%= include('card') %>
 <TR>
-  <TD COLSPAN=2>
+  <TD COLSPAN=8>
     <INPUT TYPE="checkbox" CHECKED NAME="save" VALUE="1">
     Remember this information
   </TD>
 </TR><TR>
-  <TD COLSPAN=2>
+  <TD COLSPAN=8>
     <INPUT TYPE="checkbox"<%= $payby eq 'CARD' ? ' CHECKED' : '' %> NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }">
     Charge future payments to this card automatically
   </TD>
diff --git a/fs_selfservice/FS-SelfService/cgi/misc/counties.cgi b/fs_selfservice/FS-SelfService/cgi/misc/counties.cgi
new file mode 100755 (executable)
index 0000000..476fe09
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/perl -w
+
+use strict;
+use CGI;
+use FS::SelfService qw( mason_comp );
+
+my $cgi = new CGI;
+
+my $rv = mason_comp( 'comp'         => '/misc/counties.cgi',
+                     'query_string' => $cgi->query_string, #pass CGI params...
+                   );
+
+#hmm.
+my $output = $rv->{'error'} || $rv->{'output'};
+
+print $cgi->header( '-expires' => 'now' ).
+      $output;
+
diff --git a/fs_selfservice/FS-SelfService/cgi/misc/states.cgi b/fs_selfservice/FS-SelfService/cgi/misc/states.cgi
new file mode 100755 (executable)
index 0000000..f75f2ae
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/perl -w
+
+use strict;
+use CGI;
+use FS::SelfService qw( mason_comp );
+
+my $cgi = new CGI;
+
+my $rv = mason_comp( 'comp'         => '/misc/states.cgi',
+                     'query_string' => $cgi->query_string, #pass CGI params...
+                   );
+
+#hmm.
+my $output = $rv->{'error'} || $rv->{'output'};
+
+print $cgi->header( '-expires' => 'now' ).
+      $output;
+
index ecf2553..4c7b1d8 100644 (file)
@@ -664,7 +664,7 @@ package FS::SelfService::_selfservicecgi;
 
 #use FS::SelfService qw(regionselector expselect popselector);
 use HTML::Entities;
-use FS::SelfService qw(regionselector popselector domainselector);
+use FS::SelfService qw(regionselector popselector domainselector location_form);
 
 #false laziness w/agent.cgi
 sub include {
index 6691bc8..dbc567d 100644 (file)
@@ -23,7 +23,7 @@ Example:
            NAME     = "<%$pre%>address1"
            ID       = "<%$pre%>address1"
            VALUE    = "<% $object->get($pre.'address1') |h %>"
-           SIZE     = 58
+           SIZE     = 54
            onChange = "<% $onchange %>"
            <% $disabled %>
            <% $style %>
@@ -38,7 +38,7 @@ Example:
            NAME     = "<%$pre%>address2"
            ID       = "<%$pre%>address2"
            VALUE    = "<% $object->get($pre.'address2') |h %>"
-           SIZE     = 58
+           SIZE     = 54
            onChange = "<% $onchange %>"
            <% $disabled %>
            <% $style %>
@@ -48,7 +48,7 @@ Example:
 
 <TR>
   <TH ALIGN="right"><%$r%>City</TH>
-  <TD>
+  <TD WIDTH="1">
     <INPUT TYPE     = "text"
            NAME     = "<%$pre%>city"
            ID       = "<%$pre%>city"
@@ -57,13 +57,11 @@ Example:
            <% $disabled %>
            <% $style %>
     >
- </TD>
-  <TH ALIGN="right" ID="<%$pre%>countylabel" <%$county_style%>><%$r%>County</TH>
-  <TD>
-    <% include('/elements/select-county.html', %select_hash ) %>
   </TD>
-  <TH ALIGN="right"><%$r%>State</TH>
-  <TD>
+  <TH ALIGN="right" ID="<%$pre%>countylabel" <%$county_style%>><%$r%>County</TH>
+  <TD><% include('/elements/select-county.html', %select_hash ) %></TD>
+  <TH ALIGN="right" WIDTH="1"><%$r%>State</TH>
+  <TD WIDTH="1">
     <% include('/elements/select-state.html', %select_hash ) %>
   </TD>
   <TH><%$r%>Zip</TH>
@@ -82,7 +80,7 @@ Example:
 
 <TR>
   <TH ALIGN="right"><%$r%>Country</TH>
-  <TD COLSPAN=5><% include('/elements/select-country.html', %select_hash ) %></TD>
+  <TD COLSPAN=6><% include('/elements/select-country.html', %select_hash ) %></TD>
 </TR>
 
 % if ( !$pre ) { 
@@ -126,7 +124,7 @@ my @counties = counties( $object->get($pre.'state'),
                          $object->get($pre.'country'),
                        );
 my @county_style = ();
-push @county_style, 'visibility:hidden'
+push @county_style, 'display:none' # 'visibility:hidden'
   unless scalar(@counties) > 1;
 
 my $style =
index 59f235a..aa88abe 100644 (file)
@@ -58,10 +58,12 @@ Example:
 
         if ( countiesArray.length > 1 ) { 
           what.form.<% $pre %>county.style.display = '';
-          countyFormLabel.style.visibility = 'visible';
+          //countyFormLabel.style.visibility = 'visible';
+          countyFormLabel.style.display = '';
         } else {
           what.form.<% $pre %>county.style.display = 'none';
-          countyFormLabel.style.visibility = 'hidden';
+          //countyFormLabel.style.visibility = 'hidden';
+          countyFormLabel.style.display = 'none';
         }
 
         //run the callback