Skip to content

Commit

Permalink
Amend the API to get alerts from the TRS DB (#1562)
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad authored Nov 12, 2024
1 parent 3c6ef2c commit 475f8c5
Show file tree
Hide file tree
Showing 54 changed files with 667 additions and 924 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using TeachingRecordSystem.Api.V1.Requests;
using TeachingRecordSystem.Api.V1.Responses;
using TeachingRecordSystem.Api.V2.ApiModels;
using TeachingRecordSystem.Core.DataStore.Postgres;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Dqt.Models;

Expand All @@ -11,10 +12,12 @@ namespace TeachingRecordSystem.Api.V1.Handlers;
public class GetTeacherHandler : IRequestHandler<GetTeacherRequest, GetTeacherResponse>
{
private readonly IDataverseAdapter _dataverseAdapter;
private readonly TrsDbContext _dbContext;

public GetTeacherHandler(IDataverseAdapter dataverseAdapter)
public GetTeacherHandler(IDataverseAdapter dataverseAdapter, TrsDbContext dbContext)
{
_dataverseAdapter = dataverseAdapter;
_dbContext = dbContext;
}

public async Task<GetTeacherResponse> Handle(GetTeacherRequest request, CancellationToken cancellationToken)
Expand Down Expand Up @@ -66,11 +69,13 @@ public async Task<GetTeacherResponse> Handle(GetTeacherRequest request, Cancella
teacher.dfeta_contact_dfeta_qualification = qualifications;
}

var response = MapContactToResponse(teacher);
var hasActiveAlert = await _dbContext.Alerts.Where(a => a.PersonId == teacher.Id && a.IsOpen).AnyAsync();

var response = MapContactToResponse(teacher, hasActiveAlert);
return response;
}

internal static GetTeacherResponse MapContactToResponse(Contact teacher)
internal static GetTeacherResponse MapContactToResponse(Contact teacher, bool hasActiveAlert)
{
return new GetTeacherResponse()
{
Expand All @@ -82,7 +87,7 @@ internal static GetTeacherResponse MapContactToResponse(Contact teacher)
Qualifications = MapQualifications(),
Name = teacher.FullName,
DateOfBirth = teacher.BirthDate,
ActiveAlert = teacher.dfeta_ActiveSanctions,
ActiveAlert = hasActiveAlert,
State = teacher.StateCode.Value,
StateName = teacher.FormattedValues[Contact.Fields.StateCode]
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
using MediatR;
using TeachingRecordSystem.Api.V2.Requests;
using TeachingRecordSystem.Api.V2.Responses;
using TeachingRecordSystem.Core.DataStore.Postgres;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Dqt.Models;

namespace TeachingRecordSystem.Api.V2.Handlers;

public class FindTeachersHandler : IRequestHandler<FindTeachersRequest, FindTeachersResponse>
{
private readonly TrsDbContext _dbContext;
private readonly IDataverseAdapter _dataverseAdapter;
private readonly ILogger<FindTeachersHandler> _logger;

public FindTeachersHandler(IDataverseAdapter dataverseAdapter, ILogger<FindTeachersHandler> logger)
public FindTeachersHandler(TrsDbContext dbContext, IDataverseAdapter dataverseAdapter, ILogger<FindTeachersHandler> logger)
{
_dbContext = dbContext;
_dataverseAdapter = dataverseAdapter;
_logger = logger;
}
Expand All @@ -24,6 +27,13 @@ public async Task<FindTeachersResponse> Handle(FindTeachersRequest request, Canc
await HandleDefaultRequest(request) :
await HandleStrictRequest(request);

var matchedPersonIds = result.Select(c => c.Id).ToHashSet();
var resultsWithActiveAlerts = await _dbContext.Alerts
.Where(a => matchedPersonIds.Contains(a.PersonId) && a.IsOpen)
.Select(a => a.PersonId)
.Distinct()
.ToArrayAsync();

return new FindTeachersResponse()
{
Results = result.Select(a => new FindTeacherResult()
Expand All @@ -36,7 +46,7 @@ await HandleDefaultRequest(request) :
DateOfBirth = a.BirthDate.HasValue ? DateOnly.FromDateTime(a.BirthDate.Value) : null,
NationalInsuranceNumber = a.dfeta_NINumber,
Uid = a.Id.ToString(),
HasActiveSanctions = a.dfeta_ActiveSanctions == true
HasActiveSanctions = resultsWithActiveAlerts.Contains(a.Id)
})
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using TeachingRecordSystem.Api.V2.ApiModels;
using TeachingRecordSystem.Api.V2.Requests;
using TeachingRecordSystem.Api.V2.Responses;
using TeachingRecordSystem.Core.DataStore.Postgres;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Dqt.Models;

Expand All @@ -11,10 +12,12 @@ namespace TeachingRecordSystem.Api.V2.Handlers;
public class GetTeacherHandler : IRequestHandler<GetTeacherRequest, GetTeacherResponse>
{
private readonly IDataverseAdapter _dataverseAdapter;
private readonly TrsDbContext _dbContext;

public GetTeacherHandler(IDataverseAdapter dataverseAdapter)
public GetTeacherHandler(IDataverseAdapter dataverseAdapter, TrsDbContext dbContext)
{
_dataverseAdapter = dataverseAdapter;
_dbContext = dbContext;
}

public async Task<GetTeacherResponse> Handle(GetTeacherRequest request, CancellationToken cancellationToken)
Expand All @@ -29,7 +32,6 @@ public async Task<GetTeacherResponse> Handle(GetTeacherRequest request, Cancella
Contact.Fields.BirthDate,
Contact.Fields.dfeta_EYTSDate,
Contact.Fields.dfeta_QTSDate,
Contact.Fields.dfeta_ActiveSanctions,
Contact.Fields.dfeta_NINumber,
Contact.Fields.dfeta_TRN,
Contact.Fields.dfeta_HUSID,
Expand Down Expand Up @@ -79,11 +81,13 @@ public async Task<GetTeacherResponse> Handle(GetTeacherRequest request, Cancella
null,
request.IncludeInactive != true);

var hasActiveAlert = await _dbContext.Alerts.Where(a => a.PersonId == teacher.Id && a.IsOpen).AnyAsync();

return new GetTeacherResponse()
{
DateOfBirth = teacher.BirthDate.ToDateOnlyWithDqtBstFix(isLocalTime: false),
FirstName = teacher.FirstName,
HasActiveSanctions = teacher.dfeta_ActiveSanctions == true,
HasActiveSanctions = hasActiveAlert,
LastName = teacher.LastName,
MiddleName = teacher.MiddleName,
NationalInsuranceNumber = teacher.dfeta_NINumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public async Task Handle(SetNpqQualificationRequest request, CancellationToken c
Contact.Fields.BirthDate,
Contact.Fields.dfeta_EYTSDate,
Contact.Fields.dfeta_QTSDate,
Contact.Fields.dfeta_ActiveSanctions,
Contact.Fields.dfeta_NINumber,
Contact.Fields.dfeta_TRN
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using TeachingRecordSystem.Api.V2.Requests;
using TeachingRecordSystem.Api.V2.Responses;
using TeachingRecordSystem.Api.Validation;
using TeachingRecordSystem.Core.DataStore.Postgres;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Dqt.Models;

Expand All @@ -11,17 +12,18 @@ namespace TeachingRecordSystem.Api.V2.Handlers;
public class UnlockTeacherHandler : IRequestHandler<UnlockTeacherRequest, UnlockTeacherResponse>
{
private readonly IDataverseAdapter _dataverseAdapter;
private readonly TrsDbContext _dbContext;

public UnlockTeacherHandler(IDataverseAdapter dataverseAdapter)
public UnlockTeacherHandler(IDataverseAdapter dataverseAdapter, TrsDbContext dbContext)
{
_dataverseAdapter = dataverseAdapter;
_dbContext = dbContext;
}

public async Task<UnlockTeacherResponse> Handle(UnlockTeacherRequest request, CancellationToken cancellationToken)
{
var contact = await _dataverseAdapter.GetTeacher(request.TeacherId, columnNames: new[]
{
Contact.Fields.dfeta_ActiveSanctions,
Contact.Fields.dfeta_TRN,
Contact.Fields.dfeta_loginfailedcounter
});
Expand All @@ -31,7 +33,9 @@ public async Task<UnlockTeacherResponse> Handle(UnlockTeacherRequest request, Ca
throw new NotFoundException(resourceName: Contact.EntityLogicalName, request.TeacherId);
}

if (contact.dfeta_ActiveSanctions == true)
var hasActiveAlert = await _dbContext.Alerts.Where(a => a.PersonId == request.TeacherId && a.IsOpen).AnyAsync();

if (hasActiveAlert)
{
throw new ErrorException(ErrorRegistry.TeacherHasActiveSanctions());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ await dbContext.TpsEmployments
trn = await trnGenerationApiClient.GenerateTrn();
}

var potentialDuplicatePersonIds = potentialDuplicates.Select(d => d.ContactId).ToList();
var resultsWithActiveAlerts = await dbContext.Alerts
.Where(a => potentialDuplicatePersonIds.Contains(a.PersonId) && a.IsOpen)
.Select(a => a.PersonId)
.Distinct()
.ToArrayAsync();

var emailAddress = command.EmailAddresses?.FirstOrDefault();

await crmQueryDispatcher.ExecuteQuery(new CreateContactQuery()
Expand All @@ -114,7 +121,7 @@ await crmQueryDispatcher.ExecuteQuery(new CreateContactQuery()
DateOfBirth = command.DateOfBirth,
EmailAddress = emailAddress,
NationalInsuranceNumber = NationalInsuranceNumberHelper.Normalize(command.NationalInsuranceNumber),
PotentialDuplicates = potentialDuplicates,
PotentialDuplicates = potentialDuplicates.Select(d => (Duplicate: d, HasActiveAlert: resultsWithActiveAlerts.Contains(d.ContactId))).ToArray(),
Trn = trn,
TrnRequestId = TrnRequestHelper.GetCrmTrnRequestId(currentApplicationUserId, command.RequestId),
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Immutable;
using Microsoft.Xrm.Sdk.Query;
using TeachingRecordSystem.Api.V3.Core.SharedModels;
using TeachingRecordSystem.Core.DataStore.Postgres;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Dqt.Models;
using TeachingRecordSystem.Core.Dqt.Queries;
Expand All @@ -27,6 +28,7 @@ public record FindPersonByLastNameAndDateOfBirthResultItem
}

public class FindPersonByLastNameAndDateOfBirthHandler(
TrsDbContext dbContext,
ICrmQueryDispatcher crmQueryDispatcher,
PreviousNameHelper previousNameHelper,
ReferenceDataCache referenceDataCache)
Expand All @@ -50,11 +52,12 @@ public async Task<FindPersonByLastNameAndDateOfBirthResult> Handle(FindPersonByL

var contactsById = matched.ToDictionary(r => r.Id, r => r);

var getSanctionsTask = crmQueryDispatcher.ExecuteQuery(
new GetSanctionsByContactIdsQuery(
contactsById.Keys,
ActiveOnly: true,
new(dfeta_sanction.Fields.dfeta_StartDate, dfeta_sanction.Fields.dfeta_EndDate, dfeta_sanction.Fields.dfeta_SanctionDetails)));
var getAlertsTask = dbContext.Alerts
.Include(a => a.AlertType)
.ThenInclude(at => at.AlertCategory)
.Where(a => contactsById.Keys.Contains(a.PersonId))
.GroupBy(a => a.PersonId)
.ToDictionaryAsync(a => a.Key, a => a.ToArray());

var getPreviousNamesTask = crmQueryDispatcher.ExecuteQuery(new GetPreviousNamesByContactIdsQuery(contactsById.Keys));

Expand All @@ -69,9 +72,9 @@ public async Task<FindPersonByLastNameAndDateOfBirthResult> Handle(FindPersonByL
dfeta_qtsregistration.Fields.dfeta_PersonId,
dfeta_qtsregistration.Fields.dfeta_TeacherStatusId)));

await Task.WhenAll(getSanctionsTask, getPreviousNamesTask, getQtsRegistrationsTask);
await Task.WhenAll(getAlertsTask, getPreviousNamesTask, getQtsRegistrationsTask);

var sanctions = getSanctionsTask.Result;
var alerts = getAlertsTask.Result;
var previousNames = getPreviousNamesTask.Result;
var qtsRegistrations = getQtsRegistrationsTask.Result;

Expand All @@ -86,53 +89,38 @@ public async Task<FindPersonByLastNameAndDateOfBirthResult> Handle(FindPersonByL
FirstName = r.ResolveFirstName(),
MiddleName = r.ResolveMiddleName(),
LastName = r.ResolveLastName(),
Sanctions = sanctions[r.Id]
.Where(s => Constants.LegacyExposableSanctionCodes.Contains(s.SanctionCode))
.Where(s => s.Sanction.dfeta_EndDate is null && s.Sanction.dfeta_Spent != true)
.Select(s => new SanctionInfo()
Sanctions = alerts.GetValueOrDefault(r.Id, [])
.Where(a => Constants.LegacyExposableSanctionCodes.Contains(a.AlertType.DqtSanctionCode) && a.IsOpen)
.Select(a => new SanctionInfo()
{
Code = s.SanctionCode,
StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true)
Code = a.AlertType.DqtSanctionCode!,
StartDate = a.StartDate
})
.AsReadOnly(),
Alerts = await sanctions[r.Id]
.ToAsyncEnumerable()
.WhereAwait(async s =>
{
var alertType = await referenceDataCache.GetAlertTypeByDqtSanctionCodeIfExists(s.SanctionCode);

if (alertType is null)
{
return false;
}

return !alertType.InternalOnly;
})
.SelectAwait(async s =>
Alerts = alerts.GetValueOrDefault(r.Id, [])
.Where(a => !a.AlertType.InternalOnly)
.Select(a =>
{
var alertType = await referenceDataCache.GetAlertTypeByDqtSanctionCode(s.SanctionCode);
var alertCategory = await referenceDataCache.GetAlertCategoryById(alertType.AlertCategoryId);

return new Alert()
{
AlertId = s.Sanction.Id,
AlertId = a.AlertId,
AlertType = new()
{
AlertTypeId = alertType.AlertTypeId,
AlertTypeId = a.AlertType.AlertTypeId,
AlertCategory = new()
{
AlertCategoryId = alertCategory.AlertCategoryId,
Name = alertCategory.Name
AlertCategoryId = a.AlertType.AlertCategory.AlertCategoryId,
Name = a.AlertType.AlertCategory.Name
},
Name = alertType.Name,
DqtSanctionCode = alertType.DqtSanctionCode!
Name = a.AlertType.Name,
DqtSanctionCode = a.AlertType.DqtSanctionCode!
},
Details = s.Sanction.dfeta_SanctionDetails,
StartDate = s.Sanction.dfeta_StartDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true),
EndDate = s.Sanction.dfeta_EndDate?.ToDateOnlyWithDqtBstFix(isLocalTime: true)
Details = a.Details,
StartDate = a.StartDate,
EndDate = a.EndDate
};
})
.AsReadOnlyAsync(),
.AsReadOnly(),
PreviousNames = previousNameHelper.GetFullPreviousNames(previousNames[r.Id], contactsById[r.Id])
.Select(name => new NameInfo()
{
Expand Down
Loading

0 comments on commit 475f8c5

Please sign in to comment.