You're doing more work than you have to in a lot of this code, but the core issue is your approach itself. You should create an Integer
counter variable for the number of days elapsed, then increment a Datetime
pointer.
You also seem to have a fundamental misunderstanding about how the BusinessHours
class works. You don't need to check for yourself if the day is a weekend, that's the job of your hours definition in the first place. If you specify hours for Monday-Friday and none on Saturday or Sunday, then the isWithin
method will always return false on those weekend days. It doesn't just check holidays.
Here's how I would write a utility class to calculate business days:
public class BusinessDays
{
public static BusinessHours defaultHours
{
get
{
if (defaultHours == null)
defaultHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true];
return defaultHours;
}
private set;
}
public static Datetime add(Datetime pointer, Integer days)
{
Integer elapsedpointer = 0;BusinessHours.nextStartDate(defaultHours.Id, pointer);
while// make sure you're starting at a Datetime within BusinessHours
for (Integer elapsed = 0; elapsed < daysdays; elapsed++)
{
pointer = pointer.addDays(1);
if (!BusinessHours.isWithin(defaultHours.Id, pointer)) elapsed++;
else pointer = BusinessHours.nextStartDate(defaultHours.Id, pointer);
}
return pointer;
}
}
Then your code would simplify to:
Datetime dueDate = BusinessDays.add(createdDate, 3);
Note that the output is in GMT, so you may need to adjust it to include timezone offsets.