Salesforce’s Note object is being superseded by its ContentNote object. A limitation of the newer notes is that they don’t automatically roll up under the associated account when added to contacts and opportunities.
Here is some code I’ve written to solve this (also includes case notes):
Apex Trigger
trigger ContentDocumentLinkTrigger on ContentDocumentLink (after insert) { Set<ID> ids = Trigger.newMap.keySet(); List <ContentDocumentLink> docLinks = [SELECT LinkedEntityId,ContentDocumentId,ContentDocument.FileType FROM ContentDocumentLink WHERE Id IN: ids]; for (ContentDocumentLink docLink : docLinks) { if (docLink.ContentDocument.FileType == 'SNOTE'){ String linkedId = docLink.LinkedEntityId; if(!linkedId.startsWith('001') && !linkedId.startsWith('005')){ String sNoteId = docLink.ContentDocumentId; NoteLinkHelper.linkToAcct(sNoteId,linkedId); } } } }
Apex Class
public class NoteLinkHelper { //helper method to get account ID related to non-account record from which note was created public static String getLinkedEntityAccount(String noteId, String linkedId) { String acctId; if (linkedId.startsWith('003')){ List<Contact> contacts = [SELECT AccountId FROM Contact WHERE Id =: linkedId]; if (!contacts.isEmpty()){ if (contacts[0].AccountId != null) { acctId = contacts[0].AccountId; } } } else if (linkedId.startsWith('006')){ List<Opportunity> opps = [SELECT AccountId FROM Opportunity WHERE Id =: linkedId]; if (!opps.isEmpty()){ if (opps[0].AccountId != null) { acctId = opps[0].AccountId; } } } else if (linkedId.startsWith('500')){ List<Case> cases = [SELECT AccountId FROM Case WHERE Id =: linkedId]; if (!cases.isEmpty()){ if (cases[0].AccountId != null) { acctId = cases[0].AccountId; } } } return acctId; } //helper method to link note to an account public static void linkToAcct(String sNoteId,String linkedId) { String acctToLink = getLinkedEntityAccount(sNoteId,linkedId); if (acctToLink != null) { ContentDocumentLink sNoteLink = new ContentDocumentLink(); sNoteLink.ContentDocumentId = sNoteId; sNoteLink.LinkedEntityId = acctToLink; sNoteLink.ShareType = 'V'; insert(sNoteLink); } } }
I hope this helps your users get a more comprehensive view of their accounts.
That looks great, don’t suppose you have the test class as well? 🙂
LikeLike
Hello, verry good stuff… help me too much.
But have some question. I Try to get Title and Note TextPreview (from contentNote) value to store in custom object, I can’t. Some time the title is trunced and TextPreview is alway null.How could I Fixe that
Tks
LikeLiked by 1 person
Hi, DJO. Please see if these two sites help solve your problem:
https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentnote.htm
https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentversion.htm
LikeLike