I think you may be overcomplicating things a bit. All you need to do is get the correct parent tasks, and update it with their attachment count. The following code should do what you need.
trigger CountAttachment on Attachment (after insert, after update, after delete, after undelete) {
// Contains the IDs of all the parent tasks
Set<Id> parentTaskIdSet = new Set<id>();
if (trigger.new != null)
{
for (Attachment a: trigger.new)
{
parentTaskIdSet.add(a.parentId);
}
}
if (trigger.old != null)
{
for (Attachment a: trigger.old)
{
parentTaskIdSet.add(a.parentId);
}
}
// List of tasks that needs to be updated
List<Task> parentTaskList = [SELECT id, (SELECT id FROM Attachments) FROM Task WHERE id in: parentTaskIdSet];
for (Task t: parentTaskList)
{
t.NumberOfAttachments__c = t.Attachments.size();
}
update parentTaskList;
}
Hope this helps. Feel free to ask any questions and please remember to select a best answer if it helped resolve your issue(s).
I am a salesforce administrator and learning development. So please guide me. I am trying this in my Developer Sandbox. I created two custom fields on the Task. One for counting the attachments and one which displays the number on the task.
Code i am using is -
trigger countattachment on Attachment (after insert, after update, after delete, after undelete) { Map<Id,List<Attachment>> parent = new Map<Id,List<Attachment>>(); set<id> attids = new set<id>();
}else if(Trigger.old != null){ for(Attachment c:Trigger.old){ if(c.ParentId<>null) attids.add(Trigger.oldMap.get(c.id).parentid); } } if(attids.size()>0){ try{ List<Attachment> a = new List<Attachment>(); Map<id,Task> testmap = new Map<id,Task>([select id,CountAttachment__c from Task where id IN: attids]); a = [select id,parentid from Attachment where parentid IN:attids];
I think you may be overcomplicating things a bit. All you need to do is get the correct parent tasks, and update it with their attachment count. The following code should do what you need.
trigger CountAttachment on Attachment (after insert, after update, after delete, after undelete) {
// Contains the IDs of all the parent tasks
Set<Id> parentTaskIdSet = new Set<id>();
if (trigger.new != null)
{
for (Attachment a: trigger.new)
{
parentTaskIdSet.add(a.parentId);
}
}
if (trigger.old != null)
{
for (Attachment a: trigger.old)
{
parentTaskIdSet.add(a.parentId);
}
}
// List of tasks that needs to be updated
List<Task> parentTaskList = [SELECT id, (SELECT id FROM Attachments) FROM Task WHERE id in: parentTaskIdSet];
for (Task t: parentTaskList)
{
t.NumberOfAttachments__c = t.Attachments.size();
}
update parentTaskList;
}
Hope this helps. Feel free to ask any questions and please remember to select a best answer if it helped resolve your issue(s).
Thank you for the response. I tried this as well but it does not work. i mean i have added two attachments on my task but the total still shows zero and not two. Can we connect to discuss this please.
Hi Ken,
I tried but this is also not working.
I am trying this in my Developer Sandbox. Can that be the reason? Also, I am new to writing this code so can you confirm that I only need to write the trigger in Developer Console and save it. Do I need to do anything else as well for it to run? I am not sure how this works. Please elaborate and help.
Thanks
Surbhi
Saving it in Developer Console and saving it should be sufficient. You can always go to setup -> develop -> apex triggers and see the list of triggers that are in your org there.
First, check if the field updates when you edit the attachment and save the attachment. Also see if deleting the attachment updates the field. Those should at least work.
So the problem is probably because when you create attachments on a task, you need to edit the task, create the attachments, then save the task. When you are saving the task, you are probably writing over the trigger's update on task.
So to fix this you will actually need to write another trigger, this time on Task. And since we will be updating task in the task trigger, we need a class to prevent recursion.
Here's what the trigger on Task would look like:
trigger UpdateAttachmentCount on Task (after insert, after update) {
if (checkRecursive.runOnce())
{
List<Task> taskList = new List<Task>();
Set<ID> taskIDSet = new Set<ID>();
if (trigger.old != null)
{
for (Task t: trigger.old)
{
taskIDSet.add(t.ID);
}
}
if (trigger.new != null)
{
for (Task t: trigger.new)
{
taskIDSet.add(t.ID);
}
}
// Query for the attachment children of the tasks
taskList = [SELECT id, (SELECT id FROM attachments) FROM Task WHERE ID in: taskIDSet];
for (Task t: taskList)
{
t.NumberOfAttachments__c = t.Attachments.size();
}
update taskList;
}
And here's what the class that prevents recursion looks like:
public Class checkRecursive{
private static boolean run = true;
public static boolean runOnce(){
if (run){
run = false;
return true;
}
else
{
return run;
}
}
}
I just tested this code on my own org, and it works fine. Let me know if this works for you.
Hi Ken,
Shall I only create this class and trigger now. Delete the previous one?
Also, do I need to create two fields – one which is used in trigger and the second which displays the value on the pagelayout?
Please confirm.
Thanks
Surbhi
You should only need one field that you update in your trigger and display on the page layout. Also you need to keep the attachment trigger as well, because that will update the field when you update/delete/undelete the attachment. The task trigger is basically only for when you're inserting the attachments.
It depends on your other needs, but I'm inclined to say a number field should suffice in most cases. The trigger I wrote is assuming that it is a number field.
Hi Ken,
Thanks for all the help but I am still stuck. I will detail the steps with the screenshots that I have done.
1. Create the field – NumberofAttachments with data type number.
2. Write the Trigger on attachment.
3. Write the trigger on Task.
4. Write the Class
Now I receive the below error after writing the task trigger and Class.
[cid:image003.jpg@01D209BA.FDE9A300]
Because of this, I get the error while saving a task.
[cid:image004.jpg@01D209BA.FDE9A300]
Please advise.
Thanks
Surbhi
It looks like the trigger is not recognizing checkRecursive.xyz(). Are you sure you named your function xyz()? If you copied my code it should be called runOnce(). The reason why you're getting the depth error on saving the task is because the trigger is getting called recursively. Maybe post your class code, and I'll be able to tell what happened. If you directly copy pasted my code, you shouldn't be calling xyz.
Hi Ken,
I copied your code only and it was runOnce() only. I received the same error with runOnce().
I changed the name to see if it works but no luck. Same error ☹
Is it possible to connect with you and discuss this please. This is very URGENT for me.
Thanks
Surbhi
Please double check to see if your class is saved correctly, and that all spelling is correct. The error is just saying that the method doesn't exist, so the trigger is unable to find that method for some reason. It's difficult to see your code in the screenshot, maybe just post the code as text here. Please include the class too.
Hi Ken,
I have written the class and trigger in my Developer Edition. Can you please help me in getting this deployed in my production as well.
Can you provide the steps please.
Thanks
Surbhi
Can you mark best answer so that this can help others in the future and i will be glad to answer your follow up question in another thread. It's just that your follow up question is about deployment, which is a very different topic!
Hi Ken,
Can you please advise on my new question - https://developer.salesforce.com/forums/ForumsMain?id=906F0000000g2mp
This is very important and urgent.
Thanks
Surbhi
From: Surbhi Dham
Sent: 14 September 2016 10:37
To: 'reply'
Subject: RE: (Salesforce Developers): New reply to your question.
Hi Ken,
Done that. Please advise.
https://developer.salesforce.com/forums/ForumsMain#!/feedtype=SINGLE_QUESTION_DETAIL&dc=Developer_Forums&criteria=OPENQUESTIONS&id=906F0000000g2mpIAA
Thanks
Surbhi
Hi Ken,
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Thanks
Surbhi
Hi Ken,
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Thanks
Surbhi
From: Surbhi Dham
Sent: 03 October 2016 17:36
To: 'reply'
Subject: RE: (Salesforce Developers): New reply to your question.
Hi Ken,
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Thanks
Surbhi
Hi Ken, Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Link for the this Query is - https://developer.salesforce.com/forums/ForumsMain?id=906F0000000g2mp
Hi Ken,
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Thanks
Surbhi
From: Surbhi Dham
Sent: 04 October 2016 17:13
To: 'reply'
Subject: RE: (Salesforce Developers): New reply to your question.
Hi Ken,
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Thanks
Surbhi
From: Surbhi Dham
Sent: 03 October 2016 17:36
To: 'reply' >
Subject: RE: (Salesforce Developers): New reply to your question.
Hi Ken,
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Thanks
Surbhi
I think you may be overcomplicating things a bit. All you need to do is get the correct parent tasks, and update it with their attachment count. The following code should do what you need.
Hope this helps. Feel free to ask any questions and please remember to select a best answer if it helped resolve your issue(s).
All Answers
I am a salesforce administrator and learning development. So please guide me. I am trying this in my Developer Sandbox.
I created two custom fields on the Task. One for counting the attachments and one which displays the number on the task.
Code i am using is -
trigger countattachment on Attachment (after insert, after update, after delete, after undelete) {
Map<Id,List<Attachment>> parent = new Map<Id,List<Attachment>>();
set<id> attids = new set<id>();
if(Trigger.new<>null){
for(Attachment c:Trigger.new){
Task l;
if(c.ParentId != null)
attids.add(c.parentid);
}
}else if(Trigger.old != null){
for(Attachment c:Trigger.old){
if(c.ParentId<>null)
attids.add(Trigger.oldMap.get(c.id).parentid);
}
}
if(attids.size()>0){
try{
List<Attachment> a = new List<Attachment>();
Map<id,Task> testmap = new Map<id,Task>([select id,CountAttachment__c from Task where id IN: attids]);
a = [select id,parentid from Attachment where parentid IN:attids];
for(Attachment at: a){
List<Attachment> llist = new List<Attachment>();
if(parent.get(at.parentid) == null){
llist = new List<Attachment>();
llist.add(at);
parent.put(at.parentid,llist);
}else if(parent.get(at.parentid) != null){
llist = new List<Attachment>();
llist = parent.get(at.parentid);
llist.add(at);
parent.put(at.parentid,llist);
}
}
for(Id i: attids){
if(testmap.get(i) != null && parent.get(i) != null){
testmap.get(i).CountAttachment__c = parent.get(i).size();
}else if(testmap.get(i) != null && parent.get(i) == null){
testmap.get(i).CountAttachment__c = 0;
}
}
update testmap.values();
System.Debug(testmap.values());
}catch(Exception e){}
}
}
I think you may be overcomplicating things a bit. All you need to do is get the correct parent tasks, and update it with their attachment count. The following code should do what you need.
Hope this helps. Feel free to ask any questions and please remember to select a best answer if it helped resolve your issue(s).
Thank you for the response. I tried this as well but it does not work. i mean i have added two attachments on my task but the total still shows zero and not two. Can we connect to discuss this please.
Saving it in Developer Console and saving it should be sufficient. You can always go to setup -> develop -> apex triggers and see the list of triggers that are in your org there.
First, check if the field updates when you edit the attachment and save the attachment. Also see if deleting the attachment updates the field. Those should at least work.
So the problem is probably because when you create attachments on a task, you need to edit the task, create the attachments, then save the task. When you are saving the task, you are probably writing over the trigger's update on task.
So to fix this you will actually need to write another trigger, this time on Task. And since we will be updating task in the task trigger, we need a class to prevent recursion.
Here's what the trigger on Task would look like:
And here's what the class that prevents recursion looks like:
I just tested this code on my own org, and it works fine. Let me know if this works for you.
You should only need one field that you update in your trigger and display on the page layout. Also you need to keep the attachment trigger as well, because that will update the field when you update/delete/undelete the attachment. The task trigger is basically only for when you're inserting the attachments.
It depends on your other needs, but I'm inclined to say a number field should suffice in most cases. The trigger I wrote is assuming that it is a number field.
Please reupload those attachments, so I can see what errors you are getting.
Thanks for all the help but I am still stuck. I will detail the steps with the screenshots that I have done.
Now I receive the below error after writing the task trigger and Class.
Because of this, I get the error while saving a task
Please advise.
Thanks
Surbhi
It looks like the trigger is not recognizing checkRecursive.xyz(). Are you sure you named your function xyz()? If you copied my code it should be called runOnce(). The reason why you're getting the depth error on saving the task is because the trigger is getting called recursively. Maybe post your class code, and I'll be able to tell what happened. If you directly copy pasted my code, you shouldn't be calling xyz.
Please double check to see if your class is saved correctly, and that all spelling is correct. The error is just saying that the method doesn't exist, so the trigger is unable to find that method for some reason. It's difficult to see your code in the screenshot, maybe just post the code as text here. Please include the class too.
Can you mark best answer so that this can help others in the future and i will be glad to answer your follow up question in another thread. It's just that your follow up question is about deployment, which is a very different topic!
Please post a new thread with your new question regarding deployment!
It looks like others beat me to the punch! Follow the change set instructions and you should be set.
Good luck!
Need your help. I need to write a test class for my trigger. Since you helped me in writing trigger and class for counting the attachments. Please advise on the test class as well.
Link for the this Query is - https://developer.salesforce.com/forums/ForumsMain?id=906F0000000g2mp
Thanks Surbhi
I tried same on a custom object and it did not allowed me to even attach file under notes and attachment system as long as Trigger was active.
Kindly help me in this case.