You need to sign in to do that
Don't have an account?
Task Apex Trigger Help!
Good Morning,
I was hoping (preying) that someone could help me with a problem I am having getting some pretty simple (IMO) fields completed.
In Leads - I have 4 custom fields:
Phone_Call_Attempts__c (Number(3, 0)
Successful_Phone_Calls__c (Number(3, 0)
Future_Dated_Task_Scheduled__c (Checkbox)
Overdue_Task_Flag__c (Checkbox)
When a Task is created (related to the lead) and has its Status' set to 'Completed', then I would like this to record as '1' in the Phone_Call_Attempts__c field on the related lead. Additional tasks of the same criteria would result in the number of Phone_Call_Attempts__c increasing. So if their had been 4 tasks with a status of completed, the Phone_Call_Attempts__c field would read '4'.
In addition, When a task (related to the lead) has its 'Status' set to 'Completed' and its 'Outcome' (Outcome__c (Picklist)) is 'Call Successful - Spoke with contact' I would like this to record as '1' in the 'Successful_Phone_Calls__c' field on the related Lead. Additional tasks of the same criteria would result in the number of 'Successful_Phone_Calls__c' increaseing. So if their had been 4 tasks with the outcome of 'Call Successful - Spoke with contact' then the Successful_Phone_Calls__c field would read '4'.
Where a task is raised against the lead that has a future date and has a 'Status' of 'Not Started' then this would result in the Future_Dated_Task_Scheduled__c checkbox being ticked. This should be unticked when/if the task is later completed.
Finally - where a task has a 'Status' of 'Not Started' and the 'ActivityDate' is in the past - the Overdue_Task_Flag__c should be ticked.
ANY help would be VERY VERY appreciated.
Steve
had to paste it into the ide to match on parenthesis :)
the for statement on leads had an extra left bracket
All Answers
For starters, I'd recommend you set a default value of 0 for the numerical fields on Lead. Here is a rather simplistic approach to thigns - i've assumed you want this only on Insert. Also, this would not cater to people deleting tasks after they've been added to the aggregate fields on Leads.
trigger TaskAfter on Task ( before insert) {
Set<Id> leadsToUpdate = new Set<Id>{};
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
for(Task t : trigger.new)
if(t.WhoId != null && ((String)t.WhoId).startsWith(leadPrefix) //if not null and whoId belongs to a Lead
leadsToUpdate.add(t.WhoId);
Map<Id, Lead> leadMap = new Map<Id, Lead>([Select Id, Phone_Call_Attempts__c, Successful_Phone_Calls__c, Future_Dated_Task_Scheduled__c, Overdue_Task_Flag__c from Lead where Id IN :leadsToUpdate ]);
for(Task t : trigger.new)
{
Lead currLead = leadMap.get(t.WhoId);
if (currLead != null)
{
if(t.Status == 'Completed')
{
currLead.Phone_Call_Attempts__c += 1;
if(t.Outcome__c == 'Call Successful - Spoke with contact')
currLead.Successful_Phone_Calls__c += 1;
}
else if(t.ActivityDate > Date.Today() && t.Status == 'Not Started')
currLead.Future_Dated_Task_Scheduled__c = true;
else if (t.ActivityDate <= Date.Today() && t.Status == 'Not Started')
currLead.Overdue_Task_Flag__c = true;
}
}
if (leadMap != null && !leadMap.values().isEmpty())
Database.update(leadMap.values());
}
Trigger Code
Hi - thanks so much for reply!
am trying this in sandbox in task triggers but am gettnig the following error:
Error: Compile Error: No such column 'WhoId' on entity 'Lead'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. at line 10 column 43
Oops, the perils of type in textpad
WhoId should not be in this SOQL Query
Map<Id, Lead> leadMap = new Map<Id, Lead>([Select Id, Phone_Call_Attempts__c, Successful_Phone_Calls__c, Future_Dated_Task_Scheduled__c, Overdue_Task_Flag__c from Lead where Id IN :leadsToUpdate ]);
This works perfectly thank you!
The only thing is when the 'Future Dated Task' is closed off as completed - it does not 'untick' the Future Dated Task Scheduled box.
Is their an easy way to do this?
sweet.
just add this couple of lines in the if block i'd written earlier
if(t.Status == 'Completed')
{
currLead.Phone_Call_Attempts__c += 1;
if(t.Outcome__c == 'Call Successful - Spoke with contact')
currLead.Successful_Phone_Calls__c += 1;
//NEW BLOCK OF CODE ADDED TO SET FUTURE TASK SCHEDULED TO FALSE IF COMPLETED
if (currLead.Future_Dated_Task_Scheduled__c)
currLead.Future_Dated_Task_Scheduled__c = false;
}
Well actually not quite, now that I think about it.
Because there may be other future dated tasks open? This depends on whether tasks are updated, or always created in a terminal state?
Coz then you'd have to maintain a counter of future dated tasks on lead, which is incremented as new tasks are created and decremented as tasks are closed. Then depending on the value of the counter, check or uncheck the future tasks scheduled.
Another alternative would be to wipe all the counters, and recalculate on every insert or update. the solution depends on the complexity / dynamic-ness of your business requirement.
yes - was just about to say - dosnt seem to work - I agree with you, i think to wipe all the counters, and recalculate on every insert or update would be the better option.
Thanks so much for this by the way.
Here, lets try the wipe and recalculate approach - (caveat hopefully you wont have thousands of tasks on each Lead, else it could break some limits, over time)
trigger TaskAfter on Task ( after insert, after update) {
Set<Id> leadsToUpdate = new Set<Id>{};
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
for(Task t : trigger.new)
if(t.WhoId != null && ((String)t.WhoId).startsWith(leadPrefix) //if not null and whoId belongs to a Lead
leadsToUpdate.add(t.WhoId);
for (Lead currLead : ([Select Id, Phone_Call_Attempts__c, Successful_Phone_Calls__c, Future_Dated_Task_Scheduled__c, Overdue_Task_Flag__c, (Select Id, Status, ActivityDate, Outcome__c from Tasks ORDER BY CreatedDate DESC) from Lead where Id IN :leadsToUpdate ])
{
currLead.Phone_Call_Attempts__c = 0;
currLead.Successful_Phone_Calls__c = 0;
currLead.Future_Dated_Task_Scheduled__c = false;
currLead.Overdue_Task_Flag__c = false;
for(Task t : currLead.Tasks )
{
if(t.Status == 'Completed')
{
currLead.Phone_Call_Attempts__c += 1;
if(t.Outcome__c == 'Call Successful - Spoke with contact')
currLead.Successful_Phone_Calls__c += 1;
}
else if(t.ActivityDate > Date.Today() && t.Status == 'Not Started')
currLead.Future_Dated_Task_Scheduled__c = true;
else if (t.ActivityDate <= Date.Today() && t.Status == 'Not Started')
currLead.Overdue_Task_Flag__c = true;
}
}
if (leadMap != null && !leadMap.values().isEmpty())
Database.update(leadMap.values());
}
ooooh getting error:
Compile Error: expecting a right parentheses, found 'leadsToUpdate.add' at line 8 column 0
doh ! then jsut add right paranthesis :) Looks like u added it last time to get it to compile :)
if(t.WhoId != null && ((String)t.WhoId).startsWith(leadPrefix)) //if not null and whoId belongs to a Lead
leadsToUpdate.add(t.WhoId);
tried that but now get:
Compile Error: unexpected token: '{' at line 11 column 0
when I delete that I get:
Compile Error: expecting a right parentheses, found 'currLead.Phone_Call_Attempts__c' at line 12 column 0
had to paste it into the ide to match on parenthesis :)
the for statement on leads had an extra left bracket
OK - now I feel like a pain! :smileysad:
Compile Error: Variable does not exist: leadMap at line 37 column 5
I've update the corrections in my last post - apologies for the toing and froing !
Working fantasticly! You are a live saver - thank you so very much!
My company offers call handling services - if you need some assistance with your call handling - get in touch and I shall look after you.
Sweet! :)
Another satisfied 'customer' ;)
I am trying to fix my apex class testing code except I do not understand a way around what it is telling me to do. It tells me that in line 17, its expecting a right parenthesis, but only found a ;...however when I attempt to put a right parenthesis in it begins telling me all manor of things. It tells me that it does not expect token 'product' in the next line, that it is now expecting a close right curly bracket in line 17, etc. Please help!
This is my code, you will probably recognize it from the force.com workbook spring 13 release. I followed their instructions exactly:
@isTest
private
class TestHandleProductPriceChange {
statictestMethodvoid testPriceChange () {
Invoice_Statement__c Invoice = newInvoice_Statement__c(Status__c = 'Negotiating');
insert Invoice;
Merchandise__c[] products = new merchandise__c[]{
newMerchandise__c(Name = 'item 1', Description__c =
'test product 1', Price__c = 10,Total_Inventory__c = 10),
newMerchandise__c(Name = 'item 2', Description__c =
'test product 2', Price__c = 11,Total_Inventory__c = 10)
};
Insert products;
Line_Items__c[] LineItems = newLine_Items__c[] {
newLine_Items__c(Invoice_Statement__c = invoice.id,
Merchandise__c = products[0].price__c = 20; //raise price
prodcts[1].price__c = 5;
//lower price
Test.startTest();
update products;
Test,stopTest();
lineItems =
[
SELECT id, unit_price__c FROM Line_items__c WHERE id IN :lineItems];
System.assert(lineItems[0].unit_price__c ==10);
//unchanged
System.assert(lineItems[1].unit_price__c == 5);
//changed!!
};
insert lineItems;
products[0].price__c = 20;
Test.startTest();
update products;
Test.stopTest ();
lineItems = [
SELECT id, unit_Price__c FROMLine_Items__cWHERE id IN :lineItems];
system.assert(lineItems[0].unit_Price__c == 10);
}
}