user confirmation for FFIEC censustract lookups
authorMark Wells <mark@freeside.biz>
Wed, 18 Apr 2012 22:51:33 +0000 (15:51 -0700)
committerMark Wells <mark@freeside.biz>
Wed, 18 Apr 2012 22:51:33 +0000 (15:51 -0700)
FS/FS/Misc/Geo.pm
httemplate/edit/cust_main/bottomfixup.js
httemplate/elements/location.html
httemplate/elements/standardize_locations.js
httemplate/misc/confirm-address_standardize.html
httemplate/misc/confirm-censustract.html [new file with mode: 0644]
httemplate/misc/xmlhttp-address_standardize.html

index c8290e7..733c298 100644 (file)
@@ -132,7 +132,7 @@ sub get_censustract_ffiec {
 
   } #unless ($res->code  eq '200')
 
-  die "FFIEC Geocoding error: $error" if $error;
+  die "FFIEC Geocoding error: $error\n" if $error;
 
   $return->{'statecode'} .  $return->{'countycode'} .  $return->{'tractcode'};
 }
@@ -291,7 +291,7 @@ sub standardize_usps {
       UserID => $userid,
       Password => $password,
       Testing => 0,
-  } ) or die "error starting USPS WebTools";
+  } ) or die "error starting USPS WebTools\n";
 
   my($zip5, $zip4) = split('-',$location->{'zip'});
 
@@ -312,7 +312,7 @@ sub standardize_usps {
   warn $verifier->response
     if $DEBUG > 1;
 
-  die "USPS WebTools error: ".$verifier->{error}{description} 
+  die "USPS WebTools error: ".$verifier->{error}{description} ."\n"
     if $verifier->is_error;
 
   my $zip = $hash->{Zip5};
@@ -354,20 +354,19 @@ sub standardize_teleatlas {
     return $location;
   }
 
-  if ( my $path = $conf->config('teleatlas-path') ) {
-    local @INC = (@INC, $path);
-  }
-  my $userid = $conf->config('teleatlas-userid')
-    or die "no teleatlas-userid configured";
-  my $password = $conf->config('teleatlas-password')
-    or die "no teleatlas-password configured";
-
+  my $path = $conf->config('teleatlas-path') || '';
   local @INC = (@INC, $path);
   eval "use $class;";
   if ( $@ ) {
     die "Loading $class failed:\n$@".
         "\nMake sure the TeleAtlas Perl SDK is installed correctly.\n";
   }
+
+  my $userid = $conf->config('teleatlas-userid')
+    or die "no teleatlas-userid configured\n";
+  my $password = $conf->config('teleatlas-password')
+    or die "no teleatlas-password configured\n";
+
   
   my $tool = $class->new($userid, $password);
   my $match = $tool->findAddress(
@@ -390,7 +389,8 @@ sub standardize_teleatlas {
     zip         => $match->{STD_ZIP}.'-'.$match->{STD_P4},
     latitude    => $match->{MAT_LAT},
     longitude   => $match->{MAT_LON},
-    censustract => $match->{FIPS_ST}.$match->{FIPS_CTY}.$match->{CEN_TRCT},
+    censustract => $match->{FIPS_ST}.$match->{FIPS_CTY}.
+                   sprintf('%04.2f',$match->{CEN_TRCT}),
     addr_clean  => 'Y',
   };
 }
index 40bcbd5..4e11087 100644 (file)
@@ -7,8 +7,7 @@ my $company_longitude = $conf->config('company_longitude');
 
 my @fixups = ('copy_payby_fields', 'standardize_locations');
 
-#push @fixups, 'fetch_censustract'
-#    if $conf->exists('cust_main-require_censustract');
+push @fixups, 'confirm_censustract';
 
 push @fixups, 'check_unique'
     if $conf->exists('cust_main-check_unique') and !$opt{'custnum'};
@@ -95,6 +94,35 @@ function copyelement(from, to) {
   //alert(from + " (" + from.type + "): " + to.name + " => " + to.value);
 }
 
+% # the value in 'censustract' is the confirmed censustract; if it's set,
+% # do nothing here
+function confirm_censustract() {
+  var cf = document.CustomerForm;
+  if ( cf.elements['censustract'].value == '' ) {
+    var address_info = form_address_info();
+    address_info['ship_latitude']  = cf.elements['ship_latitude'].value;
+    address_info['ship_longitude'] = cf.elements['ship_longitude'].value;
+    OLpostAJAX(
+        '<%$p%>/misc/confirm-censustract.html',
+        'q=' + encodeURIComponent(JSON.stringify(address_info)),
+        function() {
+          overlib( OLresponseAJAX, CAPTION, 'Confirm censustract', STICKY,
+            AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH,
+            576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399',
+            TEXTSIZE, 3 );
+        },
+        0);
+  } else submit_continue();
+}
+
+%# called from confirm-censustract.html
+function set_censustract(tract, year) {
+  var cf = document.CustomerForm;
+  cf.elements['censustract'].value = tract;
+  cf.elements['censusyear'].value = year;
+  submit_continue();
+}
+
 function check_unique() {
   var search_hash = new Object;
 % foreach ($conf->config('cust_main-check_unique')) {
index 053e0e5..f364051 100644 (file)
@@ -203,8 +203,9 @@ Example:
 %   if ( $pre eq 'ship_' && $conf->exists('cust_main-require_censustract') ) {
       <TR><<%$th%> ALIGN="right">Census tract<BR>(automatic)</<%$th%>>
         <TD>
-          <INPUT TYPE="text" NAME="censustract" VALUE="<% $opt{censustract} %>">
+          <INPUT TYPE="text" NAME="enter_censustract" VALUE="<% $opt{censustract} %>">
           <INPUT TYPE="hidden" NAME="censusyear" VALUE="<% $object->get('censusyear') %>">
+          <INPUT TYPE="hidden" NAME="censustract" VALUE="">
         </TD>
       </TR>
 %   } else {
@@ -225,7 +226,7 @@ Example:
 %# to re-standardize
 % foreach (qw(address1 city state country zip latitude
 %             longitude censustract addr_clean) ) {
-<INPUT TYPE="hidden" NAME="old_<%$pre.$_%>" VALUE="<% $object->get($_) |h%>">
+<INPUT TYPE="hidden" NAME="old_<%$pre.$_%>" ID="old_<%$pre.$_%>" VALUE="<% $object->get($_) |h%>">
 % }
 %# Placeholders
 <INPUT TYPE="hidden" NAME="<%$pre%>cachenum" VALUE="">
index 77683b9..ee4c5e7 100644 (file)
@@ -1,14 +1,8 @@
-function standardize_locations() {
-
-  var startup_msg = '<P STYLE="position:absolute; top:50%; margin-top:-1em; width:100%; text-align:center"><B><FONT SIZE="+1">Verifying address...</FONT></B></P>';
-  overlib(startup_msg, WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0);
+function form_address_info() {
   var cf = document.<% $formname %>;
-
   var state_el      = cf.elements['<% $main_prefix %>state'];
   var ship_state_el = cf.elements['<% $ship_prefix %>state'];
-
-  var changed = false; // have any of the address fields been changed?
-  var address_info = {
+  return {
 % if ( $onlyship ) {
     'onlyship': 1,
 % } else {
@@ -26,7 +20,7 @@ function standardize_locations() {
     'ship_company':  cf.elements['<% $ship_prefix %>company'].value,
 % }
 % if ( $withcensus ) {
-    'ship_censustract': cf.elements['censustract'].value,
+    'ship_censustract': cf.elements['enter_censustract'].value,
 % }
     'ship_address1': cf.elements['<% $ship_prefix %>address1'].value,
     'ship_address2': cf.elements['<% $ship_prefix %>address2'].value,
@@ -35,6 +29,16 @@ function standardize_locations() {
     'ship_zip':      cf.elements['<% $ship_prefix %>zip'].value,
     'ship_country':  cf.elements['<% $ship_prefix %>country'].value,
   };
+}
+
+function standardize_locations() {
+
+  var startup_msg = '<P STYLE="position:absolute; top:50%; margin-top:-1em; width:100%; text-align:center"><B><FONT SIZE="+1">Verifying address...</FONT></B></P>';
+  overlib(startup_msg, WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0);
+  var cf = document.<% $formname %>;
+  var address_info = form_address_info();
+
+  var changed = false; // have any of the address fields been changed?
 
 // clear coord_auto fields if the user has changed the coordinates
 % for my $pre ($ship_prefix, $onlyship ? () : $main_prefix) {
@@ -72,16 +76,31 @@ function standardize_locations() {
     }
   }
 
+% # If address hasn't been changed, auto-confirm the existing value of 
+% # censustract so that we don't ask the user to confirm it again.
+
+  if ( !changed ) {
+    cf.elements['<% $main_prefix %>censustract'].value =
+      address_info['ship_censustract'];
+  }
+
+% if ( $conf->config('address_standardize_method') ) {
   if ( changed ) {
     address_standardize(JSON.stringify(address_info), confirm_standardize);
   }
   else {
     cf.elements['ship_addr_clean'].value = 'Y';
-% if ( !$onlyship ) {
+%   if ( !$onlyship ) {
     cf.elements['addr_clean'].value = 'Y';
-% }
+%   }
     post_standardization();
   }
+
+% } else {
+
+  post_standardization();
+
+% } # if address_standardize_method
 }
 
 var returned;
@@ -157,22 +176,33 @@ function replace_address() {
       setselect(cf.elements['<% $ship_prefix %>state'], newaddr['ship_state']);
       cf.elements['<% $ship_prefix %>zip'].value      = newaddr['ship_zip'];
       cf.elements['<% $ship_prefix %>addr_clean'].value = 'Y';
-% if ( $withcensus ) {
-      cf.elements['<% $main_prefix %>censustract'].value = newaddr['ship_censustract']
-%    }
       if ( cf.elements['<% $ship_prefix %>coord_auto'].value ) {
         cf.elements['<% $ship_prefix %>latitude'].value = newaddr['latitude'];
         cf.elements['<% $ship_prefix %>longitude'].value = newaddr['longitude'];
       }
   }
+% if ( $withcensus ) {
+% # then set the censustract if address_standardize provided one.
+  if ( ship_clean && newaddr['ship_censustract'] ) {
+      cf.elements['<% $main_prefix %>censustract'].value = newaddr['ship_censustract'];
+  }
+% }
 
   post_standardization();
 
 }
 
-function post_standardization() {
-
+function confirm_manual_address() {
+%# not much to do in this case, just confirm the censustract
+% if ( $withcensus ) {
   var cf = document.<% $formname %>;
+  cf.elements['<% $main_prefix %>censustract'].value =
+  cf.elements['<% $main_prefix %>enter_censustract'].value;
+% }
+  post_standardization();
+}
+
+function post_standardization() {
 
 % if ( $conf->exists('enable_taxproducts') ) {
 
index 1f94dd9..24363ea 100644 (file)
@@ -51,7 +51,7 @@ Confirm address standardization
 %     }
   <TR>
     <TD><% $old{$pre.'address1'} %></TD>
-    <TD><FONT COLOR="#ff0000"><B><% $new{$pre.'error'} %></B></FONT></TD>
+    <TD ROWSPAN=3><FONT COLOR="#ff0000"><B><% $new{$pre.'error'} %></B></FONT></TD>
   </TR>
   <TR>
     <TD><% $old{$pre.'address2'} %></TD>
@@ -62,7 +62,8 @@ Confirm address standardization
 %   } #if error
 % } # for $pre
 
-% if ( $old{'ship_censustract'} or $new{'ship_censustract'} ) {
+%# only do this part if address standardization provided a censustract
+% if ( $new{'ship_censustract'} ) {
   <TR>
     <TH>Entered census tract</TH>
     <TH>Calculated census tract</TH>
@@ -82,7 +83,7 @@ Confirm address standardization
 % if ( $new{error} or $new{ship_error} ) {
   <TR>
     <TD ALIGN="center">
-    <BUTTON TYPE="button" STYLE="width:205px" onclick="post_standardization();">
+    <BUTTON TYPE="button" STYLE="width:205px" onclick="confirm_manual_address();">
       <IMG SRC="<%$p%>images/error.png" ALT=""> Use entered <%$addresses%>
     </BUTTON></TD>
     <TD ALIGN="center">
@@ -94,7 +95,7 @@ Confirm address standardization
 % else {
   <TR>
     <TD ALIGN="center">
-    <BUTTON TYPE="button" STYLE="width:205px" onclick="post_standardization();">
+    <BUTTON TYPE="button" STYLE="width:205px" onclick="confirm_manual_address()();">
       <IMG SRC="<%$p%>images/error.png" ALT=""> Use entered <%$addresses%>
     </BUTTON></TD>
     <TD ALIGN="center">
diff --git a/httemplate/misc/confirm-censustract.html b/httemplate/misc/confirm-censustract.html
new file mode 100644 (file)
index 0000000..ae0ae3a
--- /dev/null
@@ -0,0 +1,78 @@
+<CENTER><BR><B>
+% if ( $error ) {
+Census tract error
+% }
+% else {
+Confirm census tract
+% }
+</B><BR>
+% my $querystring = "census_year=$year&latitude=".$cache->get('latitude').'&longitude='.$cache->get('longitude');
+<A HREF="http://maps.ffiec.gov/FFIECMapper/TGMapSrv.aspx?<% $querystring %>"
+   TARGET="_blank">Map service module location</A><BR>
+% $querystring = "census_year=$year&zip_code=".$cache->get('zip');
+<A HREF="http://maps.ffiec.gov/FFIECMapper/TGMapSrv.aspx?<% $querystring %>"
+   TARGET="_blank">Map zip code center</A><BR>
+<BR>
+<TABLE>
+  <TR>
+    <TH style="width:50%">Entered census tract</TH>
+    <TH style="width:50%">Calculated census tract</TH>
+  </TR>
+  <TR>
+    <TD><% $old_tract %></TD>
+% if ( $error ) {
+    <TD><FONT COLOR="#ff0000"><% $error %></FONT></TD>
+% } else {
+    <TD><% $new_tract %></TD>
+% }
+  </TR>
+  <TR>
+    <TD ALIGN="center">
+      <BUTTON TYPE="button"
+              onclick="set_censustract('<% $old_tract %>', '<% $year %>')">
+      <IMG SRC="<%$p%>images/error.png" ALT=""> Use entered census tract
+      </BUTTON>
+    </TD>
+    <TD ALIGN="center">
+      <BUTTON TYPE="button"
+              onclick="set_censustract('<% $new_tract %>', '<% $year %>')">
+      <IMG SRC="<%$p%>images/tick.png" ALT=""> Use calculated census tract
+      </BUTTON>
+    </TD>
+  </TR>
+  <TR>
+    <TD COLSPAN=2 ALIGN="center">
+      <BUTTON TYPE="button" onclick="submit_abort()">
+      <IMG SRC="<%$p%>images/cross.png" ALT=""> Cancel submission
+      </BUTTON>
+    </TD>
+  </TR>
+</TABLE></CENTER>
+<%init>
+
+local $SIG{__DIE__}; #disable Mason error trap
+
+my $DEBUG = 0;
+
+my $conf = new FS::Conf;
+
+warn $cgi->param('q') if $DEBUG;
+
+my $q = decode_json($cgi->param('q'))
+  or die "bad argument '".$cgi->param('q')."'";
+
+my %location = (
+  map { $_ => $q->{'ship_'.$_} }
+    qw( company address1 address2 city state zip country latitude longitude )
+);
+
+my $old_tract = $q->{'ship_censustract'};
+my $cache = eval { FS::GeocodeCache->new(%location) };
+$cache->set_censustract;
+my $year = FS::Conf->new->config('census_year');
+my $new_tract = $cache->get('censustract');
+my $error = $cache->get('censustract_error');
+
+warn Dumper($cache) if $DEBUG;
+
+</%init>
index c2d6d7a..f53c35f 100644 (file)
@@ -25,8 +25,8 @@ foreach my $pre ( '', 'ship_' ) {
   };
 
   my $cache = eval { FS::GeocodeCache->standardize($location) };
-  $cache->set_censustract if $pre;
   $cache->set_coord;
+  # don't do set_censustract here, though censustract may be set by now
 
   foreach ( keys(%$cache) ) {
     $new{$pre.$_} = $cache->get($_);