Create T4S Trim Records Programaticly

If you do not want T4S to automatically create new Trim Records for each configured sObject that has been configured, you are able to write your own custom code to achieve this.

Below is an example of creating new Trim Records when a new ContentDocument and its related ContentDocumentLink have been created.

 

ContentDocumentLink Trigger

/***************************** * Class : ContentDocumentLinkTrigger * Created By : FuseIT ----------------------------------------------------------------------------------- * Description : After a Salesforce ContentDocument has been uploaded and custom metadata setting has OPSWAT package disabled. * check if it should be saved as a Trim Record and sent to TRIM Server ----------------------------------------------------------------------------------- * ****************************/ trigger ContentDocumentLinkTrigger on ContentDocumentLink (after insert, after update) { if(Trigger.isAfter && Trigger.isInsert) { ContentDocumentLinkHelper.onAfterInsert(Trigger.new); } }

 

Helper class.
In this example, there have been some custom text fields added to the Account object and Case object to keep track of the TRIM Container Unique Identifier, Container name, and Container title, that had been created for the Salesforce record.
e.g. Account “Trim_URI__c“, “Trim_Record_Number__c“, “Trim_Container_Name__c

 

/***************************** * Class : ContentDocumentLinkHelper * Created By : FuseIT ----------------------------------------------------------------------------------- * @description : Utility Class for ContentDocumentVersion and ContentDocumentLink TRIM interaction ----------------------------------------------------------------------------------- * ****************************/ public without sharing class ContentDocumentLinkHelper { static final String prefixAccount = '001'; static final String prefixCase = '500'; static final String defaultDocumentType = 'Document'; /***************************** * @method : onAfterInsert * @description : Check if trigger is enabled and if it should call method to create new Trim Records * @param newLinks ****************************/ public static void onAfterInsert(List<ContentDocumentLink> newLinks) { //Is T4S enabled, and is the Auto Add Files disabled for this code to run. if (fuseit_t4s.TrimCustomSettingHelper.isTriggerEnabled && !fuseit_t4s.TrimCustomSettingHelper.isTriggerAutoAddEnabled) { linkAfterUpdateCreateTrimRecords(newLinks); } } /***************************** * @method : onAfterTrimRecordInsert * @description : Check if trigger is enabled and if it should call method to create related Trim Records * @param newRelations ****************************/ public static void onAfterTrimRecordInsert(List<fuseit_t4s__Trim_Record__c> newTrimRecords) { linkAfterTrimRecordInsert(newTrimRecords); } /***************************** * @method : linkAfterUpdateCreateTrimRecords * @description : Loop through list and map the ContentDocumentId with the ContentDocumentLinks * @param newDocumentLinkMap ****************************/ private static void linkAfterUpdateCreateTrimRecords(List<ContentDocumentLink> newDocumentLinkMap) { String trimRecordPrefix = fuseit_t4s__Trim_Record__c.fuseit_t4s__Trim_Record_Type__c.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).getKeyPrefix(); Map<Id, ContentDocumentLink> mapDocumentLinks = new Map<Id, ContentDocumentLink>(); Map<Id, Id> mapUpdateRecords = new Map<Id, Id>(); String parentId = ''; //System.debug('---------------- Debug --------- LinkAfterUpdateCreatTrimRecords() newDocumentLinkMap.size()= ' + newDocumentLinkMap.size()); for(ContentDocumentLink link : newDocumentLinkMap) { parentId = link.LinkedEntityId; if((parentId.startsWith(prefixAccount) || parentId.startsWith(prefixCase)) && !mapDocumentLinks.containsKey(link.ContentDocumentId)) { mapDocumentLinks.put(link.ContentDocumentId, link); } else if(parentId.startsWith(trimRecordPrefix) && !mapUpdateRecords.containsKey(link.ContentDocumentId)) { mapUpdateRecords.put(link.ContentDocumentId, link.LinkedEntityId); } } // System.debug('---------------- Debug --------- LinkAfterUpdateCreatTrimRecords() mapDocumentLinks.size()= ' + mapDocumentLinks.size()); if(mapDocumentLinks.size() > 0) { queryContentDocuments(mapDocumentLinks); } if(mapUpdateRecords.size() > 0) { queryTrimRecords(mapUpdateRecords); } } /***************************** * @method : queryContentDocuments * @description : reated for new ContentDocumentLink records. Only create Trim Records for Person Account and Cases * @param mapDocumentLinks ****************************/ private static void queryContentDocuments(Map<Id, ContentDocumentLink> mapDocumentLinks) { Map<Id, ContentDocumentLink> mapAccountLinks = new Map<Id, ContentDocumentLink>(); Map<Id, ContentDocumentLink> mapCaseLinks = new Map<Id, ContentDocumentLink>(); Set<Id> accountIds = new Set<Id>(); Set<Id> caseIds = new Set<Id>(); String parentId = ''; //Loop and only get Attachments for Accounts for(ContentDocumentLink c : mapDocumentLinks.values()) { parentId = c.LinkedEntityId; if(parentId.indexOf(prefixAccount) == 0) { mapAccountLinks.put(c.ContentDocumentId, c); if(!accountIds.contains(parentId)) { accountIds.add(parentId); //Add Account ID only once } } if(parentId.indexOf(prefixCase) == 0) { mapCaseLinks.put(c.ContentDocumentId, c); if(!caseIds.contains(parentId)) { caseIds.add(parentId); //Add Case ID only once } } } if(accountIds.size() > 0) { processAccountLinks(accountIds, mapAccountLinks); } if(caseIds.size() > 0) { processCaseLinks(caseIds, mapCaseLinks); } } /***************************** * @method : processAccountLinks * @description : Create new T4S Trim Records for all ContentDocuments that match the configured Account Record Types * @param accountIds * @param mapAccountLinks ****************************/ private static void processAccountLinks(Set<Id> accountIds, Map<Id, ContentDocumentLink> mapAccountLinks) { Map<Id, Boolean> mapRecordTypes = new Map<Id, Boolean>(); List<fuseit_t4s__Trim_Record__c> newRecords = new List<fuseit_t4s__Trim_Record__c>(); String recordName = ''; Id trimID = null; List<fuseit_t4s__Trim_Setting_RecordType__c> settings = [Select Id, fuseit_t4s__Trim_Setting__c, fuseit_t4s__RecordTypeId__c, fuseit_t4s__Trim_Setting__r.fuseit_t4s__Auto_Delete_Attachment__c, fuseit_t4s__Trim_Setting__r.fuseit_t4s__Trim_Server__c from fuseit_t4s__Trim_Setting_RecordType__c Where fuseit_t4s__Trim_Setting__r.fuseit_t4s__sObject_Prefix__c =: prefixAccount WITH SECURITY_ENFORCED]; for(fuseit_t4s__Trim_Setting_RecordType__c setting : settings) { mapRecordTypes.put(setting.fuseit_t4s__RecordTypeId__c, setting.fuseit_t4s__Trim_Setting__r.fuseit_t4s__Auto_Delete_Attachment__c); if(trimID == null) { trimID = setting.fuseit_t4s__Trim_Setting__r.fuseit_t4s__Trim_Server__c; } } Map<Id,Account> accounts = new Map<Id, Account>([SELECT Id, RecordTypeId, Trim_URI__c, Trim_Record_Number__c, Trim_Container_Name__c FROM Account Where Id in: accountIds And RecordTypeId in: mapRecordTypes.keySet() WITH SECURITY_ENFORCED LIMIT 5000]); Set<Id> fileIds = mapAccountLinks.keySet(); Map<Id, ContentVersion> files = new Map<Id, ContentVersion>(); for(ContentVersion c : [Select Id, CreatedDate, ContentDocumentId, Title, FileExtension, ContentSize, ContentDocument.CreatedById From ContentVersion Where ContentDocumentId in: fileIds And IsLatest = true WITH SECURITY_ENFORCED]) { files.put(c.ContentDocumentId, c); } Account acc = null; Boolean isToBeDeleted = false; for(ContentDocumentLink documentLink : mapAccountLinks.values()) { //Is the Account one of the assigned Record Types if(accounts.containsKey(documentLink.LinkedEntityId)) { acc = accounts.get(documentLink.LinkedEntityId); //Get the title from the ContentVersion recordName = files.get(documentLink.ContentDocumentId).Title; //Create a new Trim Record for this Attachment. fuseit_t4s__Trim_Record__c record = new fuseit_t4s__Trim_Record__c(); record.Name = fuseit_t4s.TrimConnector.getFileName(recordName, 80, fuseit_t4s.TrimCustomSettingHelper.getRecordNameRegEx); record.fuseit_t4s__Attachment_ID__c = files.get(documentLink.ContentDocumentId).Id; record.fuseit_t4s__Attachment_Name__c = fuseit_t4s.TrimConnector.getFileName(recordName, 255, fuseit_t4s.TrimCustomSettingHelper.getRecordNameRegEx); record.fuseit_t4s__Attachment_Type__c = 'File'; record.fuseit_t4s__File_Extension__c = '.' + files.get(documentLink.ContentDocumentId).FileExtension; record.fuseit_t4s__Parent_ID__c = documentLink.LinkedEntityId; record.fuseit_t4s__Trim_ID__c = trimID; record.fuseit_t4s__Trim_Status__c = 'Scheduled'; record.fuseit_t4s__Trim_Record_Type__c = defaultDocumentType; record.fuseit_t4s__ContentDocumentId__c = documentLink.ContentDocumentId; record.fuseit_t4s__File_CreatedDate__c = files.get(documentLink.ContentDocumentId).CreatedDate; record.fuseit_t4s__File_ContentSize__c = files.get(documentLink.ContentDocumentId).ContentSize; record.fuseit_t4s__File_CreatedById__c = files.get(documentLink.ContentDocumentId).ContentDocument.CreatedById; if(String.isNotBlank(acc.Trim_URI__c)) { record.fuseit_t4s__Trim_Location_ID__c = acc.Trim_URI__c; } if(String.isNotBlank(acc.Trim_Record_Number__c)) { record.fuseit_t4s__Trim_Container_Record_Number__c = acc.Trim_Record_Number__c; } if(String.isNotBlank(acc.Trim_Container_Name__c)) { record.fuseit_t4s__Trim_Container_Title__c = acc.Trim_Container_Name__c; } //Mark isLinkRecord__c true if setting has auto delete attachment after //the Record has been synced with TRIM isToBeDeleted = mapRecordTypes.get(acc.RecordTypeId); if(isToBeDeleted) { record.fuseit_t4s__isLinkRecord__c = true; } newRecords.add(record); } }// end of for if(newRecords.size() > 0 && Schema.sObjectType.fuseit_t4s__Trim_Record__c.isCreateable()) { insert newRecords; } } /***************************** * @method : processCaseLinks * @description : Create new T4S Trim Records for all ContentDocuments that are linked to a Case * @param caseIds * @param mapCaseLinks ****************************/ private static void processCaseLinks(Set<Id> caseIds, Map<Id, ContentDocumentLink> mapCaseLinks) { List<fuseit_t4s__Trim_Record__c> newRecords = new List<fuseit_t4s__Trim_Record__c>(); fuseit_t4s__Trim_Setting__c setting; String recordName = ''; List<fuseit_t4s__Trim_Setting__c> settings = [Select Id, fuseit_t4s__Auto_Delete_Attachment__c, fuseit_t4s__Trim_Server__c, fuseit_t4s__Trim_Container_Uri__c From fuseit_t4s__Trim_Setting__c Where fuseit_t4s__sObject_Prefix__c =: prefixCase WITH SECURITY_ENFORCED]; if(!settings.isEmpty()) { setting = settings[0]; } else { return; } Map<Id,Case> cases = new Map<Id, Case>([SELECT Id, CaseNumber, Trim_URI__c, Trim_Record_Number__c, Trim_Container_Name__c FROM Case Where Id in: caseIds WITH SECURITY_ENFORCED LIMIT 5000]); Set<Id> fileIds = mapCaseLinks.keySet(); Map<Id, ContentVersion> files = new Map<Id, ContentVersion>(); for(ContentVersion c : [Select Id, CreatedDate, ContentDocumentId, Title, FileExtension, ContentSize, ContentDocument.CreatedById From ContentVersion Where ContentDocumentId in: fileIds And IsLatest = true WITH SECURITY_ENFORCED]) { files.put(c.ContentDocumentId, c); } Case c = null; for(ContentDocumentLink documentLink : mapCaseLinks.values()) { //Is the Account one of the assigned Record Types if(cases.containsKey(documentLink.LinkedEntityId)) { c = cases.get(documentLink.LinkedEntityId); //Get the title from the ContentVersion recordName = files.get(documentLink.ContentDocumentId).Title; //Create a new Trim Record for this Attachment. fuseit_t4s__Trim_Record__c record = new fuseit_t4s__Trim_Record__c(); record.Name = fuseit_t4s.TrimConnector.getFileName(recordName, 80, fuseit_t4s.TrimCustomSettingHelper.getRecordNameRegEx); record.fuseit_t4s__Attachment_ID__c = files.get(documentLink.ContentDocumentId).Id; record.fuseit_t4s__Attachment_Name__c = fuseit_t4s.TrimConnector.getFileName(recordName, 255, fuseit_t4s.TrimCustomSettingHelper.getRecordNameRegEx); record.fuseit_t4s__Attachment_Type__c = 'File'; record.fuseit_t4s__File_Extension__c = '.' + files.get(documentLink.ContentDocumentId).FileExtension; record.fuseit_t4s__Parent_ID__c = documentLink.LinkedEntityId; record.fuseit_t4s__Trim_ID__c = setting.fuseit_t4s__Trim_Server__c; record.fuseit_t4s__Trim_Status__c = 'Scheduled'; record.fuseit_t4s__Trim_Record_Type__c = defaultDocumentType; record.fuseit_t4s__ContentDocumentId__c = documentLink.ContentDocumentId; record.fuseit_t4s__File_CreatedDate__c = files.get(documentLink.ContentDocumentId).CreatedDate; record.fuseit_t4s__File_ContentSize__c = files.get(documentLink.ContentDocumentId).ContentSize; record.fuseit_t4s__File_CreatedById__c = files.get(documentLink.ContentDocumentId).ContentDocument.CreatedById; if(String.isNotBlank(c.Trim_URI__c)) { record.fuseit_t4s__Trim_Location_ID__c = c.Trim_URI__c; } else { record.fuseit_t4s__Trim_Location_ID__c = setting.fuseit_t4s__Trim_Container_Uri__c; } if(String.isNotBlank(c.Trim_Record_Number__c)) { record.fuseit_t4s__Trim_Container_Record_Number__c = c.Trim_Record_Number__c; } if(String.isNotBlank(c.Trim_Container_Name__c)) { record.fuseit_t4s__Trim_Container_Title__c = c.Trim_Container_Name__c; } //Mark isLinkRecord__c true if setting has auto delete attachment after //the Record has been synced with TRIM if(setting.fuseit_t4s__Auto_Delete_Attachment__c) { record.fuseit_t4s__isLinkRecord__c = true; } newRecords.add(record); } }// end of for if(newRecords.size() > 0 && Schema.sObjectType.fuseit_t4s__Trim_Record__c.isCreateable()) { insert newRecords; } } /***************************** * @method : queryTrimRecords * @description : Update any existing TrimRecords when new ContentDocuments are added as an update * @param mapUpdateRecords ****************************/ private static void queryTrimRecords(Map<Id, Id> mapUpdateRecords) { List<fuseit_t4s__Trim_Record__c> updateRecords = new List<fuseit_t4s__Trim_Record__c>(); fuseit_t4s__Trim_Record__c record; Id recId; if(mapUpdateRecords.size() > 0) { List<Id> recordIds = mapUpdateRecords.values(); Map<ID, fuseit_t4s__Trim_Record__c> mapRecords = new Map<ID, fuseit_t4s__Trim_Record__c>([Select Id, fuseit_t4s__Attachment_ID__c, fuseit_t4s__Attachment_Name__c, fuseit_t4s__Attachment_Type__c, fuseit_t4s__Trim_Status__c, fuseit_t4s__ContentDocumentId__c from fuseit_t4s__Trim_Record__c Where Id in: recordIds WITH SECURITY_ENFORCED limit 1000]); if(mapRecords.size() > 0) { for(Id docId : mapUpdateRecords.keySet()) { recId = mapUpdateRecords.get(docId); if(mapRecords.containsKey(recId)) { record = mapRecords.get(recId); record.fuseit_t4s__ContentDocumentId__c = docId; record.fuseit_t4s__Attachment_Type__c = 'File'; record.fuseit_t4s__Trim_Status__c = 'Scheduled'; updateRecords.add(record); } } if(updateRecords.size() > 0) { if (Schema.sObjectType.fuseit_t4s__Trim_Record__c.isUpdateable()){ update updateRecords; } } } } } /***************************** * @method : linkAfterRelatedCaseInsert * @description : Create fuseit_t4s__Trim_Record_Link__c links between child and parent Case Trim Records * @param mapUpdateRecords ****************************/ private static void linkAfterTrimRecordInsert(List<fuseit_t4s__Trim_Record__c> newTrimRecords) { List<fuseit_t4s__Trim_Record_Link__c> links = new List<fuseit_t4s__Trim_Record_Link__c>(); Map<Id, Id> mapCaseTrimRecords = new Map<Id, Id>(); for(fuseit_t4s__Trim_Record__c r : newTrimRecords) { if(r.fuseit_t4s__Parent_ID__c.startsWith('500') && !mapCaseTrimRecords.containsKey(r.fuseit_t4s__Parent_ID__c)) { mapCaseTrimRecords.put(r.fuseit_t4s__Parent_ID__c, r.Id); } } if(!mapCaseTrimRecords.isEmpty()) { List<RelatedCase__c> childCases = [Select Id, Name, RelatedFrom__c, RelatedTo__c, Is_Child_Case__c From RelatedCase__c Where RelatedTo__c in: mapCaseTrimRecords.keySet() WITH SECURITY_ENFORCED]; for(RelatedCase__c child : childCases) { fuseit_t4s__Trim_Record_Link__c newLink = new fuseit_t4s__Trim_Record_Link__c(); newLink.fuseit_t4s__LinkedEntityId__c = child.RelatedFrom__c; newLink.fuseit_t4s__Trim_Record__c = mapCaseTrimRecords.get(child.RelatedTo__c); newLink.fuseit_t4s__UniqueId__c = newLink.fuseit_t4s__Trim_Record__c + '-' + child.RelatedFrom__c; links.add(newLink); } } if(!links.isEmpty() && Schema.sObjectType.fuseit_t4s__Trim_Record_Link__c.isCreateable() && Schema.sObjectType.fuseit_t4s__Trim_Record_Link__c.isUpdateable() ) { upsert links fuseit_t4s__UniqueId__c; } } }