function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
syed akramsyed akram 

Apex code for email alert?


My requiremenrt is suppose i have 10 opportunity with same closed date with same opportunity owner then workflow will send 10 mail to same address i.e 10 mail, but i want one email need to send which contain all 10 opportunity list in table.that can be done through schedular class.i tried my self but i am not getting the exact result.

global class Opp_Scheduled Implements Schedulable
    {
     Map<Id , List<Opportunity>> oppMap {get; set;}
        global void execute(SchedulableContext sc)
        {
            setopplist();
        }


        public void setopplist()
        {
        
         Date d = Date.today();
        //Map to maintain opportunity id 
       oppMap = new Map<Id, List<Opportunity>>() ;
       
       //All opportunity closeDate 
       List<Opportunity> opplist = new List<Opportunity>() ;
       opplist = [select id, name, Owner.id, StageName, closeDate from Opportunity where CloseDate >= :d AND CloseDate <=:d-7];    
       List<Id> Idlist = new List<Id>() ;
       for(Opportunity opp : opplist )
       {
           Idlist.add(opp.owner.id) ;
       }
          Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;
           List<String> toAddresses = new List<String>();  
            mail.setTemplateId('00Xe0000000RUOp');
           //Setting user email in to address
             
            toAddresses.add('Syed.Akram@cyient.com');
             mail.setToAddresses(toAddresses);
    
              //Email subject to be changed
              mail.setSubject('Opportunity Expired');
              
              //Body of email
              mail.setHtmlBody('Hi ');
                  
        }
    }

 
ProlayProlay
Please find the solution. You have to implement Batchable and Schedulable interface to achieve the desired goal. Please modify the code based on your requirement. I did not implement the date manipulation part.
 
global class Opp_Scheduled Implements Database.Batchable<sObject>, Schedulable
{
    set <String> Uniqueowner ;
  map <String,String> owneridandemail;  
  list<Opportunity> opptgroup ;
    list <User> activeuserdetails;
    List<String> toAddresses ;
    String body ;
    
    //Constructor
    global Opp_Scheduled()
    {
           Uniqueowner = new set<String>();
      owneridandemail = new map<String,String>();  
      opptgroup = new list<Opportunity>();
          activeuserdetails = new list<User>();
           toAddresses = new List<String>();
          body = '';
    }
    //Start method of Batchable Interface
  global Database.QueryLocator start(Database.BatchableContext bc)
    {
        return Database.getQueryLocator([select id, name, Ownerid, owner.email , closeDate from Opportunity where CALENDAR_YEAR(CloseDate) > 2000 and CALENDAR_YEAR(CloseDate) < 2015 ]);
    } 
    
    //Execute method for the batchable interface
    global void execute(Database.BatchableContext BC, list<Opportunity> scope)
    { 
        opptgroup = scope;
    if (opptgroup.size() > 0)
    {
           for (Opportunity op : opptgroup) 
           {
              uniqueowner.add((ID)op.OwnerId);
           }
           for(Opportunity op : opptgroup)
                {
              if (uniqueowner.contains((String)op.OwnerId))
              {
                  owneridandemail.put((String)op.OwnerId, (String)op.Owner.Email);
              }
      
              } 
        }
    } 
    
    //Execute method for the Schedulable interface
    global void execute(SchedulableContext sc)
    {   
        //execute the batch
        Opp_Scheduled OppCS = new Opp_Scheduled();
        ID batchprocessid = Database.executeBatch(OppCS);
    }
    
    //Finish method for Batchable Interface
    global void finish(Database.BatchableContext BC)
    {
        
        // Get the ID of the AsyncApexJob representing this batch job
    // from Database.BatchableContext.
    // Query the AsyncApexJob object to retrieve the current job's information.

     AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id =: BC.getJobId()];

    // Send an email to the Apex job's submitter notifying of job completion.

    if (Integer.ValueOf(a.NumberOfErrors) > 0)
    {
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

      String[] toAddresses = new String[] {a.CreatedBy.Email};

      mail.setToAddresses(toAddresses);

      mail.setSubject('Apex Opportunity Schedule  ' + a.Status);

      mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures.');

      Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

    }
    else
        {
             
          
          for (String s: owneridandemail.keySet() )
        {
            toAddresses.add(owneridandemail.get(s));
        }
          if (toAddresses.size() > 0)
            {
            activeuserdetails = [SELECT FirstName, LastName, IsActive FROM User where id in :uniqueowner and IsActive=true];
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;
            mail.setToAddresses(toAddresses); 
            mail.setSubject('The Closed Opportunities');
            for (User u :activeuserdetails)
            {
                    body = 'Mr/Mrs. ' + u.FirstName +' '+ u.LastName +'--Your Opportunities are closed ';
                     
                
                    
            }
            mail.setPlainTextBody(body);
            Messaging.sendEmail(new Messaging.SingleEMailMessage[]{mail});
            }
        }
        
    }


     
}