From: Mark Wells Date: Tue, 1 Nov 2016 08:47:22 +0000 (-0700) Subject: fix duplication of Washington sales taxes, #73185, fallout from #71501 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=6a4b5b3bf9b3e589cf8ff18453e9c6be6a50091a fix duplication of Washington sales taxes, #73185, fallout from #71501 --- diff --git a/FS/FS/cust_main_county.pm b/FS/FS/cust_main_county.pm index a1233d083..65fb72208 100644 --- a/FS/FS/cust_main_county.pm +++ b/FS/FS/cust_main_county.pm @@ -682,6 +682,37 @@ END } +sub _merge_into { + # for internal use: takes another cust_main_county object, transfers + # all existing references to this record to that one, and deletes this + # one. + my $record = shift; + my $other = shift or die "record to merge into must be provided"; + my $new_taxnum = $other->taxnum; + my $old_taxnum = $record->taxnum; + if ($other->tax != $record->tax or + $other->exempt_amount != $record->exempt_amount) { + # don't assume these are the same. + warn "Found duplicate taxes (#$new_taxnum and #$old_taxnum) but they have different rates and can't be merged.\n"; + } else { + warn "Merging tax #$old_taxnum into #$new_taxnum\n"; + foreach my $table (qw( + cust_bill_pkg_tax_location + cust_bill_pkg_tax_location_void + cust_tax_exempt_pkg + cust_tax_exempt_pkg_void + )) { + foreach my $row (qsearch($table, { 'taxnum' => $old_taxnum })) { + $row->set('taxnum' => $new_taxnum); + my $error = $row->replace; + die $error if $error; + } + } + my $error = $record->delete; + die $error if $error; + } +} + sub _upgrade_data { my $class = shift; # assume taxes in Washington with district numbers, and null name, or @@ -704,6 +735,28 @@ sub _upgrade_data { } FS::upgrade_journal->set_done($journal); } + my @key_fields = (qw(city county state country district taxname taxclass)); + + # remove duplicates (except disabled records) + my @duplicate_sets = qsearch({ + table => 'cust_main_county', + select => FS::Record::group_concat_sql('taxnum', ',') . ' AS taxnums, ' . + join(',', @key_fields), + extra_sql => ' WHERE tax > 0 + GROUP BY city, county, state, country, district, taxname, taxclass + HAVING COUNT(*) > 1' + }); + warn "Found ".scalar(@duplicate_sets)." set(s) of duplicate tax definitions\n" + if @duplicate_sets; + foreach my $set (@duplicate_sets) { + my @taxnums = split(',', $set->get('taxnums')); + my $first = FS::cust_main_county->by_key(shift @taxnums); + foreach my $taxnum (@taxnums) { + my $record = FS::cust_main_county->by_key($taxnum); + $record->_merge_into($first); + } + } + # trim whitespace and convert to uppercase in the 'city' field. foreach my $record (qsearch({ table => 'cust_main_county', @@ -714,33 +767,10 @@ sub _upgrade_data { # create an exact duplicate. # so find the record this one would duplicate, and merge them. $record->check; # trims whitespace - my %match = map { $_ => $record->get($_) } - qw(city county state country district taxname taxclass); + my %match = map { $_ => $record->get($_) } @key_fields; my $other = qsearchs('cust_main_county', \%match); if ($other) { - my $new_taxnum = $other->taxnum; - my $old_taxnum = $record->taxnum; - if ($other->tax != $record->tax or - $other->exempt_amount != $record->exempt_amount) { - # don't assume these are the same. - warn "Found duplicate taxes (#$new_taxnum and #$old_taxnum) but they have different rates and can't be merged.\n"; - } else { - warn "Merging tax #$old_taxnum into #$new_taxnum\n"; - foreach my $table (qw( - cust_bill_pkg_tax_location - cust_bill_pkg_tax_location_void - cust_tax_exempt_pkg - cust_tax_exempt_pkg_void - )) { - foreach my $row (qsearch($table, { 'taxnum' => $old_taxnum })) { - $row->set('taxnum' => $new_taxnum); - my $error = $row->replace; - die $error if $error; - } - } - my $error = $record->delete; - die $error if $error; - } + $record->_merge_into($other); } else { # else there is no record this one duplicates, so just fix it my $error = $record->replace; diff --git a/FS/FS/geocode_Mixin.pm b/FS/FS/geocode_Mixin.pm index a372faaa8..09b113112 100644 --- a/FS/FS/geocode_Mixin.pm +++ b/FS/FS/geocode_Mixin.pm @@ -273,7 +273,7 @@ sub process_district_update { my $error = $self->replace; die $error if $error; - my %hash = map { $_ => $tax_info->{$_} } + my %hash = map { $_ => uc( $tax_info->{$_} ) } qw( district city county state country ); $hash{'source'} = $method; # apply the update only to taxes we maintain