You need to sign in to do that
Don't have an account?
Ganesh Vinnakota
Apex batch to send Email to users on Leads with their past due leads in an attachment
Hello,
I am trying to build a batch that can be scheduled daily and sends email to all the lead owners if they have any past due date leads.
Each owner should get their own email with an attachment containing only leads assigned to them.
My code below is failing to get an attachment containing only leads assigned to them.
Can any one help me?
global class BatchableLeadEmailAlert implements Database.Batchable<sObject>, Database.AllowsCallOuts, Database.Stateful {
global String query;
String YES = 'Yes';
// ---------------------------------------------------------------------
// CONSTRUCTOR
// ---------------------------------------------------------------------
global BatchableLeadEmailAlert() {
query = 'SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Secondary_Lead_Owner__c != null AND Test_Record__c = \''+YES+'\'';
}
// ---------------------------------------------------------------------
// INTERFACE METHOD: start
// ---------------------------------------------------------------------
global Database.QueryLocator start(Database.BatchableContext bc){
return Database.getQueryLocator(query);
}
// ---------------------------------------------------------------------
// INTERFACE METHOD: execute
// ---------------------------------------------------------------------
global void execute(Database.BatchableContext bc, List<sObject> scope) {
Set<Id> userid = new Set<Id>();
Set<Id> LdId = new Set<Id>();
for (SObject s: scope) {
Lead LdsIds = (Lead) s;
LdId.add(LdsIds.Id);
userid.add(LdsIds.Secondary_Lead_Owner__c);
}
List<User> Addresses = new List<User>();
Addresses = [select Email,LastName from User where Id =: userid];
List<String> toAddresses = new List<String>();
for(User usr: Addresses){
toAddresses.add(usr.Email);
}
List<Lead> leadlist = [SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Id =:LdId ORDER BY Secondary_Lead_Owner__c];
String header = 'Name, First Name, Last Name, Phone,Secondary_Lead_Owner__c \n';
String finalstr = header;
map<Id, String> userleadsmap = new map<Id, String>();
for(Lead a: leadlist)
{
string recordString = a.Name+','+a.FirstName+','+a.LastName+','+a.Phone+','+a.Secondary_Lead_Owner__c+'\n';
finalstr = finalstr +recordString;
userleadsmap.put(a.Secondary_Lead_Owner__c, finalstr);
}
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(User portalUser :Addresses) {
Messaging.EmailFileAttachment csvAttc = new Messaging.EmailFileAttachment();
if(userleadsmap.containskey(portalUser.Id)){
blob csvBlob = Blob.valueOf(userleadsmap.get(portalUser.Id));
string csvname= 'Lead.csv';
csvAttc.setFileName(csvname);
csvAttc.setBody(csvBlob);
}
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
string body = 'Hi '+ portalUser.LastName;
String[] ccAddresses = new list<string> {'gvinnakota@ten-x.com'};
mail.setCcAddresses( ccAddresses );
mail.setSubject('Test Subject');
mail.setTargetObjectId(portalUser.Id);
mail.setSaveAsActivity(false);
mail.setHtmlBody(body); mails.add(mail);
mail.setFileAttachments(new Messaging.EmailFileAttachment[]{csvAttc});
}
Messaging.sendEmail(mails);
}
global void finish(Database.BatchableContext bc){ }
}
I am trying to build a batch that can be scheduled daily and sends email to all the lead owners if they have any past due date leads.
Each owner should get their own email with an attachment containing only leads assigned to them.
My code below is failing to get an attachment containing only leads assigned to them.
Can any one help me?
global class BatchableLeadEmailAlert implements Database.Batchable<sObject>, Database.AllowsCallOuts, Database.Stateful {
global String query;
String YES = 'Yes';
// ---------------------------------------------------------------------
// CONSTRUCTOR
// ---------------------------------------------------------------------
global BatchableLeadEmailAlert() {
query = 'SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Secondary_Lead_Owner__c != null AND Test_Record__c = \''+YES+'\'';
}
// ---------------------------------------------------------------------
// INTERFACE METHOD: start
// ---------------------------------------------------------------------
global Database.QueryLocator start(Database.BatchableContext bc){
return Database.getQueryLocator(query);
}
// ---------------------------------------------------------------------
// INTERFACE METHOD: execute
// ---------------------------------------------------------------------
global void execute(Database.BatchableContext bc, List<sObject> scope) {
Set<Id> userid = new Set<Id>();
Set<Id> LdId = new Set<Id>();
for (SObject s: scope) {
Lead LdsIds = (Lead) s;
LdId.add(LdsIds.Id);
userid.add(LdsIds.Secondary_Lead_Owner__c);
}
List<User> Addresses = new List<User>();
Addresses = [select Email,LastName from User where Id =: userid];
List<String> toAddresses = new List<String>();
for(User usr: Addresses){
toAddresses.add(usr.Email);
}
List<Lead> leadlist = [SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Id =:LdId ORDER BY Secondary_Lead_Owner__c];
String header = 'Name, First Name, Last Name, Phone,Secondary_Lead_Owner__c \n';
String finalstr = header;
map<Id, String> userleadsmap = new map<Id, String>();
for(Lead a: leadlist)
{
string recordString = a.Name+','+a.FirstName+','+a.LastName+','+a.Phone+','+a.Secondary_Lead_Owner__c+'\n';
finalstr = finalstr +recordString;
userleadsmap.put(a.Secondary_Lead_Owner__c, finalstr);
}
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(User portalUser :Addresses) {
Messaging.EmailFileAttachment csvAttc = new Messaging.EmailFileAttachment();
if(userleadsmap.containskey(portalUser.Id)){
blob csvBlob = Blob.valueOf(userleadsmap.get(portalUser.Id));
string csvname= 'Lead.csv';
csvAttc.setFileName(csvname);
csvAttc.setBody(csvBlob);
}
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
string body = 'Hi '+ portalUser.LastName;
String[] ccAddresses = new list<string> {'gvinnakota@ten-x.com'};
mail.setCcAddresses( ccAddresses );
mail.setSubject('Test Subject');
mail.setTargetObjectId(portalUser.Id);
mail.setSaveAsActivity(false);
mail.setHtmlBody(body); mails.add(mail);
mail.setFileAttachments(new Messaging.EmailFileAttachment[]{csvAttc});
}
Messaging.sendEmail(mails);
}
global void finish(Database.BatchableContext bc){ }
}
I believe this can be best acheived usig two batch class. In the First batch Class Create a Map of User and Lead Ids
Map<String , Set<String>>
So now u have this map with user Id and corresponding Lead ids, this helps to make sure one user gets only one email with all the pending leads.
Let me know if any further help you may need.
Thanks,
JS
Thank you. I got this working by adding list map.
global class BatchableLeadEmailAlert implements Database.Batchable<sObject>, Database.AllowsCallOuts, Database.Stateful {
global String query;
String YES = 'Yes';
// ---------------------------------------------------------------------
// CONSTRUCTOR
// ---------------------------------------------------------------------
global BatchableLeadEmailAlert() {
query = 'SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Secondary_Lead_Owner__c != null AND Test_Record__c = \''+YES+'\'';
if(Test.isRunningTest()) {
query = 'SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Secondary_Lead_Owner__c != null AND Test_Record__c = \''+YES+'\'';
}
}
// ---------------------------------------------------------------------
// INTERFACE METHOD: start
// ---------------------------------------------------------------------
global Database.QueryLocator start(Database.BatchableContext bc){
return Database.getQueryLocator(query);
}
// ---------------------------------------------------------------------
// INTERFACE METHOD: execute
// ---------------------------------------------------------------------
global void execute(Database.BatchableContext bc, List<sObject> scope) {
Set<Id> userid = new Set<Id>();
Set<Id> LdId = new Set<Id>();
for (SObject s: scope) {
Lead LdsIds = (Lead) s;
LdId.add(LdsIds.Id);
userid.add(LdsIds.Secondary_Lead_Owner__c);
}
List<User> Addresses = new List<User>();
Addresses = [select Email,LastName from User where Id =: userid];
List<String> toAddresses = new List<String>();
for(User usr: Addresses){
toAddresses.add(usr.Email);
}
List<Lead> leadlist = [SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Id =:LdId ORDER BY Secondary_Lead_Owner__c];
map<Id, List<Lead>> mapUserIdToLstLead = new map<Id, List<Lead>>();
for(Lead ld: [SELECT Id,Name,FirstName,LastName,Phone,Secondary_Lead_Owner__c from Lead where Id IN:LdId ORDER BY Secondary_Lead_Owner__c]) {
if(!mapUserIdToLstLead.containsKey(ld.Secondary_Lead_Owner__c)) {
mapUserIdToLstLead.put(ld.Secondary_Lead_Owner__c, new List<Lead>{ld});
}
else {
mapUserIdToLstLead.get(ld.Secondary_Lead_Owner__c).add(ld);
}
}
system.debug('mapUserIdToLstLead--> ' + mapUserIdToLstLead);
String header = 'Name, First Name, Last Name, Phone,Secondary_Lead_Owner__c \n';
String finalstr = header;
map<Id, String> userleadsmap = new map<Id, String>();
for(Id userIds: mapUserIdToLstLead.keySet())
{
finalstr = '';
for (integer i = 0 ; i < mapUserIdToLstLead.get(userIds).size(); i++) {
string recordString = mapUserIdToLstLead.get(userIds)[i].Name+','+mapUserIdToLstLead.get(userIds)[i].FirstName+','+mapUserIdToLstLead.get(userIds)[i].LastName+','+mapUserIdToLstLead.get(userIds)[i].Phone+','+mapUserIdToLstLead.get(userIds)[i].Secondary_Lead_Owner__c+'\n';
finalstr = finalstr + recordString;
}
userleadsmap.put(userIds, header+finalstr);
}
system.debug('userleadsmap--> ' + userleadsmap);
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(User portalUser :Addresses) {
Messaging.EmailFileAttachment csvAttc = new Messaging.EmailFileAttachment();
if(userleadsmap.containskey(portalUser.Id)){
blob csvBlob = Blob.valueOf(userleadsmap.get(portalUser.Id));
string csvname= 'Lead.csv';
csvAttc.setFileName(csvname);
csvAttc.setBody(csvBlob);
}
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
string body = 'Hi '+ portalUser.LastName;
String[] ccAddresses = new list<string> {''};
mail.setCcAddresses( ccAddresses );
mail.setSubject('Test Subject');
mail.setTargetObjectId(portalUser.Id);
mail.setSaveAsActivity(false);
mail.setHtmlBody(body); mails.add(mail);
mail.setFileAttachments(new Messaging.EmailFileAttachment[]{csvAttc});
}
Messaging.sendEmail(mails);
}
global void finish(Database.BatchableContext bc){ }