diff --git a/src/Communication/Communication.Types/Interfaces/ITemplateIdProvider.cs b/src/Communication/Communication.Types/Interfaces/ITemplateIdProvider.cs index 407f08a9ff..2df8db1d07 100644 --- a/src/Communication/Communication.Types/Interfaces/ITemplateIdProvider.cs +++ b/src/Communication/Communication.Types/Interfaces/ITemplateIdProvider.cs @@ -8,6 +8,6 @@ public interface ITemplateIdProvider /// This has to be unique value across all the possible services /// Example value: VacancyServices.Recruit.Employer string ProviderServiceName { get; } - Task GetTemplateId(CommunicationMessage message, bool isAggregate = false); + Task GetTemplateIdAsync(CommunicationMessage message); } } \ No newline at end of file diff --git a/src/Shared/Recruit.Vacancies.Client/Application/Communications/CommunicationConstants.cs b/src/Shared/Recruit.Vacancies.Client/Application/Communications/CommunicationConstants.cs index 2bc27ea86c..742378c2b4 100644 --- a/src/Shared/Recruit.Vacancies.Client/Application/Communications/CommunicationConstants.cs +++ b/src/Shared/Recruit.Vacancies.Client/Application/Communications/CommunicationConstants.cs @@ -44,6 +44,12 @@ public static class Vacancy public const string EmployerName = "employer-name"; } + public static class Application + { + public const string ApplicationsSubmittedAggregateHeader = "applications-submitted-aggregate-header"; + public const string ApplicationsSubmittedAggregateBodySnippets = "applications-submitted-aggregate-body-snippets"; + } + public static class ApprenticeshipService { public const string ApprenticeshipServiceUrl = "apprenticeship-service-url"; diff --git a/src/Shared/Recruit.Vacancies.Client/Application/Communications/CompositeDataItemProviderPlugins/ApplicationsSubmittedCompositeDataItemPlugin.cs b/src/Shared/Recruit.Vacancies.Client/Application/Communications/CompositeDataItemProviderPlugins/ApplicationsSubmittedCompositeDataItemPlugin.cs new file mode 100644 index 0000000000..67bb7783c2 --- /dev/null +++ b/src/Shared/Recruit.Vacancies.Client/Application/Communications/CompositeDataItemProviderPlugins/ApplicationsSubmittedCompositeDataItemPlugin.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Communication.Types; +using Communication.Types.Interfaces; +using Esfa.Recruit.Vacancies.Client.Application.Communications; +using Humanizer; + +namespace Recruit.Vacancies.Client.Application.Communications.CompositeDataItemProviderPlugins +{ + public class ApplicationsSubmittedCompositeDataItemPlugin : ICompositeDataItemProvider + { + public string ProviderName => GetType().Name; + + public Task> GetConsolidatedMessageDataItemsAsync(CommunicationMessage aggregateMessage, IEnumerable messages) + { + var dataItems = new List(); + var vacancyRefs = GetUniqueVacancyRefs(messages); + var header = GetNoApplicationsSubmittedHeader(messages, vacancyRefs); + var vacanciesAndApplicationsSubmittedSnippets = GetPerVacancyApplicationsSubmittedSnippet(messages, vacancyRefs); + var apprenticeshipServiceUrlDataItem = messages.First().DataItems.First(di => di.Key == CommunicationConstants.DataItemKeys.ApprenticeshipService.ApprenticeshipServiceUrl); + + dataItems.Add(new CommunicationDataItem(CommunicationConstants.DataItemKeys.Application.ApplicationsSubmittedAggregateHeader, header)); + dataItems.Add(new CommunicationDataItem(CommunicationConstants.DataItemKeys.Application.ApplicationsSubmittedAggregateBodySnippets, vacanciesAndApplicationsSubmittedSnippets)); + dataItems.Add(apprenticeshipServiceUrlDataItem); + + return Task.FromResult(dataItems.AsEnumerable()); + } + + private string GetPerVacancyApplicationsSubmittedSnippet(IEnumerable messages, List vacancyRefs) + { + var vacanciesAndNewApplicationCounts = GetUniqueVacanciesAndNewApplicationCounts(messages, vacancyRefs); + + var sb = new StringBuilder(); + + foreach (var vr in vacancyRefs) + { + var msg = messages.First(m => m.DataItems.Exists(di => di.Key == CommunicationConstants.DataItemKeys.Vacancy.VacancyReference && di.Value == vr)); + var applicationCount = vacanciesAndNewApplicationCounts.First(va => va.Key == long.Parse(vr)).Value; + var vacancyTitle = msg.DataItems.Single(di => di.Key == CommunicationConstants.DataItemKeys.Vacancy.VacancyTitle).Value; + var employerName = msg.DataItems.Single(di => di.Key == CommunicationConstants.DataItemKeys.Vacancy.VacancyTitle).Value; + + sb.AppendLine($"VAC{vr}: {vacancyTitle}"); + sb.AppendLine(employerName); + sb.AppendLine($"{applicationCount} new {"application".ToQuantity(applicationCount, ShowQuantityAs.None)}"); + sb.AppendLine(); + sb.AppendLine("---"); + sb.AppendLine(); + } + + return sb.ToString(); + } + + private string GetNoApplicationsSubmittedHeader(IEnumerable messages, List vacancyRefs) + { + var totalNoOfVacancies = vacancyRefs.Count(); + var totalNoOfApplications = messages.Count(); + + var header = $"There has been {totalNoOfApplications} new {"application".ToQuantity(totalNoOfApplications, ShowQuantityAs.None)} for {totalNoOfVacancies} {"vacancy".ToQuantity(totalNoOfVacancies, ShowQuantityAs.None)}"; + return header; + } + + private List GetUniqueVacancyRefs(IEnumerable messages) + { + return messages + .SelectMany(m => m.DataItems + .Where(di => di.Key == CommunicationConstants.DataItemKeys.Vacancy.VacancyReference) + .Select(di => di.Value) + ) + .Distinct() + .ToList(); + } + + private IEnumerable> GetUniqueVacanciesAndNewApplicationCounts(IEnumerable messages, List vacancyRefs) + { + var vacancyRefApplicationCounts = messages + .SelectMany(m => m.DataItems + .Where(di => di.Key == CommunicationConstants.DataItemKeys.Vacancy.VacancyReference && vacancyRefs.Contains(di.Value)) + .GroupBy(di => di.Value) + ) + .GroupBy(di => di.Key) + .ToDictionary( + vacancyApplicationGroup => long.Parse(vacancyApplicationGroup.Key), + vacancyApplicationGroup => vacancyApplicationGroup.Count() + ); + return vacancyRefApplicationCounts; + } + } +} \ No newline at end of file diff --git a/src/Shared/Recruit.Vacancies.Client/Application/Communications/TemplateIdProviderPlugin.cs b/src/Shared/Recruit.Vacancies.Client/Application/Communications/TemplateIdProviderPlugin.cs index 08c6a5262e..92ff0444bc 100644 --- a/src/Shared/Recruit.Vacancies.Client/Application/Communications/TemplateIdProviderPlugin.cs +++ b/src/Shared/Recruit.Vacancies.Client/Application/Communications/TemplateIdProviderPlugin.cs @@ -9,7 +9,7 @@ public class TemplateIdProviderPlugin : ITemplateIdProvider { public string ProviderServiceName => CommunicationConstants.ServiceName; - public Task GetTemplateId(CommunicationMessage message, bool isAggregate = false) + public Task GetTemplateIdAsync(CommunicationMessage message) { var templateId = string.Empty; switch(message.RequestType) diff --git a/src/Shared/Recruit.Vacancies.Client/Recruit.Vacancies.Client.csproj b/src/Shared/Recruit.Vacancies.Client/Recruit.Vacancies.Client.csproj index 19cb74544c..0074162b97 100644 --- a/src/Shared/Recruit.Vacancies.Client/Recruit.Vacancies.Client.csproj +++ b/src/Shared/Recruit.Vacancies.Client/Recruit.Vacancies.Client.csproj @@ -21,6 +21,7 @@ + diff --git a/src/Shared/UnitTests/Vacancies.Client/Application/Communications/TemplateIdProviderPluginTests.cs b/src/Shared/UnitTests/Vacancies.Client/Application/Communications/TemplateIdProviderPluginTests.cs index c7b5f0e6af..98287d37e4 100644 --- a/src/Shared/UnitTests/Vacancies.Client/Application/Communications/TemplateIdProviderPluginTests.cs +++ b/src/Shared/UnitTests/Vacancies.Client/Application/Communications/TemplateIdProviderPluginTests.cs @@ -17,14 +17,14 @@ public class TemplateIdProviderPluginTests public async Task ReturnRespectiveTemplateId(string requestType, DeliveryFrequency frequency, string expectedTemplateId) { var plugin = new TemplateIdProviderPlugin(); - + var message = new CommunicationMessage() { RequestType = requestType, Frequency = frequency }; - var templateId = await plugin.GetTemplateId(message); + var templateId = await plugin.GetTemplateIdAsync(message); templateId.Should().Be(expectedTemplateId); }