Salesforce: Restrict User from Deleting Files Once Record Status Changed
Business Requirement:
There is a custom object in Salesforce having a status field. If the status of that record is marked as "Completed" user is not allowed to attach/upload new files with it, nor user can upload new version of file nor he can delete file.
Solution:
On the front end we see Files object ,its related list and tab and in my requirement data is saved from front end in files. From back-end Salesforce use 3 diffrent object.
So in order to achieve this functionality we have to write trigger on all three objects.
Content Document Trigger:
trigger ContentDocumentTrg on ContentDocument (before delete,before update) {
Map<Id,String> MapOfStatus = new Map<Id,String>();
Set<Id> SetOfCdl = new Set<Id>();
Set<Id> SetOfCd = new Set<Id>();
map<Id,Id> MapOfCdNCdl = new map<Id,Id>();
if(Trigger.IsUpdate){
for(ContentDocument cd :Trigger.new){
SetOfCd.add(cd.Id);
}
}
if(Trigger.Isdelete){
for(ContentDocument cd :Trigger.old){
SetOfCd.add(cd.Id);
}
}
for(ContentDocumentLink cdl : [SELECT LinkedEntityId,ContentDocumentId FROM ContentDocumentLink WHERE ContentDocumentId IN:SetOfCd]){
string cdlentityId = cdl.LinkedEntityId;
if (cdlentityId.substring(0,3) == 'a0h') {
SetOfCdl.add(cdl.LinkedEntityId);
MapOfCdNCdl.put(cdl.ContentDocumentId, cdl.LinkedEntityId);
}
}
MapOfStatus = ContectDocLinkHandler.CheckStatus(SetOfCdl);
if(Trigger.IsUpdate){
for(ContentDocument cd :Trigger.new){
Id cdlId = MapOfCdNCdl.get(cd.Id);
if(MapOfStatus.get(cdlId) == 'Completed'){
cd.addError('Sorry you cannot add/update this file.');
}
}
}
if(Trigger.Isdelete){
for(ContentDocument cd :Trigger.old){
Id cdlId = MapOfCdNCdl.get(cd.Id);
if(MapOfStatus.get(cdlId) == 'Completed'){
cd.addError('Sorry you cannot delete this file.');
}
}
}
}
Map<Id,String> MapOfStatus = new Map<Id,String>();
Set<Id> SetOfCdl = new Set<Id>();
Set<Id> SetOfCd = new Set<Id>();
map<Id,Id> MapOfCdNCdl = new map<Id,Id>();
if(Trigger.IsUpdate){
for(ContentDocument cd :Trigger.new){
SetOfCd.add(cd.Id);
}
}
if(Trigger.Isdelete){
for(ContentDocument cd :Trigger.old){
SetOfCd.add(cd.Id);
}
}
for(ContentDocumentLink cdl : [SELECT LinkedEntityId,ContentDocumentId FROM ContentDocumentLink WHERE ContentDocumentId IN:SetOfCd]){
string cdlentityId = cdl.LinkedEntityId;
if (cdlentityId.substring(0,3) == 'a0h') {
SetOfCdl.add(cdl.LinkedEntityId);
MapOfCdNCdl.put(cdl.ContentDocumentId, cdl.LinkedEntityId);
}
}
MapOfStatus = ContectDocLinkHandler.CheckStatus(SetOfCdl);
if(Trigger.IsUpdate){
for(ContentDocument cd :Trigger.new){
Id cdlId = MapOfCdNCdl.get(cd.Id);
if(MapOfStatus.get(cdlId) == 'Completed'){
cd.addError('Sorry you cannot add/update this file.');
}
}
}
if(Trigger.Isdelete){
for(ContentDocument cd :Trigger.old){
Id cdlId = MapOfCdNCdl.get(cd.Id);
if(MapOfStatus.get(cdlId) == 'Completed'){
cd.addError('Sorry you cannot delete this file.');
}
}
}
}
Content Version Trigger
trigger ContentVersionTrg on ContentVersion (before update) {
if(Trigger.IsBefore && (Trigger.IsInsert || Trigger.IsUpdate)){
Map<Id,String> MapOfStatus = new Map<Id,String>();
Set<Id> SetOfCdl = new Set<Id>();
Set<Id> SetOfCd = new Set<Id>();
map<Id,Id> MapOfCdNCdl = new map<Id,Id>();
for(ContentVersion cv :Trigger.new){
SetOfCd.add(cv.ContentDocumentId);
}
system.debug('Set Of Content Doc'+SetOfCd);
for(ContentDocumentLink cdl : [SELECT LinkedEntityId,ContentDocumentId FROM ContentDocumentLink WHERE ContentDocumentId IN:SetOfCd]){
string cdlentityId = cdl.LinkedEntityId;
//Hard coding start 3 character of my custom object
if (cdlentityId.substring(0,3) == 'a0h') {
SetOfCdl.add(cdl.LinkedEntityId);
MapOfCdNCdl.put(cdl.ContentDocumentId, cdl.LinkedEntityId);
}
}
MapOfStatus = ContectDocLinkHandler.CheckStatus(SetOfCdl);
for(ContentVersion cv :Trigger.new){
Id cdlId = MapOfCdNCdl.get(cv.ContentDocumentId);
if(MapOfStatus.get(cdlId) == 'Completed'){
cv.addError('Sorry you cannot add/update this file');
}
}
}
}
Content Document Link Trigger:
trigger ContectDocLinkTrg on ContentDocumentLink (before delete,before update) {
set<Id> SetOfCdlLinkId = new set<Id>();
map <Id,String> MapOfStatus = new map<Id,String>();
for(ContentDocumentLink cdl :Trigger.old){
SetOfCdlLinkId.add(cdl.LinkedEntityId);
}
MapOfStatus = ContectDocLinkHandler.CheckStatus(SetOfCdlLinkId);
for(ContentDocumentLink cdl :Trigger.old){
if(MapOfStatus.get(cdl.LinkedEntityId) == 'Completed'){
cdl.addError('Sorry you cannot delete this file');
}
}
}
Content Document Link Handler :
public without sharing class ContectDocLinkHandler {
// function used to check status of Jira Issue object as complete
public Static Map<Id,String> CheckStatus(set<Id> SetOfCdl)
{
map <Id,String> MapOfJIStatus = new map<Id,String>();
if(SetOfCdl.size() > 0){
for(Jira_Issues__c js : [select Id, Status__c from Jira_Issues__c where Id IN: SetOfCdl]){
MapOfJIStatus.put(js.Id, js.Status__c);
}
}
return MapOfJIStatus;
}
}
Happy Coding !!!
Use the ContentVersion object to create, query, retrieve, search, edit, and update a specific version of a Salesforce CRM Content document or Chatter file.