diff options
Diffstat (limited to 'httemplate')
-rwxr-xr-x | httemplate/edit/cust_main.cgi | 36 | ||||
-rw-r--r-- | httemplate/edit/cust_main/choose_tax_location.html | 74 | ||||
-rw-r--r-- | httemplate/edit/cust_main/contact.html | 4 | ||||
-rw-r--r-- | httemplate/elements/ajaxcontentmws.js | 185 | ||||
-rw-r--r-- | httemplate/misc/tax-import.cgi | 2 | ||||
-rw-r--r-- | httemplate/misc/xmlhttp-cust_main-address_standardize.html | 4 |
6 files changed, 303 insertions, 2 deletions
diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi index 8de73c513..8336183b8 100755 --- a/httemplate/edit/cust_main.cgi +++ b/httemplate/edit/cust_main.cgi @@ -5,6 +5,7 @@ ) %> <% include('/elements/init_overlib.html') %> +<SCRIPT SRC="<% $fsurl %>elements/ajaxcontentmws.js" TYPE="text/javascript"></SCRIPT> <% include('/elements/error.html') %> @@ -249,6 +250,8 @@ function bottomfixup(what) { 'ship_county', 'ship_state', 'ship_zip', 'ship_country', 'ship_daytime','ship_night', 'ship_fax', + 'geocode', + 'select' // XXX key ); @@ -329,6 +332,8 @@ function update_address(arg) { var changed = argsHash['address_standardized']; var ship_changed = argsHash['ship_address_standardized']; + var error = argsHash['error']; + var ship_error = argsHash['ship_error']; //yay closures standardize_address = function () { @@ -355,7 +360,14 @@ function update_address(arg) { } - if ( changed || ship_changed ) { + if ( error || ship_error ) { + + var url = "cust_main/choose_tax_location.html?data_vendor=cch-zip;city="+document.bottomform.elements['city'].value+";state="+document.bottomform.elements['state'].value+";zip="+document.bottomform.elements['zip'].value+";"; + // popup a chooser + OLgetAJAX( url, update_geocode, 300 ); + + + } else if ( changed || ship_changed ) { % if ( $conf->exists('cust_main-auto_standardize_address') ) { @@ -448,6 +460,26 @@ function update_address(arg) { } +function update_geocode() { + + //yay closures + set_geocode = function (what) { + + //alert(what.options[what.selectedIndex].value); + var argsHash = eval('(' + what.options[what.selectedIndex].value + ')'); + document.bottomform.elements['city'].value = argsHash['city']; + document.bottomform.elements['state'].value = argsHash['state']; + document.bottomform.elements['zip'].value = argsHash['zip']; + document.bottomform.elements['geocode'].value = argsHash['geocode']; + + } + + // popup a chooser + + overlib( OLresponseAJAX, CAPTION, 'Select tax location', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); + +} + function copyelement(from, to) { if ( from == undefined ) { to.value = ''; @@ -490,6 +522,8 @@ function copyelement(from, to) { % 'ship_county', 'ship_state', 'ship_zip', 'ship_country', % 'ship_daytime','ship_night', 'ship_fax', % +% 'geocode', +% % 'select', #XXX key % % 'payauto', diff --git a/httemplate/edit/cust_main/choose_tax_location.html b/httemplate/edit/cust_main/choose_tax_location.html new file mode 100644 index 000000000..23fdbf282 --- /dev/null +++ b/httemplate/edit/cust_main/choose_tax_location.html @@ -0,0 +1,74 @@ +<FORM NAME="choosegeocodeform"> +<CENTER><BR><B>Choose tax location</B><BR><BR> +<P STYLE="<% $style %>"><% $header %></P> + +<SELECT NAME='geocodes' ID='geocodes' STYLE="<% $style %>"> +% foreach my $location (@cust_tax_location) { +% my $value = encode_entities(objToJson({ zip => $zip5, +% map { $_ => $location->$_ } +% qw ( city state geocode ) +% }) +% ); +% my $content = ''; +% $content .= $location->$_. ' ' x ( $max{$_} - length($location->$_) ) +% foreach qw( city county state ); +% $content .= $location->cityflag eq 'I' ? 'Y' : 'N' ; +% my $selected = '' ; +% if (!$have_selected && lc($location->city) eq lc($city)) { +% $selected = 'SELECTED'; +% } + <OPTION VALUE="<% $value %>" STYLE="<% $style %>" <% $selected %>><% $content %> +% } +</SELECT><BR><BR> + +<TABLE><TR> + <TD> <BUTTON TYPE="button" onClick="set_geocode(document.getElementById('geocodes')); document.bottomform.submit();"><IMG SRC="<%$p%>images/tick.png" ALT=""> Set location </BUTTON></TD> + <TD><BUTTON TYPE="button" onClick="document.bottomform.submitButton.disabled=false; parent.cClick();"><IMG SRC="<%$p%>images/cross.png" ALT=""> Cancel submission </BUTTON></TD> +</TR> +</TABLE> + +</CENTER> +</FORM> +<%init> + +my $conf = new FS::Conf; +my $have_selected = 0; + +my ($data_vendor) = $cgi->param('data_vendor') =~ /^([-\w]+)$/; +my ($city) = $cgi->param('city') =~ /^([\w ]+)$/; +my ($state) = $cgi->param('state') =~ /^(\w+)$/; +my ($zip) = $cgi->param('zip') =~ /^([-\w]+)$/; + +my($zip5, $zip4) = split('-', $zip); + +my $hashref = { data_vendor => $data_vendor, + #city => $city, + #state => $state, + zip => $zip5, + }; +#my @keys = qw ( city state zip ); +my @keys = qw ( zip ); +my @cust_tax_location = (); +until ( @cust_tax_location ) { + @cust_tax_location = qsearch( 'cust_tax_location', $hashref ); + last unless scalar(@keys); + delete $hashref->{ shift @keys }; +} + +my %max = ( city => 4, county => 6, state => 5); +foreach my $location (@cust_tax_location) { + foreach ( qw( city county state ) ) { + my $length = length($location->$_); + $max{$_} = ($length > $max{$_}) ? $length : $max{$_}; + } +} +$max{$_}++ foreach qw( city county state ); + +my $header = ' '; +$header .= $_. ' ' x ( $max{lc($_)} - length($_) ) + foreach qw( City County State ); +$header .= "In city?"; + +my $style = "font-family:monospace;"; + +</%init> diff --git a/httemplate/edit/cust_main/contact.html b/httemplate/edit/cust_main/contact.html index 21c6b2990..2d37dc895 100644 --- a/httemplate/edit/cust_main/contact.html +++ b/httemplate/edit/cust_main/contact.html @@ -69,6 +69,10 @@ <TR> <TH ALIGN="right"><%$r%>Country</TH> <TD COLSPAN=5><% include('select-country.html', %select_hash ) %></TD> +% if ( !$pre ) { + <TD><INPUT TYPE="hidden" NAME="geocode" VALUE="<% $opt{geocode} %>"></TD> +% } + </TR> <TR> diff --git a/httemplate/elements/ajaxcontentmws.js b/httemplate/elements/ajaxcontentmws.js new file mode 100644 index 000000000..917704902 --- /dev/null +++ b/httemplate/elements/ajaxcontentmws.js @@ -0,0 +1,185 @@ +/*
+ ajaxcontentmws.js - Foteos Macrides (author and Copyright holder)
+ Initial: June 22, 2006 - Last Revised: March 24, 2008
+ Wrapper function set for getting and using the responseText and / or
+ responseXML from a GET or POST XMLHttpRequest, which can be used to
+ generate dynamic content for overlib or overlib2 calls, or to modify
+ the content of a displayed STICKY popup dynamically.
+
+ For GET Use:
+ onmouseover="return OLgetAJAX(url, command, delay, css);"
+ onmouseout="OLclearAJAX();" (if delay > 0)
+ or:
+ onclick="OLgetAJAX(url, command, 0, css); return false;"
+ or:
+ onload="OLgetAJAX(url, command, 0, css);
+
+ Where:
+ url (required)
+ is a quoted string, or unquoted string variable name or array entry, with
+ the full, relative, or partial URL for a file or a server-side script (php,
+ asp, or cgi, e.g. perl), and may have a query string appended (e.g.,
+ 'http://my.domain.com/scripts/myScript.php?foo=bar&life=grand').
+ And:
+ command (required)
+ is the function reference (unquoted name without parens) of a function to
+ be called when the server's response has been received (it could instead be
+ an inline function, i.e., defined within the 2nd argument, or a quoted string
+ for a function with parens and any args)
+ And:
+ delay (may be omitted unless css is included)
+ is an unquoted number indicating the number of millisecs to wait before
+ initiating an XMLHttpRequest GET request. It should be 0 when using onclick
+ or onload, but may be a modest value such as 300 for onmouseover to avoid
+ any chatter of requests. When used with onmouseover, include:
+ onmouseout="OLclearAJAX();"
+ to clear the request if the user does not hover for at least that long. If
+ the popup is not STICKY, include an nd or nd2 call, e.g.,
+ onmouseout="OLclearAJAX(); nd();"
+ And:
+ css (may be omitted)
+ is a quoted string with the CSS class (e.g. 'ovfl510' for
+ .ovfl510 {width:510px; height:145px; overflow:auto; ...} ) for a div to
+ encase the responseText and set the width, height and scrollbars in the
+ main text area of the popup, or the unquoted number 0 if no encasing div
+ is to be used.
+
+ For POST substitute OLpostAJAX(url, qry, command, delay, css);
+ Where
+ qry (required)
+ is the string to be posted, typically a query string (without a lead ?)
+ and the other arguments are as above.
+
+ See http://www.macridesweb.com/oltest/AJAX.html for more information.
+*/
+
+// Initialize our global variables for this function set.
+var OLhttp=false,OLcommandAJAX=null,OLdelayidAJAX=0,OLclassAJAX='',
+OLresponseAJAX='',OLabortAJAX=0,OLdebugAJAX=0;
+
+// Create a series of wrapper functions (e.g. OLcmdT#() for ones which
+// use OLhttp.responseText via the OLresponseAJAX global, and OLcmdX#()
+// for ones which use OLhttp.responseXML) whose reference (unquoted name
+// without parens) is the 2nd argument in OLgetAJAX(url,command,delay,css)
+// calls. This one is for the first example in the AJAX.html support
+// document, to use the OLresponseAJAX global as the lead argument for an
+// overlib popup. Put your functions in the head, or in another imported
+// .js file, so that they will not be affected by updates of this .js file.
+//
+function OLcmdExT1() {
+ return overlib(OLresponseAJAX, TEXTPADDING,0, CAPTIONPADDING,4,
+ CAPTION,'Example with AJAX content via <span '
+ +'class="yellow">responseText</span>. Popup scrolls with the window.',
+ WRAP, BORDER,2, STICKY, CLOSECLICK, SCROLL,
+ MIDX,0, RELY,100,
+ STATUS,'Example with AJAX content via responseText of XMLHttpResponse');
+}
+
+// Alert for old browsers which lack XMLHttpRequest support.
+function OLsorryAJAX() {
+ alert('Sorry, AJAX is not supported by your browser.');
+ return false;
+}
+
+// Check 2nd arg for function
+function OLchkFuncAJAX(ar){
+ var t=typeof ar;return (((t=='function'))||((t=='string')&&(/.+\(.*\)/.test(ar))));
+}
+
+// Alert for bad 2nd argument
+function OLnotFuncAJAX(m) {
+ if(over)cClick();
+ alert('The 2nd arg of OL'+m+'AJAX is not a function reference, nor an inline function, '
+ +'nor a quoted string with a function indicated.');
+ return OLclearAJAX();
+}
+
+// Alert for indicating an XMLHttpRequest network error.
+function OLerrorAJAX() {
+ if(OLhttp.status&&OLhttp.status!=2147746065)alert('Network error '+OLhttp.status+'. Try again later.');
+ return false;
+}
+
+// Returns a new XMLHttpRequest object, or false for older browsers
+// which did not yet support it. Called as OLhttp=OLnewXMLHttp() via
+// the OLgetAJAX(url,command,delay,css) wrapper function.
+//
+function OLnewXMLHttp() {
+ var f=false,req=f;
+ if(window.XMLHttpRequest)eval(new Array('try{',
+ 'req=new XMLHttpRequest();','}catch(e){','req=f;','}').join('\n'));
+ /*@cc_on @if(@_jscript_version>=5)if(!req)
+ eval(new Array('try{','req=new ActiveXObject("Msxml2.XMLHTTP");',
+ '}catch(e){','try{','req=new ActiveXObject("Microsoft.XMLHTTP");',
+ '}catch(e){','req=f;','}}').join('\n')); @end @*/
+ return req;
+}
+
+// Handle the OLhttp.responseText string from the XMLHttpRequest object.
+function OLdoAJAX() {
+ if(OLhttp.readyState==4){
+ if(OLdebugAJAX)alert(
+ 'OLhttp.status = '+OLhttp.status+'\n'
+ +'OLhttp.statusText = '+OLhttp.statusText+'\n'
+ +'OLhttp.getAllResponseHeaders() = \n'
+ +OLhttp.getAllResponseHeaders()+'\n'
+ +'OLhttp.getResponseHeader("Content-Type") = '
+ +OLhttp.getResponseHeader("Content-Type")+'\n');
+ if(OLhttp.status==200||(OLhttp.status==0&&!OLabortAJAX&&!OLie55)){
+ OLresponseAJAX=OLclassAJAX?'<div class="'+OLclassAJAX+'">':'';
+ OLresponseAJAX += OLhttp.responseText;
+ OLresponseAJAX += OLclassAJAX?'</div>':'';
+ if(OLdebugAJAX)alert('OLresponseAJAX = \n'+OLresponseAJAX);
+ OLclassAJAX=0;
+ return (typeof OLcommandAJAX=='string')?eval(OLcommandAJAX):OLcommandAJAX();
+ }else{
+ OLclassAJAX=0;
+ OLabortAJAX=0;
+ return OLerrorAJAX();
+ }
+ }
+}
+
+// Actually make the request initiated via OLgetAJAX or OLpostAJAX, or
+// invoke a "permission denied" alert if a cross-domain URL was used.
+function OLsetAJAX(url,qry) {
+ if(window.location.protocol.indexOf('http')==0&&
+ (url.indexOf('file:')==0||url.indexOf('ftp:')==0)){
+ alert('[object Error]\n(Cross-domain access not permitted)');return false;}
+ qry=(qry||null);var s='',m=(qry)?'POST':'GET';OLabortAJAX=0;
+ OLdelayidAJAX=0;eval(new Array('try{','OLhttp.open(m,url,true);',
+ '}catch(e){','s=e','OLhttp=false;','}').join('\n'));if(!OLhttp){
+ alert(s+'\n(Cross-domain access not permitted)');return false;}if(qry)
+ OLhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
+ OLhttp.onreadystatechange=OLdoAJAX;
+ OLhttp.send(qry);
+}
+
+// Clear or abort any delayed OLsetAJAX call or pending request.
+function OLclearAJAX() {
+ if(OLdelayidAJAX){clearTimeout(OLdelayidAJAX);OLdelayidAJAX=0;}
+ if(OLhttp&&!OLdebugAJAX){OLabortAJAX=1;OLhttp.abort();}
+ return false;
+}
+
+// Load a new XMLHttpRequest object into the OLhttp global, load the
+// OLcommandAJAX and OLclassAJAX globals, and initiate a GET request
+// via OLsetAJAX(url) to populate OLhttp.
+function OLgetAJAX(url,command,delay,css) {
+ if(!OLchkFuncAJAX(command))return OLnotFuncAJAX('get');
+ OLclearAJAX();OLhttp=OLnewXMLHttp();if(!OLhttp)return OLsorryAJAX();
+ OLcommandAJAX=command;delay=(delay||0);css=(css||0);OLclassAJAX=css;
+ if(delay)OLdelayidAJAX=setTimeout("OLsetAJAX('"+url+"')",delay);
+ else OLsetAJAX(url);
+}
+
+// Load a new XMLHttpRequest object into the OLhttp global, load the
+// OLcommandAJAX and OLclassAJAX globals, and initiate a POST request
+// via OLsetAJAX(url,qry) to populate OLhttp.
+function OLpostAJAX(url,qry,command,delay,css) {
+ if(!OLchkFuncAJAX(command))return OLnotFuncAJAX('post');
+ OLclearAJAX();OLhttp=OLnewXMLHttp();if(!OLhttp)return OLsorryAJAX();
+ qry=(qry||0);OLcommandAJAX=command;delay=(delay||0);css=(css||0);OLclassAJAX=css;
+ if(delay)OLdelayidAJAX=setTimeout("OLsetAJAX('"+url+"','"+qry+"')",delay);
+ else OLsetAJAX(url,qry);
+}
diff --git a/httemplate/misc/tax-import.cgi b/httemplate/misc/tax-import.cgi index 2bae6f10a..bca623fed 100644 --- a/httemplate/misc/tax-import.cgi +++ b/httemplate/misc/tax-import.cgi @@ -29,11 +29,13 @@ Import a CSV file set containing tax rate records. <% include( '/elements/file-upload.html', 'field' => [ 'codefile', 'plus4file', + 'zipfile', 'txmatrix', 'detail', ], 'label' => [ 'code filename', 'plus4 filename', + 'zip filename', 'txmatrix filename', 'detail filename', ], diff --git a/httemplate/misc/xmlhttp-cust_main-address_standardize.html b/httemplate/misc/xmlhttp-cust_main-address_standardize.html index 8532bb23a..72fa4a464 100644 --- a/httemplate/misc/xmlhttp-cust_main-address_standardize.html +++ b/httemplate/misc/xmlhttp-cust_main-address_standardize.html @@ -72,7 +72,9 @@ if ( $sub eq 'address_standardize' ) { } else { - warn "USPS WebTools error: ". $verifier->response. "\n"; + $return->{$pre.'error'} = "USPS WebTools error: ". + $verifier->{error}{description}; + } |