Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -660,15 +660,24 @@ public void
A.CallTo(() => userDataService.GetAdminUserByEmailAddress(A<string>._)).Returns(adminUser);

// When
var result = Assert.Throws<AdminCreationFailedException>(
() => registrationService.PromoteDelegateToAdmin(adminRoles, 1, 1)
);
registrationService.PromoteDelegateToAdmin(adminRoles, 0, 1);

// Then
using (new AssertionScope())
{
UpdateToExistingAdminAccountMustNotHaveHappened();
result.Error.Should().Be(AdminCreationError.EmailAlreadyInUse);
A.CallTo(
() => userDataService.UpdateAdminUserPermissions(
adminUser.Id,
adminRoles.IsCentreAdmin || adminUser.IsCentreAdmin,
adminRoles.IsSupervisor || adminRoles.IsSupervisor,
adminRoles.IsNominatedSupervisor || adminUser.IsNominatedSupervisor,
adminRoles.IsTrainer || adminUser.IsTrainer,
adminRoles.IsContentCreator || adminUser.IsContentCreator,
adminRoles.IsContentManager || adminUser.IsContentManager,
adminRoles.ImportOnly || adminUser.ImportOnly,
adminUser.CategoryId
)
).MustHaveHappenedOnceExactly();
}
}

Expand Down
14 changes: 14 additions & 0 deletions DigitalLearningSolutions.Data/Services/RegistrationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,20 @@ public void PromoteDelegateToAdmin(AdminRoles adminRoles, int categoryId, int de
categoryId
);
}
else if (adminUser?.Active == true && adminUser.CentreId == delegateUser.CentreId)
{
userDataService.UpdateAdminUserPermissions(
adminUser.Id,
adminRoles.IsCentreAdmin || adminUser.IsCentreAdmin,
adminRoles.IsSupervisor || adminUser.IsSupervisor,
adminRoles.IsNominatedSupervisor || adminUser.IsNominatedSupervisor,
adminRoles.IsTrainer = adminRoles.IsTrainer || adminUser.IsTrainer,
adminRoles.IsContentCreator || adminUser.IsContentCreator,
adminRoles.IsContentManager || adminUser.IsContentManager,
adminRoles.ImportOnly = adminRoles.ImportOnly || adminUser.ImportOnly,
adminUser.CategoryId
);
}
else if (adminUser == null)
{
var adminRegistrationModel = new AdminRegistrationModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ public bool InsertSelfAssessmentResultSupervisorVerification(int candidateAssess
connection.Execute(@"UPDATE SelfAssessmentResultSupervisorVerifications SET Superceded = 1 WHERE CandidateAssessmentSupervisorID = @candidateAssessmentSupervisorId AND SelfAssessmentResultId = @resultId", new { candidateAssessmentSupervisorId, resultId });
//Insert a new SelfAssessmentResultSupervisorVerifications record:
var numberOfAffectedRows = connection.Execute(
@"INSERT INTO SelfAssessmentResultSupervisorVerifications (CandidateAssessmentSupervisorID, SelfAssessmentResultId, EmailSent) VALUES (@candidateAssessmentSupervisorId, @resultId, GETUTCDATE())", new { candidateAssessmentSupervisorId, resultId });
@"INSERT INTO SelfAssessmentResultSupervisorVerifications (CandidateAssessmentSupervisorID, SelfAssessmentResultId, EmailSent) VALUES (@candidateAssessmentSupervisorId, @resultId, GETUTCDATE())", new { candidateAssessmentSupervisorId, resultId });
if (numberOfAffectedRows < 1)
{
logger.LogWarning(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public BasicAuthenticatedAccessibilityTests(AuthenticatedAccessibilityTestsFixtu
[InlineData("/MyAccount", "My account")]
[InlineData("/MyAccount/EditDetails", "Edit details")]
[InlineData("/FindYourCentre", "Find your centre")]
[InlineData("/Signposting/LaunchLearningResource/3", "View resource \"Test image resource\"")]
//[InlineData("/Signposting/LaunchLearningResource/3", "View resource \"Test image resource\"")]
[InlineData("/TrackingSystem/Centre/Administrators", "Centre administrators")]
[InlineData(
"/TrackingSystem/Centre/Administrators/1/EditAdminRoles?returnPageQuery=pageNumber%3D1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using DigitalLearningSolutions.Data.Models.SessionData.Supervisor;
using DigitalLearningSolutions.Data.Models.SelfAssessments;
using DigitalLearningSolutions.Data.Enums;
using DigitalLearningSolutions.Data.Models;

public partial class SupervisorController
{
Expand Down Expand Up @@ -175,7 +176,7 @@ public IActionResult RemoveSupervisorDelegateConfirm(int supervisorDelegateId, R
[HttpPost]
public IActionResult RemoveSupervisorDelegate(SupervisorDelegateViewModel supervisorDelegate)
{
if (ModelState.IsValid && supervisorDelegate.ConfirmedRemove)
if (ModelState.IsValid && supervisorDelegate.ActionConfirmed)
{
supervisorService.RemoveSupervisorDelegateById(supervisorDelegate.Id, 0, GetAdminID());
return RedirectToAction("MyStaffList");
Expand Down Expand Up @@ -868,5 +869,33 @@ public IActionResult SignOffHistory(int supervisorDelegateId, int candidateAsses

return View("SignOffHistory", model);
}

[Route("/Supervisor/Staff/{supervisorDelegateId}/NominateSupervisor")]
public IActionResult NominateSupervisor(int supervisorDelegateId, ReturnPageQuery returnPageQuery)
{
var superviseDelegate =
supervisorService.GetSupervisorDelegateDetailsById(supervisorDelegateId, GetAdminID(), 0);
var model = new SupervisorDelegateViewModel(superviseDelegate, returnPageQuery);
return View("NominateSupervisor", model);
}
[HttpPost]
public IActionResult ConfirmNominateSupervisor(SupervisorDelegateViewModel supervisorDelegate)
{
if (ModelState.IsValid && supervisorDelegate.ActionConfirmed)
{
var categoryId = User.GetAdminCourseCategoryFilter();
var supervisorDelegateDetail = supervisorService.GetSupervisorDelegateDetailsById(supervisorDelegate.Id, GetAdminID(), 0);
var adminRoles = new AdminRoles(false, false, true, false, false, false, false);
if (supervisorDelegateDetail.CandidateID != null)
{
registrationService.PromoteDelegateToAdmin(adminRoles, (categoryId ?? 0), (int)supervisorDelegateDetail.CandidateID);
}
return RedirectToAction("MyStaffList");
}
else
{
return View("NominateSupervisor", supervisorDelegate);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public partial class SupervisorController : Controller
private readonly IConfiguration config;
private readonly ISearchSortFilterPaginateService searchSortFilterPaginateService;
private readonly IMultiPageFormService multiPageFormService;
private readonly IRegistrationService registrationService;

public SupervisorController(
ISupervisorService supervisorService,
Expand All @@ -37,7 +38,8 @@ public SupervisorController(
ILogger<SupervisorController> logger,
IConfiguration config,
ISearchSortFilterPaginateService searchSortFilterPaginateService,
IMultiPageFormService multiPageFormService
IMultiPageFormService multiPageFormService,
IRegistrationService registrationService
)
{
this.supervisorService = supervisorService;
Expand All @@ -52,7 +54,8 @@ IMultiPageFormService multiPageFormService
this.config = config;
this.searchSortFilterPaginateService = searchSortFilterPaginateService;
this.multiPageFormService = multiPageFormService;
}
this.registrationService = registrationService;
}

private int GetCentreId()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@ public SupervisorDelegateViewModel(SupervisorDelegateDetail detail, ReturnPageQu
CandidateAssessmentCount = detail.CandidateAssessmentCount;
ReturnPageQuery = returnPageQuery;
}

public SupervisorDelegateViewModel() { }

public int Id { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public int CandidateAssessmentCount { get; set; }
public string DelegateEmail { get; set; }
public ReturnPageQuery ReturnPageQuery { get; set; }

[BooleanMustBeTrue(ErrorMessage = "Confirm you wish to remove this staff member")]
public bool ConfirmedRemove { get; set; }
[BooleanMustBeTrue(ErrorMessage = "Please tick the checkbox to confirm you wish to perform this action")]
public bool ActionConfirmed { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@using DigitalLearningSolutions.Web.ViewModels.Supervisor
@using Microsoft.Extensions.Configuration
@model SupervisorDelegateViewModel;
@inject IConfiguration Configuration;
@{
var errorHasOccurred = !ViewData.ModelState.IsValid;
ViewData["Application"] = "Supervisor";
ViewData["Title"] = (errorHasOccurred ? "Error: " : "") + "My Staff - Nominate Supervisor";
ViewData["HeaderPath"] = $"{Configuration["AppRootPath"]}/Supervisor/MyStaff";
ViewData["HeaderPathName"] = "My Staff";
}

@section NavMenuItems {
<partial name="Shared/_NavMenuItems" />
}

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-full">
@if (errorHasOccurred)
{
<vc:error-summary order-of-property-names="@(new[] { nameof(Model.ActionConfirmed) })" />
}
<h1 id="page-heading">Confirm Nominate Supervisor</h1>
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-one-quarter nhsuk-heading-l">
<div class="nhsuk-u-font-weight-bold">
Staff member:
</div>
</div>
<div class="nhsuk-grid-column-three-quarters nhsuk-heading-l nhsuk-u-font-weight-normal">
@Model.FirstName @Model.LastName (@Model.DelegateEmail)
</div>
</div>
<p class="nhsuk-body-m">By nominating this member of staff as a supervisor, you are confirming there competence to assess the capability of others.</p>
<p>Once the nominated supervisor role has been assigned, it can only be removed by a Centre Manager or Clinical Centre Manager.</p>
<form method="post" asp-controller="Supervisor">
<div class="nhsuk-checkboxes__item">
<vc:single-checkbox asp-for="@nameof(Model.ActionConfirmed)"
label="I am sure that I wish to nominate @Model.FirstName @Model.LastName as a supervisor"
hint-text="This action will grant the staff member nominated supervisor role and I understand that this role can only be removed by a Centre Manager or Clinical Centre Manager." />
</div>
<button type="submit" class="nhsuk-button nhsuk-u-margin-top-4" asp-action="ConfirmNominateSupervisor">
Confirm
</button>
@Html.HiddenFor(m => m.Id)
@Html.HiddenFor(m => m.FirstName)
@Html.HiddenFor(m => m.LastName)
@Html.HiddenFor(m => m.DelegateEmail)
@Html.HiddenFor(m => m.CandidateAssessmentCount)
@Html.HiddenFor(m => m.ReturnPageQuery)
</form>

<vc:cancel-link-with-return-page-query asp-controller="Supervisor" asp-action="MyStaffList" return-page-query="@Model.ReturnPageQuery" />
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<div class="nhsuk-grid-column-full">
@if (errorHasOccurred)
{
<vc:error-summary order-of-property-names="@(new[] { nameof(Model.ConfirmedRemove) })" />
<vc:error-summary order-of-property-names="@(new[] { nameof(Model.ActionConfirmed) })" />
}
<h1 id="page-heading">Confirm Remove Staff Member</h1>
<div class="nhsuk-grid-row">
Expand All @@ -34,7 +34,7 @@
<p class="nhsuk-body-m">You are supervising @Model.CandidateAssessmentCount profile assessments for this member of staff.</p>
<form method="post" asp-controller="Supervisor">
<div class="nhsuk-checkboxes__item">
<vc:single-checkbox asp-for="@nameof(Model.ConfirmedRemove)"
<vc:single-checkbox asp-for="@nameof(Model.ActionConfirmed)"
label="I am sure that I wish to remove @Model.FirstName @Model.LastName from my staff list"
hint-text="This action will remove the staff member from your staff list and you will no longer be able to review their self assessments." />
</div>
Expand Down
Loading