diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Commands/PatchApprenticeshipPaymentsCommandHandlerTests.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Commands/PatchApprenticeshipPaymentsCommandHandlerTests.cs index 430336ea5..21f48fd0e 100644 --- a/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Commands/PatchApprenticeshipPaymentsCommandHandlerTests.cs +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2.UnitTests/Application/Commands/PatchApprenticeshipPaymentsCommandHandlerTests.cs @@ -1,12 +1,14 @@ using NServiceBus; using SFA.DAS.CommitmentsV2.Application.Commands.PatchApprenticeshipPayments; using SFA.DAS.CommitmentsV2.Authentication; +using SFA.DAS.CommitmentsV2.Configuration; using SFA.DAS.CommitmentsV2.Data; using SFA.DAS.CommitmentsV2.Domain.Exceptions; using SFA.DAS.CommitmentsV2.Messages.Commands; using SFA.DAS.CommitmentsV2.Models; using SFA.DAS.CommitmentsV2.Shared.Interfaces; using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.Encoding; using SFA.DAS.UnitOfWork.Context; namespace SFA.DAS.CommitmentsV2.UnitTests.Application.Commands; @@ -20,6 +22,9 @@ public class PatchApprenticeshipPaymentsCommandHandlerTests private Mock _currentDateTime; private Mock _messageSession; private UnitOfWorkContext _unitOfWorkContext; + private Mock _encodingService; + private CommitmentsV2Configuration _commitmentsV2Configuration; + private PatchApprenticeshipPaymentsCommandHandler _handler; [SetUp] @@ -33,13 +38,21 @@ public void Init() _currentDateTime = new Mock(); _currentDateTime.Setup(x => x.UtcNow).Returns(DateTime.UtcNow); _messageSession = new Mock(); + _encodingService = new Mock(); + _encodingService.Setup(x => x.Encode(It.IsAny(), EncodingType.ApprenticeshipId)).Returns("ABC123"); + _commitmentsV2Configuration = new CommitmentsV2Configuration(); + _commitmentsV2Configuration.ProviderUrl = new ProviderUrlConfiguration(); + _commitmentsV2Configuration.ProviderUrl.ProviderApprenticeshipServiceBaseUrl = "https://test.local"; _unitOfWorkContext = new UnitOfWorkContext(); _handler = new PatchApprenticeshipPaymentsCommandHandler( new Lazy(() => _dbContext), _currentDateTime.Object, _authenticationService.Object, - _messageSession.Object); + _messageSession.Object, + _encodingService.Object, + _commitmentsV2Configuration + ); } [TearDown] @@ -106,6 +119,30 @@ await _handler.Handle(new PatchApprenticeshipPaymentsCommand It.IsAny()), Times.Once); } + [TestCase(true, "ProviderApprenticeshipPaymentFrozenNotification")] + [TestCase(false, "ProviderApprenticeshipPaymentUnfrozenNotification")] + public async Task Handle_WhenPaymentFreezeDateProvided_SendsNotificationEmail(bool freeze, string template) + { + var apprenticeship = await SetupApprenticeship(frozen: !freeze); + _authenticationService.Setup(a => a.GetUserParty()).Returns(Party.Employer); + + await _handler.Handle(new PatchApprenticeshipPaymentsCommand + { + ApprenticeshipId = apprenticeship.Id, + PaymentFreezeDate = freeze ? DateTime.UtcNow.Date : null, + FreezePaymentsReason = freeze ? FreezePaymentsReason.LearnerOnBreak : null, + UserInfo = new UserInfo() + }, CancellationToken.None); + + _messageSession.Verify(x => x.Send( + It.Is(c => c.ProviderId == apprenticeship.Cohort.ProviderId && + c.Template == template && + c.Tokens["employer_name"] == apprenticeship.Cohort.AccountLegalEntity.Name && + c.Tokens["link_to_manage_apprenticeships"].Contains($"{apprenticeship.Cohort.ProviderId}/apprentices/ABC123") + ), + It.IsAny()), Times.Once); + } + [Test] public async Task Handle_WhenFreezePaymentsReasonMissing_ThrowsDomainException() { @@ -273,7 +310,7 @@ private async Task SetupApprenticeship(bool frozen = false, stri { EmployerAccountId = fixture.Create(), ProviderId = fixture.Create(), - AccountLegalEntity = new AccountLegalEntity() + AccountLegalEntity = new AccountLegalEntity(new Account(), 123, 1234, "XXXXX", "XXX123", "Test", CommitmentsV2.Models.OrganisationType.Other, null, DateTime.Today) }, PaymentStatus = PaymentStatus.Active, StartDate = DateTime.UtcNow.AddMonths(-2), diff --git a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Commands/PatchApprenticeshipPayments/PatchApprenticeshipPaymentsCommandHandler.cs b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Commands/PatchApprenticeshipPayments/PatchApprenticeshipPaymentsCommandHandler.cs index 097c22f2b..27d4c2c1a 100644 --- a/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Commands/PatchApprenticeshipPayments/PatchApprenticeshipPaymentsCommandHandler.cs +++ b/src/CommitmentsV2/SFA.DAS.CommitmentsV2/Application/Commands/PatchApprenticeshipPayments/PatchApprenticeshipPaymentsCommandHandler.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using NServiceBus; using SFA.DAS.CommitmentsV2.Authentication; +using SFA.DAS.CommitmentsV2.Configuration; using SFA.DAS.CommitmentsV2.Data; using SFA.DAS.CommitmentsV2.Data.Extensions; using SFA.DAS.CommitmentsV2.Domain.Exceptions; @@ -9,6 +10,7 @@ using SFA.DAS.CommitmentsV2.Models; using SFA.DAS.CommitmentsV2.Shared.Interfaces; using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.Encoding; namespace SFA.DAS.CommitmentsV2.Application.Commands.PatchApprenticeshipPayments; @@ -16,7 +18,9 @@ public class PatchApprenticeshipPaymentsCommandHandler( Lazy dbContext, ICurrentDateTime currentDate, IAuthenticationService authenticationService, - IMessageSession messageSession) + IMessageSession messageSession, + IEncodingService encodingService, + CommitmentsV2Configuration commitmentsV2Configuration) : IRequestHandler { public async Task Handle(PatchApprenticeshipPaymentsCommand command, CancellationToken cancellationToken) @@ -46,6 +50,8 @@ public async Task Handle(PatchApprenticeshipPaymentsCommand command, Cancellatio await dbContext.Value.SaveChangesAsync(cancellationToken); + await SendEmail(isFreeze, apprenticeship.Cohort.ProviderId, apprenticeship.Cohort.AccountLegalEntity.Name, apprenticeship.Id); + await messageSession.Send(new StoreLearningHistoryCommand { ApprenticeshipId = command.ApprenticeshipId, @@ -103,4 +109,24 @@ private async Task CheckPaymentsCanBeFrozen(Apprenticeship apprenticeship, Cance return null; } -} + + private async Task SendEmail(bool isFreeze, long providerId, string employerName, long apprenticeshipId) + { + var encodedApprenticeshipId = encodingService.Encode(apprenticeshipId, EncodingType.ApprenticeshipId); + + var sendEmailToProviderCommand = new SendEmailToProviderCommand( + providerId, + isFreeze ? "ProviderApprenticeshipPaymentFrozenNotification" : "ProviderApprenticeshipPaymentUnfrozenNotification", + new Dictionary + { + {"employer_name", employerName}, + { + "link_to_manage_apprenticeships", + $"{commitmentsV2Configuration.ProviderCommitmentsBaseUrl}{providerId}/apprentices/{encodedApprenticeshipId}\"" + }, + { "link_to_unsubscribe", $"{commitmentsV2Configuration.ProviderUrl.ProviderApprenticeshipServiceBaseUrl}notification-settings" } + }); + + await messageSession.Send(sendEmailToProviderCommand); + } +} \ No newline at end of file