diff --git a/DigitalLearningSolutions.Data.Tests/DataServices/UserDataServiceTests/AdminUserDataServiceTests.cs b/DigitalLearningSolutions.Data.Tests/DataServices/UserDataServiceTests/AdminUserDataServiceTests.cs index 7db6b59399..cc2897c58b 100644 --- a/DigitalLearningSolutions.Data.Tests/DataServices/UserDataServiceTests/AdminUserDataServiceTests.cs +++ b/DigitalLearningSolutions.Data.Tests/DataServices/UserDataServiceTests/AdminUserDataServiceTests.cs @@ -163,7 +163,7 @@ public void UpdateAdminUserPermissions_updates_user() try { // When - userDataService.UpdateAdminUserPermissions(7, true, true, true, true, true, true, true, 1); + userDataService.UpdateAdminUserPermissions(7, true, true, true, true, true, true, true, 1, false); var updatedUser = userDataService.GetAdminUserById(7)!; // Then diff --git a/DigitalLearningSolutions.Data.Tests/Services/RegistrationServiceTests.cs b/DigitalLearningSolutions.Data.Tests/Services/RegistrationServiceTests.cs index 94c26c3914..3f354282f0 100644 --- a/DigitalLearningSolutions.Data.Tests/Services/RegistrationServiceTests.cs +++ b/DigitalLearningSolutions.Data.Tests/Services/RegistrationServiceTests.cs @@ -619,7 +619,7 @@ public void PromoteDelegateToAdmin_throws_AdminCreationFailedException_if_delega { // Given var delegateUser = UserTestHelper.GetDefaultDelegateUser(firstName: null); - var adminRoles = new AdminRoles(true, true, true, true, true, true, true); + var adminRoles = new AdminRoles(true, true, true, true, true, true, true, false); A.CallTo(() => userDataService.GetDelegateUserById(A._)).Returns(delegateUser); // When @@ -636,7 +636,7 @@ public void PromoteDelegateToAdmin_throws_AdminCreationFailedException_if_delega { // Given var delegateUser = UserTestHelper.GetDefaultDelegateUser(emailAddress: null); - var adminRoles = new AdminRoles(true, true, true, true, true, true, true); + var adminRoles = new AdminRoles(true, true, true, true, true, true, true, false); A.CallTo(() => userDataService.GetDelegateUserById(A._)).Returns(delegateUser); // When @@ -655,7 +655,7 @@ public void // Given var delegateUser = UserTestHelper.GetDefaultDelegateUser(); var adminUser = UserTestHelper.GetDefaultAdminUser(); - var adminRoles = new AdminRoles(true, true, true, true, true, true, true); + var adminRoles = new AdminRoles(true, true, true, true, true, true, true, false); A.CallTo(() => userDataService.GetDelegateUserById(A._)).Returns(delegateUser); A.CallTo(() => userDataService.GetAdminUserByEmailAddress(A._)).Returns(adminUser); @@ -675,7 +675,8 @@ public void adminRoles.IsContentCreator || adminUser.IsContentCreator, adminRoles.IsContentManager || adminUser.IsContentManager, adminRoles.ImportOnly || adminUser.ImportOnly, - adminUser.CategoryId + adminUser.CategoryId, + adminRoles.IsCentreManager || adminUser.IsCentreManager ) ).MustHaveHappenedOnceExactly(); } @@ -688,7 +689,7 @@ public void // Given var delegateUser = UserTestHelper.GetDefaultDelegateUser(); var adminUser = UserTestHelper.GetDefaultAdminUser(centreId: 3, active: false); - var adminRoles = new AdminRoles(true, true, true, true, true, true, true); + var adminRoles = new AdminRoles(true, true, true, true, true, true, true, false); A.CallTo(() => userDataService.GetDelegateUserById(A._)).Returns(delegateUser); A.CallTo(() => userDataService.GetAdminUserByEmailAddress(A._)).Returns(adminUser); @@ -712,7 +713,7 @@ public void PromoteDelegateToAdmin_updates_existing_admin_if_inactive_admin_at_s const int categoryId = 1; var delegateUser = UserTestHelper.GetDefaultDelegateUser(); var adminUser = UserTestHelper.GetDefaultAdminUser(active: false); - var adminRoles = new AdminRoles(true, true, true, true, true, true, true); + var adminRoles = new AdminRoles(true, true, true, true, true, true, true, true); A.CallTo(() => userDataService.GetDelegateUserById(A._)).Returns(delegateUser); A.CallTo(() => userDataService.GetAdminUserByEmailAddress(A._)).Returns(adminUser); @@ -744,7 +745,8 @@ public void PromoteDelegateToAdmin_updates_existing_admin_if_inactive_admin_at_s adminRoles.IsContentCreator, adminRoles.IsContentManager, adminRoles.ImportOnly, - categoryId + categoryId, + adminRoles.IsCentreManager ) ).MustHaveHappenedOnceExactly(); } @@ -755,7 +757,7 @@ public void PromoteDelegateToAdmin_calls_data_service_with_expected_value() { // Given var delegateUser = UserTestHelper.GetDefaultDelegateUser(); - var adminRoles = new AdminRoles(true, true, true, true, true, true, true); + var adminRoles = new AdminRoles(true, true, true, true, true, true, true, true); A.CallTo(() => userDataService.GetDelegateUserById(A._)).Returns(delegateUser); A.CallTo(() => userDataService.GetAdminUserByEmailAddress(A._)).Returns(null); @@ -837,7 +839,8 @@ private void UpdateToExistingAdminAccountMustNotHaveHappened() A._, A._, A._, - A._ + A._, + A._ ) ).MustNotHaveHappened(); } diff --git a/DigitalLearningSolutions.Data.Tests/Services/UserServiceTests.cs b/DigitalLearningSolutions.Data.Tests/Services/UserServiceTests.cs index 0031064066..babb9b06c2 100644 --- a/DigitalLearningSolutions.Data.Tests/Services/UserServiceTests.cs +++ b/DigitalLearningSolutions.Data.Tests/Services/UserServiceTests.cs @@ -790,7 +790,7 @@ public void UpdateAdminUserPermissions_edits_roles_when_spaces_available() ); var numberOfAdmins = CentreContractAdminUsageTestHelper.GetDefaultNumberOfAdministrators(); GivenAdminDataReturned(numberOfAdmins, currentAdminUser); - var adminRoles = new AdminRoles(true, true, true, true, true, true, true); + var adminRoles = new AdminRoles(true, true, true, true, true, true, true, true); // When userService.UpdateAdminUserPermissions(currentAdminUser.Id, adminRoles, 0); @@ -816,7 +816,7 @@ bool importOnly var numberOfAdmins = GetFullCentreContractAdminUsage(); GivenAdminDataReturned(numberOfAdmins, currentAdminUser); - var adminRoles = new AdminRoles(true, true, true, true, true, true, importOnly); + var adminRoles = new AdminRoles(true, true, true, true, true, true, importOnly, true); // When userService.UpdateAdminUserPermissions(currentAdminUser.Id, adminRoles, 0); @@ -845,7 +845,7 @@ bool newImportOnly ); var numberOfAdmins = GetFullCentreContractAdminUsage(); GivenAdminDataReturned(numberOfAdmins, currentAdminUser); - var adminRoles = new AdminRoles(true, true, newIsContentCreator, true, newIsTrainer, true, newImportOnly); + var adminRoles = new AdminRoles(true, true, newIsContentCreator, true, newIsTrainer, true, newImportOnly, true); // Then Assert.Throws( @@ -1318,7 +1318,8 @@ int categoryId adminRoles.IsContentCreator, adminRoles.IsContentManager, adminRoles.ImportOnly, - categoryId + categoryId, + adminRoles.IsCentreManager ) ).MustHaveHappened(); } @@ -1335,7 +1336,8 @@ private void AssertAdminPermissionUpdateMustNotHaveHappened() A._, A._, A._, - A._ + A._, + A._ ) ).MustNotHaveHappened(); } diff --git a/DigitalLearningSolutions.Data.Tests/TestHelpers/CentreContractAdminUsageTestHelper.cs b/DigitalLearningSolutions.Data.Tests/TestHelpers/CentreContractAdminUsageTestHelper.cs index a1e5d8a765..6539fbae64 100644 --- a/DigitalLearningSolutions.Data.Tests/TestHelpers/CentreContractAdminUsageTestHelper.cs +++ b/DigitalLearningSolutions.Data.Tests/TestHelpers/CentreContractAdminUsageTestHelper.cs @@ -6,6 +6,7 @@ public static class CentreContractAdminUsageTestHelper { public static CentreContractAdminUsage GetDefaultNumberOfAdministrators( int admins = 1, + int centreManager=1, int supervisors = 2, int trainers = 3, int ccLicences = 4, @@ -23,6 +24,7 @@ public static CentreContractAdminUsage GetDefaultNumberOfAdministrators( SupervisorCount = supervisors, TrainerCount = trainers, CcLicenceCount = ccLicences, + CentreManagerCheckCount= centreManager, CmsAdministratorCount = cmsAdministrators, CmsManagerCount = cmsManagers, TrainerSpots = trainerSpots, diff --git a/DigitalLearningSolutions.Data/DataServices/UserDataService/AdminUserDataService.cs b/DigitalLearningSolutions.Data/DataServices/UserDataService/AdminUserDataService.cs index eb52db9dad..652ea9c333 100644 --- a/DigitalLearningSolutions.Data/DataServices/UserDataService/AdminUserDataService.cs +++ b/DigitalLearningSolutions.Data/DataServices/UserDataService/AdminUserDataService.cs @@ -118,7 +118,8 @@ public void UpdateAdminUserPermissions( bool isContentCreator, bool isContentManager, bool importOnly, - int categoryId + int categoryId, + bool isCentreManager ) { connection.Execute( @@ -131,7 +132,8 @@ int categoryId ContentCreator = @isContentCreator, ContentManager = @isContentManager, ImportOnly = @importOnly, - CategoryID = @categoryId + CategoryID = @categoryId, + IsCentreManager = @isCentreManager WHERE AdminID = @adminId", new { @@ -144,6 +146,7 @@ int categoryId importOnly, categoryId, adminId, + isCentreManager } ); } diff --git a/DigitalLearningSolutions.Data/DataServices/UserDataService/UserDataService.cs b/DigitalLearningSolutions.Data/DataServices/UserDataService/UserDataService.cs index 943d55c5ab..0cee9c8dfb 100644 --- a/DigitalLearningSolutions.Data/DataServices/UserDataService/UserDataService.cs +++ b/DigitalLearningSolutions.Data/DataServices/UserDataService/UserDataService.cs @@ -35,7 +35,8 @@ void UpdateAdminUserPermissions( bool isContentCreator, bool isContentManager, bool importOnly, - int categoryId + int categoryId, + bool isCentreManager ); void UpdateAdminUserFailedLoginCount(int adminId, int updatedCount); diff --git a/DigitalLearningSolutions.Data/Models/AdminRoles.cs b/DigitalLearningSolutions.Data/Models/AdminRoles.cs index d0a69d71db..e06649250f 100644 --- a/DigitalLearningSolutions.Data/Models/AdminRoles.cs +++ b/DigitalLearningSolutions.Data/Models/AdminRoles.cs @@ -9,7 +9,8 @@ public AdminRoles( bool isContentCreator, bool isTrainer, bool isContentManager, - bool importOnly + bool importOnly, + bool isCentreManager ) { IsCentreAdmin = isCentreAdmin; @@ -19,6 +20,7 @@ bool importOnly IsTrainer = isTrainer; IsContentManager = isContentManager; ImportOnly = importOnly; + IsCentreManager = isCentreManager; } public bool IsCentreAdmin { get; set; } @@ -28,6 +30,7 @@ bool importOnly public bool IsContentCreator { get; set; } public bool IsContentManager { get; set; } public bool ImportOnly { get; set; } + public bool IsCentreManager { get; set; } public bool IsCmsAdministrator => IsContentManager && ImportOnly; public bool IsCmsManager => IsContentManager && !ImportOnly; diff --git a/DigitalLearningSolutions.Data/Models/CentreContractAdminUsage.cs b/DigitalLearningSolutions.Data/Models/CentreContractAdminUsage.cs index 68d34807d6..c863b264c2 100644 --- a/DigitalLearningSolutions.Data/Models/CentreContractAdminUsage.cs +++ b/DigitalLearningSolutions.Data/Models/CentreContractAdminUsage.cs @@ -14,6 +14,7 @@ public CentreContractAdminUsage(Centre centreDetails, List adminUsers AdminCount = adminUsers.Count(a => a.IsCentreAdmin); SupervisorCount = adminUsers.Count(a => a.IsSupervisor); NominatedSupervisorCount = adminUsers.Count(a => a.IsNominatedSupervisor); + CentreManagerCheckCount = adminUsers.Count(a => a.IsCentreManager); TrainerCount = adminUsers.Count(a => a.IsTrainer); CmsAdministratorCount = adminUsers.Count(a => a.IsCmsAdministrator); CmsManagerCount = adminUsers.Count(a => a.IsCmsManager); @@ -27,6 +28,7 @@ public CentreContractAdminUsage(Centre centreDetails, List adminUsers public int AdminCount { get; set; } public int SupervisorCount { get; set; } public int NominatedSupervisorCount { get; set; } + public int CentreManagerCheckCount { get; set; } public int TrainerCount { get; set; } public int CmsAdministratorCount { get; set; } public int CmsManagerCount { get; set; } diff --git a/DigitalLearningSolutions.Data/Services/RegistrationService.cs b/DigitalLearningSolutions.Data/Services/RegistrationService.cs index 18f4e7ede1..35da5d4ffb 100644 --- a/DigitalLearningSolutions.Data/Services/RegistrationService.cs +++ b/DigitalLearningSolutions.Data/Services/RegistrationService.cs @@ -180,7 +180,8 @@ public void PromoteDelegateToAdmin(AdminRoles adminRoles, int categoryId, int de adminRoles.IsContentCreator, adminRoles.IsContentManager, adminRoles.ImportOnly, - categoryId + categoryId, + adminRoles.IsCentreManager ); } else if (adminUser?.Active == true && adminUser.CentreId == delegateUser.CentreId) @@ -194,7 +195,8 @@ public void PromoteDelegateToAdmin(AdminRoles adminRoles, int categoryId, int de adminRoles.IsContentCreator || adminUser.IsContentCreator, adminRoles.IsContentManager || adminUser.IsContentManager, adminRoles.ImportOnly = adminRoles.ImportOnly || adminUser.ImportOnly, - adminUser.CategoryId + adminUser.CategoryId, + adminRoles.IsCentreManager || adminUser.IsCentreManager ); } else if (adminUser == null) diff --git a/DigitalLearningSolutions.Data/Services/UserService.cs b/DigitalLearningSolutions.Data/Services/UserService.cs index e5bec8057b..1c21bd7a11 100644 --- a/DigitalLearningSolutions.Data/Services/UserService.cs +++ b/DigitalLearningSolutions.Data/Services/UserService.cs @@ -349,7 +349,8 @@ int categoryId adminRoles.IsContentCreator, adminRoles.IsContentManager, adminRoles.ImportOnly, - categoryId + categoryId, + adminRoles.IsCentreManager ); } diff --git a/DigitalLearningSolutions.Web.Tests/ViewModels/Common/NumberOfAdministratorViewModelTests.cs b/DigitalLearningSolutions.Web.Tests/ViewModels/Common/NumberOfAdministratorViewModelTests.cs index 853682aada..a6d8e3de02 100644 --- a/DigitalLearningSolutions.Web.Tests/ViewModels/Common/NumberOfAdministratorViewModelTests.cs +++ b/DigitalLearningSolutions.Web.Tests/ViewModels/Common/NumberOfAdministratorViewModelTests.cs @@ -12,9 +12,9 @@ public void ViewModel_populates_expected_values() { // Given var numberOfAdmins = CentreContractAdminUsageTestHelper.GetDefaultNumberOfAdministrators( - 7, - 6, - 1, + admins: 7, + supervisors: 6, + trainers: 1, trainerSpots: 15, cmsAdministrators: 3, cmsAdministratorSpots: 12, diff --git a/DigitalLearningSolutions.Web.Tests/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModelTests.cs b/DigitalLearningSolutions.Web.Tests/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModelTests.cs index e9e16ca8f6..5ee2e744c2 100644 --- a/DigitalLearningSolutions.Web.Tests/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModelTests.cs +++ b/DigitalLearningSolutions.Web.Tests/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModelTests.cs @@ -124,7 +124,7 @@ public void EditRolesViewModel_sets_up_all_checkboxes_and_inputs_when_under_limi // Then using (new AssertionScope()) { - result.Checkboxes.Count.Should().Be(5); + result.Checkboxes.Count.Should().Be(6); result.Radios.Count.Should().Be(3); result.Checkboxes.Contains(AdminRoleInputs.CentreAdminCheckbox).Should().BeTrue(); result.Checkboxes.Contains(AdminRoleInputs.SupervisorCheckbox).Should().BeTrue(); @@ -159,7 +159,7 @@ public void // Then using (new AssertionScope()) { - result.Checkboxes.Count.Should().Be(4); + result.Checkboxes.Count.Should().Be(5); result.Checkboxes.Contains(AdminRoleInputs.TrainerCheckbox).Should().BeFalse(); result.NotAllRolesDisplayed.Should().BeTrue(); } @@ -185,7 +185,7 @@ public void EditRolesViewModel_does_set_up_Trainer_checkbox_when_its_limit_is_re // Then using (new AssertionScope()) { - result.Checkboxes.Count.Should().Be(5); + result.Checkboxes.Count.Should().Be(6); result.Checkboxes.Contains(AdminRoleInputs.TrainerCheckbox).Should().BeTrue(); result.NotAllRolesDisplayed.Should().BeFalse(); } @@ -212,7 +212,7 @@ public void // Then using (new AssertionScope()) { - result.Checkboxes.Count.Should().Be(4); + result.Checkboxes.Count.Should().Be(5); result.Checkboxes.Contains(AdminRoleInputs.ContentCreatorCheckbox).Should().BeFalse(); result.NotAllRolesDisplayed.Should().BeTrue(); } @@ -239,7 +239,7 @@ public void // Then using (new AssertionScope()) { - result.Checkboxes.Count.Should().Be(5); + result.Checkboxes.Count.Should().Be(6); result.Checkboxes.Contains(AdminRoleInputs.ContentCreatorCheckbox).Should().BeTrue(); result.NotAllRolesDisplayed.Should().BeFalse(); } diff --git a/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs b/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs index d9f779aa99..ed2ad45590 100644 --- a/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs +++ b/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs @@ -914,7 +914,7 @@ public IActionResult ConfirmNominateSupervisor(SupervisorDelegateViewModel super { var categoryId = User.GetAdminCourseCategoryFilter(); var supervisorDelegateDetail = supervisorService.GetSupervisorDelegateDetailsById(supervisorDelegate.Id, GetAdminID(), 0); - var adminRoles = new AdminRoles(false, false, true, false, false, false, false); + var adminRoles = new AdminRoles(false, false, true, false, false, false, false, false); if (supervisorDelegateDetail.CandidateID != null) { registrationService.PromoteDelegateToAdmin(adminRoles, (categoryId ?? 0), (int)supervisorDelegateDetail.CandidateID); diff --git a/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesFormData.cs b/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesFormData.cs index a4247acaf7..be9e0fb957 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesFormData.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesFormData.cs @@ -19,6 +19,7 @@ public AdminRolesFormData(User user) public bool IsCentreAdmin { get; set; } public bool IsSupervisor { get; set; } public bool IsNominatedSupervisor { get; set; } + public bool IsCenterManager { get; set; } public bool IsTrainer { get; set; } public bool IsContentCreator { get; set; } public ContentManagementRole ContentManagementRole { get; set; } @@ -34,7 +35,8 @@ public AdminRoles GetAdminRoles() IsContentCreator, IsTrainer, ContentManagementRole.IsContentManager, - ContentManagementRole.ImportOnly + ContentManagementRole.ImportOnly, + IsCenterManager ); } } diff --git a/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesViewModel.cs index a03e41ea66..c2c859b02b 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Common/AdminRolesViewModel.cs @@ -10,10 +10,11 @@ public abstract class AdminRolesViewModel : AdminRolesFormData { private const int MaxNumberOfCmsRoleRadios = 3; private const int MinNumberOfCmsRoleRadios = 1; - private const int MaxNumberOfRoleCheckboxes = 5; + private const int MaxNumberOfRoleCheckboxes = 6; public readonly List Checkboxes = new List { + AdminRoleInputs.CentreManagerCheckbox, AdminRoleInputs.CentreAdminCheckbox, AdminRoleInputs.SupervisorCheckbox, AdminRoleInputs.NominatedSupervisorCheckbox diff --git a/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/AdminRoleInputs.cs b/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/AdminRoleInputs.cs index 805448899b..1d031faa3a 100644 --- a/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/AdminRoleInputs.cs +++ b/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/AdminRoleInputs.cs @@ -11,6 +11,12 @@ public class AdminRoleInputs "Manage delegates, courses and course groups. Enrol users on courses. View reports." ); + public static CheckboxListItemViewModel CentreManagerCheckbox = new CheckboxListItemViewModel( + nameof(EditRolesViewModel.IsCenterManager), + "Centre manager", + "Manages user access permissions for administrators at the centre, sees all support tickets for the centre in addition to having all of the permissions of a centre administrator." + ); + public static CheckboxListItemViewModel SupervisorCheckbox = new CheckboxListItemViewModel( nameof(EditRolesViewModel.IsSupervisor), "Supervisor", diff --git a/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModel.cs index 9dc6b3821c..250ca91934 100644 --- a/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Centre/Administrator/EditRolesViewModel.cs @@ -24,6 +24,7 @@ ReturnPageQuery returnPageQuery { IsCentreAdmin = user.IsCentreAdmin; IsSupervisor = user.IsSupervisor; + IsCenterManager = user.IsCentreManager; IsNominatedSupervisor = user.IsNominatedSupervisor; IsTrainer = user.IsTrainer; IsContentCreator = user.IsContentCreator;