Skip to content

Commit

Permalink
Merge pull request #700 from CareTogether/odata-approvalsv2
Browse files Browse the repository at this point in the history
OData & fixes for Approvals V2
  • Loading branch information
LarsKemmann authored Feb 29, 2024
2 parents 96cef2a + 2de0a09 commit 73264c7
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 59 deletions.
53 changes: 39 additions & 14 deletions src/CareTogether.Api/OData/LiveODataModelController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,19 @@ public sealed record Address(
public sealed record FamilyRoleApproval(
[property: ForeignKey("FamilyId")] Family Family, [property: Key] Guid FamilyId,
[property: ForeignKey("RoleName")] Role Role, [property: Key] string RoleName,
ImmutableList<DateRange<RoleApprovalStatus>>? ApprovalStatusRanges);
[property: Key] DateOnly Start, [property: Key] DateOnly End, RoleApprovalStatus? Status);

public sealed record IndividualRoleApproval(
[property: ForeignKey("PersonId")] Person Person, [property: Key] Guid PersonId,
[property: ForeignKey("RoleName")] Role Role, [property: Key] string RoleName,
ImmutableList<DateRange<RoleApprovalStatus>>? ApprovalStatusRanges);
[property: ForeignKey("FamilyId")] Family Family, Guid FamilyId,
[property: Key] DateOnly Start, [property: Key] DateOnly End, RoleApprovalStatus? Status);

public sealed record IndividualRemovedRole(
public sealed record FamilyRoleRemovedIndividual(
[property: ForeignKey("PersonId")] Person Person, [property: Key] Guid PersonId,
[property: ForeignKey("RoleName")] Role Role, [property: Key] string RoleName);
[property: ForeignKey("RoleName")] Role Role, [property: Key] string RoleName,
[property: ForeignKey("FamilyId")] Family Family, Guid FamilyId,
[property: Key] DateOnly Start, [property: Key] DateOnly End);

public sealed record Role([property: Key] string Name);

Expand Down Expand Up @@ -93,6 +96,7 @@ public sealed record LiveModel(IEnumerable<Location> Locations,
IEnumerable<Role> Roles,
IEnumerable<FamilyRoleApproval> FamilyRoleApprovals,
IEnumerable<IndividualRoleApproval> IndividualRoleApprovals,
IEnumerable<FamilyRoleRemovedIndividual> FamilyRoleRemovedIndividuals,
IEnumerable<Referral> Referrals,
IEnumerable<Arrangement> Arrangements,
IEnumerable<ArrangementType> ArrangementTypes,
Expand Down Expand Up @@ -162,6 +166,13 @@ public async Task<IEnumerable<IndividualRoleApproval>> GetIndividualRoleApproval
return liveModel.IndividualRoleApprovals;
}

[HttpGet("FamilyRoleRemovedIndividuals")]
public async Task<IEnumerable<FamilyRoleRemovedIndividual>> GetFamilyRoleRemovedIndividualsAsync()
{
var liveModel = await RenderLiveModelAsync();
return liveModel.FamilyRoleRemovedIndividuals;
}

[HttpGet("Referral")]
public async Task<IEnumerable<Referral>> GetReferralsAsync()
{
Expand Down Expand Up @@ -259,6 +270,8 @@ private async Task<LiveModel> RenderLiveModelInternalAsync(Guid organizationId)
.SelectMany(x => RenderFamilyRoleApprovals(x.Item1, x.Item2, roles)).ToArray();
var individualRoleApprovals = familiesWithInfo
.SelectMany(x => RenderIndividualRoleApprovals(x.Item1, x.Item2, people, roles)).ToArray();
var familyRoleRemovedIndividuals = familiesWithInfo
.SelectMany(x => RenderFamilyRoleRemovedIndividuals(x.Item1, x.Item2, people, roles)).ToArray();

var referrals = familiesWithInfo.SelectMany(x => RenderReferrals(x.Item1, x.Item2)).ToArray();

Expand All @@ -277,7 +290,7 @@ private async Task<LiveModel> RenderLiveModelInternalAsync(Guid organizationId)
var individualFunctionAssignments = familiesWithInfo.SelectMany(x => RenderIndividualFunctionAssignments(x.Item1, x.Item2, families, people, arrangements)).ToArray();

return new LiveModel(locations, families, people,
roles, familyRoleApprovals, individualRoleApprovals,
roles, familyRoleApprovals, individualRoleApprovals, familyRoleRemovedIndividuals,
referrals, arrangements, arrangementTypes,
childLocationRecords, familyFunctionAssignments, individualFunctionAssignments);
}
Expand Down Expand Up @@ -345,25 +358,37 @@ private static IEnumerable<FamilyRoleApproval> RenderFamilyRoleApprovals(
CombinedFamilyInfo familyInfo, Family family, Role[] roles)
{
return familyInfo.VolunteerFamilyInfo?.FamilyRoleApprovals
.Select(fra =>
new FamilyRoleApproval(family, family.Id,
.SelectMany(fra => fra.Value.EffectiveRoleApprovalStatus?.Ranges
.Select(range => new FamilyRoleApproval(family, family.Id,
roles.Single(role => role.Name == fra.Key), fra.Key,
fra.Value.EffectiveRoleApprovalStatus?.Ranges))
?? Enumerable.Empty<FamilyRoleApproval>();
//TODO: Include *when approval began* (requires returning *all* the approvals and adding a 'Since' date property!)
range.Start, range.End, range.Tag)) ?? []) ?? [];
}

private static IEnumerable<IndividualRoleApproval> RenderIndividualRoleApprovals(
CombinedFamilyInfo familyInfo, Family family, Person[] people, Role[] roles)
{
return familyInfo.VolunteerFamilyInfo?.IndividualVolunteers
.SelectMany(individual => individual.Value.ApprovalStatusByRole
.Select(ira =>
new IndividualRoleApproval(
.SelectMany(ira => ira.Value.EffectiveRoleApprovalStatus?.Ranges
.Select(range => new IndividualRoleApproval(
people.Single(person => person.Id == individual.Key), individual.Key,
roles.Single(role => role.Name == ira.Key), ira.Key,
ira.Value.EffectiveRoleApprovalStatus?.Ranges)))
?? Enumerable.Empty<IndividualRoleApproval>();
family, family.Id,
range.Start, range.End, range.Tag)) ?? []) ?? []) ?? [];
}

private static IEnumerable<FamilyRoleRemovedIndividual> RenderFamilyRoleRemovedIndividuals(
CombinedFamilyInfo familyInfo, Family family, Person[] people, Role[] roles)
{
return familyInfo.VolunteerFamilyInfo?.IndividualVolunteers
.SelectMany(individual => individual.Value.RoleRemovals
.Where(removal =>
familyInfo.VolunteerFamilyInfo.FamilyRoleApprovals.Keys.Contains(removal.RoleName))
.Select(removal => new FamilyRoleRemovedIndividual(
people.Single(person => person.Id == individual.Key), individual.Key,
roles.Single(role => role.Name == removal.RoleName), removal.RoleName,
family, family.Id,
removal.EffectiveSince, removal.EffectiveUntil ?? DateOnly.MaxValue))) ?? [];
}

private static IEnumerable<Referral> RenderReferrals(
Expand Down
2 changes: 1 addition & 1 deletion src/CareTogether.Api/OData/ODataModelProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static IEdmModel GetLiveEdmModel()
builder.EntitySet<Role>("Role");
builder.EntitySet<FamilyRoleApproval>("FamilyRoleApprovals");
builder.EntitySet<IndividualRoleApproval>("IndividualRoleApprovals");
builder.EntitySet<IndividualRemovedRole>("IndividualRemovedRoles");
builder.EntitySet<FamilyRoleRemovedIndividual>("FamilyRoleRemovedIndividuals");
builder.EntitySet<Referral>("Referral");
builder.EntitySet<Arrangement>("Arrangement");
builder.EntitySet<ArrangementType>("ArrangementType");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ internal static ImmutableDictionary<string, FamilyRoleApprovalStatus>
ImmutableDictionary<Guid, ImmutableList<RoleRemoval>> individualRoleRemovals)
{
var allFamilyRoleApprovals = volunteerFamilyRoles
.Where(rolePolicy =>
!familyRoleRemovals.Any(x => x.RoleName == rolePolicy.Key))
.ToImmutableDictionary(
rolePolicy => rolePolicy.Key,
rolePolicy => CalculateFamilyRoleApprovalStatus(
rolePolicy.Key, rolePolicy.Value,
family,
completedFamilyRequirements, exemptedFamilyRequirements,
familyRoleRemovals,
familyRoleRemovals.Where(role => role.RoleName == rolePolicy.Key).ToImmutableList(),
completedIndividualRequirements, exemptedIndividualRequirements,
individualRoleRemovals));

Expand All @@ -43,7 +41,7 @@ internal static FamilyRoleApprovalStatus
string roleName, VolunteerFamilyRolePolicy rolePolicy, Family family,
ImmutableList<CompletedRequirementInfo> completedFamilyRequirements,
ImmutableList<ExemptedRequirementInfo> exemptedFamilyRequirements,
ImmutableList<RoleRemoval> familyRoleRemovals,
ImmutableList<RoleRemoval> removalsOfThisRole,
ImmutableDictionary<Guid, ImmutableList<CompletedRequirementInfo>> completedIndividualRequirements,
ImmutableDictionary<Guid, ImmutableList<ExemptedRequirementInfo>> exemptedIndividualRequirements,
ImmutableDictionary<Guid, ImmutableList<RoleRemoval>> individualRoleRemovals)
Expand All @@ -53,7 +51,7 @@ internal static FamilyRoleApprovalStatus
CalculateFamilyRoleVersionApprovalStatus(
roleName, policyVersion, family,
completedFamilyRequirements, exemptedFamilyRequirements,
familyRoleRemovals,
removalsOfThisRole,
completedIndividualRequirements, exemptedIndividualRequirements,
individualRoleRemovals))
.ToImmutableList();
Expand All @@ -73,7 +71,7 @@ internal static FamilyRoleVersionApprovalStatus
Family family,
ImmutableList<CompletedRequirementInfo> completedFamilyRequirements,
ImmutableList<ExemptedRequirementInfo> exemptedFamilyRequirements,
ImmutableList<RoleRemoval> familyRoleRemovals,
ImmutableList<RoleRemoval> removalsOfThisRole,
ImmutableDictionary<Guid, ImmutableList<CompletedRequirementInfo>> completedIndividualRequirements,
ImmutableDictionary<Guid, ImmutableList<ExemptedRequirementInfo>> exemptedIndividualRequirements,
ImmutableDictionary<Guid, ImmutableList<RoleRemoval>> individualRoleRemovals)
Expand Down Expand Up @@ -112,8 +110,7 @@ internal static FamilyRoleVersionApprovalStatus
SharedCalculations.CalculateRoleVersionApprovalStatus(
requirementCompletions
.Select(x => (x.Stage, x.WhenMet)).ToImmutableList(),
familyRoleRemovals
.Where(x => x.RoleName == roleName).ToImmutableList());
removalsOfThisRole);

return new FamilyRoleVersionApprovalStatus(
policyVersion.Version, roleVersionApprovalStatus,
Expand Down
10 changes: 5 additions & 5 deletions src/caretogether-pwa/src/Families/AdultCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ export function AdultCard({ familyId, personId }: AdultCardProps) {

const participatingFamilyRoles =
Object.entries(family.volunteerFamilyInfo?.familyRoleApprovals || {}).filter(
([role,]) => !family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.removedRoles?.find(x => x.roleName === role));
([role,]) => !family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.roleRemovals?.find(x => x.roleName === role));
const participatingIndividualRoles =
Object.entries(family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.individualRoleApprovals || {}).filter(
([role,]) => !family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.removedRoles?.find(x => x.roleName === role));
const removedRoles = family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.removedRoles || [];
Object.entries(family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.approvalStatusByRole || {}).filter(
([role,]) => !family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.roleRemovals?.find(x => x.roleName === role));
const removedRoles = family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.roleRemovals || [];

return <>{adult?.item1 && adult.item1.id && adult.item2 &&
<Card variant="outlined" sx={{ minWidth: '275px' }}>
Expand Down Expand Up @@ -130,7 +130,7 @@ export function AdultCard({ familyId, personId }: AdultCardProps) {
}} component="div">
{Object.entries(family.volunteerFamilyInfo?.individualVolunteers?.[adult.item1.id].approvalStatusByRole || {}).map(([role, roleApprovalStatus]) =>
<VolunteerRoleApprovalStatusChip key={role} roleName={role} status={roleApprovalStatus.effectiveRoleApprovalStatus} />)}
{(family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.removedRoles || []).map(removedRole =>
{(family.volunteerFamilyInfo?.individualVolunteers?.[personId]?.roleRemovals || []).map(removedRole =>
<Chip key={removedRole.roleName} size="small" label={`${removedRole.roleName} - ${RoleRemovalReason[removedRole.reason!]} - ${removedRole.additionalComments}`} />)}
{(adult.item2.relationshipToFamily && <Chip size="small" label={adult.item2.relationshipToFamily} />) || null}
{adult.item2.isInHousehold && <Chip size="small" label="In Household" />}
Expand Down
10 changes: 5 additions & 5 deletions src/caretogether-pwa/src/Families/FamilyScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function FamilyScreen() {

const participatingFamilyRoles =
Object.entries(family?.volunteerFamilyInfo?.familyRoleApprovals || {}).filter(
([role,]) => !family?.volunteerFamilyInfo?.removedRoles?.find(x => x.roleName === role));
([role,]) => !family?.volunteerFamilyInfo?.roleRemovals?.find(x => x.roleName === role));

const [removeRoleParameter, setRemoveRoleParameter] = useState<{ volunteerFamilyId: string, role: string } | null>(null);
function selectRemoveRole(role: string) {
Expand Down Expand Up @@ -180,8 +180,8 @@ export function FamilyScreen() {
</Button>}
{permissions(Permission.EditVolunteerRoleParticipation) &&
(participatingFamilyRoles.length > 0 ||
(family.volunteerFamilyInfo?.removedRoles &&
family.volunteerFamilyInfo.removedRoles.length > 0)) &&
(family.volunteerFamilyInfo?.roleRemovals &&
family.volunteerFamilyInfo.roleRemovals.length > 0)) &&
<IconButton
onClick={(event) => setFamilyMoreMenuAnchor(event.currentTarget)}
size="large">
Expand All @@ -200,7 +200,7 @@ export function FamilyScreen() {
</MenuItem>
))}
{permissions(Permission.EditVolunteerRoleParticipation) &&
(family.volunteerFamilyInfo?.removedRoles || []).map(removedRole => (
(family.volunteerFamilyInfo?.roleRemovals || []).map(removedRole => (
<MenuItem key={removedRole.roleName}
onClick={() => selectResetRole(removedRole.roleName!, removedRole.reason!, removedRole.additionalComments!)}>
<ListItemText primary={`Reset ${removedRole.roleName} participation`} />
Expand Down Expand Up @@ -335,7 +335,7 @@ export function FamilyScreen() {
}}>
{Object.entries(family.volunteerFamilyInfo?.familyRoleApprovals || {}).flatMap(([role, roleApprovalStatus]) =>
<VolunteerRoleApprovalStatusChip key={role} roleName={role} status={roleApprovalStatus.effectiveRoleApprovalStatus} />)}
{(family.volunteerFamilyInfo?.removedRoles || []).map(removedRole =>
{(family.volunteerFamilyInfo?.roleRemovals || []).map(removedRole =>
<Chip key={removedRole.roleName} size="small" label={`${removedRole.roleName} - ${RoleRemovalReason[removedRole.reason!]} - ${removedRole.additionalComments}`} />)}
</Box>
</Grid>
Expand Down
Loading

0 comments on commit 73264c7

Please sign in to comment.