improved address standardization, #13763
[freeside.git] / httemplate / elements / standardize_locations.js
1 function form_address_info() {
2   var cf = document.<% $formname %>;
3   var state_el      = cf.elements['<% $main_prefix %>state'];
4   var ship_state_el = cf.elements['<% $ship_prefix %>state'];
5   return {
6 % if ( $onlyship ) {
7     'onlyship': 1,
8 % } else {
9 %   if ( $withfirm ) {
10     'company',  cf.elements['company'].value,
11 %   }
12     'address1': cf.elements['<% $main_prefix %>address1'].value,
13     'address2': cf.elements['<% $main_prefix %>address2'].value,
14     'city':     cf.elements['<% $main_prefix %>city'].value,
15     'state':    state_el.options[ state_el.selectedIndex ].value,
16     'zip':      cf.elements['<% $main_prefix %>zip'].value,
17     'country':  cf.elements['<% $main_prefix %>country'].value,
18 % }
19 % if ( $withcensus ) {
20     'ship_censustract': cf.elements['enter_censustract'].value,
21 % }
22     'ship_address1': cf.elements['<% $ship_prefix %>address1'].value,
23     'ship_address2': cf.elements['<% $ship_prefix %>address2'].value,
24     'ship_city':     cf.elements['<% $ship_prefix %>city'].value,
25     'ship_state':    ship_state_el.options[ ship_state_el.selectedIndex ].value,
26     'ship_zip':      cf.elements['<% $ship_prefix %>zip'].value,
27     'ship_country':  cf.elements['<% $ship_prefix %>country'].value,
28   };
29 }
30
31 function standardize_locations() {
32
33   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>';
34   overlib(startup_msg, WIDTH, 444, HEIGHT, 168, CAPTION, 'Please wait...', STICKY, AUTOSTATUSCAP, CLOSECLICK, MIDX, 0, MIDY, 0);
35   var cf = document.<% $formname %>;
36   var address_info = form_address_info();
37
38   var changed = false; // have any of the address fields been changed?
39
40 // clear coord_auto fields if the user has changed the coordinates
41 % for my $pre ($ship_prefix, $onlyship ? () : $main_prefix) {
42 %   for my $field ($pre.'latitude', $pre.'longitude') {
43
44   if ( cf.elements['<% $field %>'].value != cf.elements['old_<% $field %>'].value ) {
45     cf.elements['<% $pre %>coord_auto'].value = '';
46   }
47
48 %   }
49   // but if the coordinates have been set to null, turn coord_auto on 
50   // and standardize
51   if ( cf.elements['<% $pre %>latitude'].value == '' &&
52        cf.elements['<% $pre %>longitude'].value == '' ) {
53     cf.elements['<% $pre %>coord_auto'].value = 'Y';
54     changed = true;
55   }
56
57 % }
58
59   // standardize if the old address wasn't clean
60   if ( cf.elements['old_<% $ship_prefix %>addr_clean'].value == '' ||
61       ( <% !$onlyship || 0 %> && 
62         cf.elements['old_<% $main_prefix %>addr_clean'].value == '' ) ) {
63
64     changed = true;
65
66   }
67   // or if it was clean but has been changed
68   for (var key in address_info) {
69     var old_el = cf.elements['old_'+key];
70     if ( old_el && address_info[key] != old_el.value ) {
71       changed = true;
72       break;
73     }
74   }
75
76 % # If address hasn't been changed, auto-confirm the existing value of 
77 % # censustract so that we don't ask the user to confirm it again.
78
79   if ( !changed ) {
80     cf.elements['<% $main_prefix %>censustract'].value =
81       address_info['ship_censustract'];
82   }
83
84 % if ( $conf->config('address_standardize_method') ) {
85   if ( changed ) {
86     address_standardize(JSON.stringify(address_info), confirm_standardize);
87   }
88   else {
89     cf.elements['ship_addr_clean'].value = 'Y';
90 %   if ( !$onlyship ) {
91     cf.elements['addr_clean'].value = 'Y';
92 %   }
93     post_standardization();
94   }
95
96 % } else {
97
98   post_standardization();
99
100 % } # if address_standardize_method
101 }
102
103 var returned;
104
105 function confirm_standardize(arg) {
106   // contains 'old', which was what we sent, and 'new', which is what came
107   // back, including any errors
108   returned = JSON.parse(arg);
109
110   if ( <% $conf->exists('cust_main-auto_standardize_address') || 0 %> ) {
111
112     replace_address(); // with the contents of returned['new']
113   
114   }
115   else {
116
117     var querystring = encodeURIComponent( JSON.stringify(returned) );
118     // confirmation popup: knows to call replace_address(), 
119     // post_standardization(), or submit_abort() depending on the 
120     // user's choice.
121     OLpostAJAX(
122         '<%$p%>/misc/confirm-address_standardize.html', 
123         'q='+querystring,
124         function() {
125           overlib( OLresponseAJAX, CAPTION, 'Address standardization', STICKY, 
126             AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 
127             576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', 
128             TEXTSIZE, 3 );
129         }, 0);
130
131   }
132 }
133
134 function replace_address() {
135
136   var newaddr = returned['new'];
137
138   var clean = newaddr['addr_clean'] == 'Y';
139   var ship_clean = newaddr['ship_addr_clean'] == 'Y';
140   var error = newaddr['error'];
141   var ship_error = newaddr['ship_error'];
142
143   var cf = document.<% $formname %>;
144   var state_el      = cf.elements['<% $main_prefix %>state'];
145   var ship_state_el = cf.elements['<% $ship_prefix %>state'];
146
147 % if ( !$onlyship ) {
148   if ( clean ) {
149 %   if ( $withfirm ) {
150         cf.elements['<% $main_prefix %>company'].value  = newaddr['company'];
151 %   }
152         cf.elements['<% $main_prefix %>address1'].value = newaddr['address1'];
153         cf.elements['<% $main_prefix %>address2'].value = newaddr['address2'];
154         cf.elements['<% $main_prefix %>city'].value     = newaddr['city'];
155         setselect(cf.elements['<% $main_prefix %>state'], newaddr['state']);
156         cf.elements['<% $main_prefix %>zip'].value      = newaddr['zip'];
157         cf.elements['<% $main_prefix %>addr_clean'].value = 'Y';
158
159         if ( cf.elements['<% $main_prefix %>coord_auto'].value ) {
160           cf.elements['<% $main_prefix %>latitude'].value = newaddr['latitude'];
161           cf.elements['<% $main_prefix %>longitude'].value = newaddr['longitude'];
162         }
163   }
164 % }
165
166   if ( ship_clean ) {
167 % if ( $withfirm ) {
168       cf.elements['<% $ship_prefix %>company'].value  = newaddr['ship_company'];
169 % }
170       cf.elements['<% $ship_prefix %>address1'].value = newaddr['ship_address1'];
171       cf.elements['<% $ship_prefix %>address2'].value = newaddr['ship_address2'];
172       cf.elements['<% $ship_prefix %>city'].value     = newaddr['ship_city'];
173       setselect(cf.elements['<% $ship_prefix %>state'], newaddr['ship_state']);
174       cf.elements['<% $ship_prefix %>zip'].value      = newaddr['ship_zip'];
175       cf.elements['<% $ship_prefix %>addr_clean'].value = 'Y';
176       if ( cf.elements['<% $ship_prefix %>coord_auto'].value ) {
177         cf.elements['<% $ship_prefix %>latitude'].value = newaddr['latitude'];
178         cf.elements['<% $ship_prefix %>longitude'].value = newaddr['longitude'];
179       }
180   }
181 % if ( $withcensus ) {
182 % # then set the censustract if address_standardize provided one.
183   if ( ship_clean && newaddr['ship_censustract'] ) {
184       cf.elements['<% $main_prefix %>censustract'].value = newaddr['ship_censustract'];
185   }
186 % }
187
188   post_standardization();
189
190 }
191
192 function confirm_manual_address() {
193 %# not much to do in this case, just confirm the censustract
194 % if ( $withcensus ) {
195   var cf = document.<% $formname %>;
196   cf.elements['<% $main_prefix %>censustract'].value =
197   cf.elements['<% $main_prefix %>enter_censustract'].value;
198 % }
199   post_standardization();
200 }
201
202 function post_standardization() {
203
204 % if ( $conf->exists('enable_taxproducts') ) {
205
206   if ( new String(cf.elements['<% $taxpre %>zip'].value).length < 10 )
207   {
208
209     var country_el = cf.elements['<% $taxpre %>country'];
210     var country = country_el.options[ country_el.selectedIndex ].value;
211     var geocode = cf.elements['geocode'].value;
212
213     if ( country == 'CA' || country == 'US' ) {
214
215       var state_el = cf.elements['<% $taxpre %>state'];
216       var state = state_el.options[ state_el.selectedIndex ].value;
217
218       var url = "<% $p %>/misc/choose_tax_location.html" +
219                   "?data_vendor=cch-zip" + 
220                   ";city="     + cf.elements['<% $taxpre %>city'].value +
221                   ";state="    + state + 
222                   ";zip="      + cf.elements['<% $taxpre %>zip'].value +
223                   ";country="  + country +
224                   ";geocode="  + geocode +
225                   ";formname=" + '<% $formname %>' +
226                   ";";
227
228       // popup a chooser
229       OLgetAJAX( url, update_geocode, 300 );
230
231     } else {
232
233       cf.elements['geocode'].value = 'DEFAULT';
234       <% $post_geocode %>;
235
236     }
237
238   } else {
239
240     cf.elements['geocode'].value = '';
241     <% $post_geocode %>;
242
243   }
244
245 % } else {
246
247   <% $post_geocode %>;
248
249 % }
250
251 }
252
253 function update_geocode() {
254
255   //yay closures
256   set_geocode = function (what) {
257
258     var cf = document.<% $formname %>;
259
260     //alert(what.options[what.selectedIndex].value);
261     var argsHash = eval('(' + what.options[what.selectedIndex].value + ')');
262     cf.elements['<% $taxpre %>city'].value     = argsHash['city'];
263     setselect(cf.elements['<% $taxpre %>state'], argsHash['state']);
264     cf.elements['<% $taxpre %>zip'].value      = argsHash['zip'];
265     cf.elements['geocode'].value  = argsHash['geocode'];
266     <% $post_geocode %>;
267
268   }
269
270   // popup a chooser
271
272   overlib( OLresponseAJAX, CAPTION, 'Select tax location', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 );
273
274 }
275
276 function setselect(el, value) {
277
278   for ( var s = 0; s < el.options.length; s++ ) {
279      if ( el.options[s].value == value ) {
280        el.selectedIndex = s;
281      }
282   }
283
284 }
285 <%init>
286
287 my %opt = @_;
288 my $conf = new FS::Conf;
289
290 my $withfirm = 1;
291 my $withcensus = 1;
292
293 my $formname =  $opt{form} || 'CustomerForm';
294 my $onlyship =  $opt{onlyship} || '';
295 my $main_prefix =  $opt{main_prefix} || '';
296 my $ship_prefix =  $opt{ship_prefix} || ($onlyship ? '' : 'ship_');
297 my $taxpre = $main_prefix;
298 $taxpre = $ship_prefix if ( $conf->exists('tax-ship_address') || $onlyship );
299 my $post_geocode = $opt{callback} || 'post_geocode();';
300 $withfirm = 0 if $opt{no_company};
301 $withcensus = 0 if $opt{no_census};
302
303 </%init>