Reason for Mix DML error
sObjects That Cannot Be Used Together in DML Operations DML
operations on certain sObjects sometimes referred to as setup
objects, can’t be mixed with DML on other sObjects in the same
transaction. This restriction exists because some sObjects affect the
user’s access to records in the org. You must insert or update these
types of sObjects in a different transaction to prevent operations
from happening with incorrect access-level permissions. For example,
you can’t update an account and a user role in a single transaction.
However, deleting a DML operation has no restrictions.
Solution - Use Future method
you need to use future method for updating the task records. That will solve your mix DML error
if(!Task2Close.isEmpty())
{
// call a future method. SInce we can pass list in future method thats why
// pass the json string
futureClassForUpdate.updateTak(json.serialize(Task2Close));
}
Future Method
public class futureClassForUpdate
{
@future
public static void updateTak(String strJSON)
{
// deserialize your string into list of task and update that list in future method to avoid mix dml error
List<Task > lstTask = (List<Task>) json.deserialize(strJSON, List<Task >.class);
update lstTask;
}
}
Updates - Handler Recurrence Task Update
INVALID_FIELD_FOR_INSERT_UPDATE, You cannot update the Status of a
recurring task.: [Status]"
I got this answer How to get around this - “Error: You cannot reassign a recurring task occurrence.”?
From Apex, have a read of Task - Recurring Tasks. If the IsRecurrence
field is true on the current Task you can use the RecurrenceActivityId
to get the ID of the main record that created the current recurrence.
You can then modify this parent record.
From the UI, first use the edit series link in the recurrence to get
to the parent record and modify that.
To handle this error, you need to update recurrence task's parent task record
trigger AutoDeleteTasks4InactiveUsers on User (after update)
{
Set<Id> UserIds = new Set<Id>();
for (User u: trigger.new)
{
if(u.IsActive == false)
{
UserIds.add(u.id);
}
}
List<Task> Task2Close = [SELECT Id, IsRecurrence, RecurrenceActivityId
FROM Task
where IsClosed = false
and OwnerId = :UserIds];
// use new list of task to update the record
List<Task> lstTask = new List<Task>();
for(Task tsk : Task2Close)
{
// if task is recurrence type then get the parent task Id using RecurrenceActivityId and update parent task status
lstTask.add(new Task(Status = 'Closed - User Deactivated',
Id = tsk.IsRecurrence ? tsk.RecurrenceActivityId : tsk.Id ));
}
if(!lstTask.isEmpty())
{
// call a future method. Since we can't pass list in future method thats why
// pass the json string
futureClassForUpdate.updateTak(json.serialize(lstTask));
}
}