I would like to delete attachments from case object whenever the case closed date is more than 30 days

So I have created a custom field in a case called Closed30days(checkbox) whenever the closing date is more than 30 days this checkbox will get updated.

But now I am stuck with trigger part

How can I write a trigger to delete attachments from the case whenever this Closed30day Checkbox field is updated and also once the attachment is deleted I would like to get a comment in the case record that attachments are deleted.

Can anyone please help me on this.

2 Answers 2


Please refer the below code :

Explanation : Here My_Demo_ChkBx__c is ur check box which is getting updated once 30 days has passed. The query is getting the attachments related to case object that has being closed 30 earlier.

trigger DeleteAttmt_After30DClose on Case (Before Update,After Update) {
 public Set<Id> CaseSetId = new Set<Id>();
 List<Case> csToUpdt = new List<Case>();

 //Section used to update the description as 'Attachment is deleted'
 if(Trigger.isBefore && Trigger.isUpdate){
     for(Case cs:Trigger.New){ 
         if(cs.My_Demo_ChkBx__c== True){
             cs.Description = 'Attachment is deleted';

 if(Trigger.isAfter && Trigger.isUpdate){
    for(Case cs:Trigger.New){ 
        if(cs.My_Demo_ChkBx__c== True){
        List<Attachment> casAttmtList = [SELECT Id,ParentId FROM Attachment WHERE ParentId in: CaseSetId];
        delete casAttmtList;

        List<CaseComment> childCommand = new List<CaseComment>();// Forming case comment list.              
        for(Id cseID:CaseSetId){
            CaseComment newCommmand = new CaseComment();
            newCommmand.CommentBody = 'Attachment is deleted';
            newCommmand.IsPublished = TRUE;
            newCommmand.ParentId = cseID;
            insert childCommand;


WE also need to write the scheduler class . This scheduler class will help to check the checkbox "My_Demo_ChkBx__c" to true once the desired day (here 30 days) has passed after the case is Closed. Once the check box is checked the Trigger will do its task : deleting the attachment and do case comment.

Schdeuler Class:

global class CaseClsAge_Scheduled Implements Schedulable{
        global void execute(SchedulableContext sc){

        public void chkCLoseAge(){
            List<Case> listCases = new List<Case>();
            listCases = [SELECT ID,My_Demo_ChkBx__c,ClosedDate FROM Case WHERE Status = 'Closed' and My_Demo_ChkBx__c = False];
            List<Case> lstCaseToUpadte = new List<Case>();
            for(Case cc : listCases)
                integer intDays =  cc.ClosedDate.Date().daysBetween(system.now().Date());
                if(intDays > 1){
                    cc.My_Demo_ChkBx__c = True;
                update lstCaseToUpadte;

PS: This need to be schedule afterwards you can go to Setup > Build > Develop > Apex Classes and then press on the 'Schedule Apex' to set up your class.

enter image description here

  • The Code removes an attachments, but when ever the attachment is deleted i should generate a comment in comment section that attachment is deleted. May 19, 2017 at 10:48
  • @user3585019 ...Modified the code based on your comment May 19, 2017 at 11:11
  • @ParthaSarathiMandal They wanted to add a case comment, not modify the description. You can do all of this "after update" instead of splitting the trigger.
    – sfdcfox
    May 19, 2017 at 11:51
  • @sfdcfox .... I have updated the code based on your feedback. Currently the trigger will also provide case comment along with deletion of attachment. @user3585019 ... please discard the beforeUpdate module if you don`t need to change the description. May 21, 2017 at 5:16
  • @Partha - thanks for helping me in trigger, i was thinking rather than going for batch apex to check the checkbox, cant we go for workflow rule? May 23, 2017 at 5:57

Better go with batch class insted of trigger. Here sample code for batch class, refer it.

global class DeleteAttachmentScheduleClass implements Schedulable{
public String  accstr1;
public String  accstr2;
public list<Account> acclist1 { get; set; }
public list<Account> acclist2 { get; set; }
public list<Account> acclistall { get; set; }
public Set<Id> setAttachmetIds{ get; set; }
public String  query;    

global void execute(SchedulableContext sc){   
     acclist1 = new list<Account>();
     acclist2 = new list<Account>();
     acclistall = new list<Account>();

//Custom Settins
    AccountSetting__c ecs =AccountSetting__c.getInstance();
    integer read=integer.valueOf(ecs.Read__c); // Read__c = 10
    integer unread=integer.valueOf(ecs.Unread__c); //Unread__c = 20

    accstr1='select id,name,is_read__c,(select id from Attachments where createddate < last_n_days :'+unread+') from Account where is_read__C = false';
    accstr2='select id,name,is_read__c,(select id from Attachments where createddate < last_n_days :'+read+') from Account where is_read__C = true';

    acclist1 = database.query(accstr1);
    acclist2 = database.query(accstr2);
    for (Account objAccount:acclistall) {
        if (objAccount.attachments != null && objAccount.attachments.size() > 0) {
            for (Attachment objAttachment:objAccount.attachments) {


    query = 'select id from attachment where id in :setAttachmetIds';

    list<Attachment> attlist = database.query(query);
    if(attlist != null){
            DeleteAttachmentsBatchClass delBatch = new DeleteAttachmentsBatchClass(query);
            Id BatchProcessId = Database.ExecuteBatch(delBatch);
      }catch(Exception e){



  • 1
    +1 for the idea, -1 for the actual code example. It's not related to cases, as the OP asked, is not optimized, likely to crash because of governor limits, etc. There's much better ways of writing this.
    – sfdcfox
    May 19, 2017 at 11:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .