From: Mark Wells Date: Thu, 1 Mar 2012 20:33:48 +0000 (-0800) Subject: duplicate address checking for new customers, #16582 X-Git-Url: http://git.freeside.biz/gitweb/?a=commitdiff_plain;h=943e96a24a110babfd15f94f95abbf42a95c71ab;p=freeside.git duplicate address checking for new customers, #16582 --- diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 624ea1af3..29e3111dd 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -3588,6 +3588,17 @@ and customer address. Include units.', }, { + 'key' => 'cust_main-check_unique', + 'section' => '', + 'description' => 'Warn before creating a customer record where these fields duplicate another customer.', + 'type' => 'select', + 'multiple' => 1, + 'select_hash' => [ + 'address1' => 'Billing address', + ], + }, + + { 'key' => 'svc_acct-display_paid_time_remaining', 'section' => '', 'description' => 'Show paid time remaining in addition to time remaining.', diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi index 14825d055..d2c0cb785 100755 --- a/httemplate/edit/cust_main.cgi +++ b/httemplate/edit/cust_main.cgi @@ -195,7 +195,7 @@ function samechanged(what) { % } -<& cust_main/bottomfixup.html &> +<& cust_main/bottomfixup.html, 'custnum' => $custnum &>
+<& /elements/init_overlib.html &> -<% include( '/elements/xmlhttp.html', - 'url' => $p.'misc/xmlhttp-cust_main-address_standardize.html', - 'subs' => [ 'address_standardize' ], - #'method' => 'POST', #could get too long? - ) -%> +<& /elements/xmlhttp.html, + url => $p.'misc/xmlhttp-cust_main-address_standardize.html', + subs => [ 'address_standardize' ], + #'method' => 'POST', #could get too long? +&> -<% include( '/elements/xmlhttp.html', - 'url' => $p.'misc/xmlhttp-cust_main-censustract.html', - 'subs' => [ 'censustract' ], - #'method' => 'POST', #could get too long? - ) -%> +<& /elements/xmlhttp.html, + url => $p.'misc/xmlhttp-cust_main-censustract.html', + subs => [ 'censustract' ], + #'method' => 'POST', #could get too long? +&> + + +<& /elements/xmlhttp.html, + url => $p.'misc/xmlhttp-cust_main-duplicates.html', + subs => [ 'duplicates_form' ] +&> diff --git a/httemplate/edit/cust_main/bottomfixup.js b/httemplate/edit/cust_main/bottomfixup.js index 6b30cbc80..800864bc8 100644 --- a/httemplate/edit/cust_main/bottomfixup.js +++ b/httemplate/edit/cust_main/bottomfixup.js @@ -1,6 +1,48 @@ +<%init> +my %opt = @_; # custnum +my $conf = new FS::Conf; + +my $company_latitude = $conf->config('company_latitude'); +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, 'check_unique' + if $conf->exists('cust_main-check_unique') and !$opt{'custnum'}; + +push @fixups, 'do_submit'; # always last + + +var fixups = <% encode_json(\@fixups) %>; +var fixup_position; + +%# state machine to deal with all the asynchronous stuff we're doing +%# call this after each fixup on success: +function submit_continue() { + window[ fixups[fixup_position++] ].call(); +} + +%# or on failure: +function submit_abort() { + fixup_position = 0; + document.CustomerForm.submitButton.disabled = false; + cClick(); +} + function bottomfixup(what) { + fixup_position = 0; + document.CustomerForm.submitButton.disabled = true; + submit_continue(); +} + +function do_submit() { + document.CustomerForm.submit(); +} -%# ../cust_main.cgi +function copy_payby_fields() { var layervars = new Array( 'payauto', 'billday', 'payinfo', 'payinfo1', 'payinfo2', 'payinfo3', 'paytype', @@ -18,20 +60,17 @@ function bottomfixup(what) { cf.elements[field] ); } - - //this part does USPS address correction - standardize_locations(); - + submit_continue(); } +%# call submit_continue() on completion... +%# otherwise not touching standardize_locations for now <% include( '/elements/standardize_locations.js', - 'callback', 'post_geocode();' + 'callback' => 'submit_continue();' ) %> -function post_geocode() { - -% if ( $conf->exists('cust_main-require_censustract') ) { +function fetch_censustract() { //alert('fetch census tract data'); var cf = document.CustomerForm; @@ -46,12 +85,6 @@ function post_geocode() { censustract( census_data, update_censustract ); -% }else{ - - document.CustomerForm.submit(); - -% } - } var set_censustract; @@ -77,7 +110,7 @@ function update_censustract(arg) { set_censustract = function () { cf.elements['censustract'].value = newcensus; - cf.submit(); + submit_continue(); } @@ -112,12 +145,12 @@ function update_censustract(arg) { choose_censustract = choose_censustract + '' + - '' + + '' + '' + '' + '' + '' + - '' + + '' + ''; @@ -125,7 +158,7 @@ function update_censustract(arg) { } else { - cf.submit(); + submit_continue(); } @@ -153,12 +186,24 @@ function copyelement(from, to) { //alert(from + " (" + from.type + "): " + to.name + " => " + to.value); } -<%init> - -my $conf = new FS::Conf; +function check_unique() { + var search_hash = new Object; +% foreach ($conf->config('cust_main-check_unique')) { + search_hash['<% $_ %>'] = document.CustomerForm.elements['<% $_ %>'].value; +% } -my $company_latitude = $conf->config('company_latitude'); -my $company_longitude = $conf->config('company_longitude'); +%# supported in IE8+, Firefox 3.5+, WebKit, Opera 10.5+ + duplicates_form(JSON.stringify(search_hash), confirm_unique); +} +function confirm_unique(arg) { + if ( arg.match(/\S/) ) { +%# arg contains a complete form to choose an existing customer, or not + overlib( arg, CAPTION, 'Duplicate customer', STICKY, AUTOSTATUSCAP, + CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, + 268, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); + } else { // no duplicates + submit_continue(); + } +} - diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi index f75e2a6ae..994f9b7ca 100755 --- a/httemplate/edit/process/cust_main.cgi +++ b/httemplate/edit/process/cust_main.cgi @@ -66,6 +66,16 @@ my $new = new FS::cust_main ( { } fields('cust_main') } ); +$cgi->param('duplicate_of_custnum') =~ /^(\d+)$/; +my $duplicate_of = $1; +if ( $duplicate_of ) { + # then negate all changes to the customer; the only change we should + # make is to order a package, if requested + $new = qsearchs('cust_main', { 'custnum' => $duplicate_of }) + # this should never happen + or die "nonexistent existing customer (custnum $duplicate_of)"; +} + if ( defined($cgi->param('same')) && $cgi->param('same') eq "Y" ) { $new->setfield("ship_$_", '') foreach qw( last first company address1 address2 city county state zip @@ -122,7 +132,7 @@ my @exempt_groups = grep /\S/, $conf->config('tax-cust_exempt-groups'); my @tax_exempt = grep { $cgi->param("tax_$_") eq 'Y' } @exempt_groups; #perhaps this stuff should go to cust_main.pm -if ( $new->custnum eq '' ) { +if ( $new->custnum eq '' or $duplicate_of ) { my $cust_pkg = ''; my $svc; @@ -216,23 +226,31 @@ if ( $new->custnum eq '' ) { } + use Tie::RefHash; tie my %hash, 'Tie::RefHash'; %hash = ( $cust_pkg => [ $svc ] ) if $cust_pkg; - $error ||= $new->insert( \%hash, \@invoicing_list, + if ( $duplicate_of ) { + # order the package and service normally + $error ||= $new->order_pkgs( \%hash ) if $cust_pkg; + } + else { + # create the customer + $error ||= $new->insert( \%hash, \@invoicing_list, 'tax_exemption'=> \@tax_exempt, 'prospectnum' => scalar($cgi->param('prospectnum')), - ); + ); - my $conf = new FS::Conf; - if ( $conf->exists('backend-realtime') && ! $error ) { + my $conf = new FS::Conf; + if ( $conf->exists('backend-realtime') && ! $error ) { - my $berror = $new->bill - || $new->apply_payments_and_credits - || $new->collect( 'realtime' => 1 ); - warn "Warning, error billing during backend-realtime: $berror" if $berror; + my $berror = $new->bill + || $new->apply_payments_and_credits + || $new->collect( 'realtime' => 1 ); + warn "Warning, error billing during backend-realtime: $berror" if $berror; - } + } + } #if $duplicate_of } else { #create old record object diff --git a/httemplate/misc/xmlhttp-cust_main-search.cgi b/httemplate/misc/xmlhttp-cust_main-search.cgi index 6f023121f..68c5bf597 100644 --- a/httemplate/misc/xmlhttp-cust_main-search.cgi +++ b/httemplate/misc/xmlhttp-cust_main-search.cgi @@ -22,6 +22,21 @@ % my $return = $inv ? findbycustnum($inv->custnum,0) : []; <% objToJson($return) %> % } +% elsif ( $sub eq 'exact_search' ) { +% # XXX possibly should query each element separately +% my $hashref = decode_json($cgi->param('arg')); +% my @cust_main = qsearch('cust_main', $hashref); +% my $return = []; +% foreach (@cust_main) { +% push @$return, { +% custnum => $_->custnum, +% name => $_->name_short, +% address1 => $_->address1, +% city => $_->city, +% }; +% } +<% objToJson($return) %> +% } <%init> my $conf = new FS::Conf;