Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloDinella committed Dec 13, 2024
1 parent 04ee1de commit a4640ea
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 42 deletions.
14 changes: 1 addition & 13 deletions src/CareTogether.Core/Engines/PolicyEvaluation/ChildLocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,4 @@ public sealed record ChildLocation(
Guid ChildLocationFamilyId,
DateOnly Date,
bool Paused // means "from now on, we stop checking for completion until resuming"
)
: IComparable<ChildLocation>
{
public int CompareTo(ChildLocation? other)
{
return other == null
? 1
: DateTime.Compare(
new DateTime(Date, new TimeOnly()),
new DateTime(other.Date, new TimeOnly())
);
}
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ public async Task<FamilyApprovalStatus> CalculateCombinedFamilyApprovalsAsync(
ImmutableList<Resources.CompletedRequirementInfo> completedFamilyRequirements,
ImmutableList<Resources.ExemptedRequirementInfo> exemptedFamilyRequirements,
ImmutableList<RoleRemoval> familyRoleRemovals,
ImmutableDictionary<Guid, ImmutableList<Resources.CompletedRequirementInfo>> completedIndividualRequirements,
ImmutableDictionary<
Guid,
ImmutableList<Resources.CompletedRequirementInfo>
> completedIndividualRequirements,
ImmutableDictionary<Guid, ImmutableList<Resources.ExemptedRequirementInfo>> exemptedIndividualRequirements,
ImmutableDictionary<Guid, ImmutableList<RoleRemoval>> individualRoleRemovals
)
Expand Down Expand Up @@ -140,7 +143,7 @@ TimeZoneInfo locationTimeZone

var ChildLocationHistory = entry
.ChildLocationHistory.Select(item => ToChildLocation(item, locationTimeZone))
.ToImmutableSortedSet();
.ToImmutableList();

var individualVolunteerAssignments = entry
.IndividualVolunteerAssignments.Select(item =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ internal static ImmutableList<DateOnly> CalculateMissingMonitoringRequirementIns
DateOnly arrangementStartedAtDate,
DateOnly? arrangementEndedAtDate,
ImmutableList<DateOnly> completions,
ImmutableSortedSet<ChildLocation> childLocationHistory,
ImmutableList<ChildLocation> childLocationHistory,
DateOnly today
)
{
Expand Down Expand Up @@ -501,7 +501,7 @@ ImmutableList<DateOnly> completionDates
Guid? filterToFamilyId = null
)
{
var dateRanges = GenerateDateRanges(childLocations).ToImmutableList();
var dateRanges = GenerateDateRanges(childLocations, filterToFamilyId).ToImmutableList();

var filteredDateRanges = (
filterToFamilyId != null ? dateRanges.Where(item => item.Tag == filterToFamilyId) : dateRanges
Expand All @@ -514,43 +514,71 @@ ImmutableList<DateOnly> completionDates
return null;
}

return new DateOnlyTimeline(filteredDateRanges);
// DateOnlyTimeline.FromOverlappingDateRanges();

var nonOverlapping = filteredDateRanges.Aggregate(
ImmutableList<DateRange>.Empty,
(final, item) =>
{
var last = final.LastOrDefault();

if (last.End >= item.Start)
{
return final.Replace(last, new DateRange(last.Start, item.End));
}

return final.Add(item);
}
);

return new DateOnlyTimeline(nonOverlapping);
}

private static IEnumerable<DateRange<Guid>> GenerateDateRanges(ImmutableList<ChildLocation> childLocations)
private static IEnumerable<DateRange<Guid>> GenerateDateRanges(
ImmutableList<ChildLocation> childLocations,
Guid? filterToFamilyId
)
{
(DateOnly, Guid)? entry = null;
(DateOnly Date, Guid ChildLocationFamilyId)? previousChildLocation = null;

foreach (var childLocation in childLocations)
{
if (!entry.HasValue && !childLocation.Paused)
if (!previousChildLocation.HasValue && !childLocation.Paused)
{
entry = (childLocation.Date, childLocation.ChildLocationFamilyId);
previousChildLocation = (childLocation.Date, childLocation.ChildLocationFamilyId);
continue;
}

if (entry.HasValue && !childLocation.Paused)
if (previousChildLocation.HasValue && !childLocation.Paused)
{
yield return new DateRange<Guid>(
entry.Value.Item1,
childLocation.Date.AddDays(-1),
entry.Value.Item2
previousChildLocation.Value.Date,
childLocation.Date,
previousChildLocation.Value.ChildLocationFamilyId
);
entry = (childLocation.Date, childLocation.ChildLocationFamilyId);

previousChildLocation = (childLocation.Date, childLocation.ChildLocationFamilyId);
continue;
}

if (entry.HasValue && childLocation.Paused)
if (previousChildLocation.HasValue && childLocation.Paused)
{
yield return new DateRange<Guid>(entry.Value.Item1, childLocation.Date, entry.Value.Item2);
entry = null;
yield return new DateRange<Guid>(
previousChildLocation.Value.Date,
childLocation.Date,
previousChildLocation.Value.ChildLocationFamilyId
);
previousChildLocation = null;
continue;
}
}

if (entry.HasValue)
if (previousChildLocation.HasValue)
{
yield return new DateRange<Guid>(entry.Value.Item1, entry.Value.Item2);
yield return new DateRange<Guid>(
previousChildLocation.Value.Date,
previousChildLocation.Value.ChildLocationFamilyId
);
}
}

Expand Down Expand Up @@ -715,7 +743,7 @@ internal static ImmutableList<DateOnly> CalculateMissingMonitoringRequirementIns
DateOnly? arrangementEndedDate,
DateOnly today,
ImmutableList<DateOnly> completionDates,
ImmutableSortedSet<ChildLocation> childLocationHistory
ImmutableList<ChildLocation> childLocationHistory
)
{
// Technically, the RecurrencePolicyStage model currently allows any stage to have an unlimited
Expand Down Expand Up @@ -759,7 +787,7 @@ internal static ImmutableList<DateOnly> CalculateMissingMonitoringRequirementIns
ChildCareOccurrenceBasedRecurrencePolicy recurrence,
Guid? filterToFamilyId,
ImmutableList<DateOnly> completionDates,
ImmutableSortedSet<ChildLocation> childLocationHistory
ImmutableList<ChildLocation> childLocationHistory
)
{
// Determine which child care occurrences the requirement will apply to.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ public sealed record ReferralEntry(
ImmutableDictionary<Guid, ArrangementEntry> Arrangements
);

public sealed record CompletedRequirementInfo(
string RequirementName,
DateOnly CompletedAt,
DateOnly? ExpiresAt
);
public sealed record CompletedRequirementInfo(string RequirementName, DateOnly CompletedAt, DateOnly? ExpiresAt);

public sealed record ExemptedRequirementInfo(
string RequirementName,
Expand All @@ -33,7 +29,7 @@ public sealed record ArrangementEntry(
ImmutableList<ExemptedRequirementInfo> ExemptedRequirements,
ImmutableList<IndividualVolunteerAssignment> IndividualVolunteerAssignments,
ImmutableList<FamilyVolunteerAssignment> FamilyVolunteerAssignments,
ImmutableSortedSet<ChildLocation> ChildLocationHistory
ImmutableList<ChildLocation> ChildLocationHistory
);

public sealed record IndividualVolunteerAssignment(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,68 @@ public void CreateTimelineFilteredByFamilyIdNoPauses()
new DateOnlyTimeline([new DateRange(DateOnly.FromDateTime(H.DateTime(1, 20)))])
);
}

[TestMethod]
public void CreateTimelineFilteredByFamilyIdMultipleChangesInSameDay()
{
var hist = H.ChildLocationHistory(
(H.Id('0'), ChildLocationPlan.WithParent, 1, 1),
(H.Id('1'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('2'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('1'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('0'), ChildLocationPlan.WithParent, 1, 15)
);

var result = ReferralCalculations.CreateChildLocationBasedTimeline(hist.ToImmutableList(), H.Id('1'));

AssertEx.SequenceIs(
result,
new DateOnlyTimeline(
[new DateRange(DateOnly.FromDateTime(H.DateTime(1, 10)), DateOnly.FromDateTime(H.DateTime(1, 15)))]
)
);
}

[TestMethod]
public void CreateTimelineFilteredByFamilyIdMultipleChangesInSameDay2()
{
var hist = H.ChildLocationHistory(
(H.Id('0'), ChildLocationPlan.WithParent, 1, 1),
(H.Id('1'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('2'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('1'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('0'), ChildLocationPlan.WithParent, 1, 15)
);

var result = ReferralCalculations.CreateChildLocationBasedTimeline(hist.ToImmutableList(), H.Id('2'));

AssertEx.SequenceIs(
result,
new DateOnlyTimeline(
[new DateRange(DateOnly.FromDateTime(H.DateTime(1, 10)), DateOnly.FromDateTime(H.DateTime(1, 10)))]
)
);
}

[TestMethod]
public void CreateTimelineMultipleChangesInSameDay()
{
var hist = H.ChildLocationHistory(
(H.Id('0'), ChildLocationPlan.WithParent, 1, 1),
(H.Id('1'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('2'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('1'), ChildLocationPlan.DaytimeChildCare, 1, 10),
(H.Id('0'), ChildLocationPlan.WithParent, 1, 15)
);

var result = ReferralCalculations.CreateChildLocationBasedTimeline(hist.ToImmutableList());

AssertEx.SequenceIs(
result,
new DateOnlyTimeline(
[new DateRange(DateOnly.FromDateTime(H.DateTime(1, 10)), DateOnly.FromDateTime(H.DateTime(1, 15)))]
)
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static ImmutableSortedSet<ChildLocationHistoryEntry> LocationHistoryEntri
))
.ToImmutableSortedSet();

public static ImmutableSortedSet<ChildLocation> ChildLocationHistory(
public static ImmutableList<ChildLocation> ChildLocationHistory(
params (Guid childLocationFamilyId, ChildLocationPlan plan, int month, int day)[] values
) =>
values
Expand All @@ -88,7 +88,7 @@ public static ImmutableSortedSet<ChildLocation> ChildLocationHistory(
DateOnly.FromDateTime(DateTime(value.month, value.day)),
value.plan == ChildLocationPlan.WithParent
))
.ToImmutableSortedSet();
.ToImmutableList();

public static ArrangementFunction FunctionWithoutEligibility(
string arrangementFunction,
Expand Down

0 comments on commit a4640ea

Please sign in to comment.