Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

ER-1377_show link to restore access for blocked provider. #810

Merged
merged 10 commits into from
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/QA/QA.Web/Configuration/Routing/RouteNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public static class RouteNames
public const string BlockProvider_Consent_Post = "BlockProvider_Consent_Post";
public const string BlockProvider_Acknowledgement_Get = "BlockProvider_Acknowledgement_Get";
public const string BlockProvider_AlreadyBlocked_Get = "BlockProvider_AlreadyBlocked_Get";
public const string UnBlockProvider_Confirm_Get = "UnBlockProvider_Confirm_Get";
public const string UnBlockProvider_Confirm_Post = "UnBlockProvider_Confirm_Post";
public const string UnBlockProvider_Acknowledgement_Get = "UnBlockProvider_Acknowledgement_Get";
public const string WithdrawVacancy_FindVacancy_Get = "WithdrawVacancy_FindVacancy_Get";
public const string WithdrawVacancy_FindVacancy_Post = "WithdrawVacancy_FindVacancy_Post";
public const string WithdrawVacancy_AlreadyClosed_Get = "WithdrawVacancy_AlreadyClosed_Get";
Expand Down
1 change: 1 addition & 0 deletions src/QA/QA.Web/Configuration/TempDataKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class TempDataKeys
{
public const string DashboardMessage = "Dashboard_Message";
public const string BlockProviderUkprnKey = "BlockProviderUkprnKey";
public const string UnBlockedProviderUkprnKey = "UnBlockedProviderUkprnKey";
public const string WithdrawVacancyReference = "WithdrawVacancyReference";
}
}
5 changes: 2 additions & 3 deletions src/QA/QA.Web/Controllers/BlockedOrganisationsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ namespace Esfa.Recruit.QA.Web.Controllers
public class BlockedOrganisationsController : Controller
{
private readonly BlockedOrganisationsOrchestrator _orchestrator;
private readonly UserAuthorizationService _userAuthorizationService;
public BlockedOrganisationsController(UserAuthorizationService userAuthorizationService, BlockedOrganisationsOrchestrator orchestrator)

public BlockedOrganisationsController(BlockedOrganisationsOrchestrator orchestrator)
{
_orchestrator = orchestrator;
_userAuthorizationService = userAuthorizationService;
}

[HttpGet("", Name = RouteNames.BlockedOrganisations_Get)]
Expand Down
59 changes: 59 additions & 0 deletions src/QA/QA.Web/Controllers/UnBlockOrganisationController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Microsoft.AspNetCore.Mvc;
using Esfa.Recruit.Qa.Web.Configuration.Routing;
using System.Threading.Tasks;
using Esfa.Recruit.QA.Web.Orchestrators;
using Esfa.Recruit.Qa.Web.Security;
using Microsoft.AspNetCore.Authorization;
using Esfa.Recruit.QA.Web.ViewModels.ManageProvider;
using Esfa.Recruit.Qa.Web.Configuration;
using Esfa.Recruit.Qa.Web.Extensions;

namespace Esfa.Recruit.QA.Web.Controllers
{
[Authorize(Policy = AuthorizationPolicyNames.TeamLeadUserPolicyName)]
[Route(RoutePaths.BlockedOrganisations)]
public class UnblockOrganisationController : Controller
{
private readonly UnblockOrganisationOrchestrator _orchestrator;

public UnblockOrganisationController(UnblockOrganisationOrchestrator orchestrator)
{
_orchestrator = orchestrator;
}

[HttpGet("unblock", Name = RouteNames.UnBlockProvider_Confirm_Get)]
public async Task<IActionResult> ConfirmTrainingProviderUnblocking(string organisationId)
{
if (long.TryParse(organisationId, out var ukprn) == false) return BadRequest();
var vm = await _orchestrator.GetConfirmTrainingProviderUnblockingViewModel(ukprn);
return View(vm);
}

[HttpPost("unblock", Name = RouteNames.UnBlockProvider_Confirm_Post)]
public async Task<IActionResult> ConfirmTrainingProviderUnblocking(ConfirmTrainingProviderUnblockingEditModel model)
{
if (ModelState.IsValid == false)
{
return View(new ConfirmTrainingProviderUnblockingEditModel() { Ukprn = model.Ukprn, ProviderName = model.ProviderName });
}
var isBlocked = await _orchestrator.IsProviderAlreadyBlocked(model.Ukprn);

if (isBlocked && model.CanRestoreAccess)
{
TempData[TempDataKeys.UnBlockedProviderUkprnKey] = model.Ukprn;
await _orchestrator.UnblockProviderAsync(model.Ukprn, User.GetVacancyUser());
return RedirectToRoute(RouteNames.UnBlockProvider_Acknowledgement_Get);
}
return RedirectToRoute(RouteNames.BlockedOrganisations_Get);
}

[HttpGet("unblocking-acknowledgement", Name = RouteNames.UnBlockProvider_Acknowledgement_Get)]
public async Task<IActionResult> ProviderUnBlockedAcknowledgement()
{
var data = TempData[TempDataKeys.UnBlockedProviderUkprnKey]?.ToString();
if (long.TryParse(data, out var ukprn) == false) return BadRequest();
var vm = await _orchestrator.GetAcknowledgementViewModelAsync(ukprn);
return View(vm);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public async Task<ProviderBlockedAcknowledgementViewModel> GetAcknowledgementVie
public async Task<bool> IsProviderAlreadyBlocked(long ukprn)
{
var blockedOrganisation = await _blockedOrganisationQuery.GetByOrganisationIdAsync(ukprn.ToString());
return blockedOrganisation != null;
return blockedOrganisation?.BlockedStatus == BlockedStatus.Blocked;
}

public async Task<ProviderAlreadyBlockedViewModel> GetProviderAlreadyBlockedViewModelAsync(long ukprn)
Expand Down
66 changes: 66 additions & 0 deletions src/QA/QA.Web/Orchestrators/UnBlockOrganisationOrchestrator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Threading.Tasks;
using Esfa.Recruit.QA.Web.ViewModels.ManageProvider;
using Esfa.Recruit.Vacancies.Client.Application.Commands;
using Esfa.Recruit.Vacancies.Client.Application.Providers;
using Esfa.Recruit.Vacancies.Client.Domain.Entities;
using Esfa.Recruit.Vacancies.Client.Domain.Messaging;
using Esfa.Recruit.Vacancies.Client.Domain.Repositories;
using Esfa.Recruit.Vacancies.Client.Infrastructure.Services.TrainingProvider;

namespace Esfa.Recruit.QA.Web.Orchestrators
{
public class UnblockOrganisationOrchestrator
{
private readonly IBlockedOrganisationQuery _blockedOrganisationQuery;
private readonly IMessaging _messaging;
private readonly ITimeProvider _timeProvider;
private readonly ITrainingProviderService _trainingProviderService;
public UnblockOrganisationOrchestrator(
IBlockedOrganisationQuery blockedOrganisationQuery,
IMessaging messaging, ITimeProvider timeProvider, ITrainingProviderService trainingProviderService)
{
_blockedOrganisationQuery = blockedOrganisationQuery;
_messaging = messaging;
_timeProvider = timeProvider;
_trainingProviderService = trainingProviderService;
}

public async Task<ProviderUnblockedAcknowledgementViewModel> GetAcknowledgementViewModelAsync(long ukprn)
{
var providerDetail = await _trainingProviderService.GetProviderAsync(ukprn);

return new ProviderUnblockedAcknowledgementViewModel
{
Name = providerDetail.Name,
Ukprn = ukprn
};
}

public async Task<bool> IsProviderAlreadyBlocked(long ukprn)
{
var blockedOrganisation = await _blockedOrganisationQuery.GetByOrganisationIdAsync(ukprn.ToString());
return blockedOrganisation?.BlockedStatus == BlockedStatus.Blocked;
}

public Task UnblockProviderAsync(long ukprn, VacancyUser user)
{
var command = new UnblockProviderCommand(ukprn, user, _timeProvider.Now);
return _messaging.SendCommandAsync(command);
}

public async Task<ConfirmTrainingProviderUnblockingEditModel> GetConfirmTrainingProviderUnblockingViewModel(long ukprn)
{
var provider = await _trainingProviderService.GetProviderAsync(ukprn);
return ConvertToConfirmViewModel(provider);
}

private ConfirmTrainingProviderUnblockingEditModel ConvertToConfirmViewModel(TrainingProvider provider)
{
return new ConfirmTrainingProviderUnblockingEditModel
{
Ukprn = provider.Ukprn.GetValueOrDefault(),
ProviderName = provider.Name
};
}
}
}
2 changes: 1 addition & 1 deletion src/QA/QA.Web/QA.Web.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<UserSecretsId>recruit-qa-web</UserSecretsId>
Expand Down
2 changes: 1 addition & 1 deletion src/QA/QA.Web/Startup.ConfigureServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddScoped<ReportDashboardOrchestrator>();
services.AddScoped<ApplicationsReportOrchestrator>();
services.AddScoped<BlockedOrganisationsOrchestrator>();

services.AddScoped<UnblockOrganisationOrchestrator>();
services.AddScoped<ReportConfirmationOrchestrator>();
services.AddScoped<WithdrawVacancyOrchestrator>();
services.AddTransient<UserAuthorizationService>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Esfa.Recruit.QA.Web.ViewModels.ManageProvider
{
public class ConfirmTrainingProviderUnblockingEditModel
{
public long Ukprn { get; set; }
public string ProviderName { get; set; }
public bool? RestoreAccess { get; set; }
public bool CanRestoreAccess => RestoreAccess.HasValue && RestoreAccess.Value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Esfa.Recruit.QA.Web.ViewModels.ManageProvider
{
public class ProviderUnblockedAcknowledgementViewModel
{
public string Name { get; set; }
public long Ukprn { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Esfa.Recruit.QA.Web.ViewModels.ManageProvider;
using FluentValidation;

namespace Esfa.Recruit.Qa.Web.ViewModels.Validations
{
public class TrainingProviderUnblockingViewModelValidator : AbstractValidator<ConfirmTrainingProviderUnblockingEditModel>
{
public const string SelectionRequired = "Please select an option to confirm";
public TrainingProviderUnblockingViewModelValidator()
{
RuleFor(x => x.RestoreAccess)
.NotNull()
.WithMessage(SelectionRequired);

}
}
}
6 changes: 6 additions & 0 deletions src/QA/QA.Web/Views/BlockedOrganisations/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<th class="govuk-table__header">Postcode</th>
<th class="govuk-table__header">Removed on</th>
<th class="govuk-table__header">Removed by</th>
<th class="govuk-table__header"></th>
</tr>
</thead>
<tbody class="govuk-table__body">
Expand All @@ -41,6 +42,11 @@
<td class="govuk-table__cell">@organisation.Postcode</td>
<td class="govuk-table__cell">@organisation.BlockedOn</td>
<td class="govuk-table__cell">@organisation.BlockedBy</td>
<td class="govuk-table__cell">
<a asp-route="@RouteNames.UnBlockProvider_Confirm_Get" class="govuk-link" asp-route-organisationId="@organisation.OrganisationId">
Restore access
</a>
</td>
</tr>
}
</tbody>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@model Esfa.Recruit.QA.Web.ViewModels.ManageProvider.ProviderUnblockedAcknowledgementViewModel
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<div class="govuk-panel govuk-panel--confirmation">
<h1 class="govuk-panel__title">
Restored access to recruitment service
</h1>
<div class="govuk-panel__body">
<p class="govuk-body">
<div>@Model.Name</div>
<strong class="govuk-!-font-weight-bold">UKPRN: @Model.Ukprn</strong>
</p>
</div>
</div>
<p class="govuk-body">
The employer will need to add permissions before the training provider can start to create and manage vacancies.
</p>
<a asp-route="@RouteNames.BlockedOrganisations_Get" class="govuk-button">Back to permissions dashboard</a>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@using Esfa.Recruit.QA.Web.ViewModels.ManageProvider
@model ConfirmTrainingProviderUnblockingEditModel
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">Restore access for @Model.ProviderName</h1>
</div>
</div>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<p class="govuk-body">
Restoring access to the recruitment service will allow the training provider to create or manage vacancies on behalf of employers.
</p>
<p class="govuk-body">
The employer will need to add permissions again.
</p>
<h2 class="govuk-heading-s">Are you sure you want to restore access for this training provider?</h2>
<form asp-route="@RouteNames.UnBlockProvider_Confirm_Post">
<input type="hidden" asp-for="Ukprn">
<input type="hidden" asp-for="ProviderName">
<div esfa-validation-marker-for="RestoreAccess" class="govuk-form-group">
<fieldset class="govuk-fieldset">
<span esfa-validation-message-for="RestoreAccess" class="govuk-error-message"></span>
<div class="govuk-radios">
<div class="govuk-radios__item">
<input asp-for="RestoreAccess" class="govuk-radios__input" id="restore-access-yes" type="radio" value="true">
<label for="restore-access-yes" class="govuk-label govuk-radios__label">Yes</label>
</div>
<div class="govuk-radios__item">
<input asp-for="RestoreAccess" class="govuk-radios__input" id="restore-access-no" type="radio" value="false">
<label for="restore-access-no" class="govuk-label govuk-radios__label">No</label>
</div>
</div>
</fieldset>
</div>
<div class="govuk-form-group">
<input type="submit" value="Confirm" class="govuk-button" />
<a asp-route="@RouteNames.BlockedOrganisations_Get" class="govuk-link das-button-link">Cancel</a>
</div>
</form>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Esfa.Recruit.Vacancies.Client.Application.Commands;
using Esfa.Recruit.Vacancies.Client.Domain.Entities;
using Esfa.Recruit.Vacancies.Client.Domain.Events;
using Esfa.Recruit.Vacancies.Client.Domain.Messaging;
using Esfa.Recruit.Vacancies.Client.Domain.Repositories;
using Esfa.Recruit.Vacancies.Client.Infrastructure.QueryStore;
using Esfa.Recruit.Vacancies.Client.Infrastructure.QueryStore.Projections.EditVacancyInfo;
using MediatR;
using Microsoft.Extensions.Logging;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Threading;
using System.Threading.Tasks;
using Esfa.Recruit.Vacancies.Client.Application.Commands;
using Esfa.Recruit.Vacancies.Client.Domain.Entities;
using Esfa.Recruit.Vacancies.Client.Domain.Events;
using Esfa.Recruit.Vacancies.Client.Domain.Messaging;
using Esfa.Recruit.Vacancies.Client.Domain.Repositories;
using MediatR;
using Microsoft.Extensions.Logging;

namespace Esfa.Recruit.Vacancies.Client.Application.CommandHandlers
{
public class UnblockProviderCommandHandler : IRequestHandler<UnblockProviderCommand>
{
private readonly ILogger<UnblockProviderCommandHandler> _logger;
private readonly IBlockedOrganisationQuery _blockedOrganisationQuery;
private readonly IBlockedOrganisationRepository _blockedOrganisationRepository;
private readonly IMessaging _messaging;
public UnblockProviderCommandHandler(
ILogger<UnblockProviderCommandHandler> logger,
IBlockedOrganisationQuery blockedOrganisationQuery,
IBlockedOrganisationRepository blockedOrganisationRepository,
IMessaging messaging)
{
_logger = logger;
_blockedOrganisationQuery = blockedOrganisationQuery;
_blockedOrganisationRepository = blockedOrganisationRepository;
_messaging = messaging;
}

public async Task Handle(UnblockProviderCommand message, CancellationToken cancellationToken)
{
var blockedOrg = await _blockedOrganisationQuery.GetByOrganisationIdAsync(message.Ukprn.ToString());
if (blockedOrg?.BlockedStatus == BlockedStatus.Blocked)
{
_logger.LogInformation($"Request to unblock provider with ukprn {message.Ukprn}.");
await _blockedOrganisationRepository.CreateAsync(ConvertToBlockedOrganisation(message));

await _messaging.PublishEvent(new ProviderBlockedEvent()
{
Ukprn = message.Ukprn,
BlockedDate = message.UnblockedDate,
QaVacancyUser = message.QaVacancyUser
});
}
}

private static BlockedOrganisation ConvertToBlockedOrganisation(UnblockProviderCommand message)
{
return new BlockedOrganisation()
{
BlockedStatus = BlockedStatus.Unblocked,
OrganisationType = OrganisationType.Provider,
OrganisationId = message.Ukprn.ToString(),
UpdatedByUser = message.QaVacancyUser,
UpdatedDate = message.UnblockedDate
};
}
}
}
Loading