Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per child location #794

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a284e5c
Update calculation functions to work with date only
PabloDinella Sep 12, 2024
e474d32
Add a unit test in CalculateMissingMonitoringRequirementInstances
PabloDinella Sep 16, 2024
9c28da0
Include unit tests for the ongoing bug of a completion in the same da…
PabloDinella Sep 26, 2024
bc8c7aa
Create new logic for calculating missing requirements in recurrence p…
PabloDinella Oct 22, 2024
4c05fad
Update calculation for per child policies
PabloDinella Oct 31, 2024
50372d5
Remove `isFirst` param from recurrence calculations
PabloDinella Nov 1, 2024
a9aa293
Review comments & minor edits
LarsKemmann Nov 4, 2024
c2b9c0a
Move DateOfInterest to a new file and convert to record
PabloDinella Nov 4, 2024
a76dcf1
Clean up unnecessary params and tidy up recursion function
PabloDinella Nov 4, 2024
824290e
Improve semantics for GetPossiblyDiscontinuousWindowBasedOnChildLocat…
PabloDinella Nov 5, 2024
e1408ca
Create a dedicated ChildLocation for ReferralCalculations and improve…
PabloDinella Nov 5, 2024
5572931
Simplify GetWindow functions
PabloDinella Nov 5, 2024
291cf87
Code cleanup (namespaces & sealing records)
LarsKemmann Nov 5, 2024
ed3f722
Suggestion to change recursion with conditions to a loop with iterator
LarsKemmann Nov 5, 2024
3382975
Converted CalculateDatesOfInterest recursion with conditions to iterator
LarsKemmann Nov 5, 2024
7534ecc
Fixed while-plus-one condition
LarsKemmann Nov 5, 2024
86dbd61
Renamed method arguments for consistency
LarsKemmann Nov 5, 2024
942f423
Remaining code cleanup challenge
LarsKemmann Nov 5, 2024
b77c81d
WIP: New approach to calculating windows of requirement completion
PabloDinella Nov 6, 2024
ab3e710
Fixes in discontinuous timeline logic and Timeline methods improvements
PabloDinella Nov 7, 2024
5d48916
Names cleanup
PabloDinella Nov 7, 2024
98b136e
WIP restart policies when child change location to a new volunteer fa…
PabloDinella Nov 8, 2024
9601ed7
Restart policies when child location family changes
PabloDinella Nov 8, 2024
7e4ee6a
Some cleanup and method renaming
PabloDinella Nov 11, 2024
a74918a
Some more cleanup and unit tests addition
PabloDinella Nov 11, 2024
b83d8be
Rename DateOnlyTimeline.FirstDay and LastDay to Start and End
PabloDinella Nov 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/CareTogether.Core/Engines/PolicyEvaluation/ChildLocation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;

namespace CareTogether.Engines.PolicyEvaluation;

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
@@ -0,0 +1,4 @@
using System;

//NOTE: If there are ever more than two options, IsMissing should become an enum.
public sealed record DateOfInterest(DateOnly Date, bool IsMissing);
494 changes: 274 additions & 220 deletions src/CareTogether.Core/Engines/PolicyEvaluation/ReferralCalculations.cs

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/CareTogether.Core/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,25 @@ public static async IAsyncEnumerable<U> SelectManyAsync<T, U>(this IEnumerable<T
await foreach (var result in selector(value))
yield return result;
}

public static IEnumerable<T> TakeWhilePlusOne<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
if (predicate(current))
{
yield return current;
}
else
{
yield return current;
break;
}
}
}
}
}
}
50 changes: 50 additions & 0 deletions src/Timelines/DateOnlyTimeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public DateOnlyTimeline(ImmutableList<DateRange> ranges)
}
}

public DateOnly Start =>
Ranges.First().Start;

public DateOnly End =>
Ranges.Last().End;

public static DateOnlyTimeline? UnionOf(ImmutableList<DateOnlyTimeline?> timelines)
{
Expand Down Expand Up @@ -275,6 +280,51 @@ public override int GetHashCode()
hashCode.Add(range.GetHashCode());
return hashCode.ToHashCode();
}

/// <summary>
/// Returns a new DateOnlyTimeline that includes up to the specified number of days from the start of this timeline.
/// For discontinuous timelines, this will include ranges in order until the total length is reached.
/// If the requested length is greater than or equal to the total days in this timeline, returns this timeline unchanged.
/// </summary>
/// <param name="requestedLength">The maximum number of days to include in the new timeline</param>
/// <returns>A new DateOnlyTimeline containing up to the specified number of days from the start of this timeline</returns>
/// <exception cref="ArgumentException">Thrown when requestedLength is not positive</exception>
public DateOnlyTimeline? TakeDays(int requestedLength)
{
if (requestedLength <= 0)
throw new ArgumentException("Requested length must be positive.", nameof(requestedLength));

// If total length is already within limit, return unchanged
var totalLength = Ranges.Sum(r => r.TotalDaysInclusive);
if (totalLength <= requestedLength)
return this;

var remainingTotalLength = requestedLength;
var newRanges = new List<DateRange>();

foreach (var range in Ranges)
{
if (remainingTotalLength <= 0)
break;

// Only take part of this range up to remaining length
var newRange = range.TakeDays(remainingTotalLength);
newRanges.Add(newRange);
remainingTotalLength -= newRange.TotalDaysInclusive;
}

return new DateOnlyTimeline(newRanges.ToImmutableList());
}

/// <summary>
/// Gets the total number of days in this timeline, inclusive of both the start and end dates of each range.
/// For discontinuous timelines, this is the sum of the lengths of each range.
/// </summary>
/// <returns>The total number of days in this timeline</returns>
public int TotalDaysInclusive()
{
return Ranges.Sum(range => range.TotalDaysInclusive);
}
}

public sealed class DateOnlyTimeline<T> : IEquatable<DateOnlyTimeline<T>>
Expand Down
20 changes: 20 additions & 0 deletions src/Timelines/DateRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ public DateRange(DateOnly start, DateOnly end)
End = end;
}

/// <summary>
/// Gets the total number of days in this date range, inclusive of both the start and end dates.
/// </summary>
public int TotalDaysInclusive =>
End.DayNumber - Start.DayNumber + 1;

/// <summary>
/// Returns a new DateRange that includes up to the specified number of days from the start of this range.
/// If the requested length is greater than or equal to the total days in this range, returns this range unchanged.
/// </summary>
/// <param name="requestedLength">The maximum number of days to include in the new range</param>
/// <returns>A new DateRange containing up to the specified number of days from the start of this range</returns>
public DateRange TakeDays(int requestedLength)
{
if (TotalDaysInclusive <= requestedLength)
return this;

return new DateRange(Start, Start.AddDays(requestedLength - 1));
}


public bool Contains(DateOnly value) =>
value >= Start && value <= End;
Expand Down
12 changes: 12 additions & 0 deletions src/caretogether-pwa/src/GeneratedClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5969,6 +5969,8 @@ export interface IFamilyRoleRequirementCompletionStatus {

export class DateOnlyTimeline implements IDateOnlyTimeline {
ranges?: DateRange[];
start?: Date;
end?: Date;

constructor(data?: IDateOnlyTimeline) {
if (data) {
Expand All @@ -5986,6 +5988,8 @@ export class DateOnlyTimeline implements IDateOnlyTimeline {
for (let item of _data["ranges"])
this.ranges!.push(DateRange.fromJS(item));
}
this.start = _data["start"] ? new Date(_data["start"].toString()) : <any>undefined;
this.end = _data["end"] ? new Date(_data["end"].toString()) : <any>undefined;
}
}

Expand All @@ -6003,17 +6007,22 @@ export class DateOnlyTimeline implements IDateOnlyTimeline {
for (let item of this.ranges)
data["ranges"].push(item.toJSON());
}
data["start"] = this.start ? formatDate(this.start) : <any>undefined;
data["end"] = this.end ? formatDate(this.end) : <any>undefined;
return data;
}
}

export interface IDateOnlyTimeline {
ranges?: DateRange[];
start?: Date;
end?: Date;
}

export class DateRange implements IDateRange {
start?: Date;
end?: Date;
totalDaysInclusive?: number;

constructor(data?: IDateRange) {
if (data) {
Expand All @@ -6028,6 +6037,7 @@ export class DateRange implements IDateRange {
if (_data) {
this.start = _data["start"] ? new Date(_data["start"].toString()) : <any>undefined;
this.end = _data["end"] ? new Date(_data["end"].toString()) : <any>undefined;
this.totalDaysInclusive = _data["totalDaysInclusive"];
}
}

Expand All @@ -6042,13 +6052,15 @@ export class DateRange implements IDateRange {
data = typeof data === 'object' ? data : {};
data["start"] = this.start ? formatDate(this.start) : <any>undefined;
data["end"] = this.end ? formatDate(this.end) : <any>undefined;
data["totalDaysInclusive"] = this.totalDaysInclusive;
return data;
}
}

export interface IDateRange {
start?: Date;
end?: Date;
totalDaysInclusive?: number;
}

export class FamilyRequirementStatusDetail implements IFamilyRequirementStatusDetail {
Expand Down
12 changes: 12 additions & 0 deletions swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3545,6 +3545,14 @@
"items": {
"$ref": "#/components/schemas/DateRange"
}
},
"start": {
"type": "string",
"format": "date"
},
"end": {
"type": "string",
"format": "date"
}
}
},
Expand All @@ -3559,6 +3567,10 @@
"end": {
"type": "string",
"format": "date"
},
"totalDaysInclusive": {
"type": "integer",
"format": "int32"
}
}
},
Expand Down
Loading
Loading