Posts
From: Shantinath Patil: Review Your Resource
/0 Comments/in Salesforce Feedback (Surveys), Scheduler /by AIn Spring 22, the Salesforce scheduler has given a new feature: enabling rendering HTML tags in Service Resource cards. This new feature has opened up many possibilities to show additional information about the resource.

This help guide lets you add fields to the Service Resource cards: https://help.salesforce.com/s/articleView?id=sf.ls_change_the_fields_that_appear_on_the_service_resource_cards.htm&type=5.
Peer reviews and ratings are common decision making guides for customers today to help them pick among
Imagine you were to add the capabilities of a feedback management software (eg: Salesforce Feedback management) to Salesforce Scheduler, you could ask your customers to provide ratings for their appointments and then use those ratings to guide future customers.
With Feedback Management you can not only use survey invitation rules to distribute surveys when an appointment is closed but also use the data mapper feature to easily map the rating from the survey to any object in Salesforce, in this case to the Service Appointment object.
Refer to this link for more details on the datamapper and survey invitation rules
Once you have captured the rating data for your resources, there are several possibilities
- Help the consumer decide between resources
- Help Territory Mgr evaluate resources & branch
- Give preferential treatment to premium customers by only showing them higher rated resources
- Use Salesforce Einstein’s Machine Learning capabilities to predict who would be the best resource for this prospect based on past ratings giving by similar prospects eg: Someone from the South might prefer a resource from the south, or someone from an age group would prefer certain Resources.
For this blog, we’re going to focus on the Salesforce Scheduler changes you need to make to get the above capabilities going.
let’s take an example of adding a rating to the service resource. Please follow the below steps to show the shining rating stars on the resource card:
1. Fields on Service Resource
To show the rating, we need to create a formula field on Service Resource to render rating stars in cards. We will add this field to the compact layout to show up in the out of the box component. However, to populate value in this field, we need two more fields on Service Resource: to capture the average rating for each of the appointments he served and the number of appointments.
Field Label | Field API Name | Data Type | Comments |
Rating | Rating__c | Number(1,0) | Number field to store rating between 1-5 |
Review Count | Review_Count__c | Number(18,0) | Number field to store number of reviews this service resource have received |
Star Rating | Star_Rating__c | Formula(Text) | Formula field which will show ratings based on above 2 fields |
The sample formula will turn out like this:
IMAGE(
IF(TEXT( CEILING(Rating__c) ) = '0', "/img/samples/stars_000.gif",
IF(TEXT( CEILING(Rating__c) ) = '1', "/img/samples/stars_100.gif",
IF(TEXT( CEILING(Rating__c) ) = '2', "/img/samples/stars_200.gif",
IF(TEXT( CEILING(Rating__c) ) = '3', "/img/samples/stars_300.gif",
IF(TEXT( CEILING(Rating__c) ) = '4', "/img/samples/stars_400.gif",
IF(TEXT( CEILING(Rating__c) ) = '5', "/img/samples/stars_500.gif",
"/img/samples/stars_000.gif"
)
)
)
)
)
),
'Rating Level'
) + ' ('+ TEXT( Review_Count__c ) + ' Reviews)'
2. Field on Service Appointment
We will have to create a field on Service Appointment to capture the sentiment of a customer based on how the appointment went. We can populate this value from a Survey, which will be sent out once an appointment is complete.
Field Label | Field API Name | Data Type | Comments |
Rating | Rating__c | Number(1,0) | Number field to store rating between 1-5 |
3. Propagate value from Service Appointment to Service Resource
Now that we have fields on Service Resource and Service Appointment, we will have to process the aggregate reviews. As shown in the below data model diagram, we can traverse through Assigned Resource and populate this value to Service Resource.

The review aggregator formula that we can use is:
((Current Average Rating * Total Reviews) + New Rating) / (Total Reviews+ 1)
Using this formula, we can write a trigger on Service Appointment. As soon as we get a rating from Service Appointment, we will aggregate the review and update its corresponding Service Resource. A sample trigger code is given below:
trigger UpdateSurveyRating on ServiceAppointment (after insert, after update) {
Set<Id> vSetServiceAppointment = new Set<Id>();
for(ServiceAppointment sapp : Trigger.new){
if(Trigger.isInsert && sapp.Rating__c != null){
vSetServiceAppointment.add(sapp.Id);
}else if(Trigger.isUpdate && Trigger.oldMap.get(sapp.Id).Rating__c != sapp.Rating__c){
vSetServiceAppointment.add(sapp.Id);
}
}
if(!vSetServiceAppointment.isEmpty()){
Map<Id, List<ServiceResource>> vMapServiceAppToResources = new Map<Id, List<ServiceResource>>();
List<AssignedResource> vListAssResource = [SELECT Id, ServiceResourceId, ServiceAppointmentId FROM AssignedResource WHERE ServiceAppointmentId IN: vSetServiceAppointment];
if(vListAssResource != NULL && !vListAssResource.isEmpty()){
Set<Id> vSetServiceResource = new Set<Id>();
for(AssignedResource vAssRes : vListAssResource){
vSetServiceResource.add(vAssRes.ServiceResourceId);
}
Map<Id, ServiceResource> vMapServiceResource = new Map<Id, ServiceResource>([SELECT Id, Rating__c, Review_Count__c FROM ServiceResource WHERE Id IN: vSetServiceResource]);
for(AssignedResource vAssRes : vListAssResource){
if(!vMapServiceAppToResources.keySet().isEmpty() && vMapServiceAppToResources.containsKey(vAssRes.ServiceAppointmentId)){
List<ServiceResource> vTempResources = vMapServiceAppToResources.get(vAssRes.ServiceAppointmentId);
vTempResources.add(vMapServiceResource.get(vAssRes.ServiceResourceId));
vMapServiceAppToResources.put(vAssRes.ServiceAppointmentId, vTempResources);
}else{
List<ServiceResource> vTempResources = new List<ServiceResource>();
vTempResources.add(vMapServiceResource.get(vAssRes.ServiceResourceId));
vMapServiceAppToResources.put(vAssRes.ServiceAppointmentId, vTempResources);
}
}
//((Current Average Rating * Total Reviews) + New Rating) / (Total Reviews+ 1)
Map<Id, ServiceResource> vMapServiceResourceToUpdate = new Map<Id, ServiceResource>();
for(ServiceAppointment sapp : Trigger.new){
if(vMapServiceAppToResources.containsKey(sapp.Id)){
for(ServiceResource vResource : vMapServiceAppToResources.get(sapp.Id)){
if(vMapServiceResourceToUpdate != NULL && vMapServiceResourceToUpdate.containsKey(vResource.Id)){
ServiceResource vTempResource = vMapServiceResourceToUpdate.get(vResource.Id);
vTempResource.Rating__c = (((vTempResource.Rating__c * vTempResource.Review_Count__c) + sapp.Rating__c) / vTempResource.Review_Count__c+1);
vTempResource.Review_Count__c++;
vMapServiceResourceToUpdate.put(vTempResource.Id, vTempResource);
}else{
Decimal rating = vResource.Rating__c != NULL ? vResource.Rating__c : 0;
Decimal reviews = vResource.Review_Count__c != NULL ? vResource.Review_Count__c : 0;
vResource.Rating__c = (((rating * reviews) + sapp.Rating__c) / (reviews+1));
vResource.Review_Count__c = ++reviews;
vMapServiceResourceToUpdate.put(vResource.Id, vResource);
}
}
}
}
UPDATE vMapServiceResourceToUpdate.values();
}
}
}
Note: This is just a concept illustrator built for a simple create Guest appointment use case using the out of the box flow template.
Possibilities
- Create a Next Best Action Employee App – Part 2June 30, 2020 - 3:20 pm
- Create A Next Best Action Employee App- Part 1June 30, 2020 - 3:19 pm
- Adding Lightning Web Components to Flow ScreensOctober 21, 2019 - 7:45 am
- The Top 10 Things You Want to Know About the New Flow B...February 11, 2019 - 5:36 pm
- Salesforce Einstein Next Best Action “Getting Started”...February 3, 2019 - 2:34 am
- Send Rich Email (Send HTML Email Action)September 12, 2019 - 4:15 pm
- Quick Choice – Improved Picklists and Radio Buttons...December 25, 2019 - 12:57 pm
- Collection Processors for Flow (Sort, Filter, Find, Join,...December 17, 2019 - 12:18 am
- Send Richer Email with the ‘Send Better Email’...August 11, 2020 - 10:23 am
- Create a Next Best Action Employee App – Part 2June 30, 2020 - 3:20 pm
- Create A Next Best Action Employee App- Part 1June 30, 2020 - 3:19 pm
- Adding Lightning Web Components to Flow ScreensOctober 21, 2019 - 7:45 am
- The Top 10 Things You Want to Know About the New Flow B...February 11, 2019 - 5:36 pm
- Salesforce Einstein Next Best Action “Getting Started”...February 3, 2019 - 2:34 am
- Four New Collection Processor Actions added as Reactive...October 23, 2023 - 6:34 am
- Dreamforce 2023 Omni-Channel presentationSeptember 12, 2023 - 12:09 pm
- Best practices for Status-Based Capacity with Omni-Chan...September 12, 2023 - 11:53 am
- Blending Phone and Chat channels togetherSeptember 12, 2023 - 10:52 am
- […] end of a screen flow. However, it is possible...November 23, 2023 - 11:21 pm by Automatically Navigate to Quote Line Editor After Creating Quote in CPQ - Salesforce Time
- […] use case, less practical but lots of fun, is a...November 6, 2023 - 12:10 am by Top Salesforce Flow Features in Summer ’23 Release | RafterOne
- […] a Flow Migration tool of any kind. One that’s...November 1, 2023 - 8:18 am by Migrate Salesforce Workflow Rules & Process Builder to Flow (+ Video) | Salesforce Ben
- […] Sounding too good to be true? For most Omni-Channel...October 26, 2023 - 11:38 am by What is Enhanced Omni-Channel? – UnofficialSF