
I'm getting the error First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []:. The purpose of the trigger is to find existing User History record & create a new one if a User record is updated and matches the criteria. When I checked the debug log, I do see the query finding the existing User History record Id.
public class UserHistory_CreateUpdateFromUser {
public static void findUser(List<User> newUsers, Map<Id,User> oldUsers, Boolean isInsert){
List<User> newUserList = new List<User>();
List<User> lOBChannelList = new List<User>();
List<User> isActiveList = new List<User>();
List<User> uManagerLOBChannelList = new List<User>();
List<User> uManagerList = new List<User>();
Map<Id,List<User>> reasonForUpdatingUser = new Map<Id,List<User>>();
for(User u : newUsers){
//New user && Channel != Non Sales
if(u.Channel__c != 'Non Sales'){
if(isInsert){
newUserList.add(u);
System.debug('newUserList: '+ newUserList);
}
//Existing user && Channel || LOB is changed
else if(!isInsert && (u.Channel__c != oldUsers.get(u.Id).Channel__c || u.LOB_Focus__c != oldUsers.get(u.Id).LOB_Focus__c)) {
lOBChannelList.add(u);
System.debug('lOBChannelList: '+ lOBChannelList);
}
//Existing user && deactived
else if(!isInsert && u.IsActive != oldUsers.get(u.Id).IsActive){
isActiveList.add(u);
System.debug('isActiveList: '+ isActiveList);
}
//Existing user && Manager is changed && Channel || LOB is changed
else if(!isInsert && u.ManagerId != oldUsers.get(u.Id).ManagerId &&
(u.Channel__c != oldUsers.get(u.Id).Channel__c || u.LOB_Focus__c != oldUsers.get(u.Id).LOB_Focus__c)){
uManagerLOBChannelList.add(u);
System.debug('uManagerLOBChannelList: '+ uManagerLOBChannelList);
}
//Existing user && Manager is changed
else if(!isInsert && u.ManagerId != oldUsers.get(u.Id).ManagerId){
uManagerList.add(u);
System.debug('uManagerList: '+ uManagerList);
}
}
}
if(newUserList.size()>0){
newUser(newUserList);
}
if(lOBChannelList.size()>0){
lOBChannelUpdate(lOBChannelList);
}
if(isActiveList.size()>0){
userisActiveUpdate(isActiveList);
}
if(uManagerList.size()>0){
managerUpdateOnly(uManagerList);
}
if(uManagerLOBChannelList.size()>0){
managerLOBChannelUpdate(uManagerLOBChannelList);
}
}
public static void lOBChannelUpdate(List<User> lOBChannelList){
//Find existing User History record and update end date fields
//Create new user history record and update fields based on user changes
List<Id> userIds = new List<Id>();
List<User_History__c> existingUHtoUpdate = new List<User_History__c>();
List<User_History__c> newUHtoInsert = new List<User_History__c>();
for(User u : lOBChannelList){
userIds.add(u.Id);
}
System.debug('userIds: '+ userIds);
System.debug('lOBChannelList: '+ lOBChannelList);
if(userIds.size()>0){
List<User_History__c> eUH = [SELECT Id, User__C, Role_End_Date__c, Manager_End_Date__c FROM User_History__c
WHERE User__c =:userIds];
System.debug('eUH' + eUH);
for(User_History__c uH : eUH){
User_History__c existingUH = new User_History__c();
if(uH.Role_End_Date__c == NULL){
existingUH.Role_End_Date__c = Date.today();
existingUH.Id = uH.Id;
}
else if(uH.Manager_End_Date__c == NULL){
existingUH.Manager_End_Date__c = Date.today();
existingUH.Id = uH.Id;
}
else if(uH.Role_End_Date__c == NULL && uH.Manager_End_Date__c == NULL){
existingUH.Role_End_Date__c = Date.today();
existingUH.Manager_End_Date__c = Date.today();
existingUH.Id = uH.Id;
}
existingUHtoUpdate.add(existingUH);
}
System.debug('existingUHtoUpdate: '+ existingUHtoUpdate);
for(User u1 : lOBChannelList){
User_History__c newUH = new User_History__c(
User__c = u1.Id,
Channel__c = u1.Channel__c,
LOB_Focus__c = u1.LOB_Focus__c,
Role_Start_Date__c = Date.today(),
Manager_Start_Date__c = Date.today()
);
newUHtoInsert.add(newUH);
}
System.debug('newUHtoInsert: '+ newUHtoInsert);
}
if(!existingUHtoUpdate.isempty()){
Database.update(existingUHtoUpdate);
}
System.debug('Databaseupdate existingUHtoUpdate: ' + existingUHtoUpdate);
if(!newUHtoInsert.isempty()){
Database.insert(newUHtoInsert);
}
}
When the line below is executed, you're instantiating a new object. This basically means you have an empty shell of a record with no Id nor fields populated.
User_History__c existingUH = new User_History__c();
Instead, just update the loop variable. See the example below, where I updated your existingUH variable to use the "uh" loop variable isntead.
public static void lOBChannelUpdate(List<User> lOBChannelList){
//Find existing User History record and update end date fields
//Create new user history record and update fields based on user changes
List<Id> userIds = new List<Id>();
List<User_History__c> existingUHtoUpdate = new List<User_History__c>();
List<User_History__c> newUHtoInsert = new List<User_History__c>();
for(User u : lOBChannelList){
userIds.add(u.Id);
}
if(!userIds.isEmpty()){
for(User_History__c uH :
[Select
Id,
User__C,
Role_End_Date__c,
Manager_End_Date__c
From
User_History__c
Where
User__c =:userIds]){
//Remove this line... User_History__c existingUH = new User_History__c();
if(uH.Role_End_Date__c == NULL){
uh.Role_End_Date__c = Date.today();
uh.Id = uH.Id;
}else if(uH.Manager_End_Date__c == NULL){
uh.Manager_End_Date__c = Date.today();
uh.Id = uH.Id;
}else if(uH.Role_End_Date__c == NULL && uH.Manager_End_Date__c == NULL){
uh.Role_End_Date__c = Date.today();
uh.Manager_End_Date__c = Date.today();
uh.Id = uH.Id;
}
existingUHtoUpdate.add(uh);
}
for(User u1 : lOBChannelList){
newUHtoInsert.add(
new User_History__c(
User__c = u1.Id,
Channel__c = u1.Channel__c,
LOB_Focus__c = u1.LOB_Focus__c,
Role_Start_Date__c = Date.today(),
Manager_Start_Date__c = Date.today()
)
);
}
}
update existingUHtoUpdate;
insert newUHtoInsert;
}