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
Collen Mayer 6Collen Mayer 6 

Use Apex Scheduler to Run Flow First Day of Month

HI All,
I need a solution to run an auto-launched visualwork flow on the first day of each month.  Would this be possible with Apex Scheduler?  Would anyone have any sample code of launching a flow from apex scheduler to help get me started (I've never worked wtih Apex Scheduler before)?

Thanks,
Collen. 
NagendraNagendra (Salesforce Developers) 
Hi Collen, Here is one of my utilities that I use to schedule. I have simplified it a great deal for example purposes, but you should be able to get the gist:
/**
 * @descirption: This is a utility class for scheduled jobs that will execute hourly.
 * Will help reduce complexity by having one area to look in for all classes that need to execute hourly.
 **/
global with sharing class UtilityHourlySchedule implements Schedulable 
{
    /**
     * @description: Executes the schedulable class
     * @param sc: This is the scheduable context variable
     **/
    global void execute(SchedulableContext sc)
    {
        contactInterviewExpiration();
    }
    
    /**
     * @description: This method will check for contcacts that must be reset based on an experiation date
     * and process the ones that need to be modified.
     */
    private static void contactInterviewExpiration()
    {
        try {
            update updateContacts2Clear(checkForContacts2Reset());
        }catch(Exception e){

        }
    }
    
    /**
     * @description: This method will check for expired records.
     * @return list<Contact>: A list of contacts that match the criteria.
     */
    public static List<Contact> checkForContacts2Reset()
    {    
        return  
        [
            select id, Candidate_Status__c, Do_not_contact_before__c
            from Contact
            where Do_not_contact_before__c <=TODAY
        ];
    }
    
    /**
     * @description: This method will take a list of contacs and update them to have a null expiration date
     * as well as a status of active.
     * @param contacts: The list of contacts that will be processed.
     * @return List<Contact>: List of modified contacts that must be adjusted.
     **/
    private static List<Contact> updateContacts2Clear(list<Contact> contacts)
    {
        List<Contact> returnList = new list<Contact>();
        
        if(!contacts.isEmpty())
        {
            for(Contact c: contacts)
            {
                c.Candidate_Status__c = 'Active';
                c.Do_not_contact_before__c = null;
                returnList.add(c);
            }
        }
        
        return returnList;
    }
}
Here is the test class (modified a bit) that would work with it (also, it's 2 years old before some of the new bells and whistles came out
/**
&nbsp;* @description: This is a test utility for the hourly scheduling utility class.
&nbsp;*/
@isTest
private class UtilityHourlyScheduleTest&nbsp;
{
&nbsp;&nbsp; &nbsp;//Declaring some of the items that can be re-used for multiple tests
&nbsp; &nbsp; private static string yr2test = string.valueof(date.today().addYears(10).year());
&nbsp;&nbsp; &nbsp;private static string CRON_EXP = '0 0 0 3 9 ? ' +yr2test;
&nbsp;&nbsp; &nbsp;private static list<Account> candidateAcctList = createAndInsertAccounts(3);
&nbsp;&nbsp; &nbsp;private static list<Contact> candidateList = createAndInsertContacts(1,candidateAcctList);
&nbsp;&nbsp; &nbsp;
&nbsp;&nbsp; &nbsp;/**
&nbsp;&nbsp; &nbsp; * @description: This is a test that will make sure that the interviews reset
&nbsp;&nbsp; &nbsp; */
&nbsp; &nbsp; static testMethod void testSample()&nbsp;
&nbsp; &nbsp; { &nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;//Setting up the the scheduled job to run
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;system.Test.startTest();
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;string jobId = scheduleTestJobUtilityHourlySchedule();
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;CronTrigger ct = [select id, CronExpression, TimesTriggered, NextFireTime from CronTrigger where id = :jobId];
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//Checking to make sure that the epxpressions line up
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;system.assertEquals(CRON_EXP,ct.CronExpression);
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//Verifying it hasn't run yet
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;system.assertEquals(0, ct.TimesTriggered);
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//Verifying that the job will run at the indicated date and time
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;system.assertEquals(yr2test+'-09-03 00:00:00', string.valueOf(ct.NextFireTime));
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;system.Test.stopTest();
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;//Making sure that all of the records were updated
&nbsp; &nbsp; &nbsp; &nbsp; System.assert(UtilityHourlySchedule.checkForContacts2Reset().isEmpty());
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; /**
&nbsp; &nbsp; &nbsp;* @description: This method will generate a system schedule for the utility hourly schedule job.
&nbsp; &nbsp; &nbsp;* @return string: This is the job ID that will be used for validation purposes
&nbsp; &nbsp; &nbsp;**/
&nbsp; &nbsp; private static string scheduleTestJobUtilityHourlySchedule()
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;return System.Schedule('UtilityHourlySchedule_Job',CRON_EXP,new UtilityHourlySchedule());
&nbsp; &nbsp; }
&nbsp; &nbsp; /**
&nbsp; &nbsp; &nbsp;* @description: This method will create and insert a group of accounts
&nbsp; &nbsp; &nbsp;* @param num2Create: The number of accounts to create
&nbsp; &nbsp; &nbsp;* @return list<Account>
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp; private static List<Account> createAndInsertAccounts(integer num2Create)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; List<Account> returnList = new list<Account>();
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; for(integer i=0; i<num2Create; i++){
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; returnList.add(createAccount('Test '+i));
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; insert returnList;

&nbsp; &nbsp; &nbsp; &nbsp; return returnList;
&nbsp; &nbsp; }

&nbsp; &nbsp; /**
&nbsp; &nbsp; &nbsp;* @description: This method will create an account based on the passed account name
&nbsp; &nbsp; &nbsp;* @param acctName: The Account name
&nbsp; &nbsp; &nbsp;* @return Account
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp; public static Account createAccount(string acctName)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; return new Account(
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name = acctName
&nbsp; &nbsp; &nbsp; &nbsp; );
&nbsp; &nbsp; }

&nbsp; &nbsp; /**
&nbsp; &nbsp; &nbsp;* @description: This method will create a list of contacts based on the list of accounts
&nbsp; &nbsp; &nbsp;* @param num2create: How many contacts per account are we creating
&nbsp; &nbsp; &nbsp;* @param acctList: The account list
&nbsp; &nbsp; &nbsp;* @return list<Contact> List of contacts that were created and inserted
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp; private static list<Contact> createAndInsertContacts(integer num2create, list<Account> acctList)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; list<Contact> returnList = new list<Contact>();
&nbsp; &nbsp; &nbsp; &nbsp; Date d = Date.today().addDays(-1);
&nbsp; &nbsp; &nbsp; &nbsp; for(Account a : acctList){
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(integer i = 0; i<num2Create; i++){
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Contact c = createContact('Test Contact '+a.Name,a.Id);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.Do_Not_contact_before__c=d;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.Candidate_Status__c='Do Not Contact';
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; returnList.add(c);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; insert returnList;
&nbsp; &nbsp; &nbsp; &nbsp; return returnList;
&nbsp; &nbsp; }

&nbsp; &nbsp; /**
&nbsp; &nbsp; &nbsp;* @description: This method will create a contact based on the information passed
&nbsp; &nbsp; &nbsp;* @param lName: Last name of the contact
&nbsp; &nbsp; &nbsp;* @param acctID: Account ID of the contact
&nbsp; &nbsp; &nbsp;* @return Contact The contact that was created
&nbsp; &nbsp; &nbsp;*/
&nbsp; &nbsp; private static Contact createContact(string lName, id acctID)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; String areaCode='(123) ';
&nbsp; &nbsp; &nbsp; &nbsp; String prefix='456-';
&nbsp; &nbsp; &nbsp; &nbsp; String num='7890';
&nbsp; &nbsp; &nbsp; &nbsp; return new Contact(
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LastName = lName,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AccountID = acctID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MobilePhone = areaCode+prefix+num);
&nbsp; &nbsp; }
}
Hope this helps.

Kindly mark this as solved if it's resolved so that it gets removed from the unanswered queue which results in helping others who are encountering a similar issue.

Thanks,
Nagendra