0

So I'm receiving some Accounts from an external source. They could be exactly the ones I already have on the org but this external ones also have some custom Ids that I need to assign to the old ones.

I'm trying to achive this with an After Insert trigger:
-> get the Accounts that have the same Email as the new ones
-> get the data from the new ones and assign to the old ones
-> delete the new ones and update the old ones.

Trigger:

trigger AccountEmail on Account (after insert) {
//List<Account> Emails = [Select PersonEmail from Account];

List<Account> ToUpdate = new List<Account>();
List<Id> ToDelete = new List<Id>();
Map<String,Account> newAccs = new Map<String,Account>();
if(Trigger.isAfter) {
    for(Account a : Trigger.New) {
        if(a.some_Id__c != null && a.some_Id__c > 0) {
            newAccs.put(a.PersonEmail,a);
        }
    }


    for(Account oldAcc : [Select Id,PersonEmail,some_Id__c from Account where PersonEmail IN: newAccs.keySet()]) {
        if(oldAcc.some_Id__c == null) {
            Account d = newAccs.get(oldAcc.PersonEmail);
            oldAcc.some_Id__c = d.some_Id__c ;
            ToUpdate.add(oldAcc);
            ToDelete.add(d.id);
        }
    }
}

delete [select Id from Account where Id IN: ToDelete];
update ToUpdate; }  

And my test class:

 @isTest
public class AccountEmailDupeTest {
    @IsTest//(SeeAllData=true)
    static void testAccDupePreventer() {

      Account a1 = new Account(LastName='Test1', 
                            PersonEmail='test1@duptest.com');
      Account a2 = new Account(LastName='Test2', 
                            PersonEmail='test4@duptest.com');
      Account a3 = new Account(LastName='Test3', 
                            PersonEmail='test5@duptest.com');
      Account[] accs = new Account[] {a1, a2, a3};
      insert accs;

      a2.PersonEmail = 'test2@duptest.com';
      a3.PersonEmail = 'test3@duptest.com';
      update accs;  

      Account dup1 = new Account(LastName='Test1Dup',
                                PersonEmail='test1@duptest.com',
                                some_Id__c = 123);
      try {
         insert dup1;
      } catch (DmlException e) {
         system.debug('***ex:' + e.getMessage());
      }
      List<Account> t = [Select LastName, PersonEmail, some_Id__c from Account where some_Id__c = 123];
      system.debug('***t:' + t);

      Account dup2 = dup1;
      dup2.some_Id__c = 333;
      try {
         insert dup2;
      } catch (DmlException e) {
         system.debug('***ex:' + e.getMessage());
      }
    }
}  

On insert dup1 all works good and the first select returns the expected result but on the second insert I get: Insert failed. First exception on row 0 with id 001b000002LPfNWAA1; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]

Any solutions to this? Much appreciated!

EDIT: I get this on production:
First error: Upsert failed. First exception on row 3; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, namespace.AccountEmail: execution of AfterInsert

caused by: System.DmlException: Update failed. First exception on row 1 with id 001U00000...

2

You can see your code once you inserted dup1

insert dup1; // now it has id

If you assign dup1 to dup2

Account dup2 = dup1;

Then dup2 having same id/record. so you can't perform insert on dup2

what you need to do you can clone dup1 or create new account instance

instead of Account dup2 = dup1; use like below

 Account dup2 = dup1.clone();

or

Account dup2 = new Account(name='test');
  • Yup, it worked perfectly fine. Though I've had problems with the trigger on a production org and received the same error (not the test class but the real thing). I'll put this in prod and see if it's a go, if it is, I'll mark you as best answer. Thanks! – stefan Dec 2 '15 at 17:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.