Description: When I deactivate multiple users, say a,b,c, the following code is triggered to send emails to their respective managers. but in my case the manager receives the email with only the username of the last user for all emails i.e for a, b, c.
the expected scenario is that the manager should receive email for all 3 users mentioning their corresponding names in the mail as opposed to a single user name in all emails.
Could you please help me with what changes need to be done to make this piece of code work as expected
Apex Code:
public without sharing class ChangeOpportunityOwner {
@Future
public static void changeOwner(List<Id> usrIds){
Boolean isUpdate=false;
List<Messaging.MassEmailMessage> messages=new list<Messaging.SingleEmailMessage>();
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
Map<Id, Boolean> mapUserToActive = new Map<Id, Boolean>();
try{
for (User u1 : [SELECT Id, isActive FROM User]) {
mapUserToActive.put(u1.Id, u1.isActive);
}
List <user>usrs= [Select Id,Name,ManagerId,IsActive from user where Id=:usrIds];
List<Opportunity> finalOptList=new List<Opportunity>();
for(User u:usrs){
List<Opportunity>optys=[Select Id,OwnerId,StageName from Opportunity where OwnerId=:u.Id];
for(Opportunity opt:optys){
if(opt.StageName!='Closed Won' && opt.StageName!='Closed Lost')
{
if (mapUserToActive.get(u.ManagerId)== true && mapUserToActive.get(u.ManagerId)!=null) {
opt.OwnerId=u.ManagerId;
}
else{
User usr= [Select Id,Name,ManagerId from user where Name='Test Manager'];
opt.OwnerId=usr.Id;
}
finalOptList.add(opt);
// Set list of people who should get the email
List<String> sendTo = new List<String>();
sendTo.add(u.ManagerId);
mail.setToAddresses(sendTo);
// Set who the email is sent from
mail.setReplyTo('[email protected]');
mail.setSenderDisplayName('Customer Service');
// Set email contents - you can use variables!
mail.setSubject('Open Opportunities transferred to you');
String body = 'Dear Manager,<br> ';
body +='<br>';
body += 'Please note that '+u.name+' has been deactivated as a Salesforce User hence all of its <br> Open Opportunities has been assigned to you if any.<br>';
body +='<br>';
body +='Kind regards,<br>';
body +='<br>';
body +='SFDC Support';
mail.setHtmlBody(body);
isUpdate=true;
}
}
messages.add(mail);
//In the below debugs I can see all 3 users inserted properly in the email template body
system.debug('messages:'+messages);
system.debug('Mail:'+mail);
}
if(isUpdate)
system.debug('message1:'+messages);//in this debug when I receive an email,it always displays user c's information.which is last user.
Messaging.sendEmail(messages,false);
if(isUpdate)
{
update finalOptList;
}
}
catch(Exception e)
{
system.debug('An Exception Occured: '+e.getMessage());
}
}
@InvocableMethod(label='Change Opportunity Owner' description='It Change the owner of opportunity when owner is inactive')
public static void changeOwnerFuture(List<Id> usrIds)
{
changeOwner(usrIds);
}
}
Updating the code below:
public without sharing class ChangeOpportunityOwner {
@Future
public static void changeOwner(List<Id> usrIds){
Boolean isUpdate=false;
List<Messaging.SingleEmailMessage> messages=new list<Messaging.SingleEmailMessage>();
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
Map<Id, Boolean> mapUserToActive = new Map<Id, Boolean>();
map<Id,user>idToUser= new map<Id,User>([Select Id,Name,ManagerId,IsActive from user where Id IN :usrIds]);
List<Opportunity> finalOptList=new List<Opportunity>();
set<Id>mgrIds = new set<Id>();
for (User u1 : idToUser.values()) {
mgrIds.add(u1.ManagerId);
// collect the ids of the managers
}
/*for (User u1 : [SELECT Id, isActive FROM User]) {
mapUserToActive.put(u1.Id, u1.isActive);
}*/
map<Id,user>idToManager = new map<Id,User>([Select Id,Name,ManagerId,IsActive from user where Id IN :mgrIds]);
for (User u2 : idToManager.values()) {
mapUserToActive.put(u2.Id, u2.isActive);
// you can add them to your map if you need the map
}
//List <user>usrs= [Select Id,Name,ManagerId,IsActive from user where Id=:usrIds];
for(User u: idToUser.values()){
List<Opportunity>optys=[Select Id,OwnerId,StageName from Opportunity where OwnerId=:u.Id];
for(Opportunity opt:optys){
if(opt.StageName!='Closed Won' && opt.StageName!='Closed Lost')
{
if (mapUserToActive.get(u.ManagerId)== true && mapUserToActive.get(u.ManagerId)!=null) {
opt.OwnerId=u.ManagerId;
}
else{
User usr= [Select Id,Name,ManagerId from user where Name='Test Manager'];
opt.OwnerId=usr.Id;
}
finalOptList.add(opt);
list<string> userStore=new List<String>();
userStore.add(u.Name);
system.debug('userStore:'+userStore);
// Set list of people who should get the email
List<String> sendTo = new List<String>();
sendTo.add(u.ManagerId);
mail.setToAddresses(sendTo);
// Set who the email is sent from
mail.setReplyTo('[email protected]');
mail.setSenderDisplayName('Customer Service');
// Set email contents - you can use variables!
mail.setSubject('Open Opportunities transferred to you');
String body = 'Dear Manager,<br> ';
body +='<br>';
body += 'Please note that '+userStore+' has been deactivated as a Salesforce User hence all of its <br> Open Opportunities has been assigned to you if any.<br>';
body +='<br>';
body +='Kind regards,<br>';
body +='<br>';
body +='SFDC Support';
mail.setHtmlBody(body);
//isUpdate=true;
}
}
messages.add(mail);
system.debug('messages:'+messages);
system.debug('Mail:'+mail);
}
//if(isUpdate)
//messages1 = new List<Messaging.SingleEmailMessage>(messages);
system.debug('message1:'+messages);
Messaging.sendEmail(messages,true);
//if(isUpdate)
//{
update finalOptList;
//}
}
@InvocableMethod(label='Change Opportunity Owner' description='It Change the owner of opportunity when owner is inactive')
public static void changeOwnerFuture(List<Id> usrIds)
{
changeOwner(usrIds);
}
}
It still displays the Latest users info i.e.User C. Please suggest what is wrong in the updated code..
Developer Console
(theExecute Anonymous
window) and hitShift
+Tab
. If you're pasting it into SFSE, you can just select all and tab it out one extra tab before copying so that it formats it as code here.