diff --git a/DigitalLearningSolutions.Data.Migrations/202504241517_AddFieldIsPrimaryToSelfAssessmentFrameworksTable.cs b/DigitalLearningSolutions.Data.Migrations/202504241517_AddFieldIsPrimaryToSelfAssessmentFrameworksTable.cs new file mode 100644 index 0000000000..fe1e096135 --- /dev/null +++ b/DigitalLearningSolutions.Data.Migrations/202504241517_AddFieldIsPrimaryToSelfAssessmentFrameworksTable.cs @@ -0,0 +1,12 @@ +namespace DigitalLearningSolutions.Data.Migrations +{ + using FluentMigrator; + [Migration(202504241517)] + public class AddFieldIsPrimaryToSelfAssessmentFrameworksTable : AutoReversingMigration + { + public override void Up() + { + Alter.Table("SelfAssessmentFrameworks").AddColumn("IsPrimary").AsBoolean().NotNullable().WithDefaultValue(1); + } + } +} diff --git a/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs b/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs index 983bdba073..2f597dc696 100644 --- a/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs +++ b/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs @@ -28,6 +28,12 @@ public interface ICompetencyAssessmentDataService CompetencyAssessmentTaskStatus GetOrInsertAndReturnAssessmentTaskStatus(int assessmentId, bool frameworkBased); + int[] GetLinkedFrameworkIds (int assessmentId); + + int? GetPrimaryLinkedFrameworkId(int assessmentId); + + int GetCompetencyCountByFrameworkId(int assessmentId, int frameworkId); + //UPDATE DATA bool UpdateCompetencyAssessmentName(int competencyAssessmentId, int adminId, string competencyAssessmentName); @@ -44,10 +50,19 @@ int categoryId bool UpdateBrandingTaskStatus(int assessmentId, bool taskStatus); bool UpdateVocabularyTaskStatus(int assessmentId, bool taskStatus); bool UpdateRoleProfileLinksTaskStatus(int assessmentId, bool taskStatus); + bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus); + bool RemoveSelfAssessmentFramework(int assessmentId, int frameworkId, int adminId); + bool UpdateSelectCompetenciesTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus); + bool UpdateOptionalCompetenciesTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus); + bool UpdateRoleRequirementsTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus); + //INSERT DATA int InsertCompetencyAssessment(int adminId, int centreId, string competencyAssessmentName); bool InsertSelfAssessmentFramework(int adminId, int selfAssessmentId, int frameworkId); + //DELETE DATA + bool RemoveFrameworkCompetenciesFromAssessment(int competencyAssessmentId, int frameworkId); + } public class CompetencyAssessmentDataService : ICompetencyAssessmentDataService @@ -77,13 +92,15 @@ FROM AdminUsers sa.Archived, sa.LastEdit, STUFF(( - SELECT - ', ' + f.FrameworkName - FROM - Frameworks f - WHERE - f.ID = saf.FrameworkId - FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS LinkedFrameworks, + SELECT + ', ' + f.FrameworkName + FROM + SelfAssessmentFrameworks saf2 + INNER JOIN Frameworks f ON f.ID = saf2.FrameworkId + WHERE + saf2.SelfAssessmentId = sa.ID + FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '' + ) AS LinkedFrameworks, (SELECT ProfessionalGroup FROM NRPProfessionalGroups WHERE (ID = sa.NRPProfessionalGroupID)) AS NRPProfessionalGroup, @@ -100,8 +117,7 @@ FROM NRPRoles private const string SelfAssessmentTables = @" LEFT OUTER JOIN - SelfAssessmentReviews AS sar ON sac.ID = sar.SelfAssessmentCollaboratorID AND sar.Archived IS NULL AND sar.ReviewComplete IS NULL - LEFT OUTER JOIN SelfAssessmentFrameworks AS saf ON sa.ID = saf.SelfAssessmentId"; + SelfAssessmentReviews AS sar ON sac.ID = sar.SelfAssessmentCollaboratorID AND sar.Archived IS NULL AND sar.ReviewComplete IS NULL"; private readonly IDbConnection connection; private readonly ILogger logger; @@ -324,14 +340,28 @@ public bool UpdateCompetencyAssessmentVocabulary(int competencyAssessmentId, int public bool InsertSelfAssessmentFramework(int adminId, int selfAssessmentId, int frameworkId) { + bool isPrimary = Convert.ToInt32(connection.ExecuteScalar( + @"SELECT Count(1) FROM SelfAssessmentFrameworks + WHERE SelfAssessmentId = @selfAssessmentId AND IsPrimary = 1", new { selfAssessmentId })) == 0; + var numberOfAffectedRows = connection.Execute( - @"INSERT INTO SelfAssessmentFrameworks (SelfAssessmentId, FrameworkId, CreatedByAdminId) - SELECT @selfAssessmentId, @frameworkId, @adminId + @"INSERT INTO SelfAssessmentFrameworks (SelfAssessmentId, FrameworkId, CreatedByAdminId, IsPrimary) + SELECT @selfAssessmentId, @frameworkId, @adminId, @isPrimary WHERE NOT EXISTS (SELECT 1 FROM SelfAssessmentFrameworks WHERE SelfAssessmentId = @selfAssessmentId AND FrameworkId = @frameworkId)" , - new { adminId, selfAssessmentId, frameworkId } + new { adminId, selfAssessmentId, frameworkId, isPrimary } ); if (numberOfAffectedRows < 1) + { + numberOfAffectedRows = connection.Execute( + @"UPDATE SelfAssessmentFrameworks + SET RemovedDate = NULL, RemovedByAdminId = NULL, AmendedByAdminId = @adminId + WHERE SelfAssessmentId = @selfAssessmentId AND FrameworkId = @frameworkId" + , + new { adminId, selfAssessmentId, frameworkId } + ); + } + if (numberOfAffectedRows < 1) { logger.LogWarning( "Not inserting SelfAssessmentFrameworks record as db insert failed. " + @@ -459,5 +489,148 @@ public bool UpdateRoleProfileLinksTaskStatus(int assessmentId, bool taskStatus) } return true; } + + public int[] GetLinkedFrameworkIds(int assessmentId) + { + return [.. connection.Query( + @"SELECT FrameworkId + FROM SelfAssessmentFrameworks + WHERE (SelfAssessmentId = @assessmentId) AND (RemovedDate IS NULL) AND (IsPrimary = 0) + ORDER BY ID", + new { assessmentId } + )]; + } + + public bool RemoveSelfAssessmentFramework(int assessmentId, int frameworkId, int adminId) + { + var numberOfAffectedRows = connection.Execute( + @"UPDATE SelfAssessmentFrameworks SET RemovedDate = @removedDate, RemovedByAdminId = @adminId + WHERE SelfAssessmentId = @assessmentId AND FrameworkId = @frameworkId", + new { removedDate = DateTime.Now, assessmentId, frameworkId, adminId } + ); + if (numberOfAffectedRows < 1) + { + logger.LogWarning( + "Not updating SelfAssessmentFrameworks as db update failed. " + + $"assessmentId: {assessmentId}, frameworkId: {frameworkId}, adminId: {adminId}" + ); + return false; + } + return true; + } + + public int? GetPrimaryLinkedFrameworkId(int assessmentId) + { + return connection.QuerySingleOrDefault( + @"SELECT TOP(1) FrameworkId + FROM SelfAssessmentFrameworks + WHERE (SelfAssessmentId = @assessmentId) AND (RemovedDate IS NULL) AND (IsPrimary = 1) + ORDER BY ID DESC", + new { assessmentId } + ); + } + + public bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + var numberOfAffectedRows = connection.Execute( + @"UPDATE SelfAssessmentTaskStatus SET FrameworkLinksTaskStatus = @taskStatus + WHERE SelfAssessmentId = @assessmentId AND (@previousStatus IS NULL OR FrameworkLinksTaskStatus = @previousStatus)", + new { assessmentId, taskStatus, previousStatus } + ); + if (numberOfAffectedRows < 1) + { + logger.LogWarning( + "Not updating FrameworkLinksTaskStatus as db update failed. " + + $"assessmentId: {assessmentId}, taskStatus: {taskStatus}" + ); + return false; + } + return true; + } + + public int GetCompetencyCountByFrameworkId(int assessmentId, int frameworkId) + { + return connection.ExecuteScalar( + @"SELECT COUNT(sas.CompetencyID) AS Competencies + FROM SelfAssessmentStructure AS sas INNER JOIN + FrameworkCompetencies AS fc ON sas.CompetencyID = fc.CompetencyID INNER JOIN + SelfAssessmentFrameworks AS saf ON fc.FrameworkID = saf.FrameworkId AND sas.SelfAssessmentID = saf.SelfAssessmentId + WHERE (saf.SelfAssessmentId = @assessmentId) AND (saf.FrameworkId = @frameworkId)", + new { assessmentId, frameworkId } + ); + } + + public bool RemoveFrameworkCompetenciesFromAssessment(int competencyAssessmentId, int frameworkId) + { + var numberOfAffectedRows = connection.Execute( + @"DELETE FROM SelfAssessmentStructure + FROM SelfAssessmentStructure INNER JOIN + FrameworkCompetencies AS fc ON SelfAssessmentStructure.CompetencyID = fc.CompetencyID INNER JOIN + SelfAssessmentFrameworks AS saf ON fc.FrameworkID = saf.FrameworkId AND SelfAssessmentStructure.SelfAssessmentID = saf.SelfAssessmentId + WHERE (saf.SelfAssessmentId = @competencyAssessmentId) AND (saf.FrameworkId = @frameworkId)", + new { competencyAssessmentId, frameworkId } + ); + if (numberOfAffectedRows < 1) + { + logger.LogWarning( + "Not removing competencies linked to source framework as db update failed. " + + $"assessmentId: {competencyAssessmentId}, taskStatus: {frameworkId}" + ); + return false; + } + return true; + } + + public bool UpdateSelectCompetenciesTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + var numberOfAffectedRows = connection.Execute( + @"UPDATE SelfAssessmentTaskStatus SET SelectCompetenciesTaskStatus = @taskStatus + WHERE SelfAssessmentId = @assessmentId AND (@previousStatus IS NULL OR SelectCompetenciesTaskStatus = @previousStatus)", + new { assessmentId, taskStatus, previousStatus } + ); + if (numberOfAffectedRows < 1) + { + logger.LogWarning( + "Not updating SelectCompetenciesTaskStatus as db update failed. " + + $"assessmentId: {assessmentId}, taskStatus: {taskStatus}" + ); + return false; + } + return true; + } + public bool UpdateOptionalCompetenciesTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + var numberOfAffectedRows = connection.Execute( + @"UPDATE SelfAssessmentTaskStatus SET OptionalCompetenciesTaskStatus = @taskStatus + WHERE SelfAssessmentId = @assessmentId AND (@previousStatus IS NULL OR OptionalCompetenciesTaskStatus = @previousStatus)", + new { assessmentId, taskStatus, previousStatus } + ); + if (numberOfAffectedRows < 1) + { + logger.LogWarning( + "Not updating OptionalCompetenciesTaskStatus as db update failed. " + + $"assessmentId: {assessmentId}, taskStatus: {taskStatus}" + ); + return false; + } + return true; + } + public bool UpdateRoleRequirementsTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + var numberOfAffectedRows = connection.Execute( + @"UPDATE SelfAssessmentTaskStatus SET RoleRequirementsTaskStatus = @taskStatus + WHERE SelfAssessmentId = @assessmentId AND (@previousStatus IS NULL OR RoleRequirementsTaskStatus = @previousStatus)", + new { assessmentId, taskStatus, previousStatus } + ); + if (numberOfAffectedRows < 1) + { + logger.LogWarning( + "Not updating RoleRequirementsTaskStatus as db update failed. " + + $"assessmentId: {assessmentId}, taskStatus: {taskStatus}" + ); + return false; + } + return true; + } } } diff --git a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs index aee8442d14..0d8d3ec490 100644 --- a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs +++ b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs @@ -15,6 +15,9 @@ using DigitalLearningSolutions.Data.Models.Centres; using DigitalLearningSolutions.Data.Models.Frameworks; using Microsoft.CodeAnalysis.CSharp.Syntax; + using DigitalLearningSolutions.Data.Models.Courses; + using DigitalLearningSolutions.Web.Services; + using DigitalLearningSolutions.Web.ViewModels.TrackingSystem.Delegates.GroupCourses; public partial class CompetencyAssessmentsController { @@ -389,5 +392,94 @@ public IActionResult SaveVocabulary(EditVocabularyViewModel model) competencyAssessmentService.UpdateVocabularyTaskStatus(model.ID, model.TaskStatus ?? false); return RedirectToAction("ManageCompetencyAssessment", new { competencyAssessmentId = model.ID }); } + [Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/{actionName}")] + public IActionResult SelectFrameworkSources(int competencyAssessmentId, string actionName) + { + var adminId = GetAdminID(); + var frameworks = frameworkService.GetAllFrameworks(adminId); + var competencyAssessmentBase = competencyAssessmentService.GetCompetencyAssessmentBaseById(competencyAssessmentId, adminId); + if (competencyAssessmentBase == null) + { + logger.LogWarning($"Failed to load Vocabulary page for competencyAssessmentId: {competencyAssessmentId} adminId: {adminId}"); + return StatusCode(500); + } + if (competencyAssessmentBase.UserRole < 2) + { + return StatusCode(403); + } + var primaryFrameworkId = competencyAssessmentService.GetPrimaryLinkedFrameworkId(competencyAssessmentId); + var additionalFrameworks = competencyAssessmentService.GetLinkedFrameworkIds(competencyAssessmentId); + var competencyAssessmentTaskStatus = competencyAssessmentService.GetCompetencyAssessmentTaskStatus(competencyAssessmentId, null); + var model = new SelectFrameworkSourcesViewModel(competencyAssessmentBase, frameworks, additionalFrameworks, primaryFrameworkId, competencyAssessmentTaskStatus.FrameworkLinksTaskStatus, actionName); + return View(model); + } + [HttpPost] + [Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/{actionName}")] + public IActionResult SelectFrameworkSources(SelectFrameworkSourcesFormData model, string actionName) + { + var adminId = GetAdminID(); + var competencyAssessmentId = model.CompetencyAssessmentId; + if (!ModelState.IsValid) + { + + var frameworks = frameworkService.GetAllFrameworks(adminId); + var competencyAssessmentBase = competencyAssessmentService.GetCompetencyAssessmentBaseById(competencyAssessmentId, adminId); + if (competencyAssessmentBase == null) + { + logger.LogWarning($"Failed to load Vocabulary page for competencyAssessmentId: {competencyAssessmentId} adminId: {adminId}"); + return StatusCode(500); + } + if (competencyAssessmentBase.UserRole < 2) + { + return StatusCode(403); + } + var primaryFrameworkId = competencyAssessmentService.GetPrimaryLinkedFrameworkId(competencyAssessmentId); + var additionalFrameworks = competencyAssessmentService.GetLinkedFrameworkIds(competencyAssessmentId); + var viewModel = new SelectFrameworkSourcesViewModel(competencyAssessmentBase, frameworks, additionalFrameworks, primaryFrameworkId, model.TaskStatus, model.ActionName); + return View("SelectFrameworkSources", viewModel); + } + if (actionName == "AddFramework") + { + competencyAssessmentService.InsertSelfAssessmentFramework(adminId, competencyAssessmentId, model.FrameworkId); + return RedirectToAction("SelectFrameworkSources", new { competencyAssessmentId, actionName = "Summary" }); + } + else + { + competencyAssessmentService.UpdateFrameworkLinksTaskStatus(model.CompetencyAssessmentId, model.TaskStatus ?? false, null); + return RedirectToAction("ManageCompetencyAssessment", new { competencyAssessmentId = model.CompetencyAssessmentId }); + } + } + [Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/{frameworkId}/Remove")] + public IActionResult RemoveFramework(int frameworkId, int competencyAssessmentId) + { + var frameworkCompetencyCount = competencyAssessmentService.GetCompetencyCountByFrameworkId(competencyAssessmentId, frameworkId); + if (frameworkCompetencyCount > 0) + { + var adminId = GetAdminID(); + var competencyAssessmentBase = competencyAssessmentService.GetCompetencyAssessmentBaseById(competencyAssessmentId, adminId); + var framework = frameworkService.GetFrameworkDetailByFrameworkId(frameworkId, adminId); + var model = new ConfirmRemoveFrameworkSourceViewModel(competencyAssessmentBase, framework, frameworkCompetencyCount); + return View("ConfirmRemoveFrameworkSource", model); + } + else + { + var adminId = GetAdminID(); + competencyAssessmentService.RemoveSelfAssessmentFramework(competencyAssessmentId, frameworkId, adminId); + } + return RedirectToAction("SelectFrameworkSources", new { competencyAssessmentId, actionName = "Summary" }); + } + [HttpPost] + [Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/{frameworkId}/Remove")] + public IActionResult RemoveFramework(ConfirmRemoveFrameworkSourceViewModel model) + { + if (!ModelState.IsValid) + { + return View("ConfirmRemoveFrameworkSource", model); + } + var adminId = GetAdminID(); + competencyAssessmentService.RemoveFrameworkCompetenciesFromAssessment(model.CompetencyAssessmentId, model.FrameworkId); + competencyAssessmentService.RemoveSelfAssessmentFramework(model.CompetencyAssessmentId, model.FrameworkId, adminId); + return RedirectToAction("SelectFrameworkSources", new { model.CompetencyAssessmentId, actionName = "Summary" }); + } } } diff --git a/DigitalLearningSolutions.Web/Helpers/DisplayStringHelper.cs b/DigitalLearningSolutions.Web/Helpers/DisplayStringHelper.cs index 5014a2d93c..9f6e6a571b 100644 --- a/DigitalLearningSolutions.Web/Helpers/DisplayStringHelper.cs +++ b/DigitalLearningSolutions.Web/Helpers/DisplayStringHelper.cs @@ -71,6 +71,21 @@ public static string GetPluralitySuffix(int number) { return number == 1 ? string.Empty : "s"; } + public static string PluraliseStringIfRequired(string input, int number) + { + if (number == 1) + { + return input; + } + else if (input.EndsWith("y")) + { + return input.Substring(0, input.Length - 1) + "ies"; + } + else + { + return input + "s"; + } + } public static string? ReplaceNonAlphaNumericSpaceChars(string? input, string replacement) { diff --git a/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs b/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs index 7e8cf37fdb..80bb557030 100644 --- a/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs +++ b/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs @@ -1,6 +1,7 @@ using DigitalLearningSolutions.Data.DataServices; using DigitalLearningSolutions.Data.Models.Common; using DigitalLearningSolutions.Data.Models.CompetencyAssessments; +using DocumentFormat.OpenXml.EMMA; using System.Collections.Generic; using System.Threading.Tasks; @@ -23,6 +24,10 @@ public interface ICompetencyAssessmentService IEnumerable GetNRPRoles(int? nRPSubGroupID); CompetencyAssessmentTaskStatus GetCompetencyAssessmentTaskStatus(int assessmentId, int? frameworkId); + int[] GetLinkedFrameworkIds(int assessmentId); + int? GetPrimaryLinkedFrameworkId(int assessmentId); + + bool RemoveSelfAssessmentFramework(int assessmentId, int frameworkId, int adminId); //UPDATE DATA bool UpdateCompetencyAssessmentName(int competencyAssessmentId, int adminId, string competencyAssessmentName); @@ -34,9 +39,19 @@ public interface ICompetencyAssessmentService bool UpdateCompetencyAssessmentVocabulary(int assessmentId, int adminId, string vocabulary); bool UpdateVocabularyTaskStatus(int assessmentId, bool taskStatus); bool UpdateRoleProfileLinksTaskStatus(int assessmentId, bool taskStatus); + bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus); + bool UpdateSelectCompetenciesTaskStatus(int competencyAssessmentId, bool taskStatus, bool? previousStatus); + bool UpdateOptionalCompetenciesTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus); + bool UpdateRoleRequirementsTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus); //INSERT DATA int InsertCompetencyAssessment(int adminId, int centreId, string competencyAssessmentName, int? frameworkId); + bool InsertSelfAssessmentFramework(int adminId, int assessmentId, int frameworkId); + int GetCompetencyCountByFrameworkId(int competencyAssessmentId, int frameworkId); + + //DELETE DATA + bool RemoveFrameworkCompetenciesFromAssessment(int competencyAssessmentId, int frameworkId); + } public class CompetencyAssessmentService : ICompetencyAssessmentService { @@ -81,7 +96,7 @@ public int InsertCompetencyAssessment(int adminId, int centreId, string competen { competencyAssessmentDataService.InsertSelfAssessmentFramework(adminId, assessmentId, framework.ID); competencyAssessmentDataService.UpdateCompetencyAssessmentDescription(adminId, assessmentId, framework.Description); - competencyAssessmentDataService.UpdateCompetencyAssessmentBranding(assessmentId, (int)framework.BrandID, (int)framework.CategoryID, adminId); + competencyAssessmentDataService.UpdateCompetencyAssessmentBranding(assessmentId, adminId, (int)framework.BrandID, (int)framework.CategoryID); competencyAssessmentDataService.UpdateCompetencyAssessmentVocabulary(assessmentId, adminId, framework.Vocabulary); } } @@ -149,5 +164,59 @@ public bool UpdateRoleProfileLinksTaskStatus(int assessmentId, bool taskStatus) { return competencyAssessmentDataService.UpdateRoleProfileLinksTaskStatus(assessmentId, taskStatus); } + + public int[] GetLinkedFrameworkIds(int assessmentId) + { + return competencyAssessmentDataService.GetLinkedFrameworkIds(assessmentId); + } + + public bool InsertSelfAssessmentFramework(int adminId, int assessmentId, int frameworkId) + { + return competencyAssessmentDataService.InsertSelfAssessmentFramework(adminId, assessmentId, frameworkId); + } + + public bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + return competencyAssessmentDataService.UpdateFrameworkLinksTaskStatus(assessmentId, taskStatus, previousStatus); + } + + public int? GetPrimaryLinkedFrameworkId(int assessmentId) + { + return competencyAssessmentDataService.GetPrimaryLinkedFrameworkId(assessmentId); + } + + public bool RemoveSelfAssessmentFramework(int assessmentId, int frameworkId, int adminId) + { + UpdateFrameworkLinksTaskStatus(assessmentId, false, true); + return competencyAssessmentDataService.RemoveSelfAssessmentFramework(assessmentId, frameworkId, adminId); + } + + public int GetCompetencyCountByFrameworkId(int competencyAssessmentId, int frameworkId) + { + return competencyAssessmentDataService.GetCompetencyCountByFrameworkId(competencyAssessmentId, frameworkId); + } + + public bool RemoveFrameworkCompetenciesFromAssessment(int competencyAssessmentId, int frameworkId) + { + UpdateSelectCompetenciesTaskStatus(competencyAssessmentId, false, true); + UpdateOptionalCompetenciesTaskStatus(competencyAssessmentId, false, true); + UpdateRoleRequirementsTaskStatus(competencyAssessmentId, false, true); + return competencyAssessmentDataService.RemoveFrameworkCompetenciesFromAssessment(competencyAssessmentId, frameworkId); + } + + public bool UpdateSelectCompetenciesTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + return competencyAssessmentDataService.UpdateSelectCompetenciesTaskStatus(assessmentId, taskStatus, previousStatus); + } + + public bool UpdateOptionalCompetenciesTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + return competencyAssessmentDataService.UpdateOptionalCompetenciesTaskStatus(assessmentId, taskStatus, previousStatus); + } + + public bool UpdateRoleRequirementsTaskStatus(int assessmentId, bool taskStatus, bool? previousStatus) + { + return competencyAssessmentDataService.UpdateRoleRequirementsTaskStatus(assessmentId, taskStatus, previousStatus); + } } } diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/ConfirmRemoveFrameworkSourceViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/ConfirmRemoveFrameworkSourceViewModel.cs new file mode 100644 index 0000000000..1a4e78cc79 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/ConfirmRemoveFrameworkSourceViewModel.cs @@ -0,0 +1,29 @@ +using DigitalLearningSolutions.Data.Models.CompetencyAssessments; +using DigitalLearningSolutions.Data.Models.Frameworks; +using DigitalLearningSolutions.Web.Attributes; + +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + public class ConfirmRemoveFrameworkSourceViewModel + { + public ConfirmRemoveFrameworkSourceViewModel() { } + public ConfirmRemoveFrameworkSourceViewModel(CompetencyAssessmentBase competencyAssessmentBase, DetailFramework framework, int competencyCount) + { + CompetencyAssessmentId = competencyAssessmentBase.ID; + CompetencyCount = competencyCount; + AssessmentName = competencyAssessmentBase.CompetencyAssessmentName; + FrameworkName = framework.FrameworkName; + FrameworkId = framework.ID; + Vocabulary = competencyAssessmentBase.Vocabulary; + } + public int CompetencyAssessmentId { get; set; } + public string? AssessmentName { get; set; } + public string? FrameworkName { get; set; } + public int FrameworkId { get; set; } + public int CompetencyCount { get; set; } + public string? Vocabulary { get; set; } + [BooleanMustBeTrue(ErrorMessage = "You must confirm that you wish to remove this framework")] + public bool Confirm { get; set; } + + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesFormData.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesFormData.cs new file mode 100644 index 0000000000..846a0fb2dd --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesFormData.cs @@ -0,0 +1,12 @@ +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + using System.ComponentModel.DataAnnotations; + public class SelectFrameworkSourcesFormData + { + [Required] + public int FrameworkId { get; set; } + public int CompetencyAssessmentId { get; set; } + public bool? TaskStatus { get; set; } + public string? ActionName { get; set; } + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs new file mode 100644 index 0000000000..8d1adea226 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs @@ -0,0 +1,40 @@ +using DigitalLearningSolutions.Data.Models.CompetencyAssessments; +using DigitalLearningSolutions.Data.Models.Frameworks; +using System.Collections.Generic; +using System.Linq; + +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + public class SelectFrameworkSourcesViewModel : SelectFrameworkSourcesFormData + { + public SelectFrameworkSourcesViewModel() { } + public SelectFrameworkSourcesViewModel(CompetencyAssessmentBase competencyAssessmentBase, IEnumerable frameworks, int[] additionalFrameworksIds, int? primaryFramework, bool? taskStatus, string actionName) + { + ID = competencyAssessmentBase.ID; + CompetencyAssessmentName = competencyAssessmentBase.CompetencyAssessmentName; + UserRole = competencyAssessmentBase.UserRole; + TaskStatus = taskStatus; + PrimaryFramework = frameworks.FirstOrDefault(f => f.ID == primaryFramework); + var excludedIds = new HashSet(additionalFrameworksIds); + if (primaryFramework.HasValue) + { + excludedIds.Add(primaryFramework.Value); + } + Frameworks = [.. frameworks + .Where(f => !excludedIds.Contains(f.ID)) + .OrderBy(f => f.FrameworkName)]; + AdditionalFrameworks = [.. additionalFrameworksIds.Select(id => frameworks.First(f => f.ID == id))]; + ActionName = actionName; + } + public IEnumerable Frameworks { get; set; } + public IEnumerable AdditionalFrameworks { get; set; } + public BrandedFramework? PrimaryFramework { get; set; } + public IEnumerable Roles { get; set; } + public int ID { get; set; } + public string CompetencyAssessmentName { get; set; } + public int UserRole { get; set; } + public string? GroupName { get; set; } + public string? SubGroupName { get; set; } + public string? RoleName { get; set; } + } +} diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ConfirmRemoveFrameworkSource.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ConfirmRemoveFrameworkSource.cshtml new file mode 100644 index 0000000000..a20a786820 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ConfirmRemoveFrameworkSource.cshtml @@ -0,0 +1,51 @@ +@using DigitalLearningSolutions.Web.Helpers +@using DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +@model ConfirmRemoveFrameworkSourceViewModel; +@{ + var errorHasOccurred = !ViewData.ModelState.IsValid; + ViewData["Title"] = "Competency Assessments - Remove source framework"; +} +
+
+ @if (errorHasOccurred) + { + + } + +

Remove framework source from @Model.AssessmentName

+
+
+ + + +
+
+
+ + + + + + +

+ This competency assessment has @Model.CompetencyCount @DisplayStringHelper.PluraliseStringIfRequired(@Model.Vocabulary.ToLower(), Model.CompetencyCount) + associated with it from the framework @Model.FrameworkName. Removing this + framework source will remove the @DisplayStringHelper.PluraliseStringIfRequired(@Model.Vocabulary.ToLower(), Model.CompetencyCount) from the assessment. +

+ + + + + + +
+
diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/EditRoleProfileLinks.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/EditRoleProfileLinks.cshtml index b5faad6214..96e78ce8d9 100644 --- a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/EditRoleProfileLinks.cshtml +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/EditRoleProfileLinks.cshtml @@ -119,6 +119,7 @@ + @@ -170,6 +171,7 @@ else if (Model.ActionName == "EditSubGroup" && Model.ProfessionalGroupId != null + @@ -220,6 +222,7 @@ else if (Model.ActionName == "EditRole" && Model.SubGroupId != null) + diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml index 3e4f9f34be..70b5bbdc71 100644 --- a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml @@ -57,7 +57,7 @@