Merge branch 'master' of git.freeside.biz:/home/git/freeside
authorIvan Kohler <ivan@freeside.biz>
Thu, 17 Nov 2016 01:10:12 +0000 (17:10 -0800)
committerIvan Kohler <ivan@freeside.biz>
Thu, 17 Nov 2016 01:10:12 +0000 (17:10 -0800)
FS/FS/Cron/tax_rate_update.pm
FS/FS/Misc/Geo.pm
FS/FS/TaxEngine/billsoft.pm
FS/FS/cust_main_county.pm
FS/FS/geocode_Mixin.pm
FS/bin/freeside-upgrade
httemplate/elements/menu.html
httemplate/elements/standardize_locations.js
httemplate/view/cust_main/billing.html
httemplate/view/cust_main/payment_history/invoice.html

index 2c021b8..b6ac63c 100755 (executable)
@@ -40,6 +40,7 @@ sub tax_rate_update {
 
   my $taxname = $conf->config('tax_district_taxname') || '';
 
+  FS::cust_main_county->lock_table;
   if ($method eq 'wa_sales') {
     # download the update file
     my $now = DateTime->now;
index 92490bb..6b3d6ca 100644 (file)
@@ -210,13 +210,13 @@ sub wa_sales {
         if ( lc($text) eq 'location code' ) {
           $p->get_tag('td'); # skip to the next column
           undef $u;
-          $u = $p->get_token until $u->[0] eq 'T'; # and then skip non-text
+          $u = $p->get_token until ($u->[0] || '') eq 'T'; # and then skip non-text
           $return->{'district'} = $u->[1];
         }
         elsif ( lc($text) eq 'total tax rate' ) {
           $p->get_tag('td');
           undef $u;
-          $u = $p->get_token until $u->[0] eq 'T';
+          $u = $p->get_token until ($u->[0] || '') eq 'T';
           $return->{'tax'} = $u->[1];
         }
       } # get_token
index d262aa4..6bda8db 100644 (file)
@@ -105,6 +105,7 @@ sub create_batch {
     my %sales;
 
     foreach my $cust_bill_pkg ( $cust_bill->cust_bill_pkg ) {
+$DB::single = 1;
       my $cust_pkg = $cust_pkg{$cust_bill_pkg->pkgnum}
                  ||= $cust_bill_pkg->cust_pkg;
       my $pkgpart = $cust_bill_pkg->pkgpart_override || $cust_pkg->pkgpart;
index 924f9bf..5325fa5 100644 (file)
@@ -717,7 +717,7 @@ sub _upgrade_data {
   my $class = shift;
   # assume taxes in Washington with district numbers, and null name, or 
   # named 'sales tax', are looked up via the wa_sales method. mark them.
-  my $journal = 'cust_main_county__source_wa_sales';
+  my $journal = 'cust_main_county__source_wa_sales_201611';
   if (!FS::upgrade_journal->is_done($journal)) {
     my @taxes = qsearch({
         'table'     => 'cust_main_county',
@@ -737,26 +737,6 @@ sub _upgrade_data {
   }
   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',
@@ -782,7 +762,7 @@ sub _upgrade_data {
   my $district_taxname = $conf->config('tax_district_taxname');
   $journal = 'cust_main_county__district_taxclass';
   if (!FS::upgrade_journal->is_done($journal)
-      and $conf->config('enable_taxclasses')) {
+      and $conf->exists('enable_taxclasses')) {
     eval "use FS::part_pkg_taxclass";
     my @taxes = qsearch({
         'table'     => 'cust_main_county',
@@ -856,6 +836,27 @@ sub _upgrade_data {
       }   
     }
   }
+
+  # 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);
+    }
+  }
+
  
   '';
 }
index 46f8128..ef16e74 100644 (file)
@@ -260,6 +260,7 @@ sub process_district_update {
   die $@ if $@;
   die "$class has no location data" if !$class->can('location_hash');
 
+  my $error;
   my $conf = FS::Conf->new;
   my $method = $conf->config('tax_district_method')
     or return; #nothing to do if null
@@ -269,9 +270,11 @@ sub process_district_update {
   my $tax_info = get_district({ $self->location_hash }, $method);
   return unless $tax_info;
 
-  $self->set('district', $tax_info->{'district'} );
-  my $error = $self->replace;
-  die $error if $error;
+  if ($self->district ne $tax_info->{'district'}) {
+    $self->set('district', $tax_info->{'district'} );
+    $error = $self->replace;
+    die $error if $error;
+  }
 
   my %hash = map { $_ => uc( $tax_info->{$_} ) } 
     qw( district city county state country );
@@ -281,6 +284,9 @@ sub process_district_update {
   my $taxname = $conf->config('tax_district_taxname');
   # there must be exactly one cust_main_county for each district+taxclass.
   # do NOT exclude taxes that are zero.
+
+  # mutex here so that concurrent queue jobs can't make duplicates.
+  FS::cust_main_county->lock_table;
   foreach my $taxclass (@classes) {
     my @existing = qsearch('cust_main_county', {
       %hash,
index 77087c3..ffd574e 100755 (executable)
@@ -298,7 +298,7 @@ print "\n" if $DRY_RUN;
 
 if ( $dbh->{Driver}->{Name} =~ /^mysql/i && ! $opt_s ) {
 
-  foreach my $table (qw( svc_acct svc_phone )) {
+  foreach my $table (qw( svc_acct svc_phone cust_main_county )) {
 
     my $sth = $dbh->prepare(
       "SELECT COUNT(*) FROM duplicate_lock WHERE lockname = '$table'"
index c4ea9cd..72b586e 100644 (file)
@@ -503,7 +503,7 @@ tie my %tools_importing, 'Tie::IxHash',
   'Phone numbers (DIDs)' => [ $fsurl.'misc/phone_avail-import.html', '' ],
   'Call Detail Records (CDRs)' => [ $fsurl.'misc/cdr-import.html', '' ],
 ;
-if ( $conf->config('tax_data_vendor') eq 'cch' ) {
+if ( $conf->config('tax_data_vendor') ) {
   if ( $conf->exists('taxdatadirectdownload') ) {
       $tools_importing{'Tax rates from vendor site'} =
       [ $fsurl.'misc/tax-fetch_and_import.cgi', '' ];
index ecccd90..dd68370 100644 (file)
@@ -207,8 +207,8 @@ function post_standardization() {
     prefix = 'bill_';
   }
 
-  if ( new String(cf.elements[prefix + 'zip'].value).length < 10 )
-  {
+//  if ( new String(cf.elements[prefix + 'zip'].value).length < 10 )
+//  {
 
     var country_el = cf.elements[prefix + 'country'];
     var country = country_el.options[ country_el.selectedIndex ].value;
@@ -238,12 +238,12 @@ function post_standardization() {
 
     }
 
-  } else {
-
-    cf.elements[prefix + 'geocode'].value = '';
-    <% $post_geocode %>;
-
-  }
+//  } else {
+//
+//    cf.elements[prefix + 'geocode'].value = '';
+//    <% $post_geocode %>;
+//
+//  }
 
 % } else {
 
index 8d3925a..49dbeae 100644 (file)
@@ -132,13 +132,13 @@ set_display_recurring(<% encode_json({'display_recurring' => [ $cust_main->displ
     </TR>
 % }
 
-% if ( $conf->config('tax_data_vendor') eq 'cch' ) {
+% if ( $conf->config('tax_data_vendor') ) {
 <TR>
   <TH ALIGN="right"><% mt('Tax location') |h %></TH>
 % my $tax_location = $conf->exists('tax-ship_address')
 %                    ? $cust_main->ship_location
 %                    : $cust_main->bill_location;
-  <TD><% $tax_location->geocode('cch') %></TD>
+  <TD><% $tax_location->geocode %></TD>
 </TR>
 % }
 <TR>
index 3a84b9e..7c993d6 100644 (file)
@@ -3,10 +3,12 @@
 
 my( $cust_bill, %opt ) = @_;
 
-my $invoice = emt("Invoice #[_1] (Balance [_2])",$cust_bill->display_invnum,$cust_bill->owed);
-
 my $under = '';
-if ( $cust_bill->owed > 0 ) {
+my $invoice;
+if ( $cust_bill->pending ) {
+  $invoice = '<I><FONT SIZE="+1" COLOR="#D05000">' .
+    emt("Pending Invoice #[_1] (Charges of [_2])", $cust_bill->display_invnum, $cust_bill->charged);
+} elsif ( $cust_bill->owed > 0 ) {
   $invoice = '<B><FONT SIZE="+1" COLOR="#FF0000">' .
     emt("Open Invoice #[_1] (Balance [_2])",$cust_bill->display_invnum,$cust_bill->owed) .
     '</FONT></B>';
@@ -14,7 +16,9 @@ if ( $cust_bill->owed > 0 ) {
     $under .= '<BR>'. emt('Payment promised on [_1]',
         time2str($opt{'date_format'}, $cust_bill->promised_date));
   }
-} #if $cust_bill->owed
+} else {
+  $invoice = emt("Invoice #[_1] (Balance [_2])",$cust_bill->display_invnum,$cust_bill->owed);
+}
 
 my $invnum = $cust_bill->invnum;