9 use FS::cust_main_county;
11 use FS::Record qw( qsearch qsearchs );
12 use FS::UID qw( adminsuidsetup );
17 local $FS::UID::AutoCommit = 0;
28 'check' => \$opt_check,
29 'merge=s' => \@opt_merge,
30 'set-source-null=s' => \@opt_set_source_null,
32 @opt_merge = split(',',join(',',@opt_merge));
33 @opt_set_source_null = split(',',join(',',@opt_set_source_null));
37 # check => $opt_check,
38 # merge => \@opt_merge,
39 # set_source_numm => \@opt_set_source_null,
44 $dbh = adminsuidsetup( $freeside_user )
45 or die "Bad username: $freeside_user\n";
47 my $log = FS::Log->new('freeside-wa-tax-table-resolve');
51 } elsif ( @opt_merge ) {
53 } elsif ( @opt_set_source_null ) {
56 error_and_help('No options selected');
61 local $FS::UID::AutoCommit = 1;
68 for my $taxnum ( @opt_set_source_null ) {
69 my $row = qsearchs( cust_main_county => { taxnum => $taxnum } );
71 push @cust_main_county, $row;
73 error_and_help("Invalid taxnum specified: $taxnum");
77 say "=== Specified tax rows ===";
78 print_taxnum($_) for @cust_main_county;
82 The source column will be set to NULL for each of the
83 tax rows listed. The tax row will no longer be managed
84 by the washington state sales tax table update utilities.
86 The listed taxes should be manually created taxes, that
87 were never intended to be managed by the auto updater.
91 for my $row ( @cust_main_county ) {
93 $row->setfield( source => undef );
94 my $error = $row->replace;
99 my $message = sprintf 'Error setting source=null taxnum %s: %s',
100 $row->taxnum, $error;
102 $log->error( $message );
108 my $message = sprintf 'Source column set to null for taxnum %s',
111 $log->warn( $message );
117 my $source = qsearchs( cust_main_county => { taxnum => $opt_merge[0] });
118 my $target = qsearchs( cust_main_county => { taxnum => $opt_merge[1] });
120 error_and_help("Invalid source taxnum: $opt_merge[0]")
122 error_and_help("Invalid target taxnum: $opt_merge[1]")
125 local $| = 1; # disable output buffering
127 say '==== source row ====';
128 print_taxnum( $source );
130 say '==== target row ====';
131 print_taxnum( $target );
133 confirm_to_continue("
135 The source tax will be merged into the target tax.
136 All references to the source tax on customer invoices
137 will be replaced with references to the target tax.
138 The source tax will be removed from the tax tables.
143 eval { $source->_merge_into( $target, { identical_record_check => 0 } ) };
147 my $message = sprintf 'Failed to merge wa sales tax %s into %s: %s',
148 $source->taxnum, $target->taxnum, $@;
151 $log->error( $message );
154 my $message = sprintf 'Merged wa sales tax %s into %s - success',
155 $source->taxnum, $target->taxnum;
158 $log->warn( $message );
164 $freeside_user = shift @ARGV
165 or error_and_help('freeside_user parameter required');
168 error_and_help(( '--merge requires a comma separated list of two taxnums'))
169 unless scalar(@opt_merge) == 2
170 && $opt_merge[0] =~ /^\d+$/
171 && $opt_merge[1] =~ /^\d+$/;
174 for my $taxnum ( @opt_set_source_null ) {
175 if ( $taxnum =~ /\D/ ) {
176 error_and_help( "Invalid taxnum ($taxnum)" );
182 my @dupes = FS::cust_main_county->find_wa_tax_dupes;
185 say 'No duplicate tax rows detected for WA sales tax districts';
189 say sprintf '=== Detected %s duplicate tax rows ===', scalar @dupes;
191 print_taxnum($_) for @dupes;
194 sprintf 'Detected %s duplicate wa sales tax rows: %s',
196 join( ',', map{ $_->taxnum } @dupes )
203 die unless ref $taxnum;
205 say 'taxnum: '.$taxnum->taxnum;
207 map { sprintf(' %s:%s', $_, $taxnum->$_ ) }
208 qw/district city county state tax taxname taxclass source/
213 sub confirm_to_continue {
215 print "Confirm: [y/N]: ";
218 if ( lc $yn ne 'y' ) {
226 -message => sprintf( "\n\nError:\n\t%s\n\n", shift ),
237 freeside-wa-tax-table-resolve
241 freeside-wa-tax-table-resolve --help
242 freeside-wa-tax-table-resolve --check [freeside_user]
243 freeside-wa-tax-table-resolve --merge 123,234 [freeside_user]
244 freeside-wa-tax-table-resolve --set-source-null 1337,6553 [freeside_user]
252 Display help and exit
256 Display info on any taxnums considered blocking duplicates
258 =item B<--merge> [source-taxnum],[target-taxnum]
260 Update all records referring to [source-taxnum], so they now
261 refer to [target-taxnum]. [source-taxnum] is deleted.
263 Used to merge duplicate taxnums
265 =item B<--set-source-null> [taxnum],[taxnum],...
267 Update all records for the given taxnums, by setting the
268 I<source> column to NULL.
270 Used for manually entered tax entries, incorrectly labelled
271 as created and managed for Washington State Sales Taxes
277 Tool to resolve tax table issues for customer using Washington state
280 If Freeside detects duplicate rows within the wa sales tax tables,
281 tax table updates are blocked, and a log message directs the
282 sysadmin to this tool.
284 Duplicate rows may be manually entered taxes, not related
285 to WA sales tax. Or duplicate rows may have been manually entered
286 into freeside for other tax purposes.
288 Use --check to display which tax entries were detected as dupes.
290 For each tax entry, decide if it is a duplicate wa sales tax entry,
291 or some other manually entered tax.
293 if the row is a duplicate, merge the duplicates with the --merge
294 option of this script
296 If the row is a manually entered tax, not for WA state sales taxes,
297 keep the tax but remove the flag incorrectly labeling it as WA state
298 sales taxes with the --set-source-null option of this script
300 Once --check no longer returns problematic tax entries, the
301 wa state tax tables will be able to complete their automatic