Skip to content

Commit

Permalink
Start adding recurrence code
Browse files Browse the repository at this point in the history
  • Loading branch information
lmeerkatz committed Aug 16, 2024
1 parent b644a60 commit bfe5e80
Show file tree
Hide file tree
Showing 8 changed files with 602 additions and 0 deletions.
53 changes: 53 additions & 0 deletions force-app/volunteers/classes/DailyIterable.cls
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;
}
}
5 changes: 5 additions & 0 deletions force-app/volunteers/classes/DailyIterable.cls-meta.xml
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>
134 changes: 134 additions & 0 deletions force-app/volunteers/classes/MonthlyIterable.cls
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;
}
}
}
5 changes: 5 additions & 0 deletions force-app/volunteers/classes/MonthlyIterable.cls-meta.xml
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>
Loading

0 comments on commit bfe5e80

Please sign in to comment.