diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Extensions/ILinkGeneratorExtensionsTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Extensions/ILinkGeneratorExtensionsTests.cs index a55402857..32cdc87c7 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Extensions/ILinkGeneratorExtensionsTests.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Extensions/ILinkGeneratorExtensionsTests.cs @@ -53,7 +53,7 @@ public void DeleteApprentice_BuildsPathCorrectly(string accountHashedId, string public void EmployerHome_BuildsPathCorrectly(string accountHashedId) { var url = _fixture.Sut.EmployerHome(accountHashedId); - Assert.AreEqual($"{_fixture.UsersLink}accounts/{accountHashedId}/teams", url); + Assert.AreEqual($"{_fixture.AccountsLink}accounts/{accountHashedId}/teams", url); } [Test, AutoData] diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ChangeProviderInformViewModelMapperTests.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ChangeProviderInformViewModelMapperTests.cs new file mode 100644 index 000000000..71710252c --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web.UnitTests/Mappers/Apprentice/ChangeProviderInformViewModelMapperTests.cs @@ -0,0 +1,88 @@ +using AutoFixture; +using Moq; +using NUnit.Framework; +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Api.Types.Responses; +using SFA.DAS.CommitmentsV2.Types; +using SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.Encoding; +using SFA.DAS.Testing.AutoFixture; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.UnitTests.Mappers.Apprentice +{ + public class ChangeProviderInformViewModelMapperTests + { + private Mock _mockCommitmentsApiClient; + private Mock _mockEncodingService; + private GetApprenticeshipResponse _apprenticeshipResponse; + + private ChangeProviderInformViewModelMapper _mapper; + + private const long ApprenticeshipId = 10000000; + + [SetUp] + public void Arrange() + { + var autoFixture = new Fixture(); + + _apprenticeshipResponse = autoFixture.Build() + .With(a => a.Status, ApprenticeshipStatus.Stopped) + .Create(); + + + _mockCommitmentsApiClient = new Mock(); + _mockCommitmentsApiClient.Setup(a => a.GetApprenticeship(It.IsAny(), It.IsAny())) + .ReturnsAsync(_apprenticeshipResponse); + + _mockEncodingService = new Mock(); + _mockEncodingService.Setup(d => d.Decode(It.IsAny(), EncodingType.ApprenticeshipId)) + .Returns(ApprenticeshipId); + + + _mapper = new ChangeProviderInformViewModelMapper(_mockCommitmentsApiClient.Object, _mockEncodingService.Object); + } + + [Test, MoqAutoData] + public async Task ApprenticeshipHashedId_IsMapped(ChangeProviderInformRequest request) + { + var result = await _mapper.Map(request); + + Assert.AreEqual(request.ApprenticeshipHashedId, result.ApprenticeshipHashedId); + } + + [Test, MoqAutoData] + public async Task AccountHashedId_IsMapped(ChangeProviderInformRequest request) + { + var result = await _mapper.Map(request); + + Assert.AreEqual(request.AccountHashedId, result.AccountHashedId); + } + + [Test, MoqAutoData] + public async Task ApprenticeshipStatus_IsMapped(ChangeProviderInformRequest request) + { + var result = await _mapper.Map(request); + + Assert.AreEqual(ApprenticeshipStatus.Stopped, result.ApprenticeshipStatus); + } + + [Test, MoqAutoData] + public async Task WhenRequestingChangeProviderInformPage_ThenHashedApprenticeshipIdIsDecoded(ChangeProviderInformRequest request) + { + var result = await _mapper.Map(request); + + _mockEncodingService.Verify(a => a.Decode(request.ApprenticeshipHashedId, EncodingType.ApprenticeshipId), Times.Once); + } + + [Test, MoqAutoData] + public async Task WhenRequestingChangeProviderInformPage_ThenGetApprenticeshipIsCalled(ChangeProviderInformRequest request) + { + var result = await _mapper.Map(request); + + _mockCommitmentsApiClient.Verify(a => a.GetApprenticeship(ApprenticeshipId, It.IsAny()), Times.Once); + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs index b01fb11b3..c6db21843 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Controllers/ApprenticeController.cs @@ -37,7 +37,6 @@ public ApprenticeController(IModelMapper modelMapper, ICookieStorageService Index(IndexRequest request) { IndexRequest savedRequest = null; @@ -64,7 +63,6 @@ public async Task Index(IndexRequest request) } [Route("download", Name = RouteNames.ApprenticesDownload)] - [DasAuthorize(EmployerFeature.ManageApprenticesV2)] public async Task Download(DownloadRequest request) { var downloadViewModel = await _modelMapper.Map(request); @@ -73,7 +71,6 @@ public async Task Download(DownloadRequest request) } [Route("{apprenticeshipHashedId}/details/editenddate", Name = RouteNames.ApprenticeEditEndDate)] - [DasAuthorize(EmployerFeature.ManageApprenticesV2)] public async Task EditEndDate(EditEndDateRequest request) { var viewModel = await _modelMapper.Map(request); @@ -81,7 +78,6 @@ public async Task EditEndDate(EditEndDateRequest request) } [Route("{apprenticeshipHashedId}/details/editenddate", Name = RouteNames.ApprenticeEditEndDate)] - [DasAuthorize(EmployerFeature.ManageApprenticesV2)] [HttpPost] public async Task EditEndDate(EditEndDateViewModel viewModel) { @@ -91,6 +87,31 @@ public async Task EditEndDate(EditEndDateViewModel viewModel) return Redirect(url); } + [Route("{apprenticeshipHashedId}/details/changing-training-provider", Name = RouteNames.ChangeProviderInform)] + [DasAuthorize(EmployerFeature.ChangeOfProvider)] + public async Task ChangeProviderInform(ChangeProviderInformRequest request) + { + var viewModel = await _modelMapper.Map(request); + + return View(viewModel); + } + + // Placeholder for CON-2516 - url not specified yet + [Route("{apprenticeshipHashedId}/details/stopped-error", Name = RouteNames.ApprenticeNotStoppedError)] + [DasAuthorize(EmployerFeature.ChangeOfProvider)] + public IActionResult ApprenticeNotStoppedError() + { + return View(); + } + + // Placeholder for CON-2505 + [Route("{apprenticeshipHashedId}/details/enter-new-training-provider-name-or-reference-number", Name = RouteNames.EnterNewTrainingProvider)] + [DasAuthorize(EmployerFeature.ChangeOfProvider)] + public IActionResult EnterNewTrainingProvider() + { + return View(); + } + [Route("{apprenticeshipHashedId}/details/changestatus")] [DasAuthorize(EmployerFeature.ManageApprenticesV2)] [HttpGet] diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs index daa2860c4..f6a7a109b 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Extensions/ILinkGeneratorExtensions.cs @@ -4,7 +4,7 @@ namespace SFA.DAS.EmployerCommitmentsV2.Web.Extensions { public static class ILinkGeneratorExtensions { - public static string YourOrganisationsAndAgreements(this ILinkGenerator linkGenerator, string accountHashedId) + public static string YourOrganisationsAndAgreements(this ILinkGenerator linkGenerator, string accountHashedId) { return linkGenerator.AccountsLink($"accounts/{accountHashedId}/agreements"); } @@ -48,7 +48,7 @@ public static string DeleteApprentice(this ILinkGenerator linkGenerator, public static string EmployerHome(this ILinkGenerator linkGenerator, string accountHashedId) { - return linkGenerator.UsersLink($"accounts/{accountHashedId}/teams"); + return linkGenerator.AccountsLink($"accounts/{accountHashedId}/teams"); } public static string EmployerAccountsHome(this ILinkGenerator linkGenerator) diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ChangeProviderInformViewModelMapper.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ChangeProviderInformViewModelMapper.cs new file mode 100644 index 000000000..fa1f4fdd5 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Mappers/Apprentice/ChangeProviderInformViewModelMapper.cs @@ -0,0 +1,38 @@ +using SFA.DAS.CommitmentsV2.Api.Client; +using SFA.DAS.CommitmentsV2.Shared.Interfaces; +using SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice; +using SFA.DAS.Encoding; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Mappers.Apprentice +{ + public class ChangeProviderInformViewModelMapper : IMapper + { + private readonly ICommitmentsApiClient _commitmentsApiClient; + private readonly IEncodingService _encodingService; + + public ChangeProviderInformViewModelMapper(ICommitmentsApiClient commitmentsApiClient, IEncodingService encodingService) + { + _commitmentsApiClient = commitmentsApiClient; + _encodingService = encodingService; + } + + public async Task Map(ChangeProviderInformRequest source) + { + var apprenticeshipId = _encodingService.Decode(source.ApprenticeshipHashedId, EncodingType.ApprenticeshipId); + + var apprenticeship = await _commitmentsApiClient.GetApprenticeship(apprenticeshipId, CancellationToken.None); + + var result = new ChangeProviderInformViewModel + { + AccountHashedId = source.AccountHashedId, + ApprenticeshipHashedId = source.ApprenticeshipHashedId, + ApprenticeshipStatus = apprenticeship.Status + }; + + return result; + } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeProviderInformRequest.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeProviderInformRequest.cs new file mode 100644 index 000000000..57be1f581 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeProviderInformRequest.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Mvc; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class ChangeProviderInformRequest + { + [FromRoute] + public string AccountHashedId { get; set; } + + [FromRoute] + public string ApprenticeshipHashedId { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeProviderInformViewModel.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeProviderInformViewModel.cs new file mode 100644 index 000000000..00be709d5 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Models/Apprentice/ChangeProviderInformViewModel.cs @@ -0,0 +1,12 @@ + +using SFA.DAS.CommitmentsV2.Types; + +namespace SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice +{ + public class ChangeProviderInformViewModel + { + public string AccountHashedId { get; set; } + public string ApprenticeshipHashedId { get; set; } + public ApprenticeshipStatus ApprenticeshipStatus { get; set; } + } +} diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteNames.cs b/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteNames.cs index d37bcf2f4..f43233bb9 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteNames.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/RouteValues/RouteNames.cs @@ -7,5 +7,9 @@ public static class RouteNames public const string ApprenticesDownload = "apprentices-download"; public const string ApprenticeDetail = "apprentice-details"; public const string ApprenticeEditEndDate = "apprentice-edit-enddate"; + + public const string ChangeProviderInform = "changing-training-provider-inform"; + public const string ApprenticeNotStoppedError = "aprentice-not-stopped-error"; + public const string EnterNewTrainingProvider = "enter-new-training-provider-name-or-reference-number"; } } diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ApprenticeNotStoppedError.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ApprenticeNotStoppedError.cshtml new file mode 100644 index 000000000..c240cf590 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ApprenticeNotStoppedError.cshtml @@ -0,0 +1,6 @@ + +@* + Placeholder for CON-2516 +*@ + +

You need to wait until {apprentice} has stopped training

\ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ChangeProviderInform.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ChangeProviderInform.cshtml new file mode 100644 index 000000000..d877f49bc --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/ChangeProviderInform.cshtml @@ -0,0 +1,64 @@ +@inject ILinkGenerator LinkGenerator; +@using SFA.DAS.EmployerCommitmentsV2.Web.Extensions +@using SFA.DAS.CommitmentsV2.Types +@using SFA.DAS.EmployerCommitmentsV2.Web.RouteValues +@model SFA.DAS.EmployerCommitmentsV2.Web.Models.Apprentice.ChangeProviderInformViewModel; + +@{ + ViewData["Title"] = "Changing training provider - Apprenticeship service - GOV.UK"; +} + + + +@section Back +{ + +} \ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/EnterNewTrainingProvider.cshtml b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/EnterNewTrainingProvider.cshtml new file mode 100644 index 000000000..ab4271e86 --- /dev/null +++ b/src/SFA.DAS.EmployerCommitmentsV2.Web/Views/Apprentice/EnterNewTrainingProvider.cshtml @@ -0,0 +1,6 @@ + +@* + Placeholder for CON-2505 +*@ + +

Enter a new training provider

\ No newline at end of file diff --git a/src/SFA.DAS.EmployerCommitmentsV2/Features/EmployerFeature.cs b/src/SFA.DAS.EmployerCommitmentsV2/Features/EmployerFeature.cs index 5d9aadb80..c9df5fafc 100644 --- a/src/SFA.DAS.EmployerCommitmentsV2/Features/EmployerFeature.cs +++ b/src/SFA.DAS.EmployerCommitmentsV2/Features/EmployerFeature.cs @@ -3,7 +3,9 @@ namespace SFA.DAS.EmployerCommitmentsV2.Features public static class EmployerFeature { private const string Prefix = "EmployerFeature."; + public const string EnhancedApproval = Prefix + "EnhancedApproval"; public const string ManageApprenticesV2 = Prefix + "ManageApprenticesV2"; + public const string ChangeOfProvider = Prefix + "ChangeOfProvider"; } } \ No newline at end of file