function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Justin GeorgeJustin George 

Bulkify Trigger to Update Owner

I have written a trigger that updates the owner field to a queue on a custom object. The queue is selected based on fields on a related object. The logic is as follows:

- The trigger must traverse through a lookup and return the value of a field on the lookup object: 
Claim__c.Location_Lookup__r.Node__c = '1234'
- Trigger must also reference a field on the object:
Claim__c.Coverage__c = 'AB'
- Trigger should concatenate '1234AB' and return a queue with the same name (1234AB).
- The Claim__c owner field should then be updated to '1234AB'

Here is the working trigger:
trigger ReassignOwnerClaim on Claim__c (before insert, before update) {

    for(claim__c newClaim : Trigger.new){

    Hierarchy__c location = [Select Node__c from Hierarchy__c where ID =: newClaim.Location_Lookup__c LIMIT 1];
    Group[] queue = [Select Id, Name from Group where Name =: location.Node__c + newClaim.Coverage__c LIMIT 1];
   
        if (queue.size() > 0) {
            newClaim.OwnerId = queue[0].Id;
        }

    }
}

The issue is the trigger is not bulkified. I have attempted to bulkify the trigger, but I got lost is the logic and I could not find a similar piece of sample code to reference. Can someone point me in the right direction or give me some guidance.

Thanks
 
Best Answer chosen by Justin George
pconpcon
You'll want to split this out into a fetch for all your locations, then a fetch for all of your groups.  The code below should be what you are looking for.
 
trigger ReassignOwnerClaim on Claim__c (before insert, before update) {
    Set<String> nameSet = new Set<String>();
    Set<Id> locationIds = new Set<Id>();

    for (Claim__c newClaim : Trigger.new) {
        locationIds.add(newClaim.Location_Lookup__c);
    }

    if (!locationIds.isEmpty()) {
        Map<Id, Hierarchy__c> locationMap = new Map<Id, Hierarchy__c>([
            select Node__c
            from Hierarchy__c
            where Id in :locationIds
        ]);

        for (Claim__c newClaim : Trigger.new) {
            if (!locationMap.containsKey(newClaim.Location_Lookup__c)) {
                continue;
            }

            Hierarchy__c location = locationMap.get(newClaim.Location_Lookup__c);
            String name = location.Node__c + newClaim.Coverage__c;
            nameSet.add(name);
        }

        if (!nameSet.isEmpty()) {
            Map<String, Group> groupMap = new Map<String, Group>();

            for (Group queue : [
                select Name
                from Group
                where Name in :nameSet
            ]) {
                groupMap.put(queue.Name, queue);
            }

            for (Claim__c newClaim : Trigger.new) {
                String name = location.Node__c + newClaim.Coverage__c;

                if (!groupMap.containsKey(name)) {
                    continue;
                }

                newClaim.OwnerId = groupMap.get(name).Id;
            }
        }
}

NOTE: This code has not been tested and may contain typographical or logical errors

All Answers

pconpcon
You'll want to split this out into a fetch for all your locations, then a fetch for all of your groups.  The code below should be what you are looking for.
 
trigger ReassignOwnerClaim on Claim__c (before insert, before update) {
    Set<String> nameSet = new Set<String>();
    Set<Id> locationIds = new Set<Id>();

    for (Claim__c newClaim : Trigger.new) {
        locationIds.add(newClaim.Location_Lookup__c);
    }

    if (!locationIds.isEmpty()) {
        Map<Id, Hierarchy__c> locationMap = new Map<Id, Hierarchy__c>([
            select Node__c
            from Hierarchy__c
            where Id in :locationIds
        ]);

        for (Claim__c newClaim : Trigger.new) {
            if (!locationMap.containsKey(newClaim.Location_Lookup__c)) {
                continue;
            }

            Hierarchy__c location = locationMap.get(newClaim.Location_Lookup__c);
            String name = location.Node__c + newClaim.Coverage__c;
            nameSet.add(name);
        }

        if (!nameSet.isEmpty()) {
            Map<String, Group> groupMap = new Map<String, Group>();

            for (Group queue : [
                select Name
                from Group
                where Name in :nameSet
            ]) {
                groupMap.put(queue.Name, queue);
            }

            for (Claim__c newClaim : Trigger.new) {
                String name = location.Node__c + newClaim.Coverage__c;

                if (!groupMap.containsKey(name)) {
                    continue;
                }

                newClaim.OwnerId = groupMap.get(name).Id;
            }
        }
}

NOTE: This code has not been tested and may contain typographical or logical errors
This was selected as the best answer
Justin GeorgeJustin George
Thank you pcon for the quick and working solution. I had to make one small tweak to line 38 in order to get the code to copile:
 
trigger ReassignOwnerClaim on Claim__c (before insert, before update) {
    Set<String> nameSet = new Set<String>();
    Set<Id> locationIds = new Set<Id>();

    for (Claim__c newClaim : Trigger.new) {
        locationIds.add(newClaim.Location_Lookup__c);
    }

    if (!locationIds.isEmpty()) {
        Map<Id, Hierarchy__c> locationMap = new Map<Id, Hierarchy__c>([
            select Node__c
            from Hierarchy__c
            where Id in :locationIds
        ]);

        for (Claim__c newClaim : Trigger.new) {
            if (!locationMap.containsKey(newClaim.Location_Lookup__c)) {
                continue;
            }

            Hierarchy__c location = locationMap.get(newClaim.Location_Lookup__c);
            String name = location.Node__c + newClaim.Coverage__c;
            nameSet.add(name);
        }

        if (!nameSet.isEmpty()) {
            Map<String, Group> groupMap = new Map<String, Group>();

            for (Group queue : [
                select Name
                from Group
                where Name in :nameSet
            ]) {
                groupMap.put(queue.Name, queue);
            }

            for (Claim__c newClaim : Trigger.new) {
                Hierarchy__c location = locationMap.get(newClaim.Location_Lookup__c);
                String name = location.Node__c + newClaim.Coverage__c;

                if (!groupMap.containsKey(name)) {
                    continue;
                }

                newClaim.OwnerId = groupMap.get(name).Id;
            }
        }
    }
}

 
pconpcon
Yep, forgot to pull in that location, good catch!