Skip to content

Commit

Permalink
Get induction data from TRS
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad committed Feb 7, 2025
1 parent 7da6bf3 commit 6c9b418
Show file tree
Hide file tree
Showing 73 changed files with 15,465 additions and 10,704 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public async Task<GetTeacherResponse> Handle(GetTeacherRequest request, Cancella
return null;
}

var person = await _dbContext.Persons.SingleAsync(p => p.PersonId == teacher.Id);

var qualifications = await _dataverseAdapter.GetQualificationsForTeacherAsync(
teacher.Id,
columnNames: new[]
Expand Down Expand Up @@ -71,11 +73,11 @@ public async Task<GetTeacherResponse> Handle(GetTeacherRequest request, Cancella

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

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

internal static GetTeacherResponse MapContactToResponse(Contact teacher, bool hasActiveAlert)
internal static GetTeacherResponse MapContactToResponse(Contact teacher, bool hasActiveAlert, PostgresModels.Person person)
{
return new GetTeacherResponse()
{
Expand All @@ -94,25 +96,18 @@ internal static GetTeacherResponse MapContactToResponse(Contact teacher, bool ha

Induction MapInduction()
{
var induction = teacher.Extract<dfeta_induction>();
var inductionStatus = teacher.FormattedValues.ContainsKey(Contact.Fields.dfeta_InductionStatus) ? teacher.FormattedValues[Contact.Fields.dfeta_InductionStatus] : null;
var dqtStatus = person.InductionStatus.ToDqtInductionStatus(out var statusDescription);

return induction != null ?
return dqtStatus != null ?
new Induction()
{
StartDate = induction.dfeta_StartDate,
CompletionDate = induction.dfeta_CompletionDate,
InductionStatusName = inductionStatus,
State = induction.StateCode.Value,
StateName = induction.FormattedValues[dfeta_induction.Fields.StateCode]
StartDate = person.InductionStartDate.ToDateTime(),
CompletionDate = person.InductionCompletedDate.ToDateTime(),
InductionStatusName = statusDescription,
State = dfeta_inductionState.Active,
StateName = "Active"
} :
!string.IsNullOrEmpty(inductionStatus) ?
new Induction()
{
StartDate = null,
CompletionDate = null,
InductionStatusName = inductionStatus
} : null;
null;
}

QualifiedTeacherStatus MapQualifiedTeacherStatus()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ protected async Task<FindPersonsResult> CreateResultAsync(IEnumerable<Contact> m
{
var contactsById = matched.ToDictionary(r => r.Id, r => r);

var getAlertsTask = dbContext.Alerts
.Include(a => a.AlertType)
var getPersonsTask = dbContext.Persons
.Include(p => p.Alerts)
.ThenInclude(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());
.AsSplitQuery()
.Where(p => contactsById.Keys.Contains(p.PersonId))
.ToDictionaryAsync(p => p.PersonId, p => p);

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

Expand All @@ -85,9 +86,9 @@ protected async Task<FindPersonsResult> CreateResultAsync(IEnumerable<Contact> m
dfeta_qtsregistration.Fields.dfeta_PersonId,
dfeta_qtsregistration.Fields.dfeta_TeacherStatusId)));

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

var alerts = getAlertsTask.Result;
var persons = getPersonsTask.Result;
var previousNames = getPreviousNamesTask.Result;
var qtsRegistrations = getQtsRegistrationsTask.Result;

Expand All @@ -100,15 +101,15 @@ protected async Task<FindPersonsResult> CreateResultAsync(IEnumerable<Contact> m
FirstName = r.ResolveFirstName(),
MiddleName = r.ResolveMiddleName(),
LastName = r.ResolveLastName(),
Sanctions = alerts.GetValueOrDefault(r.Id, [])
Sanctions = persons[r.Id].Alerts
.Where(a => Constants.LegacyExposableSanctionCodes.Contains(a.AlertType.DqtSanctionCode) && a.IsOpen)
.Select(a => new SanctionInfo()
{
Code = a.AlertType.DqtSanctionCode!,
StartDate = a.StartDate
})
.AsReadOnly(),
Alerts = alerts.GetValueOrDefault(r.Id, [])
Alerts = persons[r.Id].Alerts
.Where(a => !a.AlertType.InternalOnly)
.Select(a => new Alert()
{
Expand Down Expand Up @@ -137,12 +138,12 @@ protected async Task<FindPersonsResult> CreateResultAsync(IEnumerable<Contact> m
LastName = name.LastName
})
.AsReadOnly(),
InductionStatus = r.dfeta_InductionStatus.ToInductionStatus(),
DqtInductionStatus = r.dfeta_InductionStatus?.ConvertToDqtInductionStatus() is Dtos.DqtInductionStatus inductionStatus ?
InductionStatus = persons[r.Id].InductionStatus,
DqtInductionStatus = persons[r.Id].InductionStatus.ToDqtInductionStatus(out var statusDescription) is string inductionStatus ?
new DqtInductionStatusInfo()
{
Status = inductionStatus,
StatusDescription = inductionStatus.GetDescription()
Status = Enum.Parse<DqtInductionStatus>(inductionStatus, ignoreCase: true),
StatusDescription = statusDescription!
} :
null,
Qts = await QtsInfo.CreateAsync(qtsRegistrations[r.Id].OrderBy(qr => qr.CreatedOn).FirstOrDefault(s => s.dfeta_QTSDate is not null), referenceDataCache, r.dfeta_qtlsdate),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,8 @@ async Task<T> WithTrsDbLockAsync<T>(Func<Task<T>> action)
var contact = contactDetail.Contact;
var personId = contact.Id;

var getInductionTask = command.Include.HasFlag(GetPersonCommandIncludes.Induction)
? crmQueryDispatcher.ExecuteQueryAsync(new GetActiveInductionByContactIdQuery(contact.Id))
var getPersonTask = command.Include.HasFlag(GetPersonCommandIncludes.Induction)
? WithTrsDbLockAsync(() => dbContext.Persons.SingleAsync(p => p.PersonId == personId))
: null;

var getIttTask = command.Include.HasFlag(GetPersonCommandIncludes.InitialTeacherTraining) ?
Expand Down Expand Up @@ -371,10 +371,6 @@ async Task<T> WithTrsDbLockAsync<T>(Func<Task<T>> action)

var qts = qtsRegistrations.OrderByDescending(x => x.CreatedOn).FirstOrDefault(qts => qts.dfeta_QTSDate is not null);
var eyts = qtsRegistrations.OrderByDescending(x => x.CreatedOn).FirstOrDefault(qts => qts.dfeta_EYTSDate is not null);
var allTeacherStatuses = await referenceDataCache.GetTeacherStatusesAsync();
var allEarlyYearsStatuses = await referenceDataCache.GetEytsStatusesAsync();
var eytsStatus = eyts is not null ? allEarlyYearsStatuses.Single(x => x.Id == eyts.dfeta_EarlyYearsStatusId.Id) : null;
var qtsStatus = qts is not null ? allTeacherStatuses.Single(x => x.Id == qts.dfeta_TeacherStatusId.Id) : null;

var allowIdSignInWithProhibitions = command.Include.HasFlag(GetPersonCommandIncludes.AllowIdSignInWithProhibitions) ?
Option.Some(contact.dfeta_AllowIDSignInWithProhibitions == true) :
Expand All @@ -384,7 +380,7 @@ async Task<T> WithTrsDbLockAsync<T>(Func<Task<T>> action)
Option<GetPersonResultInduction> induction = default;
if (command.Include.HasFlag(GetPersonCommandIncludes.Induction))
{
var mappedInduction = MapInduction((await getInductionTask!).Induction, (await getInductionTask!).InductionPeriods, contact);
var mappedInduction = MapInduction((await getPersonTask!));
dqtInduction = Option.Some(mappedInduction.DqtInduction);
induction = Option.Some(mappedInduction.Induction);
}
Expand Down Expand Up @@ -480,24 +476,17 @@ private static QtlsStatus MapQtlsStatus(DateTime? qtlsDate, bool? qtlsDateHasBee
}

private static (GetPersonResultDqtInduction? DqtInduction, GetPersonResultInduction Induction) MapInduction(
dfeta_induction? induction,
IEnumerable<dfeta_inductionperiod>? inductionPeriods,
Contact contact)
PostgresModels.Person person)
{
var status = contact.dfeta_InductionStatus.ToInductionStatus();
var dqtStatus = contact.dfeta_InductionStatus?.ConvertToDqtInductionStatus();

var startDate = status.RequiresStartDate()
? induction?.dfeta_StartDate.ToDateOnlyWithDqtBstFix(isLocalTime: true)
: null;

var completedDate = status.RequiresCompletedDate()
? induction?.dfeta_CompletionDate.ToDateOnlyWithDqtBstFix(isLocalTime: true)
var status = person.InductionStatus;
var dqtStatusName = status.ToDqtInductionStatus(out var dqtStatusDescription);
DqtInductionStatus? dqtStatus = dqtStatusName is not null
? Enum.Parse<DqtInductionStatus>(dqtStatusName, ignoreCase: true)
: null;
var startDate = person.InductionStartDate;
var completedDate = person.InductionCompletedDate;

var canGenerateCertificate = dqtStatus is DqtInductionStatus.Pass or DqtInductionStatus.PassedInWales
&& completedDate.HasValue;

var canGenerateCertificate = status is InductionStatus.Passed && completedDate.HasValue;
var certificateUrl = canGenerateCertificate ? "/v3/certificates/induction" : null;

var dqtInduction = dqtStatus is not null
Expand All @@ -506,9 +495,9 @@ private static (GetPersonResultDqtInduction? DqtInduction, GetPersonResultInduct
StartDate = startDate,
EndDate = completedDate,
Status = dqtStatus.Value,
StatusDescription = contact.dfeta_InductionStatus?.GetDescription(),
StatusDescription = dqtStatusDescription,
CertificateUrl = certificateUrl,
Periods = (inductionPeriods ?? []).Select(MapInductionPeriod).ToArray()
Periods = []
}
: null;

Expand All @@ -517,30 +506,12 @@ private static (GetPersonResultDqtInduction? DqtInduction, GetPersonResultInduct
Status = status,
StartDate = startDate,
CompletedDate = completedDate,
CertificateUrl = certificateUrl,
CertificateUrl = certificateUrl
};

return (dqtInduction, inductionInfo);
}

private static GetPersonResultDqtInductionPeriod MapInductionPeriod(dfeta_inductionperiod inductionPeriod)
{
var appropriateBody = inductionPeriod.Extract<Account>("appropriatebody", Account.PrimaryIdAttribute);

return new GetPersonResultDqtInductionPeriod()
{
StartDate = inductionPeriod.dfeta_StartDate.ToDateOnlyWithDqtBstFix(isLocalTime: true),
EndDate = inductionPeriod.dfeta_EndDate.ToDateOnlyWithDqtBstFix(isLocalTime: true),
Terms = inductionPeriod.dfeta_Numberofterms,
AppropriateBody = appropriateBody is not null ?
new GetPersonResultInductionPeriodAppropriateBody()
{
Name = appropriateBody.Name
} :
null
};
}

private static IReadOnlyCollection<GetPersonResultInitialTeacherTraining> MapInitialTeacherTraining(
dfeta_initialteachertraining[] itt,
bool userHasAppropriateBodyRole)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,13 @@ public async Task<ApiResult<SetQtlsResult>> HandleAsync(SetQtlsCommand command)
return ApiError.PersonNotFound(command.Trn);
}

var induction = await GetInductionWithAppropriateBodyAsync(contact.Id);
var person = await dbContext.Persons.SingleAsync(p => p.PersonId == contact.Id);

var (canSetQtlsDate, reviewTaskDescription) = CanSetQtlsDate(
hasQTS: contact.dfeta_QTSDate.HasValue,
overallInductionStatus: contact.dfeta_InductionStatus,
inductionStatus: induction?.Induction.dfeta_InductionStatus,
hasInductionWithAB: induction?.HasAppropriateBody ?? false,
existingQtlsdate: contact.dfeta_qtlsdate,
hasQts: contact.dfeta_QTSDate.HasValue,
person.InductionStatus,
person.InductionStatusWithoutExemption,
existingQtlsDate: contact.dfeta_qtlsdate,
incomingQtlsDate: command.QtsDate);

if (!canSetQtlsDate)
Expand All @@ -76,7 +75,7 @@ await crmQueryDispatcher.ExecuteQueryAsync(
var hasActiveAlert = await dbContext.Alerts.Where(a => a.PersonId == contact.Id && a.IsOpen).AnyAsync();

await crmQueryDispatcher.ExecuteQueryAsync(
new SetQtlsDateQuery(contact.Id, command.QtsDate, hasActiveAlert, clock.UtcNow))!;
new SetQtlsDateQuery(contact.Id, command.QtsDate, hasActiveAlert, clock.UtcNow));

return SetQtlsResult.Success(new QtlsResult()
{
Expand All @@ -85,33 +84,22 @@ await crmQueryDispatcher.ExecuteQueryAsync(
});
}

private async Task<(dfeta_induction Induction, bool HasAppropriateBody)?> GetInductionWithAppropriateBodyAsync(Guid contactId)
{
var induction = await crmQueryDispatcher.ExecuteQueryAsync(new GetActiveInductionByContactIdQuery(contactId));
if (induction.Induction == null)
{
return null;
}
else
{
var inductionPeriod = induction.InductionPeriods.Where(x => x.dfeta_EndDate == null).OrderByDescending(x => x.dfeta_StartDate).FirstOrDefault();
return (induction.Induction, inductionPeriod != null);
}
}

private (bool CanSetQtlsDate, string? TaskMessage) CanSetQtlsDate(bool hasQTS, dfeta_InductionStatus? overallInductionStatus, dfeta_InductionStatus? inductionStatus, bool hasInductionWithAB, DateTime? existingQtlsdate, DateOnly? incomingQtlsDate) =>
hasQTS switch
private static (bool CanSetQtlsDate, string? TaskMessage) CanSetQtlsDate(
bool hasQts,
InductionStatus currentInductionStatus,
InductionStatus inductionStatusWithoutExemption,
DateTime? existingQtlsDate,
DateOnly? incomingQtlsDate) =>
hasQts switch
{
true when overallInductionStatus == dfeta_InductionStatus.InProgress && !existingQtlsdate.HasValue && incomingQtlsDate.HasValue => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'In Progress'"),
true when overallInductionStatus == dfeta_InductionStatus.InductionExtended && !hasInductionWithAB && !existingQtlsdate.HasValue && incomingQtlsDate.HasValue => (true, null),
true when overallInductionStatus == dfeta_InductionStatus.InductionExtended && hasInductionWithAB && !existingQtlsdate.HasValue && incomingQtlsDate.HasValue => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'Induction Extended' claimed with an AB"),
true when overallInductionStatus == dfeta_InductionStatus.Fail => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'Fail'"),
true when overallInductionStatus == dfeta_InductionStatus.Exempt && inductionStatus == dfeta_InductionStatus.FailedinWales && existingQtlsdate.HasValue && !incomingQtlsDate.HasValue => (false, $"Unable to remove QTLSDate, teacher induction currently set to 'Failed in Wales'"),
true when overallInductionStatus == dfeta_InductionStatus.FailedinWales && !existingQtlsdate.HasValue && incomingQtlsDate.HasValue => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'Failed in Wales'"),
true when overallInductionStatus == dfeta_InductionStatus.FailedinWales && existingQtlsdate.HasValue && incomingQtlsDate.HasValue => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'Failed in Wales'"),
true when overallInductionStatus == dfeta_InductionStatus.Exempt && existingQtlsdate.HasValue && !incomingQtlsDate.HasValue => (true, null),
true when currentInductionStatus == InductionStatus.InProgress && !existingQtlsDate.HasValue && incomingQtlsDate.HasValue => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'In Progress'"),
true when currentInductionStatus == InductionStatus.Failed => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'Fail'"),
true when currentInductionStatus == InductionStatus.Exempt && inductionStatusWithoutExemption == InductionStatus.FailedInWales && existingQtlsDate.HasValue && !incomingQtlsDate.HasValue => (false, $"Unable to remove QTLSDate, teacher induction currently set to 'Failed in Wales'"),
true when currentInductionStatus == InductionStatus.FailedInWales && !existingQtlsDate.HasValue && incomingQtlsDate.HasValue => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'Failed in Wales'"),
true when currentInductionStatus == InductionStatus.FailedInWales && existingQtlsDate.HasValue && incomingQtlsDate.HasValue => (false, $"Unable to set QTLSDate {incomingQtlsDate}, teacher induction currently set to 'Failed in Wales'"),
true when currentInductionStatus == InductionStatus.Exempt && existingQtlsDate.HasValue && !incomingQtlsDate.HasValue => (true, null),
false => (true, null),
_ when existingQtlsdate.HasValue && incomingQtlsDate.HasValue && incomingQtlsDate.Value == existingQtlsdate.ToDateOnlyWithDqtBstFix(isLocalTime: false) => (false, $"Unable to set QTLSDate {incomingQtlsDate}, this matches existing QTLS date on teacher record"),
_ when existingQtlsDate.HasValue && incomingQtlsDate.HasValue && incomingQtlsDate.Value == existingQtlsDate.ToDateOnlyWithDqtBstFix(isLocalTime: false) => (false, $"Unable to set QTLSDate {incomingQtlsDate}, this matches existing QTLS date on teacher record"),
_ => (true, null)
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ public static Command CreateSyncPersonCommand(IConfiguration configuration)
}

await syncHelper.SyncPersonAsync(contact, syncAudit: true, ignoreInvalid: false, dryRun: false);

await syncHelper.SyncInductionsAsync([contact], syncAudit: true, ignoreInvalid: false, dryRun: false);
//return 0;
},
connectionStringOption,
crmConnectionStringOption,
Expand Down
Loading

0 comments on commit 6c9b418

Please sign in to comment.