global without sharing class Batch_FixDocumentToFiles implements Database.Batchable<sObject>{
|
// https://github.com/douglascayers/sfdc-convert-documents-to-files/tree/master/src/classes
|
private Set<String> folderIds = new Set<String>();//Add by Li Jun 20230703
|
//Add by Gzw 20231030 Start
|
public Batch_FixDocumentToFiles(Set<String> 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<Document> scope) {
|
Set<ID> documentIds = new Set<ID>();
|
Set<ID> folderIds = new Set<ID>();
|
for ( Document doc : scope ) {
|
documentIds.add( doc.Id );
|
folderIds.add( doc.FolderId );
|
}
|
|
Set<String> libraryNames = new Set<String>();
|
Map<ID, Folder> foldersMap = new Map<ID, Folder>([ 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<ID, ContentWorkspace> librariesMap = new Map<ID, ContentWorkspace>([ SELECT Id, Name, DeveloperName FROM ContentWorkspace WHERE Name IN :libraryNames ]);
|
Map<String, ContentWorkspace> libraryNamesMap = toMapByKeyField( ContentWorkspace.Name, librariesMap.values() );
|
|
// Map<ID, ID> alreadyConvertedDocumentIdsMap = getAlreadyConvertedDocumentIdsMap( documentIds, librariesMap.keySet() );
|
|
// todo add error handling and logging like in ConvertAttachmentsToFilesService.cls
|
List<ContentVersion> newFileVersions = new List<ContentVersion>();
|
|
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<ID, ID> getAlreadyConvertedDocumentIdsMap( Set<ID> documentIds, Set<ID> libraryIds ) {
|
|
// // map of old Document ids to new file ids
|
// Map<ID, ID> convertedDocumentIdsMap = new Map<ID, ID>();
|
|
// for ( List<ContentDocumentLink> 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<String, ContentWorkspace> toMapByKeyField( SObjectField mapKeyField, List<ContentWorkspace> records ) {
|
|
Map<String, ContentWorkspace> recordsMap = new Map<String, ContentWorkspace>();
|
|
for ( ContentWorkspace record : records ) {
|
String mapKey = String.valueOf( record.get( mapKeyField ) );
|
recordsMap.put( mapKey, record );
|
}
|
|
return recordsMap;
|
}
|
|
global void finish(Database.BatchableContext BC) {
|
|
}
|
}
|