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.
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;
}
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 ? *';
}
}
}
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 !!!