Because this is a trigger on User (a setup object), you can't do any other DML on non-setup objects in the same transaction. So, you will need to delegate the work to an asynchronous transaction (either future or queueable)
So, your trigger looks like this:
trigger insertTasks on User (after insert) {
new DelegatedUserSetup().setObjectives(
[SELECT Id
FROM User
WHERE Onboarding__c = TRUE AND
Id IN: Trigger.newMap.keySet() ]); // ensure only current trigger context
}
and you create another class as an all purpose delegation of user setup that you can use for other use cases.
public class DelegatedUserSetup {
void setObjectives(User[] users) {
System.enqueueJob(new SetObjectivesAsQueueable(users));
}
public class SetObjectivesAsQueueable implements System.Queueable {
User[] users;
SetObjectivesAsQueueable(User[] users) {this.users = users;}
public void execute(System.QueueableContext qc) {
Objectives__c[] masterObjectives =
[SELECT Id,Name,Duration__c,Minutes__c,OwnerId,URL__c, Week__c
FROM Objectives__c WHERE someField__c = 'MASTER'];
Objectives__c[] assignedObjectives = new List<Objectives__c>();
for(User u : this.users){ // every user gets ea masterObjective
for (Objective__c masterObjective : masterObjectives) {
assignedObjectives.add(new Objective__c (
OwnerId = u.Id, // assign to user
Name = masterObjective.Name,
Status__c = 'Not started',
... // other fields
));
}
}
insert assignedObjectives; // if none, no DML burnt
}
}
}
Notes
- You need some way to differentiate the master objectives from the user-assigned objectives. I put in a placeholder for you
- There's a chance you could hit DML limits if the number of users * # master objectives exceeds the number of allowed DML rows per sync transaction
- I renamed variables to be more meaningful
- I haven't tested the code; there could be typos
- You might need to introduce a guard and retry mechanism if the
enqueueJob
fails