Skip to content

Commit

Permalink
Merge pull request #1467 from DFE-Digital/prevent-duplicate-degree-su…
Browse files Browse the repository at this point in the history
…bject

Prevent duplicate degree subject
  • Loading branch information
martyn-w authored Sep 9, 2024
2 parents f2485f3 + 5913452 commit 2faa0d6
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 190 deletions.
46 changes: 23 additions & 23 deletions GetIntoTeachingApi/Jobs/UpsertCandidateJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class UpsertCandidateJob : BaseJob
private readonly ICandidateUpserter _upserter;
private readonly INotifyService _notifyService;
private readonly IPerformContextAdapter _contextAdapter;
private readonly IMetricService _metrics;
private readonly IMetricService _metrics;
private readonly IAppSettings _appSettings;
private readonly ILogger<UpsertCandidateJob> _logger;

Expand All @@ -38,23 +38,23 @@ public UpsertCandidateJob(
_appSettings = appSettings;
}

public void Run(string json, PerformContext context)
{
var candidate = json.DeserializeChangeTracked<Candidate>();

if (Deduplicate(Signature(candidate), context, _contextAdapter))
{
_logger.LogInformation("UpsertCandidateJob - Deduplicating");
return;
}

if (_appSettings.IsCrmIntegrationPaused)
{
throw new InvalidOperationException("UpsertCandidateJob - Aborting (CRM integration paused).");
}

_logger.LogInformation("UpsertCandidateJob - Started ({Attempt})", AttemptInfo(context, _contextAdapter));
_logger.LogInformation("UpsertCandidateJob - Payload {Payload}", Redactor.RedactJson(json));
public void Run(string json, PerformContext context)
{
var candidate = json.DeserializeChangeTracked<Candidate>();
if (Deduplicate(Signature(candidate), context, _contextAdapter))
{
_logger.LogInformation("UpsertCandidateJob - Deduplicating");
return;
}

if (_appSettings.IsCrmIntegrationPaused)
{
throw new InvalidOperationException("UpsertCandidateJob - Aborting (CRM integration paused).");
}

_logger.LogInformation("UpsertCandidateJob - Started ({Attempt})", AttemptInfo(context, _contextAdapter));
_logger.LogInformation("UpsertCandidateJob - Payload {Payload}", Redactor.RedactJson(json));

if (IsLastAttempt(context, _contextAdapter))
{
Expand All @@ -68,19 +68,19 @@ public void Run(string json, PerformContext context)
_logger.LogInformation("UpsertCandidateJob - Deleted");
}
else
{
{
_upserter.Upsert(candidate);

_logger.LogInformation("UpsertCandidateJob - Succeeded - {Id}", candidate.Id);
}

var duration = (DateTime.UtcNow - _contextAdapter.GetJobCreatedAt(context)).TotalSeconds;
_metrics.HangfireJobQueueDuration.WithLabels("UpsertCandidateJob").Observe(duration);
_metrics.HangfireJobQueueDuration.WithLabels("UpsertCandidateJob").Observe(duration);
}

private static string Signature(Candidate candidate)
{
return $"{candidate.Id}-{candidate.Email}-{string.Join("", candidate.ChangedPropertyNames)}";
private static string Signature(Candidate candidate)
{
return $"{candidate.Id}-{candidate.Email}-{string.Join("", candidate.ChangedPropertyNames)}";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Text.Json.Serialization;
using GetIntoTeachingApi.Models.Crm;
using GetIntoTeachingApi.Services;
Expand Down Expand Up @@ -33,6 +34,11 @@ public class SchoolsExperienceSignUp
public string Telephone { get; set; }
public bool? HasDbsCertificate { get; set; }
public DateTime? DbsCertificateIssuedAt { get; set; }
public Guid? QualificationId { get; set; }
public int? DegreeStatusId { get; set; }
public int? DegreeTypeId { get; set; }
public string DegreeSubject { get; set; }
public int? UkDegreeGradeId { get; set; }

[JsonIgnore]
public Candidate Candidate => CreateCandidate();
Expand Down Expand Up @@ -75,6 +81,17 @@ private void PopulateWithCandidate(Candidate candidate)

HasDbsCertificate = candidate.HasDbsCertificate;
DbsCertificateIssuedAt = candidate.DbsCertificateIssuedAt;

var latestQualification = candidate.Qualifications.OrderByDescending(q => q.CreatedAt).FirstOrDefault();

if (latestQualification != null)
{
QualificationId = latestQualification.Id;
DegreeSubject = latestQualification.DegreeSubject;
UkDegreeGradeId = latestQualification.UkDegreeGradeId;
DegreeStatusId = latestQualification.DegreeStatusId;
DegreeTypeId = latestQualification.TypeId;
}
}

private Candidate CreateCandidate()
Expand Down Expand Up @@ -109,6 +126,7 @@ private Candidate CreateCandidate()

ConfigureChannel(candidate);
AcceptPrivacyPolicy(candidate);
AddQualification(candidate);

return candidate;
}
Expand All @@ -132,5 +150,25 @@ private void AcceptPrivacyPolicy(Candidate candidate)
};
}
}

private void AddQualification(Candidate candidate)
{
if (ContainsQualification() && !candidate.Qualifications.Any())
{
candidate.Qualifications.Add(new CandidateQualification()
{
Id = QualificationId,
UkDegreeGradeId = UkDegreeGradeId,
DegreeStatusId = DegreeStatusId,
DegreeSubject = DegreeSubject,
TypeId = DegreeTypeId ?? (int)CandidateQualification.DegreeType.Degree
});
}
}

private bool ContainsQualification()
{
return UkDegreeGradeId != null || DegreeStatusId != null || DegreeSubject != null || DegreeTypeId != null;
}
}
}
65 changes: 39 additions & 26 deletions GetIntoTeachingApi/Services/CandidateUpserter.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using GetIntoTeachingApi.Jobs;
using GetIntoTeachingApi.Models.Crm;
using GetIntoTeachingApi.Models.Crm;
using GetIntoTeachingApi.Utils;
using Hangfire;
using static GetIntoTeachingApi.Models.Crm.Candidate;
Expand Down Expand Up @@ -33,8 +33,8 @@ public void Upsert(Candidate candidate)
UpdateEventSubscriptionType(candidate);

SaveCandidate(candidate);

SaveQualifications(qualifications, candidate);

SavePastTeachingPositions(pastTeachingPositions, candidate);
SaveApplicationForms(applicationForms, candidate);
SaveTeachingEventRegistrations(registrations, candidate);
Expand All @@ -43,8 +43,11 @@ public void Upsert(Candidate candidate)
SaveSchoolExperiences(schoolExperiences, candidate);

IncrementCallbackBookingQuotaNumberOfBookings(phoneCall);
}


// Re-add qualifications back to candidate object to ensure it is correctly returned
AddQualifications(qualifications, candidate);
}

private static IEnumerable<TeachingEventRegistration> ClearTeachingEventRegistrations(Candidate candidate)
{
// Due to reasons unknown the event registrations relationship can't be deep-inserted
Expand Down Expand Up @@ -74,15 +77,20 @@ private static IEnumerable<CandidateQualification> ClearQualifications(Candidate
var qualifications = new List<CandidateQualification>(candidate.Qualifications);
candidate.Qualifications.Clear();
return qualifications;
}

private static IEnumerable<CandidateSchoolExperience> ClearSchoolExperiences(Candidate candidate)
{
}

private static void AddQualifications(IEnumerable<CandidateQualification> candidateQualifications, Candidate candidate)
{
candidate.Qualifications.AddRange(candidateQualifications);
}

private static IEnumerable<CandidateSchoolExperience> ClearSchoolExperiences(Candidate candidate)
{
var schoolExperiences = new List<CandidateSchoolExperience>(candidate.SchoolExperiences);
candidate.SchoolExperiences.Clear();
return schoolExperiences;
}

return schoolExperiences;
}

private static PhoneCall ClearPhoneCall(Candidate candidate)
{
if (candidate.PhoneCall == null)
Expand Down Expand Up @@ -140,9 +148,23 @@ private void UpdateEventSubscriptionType(Candidate candidate)
private void SaveCandidate(Candidate candidate)
{
candidate.IsNewRegistrant = candidate.Id == null;

_crm.Save(candidate);
}

private void SaveQualifications(IEnumerable<CandidateQualification> qualifications, Candidate candidate)
{
foreach (var qualification in qualifications)
{
// only add the degree qualification to the CRM if it doesn't already exist
if (!_crm.CandidateHasDegreeQualification((Guid)candidate.Id, CandidateQualification.DegreeType.Degree,
qualification.DegreeSubject))
{
qualification.CandidateId = (Guid)candidate.Id;
// call the CRM immediate so we get qualification ID and prevent duplicate records from being created
_crm.Save(qualification);
}
}
}

private void SaveTeachingEventRegistrations(IEnumerable<TeachingEventRegistration> registrations, Candidate candidate)
{
Expand All @@ -160,16 +182,7 @@ private void SaveTeachingEventRegistrations(IEnumerable<TeachingEventRegistratio
_jobClient.Enqueue<UpsertModelWithCandidateIdJob<TeachingEventRegistration>>((x) => x.Run(json, null));
}
}

private void SaveQualifications(IEnumerable<CandidateQualification> qualifications, Candidate candidate)
{
foreach (var qualification in qualifications)
{
qualification.CandidateId = (Guid)candidate.Id;
string json = qualification.SerializeChangeTracked();
_jobClient.Enqueue<UpsertModelWithCandidateIdJob<CandidateQualification>>((x) => x.Run(json, null));
}
}


private void SaveApplicationForms(IEnumerable<ApplicationForm> applicationForms, Candidate candidate)
{
Expand All @@ -189,8 +202,8 @@ private void SavePastTeachingPositions(IEnumerable<CandidatePastTeachingPosition
string json = pastTeachingPosition.SerializeChangeTracked();
_jobClient.Enqueue<UpsertModelWithCandidateIdJob<CandidatePastTeachingPosition>>((x) => x.Run(json, null));
}
}

}

private void SaveSchoolExperiences(IEnumerable<CandidateSchoolExperience> schoolExperiences, Candidate candidate)
{
foreach (var schoolExperience in schoolExperiences)
Expand Down
Loading

0 comments on commit 2faa0d6

Please sign in to comment.