0

I am trying to send an email to an Account related user lookup field whenever Opportunity stage moved to closed-won. But when I am fetching Account Id it is getting two times in debug statement and the mail is sending two times.I am unable to figure out the issue can anyone guide me where I am doing wrong.

public static void notifyemail(List<Opportunity> newList){

    string  toEmailId ;
    set<Id> accid = new set<Id>();

  for(Opportunity opp : newList)
    {
        if(opp.AccountId != null)
        {
           accid.add(opp.AccountID);
        }
    }
 system.debug('accid************'+accid); // I am getting AccountID two times.
if(accid.size()>0){
             string testuserid= [Select Account.testuser__c from Opportunity Where accountid=:accid limit 1].Account.testuser__c;
                        string testuserEmail = [Select Email from User where Id=:testuserid limit 1].Email;
                     toEmailId  = testuserEmail;
                   system.debug('Ownerid************'+Ownerid);
                   system.debug('toEmailId************'+toEmailId);
}



     if(toEmailId != null || toEmailId != '')
    {
        EmailTemplate template1;
        EmailTemplate emailTemplates = [ Select Body, HtmlValue, Id, Name, Subject from EmailTemplate  where Name='notification on Opportunity' Limit 1];
        List<Messaging.SingleEmailMessage> theEmails = new list<Messaging.SingleEmailMessage>();
        for(Opportunity op: newList){


                list<string> emaillist= new list<string>();


               emaillist.add(toEmailId);
                string body = emailTemplates.Body;
                string subject = emailTemplates.Subject;

                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                mail.setToAddresses(emaillist);
                mail.setTemplateId(emailTemplates.Id);
                mail.setSaveAsActivity(false);
                mail.setSubject(subject);
                mail.setPlainTextBody(body);

               theEmails.add(mail);


        }
    }
} 

Trigger:

 if (Trigger.isAfter ){
    if (Trigger.isUpdate ){

        List<Opportunity> oplist = new list<opportunity>();
        for(opportunity op :trigger.new)
        {
            if( op.StageName == 'closed-won' && Trigger.oldmap.get(op.id).StageName!= op.closed-won)
                oplist.add(op);

        }
        if(!oplist.isempty())
            EmailNotificationtcalss.notifyemail(Trigger.new);

    }

1 Answer 1

0

I believe you should be doing something along these lines:

public static void notifyemail(List<Opportunity> newList){
    // ReQuery Opportuities
    List<Opportunity> opps = [SELECT Id, AccountId.TestUser__c.Email
                              FROM Opportunity
                              WHERE Id IN :Trigger.newMap.keySet()
                              WHERE AccountId.TestUser__c != null];

    // If there are no opps to process, return to stop processing
    if (opps.isEmpty())
        return;

    // Query the Email Template to be used
    EmailTemplate emailTemplates = [SELECT Body, HtmlValue, Id, Name, Subject
                                    FROM EmailTemplate 
                                    WHERE Name = 'notification on Opportunity' // This text should probably be replaced with a Custom Label to allow easy updating
                                    LIMIT 1];

    // Instantiate a List of Single Email Messages
    List<Messaging.SingleEmailMessage> messages = new List<Messaging.SingleEmailMessage>();

    // Iterate over the opps List
    for (Opportunity opp :opps) {
        // Instantiate a Single Email Message
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        // Set the To Address to the Users Email
        mail.setToAddresses(new List<String>{ opp.AccountId.TestUser__c.Email });

        // Set the Email Template Id
        mail.setTemplateId(emailTemplates.Id);

        // Set Save Activities to false
        mail.setSaveAsActivity(false);

        // Set the Subject
        mail.setSubject(emailTemplates.Subject);

        // Set the Body
        mail.setPlainTextBody(emailTemplates.Body);

        // Set Opportunity Id
        // This was missing which is what tells the Email Template what record to compile against, without it, the email won't merge data in
        mail.setWhatId(opp.Id);

        // Add the Email to messages List
        messages.add(mail);
    }

    // Send the Email Messages
    List<Messaging.SendEmailResult> results = Messaging.sendEmail(messages);

    // Iterate over the results
    for(Messaging.SendEmailResult res :results){
        // If isSuccess is false
        if(!res.isSuccess()){
            // Print Errors
            System.debug(res.getErrors());
        }
    }
} 

Doing this, also adding comments, should give you a better understanding of what is going on, the way you are doing things at the moment is iterating over the Opps, collecting the Account Ids, which you aren't then using, you are only using 1 Account Id... after that you are then iterating over all Opportunities and then trigger it to send to 1 person, but against multiple Opportunities.

1
  • Also please add comments and keep your code neat! It always makes things easier for yourself and others to read, especially if you need to post online :)
    – Tim
    Dec 16, 2019 at 12:38

You must log in to answer this question.

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