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
Afzaal HassanAfzaal Hassan 

Run apex method after several days

Hello
I am a little stuck on this and am pretty sure I need to use a Schedule Apex Job for this but I am not sure how to modify my class or whether this is the best approach. I already have a class written, which works great. What the class does is that when a client record is created, an email sent to the client owner that displays some information and has some attachments. The reason why I wrote a class instead of workflow etc is because the apex class uses logic to determine what type of email body/template and attachment needs to be selected(based on the client's company). So the apex class generates that body and sends the email. The problem is due to a new business requirement. They want this email sent 2 DAYS AFTER the client is released/created. Here is a snippet of my code. Can someone please let me know what I need to do to use Schedule Apex, or perhaps modify it to use Process Builder? Please let me know what the best way is. I tried using the Schedule apex Trailhead and I am still confused.

global class LM_ChangeAccountRT {
    
    
    @AuraEnabled
    public static String resendEmails(String accountId) {
        String response;
        
        
        try {
            
            Profile sysAdmin = [select id from profile where name='System Administrator']; 
            
            //Only send emails if user is either an ARMS Administor or System Administrator
            if (System.label.ARMS_Administrator_Profile_Id == userinfo.getProfileId() || sysAdmin.Id == userinfo.getProfileId()) {
                Account acc = [SELECT Id,FCA_Dealership__c,Branch_Manager__c,Business_Development_Manager__c,Client_Released__c,Existing_Participant__c,
                                    Dealership_Partner__c,Dealership_State__c,RecordTypeId,owner.email,owner.Supervisor_Email__c,Client_Number__c,Closing_Manager__r.name,
                                    Name,Completed_Date__c,Effective_Date__c,Closing_Manager__c,Is_the_client_receiving_compensation__c,Is_a_broker_receiving_compensation__c,Broker__r.name,
                                    Broker__r.Attention__c,Broker__r.Street_Address_1__c,Broker__r.Street_Address_2__c,Broker__r.ZipCode__c,Broker__r.City__c,Broker__r.State__c,
                                    Broker__r.Special_Notes__c, Business_Development_Manager__r.Email, Branch_Manager__r.Email, Dealership_Spiff_Payment__c, Agent__c, Agent_Email__c, Territory_Manager__c, Territory_Manager_Email__c
                                    FROM Account
                                    WHERE Id=:accountId];
                if (acc.Client_Number__c != null && acc.Client_Released__c) {
                    sendpdfgenerationEmails(acc);
                    response = 'Email Sent';
                }
                return response;
            } else {
                return 'Access Denied';
            }
                   
        } catch(Exception e) {
            System.debug(e.getMessage());
            return 'Error sending emails';
        }
    }
    
    // From Quick Action
    @AuraEnabled
    public static string updateAccountRecordType(String accountId,String rtName){
        string errormsg;
        try{ 
            system.debug('ARMS_Business_User_ProfileId---------->'+System.Label.ARMS_Business_User_ProfileId);    
            if(System.Label.ARMS_Business_User_ProfileId == userinfo.getProfileId())
                {
                    errormsg = 'Business_User';
                }
                else
                {
                    Account acc = [SELECT Id,FCA_Dealership__c,Branch_Manager__c,Business_Development_Manager__c,Client_Released__c,
                        Existing_Participant__c,Dealership_Partner__c,Dealership_State__c,RecordTypeId,owner.email,owner.Supervisor_Email__c,
                        Client_Number__c,Closing_Manager__r.name,Name,Completed_Date__c,Effective_Date__c,Closing_Manager__c,Is_the_client_receiving_compensation__c,
                        Is_a_broker_receiving_compensation__c,BrokerPayee__r.name,BrokerPayee__r.Attention__c, BrokerPayee__c,
                        BrokerPayee__r.Street_Address_1__c,BrokerPayee__r.Street_Address_2__c,BrokerPayee__r.City__c,BrokerPayee__r.State__c,BrokerPayee__r.ZipCode__c,
                        BrokerPayee__r.Special_Notes__c, BrokerPayee__r.Is_this_a_new_broker__c, Dealership_Spiff_Payment__c, Business_Development_Manager__r.Email,
                        Branch_Manager__r.Email, Agent__c, Agent_Email__c, Territory_Manager__c, Territory_Manager_Email__c FROM Account WHERE Id=:accountId];
                    acc.RecordTypeId = [SELECT Id FROM RecordType WHERE DeveloperName =:rtName AND sObjectType = 'Account'].Id;
                    system.debug('acc.Client_Released__c---------->'+acc.Client_Released__c);
                    if(acc.Client_Number__c!=null){
                        if(rtName=='Client_Record' && acc.Client_Released__c==false){ 
                           acc.Client_Released__c=true; 
                        }
                        update acc;
                        if(rtName=='Client_Record'){ 
                            
                            sendpdfgenerationEmails(acc);
                        }
                        if(rtName=='Client_Form_Cancelled'){
                            //Call cancellation approval process
                            //Dev Note Lawrence - Why approval if it is been changed to cancel?? I don't think this makes sense. 
                            Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
                            req1.setComments('Please approve client cancellation');
                            req1.setObjectId(acc.id);
                            req1.setProcessDefinitionNameOrId('LM_ClientCancelationAproval');
                            req1.setSkipEntryCriteria(true);
                            req1.setSubmitterId(acc.ownerid); 
                            Approval.ProcessResult result = Approval.process(req1); 
                        }
                    }
                    else{
                        errormsg = 'DisplayError';
                    } 
                   }
            return errormsg;
        }
        catch(Exception e){
            system.debug(e.getMessage());
            return null; 
        }
    }
    
    /*
    *  Method to send Confirmation card opt-in card by fetching visual force email template setup for different dealership.
    */
    @AuraEnabled
    public static void sendpdfgenerationEmails(Account acc){
         system.debug('start of confirmation card and pdf generation');
        //Logic to find which VF template is used to send an email.
        list<EmailTemplate> templateId = new list<EmailTemplate>();  
        string temppartner;
        String partner_opt_in_attachment;
        boolean sendFCAmail;
       
        List<Dealership_PDF_Generation__c> custsettingdata = Dealership_PDF_Generation__c.getall().values();
        System.debug('custom setting size = ' + custsettingdata.size());
        // Fetch State
        if(acc.Dealership_State__c!=null && acc.Dealership_Partner__c!=null)
        {
            for(Dealership_PDF_Generation__c tempcustsetting :custsettingdata)
            
            {   
                if(acc.Dealership_Partner__c == tempcustsetting.Dealership_Partner__c && acc.Dealership_State__c==tempcustsetting.State__c  && tempcustsetting.State__c=='WA' && acc.Dealership_State__c=='WA'){
                 
                        //For WA State
                       // temppartner= '%' + tempcustsetting.TEMPLATE_Unique_name__c + '%';
                        temppartner= tempcustsetting.TEMPLATE_Unique_name__c;
                        if(acc.Dealership_Spiff_Payment__c == '% premium'){
                            partner_opt_in_attachment=tempcustsetting.opt_in_form_premium__c;
                        }else{
                            partner_opt_in_attachment=tempcustsetting.opt_in_form_nonpremium__c;
                        }
                } 
                else if(acc.Dealership_Partner__c == tempcustsetting.Dealership_Partner__c && acc.Dealership_State__c==tempcustsetting.State__c  && tempcustsetting.State__c=='TX' && acc.Dealership_State__c=='TX'){
                     //For TX State 
                        //temppartner= '%' + tempcustsetting.TEMPLATE_Unique_name__c + '%'; 
                        temppartner= tempcustsetting.TEMPLATE_Unique_name__c;
                        if(acc.Dealership_Spiff_Payment__c == '% premium'){
                            partner_opt_in_attachment=tempcustsetting.opt_in_form_premium__c;
                        }else{
                            partner_opt_in_attachment=tempcustsetting.opt_in_form_nonpremium__c;
                        }
                }
                else if(acc.Dealership_Partner__c == tempcustsetting.Dealership_Partner__c && acc.Dealership_State__c!=tempcustsetting.State__c && tempcustsetting.State__c!='TX' && acc.Dealership_State__c!='TX' && acc.Dealership_State__c!='WA' &&tempcustsetting.State__c!='WA' ){
                      //For Non TX State
                      //temppartner= '%' + tempcustsetting.TEMPLATE_Unique_name__c + '%';
                      temppartner= tempcustsetting.TEMPLATE_Unique_name__c;
                      if(acc.Dealership_Spiff_Payment__c == '% premium'){
                            partner_opt_in_attachment=tempcustsetting.opt_in_form_premium__c;
                        }else{
                            partner_opt_in_attachment=tempcustsetting.opt_in_form_nonpremium__c;
                        }
                      system.debug('grabbed template: ' + temppartner);
                }
                //else if(acc.Dealership_Partner__c == tempcustsetting.Dealership_Partner__c) {
                     //temppartner= '%' + tempcustsetting.TEMPLATE_Unique_name__c + '%';
                //   temppartner= tempcustsetting.TEMPLATE_Unique_name__c;
                //   partner_opt_in_attachment = tempcustsetting.Opt_in_form__c;
                     
                //   system.debug('grabbed template: ' + temppartner);
                //}
            } 
        } 
        if(acc.Dealership_Partner__c != null && temppartner!=null ){
              system.debug('temppartner------------->'+temppartner);
              if(temppartner.contains('FCA') && acc.FCA_Dealership__c==true){ 
                  sendFCAmail = true;
              }
              else if(!temppartner.contains('FCA')){
                  sendFCAmail = true; 
              }
              else{
                   sendFCAmail = false; 
              } 

              // PWC originally used a LIKE in the where clause.  That didn't work for the way we built the Service Program template.
              templateId.add([Select id,DeveloperName from EmailTemplate where DeveloperName = :temppartner]);
             
        } 
        
        
        if(templateId!=null && templateId.size() > 0 && sendFCAmail){  
            string accwhatid = acc.id; 
            string emailid = acc.owner.id;
            string Supervisoremailid;
            string BDMcontact;
            string territoryManagerEmail = acc.Territory_Manager_Email__c;
            string agentEmail = acc.Agent_Email__c;
            
            if(acc.Branch_Manager__c!=null){
               Supervisoremailid = acc.Branch_Manager__c;
            } 
            if(acc.Business_Development_Manager__c!=null){  
                        BDMcontact = acc.Business_Development_Manager__c;
            } 
            list<Messaging.SingleEmailMessage> emails = new list<Messaging.SingleEmailMessage>(); 
             
            if(emailid!=null && acc.Owner.Email!= null){    
                    Messaging.SingleEmailMessage messageowner = new Messaging.SingleEmailMessage(); 
                    messageowner.setTemplateId(templateId[0].id); // Id of template that needs to rendered
                    messageowner.setTargetObjectId(emailid); // setTargetObjectId= user to which we need to send an email
                    messageowner.setSaveAsActivity(false);  // This is set as false while calling from apex
                    messageowner.setWhatId(accwhatid);   // Whatid is the ID of account used in template for merge fields
                    emails.add(messageowner);
            } 
            if(Supervisoremailid!=null && acc.Branch_Manager__r.Email != null){
                    Messaging.SingleEmailMessage messageSupervisor = new Messaging.SingleEmailMessage(); 
                    messageSupervisor.setTemplateId(templateId[0].id); // Id of template that needs to rendered
                    messageSupervisor.setTargetObjectId(Supervisoremailid); // setTargetObjectId= user to which we need to send an email
                    messageSupervisor.setSaveAsActivity(false); 
                    messageSupervisor.setWhatId(accwhatid);   // Whatid is the ID of account used in template for merge fields
                    emails.add(messageSupervisor);
            }  
            if(BDMcontact!=null && acc.Business_Development_Manager__r.email != null){
                    Messaging.SingleEmailMessage messageContact = new Messaging.SingleEmailMessage(); 
                    messageContact.setTemplateId(templateId[0].id); // Id of template that needs to rendered
                    messageContact.setTargetObjectId(BDMcontact); // setTargetObjectId= user to which we need to send an email
                    messageContact.setSaveAsActivity(false); // This is set as false while calling from apex
                    messageContact.setWhatId(accwhatid);   // Whatid is the ID of account used in template for merge fields
                    emails.add(messageContact);
            } 
                
            if(acc.Dealership_Partner__c.contains('EAM Non-OEM') && territoryManagerEmail!=null && emailid!=null && acc.Owner.Email!= null){
                Messaging.SingleEmailMessage agentMessage = new Messaging.SingleEmailMessage(); 
                String[] toAgent = new String[] {agentEmail};
                String[] tomEmail = new String[] {'Thomas.Papke@LibertyMutual.com'};
                agentMessage.setTemplateId(templateId[0].id); // Id of template that needs to rendered
                agentMessage.setTargetObjectId(emailid); // setTargetObjectId= user to which we need to send an email
                agentMessage.setToAddresses(toAgent);
                tomEmail.add(territoryManagerEmail);
                agentMessage.setccAddresses(tomEmail);
                agentMessage.setSaveAsActivity(false); // This is set as false while calling from apex
                agentMessage.setWhatId(accwhatid);   // Whatid is the ID of account used in template for merge fields
                emails.add(agentMessage);
            }
            
            // If available attach the opt-in card
            if (partner_opt_in_attachment != null) {
                StaticResource sr = [Select  s.Name, s.Id, s.Body From StaticResource s where s.Name =: partner_opt_in_attachment]; // 'static_resource' is the name of the static resource PDF.
                
                Blob tempBlob = sr.Body;
                
                Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
                efa.setBody(tempBlob);
                efa.setFileName('Opt-in.pdf');
                
                List<Messaging.EmailFileAttachment> attachments = new List<Messaging.EmailFileAttachment>();
                attachments.add(efa);
                // add attachment to each email
                for (Messaging.SingleEmailMessage email : emails) {
                    email.setFileAttachments(attachments);
                }
                
            }
            system.debug('email sent: ' + emails.size());
            Messaging.sendEmail(emails); 
            
        }
    } 
}

Thank you everyone for your help
Raj VakatiRaj Vakati
They only wany you can do it .. Call that method form the scheduler and run it on the time you want 
Afzaal HassanAfzaal Hassan
@raj vakati do you have an example or pseudo code to get me started with this?