Friday 26 May 2017

Apex: Dynamic Scheduling of batch job for quarters from VF page

Schedule Batch job for Quarters from Visualforce Page:

Few days back i get chance to work for a client requirement to give ability to schedule a batch job quarterly from a visualforce page. As you all know that you can not even schedule a batch job quarterly from salesforce UI.


In order to schedule a job on quarterly manner I have to first calculate the dates and time input by your user. I am illustrating my requirements here with screen shots.
  • A picklist to select frequency
  • A picklist to select date option
  • A picklist to select date operator
  • A text box to enter  number of days
  • A picklist for start time




Controller Class Code:


  • First of all calculate first/end of quarter

/************************************GetFirstOfQuarterMonth****************************/
    public Integer GetFirstOfQuarterMonth(){
       
        if(date.today().month() ==1 || date.today().month() ==2 || date.today().month() ==3)
            return 1;
        else if(date.today().month() ==4 ||date.today().month() ==5 || date.today().month() ==6)
            return 4;
        else if(date.today().month() ==7 || date.today().month() ==8 || date.today().month() ==9)
            return 7;
        else
            return 10;
    }
/************************************GetEndOfQuarterMonth****************************/
    public Integer GetEndOfQuarterMonth(){
       
        if(date.today().month() ==1 || date.today().month() ==2 || date.today().month() ==3)
            return 3;
        else if(date.today().month() ==4 ||date.today().month() ==5 || date.today().month() ==6)
            return 6;
        else if(date.today().month() ==7 || date.today().month() ==8 || date.today().month() ==9)
            return 9;
        else
            return 12;
    }


  • Validate Frequency Number


/****************IsValidFrequencyNo***************************/
    public Boolean IsValidFrequencyNo(String Value){
        Boolean flag = false;
        if(Value != null) {
            String CalRegex = '^(?:[1-9]{1}|4[0-6]|2[0-9]|3[0-9]|1[0-9])$';
            Pattern CalPattern    = Pattern.compile(CalRegex);
            Matcher CalMatcher    = CalPattern.matcher(Value.trim());
            flag                    =  CalMatcher.matches();
        }
        return flag;
    }

  • Calculate Cron string

if(SelectedRenewalFrequency == Constants.QUARTERLY){
            String QuarterDate = '';
            
            if(SelectedRenewalFreqDatePeriod == Constants.FIRSTOFQUARTER_VALUE){
                
                if(!String.IsBlank(SelectedRenewalFreqValue) && !String.IsBlank(SelectedRenewalFreqDateOperator)){
                    Integer FOQMonth = GetFirstOfQuarterMonth();//Getting quarter month
                    date startOfQuarter=Date.valueof(Date.today().year()+'-' + FOQMonth +'-1');//Getting start of quarter
                    String AllMonth = '';
                    if(SelectedRenewalFreqDateOperator == Constants.PLUS){
                        if(startOfQuarter.adddays(integer.valueOf(SelectedRenewalFreqValue)) < date.today())
                    startOfQuarter = date.valueOf(startOfQuarter.addMonths(3));
                        QuarterDate = string.valueOf(startOfQuarter.adddays(integer.valueOf(SelectedRenewalFreqValue)).day());
                        Integer MonthNo = Integer.valueOf(startOfQuarter.adddays(integer.valueOf(SelectedRenewalFreqValue)).month()) - FOQMonth;
                        Integer TwelvethMonth = 10+MonthNo; 
                        if(TwelvethMonth >12)
                            TwelvethMonth = MonthNo;
                        AllMonth = String.valueOf(1+MonthNo)+','+String.valueOf(4+MonthNo)+','+String.valueOf(7+MonthNo)+','+String.valueOf(TwelvethMonth);
                    }
                    else{
                    if(startOfQuarter.adddays(integer.valueOf('-'+SelectedRenewalFreqValue)) < date.today())
                    startOfQuarter = date.valueOf(startOfQuarter.addMonths(3));
                        QuarterDate = string.valueOf(startOfQuarter.adddays(integer.valueOf('-'+SelectedRenewalFreqValue)).day());
                        Integer MonthNo = Integer.valueOf(startOfQuarter.adddays(integer.valueOf('-'+SelectedRenewalFreqValue)).month()) - FOQMonth;
                        Integer FirstMonth = 1+MonthNo;
                        if(FirstMonth == 0)
                        FirstMonth = 12;
                        if(String.valueOf(FirstMonth).contains('-')){
                            if(FirstMonth == -1)
                                FirstMonth = 12;
                            else
                                FirstMonth = 11;
                        }
                        Integer TwelvethMonth = 10+MonthNo; 
                        if(TwelvethMonth >12)
                            TwelvethMonth = MonthNo;
                        AllMonth = String.valueOf(FirstMonth)+','+String.valueOf(4+MonthNo)+','+String.valueOf(7+MonthNo)+','+String.valueOf(TwelvethMonth);
                        if(FirstMonth == 12)
                        AllMonth = String.valueOf(4+MonthNo)+','+String.valueOf(7+MonthNo)+','+String.valueOf(TwelvethMonth)+ ','+String.valueOf(FirstMonth);
                    }
                    sch = '0 0 '+ Schdtime+ ' ' + QuarterDate + ' '+ AllMonth + ' ? *';
                }
                else
                    sch = '0 0 ' + Schdtime + ' 1 1,4,7,10 ? *';
            }
            else{
                if(!String.IsBlank(SelectedRenewalFreqValue)&& !String.IsBlank(SelectedRenewalFreqDateOperator)){
                    Integer EOQMonth = GetEndOfQuarterMonth();//Getting quarter month
                    //Getting start of quarter
                    date endOfQuarter=Date.valueof(Date.today().year()+'-' + EOQMonth +'-' + Date.daysInMonth(Date.today().year(), EOQMonth) );
                    if(SelectedRenewalFreqDateOperator == Constants.PLUS){
                    if(endOfQuarter.adddays(integer.valueOf(SelectedRenewalFreqValue)) < date.today())
                    endOfQuarter = date.valueOf(endOfQuarter.addMonths(3));
                        QuarterDate = string.valueOf(endOfQuarter.adddays(integer.valueOf(SelectedRenewalFreqValue)).day());
                        Integer MonthNo = Integer.valueOf(endOfQuarter.adddays(integer.valueOf(SelectedRenewalFreqValue)).month()) - EOQMonth;
                        Integer TwelvethMonth = 12+MonthNo; 
                        if(TwelvethMonth >12)
                            TwelvethMonth = MonthNo;
                        String AllMonth = String.valueOf(3+MonthNo)+','+String.valueOf(6+MonthNo)+','+String.valueOf(9+MonthNo)+','+String.valueOf(TwelvethMonth);
                        sch = '0 0 '+ Schdtime+ ' ' + QuarterDate + ' '+ AllMonth + ' ? *';
                    }
                    else{
                    if(endOfQuarter.adddays(integer.valueOf('-'+SelectedRenewalFreqValue)) < date.today())
                    endOfQuarter = date.valueOf(endOfQuarter.addMonths(3));
                        Integer MonthNo = Integer.valueOf(endOfQuarter.adddays(integer.valueOf('-'+SelectedRenewalFreqValue)).month()) - EOQMonth;
                        Integer TwelvethMonth = 12+MonthNo; 
                        if(TwelvethMonth >12)
                            TwelvethMonth = MonthNo;
                        String AllMonth = String.valueOf(3+MonthNo)+','+String.valueOf(6+MonthNo)+','+String.valueOf(9+MonthNo)+','+String.valueOf(TwelvethMonth);
                        QuarterDate = string.valueOf(endOfQuarter.adddays(integer.valueOf('-'+SelectedRenewalFreqValue)).day());
                        sch = '0 0 '+ Schdtime+ ' ' + QuarterDate + ' '+ AllMonth + ' ? *';
                    }
                }
                else{
                    sch = '0 0 '+ Schdtime +' 30 6,9 ? *';
                    
                }
            }
        }

  • Schedule job
public string JobSchedular(){
string sch = GetCronStringForSchedule();
      string  jobID = system.schedule(BATCH_JOB_NAME, sch, batchjob);
return jobID;
}

Note: Constants is a separate class i have created to keep all my constants at one place and can be used in all classes.

VF page Code:

<apex:selectList label="Date Option" multiselect="false" size="1" id="RenewalFrequencyQuartely" value="{!SelectedRenewalFreqDatePeriod}"
                    rendered="{!IF(SelectedRenewalFrequency == 'Quarterly',true,false)}" disabled="{!IsDisabled}">
                    <apex:selectOptions value="{!FrequencyDatePeriod}"/>
                       <apex:actionSupport event="onchange"  action="{!RenewalFrequencyDatePeriodOnChange}" reRender="pbs10" status="theStatus"/>
                </apex:selectList>
                
                <apex:selectList label="Date Operator" multiselect="false" size="1" id="RenewalFrequencyDateOperator"  value="{!SelectedRenewalFreqDateOperator}"
                    rendered="{!IF(SelectedRenewalFrequency == 'Quarterly',true,false)}" disabled="{!IsDisabled}">
                    <apex:selectOptions value="{!DateOperator}"/>
                </apex:selectList>
                
                <apex:selectList label="Day Of Month" multiselect="false" size="1" id="RenewalFrequencyDayOfMonth"  value="{!SelectedRenewalFreqValue}"
                    rendered="{!IF(SelectedRenewalFrequency == 'Monthly',true,false)}" disabled="{!IsDisabled}">
                    <apex:selectOptions value="{!ListNoOfDayInMonth}"/>
                </apex:selectList>
                
                <apex:inputText label="No. of Days" value="{!SelectedRenewalFreqValue}" id="RenewalFreqMonthly" title="Date can be any value"
                    rendered="{!IF(SelectedRenewalFrequency == 'Quarterly',true,false)}" disabled="{!IsDisabled}"/>
                
                
                <apex:selectList label="Time" multiselect="false" size="1" id="RenewalTime" 
                    value="{!SelectedRenewalTime}" disabled="{!IsDisabled}">
                    <apex:selectOptions value="{!FrequencyTime}"/>
                </apex:selectList>

Hope this helps you. Happy Coding !!!

No comments:

Post a Comment