+ Start a Discussion
Kirtan Patel 9Kirtan Patel 9 

When a contact is created/updated, get total score of all the UNIQUE roles that exist on all the contacts of the account.

Contact has a multi select custom field called Role__c which can have values (Surgeon;Nurse;First Assist;Admin;CSR). Account has a custom field called Total_Score__c which is a number field. Mapping table Role_Score__c looks like this Role__c Score__c
Surgeon 10
Nurse 5
First Assist 10
Admin 0
CSR 20
When a contact is created/updated, get total score of all the UNIQUE roles that exist on all the contacts of the account.
Ex: Account 1
Contact 1 with roles Surgeon;Admin
Contact 2 with roles CSR:Admin
On Account 1 we should store the value as (10 + 0 + 20 = 30) because we only have 3 unique roles.
Alaric WimerAlaric Wimer

Hi Kirtan, here's a working trigger. This one should work for you just fine. Let me know if it helps you or not. All the best

 

trigger accountTotalScore on Contact (before insert, before update) {

    Set<Id> accIds = new Set<Id>();

    // add accountIds to a set
    for (Contact myCon : Trigger.new) {
        if (myCon.AccountId != null) {
            accIds.add(myCon.AccountId);
        }
    }

    // get all accounts related to Contacts entering the trigger
    if (!accIds.isEmpty()) {
        List<Account> myAccounts = [
            SELECT Id, Total_Score__c, (SELECT Id, Role__c FROM Contacts WHERE Role__c != null)
              FROM Account
             WHERE Id IN :accIds
        ];

        if (!myAccounts.isEmpty()) { 
            
            List<Account> accToUpdateList = new List<Account>();
            // Loop through each Account
            for (Account myAccount : myAccounts) {
                // initialize variables
                Boolean surgeon    = false;
                Boolean fireAssist = false;
                Boolean csr        = false;
                Boolean admin      = false;
                Boolean nurse      = false;
                Integer score      = 0;

                if (!myAccount.contacts.isEmpty()) {
                    // Search for the Role values in each Contact
                    for (Contact accContact : myAccount.contacts) {
                        if (accContact.Role__c.containsIgnoreCase('Surgeon')) {
                            surgeon = true;
                        }
                        if (accContact.Role__c.containsIgnoreCase('Fire Assist')) {
                            fireAssist = true;
                        }
                        if (accContact.Role__c.containsIgnoreCase('CSR')) {
                            csr = true;
                        }
                        if (accContact.Role__c.containsIgnoreCase('Nurse')) {
                            nurse = true;
                        }
                        if (accContact.Role__c.containsIgnoreCase('Admin')) {
                            admin = true;
                        }
                    }

                    // set the score
                    if (surgeon == true) {
                        score += 10;
                    } 
                    if (fireAssist == true) {
                        score += 10;
                    }
                    if (nurse == true) {
                        score += 5;
                    }
                    if (csr == true) {
                        score += 20;
                    } 
                    if (admin == true) {
                        score += 0;
                    }
                }
                myAccount.Total_Score__c = score;
                accToUpdateList.add(myAccount);
            }
            if (!accToUpdateList.isEmpty()) {
                update accToUpdateList;
            }
        }
    }
}
Alaric WimerAlaric Wimer

Hi Kirtan, here's a better version of the trigger code. What I've done differently, is establish variables (lines 5 - 10 in the code below) that set variables to store the points assigned to each Role. The reason I've done this is because if the points will change in the future, you can easily go back into the code and adjust the points right there in those variables at the beginning, instead of trying to find the score assignments throughout the code.

 

I've also added the the scoring logic within the Account's Contacts loop (lines 40 - 61 in the code below).

 

As a final result you have a trigger that looks like this:

trigger accountTotalScore on Contact (before insert, before update) {

    Set<Id> accIds = new Set<Id>();
    List<Account> accToUpdateList = new List<Account>();
    // set the points for each role
    Integer surgeonScore    = 10;
    Integer fireAssistScore = 10;
    Integer csrScore        = 20;
    Integer nurseScore      = 5;
    Integer adminScore      = 0;

    // add accountIds to a set
    for (Contact myCon : Trigger.new) {
        if (myCon.AccountId != null) {
            accIds.add(myCon.AccountId);
        }
    }

    // get all accounts related to Contacts entering the trigger
    if (!accIds.isEmpty()) {
        List<Account> myAccounts = [
            SELECT Id, Total_Score__c, (SELECT Id, Role__c FROM Contacts WHERE Role__c != null)
              FROM Account
             WHERE Id IN :accIds
        ];

        if (!myAccounts.isEmpty()) { 
            // Loop through each Account
            for (Account myAccount : myAccounts) {
                // initialize variables
                Boolean surgeon    = false;
                Boolean fireAssist = false;
                Boolean csr        = false;
                Boolean admin      = false;
                Boolean nurse      = false;
                Integer score      = 0;

                if (!myAccount.contacts.isEmpty()) {
                    // Search for the Role values in each Contact
                    for (Contact accContact : myAccount.contacts) {
                        if (accContact.Role__c.containsIgnoreCase('Surgeon') && !surgeon) {
                            surgeon = true;
                            score  += surgeonScore;
                        }
                        if (accContact.Role__c.containsIgnoreCase('Fire Assist') && !fireAssist) {
                            fireAssist = true;
                            score += fireAssistScore;
                        }
                        if (accContact.Role__c.containsIgnoreCase('CSR') && !csr) {
                            csr = true;
                            score += csrScore;
                        }
                        if (accContact.Role__c.containsIgnoreCase('Nurse') && !nurse) {
                            nurse = true;
                            score += nurseScore;
                        }
                        if (accContact.Role__c.containsIgnoreCase('Admin') && !admin) {
                            admin = true;
                            score += adminScore;
                        }
                    }
                }
                myAccount.Total_Score__c = score;
                accToUpdateList.add(myAccount);
            }
            if (!accToUpdateList.isEmpty()) {
                update accToUpdateList;
            }
        }
    }
}
 

 

Alaric WimerAlaric Wimer
Hi Kirtan, were you able to try out the trigger? Does everything work for you?
Alaric WimerAlaric Wimer
Hi Kirtan, just following up with you. Has the trigger worked for you? If so, please mark as best answer to close out the question. Feel free to let me know if you have any questions. Thank you