From 3bd508b627568e433ed992bdb08b2a7547184708 Mon Sep 17 00:00:00 2001 From: Chris Woodcock Date: Fri, 11 Jun 2021 09:38:33 +0100 Subject: [PATCH 1/5] Migrated transfer details to v2 --- ...WhenCallingPostTransferDetailsForSender.cs | 104 ++++++++++ .../WhenCallingTransferDetailsForReceiver.cs | 35 ++++ .../WhenCallingTransferDetailsForSender.cs | 35 ++++ ...rRequestForReceiverViewModelMapperTests.cs | 193 ++++++++++++++++++ ...EmployerCommitmentsV2.Web.UnitTests.csproj | 4 +- .../Authorization/AuthorizationContextKeys.cs | 1 + .../AuthorizationContextProvider.cs | 6 + .../Controllers/TransferRequestController.cs | 90 ++++++++ .../Extensions/ILinkGeneratorExtensions.cs | 5 + .../TransferConfirmationViewModelMapper.cs | 23 +++ ...ansferConfirmationWhatNextRequestMapper.cs | 28 +++ ...ansferRequestForReceiverViewModelMapper.cs | 36 ++++ ...TransferRequestForSenderViewModelMapper.cs | 35 ++++ .../TransferRequestViewModelMapper.cs | 49 +++++ ...eTransferApprovalForSenderRequestMapper.cs | 35 ++++ .../TrainingCourseSummaryViewModel.cs | 17 ++ .../TransferConfirmationRequest.cs | 20 ++ .../TransferConfirmationViewModel.cs | 17 ++ .../TransferConfirmationWhatNextRequest.cs | 11 + .../TransferRequestForReceiverViewModel.cs | 9 + .../TransferRequestForSenderViewModel.cs | 9 + .../TransferRequest/TransferRequestRequest.cs | 16 ++ .../TransferRequestViewModel.cs | 28 +++ .../RouteValues/RouteValueKeys.cs | 1 + .../SFA.DAS.EmployerCommitmentsV2.Web.csproj | 8 +- .../TransferConfirmationViewModelValidator.cs | 15 ++ ...TransferRequestSenderViewModelValidator.cs | 15 ++ .../TransferConfirmation.cshtml | 67 ++++++ .../TransferDetailsForReceiver.cshtml | 96 +++++++++ .../TransferDetailsForSender.cshtml | 171 ++++++++++++++++ .../SFA.DAS.EmployerCommitmentsV2.csproj | 8 +- 31 files changed, 1177 insertions(+), 10 deletions(-) create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForSender.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapperTests.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationWhatNextRequestMapper.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapper.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForSenderViewModelMapper.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestViewModelMapper.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/UpdateTransferApprovalForSenderRequestMapper.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TrainingCourseSummaryViewModel.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationViewModel.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationWhatNextRequest.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForReceiverViewModel.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForSenderViewModel.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestRequest.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestViewModel.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferConfirmationViewModelValidator.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferRequestSenderViewModelValidator.cs create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForReceiver.cshtml create mode 100644 src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForSender.cshtml diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs new file mode 100644 index 000000000..e6f2e5989 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs @@ -0,0 +1,104 @@ +using AutoFixture.NUnit3; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Logging; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Requests; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Testing.AutoFixture; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.PaymentOrderControllerTests +{ + public class WhenCallingPostTransferDetailsForSender + { + [Test, MoqAutoData] + public async Task And_TransferDetailsForSender_Succeeds_Then_Redirect_To_Confirmation( + UpdateTransferApprovalForSenderRequest request, + TransferRequestForSenderViewModel viewModel, + [Frozen] Mock mockMapper, + TransferRequestController controller) + { + mockMapper + .Setup(mapper => mapper.Map(viewModel)) + .ReturnsAsync(request); + + request.TransferApprovalStatus = TransferApprovalStatus.Approved; + + var expectedRouteValues = new RouteValueDictionary(new + { + viewModel.AccountHashedId, + viewModel.TransferRequestHashedId, + request.TransferApprovalStatus, + viewModel.TransferReceiverName + }); + + var result = (await controller.TransferDetailsForSender(viewModel)) as RedirectToActionResult; + + result.Should().NotBeNull(); + result.ActionName.Should().Be("TransferConfirmation"); + result.ControllerName.Should().Be("TransferRequest"); + result.RouteValues.Should().BeEquivalentTo(expectedRouteValues); + } + + [Test, MoqAutoData] + public async Task And_TransferDetailsForSender_Succeeds_Then_Api_Called_To_Update( + Mock mockCommitmentsApiClient, + Mock> mockLogger, + UpdateTransferApprovalForSenderRequest request, + TransferRequestForSenderViewModel viewModel, + [Frozen] Mock mockMapper) + { + mockMapper + .Setup(mapper => mapper.Map(viewModel)) + .ReturnsAsync(request); + + mockCommitmentsApiClient + .Setup(r => r.UpdateTransferRequestForSender( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .Returns(Task.CompletedTask); + + TransferRequestController controller = new TransferRequestController(mockCommitmentsApiClient.Object, + mockLogger.Object, mockMapper.Object); + + var result = (await controller.TransferDetailsForSender(viewModel)) as RedirectToActionResult; + + mockCommitmentsApiClient.Verify(m => m.UpdateTransferRequestForSender( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), Times.Once); + } + + [Test, MoqAutoData] + public async Task And_TransferDetailsForSender_Fails_Then_Redirect_To_Error( + TransferRequestForSenderViewModel viewModel, + [Frozen] Mock mockMapper, + TransferRequestController controller) + { + mockMapper + .Setup(mapper => mapper.Map(viewModel)) + .ThrowsAsync(new Exception("Some error")); + + var result = (await controller.TransferDetailsForSender(viewModel)) as RedirectToActionResult; + + result.Should().NotBeNull(); + result.ActionName.Should().Be("Error"); + result.ControllerName.Should().Be("Error"); + result.RouteValues.Should().BeNull(); + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs new file mode 100644 index 000000000..be84f80b4 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using AutoFixture.NUnit3; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Testing.AutoFixture; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.PaymentOrderControllerTests + +{ + public class WhenCallingTransferDetailsForReceiver + { + [Test, MoqAutoData] + public async Task Then_Returns_View_With_Correct_Model( + TransferRequestRequest request, + TransferRequestForReceiverViewModel viewModel, + [Frozen] Mock mockMapper, + TransferRequestController controller) + { + mockMapper + .Setup(mapper => mapper.Map(request)) + .ReturnsAsync(viewModel); + + var result = await controller.TransferDetailsForReceiver(request) as ViewResult; + + result.ViewName.Should().BeNull(); + var model = result.Model as TransferRequestForReceiverViewModel; + model.Should().BeSameAs(viewModel); + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForSender.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForSender.cs new file mode 100644 index 000000000..c8a4533e0 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForSender.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using AutoFixture.NUnit3; +using FluentAssertions; +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Testing.AutoFixture; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.PaymentOrderControllerTests + +{ + public class WhenCallingTransferDetailsForSender + { + [Test, MoqAutoData] + public async Task Then_Returns_View_With_Correct_Model( + TransferRequestRequest request, + TransferRequestForSenderViewModel viewModel, + [Frozen] Mock mockMapper, + TransferRequestController controller) + { + mockMapper + .Setup(mapper => mapper.Map(request)) + .ReturnsAsync(viewModel); + + var result = await controller.TransferDetailsForSender(request) as ViewResult; + + result.ViewName.Should().BeNull(); + var model = result.Model as TransferRequestForSenderViewModel; + model.Should().BeSameAs(viewModel); + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapperTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapperTests.cs new file mode 100644 index 000000000..9455a082e --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapperTests.cs @@ -0,0 +1,193 @@ +using AutoFixture; +using Microsoft.Extensions.Logging; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Requests; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Encoding; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Mappers.Apprentice +{ + public class TransferConfirmationViewModelMapperTests + { + private Mock _mockCommitmentsApiClient; + private Mock _mockEncodingService; + + private GetTransferRequestResponse _getTransferRequestResponse; + private TransferRequestRequest _request; + + private TransferRequestForReceiverViewModelMapper _mapper; + + private const long AccountIdFirst = 12; + private const long TransferRequestIdFirst = 34; + private const long ReceivingEmployerAccountIdFirst = 56; + + [SetUp] + public void SetUp() + { + //Arrange + var autoFixture = new Fixture(); + _request = autoFixture.Build() + .With(x => x.AccountHashedId, $"A{AccountIdFirst}") + .With(x => x.TransferRequestHashedId, $"A{TransferRequestIdFirst}") + .Create(); + + _getTransferRequestResponse = autoFixture.Build() + .With(x => x.ReceivingEmployerAccountId, ReceivingEmployerAccountIdFirst) + .With(x => x.TransferRequestId, TransferRequestIdFirst) + .Create(); + + _mockCommitmentsApiClient = new Mock(); + _mockCommitmentsApiClient.Setup(r => r.GetTransferRequestForReceiver(It.IsAny(), It.IsAny(), CancellationToken.None)) + .ReturnsAsync(_getTransferRequestResponse); + + _mockEncodingService = new Mock(); + + _mockEncodingService.Setup(t => t.Encode(It.IsAny(), EncodingType.AccountId)) + .Returns((long value, EncodingType encodingType) => $"A{value}"); + _mockEncodingService.Setup(t => t.Encode(It.IsAny(), EncodingType.PublicAccountId)) + .Returns((long value, EncodingType encodingType) => $"P{value}"); + _mockEncodingService.Setup(t => t.Encode(It.IsAny(), EncodingType.TransferRequestId)) + .Returns((long value, EncodingType encodingType) => $"T{value}"); + _mockEncodingService.Setup(t => t.Encode(It.IsAny(), EncodingType.CohortReference)) + .Returns((long value, EncodingType encodingType) => $"C{value}"); + _mockEncodingService.Setup(t => t.Decode(It.IsAny(), It.IsAny())) + .Returns((string value, EncodingType encodingType) => long.Parse(Regex.Replace(value, "[A-Za-z ]", ""))); + + _mapper = new TransferRequestForReceiverViewModelMapper(_mockCommitmentsApiClient.Object, _mockEncodingService.Object); + } + + [Test] + public async Task GetTransferRequestForReceiverIsCalled() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + _mockCommitmentsApiClient.Verify(t => t.GetTransferRequestForReceiver(_request.AccountId, _request.TransferRequestId, It.IsAny()), Times.Once()); + } + + [Test] + public async Task TransferReceiverHashedAccountId_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual($"A{_getTransferRequestResponse.ReceivingEmployerAccountId}", result.TransferReceiverHashedAccountId); + } + + [Test] + public async Task TransferSenderPublicHashedAccountId_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual($"P{_getTransferRequestResponse.SendingEmployerAccountId}", result.TransferSenderPublicHashedAccountId); + } + + [Test] + public async Task TransferSenderName_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual(_getTransferRequestResponse.TransferSenderName, result.TransferSenderName); + } + + [Test] + public async Task HashedCohortReference_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual($"C{_getTransferRequestResponse.CommitmentId}", result.HashedCohortReference); + } + + [Test] + public async Task TransferApprovalStatusDesc_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual(_getTransferRequestResponse.Status.ToString(), result.TransferApprovalStatusDesc); + } + + [Test] + public async Task TransferApprovalSetBy_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual(_getTransferRequestResponse.ApprovedOrRejectedByUserName, result.TransferApprovalSetBy); + } + + [Test] + public async Task TransferApprovalSetOn_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual(_getTransferRequestResponse.ApprovedOrRejectedOn, result.TransferApprovalSetOn); + } + + [Test] + public async Task TotalCost_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual(_getTransferRequestResponse.TransferCost, result.TotalCost); + } + + [Test] + public async Task FundingCap_IsMapped() + { + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual(_getTransferRequestResponse.FundingCap, result.FundingCap); + } + + [TestCase(TransferApprovalStatus.Pending, 1500.0, 12000, true)] + [TestCase(TransferApprovalStatus.Approved, 1500.0, 12000, true)] + [TestCase(TransferApprovalStatus.Pending, 12000.0, 12000, false)] + [TestCase(TransferApprovalStatus.Approved, 12000.0, 12000, false)] + [TestCase(TransferApprovalStatus.Pending, 13000.0, 12000, false)] + [TestCase(TransferApprovalStatus.Approved, 13000.0, 12000, false)] + [TestCase(TransferApprovalStatus.Rejected, 1500.0, 12000, false)] + [TestCase(TransferApprovalStatus.Rejected, 12000.0, 12000, false)] + [TestCase(TransferApprovalStatus.Rejected, 13000.0, 12000, false)] + public async Task TrainingName_IsMapped(TransferApprovalStatus transferApprovalStatus, decimal transferCost, int fundingCap, bool showFundingCapWarning) + { + // Arrange + _getTransferRequestResponse.Status = transferApprovalStatus; + _getTransferRequestResponse.TransferCost = transferCost; + _getTransferRequestResponse.FundingCap = fundingCap; + + //Act + var result = await _mapper.Map(_request); + + //Assert + Assert.AreEqual(showFundingCapWarning, result.ShowFundingCapWarning); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj index 642384b13..ba3732166 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextKeys.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextKeys.cs index 3a4e6691e..8291fe25f 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextKeys.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextKeys.cs @@ -7,6 +7,7 @@ public static class AuthorizationContextKeys public const string AccountLegalEntityId = "AccountLegalEntityId"; public const string DraftApprenticeshipId = "DraftApprenticeshipId"; public const string DecodedTransferSenderId = "DecodedTransferSenderId"; + public const string TransferRequestId = "TransferRequestId"; public const string ApprenticeshipId = "ApprenticeshipId"; } } \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextProvider.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextProvider.cs index 1051499fa..bb79064a6 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextProvider.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Authorization/AuthorizationContextProvider.cs @@ -36,6 +36,7 @@ public IAuthorizationContext GetAuthorizationContext() CopyRouteValueToAuthorizationContextIfAvailable(authorizationContext, GetAccountLegalEntityHashedId(), AuthorizationContextKeys.AccountLegalEntityId); CopyRouteValueToAuthorizationContextIfAvailable(authorizationContext, GetDraftApprenticeshipId(), AuthorizationContextKeys.DraftApprenticeshipId); CopyRouteValueToAuthorizationContextIfAvailable(authorizationContext, GetTransferSenderId(), AuthorizationContextKeys.DecodedTransferSenderId); + CopyRouteValueToAuthorizationContextIfAvailable(authorizationContext, GetTransferRequestId(), AuthorizationContextKeys.TransferRequestId); CopyRouteValueToAuthorizationContextIfAvailable(authorizationContext, GetApprenticeshipId(), AuthorizationContextKeys.ApprenticeshipId); if (accountId.HasValue && userRef.HasValue) @@ -89,6 +90,11 @@ private void CopyRouteValueToAuthorizationContextIfAvailable(IAuthorizationCo return GetAndDecodeValueIfExists(RouteValueKeys.TransferSenderId, EncodingType.PublicAccountId); } + private long? GetTransferRequestId() + { + return GetAndDecodeValueIfExists(RouteValueKeys.TransferRequestHashedId, EncodingType.TransferRequestId); + } + private Guid? GetUserRef() { if (!_authenticationService.IsUserAuthenticated()) diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs new file mode 100644 index 000000000..c0b94e0f7 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs @@ -0,0 +1,90 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using SFA.DAS.Authorization.EmployerUserRoles.Options; +using SFA.DAS.Authorization.Mvc.Attributes; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Requests; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Extensions; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using System; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Controllers +{ + [DasAuthorize(EmployerUserRole.OwnerOrTransactor)] + [Route("accounts/{accountHashedId}/")] + public class TransferRequestController : Controller + { + private readonly ICommitmentsApiClient _commitmentsApiClient; + private readonly ILogger _logger; + private readonly IModelMapper _modelMapper; + + public TransferRequestController( + ICommitmentsApiClient commitmentsApiClient, + ILogger logger, + IModelMapper modelMapper) + { + _commitmentsApiClient = commitmentsApiClient; + _logger = logger; + _modelMapper = modelMapper; + } + + [HttpGet] + [Route("sender/transfers/{transferRequestHashedId}")] + public async Task TransferDetailsForSender(TransferRequestRequest request) + { + _logger.LogInformation($"Getting TransferRequest Details, Transfer Account: {request.AccountId}, TransferRequestId: {request.TransferRequestId}"); + + var viewModel = await _modelMapper.Map(request); + return View(viewModel); + } + + [HttpPost] + [Route("sender/transfers/{transferRequestHashedId}")] + public async Task TransferDetailsForSender(TransferRequestForSenderViewModel viewModel) + { + _logger.LogInformation($"Updating TransferRequest, Account: {viewModel.TransferSenderHashedAccountId}, CohortReference: {viewModel.HashedCohortReference}"); + + try + { + var request = await _modelMapper.Map(viewModel); + await _commitmentsApiClient.UpdateTransferRequestForSender(request.TransferSenderId, request.TransferRequestId, request.CohortId, request); + + return RedirectToAction(nameof(TransferRequestController.TransferConfirmation), nameof(TransferRequestController).ControllerName(), new { viewModel.AccountHashedId, viewModel.TransferRequestHashedId, request.TransferApprovalStatus, viewModel.TransferReceiverName }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to update transfer request"); + } + + return RedirectToAction("Error", "Error"); + } + + [HttpGet] + [Route("sender/transfers/{transferRequestHashedId}/confirmation")] + public async Task TransferConfirmation(TransferConfirmationRequest request) + { + var viewModel = await _modelMapper.Map(request); + return View(viewModel); + } + + [HttpPost] + [Route("sender/transfers/{transferRequestHashedId}/confirmation")] + public async Task TransferConfirmation(TransferConfirmationViewModel viewModel) + { + var request = await _modelMapper.Map(viewModel); + return Redirect(request.WhatNextUrl); + } + + [HttpGet] + [Route("receiver/transfers/{transferRequestHashedId}")] + public async Task TransferDetailsForReceiver(TransferRequestRequest request) + { + _logger.LogInformation($"Getting TransferRequest Details, Transfer Account: {request.AccountId}, TransferRequestId: {request.TransferRequestId}"); + + var viewModel = await _modelMapper.Map(request); + return View(viewModel); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs index e79f654e7..5f0da1942 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs @@ -109,6 +109,11 @@ public static string EmployerHome(this ILinkGenerator linkGenerator, string acco return linkGenerator.AccountsLink($"accounts/{accountHashedId}/teams"); } + public static string EmployerAccountsTransfers(this ILinkGenerator linkGenerator, string accountHashedId) + { + return linkGenerator.AccountsLink($"accounts/{accountHashedId}/transfers"); + } + public static string EmployerAccountsHome(this ILinkGenerator linkGenerator) { return linkGenerator.AccountsLink(); diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs new file mode 100644 index 000000000..fbf10e55c --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs @@ -0,0 +1,23 @@ +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest +{ + public class TransferConfirmationViewModelMapper : IMapper + { + public TransferConfirmationViewModelMapper() + { + } + + public async Task Map(TransferConfirmationRequest source) + { + return await Task.FromResult(new TransferConfirmationViewModel + { + TransferApprovalStatus = source.TransferApprovalStatus == TransferApprovalStatus.Approved ? "approved" : "rejected", + TransferReceiverName = source.TransferReceiverName + }); + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationWhatNextRequestMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationWhatNextRequestMapper.cs new file mode 100644 index 000000000..f57cff756 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationWhatNextRequestMapper.cs @@ -0,0 +1,28 @@ +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Extensions; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.EmployerUrlHelper; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest +{ + public class TransferConfirmationWhatNextRequestMapper : IMapper + { + private readonly ILinkGenerator _linkGenerator; + + public TransferConfirmationWhatNextRequestMapper(ILinkGenerator linkGenerator) + { + _linkGenerator = linkGenerator; + } + + public async Task Map(TransferConfirmationViewModel source) + { + return await Task.FromResult(new TransferConfirmationWhatNextRequest + { + WhatNextUrl = source.SelectedOption == TransferConfirmationViewModel.Option.Homepage + ? _linkGenerator.EmployerHome(source.AccountHashedId) + : _linkGenerator.EmployerAccountsTransfers(source.AccountHashedId) + }); ; + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapper.cs new file mode 100644 index 000000000..1bbfc3737 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForReceiverViewModelMapper.cs @@ -0,0 +1,36 @@ +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Encoding; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest +{ + public class TransferRequestForReceiverViewModelMapper : TransferRequestViewModelMapper, + IMapper + { + public TransferRequestForReceiverViewModelMapper(ICommitmentsApiClient commitmentsApiClient, IEncodingService encodingService) + : base(commitmentsApiClient, encodingService) + { + } + + public async Task Map(TransferRequestRequest source) + { + var response = await _commitmentsApiClient.GetTransferRequestForReceiver(source.AccountId, source.TransferRequestId); + var viewModel = Map(response); + return viewModel; + } + + protected override TransferRequestForReceiverViewModel Map(GetTransferRequestResponse response) + { + var viewModel = base.Map(response); + + viewModel.TransferSenderPublicHashedAccountId = _encodingService.Encode(response.SendingEmployerAccountId, EncodingType.PublicAccountId); + viewModel.TransferReceiverHashedAccountId = _encodingService.Encode(response.ReceivingEmployerAccountId, EncodingType.AccountId); + viewModel.TransferSenderName = response.TransferSenderName; + + return viewModel; + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForSenderViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForSenderViewModelMapper.cs new file mode 100644 index 000000000..172a49f6c --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestForSenderViewModelMapper.cs @@ -0,0 +1,35 @@ +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Encoding; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest +{ + public class TransferRequestForSenderViewModelMapper : TransferRequestViewModelMapper, IMapper + { + public TransferRequestForSenderViewModelMapper(ICommitmentsApiClient commitmentsApiClient, IEncodingService encodingService) + : base(commitmentsApiClient, encodingService) + { + } + + public async Task Map(TransferRequestRequest source) + { + var response = await _commitmentsApiClient.GetTransferRequestForSender(source.AccountId, source.TransferRequestId); + var viewModel = Map(response); + return viewModel; + } + + protected override TransferRequestForSenderViewModel Map(GetTransferRequestResponse response) + { + var viewModel = base.Map(response); + + viewModel.TransferReceiverPublicHashedAccountId = _encodingService.Encode(response.ReceivingEmployerAccountId, EncodingType.PublicAccountId); + viewModel.TransferSenderHashedAccountId = _encodingService.Encode(response.SendingEmployerAccountId, EncodingType.AccountId); + viewModel.TransferReceiverName = response.LegalEntityName; + + return viewModel; + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestViewModelMapper.cs new file mode 100644 index 000000000..9d5ed7cfe --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferRequestViewModelMapper.cs @@ -0,0 +1,49 @@ +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Encoding; +using System.Collections.Generic; +using System.Linq; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest +{ + public class TransferRequestViewModelMapper where T : TransferRequestViewModel, new() + { + protected readonly ICommitmentsApiClient _commitmentsApiClient; + protected readonly IEncodingService _encodingService; + + public TransferRequestViewModelMapper(ICommitmentsApiClient commitmentsApiClient, IEncodingService encodingService) + { + _commitmentsApiClient = commitmentsApiClient; + _encodingService = encodingService; + } + + protected virtual T Map(GetTransferRequestResponse response) + { + return new T + { + HashedCohortReference = _encodingService.Encode(response.CommitmentId, EncodingType.CohortReference), + TrainingList = response.TrainingList?.Select(MapTrainingCourse).ToList() ?? new List(), + TransferApprovalStatusDesc = response.Status.ToString(), + TransferApprovalStatus = response.Status, + TransferApprovalSetBy = response.ApprovedOrRejectedByUserName, + TransferApprovalSetOn = response.ApprovedOrRejectedOn, + TotalCost = response.TransferCost, + FundingCap = response.FundingCap, + ShowFundingCapWarning = (response.Status == TransferApprovalStatus.Pending + || response.Status == TransferApprovalStatus.Approved) + && response.TransferCost < response.FundingCap + }; + } + + private TrainingCourseSummaryViewModel MapTrainingCourse(TrainingCourseSummary trainingCourseSummary) + { + return new TrainingCourseSummaryViewModel + { + ApprenticeshipCount = trainingCourseSummary.ApprenticeshipCount, + CourseTitle = trainingCourseSummary.CourseTitle + }; + } + } +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/UpdateTransferApprovalForSenderRequestMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/UpdateTransferApprovalForSenderRequestMapper.cs new file mode 100644 index 000000000..d259dca45 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/UpdateTransferApprovalForSenderRequestMapper.cs @@ -0,0 +1,35 @@ +using SFA.DAS.CommitmentsV2.Api.Types.Requests; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Authentication; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; +using SFA.DAS.Encoding; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest +{ + public class UpdateTransferApprovalForSenderRequestMapper : IMapper + { + private readonly IAuthenticationService _authenticationService; + protected readonly IEncodingService _encodingService; + + public UpdateTransferApprovalForSenderRequestMapper(IAuthenticationService authenticationService, IEncodingService encodingService) + { + _authenticationService = authenticationService; + _encodingService = encodingService; + } + + public async Task Map(TransferRequestForSenderViewModel source) + { + return await Task.FromResult(new UpdateTransferApprovalForSenderRequest + { + TransferSenderId = _encodingService.Decode(source.AccountHashedId, EncodingType.AccountId), + TransferRequestId = _encodingService.Decode(source.TransferRequestHashedId, EncodingType.TransferRequestId), + CohortId = _encodingService.Decode(source.HashedCohortReference, EncodingType.CohortReference), + TransferReceiverId = _encodingService.Decode(source.TransferReceiverPublicHashedAccountId, EncodingType.PublicAccountId), + TransferApprovalStatus = source.ApprovalConfirmed.Value ? TransferApprovalStatus.Approved : TransferApprovalStatus.Rejected, + UserInfo = _authenticationService.UserInfo + }); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TrainingCourseSummaryViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TrainingCourseSummaryViewModel.cs new file mode 100644 index 000000000..ce6f1ca97 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TrainingCourseSummaryViewModel.cs @@ -0,0 +1,17 @@ +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public sealed class TrainingCourseSummaryViewModel + { + public string CourseTitle { get; set; } + public int ApprenticeshipCount { get; set; } + + public string SummaryDescription + { + get + { + var label = ApprenticeshipCount == 1 ? "Apprentice" : "Apprentices"; + return $"{CourseTitle} ({ApprenticeshipCount} {label})"; + } + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs new file mode 100644 index 000000000..1e3ff97f7 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Mvc; +using SFA.DAS.Authorization.ModelBinding; +using SFA.DAS.CommitmentsV2.Types; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public class TransferConfirmationRequest : IAuthorizationContextModel + { + [FromRoute] + public string AccountHashedId { get; set; } + public long AccountId { get; set; } + + [FromRoute] + public string TransferRequestHashedId { get; set; } + public long TransferRequestId { get; set; } + + public TransferApprovalStatus TransferApprovalStatus { get; set; } + public string TransferReceiverName { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationViewModel.cs new file mode 100644 index 000000000..884102abb --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationViewModel.cs @@ -0,0 +1,17 @@ +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public class TransferConfirmationViewModel + { + public string AccountHashedId { get; set; } + + public string TransferApprovalStatus { get; set; } + public string TransferReceiverName { get; set; } + public Option? SelectedOption { get; set; } + + public enum Option + { + Homepage, TransfersDashboard + } + + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationWhatNextRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationWhatNextRequest.cs new file mode 100644 index 000000000..c5e191dec --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationWhatNextRequest.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; +using SFA.DAS.Authorization.ModelBinding; +using SFA.DAS.CommitmentsV2.Types; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public class TransferConfirmationWhatNextRequest : IAuthorizationContextModel + { + public string WhatNextUrl { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForReceiverViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForReceiverViewModel.cs new file mode 100644 index 000000000..46e868a87 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForReceiverViewModel.cs @@ -0,0 +1,9 @@ +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public sealed class TransferRequestForReceiverViewModel : TransferRequestViewModel + { + public string TransferReceiverHashedAccountId { get; set; } + public string TransferSenderPublicHashedAccountId { get; set; } + public string TransferSenderName { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForSenderViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForSenderViewModel.cs new file mode 100644 index 000000000..120799a71 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestForSenderViewModel.cs @@ -0,0 +1,9 @@ +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public sealed class TransferRequestForSenderViewModel : TransferRequestViewModel + { + public string TransferSenderHashedAccountId { get; set; } + public string TransferReceiverPublicHashedAccountId { get; set; } + public string TransferReceiverName { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestRequest.cs new file mode 100644 index 000000000..3047499b8 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestRequest.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Mvc; +using SFA.DAS.Authorization.ModelBinding; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public class TransferRequestRequest : IAuthorizationContextModel + { + [FromRoute] + public string AccountHashedId { get; set; } + public long AccountId { get; set; } + + [FromRoute] + public string TransferRequestHashedId { get; set; } + public long TransferRequestId { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestViewModel.cs new file mode 100644 index 000000000..3bed6d884 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferRequestViewModel.cs @@ -0,0 +1,28 @@ +using SFA.DAS.CommitmentsV2.Types; +using System; +using System.Collections.Generic; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +{ + public class TransferRequestViewModel + { + public TransferRequestViewModel() + { + TrainingList = new List(); + } + + public string AccountHashedId { get; set; } + public string TransferRequestHashedId { get; set; } + public string HashedCohortReference { get; set; } + public decimal TotalCost { get; set; } + public int FundingCap { get; set; } + public List TrainingList { get; set; } + public string TransferApprovalStatusDesc { get; set; } + public TransferApprovalStatus TransferApprovalStatus { get; set; } + public string TransferApprovalSetBy { get; set; } + public DateTime? TransferApprovalSetOn { get; set; } + public bool PendingApproval => TransferApprovalStatus == TransferApprovalStatus.Pending; + public bool ShowFundingCapWarning { get; set; } + public bool? ApprovalConfirmed { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteValueKeys.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteValueKeys.cs index eb4faeb01..36d89f660 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteValueKeys.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteValueKeys.cs @@ -7,6 +7,7 @@ public class RouteValueKeys public const string AccountLegalEntityHashedId = "AccountLegalEntityHashedId"; public const string DraftApprenticeshipHashedId = "DraftApprenticeshipHashedId"; public const string TransferSenderId = "TransferSenderId"; + public const string TransferRequestHashedId = "TransferRequestHashedId"; public const string ApprenticeshipHashedId = "ApprenticeshipHashedId"; } } diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj b/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj index 86c0cce57..4473f4582 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj @@ -25,10 +25,10 @@ - - - - + + + + diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferConfirmationViewModelValidator.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferConfirmationViewModelValidator.cs new file mode 100644 index 000000000..5cdcee598 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferConfirmationViewModelValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Validators +{ + public class TransferConfirmationViewModelValidator : AbstractValidator + { + public TransferConfirmationViewModelValidator() + { + RuleFor(x => x.SelectedOption) + .NotNull() + .WithMessage("Confirm what you want to do next"); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferRequestSenderViewModelValidator.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferRequestSenderViewModelValidator.cs new file mode 100644 index 000000000..d97aa321a --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Validators/TransferRequestSenderViewModelValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Validators +{ + public class TransferRequestSenderViewModelValidator : AbstractValidator + { + public TransferRequestSenderViewModelValidator() + { + RuleFor(x => x.ApprovalConfirmed) + .NotNull() + .WithMessage("Confirm if you want to accept or reject the transfer request"); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml new file mode 100644 index 000000000..06d583ae3 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml @@ -0,0 +1,67 @@ +@inject ILinkGenerator LinkGenerator; +@using SFA.DAS.CommitmentsV2.Shared.Extensions +@using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +@model TransferConfirmationViewModel + +@{ + ViewBag.Title = $"Transfer request {Model.TransferApprovalStatus}"; + ViewBag.Section = ""; + ViewBag.PageID = "transfer-confirmation"; +} + +
+
+ +
+ +
+
+

@ViewBag.Title

+
+ You have @Model.TransferApprovalStatus a transfer request from @Model.TransferReceiverName +
+
+ +
+ + + + + @Html.AntiForgeryToken() + +

What next?

+ +
+
+ @if (!ViewData.ModelState.IsValid) + { + + Error: @ViewData.ModelState[nameof(TransferRequestForSenderViewModel.ApprovalConfirmed)].Errors.First().ErrorMessage + + } +
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+ +@section Back +{ + +} + diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForReceiver.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForReceiver.cshtml new file mode 100644 index 000000000..bf40e7769 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForReceiver.cshtml @@ -0,0 +1,96 @@ +@inject ILinkGenerator LinkGenerator; +@using SFA.DAS.EmployerCommitmentsV2.Web.Extensions +@using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +@model TransferRequestForReceiverViewModel + +@{ + ViewBag.Title = "Transfer request details"; + ViewBag.Section = "apprentices"; + ViewBag.PageID = "approve-transfer-cohort"; + ViewBag.GaData.Vpv = "/accounts/apprentices/legalEntity/create/choose-organisation"; +} + +
+
+ +

@ViewBag.Title

+ +
+
+
+ Account name +
+
+ @Model.TransferSenderName +
+
+
+
+ Cohort reference +
+
+ @Model.HashedCohortReference +
+
+
+
+ Status +
+
+ @Model.TransferApprovalStatusDesc +
+
+
+
+ Total cost +
+
+ @($"£{Model.TotalCost:n0}") +
+
+
+
+ Current transfer request +
+
+ @($"£{Model.TotalCost:n0}") +
+
+
+
+ Training +
+
+ @foreach (var item in Model.TrainingList) + { +

@item.SummaryDescription

+ } +
+
+ @if (!Model.PendingApproval) + { +
+
+ @Model.TransferApprovalStatusDesc by +
+
+ @Model.TransferApprovalSetBy +
+
+
+
+ @Model.TransferApprovalStatusDesc on +
+
+ @($"{Model.TransferApprovalSetOn:dd MMM yyyy}") +
+
+ } +
+
+
+ +@section Back +{ + Back to Transfers +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForSender.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForSender.cshtml new file mode 100644 index 000000000..4cc79ff20 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferDetailsForSender.cshtml @@ -0,0 +1,171 @@ +@inject ILinkGenerator LinkGenerator; +@using SFA.DAS.CommitmentsV2.Shared.Extensions +@using SFA.DAS.EmployerCommitmentsV2.Web.Extensions +@using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest +@model TransferRequestForSenderViewModel + +@{ + ViewBag.Title = "Transfer request details"; + ViewBag.Section = "apprentices"; + ViewBag.PageID = "approve-transfer-cohort"; + ViewBag.GaData.Vpv = "/accounts/apprentices/legalEntity/create/choose-organisation"; +} + +
+
+ @if (Model.PendingApproval) + { + + } + +

@ViewBag.Title

+ @if (Model.ShowFundingCapWarning) + { +
+
+

+ Important +

+
+
+ Transfer request is lower than the funding band maximum +

+ The receiving employer and training provider could renegotiate the total cost of the training during the lifetime of the apprenticeship up to the funding band maximum. +

+

+ You will not be asked to approve these funding changes. +

+
+
+ } + +
+
+
+ Receiving employer +
+
+ @Model.TransferReceiverName +
+
+
+
+ Receiving employer account ID +
+
+ @Model.TransferReceiverPublicHashedAccountId +
+
+
+
+ Cohort reference +
+
+ @Model.HashedCohortReference +
+
+
+
+ Status +
+
+ @Model.TransferApprovalStatusDesc +
+
+
+
+ Current transfer request +
+
+ @($"£{Model.TotalCost:n0}") +
+
+ @if (Model.ShowFundingCapWarning) + { +
+
+ Funding band maximum +
+
+ @($"£{Model.FundingCap:n0}") +
+
+ } +
+
+ Training +
+
+ @foreach (var item in Model.TrainingList) + { +

@item.SummaryDescription

+ } +
+
+ @if (!Model.PendingApproval) + { +
+
+ @Model.TransferApprovalStatusDesc by +
+
+ @Model.TransferApprovalSetBy +
+
+
+
+ @Model.TransferApprovalStatusDesc on +
+
+ @($"{Model.TransferApprovalSetOn:dd MMM yyyy}") +
+
+ } +
+ + @if (Model.PendingApproval) + { +
+ + + + + @Html.AntiForgeryToken() + +

Do you want to accept or reject the request?

+ +
+
+ @if (!ViewData.ModelState.IsValid) + { + + Error: @ViewData.ModelState[nameof(TransferRequestForSenderViewModel.ApprovalConfirmed)].Errors.First().ErrorMessage + + } +
+
+ + +
+
+ + +
+
+
+
+ + Cancel +
+ } +
+
+ +@section Back +{ + Back to Transfers +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj b/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj index d744e0d4d..b20c5c749 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj @@ -11,12 +11,12 @@ - - - + + + - + From 303329dee50556d41685f4ab1221b71ae642bd9c Mon Sep 17 00:00:00 2001 From: Chris Woodcock Date: Wed, 16 Jun 2021 13:37:24 +0100 Subject: [PATCH 2/5] Removed accounts from url for consistency with other endpoints in commitments --- .../Controllers/TransferRequestController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs index c0b94e0f7..1173e2545 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs @@ -13,7 +13,7 @@ namespace SFA.DAS.EmployerCommitmentsV2.Web.Controllers { [DasAuthorize(EmployerUserRole.OwnerOrTransactor)] - [Route("accounts/{accountHashedId}/")] + [Route("{accountHashedId}")] public class TransferRequestController : Controller { private readonly ICommitmentsApiClient _commitmentsApiClient; From 3fdcd3dad2cc01427c26b49dfc01b022fafc379b Mon Sep 17 00:00:00 2001 From: Chris Woodcock Date: Thu, 17 Jun 2021 17:15:02 +0100 Subject: [PATCH 3/5] Fixed error handling and corrected redirect --- .../WhenCallingPostTransferDetailsForSender.cs | 14 +------------- .../WhenCallingTransferDetailsForReceiver.cs | 2 +- .../Controllers/TransferRequestController.cs | 2 +- .../TransferConfirmationViewModelMapper.cs | 18 ++++++++++++------ .../TransferConfirmationRequest.cs | 5 +---- .../TransferConfirmation.cshtml | 2 +- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs index e6f2e5989..c1cc8f755 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingPostTransferDetailsForSender.cs @@ -8,7 +8,6 @@ using SFA.DAS.CommitmentsV2.Api.Client; using SFA.DAS.CommitmentsV2.Api.Types.Requests; using SFA.DAS.CommitmentsV2.Shared.Interfaces; -using SFA.DAS.CommitmentsV2.Types; using SFA.DAS.EmployerCommitmentsV2.Web.Controllers; using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; using SFA.DAS.Testing.AutoFixture; @@ -16,7 +15,7 @@ using System.Threading; using System.Threading.Tasks; -namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.PaymentOrderControllerTests +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.TransferRequestControllerTests { public class WhenCallingPostTransferDetailsForSender { @@ -31,22 +30,11 @@ public async Task And_TransferDetailsForSender_Succeeds_Then_Redirect_To_Confirm .Setup(mapper => mapper.Map(viewModel)) .ReturnsAsync(request); - request.TransferApprovalStatus = TransferApprovalStatus.Approved; - - var expectedRouteValues = new RouteValueDictionary(new - { - viewModel.AccountHashedId, - viewModel.TransferRequestHashedId, - request.TransferApprovalStatus, - viewModel.TransferReceiverName - }); - var result = (await controller.TransferDetailsForSender(viewModel)) as RedirectToActionResult; result.Should().NotBeNull(); result.ActionName.Should().Be("TransferConfirmation"); result.ControllerName.Should().Be("TransferRequest"); - result.RouteValues.Should().BeEquivalentTo(expectedRouteValues); } [Test, MoqAutoData] diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs index be84f80b4..f6550f245 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Controllers/TransferRequest/WhenCallingTransferDetailsForReceiver.cs @@ -9,7 +9,7 @@ using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; using SFA.DAS.Testing.AutoFixture; -namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.PaymentOrderControllerTests +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Controllers.TransferRequestControllerTests { public class WhenCallingTransferDetailsForReceiver diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs index 1173e2545..19100299d 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs @@ -51,7 +51,7 @@ public async Task TransferDetailsForSender(TransferRequestForSend var request = await _modelMapper.Map(viewModel); await _commitmentsApiClient.UpdateTransferRequestForSender(request.TransferSenderId, request.TransferRequestId, request.CohortId, request); - return RedirectToAction(nameof(TransferRequestController.TransferConfirmation), nameof(TransferRequestController).ControllerName(), new { viewModel.AccountHashedId, viewModel.TransferRequestHashedId, request.TransferApprovalStatus, viewModel.TransferReceiverName }); + return RedirectToAction(nameof(TransferRequestController.TransferConfirmation), nameof(TransferRequestController).ControllerName()); } catch (Exception ex) { diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs index fbf10e55c..193696dad 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/TransferRequest/TransferConfirmationViewModelMapper.cs @@ -1,4 +1,5 @@ -using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; using SFA.DAS.CommitmentsV2.Types; using SFA.DAS.EmployerCommitmentsV2.Web.Models.TransferRequest; using System.Threading.Tasks; @@ -7,17 +8,22 @@ namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.TransferRequest { public class TransferConfirmationViewModelMapper : IMapper { - public TransferConfirmationViewModelMapper() + protected readonly ICommitmentsApiClient _commitmentsApiClient; + + public TransferConfirmationViewModelMapper(ICommitmentsApiClient commitmentsApiClient) { + _commitmentsApiClient = commitmentsApiClient; } public async Task Map(TransferConfirmationRequest source) { - return await Task.FromResult(new TransferConfirmationViewModel + var response = await _commitmentsApiClient.GetTransferRequestForSender(source.AccountId, source.TransferRequestId); + + return new TransferConfirmationViewModel { - TransferApprovalStatus = source.TransferApprovalStatus == TransferApprovalStatus.Approved ? "approved" : "rejected", - TransferReceiverName = source.TransferReceiverName - }); + TransferApprovalStatus = response.Status == TransferApprovalStatus.Approved ? "approved" : "rejected", + TransferReceiverName = response.LegalEntityName + }; } } } \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs index 1e3ff97f7..5f4f4de6e 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/TransferRequest/TransferConfirmationRequest.cs @@ -9,12 +9,9 @@ public class TransferConfirmationRequest : IAuthorizationContextModel [FromRoute] public string AccountHashedId { get; set; } public long AccountId { get; set; } - + [FromRoute] public string TransferRequestHashedId { get; set; } public long TransferRequestId { get; set; } - - public TransferApprovalStatus TransferApprovalStatus { get; set; } - public string TransferReceiverName { get; set; } } } diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml index 06d583ae3..60d2246f5 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/TransferRequest/TransferConfirmation.cshtml @@ -36,7 +36,7 @@ @if (!ViewData.ModelState.IsValid) { - Error: @ViewData.ModelState[nameof(TransferRequestForSenderViewModel.ApprovalConfirmed)].Errors.First().ErrorMessage + Error: @ViewData.ModelState[nameof(TransferConfirmationViewModel.SelectedOption)].Errors.First().ErrorMessage }
From 0dced4d709734effbfc44d34e5e5d7eaab44c6c2 Mon Sep 17 00:00:00 2001 From: Chris Woodcock Date: Fri, 18 Jun 2021 13:32:43 +0100 Subject: [PATCH 4/5] Added missing route values --- .../Controllers/TransferRequestController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs index 19100299d..8c3c98d52 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/TransferRequestController.cs @@ -51,7 +51,7 @@ public async Task TransferDetailsForSender(TransferRequestForSend var request = await _modelMapper.Map(viewModel); await _commitmentsApiClient.UpdateTransferRequestForSender(request.TransferSenderId, request.TransferRequestId, request.CohortId, request); - return RedirectToAction(nameof(TransferRequestController.TransferConfirmation), nameof(TransferRequestController).ControllerName()); + return RedirectToAction(nameof(TransferRequestController.TransferConfirmation), nameof(TransferRequestController).ControllerName(), new { viewModel.AccountHashedId, viewModel.TransferRequestHashedId }); } catch (Exception ex) { From 8503f68115eb492498139cdac8b107f909e57d34 Mon Sep 17 00:00:00 2001 From: Chris Woodcock Date: Mon, 21 Jun 2021 14:53:31 +0100 Subject: [PATCH 5/5] Updated to latest commitments v2 nuget packages --- .../SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj | 4 ++-- .../SFA.DAS.EmployerCommitmentsV2.Web.csproj | 8 ++++---- .../SFA.DAS.EmployerCommitmentsV2.csproj | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj index 6c89863ff..f1d936543 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj b/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj index e3d2492f1..e71630988 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/SFA.DAS.EmployerCommitmentsV2.Web.csproj @@ -25,10 +25,10 @@ - - - - + + + + diff --git a/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj b/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj index 043d27618..3463b744d 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj +++ b/src/SFA.DAS.EmployerCommitmentsV2/SFA.DAS.EmployerCommitmentsV2.csproj @@ -11,9 +11,9 @@ - - - + + +