question

jeff-stevens avatar image
jeff-stevens asked ·

Salesforce - log a call - want to add disposition

On the salesforce log a call window (the window that is installed as part of the RingCentral app that is installed in a Salesforce org) - - I need to add an additional field that is on the ActivityHistory record.  (That's the record that the window writes to).

My Question is - is there a way to modify this page?  Is there a way to write my own custom page?  Are there any experts that have been into that portion of integration?

Thanks
topic-default
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jitender-kumar avatar image
jitender-kumar answered ·
Hello Jeff, 

You can select a call disposition by clicking on check box icon right by the call Log text field.  By default is say "Inbound call from ..."  . You can overwrite to enter your own text and use a value from the drop down.

These values are populated from Subject field in Task object in Salesforce, If you need to add or change call disposition, you can go to Task object in your Salesforce and edit the Subject field, Subject field a picker then you can edit the values for 

Here is the reference for Task Object 

https://help.salesforce.com/HTViewHelpDoc?id=task_fields.htm&language=en_US 

Please let us know if that does not help 

Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jeff-stevens avatar image
jeff-stevens answered ·
Yep - that's very helpful.  The SF field is actually called Subject - on the Task.  Those picklist values can be modified and added to.  I can write trigger's from there to populate my custom fields.

Thanks!

Just for discussion purposes though - IF we wanted to modify that page - is that possible?  Would (Can?) we write a new custom VF page to go in that spot?  I'd like to continue this discussion a bit on this subject. 

Thanks
Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered ·
Following this topic! Jeff can you share some instances where you wrote triggers? The reason being is that I do not want the subject to have to be the Call disposition. I think that they need to add the call disposition field onto the ring central/salesforce integration, it's already bad enough that I have to use subject instead of task type to record the call, becasue I like to track if it an initial call or follow up call, 2nd follow up call, but that has nothing to do with how the call went, good or bad or if I have to call back or send something.  The app is there, but not good enough I am thinking that Salesfoce has a call center, I am wondering if I can create a call center with more options.  Or like you said..is there a way to create a new VF page, (which- I have NO clue how to do)  
6 comments Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

We wanted to know the outcome of the call, and what of our services were presented on each call.  We also wanted to be able to pull up an Account record and see when the last time we talked with the Account, and if any services were presented.

So we broke this down into two steps.  First, at the call - we needed to keep what the outcome of the call was, and what of our services was presented.

Since each call generates a task/activity - I added two custom fields to our activity object.  "Call Disposition", and "Services Presented", both were pick-list fields.  We then wrote a trigger on the Task object that looks at the services presented, and copies those to a related object on the Account. 
1 Like 1 · ·
Great information Jeff, thanks for sharing!
0 Likes 0 · ·
Can you share how to copy to related objects? Do you ave a formula that you would be will to share??? :) thanks so much!

0 Likes 0 · ·
Sure,

If you haven't written any apex before - there would a bit of a learning curve.  Even if you've written in other languages - Java, or .net - you need to be aware of the limits that Salesforce has - if effects how you write code.

But here is the trigger on the Task, and the helper class/method that writes the related services for the account.....

trigger Task on Task (before insert, before update, after insert, after update) {

HandlerTask taskHandler = new HandlerTask();


/*

BEFORE INSERT, BEFORE UPDATE

*/

if(trigger.isBefore) { 

taskHandler.maintainPresentedIds(trigger.new); 

}


/*

AFTER INSERT, AFTER UPDATE

*/

if(trigger.isAfter) {

// Check for any presented services....

boolean servicesPresented = false;

for(Task t :trigger.new) {

if(t.Services_Presented__c != null && t.Services_Presented__c != 'null') {

servicesPresented = true;

}

}

if(servicesPresented) {

if(util_utilities.alreadyExecuted != true) {

util_utilities.alreadyExecuted = true;

taskHandler.addUpdateAccountServices(trigger.newmap);

}

}

 

// Update case & add new Tasks if needed....

taskHandler.caseManagement(trigger.new,trigger.oldmap);

 

}








HandlerTask.cls.....

public with sharing class HandlerTask {

/*

MAINTAIN SERVICES PRESENTED IDs

*/

public void maintainPresentedIds(list<Task> triggeredTasks) {


// Build map<ServiceName,ServiceId> mServiceNameId - from Service__c master

map<string,id> mServiceNameId = new map<string,id>();

map<id,string> mServiceIdName = new map<id,string>();

for(Service__c s :[SELECT id,name FROM Service__c]) {

mServiceNameId.put(s.name,s.id);

mServiceIdName.put(s.id,s.name);

}

for(Task t :triggeredTasks) {

list<string> presentedServiceNames = new list<string>();

presentedServiceNames = stringNullCheck(t.Services_Presented__c).split(';');

string presentedServiceIds = '';

for(string presentedServiceName :presentedServiceNames) {

if(mServiceNameId.containsKey(presentedServiceName))

if(presentedServiceIds.length()>0) {

presentedServiceIds = presentedServiceIds + ';';

}

presentedServiceIds = presentedServiceIds + mServiceNameId.get(presentedServiceName);

}

t.ServicePresentedIds__c = presentedServiceIds;

}

}

/*

ADD UPDATE ACCOUNT-SERVICES AS NEEDED 

*/

public void AddUpdateAccountServices(map<id,Task> mTriggeredTasks) {

system.debug('');

system.debug('HandlerTask.AddUpdateAccountServices....');

system.debug('');

// Get all services from Service Master ...

// Build map<ServiceName,ServiceId> mServiceNameId - from Service__c master

map<string,id> mServiceNameId = new map<string,id>();

map<id,string> mServiceIdName = new map<id,string>();

for(Service__c service :[SELECT id,name FROM Service__c]) {

mServiceNameId.put(service.name,service.id);

mServiceIdName.put(service.id,service.name);

}

// Get all services presented on this call

// Build Map<TaskId,list<PresentedServiceIds>> mTaskPresentedServicesIds

map<id,list<id>> mTaskPresentedServiceIds = new map<id,list<id>>();

set<id> accountIds = new set<id>();

set<id> presentedServiceIds = new set<id>();

for(Task t :mTriggeredTasks.values()) {

system.debug('Task='+t);

if(t.Account__c != null) {

accountIds.add(t.Account__c);

if(t.ServicePresentedIds__c != null && t.ServicePresentedIds__c != 'null') { 

list<string> iterPresentedServiceIds = t.ServicePresentedIds__c.split(';');

system.debug('t.ServicePresentedIds__c='+t.ServicePresentedIds__c);

system.debug('iterPresentedServiceIds='+iterPresentedServiceIds);

for(string s :iterPresentedServiceIds) {

system.debug('s='+s);

presentedServiceIds.add(s);

}

}

}

}

system.debug('presentedServiceIds='+presentedServiceIds);

// Get existing AccountService records

// Build map of Account to list<AccountService>

map<id,list<AccountService__c>> mAccountAccountServices = new map<id,list<AccountService__c>>();

map<string,AccountService__c> mAccountServiceIdsToAccountService = new map<string,AccountService__c>();

list<AccountService__c> accountServices = [SELECT id,name,Account__c,Last_Call_Disposition__c,

Last_Call_Services_Presented__c,Last_Contact__c,

Service__c,Status__c

FROM AccountService__c 

WHERE Account__c IN :accountIds

AND Service__c IN :presentedServiceIds 

];

for(AccountService__c accountService :accountServices) {

system.debug('accountService='+accountService);

string combinedIds = string.valueOf(accountService.Account__c) + string.valueOf(accountService.Service__c);

mAccountServiceIdsToAccountService.put(combinedIds,AccountService);

list<AccountService__c> iterAS = new list<AccountService__c>();

if(mAccountAccountServices.containsKey(accountService.Account__c)) {

iterAs = mAccountAccountServices.get(accountService.Account__c);

}

iterAs.add(accountService);

mAccountAccountServices.put(accountService.Account__c,iterAs);

}

// Loop through triggered Tasks - and update/write new AccountService__c's

list<AccountService__c> accountServicesToAdd = new list<AccountService__c>();

map<id,AccountService__c> accountServicesToUpdate = new map<id,AccountService__c>();

for(Task t :mTriggeredTasks.values()) {

system.debug('HandlerTask.AddUpdateAccountServices.Task='+t);

if(t.Account__c != null) {

list<string> iterPresentedServiceIds = t.ServicePresentedIds__c.split(';');

if(!mAccountAccountServices.containsKey(t.Account__c)) {

// No services for this account  - add them

for(id presentedServiceId :iterPresentedServiceIds) {

accountServicesToAdd.add(new AccountService__c(Name=mServiceIdName.get(presentedServiceId),

Account__c = t.Account__c,

Last_Call_Disposition__c = stringNullCheck(t.Call_Disposition__c),

Last_Call_Services_Presented__c = stringNullCheck(t.Services_Presented__c),

Last_Contact__c = t.CreatedDate,

Service__c = presentedServiceId,

Status__c = 'Presented',

TaskId__c = t.id

));

}

} else {

// Update existing AccountServices, add missing ones....

for(id presentedServiceId :iterPresentedServiceIds) {

string combinedIds = string.valueOf(t.Account__c) + string.valueOf(presentedServiceId);

if(mAccountServiceIdsToAccountService.containsKey(combinedIds)) {

// Update the AccountService__c record

AccountService__c iterAccountService = new AccountService__c();

iterAccountService = mAccountServiceIdstoAccountService.get(combinedIds);

if(t.CreatedDate > iterAccountService.Last_Contact__c) {

iterAccountService.Last_Contact__c = t.CreatedDate;

iterAccountService.Last_Call_Disposition__c = stringNullCheck(t.Call_Disposition__c);

iterAccountService.Last_Call_Services_Presented__c = stringNullCheck(t.Services_Presented__c);

If(iterAccountService.Status__c == null || 

iterAccountService.Status__c == 'None' ||

iterAccountService.Status__c == 'Opportunity Lost'

) {

iterAccountService.Status__c = 'Presented';

}

}

accountServicesToUpdate.put(iterAccountService.id,iterAccountService);

} else {

// Add a new AccountService__c record

accountServicesToAdd.add(new AccountService__c(Name=mServiceIdName.get(presentedServiceId),

Account__c = t.Account__c,

Last_Call_Disposition__c = stringNullCheck(t.Call_Disposition__c),

Last_Call_Services_Presented__c = stringNullCheck(t.Services_Presented__c),

Last_Contact__c = t.CreatedDate,

Service__c = presentedServiceId,

Status__c = 'Presented',

TaskId__c = t.id

));

}

}

}

}

}

// DML updates as needed

if(accountServicesToAdd.size()>0) {

system.debug('accountServicesToAdd='+accountServicesToUpdate);

insert accountServicesToAdd;

}

If(accountServicesToUpdate.values().size()>0) {

system.debug('accountServicesToUpdate='+accountServicesToUpdate.values());

update accountServicesToUpdate.values();

}

}

1 Like 1 · ·
WOW! Thanks...I sure wish I could use this information. haha. I am looking at another CTI phone system that might do this for me and if so, then I might just change from ringcentral because the other solution is much cheaper. If I do not change though...do you know anyone that can do these changes for me? You see I would also like the recordings to be added to the contact records notes And I would like the call to be notated on the contact records completed activities even if I have made the call through their phone app, or accepted the call from the call being forwarded.Right now it will only log a call on salesforce if I made the call through the ring central saleoforce app. Most times I am out in the field and the call then doesn't get recorded into salesforce. This is a problem because it is not accurately displaying all calls that have occurred on all contacts. 
1 Like 1 · ·
As I learn more and more, the code above can help me so much! Even without changing DTI, which I do NOT need to do. I have done so much research and the softphone that ringcentral has provided is by far the best, and with the cost it makes it even better! I still need some work (learning curve) on triggers and updating objects automatically based on triggers, but I am slowly beginning to figure out what I want to happen when a trigger takes place! Thanks for your time as well!! I am wishing you much success in your business.

1 Like 1 · ·
jitender-kumar avatar image
jitender-kumar answered ·
Samantha, You may want to try this

We have added a new feature in the App recently where you can customize the call log area, basically you can pick and choose fields from Task object.  

If you have installed latest version of the App 3.40.  You can go to  https://ringcentral.na17.visual.force.com/apex/adminUI (keep the first part of your Salesforce URL and just append /apex/adminUI) 

We are in the process of documenting this in our administrator guide.  Could not help myself sharing since I saw this discussion :) 

11 comments Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Just wanted to say thank you!! This is awesome!! 
1 Like 1 · ·
Your feedback means a lot for us.  Thanks you. 
0 Likes 0 · ·
So question...it used to open up a box that would give me the option to create a lead or contact, but it is not working or showing up anymore. Also I think the two softphones, (my desktop and the ringcentral salesforce app) are fighting with each out, because it is now logging both an inbound and outbound call on everycall. 

0 Likes 0 · ·
The option to create lead or contact is determined by Softphone layout setting in Salesforce. 
0 Likes 0 · ·
I'm not seeing the Call Result field being available for selection.  Is there a reason that it shouldn't be?
0 Likes 0 · ·
Show more comments
samantha-lee avatar image
samantha-lee answered ·
hmm.. I thought I had updated to the latest version, but it tell me that this page does not exist.


Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered ·
oh right on..I just clicked the link you provided and it open in MY salesforce! YAY!
Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jitender-kumar avatar image
jitender-kumar answered ·
Cool, means we are on the same Salesforce PODs :) 
Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered ·
I fixed the errors by making edits to my soft phone!!! YAYAYAYAYYAAY! Again you rock. 

Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

samantha-lee avatar image
samantha-lee answered ·
I just wanted to reach out one more time and let you know that, that link you provided has saved me so much time and money. I am so thankful for your time and willingness to post on here. I can now trigger workflows right from ringcentral's softphone! Without having to sacrifice my Subject notes! SOO now all we need to do is get that recording to post on the activity record and this would be a Grandprize WINNER! hint hint
Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

jeff-stevens avatar image
jeff-stevens answered ·
Yep - we are waiting for posting the recording to the activity record also.  It's not critical yet, but I think it will come up at some point for us also.  I think that with the API connectivity I've seen we could probably do this from the Salesforce trigger side, but it would be better to have it in the RingCentral Salesforce app.  Like Samanatha - I agree that would be a great addition to your existing package.
Share
1 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.