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
Vishal SawVishal Saw 

Write a trigger that calculates and updates a custom "Rating" field on a Contact based on the average ratings of all related Cases.

help to create this apex class
Best Answer chosen by Vishal Saw
SubratSubrat (Salesforce Developers) 
Hello vishal ,

Please try with the below code and let me know further :

ContactRatingTrigger.trigger:
trigger ContactRatingTrigger on Case (after insert, after update, after delete, after undelete) {
    if (Trigger.isAfter) {
        if (Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete) {
            ContactRatingHandler.updateContactRatings(Trigger.newMap.keySet());
        } else if (Trigger.isDelete) {
            ContactRatingHandler.updateContactRatings(Trigger.oldMap.keySet());
        }
    }
}
ContactRatingHandler.cls (Trigger Handler):
public class ContactRatingHandler {
    public static void updateContactRatings(Set<Id> caseIds) {
        List<Contact> contactsToUpdate = new List<Contact>();
        
        // Query related Cases and calculate average rating per Contact
        Map<Id, Decimal> contactAverageRatings = new Map<Id, Decimal>();
        for (AggregateResult result : [
            SELECT ContactId, AVG(Rating) avgRating
            FROM Case
            WHERE Id IN :caseIds
            GROUP BY ContactId
        ]) {
            Id contactId = (Id)result.get('ContactId');
            Decimal averageRating = (Decimal)result.get('avgRating');
            contactAverageRatings.put(contactId, averageRating);
        }
        
        // Update Contact records with the calculated average ratings
        for (Contact contact : [
            SELECT Id, Rating__c
            FROM Contact
            WHERE Id IN :contactAverageRatings.keySet()
        ]) {
            Decimal averageRating = contactAverageRatings.get(contact.Id);
            contact.Rating__c = averageRating;
            contactsToUpdate.add(contact);
        }
        
        if (!contactsToUpdate.isEmpty()) {
            update contactsToUpdate;
        }
    }
}

If this helps , please mark this as best answer.
Thank you.

All Answers

SubratSubrat (Salesforce Developers) 
Hello vishal ,

Please try with the below code and let me know further :

ContactRatingTrigger.trigger:
trigger ContactRatingTrigger on Case (after insert, after update, after delete, after undelete) {
    if (Trigger.isAfter) {
        if (Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete) {
            ContactRatingHandler.updateContactRatings(Trigger.newMap.keySet());
        } else if (Trigger.isDelete) {
            ContactRatingHandler.updateContactRatings(Trigger.oldMap.keySet());
        }
    }
}
ContactRatingHandler.cls (Trigger Handler):
public class ContactRatingHandler {
    public static void updateContactRatings(Set<Id> caseIds) {
        List<Contact> contactsToUpdate = new List<Contact>();
        
        // Query related Cases and calculate average rating per Contact
        Map<Id, Decimal> contactAverageRatings = new Map<Id, Decimal>();
        for (AggregateResult result : [
            SELECT ContactId, AVG(Rating) avgRating
            FROM Case
            WHERE Id IN :caseIds
            GROUP BY ContactId
        ]) {
            Id contactId = (Id)result.get('ContactId');
            Decimal averageRating = (Decimal)result.get('avgRating');
            contactAverageRatings.put(contactId, averageRating);
        }
        
        // Update Contact records with the calculated average ratings
        for (Contact contact : [
            SELECT Id, Rating__c
            FROM Contact
            WHERE Id IN :contactAverageRatings.keySet()
        ]) {
            Decimal averageRating = contactAverageRatings.get(contact.Id);
            contact.Rating__c = averageRating;
            contactsToUpdate.add(contact);
        }
        
        if (!contactsToUpdate.isEmpty()) {
            update contactsToUpdate;
        }
    }
}

If this helps , please mark this as best answer.
Thank you.
This was selected as the best answer
Vishal SawVishal Saw
Where did you created the both custom field on which data type
Arun Kumar 1141Arun Kumar 1141
Hi @Vishal,

I think you're asking about Rating__c, so this field might be created for storing the average of all the ratings.

Hence it has to be a NUMBER field, with 2 decimal places maybe.

Hope this helps.

Thank you.