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.
ContentDocument object is to retrieve, query, update, and delete the latest version of a document, but not a content pack, in a library or a file in Chatter.
Use the ContentVersion object to create, query, retrieve, search, edit, and update a specific version of a Salesforce CRM Content document or Chatter file.
Use the ContentVersion object to create, query, retrieve, search, edit, and update a specific version of a Salesforce CRM Content document or Chatter file.
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 !!!
Thank you.Well it was nice post and very helpful information on salesforce Online course Hyderabad
ReplyDeleteArtcile was simply superb salesforce Online course Hyderabad
ReplyDeleteThank you for your code. Something strange for me, a user can delete the file if he goes on file details page ?
ReplyDeleteThen, do you have the test classes for your code ?
with this code i am able restrict edit/delete. need help on how i can allow user to create a new file.
ReplyDeleteI really like and appreciate your post.Really thank you! Fantastic.
ReplyDeletesalesforce online training in hyderabad
salesforce online training hyderabad
gebze
ReplyDeletetrabzon
kütahya
burdur
çorlu
1L6İ4
ıldır transfer
ReplyDeletegüzelbahçe transfer
foça transfer
mordoğan transfer
aliağa transfer
OOFT