diff --git a/DigitalLearningSolutions.Data/Services/FrameworkNotificationService.cs b/DigitalLearningSolutions.Data/Services/FrameworkNotificationService.cs index eb230772b9..511dfcbb99 100644 --- a/DigitalLearningSolutions.Data/Services/FrameworkNotificationService.cs +++ b/DigitalLearningSolutions.Data/Services/FrameworkNotificationService.cs @@ -20,6 +20,7 @@ public interface IFrameworkNotificationService void SendSupervisorResultReviewed(int adminId, int supervisorDelegateId, int candidateAssessmentId, int resultId); void SendSupervisorEnroledDelegate(int adminId, int supervisorDelegateId, int candidateAssessmentId, DateTime? completeByDate); void SendReminderDelegateSelfAssessment(int adminId, int supervisorDelegateId, int candidateAssessmentId); + void SendSupervisorMultipleResultsReviewed(int adminId, int supervisorDelegateId, int candidateAssessmentId, int countResults); } public class FrameworkNotificationService : IFrameworkNotificationService { @@ -291,5 +292,19 @@ public void SendReminderDelegateSelfAssessment(int adminId, int supervisorDelega builder.HtmlBody = $@"

Dear {supervisorDelegate.FirstName}

This is a reminder sent by your {delegateSelfAssessment.RoleName}, {supervisorDelegate.SupervisorName}, to complete the profile assessment '{delegateSelfAssessment.RoleName}' in the NHS Health Education England, Digital Learning Solutions platform.

Click here to access your {delegateSelfAssessment.RoleName} profile assessment.

"; emailService.SendEmail(new Email(emailSubjectLine, builder, supervisorDelegate.DelegateEmail)); } + + public void SendSupervisorMultipleResultsReviewed(int adminId, int supervisorDelegateId, int candidateAssessmentId, int countResults) + { + var supervisorDelegate = supervisorService.GetSupervisorDelegateDetailsById(supervisorDelegateId); + var delegateSelfAssessment = supervisorService.GetSelfAssessmentBaseByCandidateAssessmentId(candidateAssessmentId); + var selfAssessmentUrl = GetSelfAssessmentUrl(delegateSelfAssessment.SelfAssessmentID); + string emailSubjectLine = $"{delegateSelfAssessment.SupervisorRoleTitle} Signed-off {countResults} results - Digital Learning Solutions"; + var builder = new BodyBuilder(); + builder.TextBody = $@"Dear {supervisorDelegate.FirstName}, + {supervisorDelegate.SupervisorName} has signed-off {countResults} of your self assessment results against the {delegateSelfAssessment.RoleName} profile assessment in the NHS Health Education England, Digital Learning Solutions platform. + To access your {delegateSelfAssessment.RoleName} profile assessment, please visit {selfAssessmentUrl}."; + builder.HtmlBody = $@"

Dear {supervisorDelegate.FirstName}

{supervisorDelegate.SupervisorName} has signed-off {countResults} of your self assessment results against the {delegateSelfAssessment.RoleName} profile assessment in the NHS Health Education England, Digital Learning Solutions platform.

Click here to access your {delegateSelfAssessment.RoleName} profile assessment.

"; + emailService.SendEmail(new Email(emailSubjectLine, builder, supervisorDelegate.DelegateEmail)); + } } } diff --git a/DigitalLearningSolutions.Data/Services/SelfAssessmentService.cs b/DigitalLearningSolutions.Data/Services/SelfAssessmentService.cs index d3f97a5f3a..0e1268e44f 100644 --- a/DigitalLearningSolutions.Data/Services/SelfAssessmentService.cs +++ b/DigitalLearningSolutions.Data/Services/SelfAssessmentService.cs @@ -19,6 +19,7 @@ public interface ISelfAssessmentService void SetResultForCompetency(int competencyId, int selfAssessmentId, int candidateId, int assessmentQuestionId, int result, string? supportingComments); IEnumerable GetMostRecentResults(int selfAssessmentId, int candidateId); IEnumerable GetCandidateAssessmentResultsById(int candidateAssessmentId, int adminId); + IEnumerable GetCandidateAssessmentResultsForReviewById(int candidateAssessmentId, int adminId); Competency GetCompetencyByCandidateAssessmentResultId(int resultId, int candidateAssessmentId, int adminId); void UpdateLastAccessed(int selfAssessmentId, int candidateId); void SetSubmittedDateNow(int selfAssessmentId, int candidateId); @@ -340,6 +341,27 @@ public IEnumerable GetCandidateAssessmentResultsById(int candidateAs return groupedCompetency; }); } + public IEnumerable GetCandidateAssessmentResultsForReviewById(int candidateAssessmentId, int adminId) + { + var result = connection.Query( + $@"WITH {SpecificAssessmentResults} + SELECT {CompetencyFields} + FROM {SpecificCompetencyTables} + WHERE (LAR.Requested IS NOT NULL) AND (LAR.Verified IS NULL) AND (LAR.UserIsVerifier = 1)", + (competency, assessmentQuestion) => + { + competency.AssessmentQuestions.Add(assessmentQuestion); + return competency; + }, + param: new { candidateAssessmentId, adminId } + ); + return result.GroupBy(competency => competency.Id).Select(group => + { + var groupedCompetency = group.First(); + groupedCompetency.AssessmentQuestions = group.Select(competency => competency.AssessmentQuestions.Single()).ToList(); + return groupedCompetency; + }); + } public void UpdateLastAccessed(int selfAssessmentId, int candidateId) { diff --git a/DigitalLearningSolutions.Data/Services/SupervisorService.cs b/DigitalLearningSolutions.Data/Services/SupervisorService.cs index 51a4ff049f..1c175d99cd 100644 --- a/DigitalLearningSolutions.Data/Services/SupervisorService.cs +++ b/DigitalLearningSolutions.Data/Services/SupervisorService.cs @@ -414,7 +414,7 @@ FROM CandidateAssessments public bool RemoveCandidateAssessment(int candidateAssessmentId) { var numberOfAffectedRows = connection.Execute( - @"UPDATE CandidateAssessments SET RemovedDate = getUTCDate(), RemovalMethodID = 2, + @"UPDATE CandidateAssessments SET RemovedDate = getUTCDate(), RemovalMethodID = 2 WHERE ID = @candidateAssessmentId AND RemovedDate IS NULL", new { candidateAssessmentId }); if (numberOfAffectedRows < 1) diff --git a/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs b/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs index 447066ec45..0a11f349ab 100644 --- a/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs +++ b/DigitalLearningSolutions.Web/Controllers/SupervisorController/Supervisor.cs @@ -189,7 +189,39 @@ public IActionResult SubmitReviewCompetencySelfAssessment(int supervisorDelegate }; return RedirectToAction("ReviewCompetencySelfAssessment", "Supervisor", new { supervisorDelegateId = supervisorDelegateId, candidateAssessmentId = candidateAssessmentId, viewMode = "View", resultId = resultId }); } - public IActionResult StartEnrolDelegateOnProfileAssessment(int supervisorDelegateId) + [Route("/Supervisor/Staff/{supervisorDelegateId}/ProfileAssessment/{candidateAssessmentId}/VerifyMultiple/")] + public IActionResult VerifyMultipleResults(int supervisorDelegateId, int candidateAssessmentId) + { + var adminId = GetAdminID(); + var superviseDelegate = supervisorService.GetSupervisorDelegateDetailsById(supervisorDelegateId); + var delegateSelfAssessment = supervisorService.GetSelfAssessmentBaseByCandidateAssessmentId(candidateAssessmentId); + var reviewedCompetencies = selfAssessmentService.GetCandidateAssessmentResultsForReviewById(candidateAssessmentId, adminId).ToList(); + var model = new ReviewSelfAssessmentViewModel() + { + SupervisorDelegateDetail = superviseDelegate, + DelegateSelfAssessment = delegateSelfAssessment, + CompetencyGroups = reviewedCompetencies.GroupBy(competency => competency.CompetencyGroup) + }; + return View("VerifyMultipleResults", model); + } + [HttpPost] + [Route("/Supervisor/Staff/{supervisorDelegateId}/ProfileAssessment/{candidateAssessmentId}/VerifyMultiple/")] + public IActionResult SubmitVerifyMultipleResults(int supervisorDelegateId, int candidateAssessmentId, List resultChecked) + { + int countResults = 0; + foreach (var result in resultChecked) + { + if (supervisorService.UpdateSelfAssessmentResultSupervisorVerifications(result, null, true, GetAdminID())) + { countResults += 1; } + } + if (countResults > 0) + { + //Send notification + frameworkNotificationService.SendSupervisorMultipleResultsReviewed(GetAdminID(), supervisorDelegateId, candidateAssessmentId, countResults); + } + return RedirectToAction("ReviewDelegateSelfAssessment", "Supervisor", new { supervisorDelegateId = supervisorDelegateId, candidateAssessmentId = candidateAssessmentId, viewMode = "Review" }); + } + public IActionResult StartEnrolDelegateOnProfileAssessment(int supervisorDelegateId) { TempData.Clear(); var sessionEnrolOnRoleProfile = new SessionEnrolOnRoleProfile(); diff --git a/DigitalLearningSolutions.Web/Views/Supervisor/EnrolDelegateSummary.cshtml b/DigitalLearningSolutions.Web/Views/Supervisor/EnrolDelegateSummary.cshtml index 9fc9fb2058..1418c50b72 100644 --- a/DigitalLearningSolutions.Web/Views/Supervisor/EnrolDelegateSummary.cshtml +++ b/DigitalLearningSolutions.Web/Views/Supervisor/EnrolDelegateSummary.cshtml @@ -38,7 +38,7 @@ -

Summary

+

Enrolment Summary

diff --git a/DigitalLearningSolutions.Web/Views/Supervisor/ReviewCompetencySelfAsessment.cshtml b/DigitalLearningSolutions.Web/Views/Supervisor/ReviewCompetencySelfAsessment.cshtml index bd8ca580ac..197be0780d 100644 --- a/DigitalLearningSolutions.Web/Views/Supervisor/ReviewCompetencySelfAsessment.cshtml +++ b/DigitalLearningSolutions.Web/Views/Supervisor/ReviewCompetencySelfAsessment.cshtml @@ -46,7 +46,7 @@
-

Self Assessment Outcome

+

@Model.Competency.Vocabulary Self Assessment Result

@@ -134,7 +134,7 @@

- Review Self Assessment Outcome + Review @Model.Competency.Vocabulary Self Assessment Result

@@ -146,7 +146,7 @@
I agree with @Model.SupervisorDelegate.FirstName @Model.SupervisorDelegate.LastName's self-assessment against this @Model.Competency.Vocabulary.ToLower() diff --git a/DigitalLearningSolutions.Web/Views/Supervisor/ReviewSelfAssessment.cshtml b/DigitalLearningSolutions.Web/Views/Supervisor/ReviewSelfAssessment.cshtml index 938185b4be..d250435b53 100644 --- a/DigitalLearningSolutions.Web/Views/Supervisor/ReviewSelfAssessment.cshtml +++ b/DigitalLearningSolutions.Web/Views/Supervisor/ReviewSelfAssessment.cshtml @@ -37,7 +37,21 @@
-

@Model.DelegateSelfAssessment.RoleName

+
+
+

@Model.DelegateSelfAssessment.RoleName

+
+
+ @if (Model.DelegateSelfAssessment.VerificationRequested > 0) + { + Review profile assessment + } + @if (Model.DelegateSelfAssessment.ResultsVerificationRequests > 1) + { + Verify multiple results + } +
+
@if (Model.CompetencyGroups.Any()) { foreach (var competencyGroup in Model.CompetencyGroups) diff --git a/DigitalLearningSolutions.Web/Views/Supervisor/Shared/_AssessmentQuestionCells.cshtml b/DigitalLearningSolutions.Web/Views/Supervisor/Shared/_AssessmentQuestionCells.cshtml new file mode 100644 index 0000000000..af5ac37dac --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/Supervisor/Shared/_AssessmentQuestionCells.cshtml @@ -0,0 +1,15 @@ +@using DigitalLearningSolutions.Data.Models.SelfAssessments; +@model AssessmentQuestion + + + Questions + + + @Model.Question + + + + + Responses + + diff --git a/DigitalLearningSolutions.Web/Views/Supervisor/Shared/_AssessmentQuestionReviewCells.cshtml b/DigitalLearningSolutions.Web/Views/Supervisor/Shared/_AssessmentQuestionReviewCells.cshtml index b7d4a62f64..16020f7e4b 100644 --- a/DigitalLearningSolutions.Web/Views/Supervisor/Shared/_AssessmentQuestionReviewCells.cshtml +++ b/DigitalLearningSolutions.Web/Views/Supervisor/Shared/_AssessmentQuestionReviewCells.cshtml @@ -2,18 +2,7 @@ @model AssessmentQuestion - - Questions - - - @Model.Question - - - - - Responses - - + Questions diff --git a/DigitalLearningSolutions.Web/Views/Supervisor/VerifyMultipleResults.cshtml b/DigitalLearningSolutions.Web/Views/Supervisor/VerifyMultipleResults.cshtml new file mode 100644 index 0000000000..6f6eabc2c3 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/Supervisor/VerifyMultipleResults.cshtml @@ -0,0 +1,104 @@ +@using DigitalLearningSolutions.Web.ViewModels.Supervisor; +@model ReviewSelfAssessmentViewModel; +@{ + ViewData["Title"] = "Review Self Assessment"; + ViewData["Application"] = "Supervisor"; +} + + +@section NavMenuItems { + +} +@section NavBreadcrumbs { + +} +
+ +

+ @Model.SupervisorDelegateDetail.FirstName @Model.SupervisorDelegateDetail.LastName +

+
+
+ +
+
+

Sign-off Multiple Results for @Model.DelegateSelfAssessment.RoleName

+@if (Model.CompetencyGroups.Any()) +{ +

Tick each self assessment result that you wish to verify and sign-off and then click Submit

+
+ @foreach (var competencyGroup in Model.CompetencyGroups) + { + + + + + + + + + + + @foreach (var competency in competencyGroup) + { + @foreach (var question in competency.AssessmentQuestions) + { + + + + + + } + } + +

@competencyGroup.Key

+ @competencyGroup.First().Vocabulary + + Question + + Response +
+ @competency.Vocabulary +
+ + +
+
+ } +
+
+ + Cancel +
+
+
+} +else +{ +

+ Oops. There are no results awaiting sign-off. +

+ Cancel +}