I have a batch which after creation of records send out emails to the opportunity Account manager for which new record is created.

// Get All Opportunities
   set<id> Billoppid= new set<id>();
   for ( Billing_Month__c  bm : ListofBillingMonthstoinsert) {
   // Get Account Managers
     List < opportunity > Ownerlist = new list < opportunity > ([Select id,Owner.Email, Account_Manager_lookup__c, Name from opportunity where id in : Billoppid]);
     for (opportunity Opp: Ownerlist) {
       if ( Opp.Account_Manager_lookup__c!=null)
  // Get Account Manager emails
   list < user > AMlistemails = new list < user > ([select id, email from user where id in : Userid]);
   map < id, string > Mapamuseremail = new map < id, string > ();
   List<Messaging.SingleEmailMessage> mails = new                      
  for (user u: AMlistemails) {
      Mapamuseremail.put(u.id, u.email);}
  for (opportunity  opp1:Ownerlist ) {
    if (Mapamuseremail.containskey(opp1.Account_Manager_lookup__c) && opp1.Account_Manager_lookup__c != null){

  // send email to AM's 
   Messaging.SingleEmailMessage mail = new 
   string mbody;
    if (ListAMandOwneremail.size()>0){
    mail.setSubject('Billing Month Created');
    mBody = '<html><body> Opportunity: ' + opp1.Name + ' has new Billing Months created.  </body></html>';
    mails .add(mail);
 if ( mails.size()>0){

This code captures all the opportunities Account managers and send out emails to all, because of which even those Account manager who don't belong to an opportunity still gets the mail.

How to send out mail details of an particular opportunity for it's Account manager alone?

  • 2
    Instead of attaching an image of the code (which is quite hard to read as is) can you include the code itself? Sounds like making use of a 'Map' to link the Opportunity to its Account Manager will do the job.
    – TSmith
    Commented Jul 19, 2018 at 13:38
  • @TSmith Added. Hope this helps.
    – Sowparnika
    Commented Jul 19, 2018 at 14:07

1 Answer 1


You can solve this by working backwards. Where do you set the message's to addresses?




Then, how do you populate those lists? Well, ccadd isn't used anywhere in this code, so presumably it's either empty or null - but that could be a problem too; we don't know.

ListAMandOwneremail appears more likely to be the culprit, because you don't reset the list each time you iterate through the for loop. Hence, each time the loop executes, the list retains the emails of all of the previous recipients, and then also gets the recipient for this loop. By the end of the loop, you'll be emailing everyone.

Troubleshooting this code is made far more difficult by your code style. Please use a Java formatter to clean your code. When you have things like ending braces at the end of a statement, your logic becomes impossible to follow.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .