From: Mitch Jackson Date: Sun, 20 Jan 2019 21:22:50 +0000 (-0500) Subject: RT# 80488 Block billing for customer missing tax district X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=033d235172023f4ac44088808cc735f86e092477 RT# 80488 Block billing for customer missing tax district --- diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index d42bd813b..165b9fc6b 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -5781,6 +5781,51 @@ sub pending_invoice_count { FS::cust_bill->count( 'custnum = '.shift->custnum."AND pending = 'Y'" ); } +=item cust_locations_missing_district + +Always returns empty list, unless tax_district_method eq 'wa_sales' + +Return cust_location rows for this customer, associated with active +customer packages, where tax district column is empty. Presense of +these rows should block billing, because invoice would be generated +with incorrect taxes + +=cut + +sub cust_locations_missing_district { + my ( $self ) = @_; + + my $tax_district_method = FS::Conf->new->config('tax_district_method'); + + return () + unless $tax_district_method + && $tax_district_method eq 'wa_sales'; + + qsearch({ + table => 'cust_location', + select => 'cust_location.*', + addl_from => ' + LEFT JOIN cust_main USING (custnum) + LEFT JOIN cust_pkg ON cust_location.locationnum = cust_pkg.locationnum + ', + extra_sql => sprintf(q{ + WHERE cust_location.state = 'WA' + AND cust_location.custnum = %s + AND ( + cust_location.district IS NULL + or cust_location.district = '' + ) + AND cust_pkg.pkgnum IS NOT NULL + AND ( + cust_pkg.cancel > %s + OR cust_pkg.cancel IS NULL + ) + }, + $self->custnum, time() + ), + }); +} + #starting to take quite a while for big dbs # (JRNL: journaled so it only happens once per database) # - seq scan of h_cust_main (yuck), but not going to index paycvv, so diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 1be7d39f9..5f8dd9b4c 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -152,6 +152,41 @@ sub bill_and_collect { else { die $error; } } + my $tax_district_method = $conf->config('tax_district_method'); + if ( $tax_district_method && $tax_district_method eq 'wa_sales' ) { + # When using Washington State Sales Tax Districts, + # Bail out of billing customer if sales tax district for location is missing + + $log->debug('checking cust_location tax districts', %logopt); + + if ( + my @cust_locations_missing_district = + $self->cust_locations_missing_district + ) { + $error = sprintf + 'cust_location missing tax district: '. + join( ', ' => ( + map( + { + sprintf + 'locationnum(%s) %s %s %s %s', + $_->locationnum, + $_->address1, + $_->city, + $_->state, + $_->zip + } + @cust_locations_missing_district + ) + )); + } + } + if ( $error ) { + $error = "Error calculating taxes ".$self->custnum. ": $error"; + if ( $options{fatal} && $options{fatal} eq 'return' ) { return $error; } + else { die $error; } + } + $job->update_statustext('20,billing packages') if $job; $log->debug('billing packages', %logopt); $error = $self->bill( %options );