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
lawlaw 

Contact page not refreshing updated field

I have two buttons on the contact screen.  Log a Call and Log a Meeting.  When these are selected the corresponding screen to log a call or meeting comes up.

Upon saving the call or meeting a trigger is called on insert /update/delete.  This trigger updates a Status field on the contact record.  The updates works however, the contact screen will not show this field as updated until I hit F5.   I have reproduced this in Both FireFox and Chrome.

 

Thanks in advance for your help.

Lawrence

ArunDavidNSIArunDavidNSI

Is the trigger executing in real time or as a result of a future method. If you use a future method, then the process becomes asynchronous and you will have to refresh the screen to see the update. A simple trigger though should give you the updated value when the contact screen opens up.

 

Also are you opening the log a call screen in a separate window or is it opening in the same window and returning to the contact screen?

 

Arun

lawlaw

Yes, the trigger is as a result of a future method.  I needed to do this to avoid a  soql 101  error... too many soql queries.

 

The log a screen is openng in the same window and returning to the contact screen

Avidev9Avidev9
Since you are making a async call(@future) changes wont be reflected instantaneously. Future calls has some delays.

To make this instantaneous you have to make synchronous calls by avoiding future calls.

The SOQL 101 error that you are getting is due to inefficient trigger design. That can be corrected by following the best practices.
lawlaw

The use of future calls was the suggestion SalesForce Support gave me after looking at my code.

The Soql 101 error was not caused by have queries in loops.  It was caused by  the following.

 

When a user changes ownership of a candidate record all tasks and events are copied to that new owner.

This causes an  edit  to occur for each task associated with that contact. in turn this edit causes an existing task trigger to fire off that contains

a query(not in a loop). So if the contact has more than 100 tasks for example a  recurring task.... this has caused the SOQL 101 error.

 

 

Avidev9Avidev9
Still I can see a problem with your trigger design. In a bulk trigger generally batch size is around 200 and this essentially means that if 200 records are edited, there will be only one event, i.e. the trigger will fire only once and not for each of the records.
lawlaw

Any suggestions on improvement?

Avidev9Avidev9
Can't help you without seeing the code.
hisalesforcehisalesforce

Best practice is to redesign  the trigger.If thats time consuming, at least you can exchange, some dml operation with  future method.

lawlaw

I agree seeing the code would help.  

Would you like to see the trigger making the future call or the original trigger before I modified it to use the future call?

 

Lawrence

hisalesforcehisalesforce
Yeap Post the code...
lawlaw

Below is the code before I added the future call..

 

trigger CandidateStatusFlow on Task (after insert, after update, before delete) {
if (Trigger.isDelete) {
        for (Task t : Trigger.old) {
        if (t.Status == 'Completed'&&  (!(UserInfo.getProfileId ().equals('00eU0000000o4PBIAY')))) {
                t.addError('You cannot delete a task with a status of complete.');
            }
        }
    }
else
      {

   SingletonResource singleton = SingletonResource.getInstance();
        List<Id> contactIds = new List<Id> ();
        Id callRecId = singleton.callRecId;
        Id meetingRecId = singleton.meetingRecId;
        Id faceRecId = singleton.faceToFaceRecId;
        Id prospectRecId = singleton.prospectRecId;
        Id candidateRecId = singleton.candidateRecId;
        
        String RecordType;  //lreed 02/06/2012...variable to capture recordType ID of Button.... Log a Call or Log a Meeting
        String TaskStatus;
        
        for (Task t : Trigger.new) {
         
                // The following code ensures that the contact status changes  to 'Prospect: Contacted' once a task of type call has been completed
                RecordType = t.RecordTypeId; //store value of recordType Based on Button Clicked ...Log a Call or Log a Meeting button
                TaskStatus = t.Status;
                if (t.Status == 'Completed' && !(t.IsRecurrence) &&  (t.Type == 'Inbound Call/Conversation' || t.Type == 'Outbound Call/Conversation') &&
                    t.RecordTypeId == callRecId ) {              
                    contactIds.add(t.WhoId);
            } else if (t.Status == 'Completed' && !(t.IsRecurrence) && t.RecordTypeId == meetingRecId) {

                contactIds.add(t.WhoId);
            }
        }
        
       
       if(Trigger.isUpdate)
       {
       for (Task t : Trigger.new) {
       system.debug('NEW OwnerID' + t.OwnerId);
       
            if(t.OwnerId != null && (trigger.new[0].OwnerId == trigger.old[0].OwnerId) && trigger.new[0].OwnerId  != '005U0000001i4s1IAA' ){
          
            Map<Id, Contact> contacts = new Map<Id, Contact> ([Select Id, Phone, MobilePhone, Status__c, RecordTypeId, AccountId, LeadSource, Last_Comment__c
                                                            From Contact
                                                            Where Id IN :contactIds]);
            Map<Id, Contact> desiredContacts = new Map<Id, Contact> ();             
            for (Contact c : contacts.values()) {   
 
            if (RecordType == '012U0000000L2TJIA0'&&  c.Status__c == 'Prospect: Not Contacted' ) {   //Call
                c.Status__c = 'Prospect: Contacted';
                desiredContacts.put(c.Id, c);
                               
            }else if (RecordType == '012U0000000XcyZIAS' && c.Status__c == 'Candidate: Qualified') {      //Meeting   
                    c.Status__c = 'Candidate: Meeting';           
                    desiredContacts.put(c.Id, c);
                                    //Meeting                                 //Prospect
             }
             
            if (Trigger.isInsert) {
                if (RecordType == '012U0000000XcyZIAS' && c.RecordTypeId == '012U0000000Y3ybIAC' && c.Status__c != 'Candidate: Qualified') {     /// 02-12-2013 lreed...If user has not qualified lead show error message
                      trigger.new[0].adderror('You Must Qualify The Candidate Before Logging A Meeting!');         
                                             
                }else if (RecordType == '012U0000000XcyZIAS' && c.RecordTypeId == '012U0000000Y3ybIAC' && c.Status__c != 'Prospect: Contacted')
                 {     /// 02-12-2013 lreed...If user has not qualified lead show error message
                       trigger.new[0].adderror('Please Log a Call Before Qualifying The Candidate!');
                 }            
            }
         }
         
         for (Task t2 : Trigger.new) {
            
            if (contacts.containsKey(t2.WhoId)) {
                Contact c = contacts.get(t2.WhoId);
                if (desiredContacts.containsKey(c.Id)) {
                    c = desiredContacts.get(c.Id);
                   
                }
                c.Last_Comment__c = t2.Description;
                desiredContacts.put(c.Id, c);
            }
        }
         update desiredContacts.values();
       }        
      }
      }

    
  }
}

hisalesforcehisalesforce

//I just moved the position of the update ...Its outside the loop now.YOu will not get any governor limit issue now..

So you can move the code from future method to trigger.

But be careful not to put dml,select statement inside the loop.

 

 

 

 

 

 

trigger CandidateStatusFlow on Task (after insert, after update, before delete) {
if (Trigger.isDelete) {
for (Task t : Trigger.old) {
if (t.Status == 'Completed'&& (!(UserInfo.getProfileId ().equals('00eU0000000o4PBIAY')))) {
t.addError('You cannot delete a task with a status of complete.');
}
}
}
else
{

SingletonResource singleton = SingletonResource.getInstance();
List<Id> contactIds = new List<Id> ();
Id callRecId = singleton.callRecId;
Id meetingRecId = singleton.meetingRecId;
Id faceRecId = singleton.faceToFaceRecId;
Id prospectRecId = singleton.prospectRecId;
Id candidateRecId = singleton.candidateRecId;
Map<Id, Contact> desiredContacts = new Map<Id, Contact> ();

String RecordType; //lreed 02/06/2012...variable to capture recordType ID of Button.... Log a Call or Log a Meeting
String TaskStatus;

for (Task t : Trigger.new) {

// The following code ensures that the contact status changes to 'Prospect: Contacted' once a task of type call has been completed
RecordType = t.RecordTypeId; //store value of recordType Based on Button Clicked ...Log a Call or Log a Meeting button
TaskStatus = t.Status;
if (t.Status == 'Completed' && !(t.IsRecurrence) && (t.Type == 'Inbound Call/Conversation' || t.Type == 'Outbound Call/Conversation') &&
t.RecordTypeId == callRecId ) {
contactIds.add(t.WhoId);
} else if (t.Status == 'Completed' && !(t.IsRecurrence) && t.RecordTypeId == meetingRecId) {

contactIds.add(t.WhoId);
}
}


if(Trigger.isUpdate)
{
for (Task t : Trigger.new) {
system.debug('NEW OwnerID' + t.OwnerId);

if(t.OwnerId != null && (trigger.new[0].OwnerId == trigger.old[0].OwnerId) && trigger.new[0].OwnerId != '005U0000001i4s1IAA' ){

Map<Id, Contact> contacts = new Map<Id, Contact> ([Select Id, Phone, MobilePhone, Status__c, RecordTypeId, AccountId, LeadSource, Last_Comment__c
From Contact
Where Id IN :contactIds]);

for (Contact c : contacts.values()) {

if (RecordType == '012U0000000L2TJIA0'&& c.Status__c == 'Prospect: Not Contacted' ) { //Call
c.Status__c = 'Prospect: Contacted';
desiredContacts.put(c.Id, c);

}else if (RecordType == '012U0000000XcyZIAS' && c.Status__c == 'Candidate: Qualified') { //Meeting
c.Status__c = 'Candidate: Meeting';
desiredContacts.put(c.Id, c);
//Meeting //Prospect
}

if (Trigger.isInsert) {
if (RecordType == '012U0000000XcyZIAS' && c.RecordTypeId == '012U0000000Y3ybIAC' && c.Status__c != 'Candidate: Qualified') { /// 02-12-2013 lreed...If user has not qualified lead show error message
trigger.new[0].adderror('You Must Qualify The Candidate Before Logging A Meeting!');

}else if (RecordType == '012U0000000XcyZIAS' && c.RecordTypeId == '012U0000000Y3ybIAC' && c.Status__c != 'Prospect: Contacted')
{ /// 02-12-2013 lreed...If user has not qualified lead show error message
trigger.new[0].adderror('Please Log a Call Before Qualifying The Candidate!');
}
}
}

for (Task t2 : Trigger.new) {

if (contacts.containsKey(t2.WhoId)) {
Contact c = contacts.get(t2.WhoId);
if (desiredContacts.containsKey(c.Id)) {
c = desiredContacts.get(c.Id);

}
c.Last_Comment__c = t2.Description;
desiredContacts.put(c.Id, c);
}
}

}
}
}

//Moved update outside the loop It should work now ....

if(desiredContacts.size()>0)
update desiredContacts.values();

}
}

lawlaw

When moving the update to that location I receive the following error on saving the change in code.


Save error: Variable does not exist: desiredContacts    CandidateStatusFlow.trigger    EARDEVTR2/src/triggers    line 91    Force.com save problem

hisalesforcehisalesforce

//Use this code .......................

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

Map<Id, Contact> desiredContacts = new Map<Id, Contact> ();

if (Trigger.isDelete) {
for (Task t : Trigger.old) {
if (t.Status == 'Completed'&& (!(UserInfo.getProfileId ().equals('00eU0000000o4PBIAY')))) {
t.addError('You cannot delete a task with a status of complete.');
}
}
}
else
{

SingletonResource singleton = SingletonResource.getInstance();
List<Id> contactIds = new List<Id> ();
Id callRecId = singleton.callRecId;
Id meetingRecId = singleton.meetingRecId;
Id faceRecId = singleton.faceToFaceRecId;
Id prospectRecId = singleton.prospectRecId;
Id candidateRecId = singleton.candidateRecId;


String RecordType; //lreed 02/06/2012...variable to capture recordType ID of Button.... Log a Call or Log a Meeting
String TaskStatus;

for (Task t : Trigger.new) {

// The following code ensures that the contact status changes to 'Prospect: Contacted' once a task of type call has been completed
RecordType = t.RecordTypeId; //store value of recordType Based on Button Clicked ...Log a Call or Log a Meeting button
TaskStatus = t.Status;
if (t.Status == 'Completed' && !(t.IsRecurrence) && (t.Type == 'Inbound Call/Conversation' || t.Type == 'Outbound Call/Conversation') &&
t.RecordTypeId == callRecId ) {
contactIds.add(t.WhoId);
} else if (t.Status == 'Completed' && !(t.IsRecurrence) && t.RecordTypeId == meetingRecId) {

contactIds.add(t.WhoId);
}
}


if(Trigger.isUpdate)
{
for (Task t : Trigger.new) {
system.debug('NEW OwnerID' + t.OwnerId);

if(t.OwnerId != null && (trigger.new[0].OwnerId == trigger.old[0].OwnerId) && trigger.new[0].OwnerId != '005U0000001i4s1IAA' ){

Map<Id, Contact> contacts = new Map<Id, Contact> ([Select Id, Phone, MobilePhone, Status__c, RecordTypeId, AccountId, LeadSource, Last_Comment__c
From Contact
Where Id IN :contactIds]);

for (Contact c : contacts.values()) {

if (RecordType == '012U0000000L2TJIA0'&& c.Status__c == 'Prospect: Not Contacted' ) { //Call
c.Status__c = 'Prospect: Contacted';
desiredContacts.put(c.Id, c);

}else if (RecordType == '012U0000000XcyZIAS' && c.Status__c == 'Candidate: Qualified') { //Meeting
c.Status__c = 'Candidate: Meeting';
desiredContacts.put(c.Id, c);
//Meeting //Prospect
}

if (Trigger.isInsert) {
if (RecordType == '012U0000000XcyZIAS' && c.RecordTypeId == '012U0000000Y3ybIAC' && c.Status__c != 'Candidate: Qualified') { /// 02-12-2013 lreed...If user has not qualified lead show error message
trigger.new[0].adderror('You Must Qualify The Candidate Before Logging A Meeting!');

}else if (RecordType == '012U0000000XcyZIAS' && c.RecordTypeId == '012U0000000Y3ybIAC' && c.Status__c != 'Prospect: Contacted')
{ /// 02-12-2013 lreed...If user has not qualified lead show error message
trigger.new[0].adderror('Please Log a Call Before Qualifying The Candidate!');
}
}
}

for (Task t2 : Trigger.new) {

if (contacts.containsKey(t2.WhoId)) {
Contact c = contacts.get(t2.WhoId);
if (desiredContacts.containsKey(c.Id)) {
c = desiredContacts.get(c.Id);

}
c.Last_Comment__c = t2.Description;
desiredContacts.put(c.Id, c);
}
}

}
}
}

//Moved update outside the loop It should work now ....

if(desiredContacts.size()>0)
update desiredContacts.values();

}
}