0

I was just successfully able to implement a trigger that counts the number of files attached to my custom record (SBQQ__QuoteDocument__c) on insert with your help(thanks David Reed!) now I am hung up getting that same count to update when I delete one of the files. After some research I see that Delete Triggers only run on ContentDocument and NOT on ContentDocumentLink, so I am trying to grab a Set of ContentDocument IDs in trigger.old, then query for the ContentDocumentLinks with ContentDocumentIDs that match those in the list, then query for SBQQ__Quotedocument__c records with IDs that match the LinkedEntityId from the ContentDocumentLink records in my query. This all works but my field does not update and I am thinking this is because I am doing all of this in a BEFORE DELETE trigger, so the system does it's count before the record is deleted(obviously), but when I switch my code to an AFTER DELETE trigger, it does not have any records to store in my Sets or Lists, below is my code, thank you again in advance for all your help!

ContentDocumentTrigger

trigger ContentDocumentTrigger on ContentDocument (before delete) {

    if(trigger.isBefore){

        if(trigger.isDelete){

            ContentDocumentTriggerHandler.fileDelete();

        }

    }

}

ContentDocumentTriggerHandler

public with sharing class ContentDocumentTriggerHandler {
    public static void fileDelete(){

        System.debug('delete trigger ran');

        Set<Id> contentDocumentIDs = new Set<Id>();
        Set<Id> contentDocumentLinkIDs = new Set<Id>();

        for(ContentDocument cd : (List<ContentDocument>) Trigger.old){

            contentDocumentIDs.add(cd.Id);

        }

        System.debug('contentDocumentIDs: ' + contentDocumentIDs);
        System.debug('contentDocumentIDs.size(): ' + contentDocumentIDs.size());

        List<ContentDocumentLink> contentDocumentLinks = new List<ContentDocumentLink>(
                                                    [SELECT Id, LinkedEntityId
                                                    FROM ContentDocumentLink
                                                    WHERE ContentDocumentId IN :contentDocumentIDs
                                                    ]);

        System.debug('contentDocumentLinkIDs: ' + contentDocumentLinks);
        System.debug('contentDocumentLinkIDs.size(): ' + contentDocumentLinks.size()); 
        
        Set<Id> parentQuoteDocumentIds = new Set<Id>();

        for(ContentDocumentLink cdl : contentDocumentLinks){

             parentQuoteDocumentIds.add(cdl.LinkedEntityId);

        }

        System.debug('parentQuoteDocumentIds: ' + parentQuoteDocumentIds);
        System.debug('parentQuoteDocumentIds.size(): ' + parentQuoteDocumentIds.size()); 

        List<SBQQ__QuoteDocument__c> quoteDocList = [
                                                    SELECT Id, 
                                                    (SELECT Id FROM ContentDocumentLinks)
                                                    FROM SBQQ__QuoteDocument__c
                                                    WHERE Id IN :parentQuoteDocumentIds];

        System.debug('quoteDocList: ' + quoteDocList);
        System.debug('quoteDocList.size(): ' + quoteDocList.size()); 


        for(SBQQ__QuoteDocument__c qd : quoteDocList){

            qd.Number_of_Files_Attached__c = qd.ContentDocumentLinks.size();

        }

        update quoteDocList;

    }
}

again, my debug logs seem to indicate that it is finding the correct records, just seems to me they are not updating the field on SBQQ__QuoteDocument__c(Number_of_Files_Attached__c) at the right time.

1

Future methods were the answer

ContentDocumentTriggerHandler

public with sharing class ContentDocumentTriggerHandler {

    public static void handleBeforeDelete(){

        fileDelete();

    }

    public static void fileDelete(){

        Set<Id> contentDocumentIDs = new Set<Id>();

        for(ContentDocument cd : (List<ContentDocument>) Trigger.old){

            contentDocumentIDs.add(cd.Id);

        }

        System.debug('contentDocumentIDs: ' + contentDocumentIDs);
        System.debug('contentDocumentIDs.size(): ' + contentDocumentIDs.size());

        List<ContentDocumentLink> contentDocumentLinks = new List<ContentDocumentLink>(
                                                    [SELECT Id, LinkedEntityId
                                                    FROM ContentDocumentLink
                                                    WHERE ContentDocumentId IN :contentDocumentIDs
                                                    ]);
        
        Set<Id> parentQuoteDocumentIds = new Set<Id>();

        for(ContentDocumentLink cdl : contentDocumentLinks){

             parentQuoteDocumentIds.add(cdl.LinkedEntityId);

        }
        updateQuoteDocumentFileCount(parentQuoteDocumentIds);
    }

        @future
        public static void updateQuoteDocumentFileCount(set<Id> parentQuoteDocumentIds){

            System.debug('parentQuoteDocumentIds: ' + parentQuoteDocumentIds);
            System.debug('parentQuoteDocumentIds.size(): ' + parentQuoteDocumentIds.size()); 
    
            List<SBQQ__QuoteDocument__c> quoteDocList = [
                                                        SELECT Id, 
                                                        (SELECT Id FROM ContentDocumentLinks)
                                                        FROM SBQQ__QuoteDocument__c
                                                        WHERE Id IN :parentQuoteDocumentIds];
    
            System.debug('quoteDocList: ' + quoteDocList);
            System.debug('quoteDocList.size(): ' + quoteDocList.size()); 
    
    
            for(SBQQ__QuoteDocument__c qd : quoteDocList){
    
                qd.Number_of_Files_Attached__c = qd.ContentDocumentLinks.size();
    
            }
    
            update quoteDocList;
    
        }
    }

ContentDocumentTrigger

trigger ContentDocumentTrigger on ContentDocument (before delete) {

    if(trigger.isBefore){

        if(trigger.isDelete){

            ContentDocumentTriggerHandler.handleBeforeDelete();

        }

    }

}
1
  • Can you please share how you wrote the test class for the future method? – user81642 Apr 15 at 4:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.