-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
602 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* | ||
* * Copyright (c) 2020, salesforce.com, inc. | ||
* * All rights reserved. | ||
* * SPDX-License-Identifier: BSD-3-Clause | ||
* * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause | ||
* | ||
*/ | ||
|
||
public with sharing virtual class DailyIterable implements Iterator<Date> { | ||
public RecurrenceRule rRule; | ||
public Date runningDate; | ||
public Integer runningCount; | ||
|
||
public DailyIterable(Date runningDate, RecurrenceRule rRule) { | ||
this.runningDate = runningDate; | ||
this.rRule = rRule; | ||
this.runningCount = 0; | ||
} | ||
|
||
public Boolean hasNext() { | ||
if (rRule == null || runningDate == null) { | ||
return false; | ||
} | ||
|
||
Integer count = rRule.getCount(); | ||
Date endDate = rRule.getEndDate(); | ||
calculateRunningDate(); | ||
|
||
if (count == null && endDate == null) { | ||
// If not present, and the COUNT rule part is also not present, | ||
// the "RRULE" is considered to repeat forever. See: RFC5545 | ||
return true; | ||
} | ||
|
||
Boolean hasReachedCount = count != null && runningCount >= count; | ||
Boolean hasReachedEndDate = endDate != null && runningDate > endDate; | ||
|
||
return !(hasReachedCount || hasReachedEndDate); | ||
} | ||
|
||
public virtual void calculateRunningDate() { | ||
runningDate = runningCount == 0 | ||
? runningDate | ||
: runningDate.addDays(rRule.getInterval()); | ||
} | ||
|
||
public Date next() { | ||
runningCount++; | ||
|
||
return runningDate; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>61.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/* | ||
* | ||
* * Copyright (c) 2020, salesforce.com, inc. | ||
* * All rights reserved. | ||
* * SPDX-License-Identifier: BSD-3-Clause | ||
* * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause | ||
* | ||
*/ | ||
|
||
public with sharing class MonthlyIterable extends DailyIterable { | ||
private List<Integer> byMonthDays; | ||
Integer firstOccurrenceRunningDay; | ||
|
||
public MonthlyIterable(Date runningDate, RecurrenceRule rRule) { | ||
super(runningDate, rRule); | ||
|
||
if (rRule == null || rRule.getByMonthDays() == null) { | ||
return; | ||
} | ||
|
||
byMonthDays = new List<Integer>(rRule.getByMonthDays()); | ||
byMonthDays.sort(); | ||
} | ||
|
||
public override void calculateRunningDate() { | ||
if (runningCount == 0 && rRule.getByDay() == null) { | ||
firstOccurrenceRunningDay = runningDate.day(); | ||
return; // Use first running date; | ||
} | ||
|
||
Integer startDay; | ||
|
||
if (rRule.getBySetPos() != null && byMonthDays != null) { | ||
//The startDay variable will hold the max value that is returned by rRule.getByMonthDays. | ||
startDay = byMonthDays[byMonthDays.size() - 1]; | ||
|
||
if (startDay == 31) { | ||
runningDate = runningDate.addDays(1) | ||
.addMonths(rRule.getInterval()) | ||
.addDays(-1); | ||
} else { | ||
runningDate = runningDate.addMonths(rRule.getInterval()) | ||
.addDays(startDay - runningDate.day()); | ||
} | ||
} else if (rRule.getByDay() != null) { | ||
calculateRecurrenceRunningDate(); | ||
} else { | ||
//The below value is defaulted to the day of the start date and is used to add days to runningDate below. | ||
startDay = runningDate.day(); | ||
|
||
runningDate = runningDate.addMonths(rRule.getInterval()) | ||
.addDays(startDay - runningDate.day()); | ||
|
||
if (firstOccurrenceRunningDay > startDay) { | ||
runningDate = runningDate.addDays( | ||
firstOccurrenceRunningDay - runningDate.day() | ||
); | ||
} | ||
} | ||
} | ||
|
||
public String getRecurrenceWeek() { | ||
String byDay = rRule.getByDay(); | ||
String dayNumber = byDay.subString(1, 2); // This holds first or second | ||
|
||
return dayNumber; | ||
} | ||
|
||
public String getWeekDayAbbr() { | ||
String byDay = rRule.getByDay(); | ||
String weekDayName = byDay.subString(2); //This holds the day name | ||
return weekDayName; | ||
} | ||
|
||
public Date getFirstOccurrenceOfMonth() { | ||
Date firstWeekDayOccurrence; | ||
// We need to see what month and get to the start of the month | ||
Date startOfMonth = runningDate.toStartOfMonth(); | ||
|
||
// Check what day of the week the start of the month is i.e Tuesday, Wednesday | ||
Integer startOfMonthDayNum = Util.getDayNum(startOfMonth); | ||
|
||
String recurrenceWeekDayAbbr = getWeekDayAbbr(); | ||
Integer recurrenceWeekDayNum = rRule.getDayNum(recurrenceWeekDayAbbr) + 1; | ||
if (recurrenceWeekDayNum == startOfMonthDayNum) { | ||
firstWeekDayOccurrence = startOfMonth; | ||
} else if (recurrenceWeekDayNum < startOfMonthDayNum) { | ||
firstWeekDayOccurrence = startOfMonth.addDays( | ||
7 - (startOfMonthDayNum - recurrenceWeekDayNum) | ||
); | ||
} else { | ||
firstWeekDayOccurrence = startOfMonth.addDays( | ||
recurrenceWeekDayNum - startOfMonthDayNum | ||
); | ||
} | ||
|
||
return firstWeekDayOccurrence; | ||
} | ||
|
||
public void calculateRecurrenceRunningDate() { | ||
if (runningCount > 0) { | ||
runningDate = runningDate.toStartOfMonth().addMonths(rRule.getInterval()); | ||
} | ||
|
||
Integer monthlyRecurrenceNumber = Integer.valueOf(getRecurrenceWeek()); | ||
Date firstOccurrenceOfMonth = getFirstOccurrenceOfMonth(); | ||
|
||
if (monthlyRecurrenceNumber == 1) { | ||
runningDate = firstOccurrenceOfMonth; | ||
} else { | ||
Date tempDate = firstOccurrenceOfMonth.addDays( | ||
(monthlyRecurrenceNumber - 1) * 7 | ||
); | ||
|
||
while ( | ||
tempDate.month() > runningDate.month() || | ||
tempDate.year() > runningDate.year() | ||
) { | ||
if (runningCount == 0) { | ||
runningDate = tempDate.toStartOfMonth(); | ||
} else if (runningCount > 0) { | ||
runningDate = runningDate.addMonths(rRule.getInterval()); | ||
} | ||
|
||
firstOccurrenceOfMonth = getFirstOccurrenceOfMonth(); | ||
tempDate = firstOccurrenceOfMonth.addDays( | ||
(monthlyRecurrenceNumber - 1) * 7 | ||
); | ||
} | ||
|
||
runningDate = tempDate; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>61.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
Oops, something went wrong.