Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add creation channels to remaining endpoints #1496

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 60 additions & 9 deletions GetIntoTeachingApi/Models/Crm/Candidate.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using GetIntoTeachingApi.Attributes;
using GetIntoTeachingApi.Attributes;
using GetIntoTeachingApi.Services;
using GetIntoTeachingApi.Utils;
using Microsoft.Xrm.Sdk;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;

namespace GetIntoTeachingApi.Models.Crm
{
Expand Down Expand Up @@ -300,14 +300,11 @@ public enum RegistrationStatus
[EntityRelationship("dfe_contact_dfe_contactchannelcreation_ContactId", typeof(ContactChannelCreation))]
public List<ContactChannelCreation> ContactChannelCreations { get; set; } = new List<ContactChannelCreation>();

public Candidate()
: base()
{
public Candidate() : base(){
}

public Candidate(Entity entity, ICrmService crm, IServiceProvider serviceProvider)
: base(entity, crm, serviceProvider)
{
: base(entity, crm, serviceProvider){
}

public bool HasTeacherTrainingAdviser()
Expand Down Expand Up @@ -335,6 +332,60 @@ public bool IsPlanningToRetakeGcseMathsAndEnglish()
return new[] { PlanningToRetakeGcseMathsId, PlanningToRetakeGcseEnglishId }.All(g => g == (int)GcseStatus.HasOrIsPlanningOnRetaking);
}

/// <summary>
/// Allows the configuration of a contact channel for a
/// candidate based on the provided contactChannelCreator.
/// </summary>
public void ConfigureChannel(ICreateContactChannel contactChannelCreator, Guid? candidateId)
{
if (candidateId == null)
{
if (contactChannelCreator.CreationChannelSourceId.HasValue)
{
ChannelId = null;
AddContactChannelCreation(
channelCreation: !ContactChannelCreations.Any(),
contactChannelCreator: contactChannelCreator);
}
else
{
ChannelId = contactChannelCreator.DefaultContactCreationChannel;
}
}
else // Candidate record already exists
{
// NB: we do not update a candidate's ChannelId for an existing record
// NB: CreationChannel should always be false for existing candidates
if (contactChannelCreator.CreationChannelSourceId.HasValue)
{
AddContactChannelCreation(
channelCreation: false,
contactChannelCreator: contactChannelCreator);
}
}
}

/// <summary>
/// Allows automatic creation of an <see cref="ContactChannelCreation"/>
/// and assigns to the underlying collection of contact channel creations.
/// </summary>
/// <param name="channelCreation">
/// Predicates the context of the contact channel creation based on the candidate status.
/// </param>
/// <param name="contactChannelCreator">
/// The source of the contact channel creation request, a type
/// which implements the <see cref="ICreateContactChannel"/> interface.
/// </param>
private void AddContactChannelCreation(bool channelCreation, ICreateContactChannel contactChannelCreator)
{
ContactChannelCreations.Add(
ContactChannelCreation.Create(
creationChannel: channelCreation,
sourceId: contactChannelCreator.CreationChannelSourceId,
serviceId: contactChannelCreator.CreationChannelServiceId,
activityId: contactChannelCreator.CreationChannelActivityId));
}

public bool MagicLinkTokenExpired() => MagicLinkTokenExpiresAt == null || MagicLinkTokenExpiresAt < DateTime.UtcNow;
public bool MagicLinkTokenAlreadyExchanged() => MagicLinkTokenStatusId == (int)MagicLinkTokenStatus.Exchanged;
}
Expand Down
29 changes: 22 additions & 7 deletions GetIntoTeachingApi/Models/Crm/ContactChannelCreation.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Text.Json.Serialization;
using FluentValidation;
using GetIntoTeachingApi.Attributes;
using GetIntoTeachingApi.Services;
using Microsoft.Xrm.Sdk;
using System;
using System.Text.Json.Serialization;

namespace GetIntoTeachingApi.Models.Crm
{
Expand Down Expand Up @@ -94,13 +93,29 @@ public enum CreationChannelActivity
[EntityField("dfe_creationchannelactivities", typeof(OptionSetValue))]
public int? CreationChannelActivityId { get; set; }

public ContactChannelCreation() : base()
{
public ContactChannelCreation() : base(){
}

public ContactChannelCreation(Entity entity, ICrmService crm, IServiceProvider serviceProvider)
: base(entity, crm, serviceProvider)
{
: base(entity, crm, serviceProvider){
}

/// <summary>
/// Factory method for creating a ContactChannelCreation instance.
/// </summary>
/// <returns>
/// A configured <see cref="ContactChannelCreation"/> instance.
/// </returns>
public static ContactChannelCreation Create(
bool creationChannel,
int? sourceId,
int? serviceId,
int? activityId) => new()
{
CreationChannel = creationChannel,
CreationChannelSourceId = sourceId,
CreationChannelServiceId = serviceId,
CreationChannelActivityId = activityId,
};
}
}
29 changes: 29 additions & 0 deletions GetIntoTeachingApi/Models/Crm/ICreateContactChannel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace GetIntoTeachingApi.Models.Crm
{
/// <summary>
/// Interface that defines the contract on which objects
/// that wish to invoke contact channel creation behaviour must adhere.
/// </summary>
public interface ICreateContactChannel
{
/// <summary>
/// Provides the default read-only contact creation channel integer value.
/// </summary>
int? DefaultContactCreationChannel { get; }

/// <summary>
/// Provides the ability to assign and retrieve the channel source creation identifier.
/// </summary>
int? CreationChannelSourceId { get; set; }

/// <summary>
/// Provides the ability to assign and retrieve the channel service creation identifier.
/// </summary>
int? CreationChannelServiceId { get; set; }

/// <summary>
/// Provides the ability to assign and retrieve the channel activity creation identifier.
/// </summary>
int? CreationChannelActivityId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using System;
using System.Text.Json.Serialization;
using GetIntoTeachingApi.Models.Crm;
using GetIntoTeachingApi.Models.Crm;
using GetIntoTeachingApi.Services;
using GetIntoTeachingApi.Utils;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Text.Json.Serialization;

namespace GetIntoTeachingApi.Models.GetIntoTeaching
{
public class GetIntoTeachingCallback
public class GetIntoTeachingCallback : ICreateContactChannel
{
public Guid? CandidateId { get; set; }
[SwaggerSchema(WriteOnly = true)]
Expand All @@ -20,14 +20,22 @@ public class GetIntoTeachingCallback
[SwaggerSchema(WriteOnly = true)]
public DateTime? PhoneCallScheduledAt { get; set; }
public string TalkingPoints { get; set; }

[SwaggerSchema(WriteOnly = true)]
public int? CreationChannelSourceId { get; set; }
[SwaggerSchema(WriteOnly = true)]
public int? CreationChannelServiceId { get; set; }
[SwaggerSchema(WriteOnly = true)]
public int? CreationChannelActivityId { get; set; }

[JsonIgnore]
public Candidate Candidate => CreateCandidate();
[JsonIgnore]
public IDateTimeProvider DateTimeProvider { get; set; } = new DateTimeProvider();

public GetIntoTeachingCallback()
{
public int? DefaultContactCreationChannel => (int?)Candidate.Channel.GetIntoTeachingCallback;

public GetIntoTeachingCallback(){
}

public GetIntoTeachingCallback(Candidate candidate)
Expand Down Expand Up @@ -55,8 +63,7 @@ private Candidate CreateCandidate()
LastName = LastName,
AddressTelephone = AddressTelephone,
};

ConfigureChannel(candidate);
candidate.ConfigureChannel(contactChannelCreator: this, candidateId: CandidateId);
SchedulePhoneCall(candidate);
AcceptPrivacyPolicy(candidate);

Expand All @@ -79,14 +86,6 @@ private void SchedulePhoneCall(Candidate candidate)
}
}

private void ConfigureChannel(Candidate candidate)
{
if (CandidateId == null)
{
candidate.ChannelId = (int?)Candidate.Channel.GetIntoTeachingCallback;
}
}

private void AcceptPrivacyPolicy(Candidate candidate)
{
if (AcceptedPolicyId != null)
Expand Down
48 changes: 6 additions & 42 deletions GetIntoTeachingApi/Models/GetIntoTeaching/MailingListAddMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace GetIntoTeachingApi.Models.GetIntoTeaching
{
public class MailingListAddMember
public class MailingListAddMember : ICreateContactChannel
{
public Guid? CandidateId { get; set; }
public Guid? QualificationId { get; set; }
Expand Down Expand Up @@ -45,8 +45,10 @@ public class MailingListAddMember
[JsonIgnore]
public IDateTimeProvider DateTimeProvider { get; set; } = new DateTimeProvider();

public MailingListAddMember()
{
public int? DefaultContactCreationChannel =>
ChannelId ?? (int?)Candidate.Channel.MailingList; // Use the assigned channel ID if available, else assign default.

public MailingListAddMember(){
}

public MailingListAddMember(Candidate candidate)
Expand Down Expand Up @@ -98,52 +100,14 @@ private Candidate CreateCandidate()
GdprConsentId = (int)Candidate.GdprConsent.Consent,
OptOutOfGdpr = false,
};

ConfigureChannel(candidate);
candidate.ConfigureChannel(contactChannelCreator: this, candidateId: CandidateId);
ConfigureSubscriptions(candidate);
AddQualification(candidate);
AcceptPrivacyPolicy(candidate);

return candidate;
}

private void ConfigureChannel(Candidate candidate)
{
if (CandidateId == null)
{
if (CreationChannelSourceId.HasValue)
{
candidate.ChannelId = null;
// NB: CreationChannel should be true only if it is the first ContactChannelCreation record
AddCandidateCreationChannel(candidate, !candidate.ContactChannelCreations.Any());
}
else
{
candidate.ChannelId = ChannelId ?? (int?)Candidate.Channel.MailingList;
}
}
else // Candidate record already exists
{
// NB: we do not update a candidate's ChannelId for an existing record
// NB: CreationChannel should always be false for existing candidates
if (CreationChannelSourceId.HasValue)
{
AddCandidateCreationChannel(candidate, false);
}
}
}

private void AddCandidateCreationChannel(Candidate candidate, bool creationChannel)
{
candidate.ContactChannelCreations.Add(new ContactChannelCreation()
{
CreationChannel = creationChannel,
CreationChannelSourceId = CreationChannelSourceId,
CreationChannelServiceId = CreationChannelServiceId,
CreationChannelActivityId = CreationChannelActivityId,
});
}

private void AddQualification(Candidate candidate)
{
candidate.Qualifications.Add(new CandidateQualification()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using System;
using System.Linq;
using System.Text.Json.Serialization;
using GetIntoTeachingApi.Models.Crm;
using GetIntoTeachingApi.Models.Crm;
using GetIntoTeachingApi.Services;
using GetIntoTeachingApi.Utils;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Linq;
using System.Text.Json.Serialization;

namespace GetIntoTeachingApi.Models.GetIntoTeaching
{
public class TeachingEventAddAttendee
public class TeachingEventAddAttendee : ICreateContactChannel
{
public Guid? CandidateId { get; set; }
public Guid? QualificationId { get; set; }
Expand All @@ -18,6 +18,13 @@ public class TeachingEventAddAttendee

[SwaggerSchema(WriteOnly = true)]
public int? ChannelId { get; set; }

[SwaggerSchema(WriteOnly = true)]
public int? CreationChannelSourceId { get; set; }
[SwaggerSchema(WriteOnly = true)]
public int? CreationChannelServiceId { get; set; }
[SwaggerSchema(WriteOnly = true)]
public int? CreationChannelActivityId { get; set; }

[SwaggerSchema(WriteOnly = true)]
public Guid? AcceptedPolicyId { get; set; }
Expand Down Expand Up @@ -48,8 +55,10 @@ public class TeachingEventAddAttendee
[JsonIgnore]
public IDateTimeProvider DateTimeProvider { get; set; } = new DateTimeProvider();

public TeachingEventAddAttendee()
{
public int? DefaultContactCreationChannel =>
ChannelId ?? (int?)Candidate.Channel.Event; // Use the assigned channel ID if available, else assign default.

public TeachingEventAddAttendee(){
}

public TeachingEventAddAttendee(Candidate candidate)
Expand Down Expand Up @@ -126,8 +135,7 @@ private Candidate CreateCandidate()
{
candidate.PreferredTeachingSubjectId = PreferredTeachingSubjectId;
}

ConfigureChannel(candidate);
candidate.ConfigureChannel(contactChannelCreator: this, candidateId: CandidateId);
AddTeachingEventRegistration(candidate);
AddQualification(candidate);
AcceptPrivacyPolicy(candidate);
Expand All @@ -136,14 +144,6 @@ private Candidate CreateCandidate()
return candidate;
}

private void ConfigureChannel(Candidate candidate)
{
if (CandidateId == null)
{
candidate.ChannelId = ChannelId ?? (int?)Candidate.Channel.Event;
}
}

private void AddQualification(Candidate candidate)
{
if (DegreeStatusId != null)
Expand Down
Loading
Loading