address standardization part one, finally checked in from here
authorivan <ivan>
Thu, 8 May 2008 12:47:13 +0000 (12:47 +0000)
committerivan <ivan>
Thu, 8 May 2008 12:47:13 +0000 (12:47 +0000)
FS/FS/Conf.pm
htetc/handler.pl
httemplate/edit/cust_main.cgi
httemplate/elements/xmlhttp.html
httemplate/misc/xmlhttp-cust_main-address_standardize.html [new file with mode: 0644]
httemplate/misc/xmlhttp-cust_main-search.cgi

index 2094ff0..3aa19b7 100644 (file)
@@ -2236,6 +2236,27 @@ worry that config_items is freeside-specific and icky.
                      ],
   },
 
+  {
+    'key'         => 'usps_webtools-userid',
+    'section'     => 'UI',
+    'description' => 'Production UserID for USPS web tools.   Enables USPS address standardization.  See the <a href="http://www.usps.com/webtools/">USPS website</a>, register and agree not to use the tools for batch purposes.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'usps_webtools-password',
+    'section'     => 'UI',
+    'description' => 'Production password for USPS web tools.   Enables USPS address standardization.  See <a href="http://www.usps.com/webtools/">USPS website</a>, register and agree not to use the tools for batch purposes.',
+    'type'        => 'text',
+  },
+
+  {
+    'key'         => 'cust_main-auto_standardize_address',
+    'section'     => 'UI',
+    'description' => 'When using USPS web tools, automatically standardize the address without asking.',
+    'type'        => 'checkbox',
+  },
+
 );
 
 1;
index d2fe52d..5e34c1e 100644 (file)
@@ -125,8 +125,10 @@ sub handler
       use Chart::LinesPoints;
       use Chart::Mountain;
       use Color::Scheme;
-      use HTML::Widgets::SelectLayers 0.07;
+      use HTML::Widgets::SelectLayers 0.07; #should go away in favor of
+                                            #selectlayers.html
       use Locale::Country;
+      use Business::US::USPS::WebTools::AddressStandardization;
       use FS;
       use FS::UID qw(cgisuidsetup dbh getotaker datasrc driver_name);
       use FS::Record qw(qsearch qsearchs fields dbdef str2time_sql);
index aae8093..3d727dd 100755 (executable)
@@ -210,9 +210,19 @@ Service address
            )
 %>
 
+<% include( '/elements/xmlhttp.html',
+              'url'  => $p.'misc/xmlhttp-cust_main-address_standardize.html',
+              'subs' => [ 'address_standardize' ],
+              #'method' => 'POST', #could get too long?
+          )
+%>
+
 <SCRIPT>
 function bottomfixup(what) {
 
+  //i don't think we need to copy things between two forms anymore, modern
+  //browsers are fine with DIVs inside FORMs
+
   var topvars = new Array(
     'birthdate',
 
@@ -272,6 +282,58 @@ function bottomfixup(what) {
                );
   }
 
+  //this part does USPS address correction
+
+  // XXX should this be first and should we update the form fields that are
+  // displayed???
+
+  //var state_el = document.bottomform.elements['state'];
+
+  //address_standardize(
+  var cust_main = new Array(
+    'company',  document.bottomform.elements['company'].value,
+    'address1', document.bottomform.elements['address1'].value,
+    'address2', document.bottomform.elements['address2'].value,
+    'city',     document.bottomform.elements['city'].value,
+    'state',    document.bottomform.elements['state'].value,
+    //'state',    state_el.options[ state_el.selectedIndex ].value,
+    'zip',      document.bottomform.elements['zip'].value,
+
+    'ship_company',  document.bottomform.elements['company'].value,
+    'ship_address1', document.bottomform.elements['address1'].value,
+    'ship_address2', document.bottomform.elements['address2'].value,
+    'ship_city',     document.bottomform.elements['city'].value,
+    'ship_state',    document.bottomform.elements['state'].value,
+    //'ship_state',    state_el.options[ state_el.selectedIndex ].value,
+    'ship_zip',      document.bottomform.elements['zip'].value
+  );
+
+  address_standardize( cust_main, update_address );
+
+}
+
+function update_address(arg) {
+
+  var argsHash = eval('(' + arg + ')');
+
+  var address1 = argsHash['address1'];
+  var zip      = argsHash['zip'];
+  var changed  = argsHash['address_standardized'];
+  var ship_changed = argsHash['ship_address_standardized'];
+
+  alert(address1);
+  alert(zip);
+  alert(changed);
+  alert(ship_changed);
+
+% if ( $conf->exists('cust_main-auto_standardize_address') ) {
+  // XXX this path not handled yet
+% } else {
+  // XXX well, this path not handled yet either.  popup a confirmation popup
+% }
+
+  document.bottomform.submit();
+
 }
 
 function copyelement(from, to) {
@@ -298,7 +360,7 @@ function copyelement(from, to) {
 
 </SCRIPT>
 
-<FORM ACTION="<% popurl(1) %>process/cust_main.cgi" METHOD=POST NAME="bottomform" onSubmit="document.bottomform.submit.disabled=true; bottomfixup(this.form);" STYLE="margin-top: 0; margin-bottom: 0">
+<FORM ACTION="<% popurl(1) %>process/cust_main.cgi" METHOD=POST NAME="bottomform" STYLE="margin-top: 0; margin-bottom: 0">
 % foreach my $hidden (
 %     'birthdate',
 %
@@ -438,7 +500,7 @@ function copyelement(from, to) {
 
 <INPUT TYPE="hidden" NAME="otaker" VALUE="<% $cust_main->otaker %>">
 <BR>
-<INPUT TYPE="submit" NAME="submit" VALUE="<% $custnum ?  "Apply Changes" : "Add Customer" %>">
+<INPUT TYPE="button" NAME="submitButton" ID="submitButton" VALUE="<% $custnum ?  "Apply Changes" : "Add Customer" %>" onClick="document.bottomform.submitButton.disabled=true; bottomfixup(this.form);">
 <BR>
 </FORM>
 
index 3f4462b..d0c7990 100644 (file)
@@ -1,3 +1,19 @@
+<%doc>
+
+Example:
+
+  include( '/elements/xmlhttp.html',
+    # required
+    'url'  => $p.'misc/something.html',
+    'subs' => [ 'subroutine' ],
+
+    # optional
+    'method' => 'GET', #defaults to GET, could specify POST
+    'key'    => 'unique', #unique key
+
+  );
+
+</%doc>
 <SCRIPT TYPE="text/javascript">
 
   function rs_init_object() {
diff --git a/httemplate/misc/xmlhttp-cust_main-address_standardize.html b/httemplate/misc/xmlhttp-cust_main-address_standardize.html
new file mode 100644 (file)
index 0000000..e290301
--- /dev/null
@@ -0,0 +1,87 @@
+<% to_json($return) %>
+<%init>
+
+my $DEBUG = 1;
+
+my $conf = new FS::Conf;
+
+my $sub = $cgi->param('sub');
+
+my $return = {};
+
+if ( $sub eq 'address_standardize' ) {
+
+  my %arg = $cgi->param('arg');
+  $return = \%arg;
+  warn join('', map "$_: $arg{$_}\n", keys %arg )
+    if $DEBUG;
+
+  my $userid   = $conf->config('usps_webtools-userid');
+  my $password = $conf->config('usps_webtools-password');
+
+  if ( length($userid) && length($password) ) {
+
+    my $verifier = Business::US::USPS::WebTools::AddressStandardization->new( {
+      UserID   => $userid,   #$ENV{USPS_WEBTOOLS_USERID},
+      Password => $password, #$ENV{USPS_WEBTOOLS_PASSWORD},
+      #Testing  => 1,
+    } );
+
+    foreach my $pre ( '', 'ship_' ) {
+
+      my($zip5, $zip4) = split('-',$arg{$pre.'zip'});
+
+      my %usps_args = (
+        FirmName => $arg{$pre.'company'},
+        Address2 => $arg{$pre.'address1'},
+        Address1 => $arg{$pre.'address2'},
+        City     => $arg{$pre.'city'},  
+        State    => $arg{$pre.'state'},
+        Zip5     => $zip5,
+        Zip4     => $zip4,
+      );
+      warn join('', map "$_: $usps_args{$_}\n", keys %usps_args )
+        if $DEBUG;
+
+      my $hash = $verifier->verify_address( %usps_args );
+
+      warn $verifier->response
+        if $DEBUG;
+
+      unless ( $verifier->is_error ) {
+
+        $return = {
+          %$return,
+          "new_$pre".'company'  => $hash->{FirmName},
+          "new_$pre".'address1' => $hash->{Address2},
+          "new_$pre".'address2' => $hash->{Address1},
+          "new_$pre".'city'     => $hash->{City},
+          "new_$pre".'state'    => $hash->{State},
+          "new_$pre".'zip'      => $hash->{Zip5}. '-'. $hash->{Zip4},
+        };
+
+        my @fields = (qw( company address1 address2 city state zip )); #hmm
+
+        my $changed =
+          scalar( grep { $return->{$pre.$_} ne $return->{"new_$pre$_"} }
+                       @fields
+                )
+            ? 1 : 0;
+
+        $return->{$pre.'address_standardized'} = $changed;
+
+      } else {
+
+        warn "USPS WebTools error: ". $verifier->response. "\n";
+
+      }
+
+    }
+
+  }
+
+  $return;
+
+}
+
+</%init>
index 20707da..3746230 100644 (file)
@@ -15,7 +15,7 @@
 %   my @cust_main = smart_search( 'search' => $string );
 %   my $return = [ map [ $_->custnum, $_->name ], @cust_main ];
 %     
-<% objToJson($return) %>
+<% to_json($return) %>
 % } 
 <%init>