-3

I have below code Please tell me how can i bulkify it:- Its checking for duplicate email and if found then a task is created. But because of this class many test classes are failing with error as too many soql queries. Please help here.

public class FE_TaskForEmailDuplicates extends FE_TriggerService.Handler {
    private static FE_TaskForEmailDuplicates instance;

    public static FE_TaskForEmailDuplicates instance() {
        if (instance == null) {
            instance = new FE_TaskForEmailDuplicates();
        }
        return instance;
    }

    public override void afterInsert(SObject so) {
        Account acc = (Account) so;
        checkForDuplicateEmail(acc, null);
    }

    public override void beforeUpdate(SObject oldSo, SObject so) {
        Account oldAcc = (Account) oldSo;
        Account newAcc = (Account) so;
        checkForDuplicateEmail(newAcc, oldAcc);
    }

    public void checkForDuplicateEmail(Account acc, Account oldAcc) {
        List<Task> duplicateEmailTasks = new List<Task>();

        // Query for other accounts  with the same email address
        List<Account> duplicateAccounts = [
            SELECT Id, oce__email__c
            FROM Account
            WHERE oce__email__c = :acc.oce__email__c
            AND Id != :acc.Id
        ];

        if (acc.oce__email__c != null && (oldAcc == null || acc.oce__email__c != oldAcc.oce__email__c)) {
            // Check if the email field is filled for the first time or updated to a duplicate value
            if (!duplicateAccounts.isEmpty()) {
                // Create a task for the sales rep
                Task newTask = new Task();
                newTask.WhatId = acc.Id;
                newTask.OwnerId = acc.OwnerId; // Set the sales rep as the owner
                newTask.Subject = 'Duplicate email found';
                System.debug(acc.Name);
                newTask.Description = 'You registered a new email address for this HCP:' +
                                       '\nName: ' + acc.Last_name_First_name__c +
                                       '\nLink to the doctor page: ' + getOrgUrl() + '/' + acc.Id +
                                       '\nUnique Id: ' + acc.OCE__UniqueIntegrationID__c +
                                       '\nEmail: ' + acc.oce__email__c +
                                       '\n\nUnfortunately, there seem to be duplicate records (other HCPs with the same email address):' +
                                       '\n' + getDuplicateRecordsLinks(duplicateAccounts) +
                                       '\n\nPlease check and correct the information as email addresses should be unique.' +
                                       '\nOnce done, please contact the support team to make sure that the information is correctly updated and synced to OneTrust (our consent management platform).';
                newTask.Status = 'Not Started';
                newTask.Type = 'Duplicate Email';

                duplicateEmailTasks.add(newTask);
            }
        }

        // Insert the tasks for duplicate email
       
            if (!duplicateEmailTasks.isEmpty())
            insert duplicateEmailTasks;
    }

    // Method to get the duplicate records links
    private static String getDuplicateRecordsLinks(List<Account> duplicateAccounts) {
        String links = '';
        for (Account duplicateAccount : duplicateAccounts) {
            if (duplicateAccount.Id != null) {
                links += '\nLink to duplicate account: ' + getOrgUrl() + '/' + duplicateAccount.Id;
            }
        }
        return links;
    }
    private static String getOrgUrl() {
    return URL.getSalesforceBaseUrl().toExternalForm();
}
}
6
  • 1
    Hi, what have you tried already? This seems like a classic case of an unbulkified trigger so there should be several tutorials online that explain how to bulkify it.
    – fred
    Jul 13, 2023 at 9:58
  • // Check if the email field is filled for the first time or updated to a duplicate value if (acc.oce__email__c != null && (oldAcc == null || acc.oce__email__c != oldAcc.oce__email__c)) { Set<String> emailAddresses = new Set<String>(); emailAddresses.add(acc.oce__email__c); if (oldAcc != null && oldAcc.oce__email__c != null) { emailAddresses.add(oldAcc.oce__email__c); }
    – Saachi
    Jul 13, 2023 at 12:00
  • // Query for other accounts with the same email address List<Account> duplicateAccounts = [ SELECT Id, oce__email__c FROM Account WHERE oce__email__c IN :emailAddresses AND Id != :acc.Id ];
    – Saachi
    Jul 13, 2023 at 12:01
  • The above 2 comments are part of code. I have tried to get the email address and then instead of passing one by one in query . Just passing set of string emailAddresses
    – Saachi
    Jul 13, 2023 at 12:02
  • 1
    You've... just repeated the code that you already have? You need to show us an actual, honest attempt to bulkify this. Do some searching for "bulkification" and read through some of those resources. Then come back to this question and edit it to show us what you've learned. Make an attempt, and then explain "this is where I'm stuck".
    – Derek F
    Jul 13, 2023 at 12:04

1 Answer 1

0

This looks like some trigger handler. But afterInsert(SObject so) only processes one record a time and this method executes a soql query. So that means if over 100 records get changed and fire the trigger, you will run over 100 soql queries and get the too many soql query error. So check the FE_TriggerService.Handler code and make sure instead of doing afterInsert for a single record, do afterInsert for List < Account >.

1
  • or -- the code that is inserting Accounts is doing it 1x1 rather than with a bulkified insert accounts
    – cropredy
    Jul 14, 2023 at 23:12

Not the answer you're looking for? Browse other questions tagged .