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
Erin Ryan 52Erin Ryan 52 

prevent deletion of Opportunity Attachments

I need to prohibit users from deleting Opportunity attachments via Notes & Attachments except system admin. I'm not a developer so any help is appreciated! Thanks so much.  
Sai PraveenSai Praveen (Salesforce Developers) 
Hi Erin,

Can you try the below trigger on ContentDocument object.
 
trigger ContentDocumentTrigger on ContentDocument (before delete) {
    
    String profileName = [select Name from profile where id = :UserInfo.getProfileId()].Name;
    
    Set<Id> DocumentId = Trigger.oldmap.keySet();
             system.debug('DocumentId ' + DocumentId);
             List<ContentDocumentLink> childObj= [SELECT Id, LinkedEntityId, ContentDocumentId FROM ContentDocumentLink  Where ContentDocumentId IN:DocumentId];
            
              Map<Id, ContentDocumentLink> childMapList = new Map<Id, ContentDocumentLink>(); 
             
             for(ContentDocumentLink ch1:childObj){
                 String Entityid=ch1.LinkedEntityId;
                 if(Entityid.startsWith('006') ){
                   childMapList.put(ch1.ContentDocumentId, ch1);    
                 }
                 
               }
             system.debug('childMapList# ' + childMapList);
             
             for(ContentDocument s1:Trigger.old){
                 if(childMapList.containsKey(s1.Id) && profileName!='System Administrator' ){
                     s1.addError('We can not delete related record!!');
                 }
             }
        
    }

If this solution helps, Please mark it as best answer.

Thanks,
​​​​​​​
CharuDuttCharuDutt
Hii Erin
Try Below Code
trigger PreventDeletionOfOppAttchMent on ContentDocument (before insert) {
    Schema.DescribeSObjectResult inv = Opportunity.sObjectType.getDescribe();
    String invKeyPrefix = inv.getKeyPrefix();
    
    List<Id> contentDocId = new List<Id>();
    Map<Id, Id> contDocLinkedMap = new Map<Id, Id>();
    if(trigger.IsDelete){
        for(ContentDocument con : Trigger.old){
            System.debug(Trigger.old);
            System.debug(con.Id);
            contentDocId.add(con.Id);
        }
        for(ContentDocumentLink cdl : [SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE ContentDocumentId IN : contentDocId]){
            contDocLinkedMap.put(cdl.ContentDocumentId, cdl.LinkedEntityId);
            System.debug('map ' +contDocLinkedMap);
        }
        for(ContentDocument cdoc : Trigger.Old){
            if(invKeyPrefix == String.valueOf(contDocLinkedMap.get(cdoc.Id)).left(3) &&
               [select Id,StageName from Opportunity where id = :contDocLinkedMap.get(cdoc.Id)].StageName =='Closed Won'){
                   cdoc.adderror('This attachment could not be added because this exception record is marked as Final.');
               }
        }   
    }
}
Please Mark It As Best Asnswrer If It Helps
Thank You!
Erin Ryan 52Erin Ryan 52
@Sai Praveen  -- 
Erin Ryan 52Erin Ryan 52
@Sai Praveen  Thanks so much and apologizes for the late response. The code works but it’s not specific to the Opportunity object. Sorry I don’t know how to tweak apex.

@CharuDutt  Thanks so much and apologizes for the late response , but the code isn 't working as expected. 

 
Sai PraveenSai Praveen (Salesforce Developers) 
Hi Erin,

If that is specific to any of your objects just replace the below line '006' with the starting of the Id of the object. Like for Account it starts with 001 and for Contacts it starts with 003
 
if(Entityid.startsWith('006') ){
Let me know if you need any further details on it.

Thanks,
 
Erin Ryan 52Erin Ryan 52
Hi Sai, sorry but non-System Administrator profiles are still able to delete opportunity attachments.