private EffortDuration getAssignedDuration(
List<? extends DayAssignment> assignments,
final IntraDayDate startInclusive, final IntraDayDate endExclusive) {
final IntraDayDate allocationStart = getIntraDayStartDate();
return EffortDuration.sum(assignments,
new IEffortFrom<DayAssignment>() {
@Override
public EffortDuration from(DayAssignment value) {
PartialDay partial = getPartialDay(value,
startInclusive, endExclusive);
return partial.limitWorkingDay(value.getDuration());
}
private PartialDay getPartialDay(DayAssignment assignment,
IntraDayDate startInclusive,
IntraDayDate endExclusive) {
LocalDate assignmentDay = assignment.getDay();
LocalDate startDate = startInclusive.getDate();
LocalDate endDate = endExclusive.getDate();
PartialDay result = PartialDay.wholeDay(assignment
.getDay());
if (assignmentDay.equals(startDate)) {
result = new PartialDay(startInclusive, result
.getEnd());
}
if (assignmentDay.equals(endDate)) {
result = new PartialDay(result.getStart(),
endExclusive);
}
return adjustPartialDayToAllocationStart(result);
}
// if the start of the allocation is in the middle of a day,
// its work also starts later; so the PartialDay must be
// moved to earlier so it doesn't limit the duration more
// that it should
private PartialDay adjustPartialDayToAllocationStart(
PartialDay day) {
PartialDay result = day;
if (allocationStart.areSameDay(day.getDate())) {
EffortDuration substractingAtStart = day.getStart()
.getEffortDuration();
EffortDuration newSubstractionAtStart = substractingAtStart
.minus(EffortDuration
.min(substractingAtStart,
allocationStart
.getEffortDuration()));
IntraDayDate newStart = IntraDayDate.create(
day.getDate(), newSubstractionAtStart);
result = new PartialDay(newStart, day.getEnd());
}
return result;
}