summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2016-11-01 01:47:22 -0700
committerMark Wells <mark@freeside.biz>2016-11-01 01:47:22 -0700
commit125e0f4ef17299fd25d7dacfccdc5fa5f23a4a9d (patch)
tree1075b5ae5e24eba428a59591cd27a43011b284c3
parent9367a73317b642a2f3a00bc80c1c1401f5be7b12 (diff)
fix duplication of Washington sales taxes, #73185, fallout from #71501
-rw-r--r--FS/FS/cust_main_county.pm80
-rw-r--r--FS/FS/geocode_Mixin.pm2
2 files changed, 56 insertions, 26 deletions
diff --git a/FS/FS/cust_main_county.pm b/FS/FS/cust_main_county.pm
index 40caabb..5af33c2 100644
--- a/FS/FS/cust_main_county.pm
+++ b/FS/FS/cust_main_county.pm
@@ -641,6 +641,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
@@ -663,6 +694,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',
@@ -673,33 +726,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 a372faa..09b1131 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