global without sharing class Batch_FixDocumentToFiles implements Database.Batchable{ // https://github.com/douglascayers/sfdc-convert-documents-to-files/tree/master/src/classes private Set folderIds = new Set();//Add by Li Jun 20230703 //Add by Gzw 20231030 Start public Batch_FixDocumentToFiles(Set folderIds) { this.folderIds = folderIds; } global Database.QueryLocator start(Database.BatchableContext BC) { // String queryObject = 'SELECT Id, Name, OwnerId, ParentId, Parent.Name, Parent.Type, Body, CreatedDate, CreatedById FROM Attachment WHERE Parent.Type =:objectApiName AND CreatedDate >=:creStartDate AND CreatedDate <:creEndDate Order by CreatedDate ASC'; // if(folderIds.size() > 0){ // queryObject = 'SELECT Id, Name, OwnerId, ParentId, Parent.Name, Parent.Type, Body, CreatedDate, CreatedById FROM Attachment WHERE ParentId in:parentIds'; // } String sql = 'SELECT Id, Name, DeveloperName,Description, ContentType,Type,Body,Url,Keywords,FolderId, Folder.Name,Folder.DeveloperName,AuthorId,CreatedById, CreatedDate, LastModifiedById, LastModifiedDate FROM Document where FolderId in: folderIds ' ; if(System.Test.isRunningTest()){ sql += ' limit 1'; } return Database.getQueryLocator(sql); } global void execute(Database.BatchableContext BC, List scope) { Set documentIds = new Set(); Set folderIds = new Set(); for ( Document doc : scope ) { documentIds.add( doc.Id ); folderIds.add( doc.FolderId ); } Set libraryNames = new Set(); Map foldersMap = new Map([ SELECT Id, Name, DeveloperName FROM Folder WHERE Id IN :folderIds ]); for ( Folder f : foldersMap.values() ) { // libraryNames.add( buildLibraryDeveloperName( f.Name ) ); libraryNames.add( f.Name ); } Map librariesMap = new Map([ SELECT Id, Name, DeveloperName FROM ContentWorkspace WHERE Name IN :libraryNames ]); Map libraryNamesMap = toMapByKeyField( ContentWorkspace.Name, librariesMap.values() ); // Map alreadyConvertedDocumentIdsMap = getAlreadyConvertedDocumentIdsMap( documentIds, librariesMap.keySet() ); // todo add error handling and logging like in ConvertAttachmentsToFilesService.cls List newFileVersions = new List(); for ( Document doc : scope ) { // todo log a skipped conversion result like attachment converter project // if ( alreadyConvertedDocumentIdsMap.containsKey( doc.Id ) ) { // System.debug( 'Document has already been converted, skipping... ' + doc ); // continue; // } Folder f = foldersMap.get( doc.FolderId ); // String libraryName = buildLibraryDeveloperName( f.DeveloperName ); ContentWorkspace library = libraryNamesMap.get( f.Name ); newFileVersions.add( new ContentVersion( // data fields VersionData = doc.Body, PathOnClient = '/' + doc.DeveloperName + '.' + doc.Type, Title = doc.Name, Description = doc.Description, FirstPublishLocationId = library.Id, TagCsv = doc.Keywords, // audit fields OwnerId = doc.AuthorId, // system requirement, owner and creator must be the same CreatedById = doc.AuthorId, CreatedDate = doc.CreatedDate, LastModifiedById = doc.LastModifiedById, LastModifiedDate = doc.LastModifiedDate )); } insert newFileVersions; } // private String buildLibraryDeveloperName( String folderDeveloperName ) { // return 'Doc2File_' + folderDeveloperName; // } // public Map getAlreadyConvertedDocumentIdsMap( Set documentIds, Set libraryIds ) { // // map of old Document ids to new file ids // Map convertedDocumentIdsMap = new Map(); // for ( List links : [ // SELECT // ContentDocument.LatestPublishedVersionId, // ContentDocument.LatestPublishedVersion.Original_Record_ID__c // FROM // ContentDocumentLink // WHERE // LinkedEntityId IN :libraryIds // AND // ContentDocument.LatestPublishedVersion.Original_Record_ID__c IN :documentIds // ]) { // for ( ContentDocumentLink link : links ) { // if ( link.ContentDocument != null && link.ContentDocument.LatestPublishedVersion != null ) { // if ( documentIds.contains( link.ContentDocument.LatestPublishedVersion.Original_Record_ID__c ) ) { // convertedDocumentIdsMap.put( link.ContentDocument.LatestPublishedVersion.Original_Record_ID__c, link.ContentDocument.LatestPublishedVersionId ); // } // } // } // } // return convertedDocumentIdsMap; // } public static Map toMapByKeyField( SObjectField mapKeyField, List records ) { Map recordsMap = new Map(); for ( ContentWorkspace record : records ) { String mapKey = String.valueOf( record.get( mapKeyField ) ); recordsMap.put( mapKey, record ); } return recordsMap; } global void finish(Database.BatchableContext BC) { } }