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
Rebecca PittsRebecca Pitts 

Send email with service report pdf when a new service report is created

Hey do you know if it’s possible to send email with attachment when a new service report has been created through apex trigger? In field service when my techs create a service report we have to go in and manually email the pdf report each time, but there has to be a way to do this automatically. Could you help?
CodenameSnugsCodenameSnugs
I'm a bit late to the party here, but yes it's possible.  We have an 'Email Service Report' checkbox on our Service Appointments that the trigger uses to determine whether or not to send the email.  The trigger fires after the Service Report is created:
 
trigger serviceReportSendEmail on ServiceReport (after insert) {
    ServiceAppointment so;
    string soId;
    List<Messaging.SingleEmailMessage> mails =  new List<Messaging.SingleEmailMessage>();
    List<String> sendTo = new List<String>();
    
    for(ServiceReport sr : trigger.new){
        try {
            // Get service appointment details inc contact email
            soId = sr.ParentId;
            so = [select Id, Email_Service_Report__c, Contact_Email__c, Case_Number__c from ServiceAppointment where Id = :soId limit 1];

            // Check contact email exists and report should be sent            
            if(so.Email_Service_Report__c && so.Contact_Email__c != '' && so.Contact_Email__c != null)
            {
                sendTo.add(so.Contact_Email__c);
                Messaging.SingleEmailMessage mail =  new Messaging.SingleEmailMessage();
                mail.setToAddresses(sendTo);
                mail.setSubject('Service Report Created for Case Number: '+ so.Case_Number__c);
                String body = 'Your service report is attached.';
                mail.setHtmlBody(body);
                mails.add(mail);
                
                // Get file for attachment
                List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>();
                Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
                efa.setContentType('application/pdf');
                efa.setInline(false);
                efa.setFileName(sr.ServiceReportNumber);
                // Have to fetch DocumentBody, it is null when accessing directly
                Blob attBody = [select DocumentBody from ServiceReport where Id = :sr.Id limit 1].DocumentBody;
                efa.setBody(attBody);
                fileAttachments.add(efa);
                mail.setFileAttachments(fileAttachments);

                Messaging.sendEmail(mails);
            }
        }
        catch(exception e) {
            System.debug('************************** Exception in serviceReportSendEmail trigger:'+e);
        }
    }
}

 
Alison RichardsAlison Richards
CodeNameSnugs what is the test class you used?
CodenameSnugsCodenameSnugs
Hi Alison, the test class is below.  Build your data for the class (account, contact, case, work order and service appointment, with the email trigger field checked).  The key part starts at the '// create service report' line as you need to create a 'fake' document with the service report.
 
@isTest(SeeAllData=true)
private class serviceReportSendEmailTest {

  static testMethod void CheckValidRecord() {
    // Create Account
    Id accrt = [SELECT Id FROM RecordType WHERE DeveloperName = 'Indirect' AND SobjectType = 'Account' LIMIT 1].Id;
    Account acc = new Account(Name='Test Account',RecordTypeId=accrt);
    insert acc;
    // Create Contact
    Contact con = new Contact(FirstName='Face',LastName='Hugger',email='facehugger@alien.com',MobilePhone='07777777777');
    insert con;
    // Create Case
    Id csrt = [SELECT Id FROM RecordType WHERE DeveloperName = 'Bristan_General' AND SobjectType = 'Case' LIMIT 1].Id;
    Case cs = new Case(Subject='Test Case',RecordTypeId=csrt,AccountId=acc.Id,ContactId=con.Id);
    insert cs;
    // Create Work Order
    WorkType wt = new WorkType(CurrencyIsoCode='GBP',DurationType='Minutes',EstimatedDuration=35,FSL__Due_Date_Offset__c=4320,Name='Standard');
    insert wt;
    WorkOrder wo = new WorkOrder(CaseId=cs.Id,WorkTypeId=wt.Id,Job_Postcode__c='B79 8JZ');
    insert wo;
    // Create Service Appointment
    Id sart = [SELECT Id FROM RecordType WHERE DeveloperName = 'Standard' AND SobjectType = 'ServiceAppointment' LIMIT 1].Id;
    Date d = System.today();
    DateTime dts = datetime.newInstance(d, Time.newInstance(08,00,00,00));
    DateTime dte = dts.addHours(1);
    ServiceAppointment sa = new ServiceAppointment(ParentRecordId=wo.Id,Status='None',ContactId=con.Id,EarliestStartTime=dts,SchedStartTime=dte,DueDate=dts,SchedEndTime=dte,Email_Service_Report__c=true);
    insert sa;
    // Create service report
    ServiceReport sr = new ServiceReport();
    sr.DocumentBody = Blob.valueOf('Test Content') ;
    sr.DocumentContentType ='application/pdf';
    sr.DocumentName='Test';
    sr.ParentId = sa.Id;
    insert sr;
  }
}

 
Alison RichardsAlison Richards
Thank you so much especially for the fast reply Snugs, much appreciated! I am not getting any probelms with the trigger or the test class, just don't seem to be sending the report when email service report checkbox is true on the service appointment object, contact_email contains an email and service report is generated capturing client's signature. Not sure if it will make it easier to see it. If yes, can you email me at alison@etcsimplify.com. Maybe  we can do a gotomeeting or teamviewer, if yes I can set up? 
Lukas RuessLukas Ruess
The code and the testclasses up there are super helpfull thank you. We are currently struggling that this E-Mail is really being sent out. We would like that this mail is being sent out by the Org Wide E-Mail Adress. Do you know how we could make the code look like so that this is being sent out by this e-mail adress? Thank you in advance