0

I have a trigger that runs on AccountDomains to update a Contact's Account when a new Domain is added to the Account and it's hitting the Apex CPU time limit. Right now it pulls all the contacts with emails in that domain and tries to update them. How do I pull only the contacts where the account is different than the account of the domain being added. Here's my code

trigger AccountDomain on Account_Domain__c (before insert, before update, after insert) {
if(Trigger.isBefore){
    if ((Trigger.isInsert || Trigger.isUpdate) && Trigger.isBefore) {
        for (Account_Domain__c accountDomain : Trigger.new) {
            if (String.isNotBlank(accountDomain.Domain__c)) {
                accountDomain.Domain__c = accountDomain.Domain__c.toLowerCase();
            }
        }
    }
}else if(Trigger.isAFter){
    if(Trigger.isInsert){
        UAccountDomain.handleAfterInsert(Trigger.new);
    }
 }
}
public with sharing class UAccountDomain {
public static Boolean isFirstTime = true;

public static void handleAfterInsert(List<Account_Domain__c> accountDomains){
    Set<String> domains = new Set<String>();
    for(Account_Domain__c ad : accountDomains){
        domains.add(ad.Domain__c);
    }
    Map<String,Contact_Account_Matching_Account_Types__c> typeMap = Contact_Account_Matching_Account_Types__c.getAll();

    List<Contact> contactsToProcess = [SELECT Id,AccountId,Email FROM Contact 
                                        WHERE Account.RecordType.Name IN :typeMap.keyset() 
                                        AND Domain__c IN :domains
                                      ];

    system.debug('###contactsToProcess: ' + contactsToprocess);
    if(!contactsToProcess.isEmpty()){
        UContact.assignAccounts(contactsToProcess);
        update contactsToProcess;
    }
}
}

How do I limit the contactsToProcess to only the ones where the AccountId doesn't match the AccountDomains AccountId and would that solve my CPU time limit issue or am I missing something else?

0

So the domain__c field on contact determines what the account should be.

If the domain__c is the controlling field add that to a map as a key and have the accountId (from accountDomain) as a value -->

public static void handleAfterInsert(List<Account_Domain__c> accountDomains){
    Map<String, Id> domainAccountMap = new Map<String, Id>();
    for(Account_Domain__c ad : accountDomains){
        domainAccountMap.put(ad.domain__c, ad.account__c);
    }

(Above, I'm assuming that the account Id on the accountDomain object is account__C - replace with whatever it actually is.)

Then perform your query but check the contacts account does not equal the relevant accountdomains account before inserting into list for update:

    List<Contact> allContacts = [SELECT Id,AccountId,Email FROM Contact 
                                        WHERE Account.RecordType.Name IN :typeMap.keyset() 
                                        AND Domain__c IN :domainAccountMap.keyset()
                                      ];
List<Contact> contactsToProcess = new List<contact>();
for(contact c :allContacts){
     if(c.AccountId != domainAccountMap.get(c.Domain__c){
        contactsToProcess.add(c);
     }
}
// NOW PROCESS --->

So, this takes the accountId associated with a certain domain in the accountDomain object, then does your contact query, then checks to see whether contacts with a certain domain in their domain__c field have the corresponding accountId already, and if not adds them to the update list.

| improve this answer | |

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.