0

I have created a button to update a checkbox field.

<apex:page standardController="McLabs2__Invoice__c" recordSetVar="Invoices">
<apex:form >
    <apex:pageBlock >
              <apex:pageBlockButtons >
         <apex:CommandButton value="Save" action="{!Save}"/>
        </apex:pageBlockButtons>
        <apex:pageBlockTable value="{!McLabs2__Invoice__c}" var="o">
        <apex:column headerValue="Send Invoice">
            <apex:inputCheckbox value="{!o.Send_Agent_Invoice__c}"/>
            </apex:column>
        </apex:pageBlockTable>
     </apex:pageBlock>
    </apex:form>
</apex:page>

When the field is updated I want to send an email with attachment. Here is the trigger:

trigger SendInvoice on McLabs2__Invoice__c (before update) {
 for(McLabs2__Invoice__c SAI:trigger.new){if(SAI.Send_Agent_Invoice__c==true){
        EmailTemplate et=[Select id from EmailTemplate where name=:'Notification to record owner and agent to send invoice'];

    List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();

   List<Messaging.EmailFileAttachment> attachmentList = new List<Messaging.EmailFileAttachment>();

   Messaging.SingleEmailMessage singlemail = new Messaging.SingleEmailMessage();
   singleMail.setTemplateId(et.Id);              
    singleMail.setTargetObjectId(SAI.OwnerId);

    singleMail.setSaveAsActivity(false);


    String []ToAddress= new string[] {'yyyyy@dddd.com'}; 

    singlemail.setToAddresses(toAddress);


            emails.add(singleMail);

    {



 Attachment att = [SELECT id, Name, body, ContentType FROM Attachment WHERE ParentId = : SAI.id];

Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();

{

 efa.setFileName(att.Name);
 efa.setBody(att.body);
 efa.setContentType(att.ContentType);
 efa.setInline(false);

    attachmentList.add(efa);
}

singlemail.setFileAttachments(attachmentList);
 Messaging.sendEmail(emails);
      }
}
} }

Debug Error message:

List has no rows for assignment to SObject

on line:

Attachment att = [SELECT id, Name, body, ContentType FROM Attachment WHERE ParentId = : SAI.id];
0
0

The error is telling you exactly what's wrong here: one of the records you're processing in this trigger has no Attachment. As you'll find if you search SFSE for this common error message, it occurs any time you attempt to assign a SOQL query that does not return exactly one record to an sObject variable.

While the error can be made to go away by assigning the query result to a List<Attachment> variable instead, and subsequently checking whether it contains any results, the real solution is to properly bulkify your code. You should complete the Bulk Apex Triggers module on Trailhead to learn this pattern, which will lead you to remove the SOQL query from your loop here.

I would suggest performing a parent-child subquery along the lines of

SELECT Id, OwnerId, (SELECT id, Name, body, ContentType FROM Attachments)
FROM McLabs2__Invoice__c
WHERE Id IN :Trigger.newMap.keySet() AND Send_Agent_Invoice__c = true

(You'd need to switch to after update context to make this work).

You'd then iterate over those records to generate emails, accessing the Attachments via the relationship (someInvoice.Attachments).

Other observations:

  • Remove the Email Template query from the loop.
  • You are not using an Apex bind, so remove the colon from that query as well.
  • Please consider using an automatic code formatter like Prettier. Your code is very difficult to read because you have random whitespace and indentation and braces scattered everywhere.
1
  • I will try your suggestion. Have also noted the observations. Thank you David. – Ashwini Sukumaran Mar 10 '20 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.