function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Merry SMerry S 

Batch Apex creating Multiple contentdocumentlinks when trying to “convert” tasks to notes…

I am trying to look at all tasks for a specific time frame, then create a note and set the LinkedEntityId to the whatid or whoid. This code creates the content note, 1 for each task. But then created a contentdocumentlink for each whatid or whoid for every note.
For instance, the query returns 8 tasks, 8 contentnotes are created and then each note is associated to each whatid(opps). So every opp has 8 notes. I have reworked this a million times and I am just not sure how to get it to know that I just want each contentnote associated to the task it "copied".
At this point I think I am over complicating it and the answer is so easy that I am not seeing it. How can I get this to create one note per task, and then associate it to the opp that the task is related? (whatid)
 
global class archiveTasksBatch implements Database.Batchable<SObject>, Schedulable{

public final string query;
date mydate = date.today().addDays(-369);

public archiveTasksBatch() {
    query = 'Select WhoId, WhatId, Subject, Status, OwnerId, Id, Description, CreatedDate, ActivityDate From Task where ActivityDate = :mydate' ;
}
public void execute(SchedulableContext sc){
    Database.executeBatch(this, 100);
}
public Database.QueryLocator start(Database.BatchableContext bc){
    return Database.getQueryLocator(query);
}

public void execute(Database.BatchableContext bc, List<sObject> scope){

    list<ContentNote > newObjects = new list<ContentNote >();
    list<ContentDocumentLink  > newCDL = new list<ContentDocumentLink  >();
    Map<ID, String> taskIdMap = new Map<ID, String>();





    for(Sobject s : scope){
        Task obj = (Task) s;
        String myString = obj.Description + obj.ActivityDate;
        Blob myBlob = Blob.valueof(myString.escapeHtml4());
        newObjects.add(new ContentNote (
        Title = obj.Subject,
        Content = myBlob
        ));

   }

        system.debug('*********************************newObjects' +newObjects.size());
        system.debug('*********************************scope' +scope.size());

        if(!newObjects.isEmpty()){
            Database.SaveResult[] srList = Database.insert(newObjects, false);
            for (Database.SaveResult sr : srList) {
                        for (Sobject sc : scope){
                        Task t = (Task) sc;
                        string tid = t.WhatId;
                        if(tid == null) {
                            tid = t.WhoId;}
                        taskIdMap.put(sr.Id, tid);
                if(sr.isSuccess()) {
                    ContentDocumentLink cdl = new ContentDocumentLink();
                    cdl.ContentDocumentId = sr.getId();
                    cdl.LinkedEntityId = taskIdMap.get(sr.id);
                    cdl.Visibility = 'AllUsers';
                    cdl.ShareType = 'I';
                    newCDL.add(cdl);
        system.debug('*********************************srList' +srList.size());
        system.debug('*********************************newCDL' +newCDL.size());
        system.debug('*********************************LinkedEntityId' +cdl.LinkedEntityId);
        system.debug('*********************************ContentDocumentId' +cdl.ContentDocumentId);

                }
            }
        }
     }
    insert newCDL;
}


public void finish(Database.BatchableContext bc){
    system.debug('JOB IS FINISHED');
}

 
Best Answer chosen by Merry S
Zuinglio Lopes Ribeiro JúniorZuinglio Lopes Ribeiro Júnior
Hello Merry,

I changed the code a bit and I hope it will do what you are expecting but I didn't have time to test it though. Let me know if it works!
 
global class archiveTasksBatch implements Database.Batchable<SObject>, Schedulable{

	public final string query;
	Date mydate = date.today().addDays(-369);

	public archiveTasksBatch() {
		query = 'Select WhoId, WhatId, Subject, Status, OwnerId, Id, Description, CreatedDate, ActivityDate From Task where ActivityDate = :mydate' ;
	}
	public void execute(SchedulableContext sc) {
		Database.executeBatch(this, 100);
	}
	public Database.QueryLocator start(Database.BatchableContext bc) {
		return Database.getQueryLocator(query);
	}

	public void execute(Database.BatchableContext bc, List<sObject> scope) {

		Map<Id,ContentNote> 		contentsByTask 	= new Map<Id,ContentNote>();
		List<ContentDocumentLink> 	newCDL 			= new List<ContentDocumentLink>();

		for (Task task : (List<Task>)scope) {
			
			String myString = task.Description + task.ActivityDate;
			Blob myBlob = Blob.valueof(myString.escapeHtml4());
			
			contentsByTask.put(task.Id, new ContentNote (
										Title = task.Subject,
										Content = myBlob
										));
		}

		if (!contentsByTask.isEmpty()) {
			
			Database.insert(contentsByTask.values(), false);
			
			for (Id taskId : contentsByTask.keySet()) {
				
				Content cont = contentsByTask.get(taskId);
				
				if (cont.Id != null) {
				
					ContentDocumentLink cdl 					= new ContentDocumentLink();
										cdl.ContentDocumentId 	= cont.Id;
										cdl.LinkedEntityId 		= taskId;
										cdl.Visibility 			= 'AllUsers';
										cdl.ShareType 			= 'I';
					newCDL.add(cdl);
				}
			}
			
			if (!newCDL.isEmpty())
				insert newCDL;
		}
		
	}

	public void finish(Database.BatchableContext bc){
		system.debug('JOB IS FINISHED');
	}
}

Hope to have helped!

Regards.

Don't forget to mark your thread as 'SOLVED' with the answer that best helps you.
 

All Answers

Zuinglio Lopes Ribeiro JúniorZuinglio Lopes Ribeiro Júnior
Hello Merry,

I changed the code a bit and I hope it will do what you are expecting but I didn't have time to test it though. Let me know if it works!
 
global class archiveTasksBatch implements Database.Batchable<SObject>, Schedulable{

	public final string query;
	Date mydate = date.today().addDays(-369);

	public archiveTasksBatch() {
		query = 'Select WhoId, WhatId, Subject, Status, OwnerId, Id, Description, CreatedDate, ActivityDate From Task where ActivityDate = :mydate' ;
	}
	public void execute(SchedulableContext sc) {
		Database.executeBatch(this, 100);
	}
	public Database.QueryLocator start(Database.BatchableContext bc) {
		return Database.getQueryLocator(query);
	}

	public void execute(Database.BatchableContext bc, List<sObject> scope) {

		Map<Id,ContentNote> 		contentsByTask 	= new Map<Id,ContentNote>();
		List<ContentDocumentLink> 	newCDL 			= new List<ContentDocumentLink>();

		for (Task task : (List<Task>)scope) {
			
			String myString = task.Description + task.ActivityDate;
			Blob myBlob = Blob.valueof(myString.escapeHtml4());
			
			contentsByTask.put(task.Id, new ContentNote (
										Title = task.Subject,
										Content = myBlob
										));
		}

		if (!contentsByTask.isEmpty()) {
			
			Database.insert(contentsByTask.values(), false);
			
			for (Id taskId : contentsByTask.keySet()) {
				
				Content cont = contentsByTask.get(taskId);
				
				if (cont.Id != null) {
				
					ContentDocumentLink cdl 					= new ContentDocumentLink();
										cdl.ContentDocumentId 	= cont.Id;
										cdl.LinkedEntityId 		= taskId;
										cdl.Visibility 			= 'AllUsers';
										cdl.ShareType 			= 'I';
					newCDL.add(cdl);
				}
			}
			
			if (!newCDL.isEmpty())
				insert newCDL;
		}
		
	}

	public void finish(Database.BatchableContext bc){
		system.debug('JOB IS FINISHED');
	}
}

Hope to have helped!

Regards.

Don't forget to mark your thread as 'SOLVED' with the answer that best helps you.
 
This was selected as the best answer
Merry SMerry S
I tested it and it worked!! I changed the taskid to the what/whoid and it worked beautifully.

I am on vacation, in Japan, just getting into bed and checked my email. When I saw your response I had to get up and test it. Thank you so much!

I will post the final code in the next few days so that maybe someday it can help someone else.
Zuinglio Lopes Ribeiro JúniorZuinglio Lopes Ribeiro Júnior
Hello Merry,

I'm glad to hear it worked! I forgot about the WhatId and WhoId and I'm sorry for that!

Enjoy your vacation!

Regards