0

the requirement is when an file is added not uploaded to event that is associated with some opportunity, i want that file gets associated with opportunity as well And when we add a file "it somehow fires only contentdocumentlink only" and when we upload it contentversion triggers get fired as well. now, i need to i m wrirting a trigger on contentdocumentlink in which i am inserting the contentdocumentlink which will be associated to the opportuity of the event. when i tries to add it throws

error : : Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, Document with ID: xxx is already linked with the entity with ID: xxx:

Here is the trigger and the helper class method:

if( Trigger.isAfter && Trigger.isInsert ){
    handler.EventFileToOpportunity(Trigger.new);
}

helper

public void EventFileToOpportunity(list<ContentVersion>  contentDocumentlist){
    System.debug('contentDocumentlst>>'+contentDocumentlist);
    list<id> docids= new list<id>();
    for(ContentVersion obj:contentDocumentlist){
        docids.add(obj.ContentDocumentId);
    }
    System.debug('docids in Event>>'+docids);
    list<ContentDocumentLink> contentDocumentlst = new list<ContentDocumentLink>([SELECT LinkedEntityId,LinkedEntity.Name, ContentDocumentId FROM ContentDocumentLink WHERE ContentDocumentId IN :docids]);

    Map<String, String> contentDocumentIdsOppId = new Map<String, String>();

    set<id> eventId = new set<id>();
    for(ContentDocumentLink obj : contentDocumentlst){
        if(obj.LinkedEntityId.getSobjectType() == Event.SobjectType ){
            eventId.add(obj.LinkedEntityId);
            contentDocumentIdsOppId.put(obj.ContentDocumentId,obj.LinkedEntityId);     
        }
    }
    System.debug('contentDocumentIdsOppId in Event>>'+contentDocumentIdsOppId);
    List<event> evtlist = new list<event>([select id, WhatId from event where id IN : EventId]);

    System.debug('evtlist>>'+evtlist);
    Map<String, String> RelatedToIds = new Map<String, String>();

    set<id> setOpid = new set<id>();
    for(event evtobjt: evtlist){
        if(evtobjt.WhatId.getSobjectType() == Opportunity.SobjectType){
            setOpid.add(evtobjt.WhatId);
        }
    }

    for(event evtobj: evtlist){
        if(mapOfOppId_RecordTypeName.containskey(evtobj.WhatId)){
            //system.debug('insise loop 1');
            if(mapOfOppId_RecordTypeName.get(evtobj.WhatId) == 'DEF'){
                RelatedToIds.put(evtobj.id,evtobj.WhatId);
            }
        }  
    }

    System.debug('RelatedToIds>>'+RelatedToIds);

    List<ContentDocumentLink> cdlList = new List<ContentDocumentLink>();
    list<ContentDocument> contentDoclst = [SELECT id FROM ContentDocument WHERE Id IN : contentDocumentIdsOppId.keySet() ];

    for(ContentDocument obj : contentDoclst){
        if(RelatedToIds.containsKey(contentDocumentIdsOppId.get(obj.id)) ){
            id opId = RelatedToIds.get(contentDocumentIdsOppId.get(obj.id));

            ContentDocumentLink cdl = new ContentDocumentLink();
            cdl.ContentDocumentId = obj.id;
            cdl.LinkedEntityId = opId;
            cdl.ShareType = 'V';

            system.debug('cdl>>'+cdl);

            CdlList.add(cdl);    
        }
    }

    if(!CdlList.isEMpty()){
        system.debug('CdlList>>'+CdlList);
        insert CdlList;
    }
}

1 Answer 1

0

You should be checking to see if the ContentDocumentLink exists before you create the new instance. Adding a SOQL above the existing for loop and extending your conditional logic as shown below should work.

...

List<ContentDocumentLink> existingContentDocumentlinks = [
    select ContentDocumentId,
        LINKEDENTITYID 
    from ContentDocumentLink
    where ContentDocumentId in :contentDocumentIdsOppId.keySet()];

for (ContentDocument obj : contentDoclst) {
    if( RelatedToIds.containsKey(contentDocumentIdsOppId.get(obj.id))
            && !existingContentDocumentlinks.contains(obj.Id)) {
    ....
}

You must log in to answer this question.

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