RT# 82988 - updated paybatch upgrade to move credits from combined batch file to...
[freeside.git] / FS / FS / cust_location.pm
index 5a144b8..a2bda71 100644 (file)
@@ -14,6 +14,12 @@ use FS::cust_main_county;
 use FS::part_export;
 use FS::GeocodeCache;
 
+# Essential fields. Can't be modified in place, will be considered in
+# deciding if a location is "new", and (because of that) can't have
+# leading/trailing whitespace.
+my @essential = (qw(custnum address1 address2 city county state zip country
+  location_number location_type location_kind disabled));
+
 $import = 0;
 
 $DEBUG = 0;
@@ -174,9 +180,6 @@ sub find_or_insert {
 
   warn "find_or_insert:\n".Dumper($self) if $DEBUG;
 
-  my @essential = (qw(custnum address1 address2 city county state zip country
-    location_number location_type location_kind disabled));
-
   if ($conf->exists('cust_main-no_city_in_address')) {
     warn "Warning: passed city to find_or_insert when cust_main-no_city_in_address is configured, ignoring it"
       if $self->get('city');
@@ -262,8 +265,15 @@ sub insert {
     return $error;
   }
 
-  #false laziness with cust_main, will go away eventually
-  if ( !$import and $conf->config('tax_district_method') ) {
+  # If using tax_district_method, for rows in state of Washington,
+  # without a tax district already specified, queue a job to find
+  # the tax district
+  if (
+       !$import
+    && !$self->district
+    && lc $self->state eq 'wa'
+    && $conf->config('tax_district_method')
+  ) {
 
     my $queue = new FS::queue {
       'job' => 'FS::geocode_Mixin::process_district_update'
@@ -377,9 +387,9 @@ sub check {
 
   return '' if $self->disabled; # so that disabling locations never fails
 
-  # maybe should just do all fields in the table?
-  # or in every table?
-  $self->trim_whitespace(qw(district city county state country));
+  # whitespace in essential fields leads to problems figuring out if a
+  # record is "new"; get rid of it.
+  $self->trim_whitespace(@essential);
 
   my $error = 
     $self->ut_numbern('locationnum')
@@ -433,6 +443,26 @@ sub check {
     && $conf->exists('prospect_main-alt_address_format')
     && ! $self->location_kind;
 
+  # Do not allow bad tax district values in cust_location when
+  # using Washington State district sales tax calculation - would result
+  # in incorrect or missing sales tax on invoices.
+  my $tax_district_method = FS::Conf->new->config('tax_district_method');
+  if (
+    $tax_district_method
+    && $tax_district_method eq 'wa_sales'
+    && $self->district
+  ) {
+    my $cust_main_county = qsearchs(
+      cust_main_county => { district => $self->district }
+    );
+    unless ( ref $cust_main_county ) {
+      return sprintf (
+        'WA State tax district %s does not exist in tax table',
+        $self->district
+      );
+    }
+  }
+
   unless ( $import or qsearch('cust_main_county', {
     'country' => $self->country,
     'state'   => '',
@@ -929,16 +959,22 @@ sub _upgrade_data {
 
   # trim whitespace on records that need it
   local $allow_location_edit = 1;
-  foreach my $field (qw(city county state country district)) {
+  foreach my $field (@essential) {
+    next if $field eq 'custnum';
+    next if $field eq 'disabled';
     foreach my $location (qsearch({
       table => 'cust_location',
-      extra_sql => " WHERE $field LIKE ' %' OR $field LIKE '% '"
+      extra_sql => " WHERE disabled IS NULL AND ($field LIKE ' %' OR $field LIKE '% ')"
     })) {
       my $error = $location->replace;
       die "$error (fixing whitespace in $field, locationnum ".$location->locationnum.')'
         if $error;
 
-      if ( $use_districts ) {
+      if (
+        $use_districts
+        && !$location->district
+        && lc $location->state eq 'wa'
+      ) {
         my $queue = new FS::queue {
           'job' => 'FS::geocode_Mixin::process_district_update'
         };