-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
503 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
...dSystem/src/TeachingRecordSystem.Api/V3/Core/Operations/FindPersonsByTrnAndDateOfBirth.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
using System.Collections.Immutable; | ||
using Microsoft.Xrm.Sdk.Query; | ||
using TeachingRecordSystem.Api.V3.Core.SharedModels; | ||
using TeachingRecordSystem.Core.Dqt; | ||
using TeachingRecordSystem.Core.Dqt.Models; | ||
using TeachingRecordSystem.Core.Dqt.Queries; | ||
|
||
namespace TeachingRecordSystem.Api.V3.Core.Operations; | ||
|
||
public record FindPersonsByTrnAndDateOfBirthCommand(IEnumerable<(string Trn, DateOnly DateOfBirth)> Persons); | ||
|
||
public record FindPersonsByTrnAndDateOfBirthResult(int Total, IReadOnlyCollection<FindPersonsByTrnAndDateOfBirthResultItem> Items); | ||
|
||
public record FindPersonsByTrnAndDateOfBirthResultItem | ||
{ | ||
public required string Trn { get; init; } | ||
public required DateOnly DateOfBirth { get; init; } | ||
public required string FirstName { get; init; } | ||
public required string MiddleName { get; init; } | ||
public required string LastName { get; init; } | ||
public required IReadOnlyCollection<SanctionInfo> Sanctions { get; init; } | ||
public required IReadOnlyCollection<NameInfo> PreviousNames { get; init; } | ||
public required InductionStatusInfo? InductionStatus { get; init; } | ||
public required QtsInfo? Qts { get; init; } | ||
} | ||
|
||
public class FindPersonsByTrnAndDateOfBirthHandler( | ||
ICrmQueryDispatcher crmQueryDispatcher, | ||
PreviousNameHelper previousNameHelper, | ||
ReferenceDataCache referenceDataCache) | ||
{ | ||
public async Task<FindPersonsByTrnAndDateOfBirthResult> Handle(FindPersonsByTrnAndDateOfBirthCommand command) | ||
{ | ||
var contacts = await crmQueryDispatcher.ExecuteQuery( | ||
new GetActiveContactsByTrnsQuery( | ||
command.Persons.Select(p => p.Trn), | ||
new ColumnSet( | ||
Contact.Fields.dfeta_TRN, | ||
Contact.Fields.BirthDate, | ||
Contact.Fields.FirstName, | ||
Contact.Fields.MiddleName, | ||
Contact.Fields.LastName, | ||
Contact.Fields.dfeta_StatedFirstName, | ||
Contact.Fields.dfeta_StatedMiddleName, | ||
Contact.Fields.dfeta_StatedLastName, | ||
Contact.Fields.dfeta_InductionStatus))); | ||
|
||
// Remove any results where the request DOB doesn't match the contact's DOB | ||
// (we can't easily do this in the query itself). | ||
var matched = contacts | ||
.Where(kvp => kvp.Value is not null) | ||
.Where(kvp => command.Persons.Any(p => p.Trn == kvp.Key && p.DateOfBirth == kvp.Value!.BirthDate?.ToDateOnlyWithDqtBstFix(isLocalTime: false))) | ||
.Select(kvp => kvp.Value!) | ||
.ToArray(); | ||
|
||
var contactsById = matched.ToDictionary(c => c.Id, c => c); | ||
|
||
var sanctions = await crmQueryDispatcher.ExecuteQuery( | ||
new GetSanctionsByContactIdsQuery( | ||
contactsById.Keys, | ||
ActiveOnly: true, | ||
new())); | ||
|
||
var previousNames = (await crmQueryDispatcher.ExecuteQuery(new GetPreviousNamesByContactIdsQuery(contactsById.Keys))) | ||
.ToDictionary( | ||
kvp => kvp.Key, | ||
kvp => previousNameHelper.GetFullPreviousNames(kvp.Value, contactsById[kvp.Key])); | ||
|
||
var qtsRegistrations = await crmQueryDispatcher.ExecuteQuery( | ||
new GetActiveQtsRegistrationsByContactIdsQuery( | ||
contactsById.Keys, | ||
new ColumnSet( | ||
dfeta_qtsregistration.Fields.CreatedOn, | ||
dfeta_qtsregistration.Fields.dfeta_EarlyYearsStatusId, | ||
dfeta_qtsregistration.Fields.dfeta_EYTSDate, | ||
dfeta_qtsregistration.Fields.dfeta_QTSDate, | ||
dfeta_qtsregistration.Fields.dfeta_PersonId, | ||
dfeta_qtsregistration.Fields.dfeta_TeacherStatusId))); | ||
|
||
return new FindPersonsByTrnAndDateOfBirthResult( | ||
Total: matched.Length, | ||
Items: await matched | ||
.ToAsyncEnumerable() | ||
.SelectAwait(async r => new FindPersonsByTrnAndDateOfBirthResultItem() | ||
{ | ||
Trn = r.dfeta_TRN, | ||
DateOfBirth = r.BirthDate!.Value.ToDateOnlyWithDqtBstFix(isLocalTime: false), | ||
FirstName = r.ResolveFirstName(), | ||
MiddleName = r.ResolveMiddleName(), | ||
LastName = r.ResolveLastName(), | ||
Sanctions = sanctions[r.Id] | ||
.Where(s => Constants.ExposableSanctionCodes.Contains(s.SanctionCode)) | ||
.Select(s => new SanctionInfo() | ||
{ | ||
Code = s.SanctionCode, | ||
StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true) | ||
}) | ||
.AsReadOnly(), | ||
PreviousNames = previousNames[r.Id] | ||
.Select(name => new NameInfo() | ||
{ | ||
FirstName = name.FirstName, | ||
MiddleName = name.MiddleName, | ||
LastName = name.LastName | ||
}) | ||
.AsReadOnly(), | ||
InductionStatus = r.dfeta_InductionStatus?.ConvertToInductionStatus() is InductionStatus inductionStatus ? | ||
new InductionStatusInfo() | ||
{ | ||
Status = inductionStatus, | ||
StatusDescription = inductionStatus.GetDescription() | ||
} : | ||
null, | ||
Qts = await QtsInfo.Create(qtsRegistrations[r.Id].OrderBy(qr => qr.CreatedOn).FirstOrDefault(), referenceDataCache) | ||
}) | ||
.OrderBy(c => c.Trn) | ||
.ToListAsync()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.