You need to sign in to do that
Don't have an account?

Help with a trigger to count activities on Leads
I am trying to create a trigger that will count activities (tasks) on leads.
My code is below....
When saving I am getting the following error....
Error: Compile Error: unexpected token: '}' at line 30 column 1
But if I remove the curly bracket I get a different error
Error: Compile Error: unexpected token: '<EOF>' at line 30 column 0
trigger TaskUpdateLead on Task (after delete, after insert, after undelete, after update)
{
Set<ID> LeadIds = new Set<ID>();
//We only care about tasks linked to Leads.
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
//Add any Lead ids coming from the new data
if (Trigger.new != null) {
for (Task t : Trigger.new) {
if (t.WhatId != null && string.valueOf(t.whatId).startsWith(leadprefix) )
{LeadIds.add(t.whatId);
}
}
}
//Also add any Lead ids coming from the old data (deletes, moving an activity from one Lead to another)
if (Trigger.old != null) {
for (Task t : Trigger.old) {
if (t.WhatId != null && String.valueOf(t.whatId).startsWith(leadprefix) )
{ LeadIds.add(t.whatId);
}
}
}
if (LeadIds.size() > 0)
Lead.Activity_Count__c.updateLeadCount<LeadIds>
}
Any guidance is very much appreciated.
My code is below....
When saving I am getting the following error....
Error: Compile Error: unexpected token: '}' at line 30 column 1
But if I remove the curly bracket I get a different error
Error: Compile Error: unexpected token: '<EOF>' at line 30 column 0
trigger TaskUpdateLead on Task (after delete, after insert, after undelete, after update)
{
Set<ID> LeadIds = new Set<ID>();
//We only care about tasks linked to Leads.
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
//Add any Lead ids coming from the new data
if (Trigger.new != null) {
for (Task t : Trigger.new) {
if (t.WhatId != null && string.valueOf(t.whatId).startsWith(leadprefix) )
{LeadIds.add(t.whatId);
}
}
}
//Also add any Lead ids coming from the old data (deletes, moving an activity from one Lead to another)
if (Trigger.old != null) {
for (Task t : Trigger.old) {
if (t.WhatId != null && String.valueOf(t.whatId).startsWith(leadprefix) )
{ LeadIds.add(t.whatId);
}
}
}
if (LeadIds.size() > 0)
Lead.Activity_Count__c.updateLeadCount<LeadIds>
}
Any guidance is very much appreciated.
Try the following..
trigger TaskUpdateLead on Task (after delete, after insert, after undelete, after update) {
Set<ID> LeadIds = new Set<ID>();
//We only care about tasks linked to Leads.
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
//Add any Lead ids coming from the new data
if(trigger.new!=null){
for (Task t : Trigger.new) {
if (t.WhoId!= null && string.valueof(t.WhoId).startsWith(leadPrefix) ) {
if(!LeadIds.contains(t.WhoId)){
//adding unique lead ids since there can be many tasks with single lead
LeadIds.add(t.WhoId);
}
}
}
}
//Also add any Lead ids coming from the old data (deletes, moving an activity from one Lead to another)
if(trigger.old!=null){
for (Task t2 : Trigger.old) {
if (t2.WhoId!= null && string.valueof(t2.WhoId).startsWith(leadPrefix) )
{
if(!LeadIds.contains(t2.WhoId)){
//adding unique lead ids since there can be many tasks with single lead
LeadIds.add(t2.WhoId);
}
}
}
}
if (LeadIds.size() > 0){
List<Lead> leadsWithTasks = [select id,Activity_Count__c,(select id from Tasks) from Lead where Id IN : Leadids];
List<Lead> leadsUpdatable = new List<Lead>();
for(Lead L : leadsWithTasks){
L.Activity_Count__c = L.Tasks.size();
leadsUpdatable.add(L);
}
if(leadsUpdatable.size()>0){
update leadsUpdatable;
//update all the leads with activity count
}
}
}
All Answers
Lead.Activity_Count__c = leadids.size();
I have the following trigger saved on the Activity object under task triggers. The intention is to update the custom field Activity_Count__c on the Lead object any time a new activity(task) is created, updated, deleted or undeleted.
Any ideas why my custom field is not being updated?
Here's my code....
trigger TaskUpdateLead on Task (after delete, after insert, after undelete, after update) {
Set<ID> LeadIds = new Set<ID>();
//We only care about tasks linked to Leads.
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
//Add any Lead ids coming from the new data
if (Trigger.new != null) {
for (Task t : Trigger.new) {
if (t.WhatId != null && string.valueOf(t.whatId).startsWith(leadprefix) ) {
if(!LeadIds.contains(t.WhatId)
//adding unique lead ids since there can be many tasks with single lead
)LeadIds.add(t.whatId);
}
}
}
//Also add any Lead ids coming from the old data (deletes, moving an activity from one Lead to another)
if (Trigger.old != null) {
for (Task t : Trigger.old) {
if (t.WhatId != null && String.valueOf(t.whatId).startsWith(leadprefix) )
{
if(!LeadIds.contains(t.WhatId)
//adding unique lead ids since there can be many tasks with single lead
)LeadIds.add(t.whatId);
}
}
}
if (LeadIds.size() > 0){
List<Lead> leadsWithTasks = [select id,Activity_Count__c,(select id from Tasks) from Lead where Id IN : Leadids];
List<Lead> leadsUpdatable = new List<Lead>();
for(Lead L : leadsWithTasks){
L.Activity_Count__c = L.Tasks.size();
leadsUpdatable.add(L);
}
if(leadsUpdatable.size()>0){
update leadsUpdatable;
//update all the leads with activity count
}
}
}
Thank you!
Error Error: Compile Error: Method does not exist or incorrect signature: [Id].startsWith(String) at line 13 column 30
13 if (t.WhatId != null && t.whatId.startsWith(leadprefix) ) {
Try the following..
trigger TaskUpdateLead on Task (after delete, after insert, after undelete, after update) {
Set<ID> LeadIds = new Set<ID>();
//We only care about tasks linked to Leads.
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
//Add any Lead ids coming from the new data
if(trigger.new!=null){
for (Task t : Trigger.new) {
if (t.WhoId!= null && string.valueof(t.WhoId).startsWith(leadPrefix) ) {
if(!LeadIds.contains(t.WhoId)){
//adding unique lead ids since there can be many tasks with single lead
LeadIds.add(t.WhoId);
}
}
}
}
//Also add any Lead ids coming from the old data (deletes, moving an activity from one Lead to another)
if(trigger.old!=null){
for (Task t2 : Trigger.old) {
if (t2.WhoId!= null && string.valueof(t2.WhoId).startsWith(leadPrefix) )
{
if(!LeadIds.contains(t2.WhoId)){
//adding unique lead ids since there can be many tasks with single lead
LeadIds.add(t2.WhoId);
}
}
}
}
if (LeadIds.size() > 0){
List<Lead> leadsWithTasks = [select id,Activity_Count__c,(select id from Tasks) from Lead where Id IN : Leadids];
List<Lead> leadsUpdatable = new List<Lead>();
for(Lead L : leadsWithTasks){
L.Activity_Count__c = L.Tasks.size();
leadsUpdatable.add(L);
}
if(leadsUpdatable.size()>0){
update leadsUpdatable;
//update all the leads with activity count
}
}
}
you can use a class if you need, by passing list of Tasks
List<Task> alltasks = new List<Task>();
alltasks.addAll(trigger.new);
alltasks.addAll(trigger.old);
pass this alltasks to the method of the class
class.method(alltasks);
Thank you.
because Activity count should be updated on both triggers. It will either contains count of Tasks or Count of Events.
So I suggest you to create two custom number fields (Make them Hidden / visible to admin only)
"All Tasks"(update with trigger on Task)
and "All Events"(update with trigger on Event)
Create a formula field 'Activity Count"
by summing the above two fields. Use this formula field wherever you need it.
I tried to deploy my change set with my 2 triggers but I am getting a code coverage error. Which I think means I will in fact need an apex class. I am thinking that I can do one class to test both of these triggers. I include the code below....
But when I try to save I get
Error Error: Compile Error: Variable does not exist: lead.id at line 15 column 52
@isTest
private class TestClassName{
public static testMethod void testCountTask() {
//Setup
Lead l = new Lead(lastname='Test');
insert l;
//Insert our first task
Task t = new Task(subject='Test Activity', whoId = lead.id);
insert t;
//Verify count
lead = [SELECT ID, activity_count__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(1,lead.activity_count__c);
//Disconnect task from the lead
didRun = false; //Reset
t.whoId = null;
update t;
//Verify count = 0
Lead lead = new Lead();
lead = [SELECT ID, activity_count__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(0,lead.activity_count__c);
didRun = false; //Reset
//Add an event
Event e = new Event(subject='Test Event', whoId = lead.id, startDateTime = System.Now(), endDateTime =
System.now());
insert e;
//Verify count = 1
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(1,lead.activity_countE__c);
//Relink the task to the lead
didRun = false; //Reset
t.whoId = lead.id;
update t;
//Verify count = 2
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(2,lead.activity_countE__c);
//Disconnect the event from the lead
didRun = false; //Reset
e.whoId = null;
update e;
//Verify count is back down to 1
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(1,lead.activity_countE__c);
//Delete the task
didRun = false; //reset
delete t;
//Verify count is back down to 0
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(0,lead.activity_countE__c);
}
}
You inserted the Lead -> "l" and you are trying to get the Lead ->"Lead"
You can change the initialization instead of changing code.
Check the bold text
@isTest
private class TestClassName{
public static testMethod void testCountTask() {
//Setup
Lead lead1 = new Lead(lastname='Test');
insert lead1;
//Insert our first task
Task t = new Task(subject='Test Activity', whoId = lead1.id);
insert t;
//Verify count
lead1 = [SELECT ID, activity_count__c FROM Lead WHERE ID = :lead1.id];
System.assertEquals(1,lead1.activity_count__c);
//Disconnect task from the lead
didRun = false; //Reset
t.whoId = null;
update t;
//Verify count = 0
Lead lead = new Lead(lastname='lead22');
lead = [SELECT ID, activity_count__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(0,lead.activity_count__c);
didRun = false; //Reset
//Add an event
Event e = new Event(subject='Test Event', whoId = lead.id, startDateTime = System.Now(), endDateTime =
System.now());
insert e;
//Verify count = 1
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(1,lead.activity_countE__c);
//Relink the task to the lead
didRun = false; //Reset
t.whoId = lead.id;
update t;
//Verify count = 2
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(2,lead.activity_countE__c);
//Disconnect the event from the lead
didRun = false; //Reset
e.whoId = null;
update e;
//Verify count is back down to 1
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(1,lead.activity_countE__c);
//Delete the task
didRun = false; //reset
delete t;
//Verify count is back down to 0
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(0,lead.activity_countE__c);
}
}
trigger updateLeadCounts on Task (after insert, after update) {
set<ID> LeadIds= new Set<ID>();
for(Task tt:trigger.new)
{
if(tt.whoId!=null && string.valueof(tt.WhoId).startsWith('003'))
{
LeadIDs.add(tt.whoID);
}
}
if(LeadIds.isEmpty())
return;
List<Lead> cnts= new List<Lead>();
Integer number1=1;
for(Lead ct:[select id, name, count1__c from Lead where id in:Leadids])
{
if(ct.count1__c ==null)
ct.count1__c=0;
ct.count1__c=ct.count1__c+number1;
cnts.add(ct);
}
if(cnts.size()>0)
{
update cnts;
}
}
I want to create the same trigger to count the number of referrals on a lead, will this work? I have a master-detail relationship between lead and custom object "Referrer" and my task is to display the count of referrers in a number field. Will this trigger work in my case? Do I have to consider something else?
I want to create the same trigger but I want the trigger to be on Lead and I want to count the number of referrals on a lead, will your approach work for me? I have a master-detail relationship between lead and a custom object "Referrer" and my task is to display the count of referrers in a number field. Will this trigger work in my case? Do I have to consider something else?
Use Roll-up summary fields
Create a Roll-up summary field on Lead object to COUNT the children (Referrer)
I got further requirements that I have to call the field from lead and opportunity and I have to limit it to 3 record types. Is there a better way?
I am implmenting same to get the count of Emails under my Custom Object record.
But, I am getting below error,
Didn't understand relationship 'EmailMessage' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names. at line 41 column 32
Can we not get the count fo Emails with trigger?
Here is my code so far,
Can you please let me know, where I am doing wrong?
Appreciate for your help.
Thanks in advance.
Lead or Task?
What do I replace and use my Activity counter name? (I assume this is just a field placed on the lead page)
Any help much appreciated!
Your code worked for me on Sandbox, however when writing I use the test case you provided I receive the following:
Error: Compile Error: Variable does not exist: didRun at line 27 column 1
Here is the test case I am using:
@isTest
private class TestClassName{
public static testMethod void testCountTask() {
//Setup
Lead lead1 = new Lead(lastname='Test');
insert lead1;
//Insert our first task
Task t = new Task(subject='Test Activity', whoId = lead1.id);
insert t;
//Verify count
lead1 = [SELECT ID, activity_count__c FROM Lead WHERE ID = :lead1.id];
System.assertEquals(1,lead1.activity_count__c);
//Disconnect task from the lead
didRun = false; //Reset
t.whoId = null;
update t;
//Verify count = 0
Lead lead = new Lead(lastname='lead22');
lead = [SELECT ID, activity_count__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(0,lead.activity_count__c);
didRun = false; //Reset
//Add an event
Event e = new Event(subject='Test Event', whoId = lead.id, startDateTime = System.Now(), endDateTime =
System.now());
insert e;
//Verify count = 1
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(1,lead.activity_countE__c);
//Relink the task to the lead
didRun = false; //Reset
t.whoId = lead.id;
update t;
//Verify count = 2
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(2,lead.activity_countE__c);
//Disconnect the event from the lead
didRun = false; //Reset
e.whoId = null;
update e;
//Verify count is back down to 1
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(1,lead.activity_countE__c);
//Delete the task
didRun = false; //reset
delete t;
//Verify count is back down to 0
lead = [SELECT ID, activity_countE__c FROM Lead WHERE ID = :lead.id];
System.assertEquals(0,lead.activity_countE__c);
}
}
Thanks in advance!
trigger TaskCountLead on Task (after delete, after insert, after undelete, after update) {
Set<ID> LeadIds = new Set<ID>();
//We only care about tasks linked to Leads.
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
//Add any Lead ids coming from the new data
if(trigger.new!=null){
for (Task t : Trigger.new) {
if (t.WhoId!= null && string.valueof(t.WhoId).startsWith(leadPrefix) ) {
if(!LeadIds.contains(t.WhoId)){
//adding unique lead ids since there can be many tasks with single lead
LeadIds.add(t.WhoId);
}
}
}
}
//Also add any Lead ids coming from the old data (deletes, moving an activity from one Lead to another)
if(trigger.old!=null){
for (Task t2 : Trigger.old) {
if (t2.WhoId!= null && string.valueof(t2.WhoId).startsWith(leadPrefix) )
{
if(!LeadIds.contains(t2.WhoId)){
//adding unique lead ids since there can be many tasks with single lead
LeadIds.add(t2.WhoId);
}
}
}
}
if (LeadIds.size() > 0){
List<Lead> leadsWithTasks = [select id,Task_count__c,(select id from Tasks) from Lead where Id IN : Leadids];
List<Lead> leadsUpdatable = new List<Lead>();
for(Lead L : leadsWithTasks){
L.Task_count__c = L.Tasks.size();
leadsUpdatable.add(L);
}
if(leadsUpdatable.size()>0){
update leadsUpdatable;
//update all the leads with activity count
}
}
}
task is created = new()
parse: if in the WhoId field it starts with "00Q4"
if it starts mark the createlead__c field as true
could someone help me with this trigger;
Set<Id> leadIdSet = new Set<Id>();
String leadPrefix = Lead.SObjectType.getDescribe().getKeyPrefix();
if(trigger.isInsert || trigger.isUndelete || trigger.isUpdate && (trigger.isAfter)){
for(Task objTask : trigger.new){
if(objTask.WhoId != null && String.valueOf(objTask.WhoId).startsWith(leadPrefix)){
if(trigger.isInsert || trigger.isUndelete && (trigger.isAfter)){
leadIdSet.add(objTask.WhoId);
}
if(trigger.isUpdate && trigger.isAfter){
if(objTask.WhoId != trigger.oldMap.get(objTask.Id).WhoId){
leadIdSet.add(objTask.WhoId);
}
}
}
}
}
if(trigger.isDelete && trigger.isAfter){
for(Task objTask : trigger.old){
if(objTask.WhoId != null && String.valueOf(objTask.WhoId).startsWith(leadPrefix)){
leadIdSet.add(objTask.WhoId);
}
}
}
Map<Id, Lead> leadMap = new Map<Id, Lead>();
if(!leadIdSet.isEmpty()){
for(Lead objLead : [select id, Number_of_Task__c, (select id from Tasks) from Lead where Id IN : leadIdSet]){
objLead.Number_of_Task__c = objLead.Tasks.size();
leadMap.put(objLead.Id, objLead);
}
Database.update(leadMap.values(), false);
}
}