fix contact upgrade for multiple email addresses, #40971, from #25536
authorMark Wells <mark@freeside.biz>
Wed, 9 Mar 2016 23:49:53 +0000 (15:49 -0800)
committerMark Wells <mark@freeside.biz>
Wed, 9 Mar 2016 23:49:58 +0000 (15:49 -0800)
FS/FS/contact.pm
bin/contact-upgrade-fix-multiple [new file with mode: 0755]

index 188d287..592c719 100644 (file)
@@ -945,6 +945,7 @@ sub _upgrade_data { #class method
   # always migrate cust_main_invoice records over
   local $FS::cust_main::import = 1; # override require_phone and such
   my $search = FS::Cursor->new('cust_main_invoice', {});
+  my %custnum_dest;
   while (my $cust_main_invoice = $search->fetch) {
     my $custnum = $cust_main_invoice->custnum;
     my $dest = $cust_main_invoice->dest;
@@ -956,17 +957,22 @@ sub _upgrade_data { #class method
         if !$svc_acct;
       $dest = $svc_acct->email;
     }
+    push @{ $custnum_dest{$custnum} ||= [] }, $dest;
 
-    my $error = $cust_main->replace( invoicing_list => [ $dest ] );
-
+    my $error = $cust_main_invoice->delete;
     if ( $error ) {
-      die "custnum $custnum, invoice destination $dest, creating contact: $error\n";
+      die "custnum $custnum, cleaning up cust_main_invoice: $error\n";
     }
+  }
 
-    $error = $cust_main_invoice->delete;
-    die "custnum $custnum, cleaning up cust_main_invoice: $error\n" if $error;
-
-  } # while $search->fetch
+  foreach my $custnum (keys %custnum_dest) {
+    my $dests = $custnum_dest{$custnum};
+    my $cust_main = FS::cust_main->by_key($custnum);
+    my $error = $cust_main->replace( invoicing_list => $dests );
+    if ( $error ) {
+      die "custnum $custnum, creating contact: $error\n";
+    }
+  }
 
   unless ( FS::upgrade_journal->is_done('contact_invoice_dest') ) {
 
diff --git a/bin/contact-upgrade-fix-multiple b/bin/contact-upgrade-fix-multiple
new file mode 100755 (executable)
index 0000000..f5d68fc
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+
+use FS::UID qw(adminsuidsetup);
+use FS::cust_main_invoice;
+use FS::Record qw(qsearch qsearchs dbh);
+use FS::cust_main;
+use Date::Parse 'str2time';
+use strict;
+
+my $usage = "usage: contact-upgrade-fix-multiple <user> <upgrade date>\n";
+
+my $user = shift or die $usage;
+adminsuidsetup($user);
+local $FS::UID::AutoCommit = 0;
+
+my $date = shift;
+my $timestamp = str2time($date) or die $usage;
+# safety
+die "upgrade date is before the 4.0 release, must be incorrect.\n$usage"
+  if $timestamp < 1455609600;
+
+my $search = {
+  'table'     => 'h_cust_main_invoice',
+  'hashref'   => {
+    'history_date'    => { op => '>=', value => $timestamp },
+    'history_action'  => 'delete',
+    'dest'            => { op => '!=', value => 'POST' },
+  }
+};
+
+# find deleted cust_main_invoice records
+my %custnum_dest;
+foreach my $deleted (qsearch $search) {
+  my $custnum = $deleted->custnum;
+  push @{ $custnum_dest{$custnum} ||= [] }, $deleted->dest;
+}
+
+# find those customers
+while (my ($custnum, $dests) = each(%custnum_dest)) {
+  my $cust_main = FS::cust_main->by_key($custnum);
+  # filter out the email(s) that the customer already has
+  my @curr_dest = $cust_main->invoicing_list_email;
+  my @new_dest = @curr_dest;
+  print "cust#$custnum\n";
+  foreach my $email ( @$dests ) {
+    print "      $email: ";
+    if ( grep { $_ eq $email } @curr_dest ) {
+      print "skipped.\n";
+      next;
+    }
+    print "appending.\n";
+    push @new_dest, $email;
+  }
+  my $error = $cust_main->replace( invoicing_list => \@new_dest );
+  die $error if $error;
+}
+
+dbh->commit;
+print "Done.\n";
+