From b77192608e1ccb20fa36e742deece0046e578ae2 Mon Sep 17 00:00:00 2001 From: sherif-olaboye <123654949+sherif-olaboye@users.noreply.github.com> Date: Mon, 1 Dec 2025 10:34:36 +0000 Subject: [PATCH 1/3] TD-5401 Manage supervision settings --- .../CompetencyAssessmentDataService.cs | 133 +++++++++--- .../Extensions/ConfigurationExtensions.cs | 11 + .../CompetencyAssessmentBase.cs | 5 +- .../CompetencyAssessments.cs | 199 ++++++++++++++++++ .../Services/CompetencyAssessmentService.cs | 28 +++ .../BaseSignoffDeclarationViewModel.cs | 29 +++ .../LearnerSignoffDeclarationViewModel.cs | 12 ++ .../ManagesupervisionViewModel.cs | 60 ++++++ ...upervisedSelfAssessmentSignoffViewModel.cs | 31 +++ .../SupervisorSignoffDeclarationViewModel.cs | 13 ++ .../LearnerSignoffDeclaration.cshtml | 99 +++++++++ .../ManageCompetencyAssessment.cshtml | 3 +- .../ManageSupervisionSettings.cshtml | 165 +++++++++++++++ .../SupervisedSelfAssessmentSignoff.cshtml | 121 +++++++++++ .../SupervisorSignoffDeclaration.cshtml | 97 +++++++++ .../appSettings.UAT.json | 2 + .../appsettings.Development.json | 5 +- .../appsettings.Production.json | 2 + .../appsettings.SIT.json | 2 + .../appsettings.Test.json | 2 + .../appsettings.UarTest.json | 2 + DigitalLearningSolutions.Web/appsettings.json | 4 +- 22 files changed, 997 insertions(+), 28 deletions(-) create mode 100644 DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/BaseSignoffDeclarationViewModel.cs create mode 100644 DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/LearnerSignoffDeclarationViewModel.cs create mode 100644 DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/ManagesupervisionViewModel.cs create mode 100644 DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisedSelfAssessmentSignoffViewModel.cs create mode 100644 DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisorSignoffDeclarationViewModel.cs create mode 100644 DigitalLearningSolutions.Web/Views/CompetencyAssessments/LearnerSignoffDeclaration.cshtml create mode 100644 DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageSupervisionSettings.cshtml create mode 100644 DigitalLearningSolutions.Web/Views/CompetencyAssessments/SupervisedSelfAssessmentSignoff.cshtml create mode 100644 DigitalLearningSolutions.Web/Views/CompetencyAssessments/SupervisorSignoffDeclaration.cshtml diff --git a/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs b/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs index 853e2bf42e..f92346dd63 100644 --- a/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs +++ b/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs @@ -71,7 +71,16 @@ public bool UpdateCompetencyAssessmentFeaturesTaskStatus(int id, bool descriptio bool workingGroupStatus, bool AllframeworkCompetenciesStatus); void UpdateSelfAssessmentFromFramework(int selfAssessmentId, int? frameworkId); bool UpdatePrimaryFrameworkCompetencies(int assessmentId, int frameworkId); - + bool UpdateSupervisorRolesTaskStatus(int competencyAssessmentId, bool taskCompleteChecked); + bool UpdateSelfAssessments(int competencyAssessmentId, + int? supervised, + int? signoff, + int? confirm, + int? supervisorDeclarationValue, + string? supervisorCustomText, + int? leanerDeclarationValue, + string? leanerCustomText + ); //INSERT DATA int InsertCompetencyAssessment(int adminId, int centreId, string competencyAssessmentName); bool InsertSelfAssessmentFramework(int adminId, int selfAssessmentId, int frameworkId); @@ -94,7 +103,12 @@ public class CompetencyAssessmentDataService : ICompetencyAssessmentDataService sa.NRPProfessionalGroupID, sa.NRPSubGroupID, sa.NRPRoleID, - sa.PublishStatusID, sa.Vocabulary, CASE WHEN sa.CreatedByAdminID = @adminId THEN 3 WHEN sac.CanModify = 1 THEN 2 WHEN sac.CanModify = 0 THEN 1 ELSE 0 END AS UserRole"; + sa.PublishStatusID, sa.Vocabulary, + CASE WHEN sa.CreatedByAdminID = @adminId THEN 3 WHEN sac.CanModify = 1 THEN 2 WHEN sac.CanModify = 0 THEN 1 ELSE 0 END AS UserRole, + sa.SupervisorResultsReview, + sa.SupervisorSelfAssessmentReview, + sa.SignOffSupervisorStatement, + sa.SignOffRequestorStatement"; private const string SelfAssessmentFields = @", sa.CategoryID, sa.CreatedDate, @@ -879,43 +893,43 @@ FROM FrameworkCompetencies AS FC return true; } - + public bool UpdatePrimaryFrameworkCompetencies(int assessmentId, int frameworkId) { connection.EnsureOpen(); using (var transaction = connection.BeginTransaction()) { - var numberOfAffectedRows = connection.Execute( - @"UPDATE SelfAssessmentFrameworks + var numberOfAffectedRows = connection.Execute( + @"UPDATE SelfAssessmentFrameworks SET IsPrimary = 0 WHERE (SelfAssessmentId = @assessmentId) AND (RemovedDate IS NULL)", - new { assessmentId }, - transaction: transaction - ); + new { assessmentId }, + transaction: transaction + ); - var numberOfAffectedRow = connection.Execute( - @"UPDATE SelfAssessmentFrameworks + var numberOfAffectedRow = connection.Execute( + @"UPDATE SelfAssessmentFrameworks SET IsPrimary = 1 WHERE (SelfAssessmentId = @assessmentId) AND (FrameworkId = @frameworkId) AND (RemovedDate IS NULL)", - new { assessmentId, frameworkId }, - transaction: transaction - ); + new { assessmentId, frameworkId }, + transaction: transaction + ); - if ((numberOfAffectedRow < 1) || (numberOfAffectedRows < 1)) - { - logger.LogWarning( - "Not updating SelfAssessmentFrameworks as db update failed. " + - $"assessmentId: {assessmentId}, frameworkId: {frameworkId}" - ); - transaction.Rollback(); - return false; - } + if ((numberOfAffectedRow < 1) || (numberOfAffectedRows < 1)) + { + logger.LogWarning( + "Not updating SelfAssessmentFrameworks as db update failed. " + + $"assessmentId: {assessmentId}, frameworkId: {frameworkId}" + ); + transaction.Rollback(); + return false; + } - transaction.Commit(); - return true; + transaction.Commit(); + return true; } } public int? GetSelfAssessmentStructure(int competencyAssessmentId) @@ -1057,5 +1071,76 @@ FROM SelfAssessmentCollaborators AS sc new { invitedByAdminId, id } ).FirstOrDefault(); } + public bool UpdateSupervisorRolesTaskStatus(int competencyAssessmentId, bool taskCompleteChecked) + { + var numberOfAffectedRows = connection.Execute( + @" UPDATE SelfAssessmentTaskStatus + SET SupervisorRolesTaskStatus = CASE WHEN @taskCompleteChecked = 1 THEN 1 ELSE NULL END + WHERE SelfAssessmentId = @competencyAssessmentId", + new { competencyAssessmentId, taskCompleteChecked = taskCompleteChecked ? 1 : 0 } + ); + if (numberOfAffectedRows < 1) + { + logger.LogWarning( + "Not updating SupervisorRolesTaskStatus as db update failed. " + + $"competencyAssessmentId: {competencyAssessmentId}, taskCompleteChecked: {taskCompleteChecked}" + ); + return false; + } + return true; + } + public bool UpdateSelfAssessments(int competencyAssessmentId, + int? supervised, + int? signoff, + int? confirm, + int? supervisorDeclarationValue, + string? supervisorCustomText, + int? leanerDeclarationValue, + string? leanerCustomText + ) + { + var sqlQuery = @" + IF @supervised = 0 + BEGIN + UPDATE SelfAssessments SET SupervisorResultsReview = 0 + WHERE ID = @competencyAssessmentId; + END + ELSE + BEGIN + UPDATE SelfAssessments + SET SupervisorResultsReview = 1, + SupervisorSelfAssessmentReview = @confirm, + SignOffSupervisorStatement = CASE WHEN @supervisorDeclarationValue = 0 THEN NULL ELSE @supervisorCustomText END, + SignOffRequestorStatement = CASE WHEN @leanerDeclarationValue = 0 THEN NULL ELSE @leanerCustomText END + WHERE ID = @competencyAssessmentId; + END + "; + var affectedRows = connection.Execute( + sqlQuery, + new + { + competencyAssessmentId, + supervised, + confirm, + supervisorDeclarationValue, + supervisorCustomText, + leanerDeclarationValue, + leanerCustomText + } + ); + + if ((affectedRows < 1)) + { + logger.LogWarning( + "Not updating SelfAssessments as db update failed. " + + $"competencyAssessmentId: {competencyAssessmentId}, supervised: {supervised}" + + $"signoff: {signoff}, confirm: {confirm}, supervisorDeclarationValue: {supervisorDeclarationValue} " + + $"supervisorCustomText: {supervisorCustomText}, leanerDeclarationValue: {leanerDeclarationValue}, leanerCustomText: {leanerCustomText} " + ); + return false; + } + return true; + } + } } diff --git a/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs b/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs index f869df5f74..f42dbddeed 100644 --- a/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs +++ b/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs @@ -60,6 +60,9 @@ public static class ConfigurationExtensions private const string TableauViewName = "ViewName"; private const string TableauSiteName = "SiteName"; private const string TableauAuthApi = "AuthApiPath"; + private const string SupervisorDefaultText = "SupervisorDefaultText"; + private const string LearnerDefaultText = "LearnerDefaultText"; + public static string GetAppRootPath(this IConfiguration config) { return config[AppRootPathName]!; @@ -268,5 +271,13 @@ public static string GetTableauViewName(this IConfiguration config) { return config[$"{TableauSectionKey}:{TableauViewName}"]!; } + public static string GetSupervisorDefaultText(this IConfiguration config) + { + return config[SupervisorDefaultText]!; + } + public static string GetLearnerDefaultText(this IConfiguration config) + { + return config[LearnerDefaultText]!; + } } } diff --git a/DigitalLearningSolutions.Data/Models/CompetencyAssessments/CompetencyAssessmentBase.cs b/DigitalLearningSolutions.Data/Models/CompetencyAssessments/CompetencyAssessmentBase.cs index 5fa9080ae3..19a98d0e65 100644 --- a/DigitalLearningSolutions.Data/Models/CompetencyAssessments/CompetencyAssessmentBase.cs +++ b/DigitalLearningSolutions.Data/Models/CompetencyAssessments/CompetencyAssessmentBase.cs @@ -19,8 +19,11 @@ public class CompetencyAssessmentBase public int? NRPRoleID { get; set; } public int PublishStatusID { get; set; } public int UserRole { get; set; } + public int SupervisorResultsReview { get; set; } + public int SupervisorSelfAssessmentReview { get; set; } + public string? SignOffRequestorStatement { get; set; } + public string? SignOffSupervisorStatement { get; set; } public string? Vocabulary { get; set; } - } } diff --git a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs index 75ee43be31..da3b610888 100644 --- a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs +++ b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs @@ -1,6 +1,7 @@ namespace DigitalLearningSolutions.Web.Controllers.CompetencyAssessmentsController { using DigitalLearningSolutions.Data.Enums; + using DigitalLearningSolutions.Data.Extensions; using DigitalLearningSolutions.Data.Models.CompetencyAssessments; using DigitalLearningSolutions.Data.Models.Frameworks; using DigitalLearningSolutions.Data.Models.SelfAssessments; @@ -815,7 +816,189 @@ public IActionResult RemoveCollaborator(int competencyAssessmentId, int id, stri return RedirectToAction("AssessmentWorkingGroup", "CompetencyAssessments", new { competencyAssessmentId, actionName = actionName }); } + [Route("/CompetencyAssessments/{competencyAssessmentId}/SupervisorRoles")] + public IActionResult SupervisorRoles(int competencyAssessmentId) + { + if (competencyAssessmentId == 0) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + var competencyAssessmentTaskStatus = competencyAssessmentService.GetCompetencyAssessmentTaskStatus(competencyAssessmentId, null); + if(competencyAssessmentTaskStatus.SupervisorRolesTaskStatus != null) return RedirectToAction("ManageSupervisionSettings", "CompetencyAssessments", + new + { + CompetencyAssessmentId = competencyAssessmentId, + ActionName = "SupervisorRoles" + }); return RedirectToAction("SupervisedSelfAssessmentSignoff", "CompetencyAssessments", new { competencyAssessmentId }); + } + + [Route("/CompetencyAssessments/{competencyAssessmentId}/Supervised")] + [Route("/CompetencyAssessments/{competencyAssessmentId}/{actionName}/Supervised")] + public IActionResult SupervisedSelfAssessmentSignoff(int competencyAssessmentId, string? actionName) + { + if (competencyAssessmentId == 0) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + if (actionName== "Signoff") + { + var data = GetManagesupervisionData(); + data.Signoff.ActionName = actionName; + var models = new SupervisedSelfAssessmentSignoffViewModel(data.Signoff); + return View(models); + } + var adminId = GetAdminID(); + var baseData = competencyAssessmentService.GetCompetencyAssessmentBaseById(competencyAssessmentId, adminId); + if (string.IsNullOrEmpty(baseData.CompetencyAssessmentName)) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + var model = new SupervisedSelfAssessmentSignoffViewModel(competencyAssessmentId, baseData.CompetencyAssessmentName, actionName); + return View("SupervisedSelfAssessmentSignoff", model); + } + [HttpPost] + [Route("/CompetencyAssessments/{competencyAssessmentId}/Supervised")] + public IActionResult SupervisedSelfAssessmentSignoff(SupervisedSelfAssessmentSignoffViewModel supervisedSelf) + { + if (supervisedSelf == null) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + if (supervisedSelf.ActionName != null) + { + var data = GetManagesupervisionData(); + var model = new ManagesupervisionViewModel(data.LearnerDeclaration, data.SupervisorDeclaration, supervisedSelf); + SetManagesupervisionData(model); + } + else + { + var model = new ManagesupervisionViewModel(supervisedSelf); + SetManagesupervisionData(model); + } + if (supervisedSelf.Supervised == 0) return RedirectToAction("ManageSupervisionSettings", "CompetencyAssessments", new { supervisedSelf.CompetencyAssessmentId }); + if (supervisedSelf.ActionName != null) return RedirectToAction("SupervisorSignoffDeclaration", "CompetencyAssessments", + new + { + CompetencyAssessmentId = supervisedSelf.CompetencyAssessmentId, + ActionName = "Supervisor" + }); + return RedirectToAction("SupervisorSignoffDeclaration", "CompetencyAssessments", new { supervisedSelf.CompetencyAssessmentId }); + } + + [Route("/CompetencyAssessments/{competencyAssessmentId}/SupervisorDeclaration")] + [Route("/CompetencyAssessments/{competencyAssessmentId}/{actionName}/SupervisorDeclaration")] + public IActionResult SupervisorSignoffDeclaration(int competencyAssessmentId, string? actionName) + { + if (competencyAssessmentId == 0) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + var data = GetManagesupervisionData(); + if (actionName == "Supervisor") + { + data.SupervisorDeclaration.ActionName = actionName; + var models = new SupervisorSignoffDeclarationViewModel(data.SupervisorDeclaration); + return View(models); + } + var model = new SupervisorSignoffDeclarationViewModel(competencyAssessmentId); + model.CompetencyAssessmentName = data.CompetencyAssessmentName; + model.DefaultText = this.config.GetSupervisorDefaultText(); + return View(model); + } + + [HttpPost] + [Route("/CompetencyAssessments/{competencyAssessmentId}/SupervisorDeclaration")] + public IActionResult SupervisorSignoffDeclaration(SupervisorSignoffDeclarationViewModel viewModel) + { + if (viewModel == null) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + if (!ModelState.IsValid || (viewModel.DeclarationValue == 1 && string.IsNullOrEmpty(viewModel.CustomText))) + { + ModelState.AddModelError(nameof(viewModel.CustomText), ""); + return View(viewModel); + } + var data = GetManagesupervisionData(); + var model = new ManagesupervisionViewModel(data.LearnerDeclaration,viewModel, data.Signoff ); + SetManagesupervisionData(model); + if (viewModel.ActionName != null) return RedirectToAction("LearnerSignoffDeclaration", "CompetencyAssessments", + new + { + CompetencyAssessmentId = viewModel.CompetencyAssessmentId, + ActionName = "Learner" + }); + return RedirectToAction("LearnerSignoffDeclaration", "CompetencyAssessments", new { viewModel.CompetencyAssessmentId }); + } + + [Route("/CompetencyAssessments/{competencyAssessmentId}/LearnerDeclaration")] + [Route("/CompetencyAssessments/{competencyAssessmentId}/{actionName}/LearnerDeclaration")] + public IActionResult LearnerSignoffDeclaration(int competencyAssessmentId, string? actionName) + { + if (competencyAssessmentId == 0) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + var data = GetManagesupervisionData(); + if (actionName == "Learner") + { + data.LearnerDeclaration.ActionName = actionName; + var models = new LearnerSignoffDeclarationViewModel(data.LearnerDeclaration); + return View(models); + } + var model = new LearnerSignoffDeclarationViewModel(competencyAssessmentId); + model.CompetencyAssessmentName = data.CompetencyAssessmentName; + model.DefaultText = this.config.GetLearnerDefaultText(); + return View(model); + } + + [HttpPost] + [Route("/CompetencyAssessments/{competencyAssessmentId}/LearnerDeclaration")] + public IActionResult LearnerSignoffDeclaration(LearnerSignoffDeclarationViewModel viewModel) + { + if (viewModel == null) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + if (!ModelState.IsValid || (viewModel.DeclarationValue == 1 && string.IsNullOrEmpty(viewModel.CustomText) )) + { + ModelState.AddModelError(nameof(viewModel.CustomText), ""); + return View(viewModel); + } + var data = GetManagesupervisionData(); + var model = new ManagesupervisionViewModel(viewModel, data.SupervisorDeclaration, data.Signoff); + SetManagesupervisionData(model); + return RedirectToAction("ManageSupervisionSettings", "CompetencyAssessments", new { viewModel.CompetencyAssessmentId }); + } + + [Route("/CompetencyAssessments/{competencyAssessmentId}/SupervisionSettings")] + [Route("/CompetencyAssessments/{competencyAssessmentId}/{actionName}/SupervisionSettings")] + public IActionResult ManageSupervisionSettings(int competencyAssessmentId, string? actionName) + { + if (competencyAssessmentId == 0) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + if (actionName == "SupervisorRoles") + { + var adminId = GetAdminID(); + var baseData = competencyAssessmentService.GetCompetencyAssessmentBaseById(competencyAssessmentId, adminId); + var model = new ManagesupervisionViewModel(competencyAssessmentId, baseData.CompetencyAssessmentName, + baseData.SupervisorResultsReview, + baseData.SupervisorSelfAssessmentReview, + baseData.SignOffSupervisorStatement, + baseData.SignOffRequestorStatement, + this.config.GetLearnerDefaultText(), + this.config.GetSupervisorDefaultText()); + SetManagesupervisionData(model); + return View(model); + } + var data = GetManagesupervisionData(); + return View(data); + + } + + [HttpPost] + [Route("/CompetencyAssessments/{competencyAssessmentId}/SupervisionSettings")] + [Route("/CompetencyAssessments/{competencyAssessmentId}/{actionName}/SupervisionSettings")] + public IActionResult ManageSupervisionSettings(ManagesupervisionViewModel viewModel) + { + if (viewModel == null) return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 }); + var data = GetManagesupervisionData(); + if (!ModelState.IsValid) + { + var model = new ManagesupervisionViewModel(data.LearnerDeclaration, data.SupervisorDeclaration, data.Signoff); + return View("ManageSupervisionSettings", model); + } + competencyAssessmentService.UpdateSupervisorRolesTaskStatus(data.Signoff.CompetencyAssessmentId, viewModel.TaskCompleteChecked); + competencyAssessmentService.UpdateSelfAssessments(data.Signoff.CompetencyAssessmentId, + data.Signoff.Supervised, + data.Signoff.Signoff, + data.Signoff.Confirm, + data.SupervisorDeclaration.DeclarationValue, + data.SupervisorDeclaration.CustomText, + data.LearnerDeclaration.DeclarationValue, + data.LearnerDeclaration.CustomText + ); + multiPageFormService.ClearMultiPageFormData(MultiPageFormDataFeature.AddCustomWebForm("ManagesupervisionDataCWF"), TempData); + TempData.Clear(); + return RedirectToAction("ManageCompetencyAssessment", new { competencyAssessmentId = viewModel.CompetencyAssessmentId }); + + } private void SetcompetencyAssessmentFeaturesData(CompetencyAssessmentFeaturesViewModel data) { multiPageFormService.SetMultiPageFormData( @@ -832,5 +1015,21 @@ private CompetencyAssessmentFeaturesViewModel GetcompetencyAssessmentFeaturesDat ).GetAwaiter().GetResult(); return data; } + private void SetManagesupervisionData(ManagesupervisionViewModel data) + { + multiPageFormService.SetMultiPageFormData( + data, + MultiPageFormDataFeature.AddCustomWebForm("ManagesupervisionDataCWF"), + TempData + ); + } + private ManagesupervisionViewModel GetManagesupervisionData() + { + var data = multiPageFormService.GetMultiPageFormData( + MultiPageFormDataFeature.AddCustomWebForm("ManagesupervisionDataCWF"), + TempData + ).GetAwaiter().GetResult(); + return data; + } } } diff --git a/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs b/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs index 05859537e6..79d217a58f 100644 --- a/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs +++ b/DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs @@ -60,6 +60,16 @@ bool UpdateCompetencyAssessmentFeaturesTaskStatus(int id, bool descriptionStatus bool workingGroupStatus, bool AllframeworkCompetenciesStatus); void UpdateSelfAssessmentFromFramework(int selfAssessmentId, int? frameworkId); bool UpdatePrimaryFrameworkCompetencies(int assessmentId, int frameworkId); + bool UpdateSupervisorRolesTaskStatus(int competencyAssessmentId, bool taskCompleteChecked); + bool UpdateSelfAssessments(int competencyAssessmentId, + int? supervised, + int? signoff, + int? confirm, + int? supervisorDeclarationValue, + string? supervisorCustomText, + int? leanerDeclarationValue, + string? leanerCustomText + ); //INSERT DATA int InsertCompetencyAssessment(int adminId, int centreId, string competencyAssessmentName, int? frameworkId); @@ -323,5 +333,23 @@ public void RemoveCollaboratorFromCompetencyAssessment(int competencyAssessmentI return competencyAssessmentDataService.GetCollaboratorNotification(id, invitedByAdminId); } + public bool UpdateSupervisorRolesTaskStatus(int competencyAssessmentId, bool taskCompleteChecked) + { + return competencyAssessmentDataService.UpdateSupervisorRolesTaskStatus(competencyAssessmentId, taskCompleteChecked); + } + public bool UpdateSelfAssessments(int competencyAssessmentId, + int? supervised, + int? signoff, + int? confirm, + int? supervisorDeclarationValue, + string? supervisorCustomText, + int? leanerDeclarationValue, + string? leanerCustomText + ) + { + return competencyAssessmentDataService.UpdateSelfAssessments(competencyAssessmentId, supervised, signoff, confirm, + supervisorDeclarationValue, supervisorCustomText, leanerDeclarationValue, leanerCustomText); + } + } } diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/BaseSignoffDeclarationViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/BaseSignoffDeclarationViewModel.cs new file mode 100644 index 0000000000..b5667f2a04 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/BaseSignoffDeclarationViewModel.cs @@ -0,0 +1,29 @@ +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + public abstract class BaseSignoffDeclarationViewModel + { + protected BaseSignoffDeclarationViewModel() { } + protected BaseSignoffDeclarationViewModel(int id) + { + CompetencyAssessmentId = id; + } + + public int CompetencyAssessmentId { get; set; } + public string CompetencyAssessmentName { get; set; } = string.Empty; + public int? DeclarationValue { get; set; } + public string? ActionName { get; set; } + public string? CustomText { get; set; } + public string? DefaultText { get; set; } + public string? Declaration => DeclarationValue == 1 ? "Custom" : "Default"; + public string? DeclarationText => DeclarationValue == 1 ? CustomText : DefaultText; + protected void CopyProperties(BaseSignoffDeclarationViewModel model) + { + CompetencyAssessmentId = model.CompetencyAssessmentId; + CompetencyAssessmentName = model.CompetencyAssessmentName; + CustomText = model.CustomText; + DefaultText = model.DefaultText.Replace("{{CompetencyAssessmentName}}", model.CompetencyAssessmentName); + DeclarationValue = model.DeclarationValue; + ActionName = model.ActionName; + } + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/LearnerSignoffDeclarationViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/LearnerSignoffDeclarationViewModel.cs new file mode 100644 index 0000000000..acc530ec0f --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/LearnerSignoffDeclarationViewModel.cs @@ -0,0 +1,12 @@ +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + public class LearnerSignoffDeclarationViewModel: BaseSignoffDeclarationViewModel + { + public LearnerSignoffDeclarationViewModel() : base() { } + public LearnerSignoffDeclarationViewModel(int id) : base(id) { } + public LearnerSignoffDeclarationViewModel(LearnerSignoffDeclarationViewModel model) + { + CopyProperties(model); + } + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/ManagesupervisionViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/ManagesupervisionViewModel.cs new file mode 100644 index 0000000000..f718d6dc55 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/ManagesupervisionViewModel.cs @@ -0,0 +1,60 @@ +using System.ComponentModel.DataAnnotations; + +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + public class ManagesupervisionViewModel + { + public ManagesupervisionViewModel() { } + public ManagesupervisionViewModel(SupervisedSelfAssessmentSignoffViewModel signoff) { + Signoff = signoff; + CompetencyAssessmentName = signoff.CompetencyAssessmentName; + } + public ManagesupervisionViewModel(SupervisorSignoffDeclarationViewModel supervisorDeclaration, + SupervisedSelfAssessmentSignoffViewModel signoff) + { + SupervisorDeclaration = supervisorDeclaration; + Signoff = signoff; + } + public ManagesupervisionViewModel(LearnerSignoffDeclarationViewModel learnerDeclaration, + SupervisorSignoffDeclarationViewModel supervisorDeclaration, + SupervisedSelfAssessmentSignoffViewModel signoff) + { + LearnerDeclaration = learnerDeclaration; + SupervisorDeclaration = supervisorDeclaration; + Signoff = signoff; + } + public ManagesupervisionViewModel(int competencyAssessmentId, string competencyAssessmentName, + int supervisorResultsReview, + int SupervisorSelfAssessmentReview, + string? signOffSupervisorStatement, + string? signOffRequestorStatement, + string learnerDefaultText, + string supervisorDefaultText ) + { + CompetencyAssessmentId = competencyAssessmentId; + CompetencyAssessmentName = competencyAssessmentName; + Signoff.CompetencyAssessmentId = competencyAssessmentId; + Signoff.Supervised = supervisorResultsReview; + Signoff.Signoff = supervisorResultsReview; + Signoff.Confirm = SupervisorSelfAssessmentReview; + SupervisorDeclaration.CompetencyAssessmentName = competencyAssessmentName; + SupervisorDeclaration.CompetencyAssessmentId = competencyAssessmentId; + SupervisorDeclaration.DeclarationValue = signOffSupervisorStatement == null ? 0 : 1; + SupervisorDeclaration.CustomText = signOffSupervisorStatement; + SupervisorDeclaration.DefaultText = supervisorDefaultText.Replace("{{CompetencyAssessmentName}}", CompetencyAssessmentName); + LearnerDeclaration.DeclarationValue = signOffRequestorStatement == null ? 0 : 1; + LearnerDeclaration.CustomText = signOffRequestorStatement; + LearnerDeclaration.DefaultText = learnerDefaultText.Replace("{{CompetencyAssessmentName}}", CompetencyAssessmentName); + LearnerDeclaration.CompetencyAssessmentName = competencyAssessmentName; + LearnerDeclaration.CompetencyAssessmentId = competencyAssessmentId; + } + public SupervisedSelfAssessmentSignoffViewModel Signoff { get; set; } = new SupervisedSelfAssessmentSignoffViewModel(); + public SupervisorSignoffDeclarationViewModel SupervisorDeclaration { get; set; } = new SupervisorSignoffDeclarationViewModel(); + public LearnerSignoffDeclarationViewModel LearnerDeclaration { get; set; } = new LearnerSignoffDeclarationViewModel(); + [Required] + [Range(1, 1, ErrorMessage = "Please indicate your confirmation by ticking the checkbox to show that the task has been completed.")] + public bool TaskCompleteChecked { get; set; } + public int CompetencyAssessmentId { get; set; } + public string CompetencyAssessmentName { get; set; } = string.Empty; + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisedSelfAssessmentSignoffViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisedSelfAssessmentSignoffViewModel.cs new file mode 100644 index 0000000000..28aed5e0fb --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisedSelfAssessmentSignoffViewModel.cs @@ -0,0 +1,31 @@ +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + public class SupervisedSelfAssessmentSignoffViewModel + { + public SupervisedSelfAssessmentSignoffViewModel() + { } + public SupervisedSelfAssessmentSignoffViewModel(int id, string competencyAssessmentName, string? actionName) + { + CompetencyAssessmentId = id; + CompetencyAssessmentName = competencyAssessmentName; + this.ActionName = actionName; + } + public SupervisedSelfAssessmentSignoffViewModel(SupervisedSelfAssessmentSignoffViewModel model ) + { + CompetencyAssessmentId = model.CompetencyAssessmentId; + Confirm = model.Confirm; + Supervised = model.Supervised; + Signoff = model.Signoff; + ActionName = model.ActionName; + } + public int CompetencyAssessmentId { get; set; } + public string CompetencyAssessmentName { get; set; } = string.Empty; + public int? Supervised { get; set; } + public int? Signoff { get; set; } + public int? Confirm { get; set; } + public string? ActionName { get; set; } + public string SupervisedText => Supervised == 1 ? "Yes" : "No"; + public string SignoffText => Signoff == 1 ? "Yes" : "No"; + public string ConfirmText => Confirm == 1 ? "Yes" : "No"; + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisorSignoffDeclarationViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisorSignoffDeclarationViewModel.cs new file mode 100644 index 0000000000..7c8961a20c --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SupervisorSignoffDeclarationViewModel.cs @@ -0,0 +1,13 @@ +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +{ + public class SupervisorSignoffDeclarationViewModel: BaseSignoffDeclarationViewModel + { + public SupervisorSignoffDeclarationViewModel() : base() { } + + public SupervisorSignoffDeclarationViewModel(int id) : base(id) { } + public SupervisorSignoffDeclarationViewModel(SupervisorSignoffDeclarationViewModel model) + { + CopyProperties(model); + } + } +} diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/LearnerSignoffDeclaration.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/LearnerSignoffDeclaration.cshtml new file mode 100644 index 0000000000..7fa4984644 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/LearnerSignoffDeclaration.cshtml @@ -0,0 +1,99 @@ +@using DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +@model LearnerSignoffDeclarationViewModel +@{ + var errorHasOccurred = !ViewData.ModelState.IsValid && ViewData.ModelState.ContainsKey(nameof(Model.CustomText)); + ViewData["Title"] = "Learner sign off declaration"; +} + +
+
+ @if (errorHasOccurred) + { + + } +
+
+ +

+ Learner sign off declaration +

+
+ +

+ This will be displayed to the learner is requesting supervisor signing off of their completed self assessment +

+ +
+ +
+ + + +
+
+
+ +
+ @Html.Raw(Model.DefaultText) +
+ +
+
+
+ + +
+ +
+
+ + + + + + + + Enter the declaration text + +
+
+ +
+
+ + + +
+ + + + Back + + +
+
+
+
diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml index 073dfd8d9e..22e38eaaee 100644 --- a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml @@ -5,6 +5,7 @@ ViewData["Application"] = "Framework Service"; } + @section NavMenuItems { } @@ -188,7 +189,7 @@