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
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 );