Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class SelfAssessmentSupervisor
public int? SupervisorAdminID { get; set; }
public string SupervisorName { get; set; }
public string SupervisorEmail { get; set; }
public DateTime NotificationSent { get; set; }
public string RoleName { get; set; }
public bool ReviewResults { get; set; }
public bool SelfAssessmentReview { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ public void SendDelegateSupervisorNominated(int supervisorDelegateId, int selfAs
return;
}
var delegateSelfAssessment = supervisorService.GetSelfAssessmentBySupervisorDelegateSelfAssessmentId(selfAssessmentID,(int)supervisorDelegate.ID);
string emailSubjectLine = "Invite from Supervisor - Digital Learning Solutions";
string emailSubjectLine = $"{delegateSelfAssessment.SupervisorRoleTitle} role request - Digital Learning Solutions";
var builder = new BodyBuilder();
var dlsUrlBuilder = GetDLSUriBuilder();
if (supervisorDelegate.SupervisorAdminID == null)
Expand All @@ -344,6 +344,7 @@ public void SendDelegateSupervisorNominated(int supervisorDelegateId, int selfAs
To supervise this activity, please visit {dlsUrlBuilder.Uri.ToString()} (sign in using your existing DLS credentials).";
builder.HtmlBody = $@"<body style= 'font-family: Calibri; font-size: small;'><p>Dear {supervisorDelegate.SupervisorName},</p><p>You have been identified by <a href='mailto:{supervisorDelegate.DelegateEmail}'>{supervisorDelegate.FirstName} {supervisorDelegate.LastName}</a> as their {delegateSelfAssessment.SupervisorRoleTitle} for the activity '{delegateSelfAssessment.RoleName}' in the NHS Health Education England, Digital Learning Solutions (DLS) platform.</p><p>You are already registered as a delegate at the supervisor's DLS centre. <a href='{dlsUrlBuilder.Uri.ToString()}'>Click here</a> to supervise this activity (sign in using your existing DLS credentials).</p>/body>";
}
supervisorService.UpdateNotificationSent(supervisorDelegateId);
emailService.SendEmail(new Email(emailSubjectLine, builder, supervisorDelegate.DelegateEmail));
}
}
Expand Down
10 changes: 5 additions & 5 deletions DigitalLearningSolutions.Data/Services/SelfAssessmentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ public IEnumerable<LevelDescriptor> GetLevelDescriptorsForAssessmentQuestion(int

public IEnumerable<SelfAssessmentSupervisor> GetSupervisorsForSelfAssessmentId(int selfAssessmentId, int candidateId)
{return connection.Query<SelfAssessmentSupervisor>(
@"SELECT sd.ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, au.Forename + ' ' + au.Surname AS SupervisorName, COALESCE(sasr.RoleName, 'Supervisor') AS RoleName, sasr.SelfAssessmentReview, sasr.ResultsReview, sd.AddedByDelegate, sd.Confirmed
@"SELECT sd.ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, sd.NotificationSent, au.Forename + ' ' + au.Surname AS SupervisorName, COALESCE(sasr.RoleName, 'Supervisor') AS RoleName, sasr.SelfAssessmentReview, sasr.ResultsReview, sd.AddedByDelegate, sd.Confirmed
FROM SupervisorDelegates AS sd INNER JOIN
CandidateAssessmentSupervisors AS cas ON sd.ID = cas.SupervisorDelegateId INNER JOIN
CandidateAssessments AS ca ON cas.CandidateAssessmentID = ca.ID INNER JOIN
Expand All @@ -567,7 +567,7 @@ FROM SupervisorDelegates AS sd INNER JOIN
public IEnumerable<SelfAssessmentSupervisor> GetAllSupervisorsForSelfAssessmentId(int selfAssessmentId, int candidateId)
{
return connection.Query<SelfAssessmentSupervisor>(
@"SELECT cas.ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, COALESCE(au.Forename + ' ' + au.Surname, sd.SupervisorEmail) AS SupervisorName, COALESCE(sasr.RoleName, 'Supervisor') AS RoleName, sasr.SelfAssessmentReview, sasr.ResultsReview, sd.AddedByDelegate, sd.Confirmed
@"SELECT cas.ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, sd.NotificationSent, COALESCE(au.Forename + ' ' + au.Surname, sd.SupervisorEmail) AS SupervisorName, COALESCE(sasr.RoleName, 'Supervisor') AS RoleName, sasr.SelfAssessmentReview, sasr.ResultsReview, sd.AddedByDelegate, sd.Confirmed
FROM SupervisorDelegates AS sd INNER JOIN
CandidateAssessmentSupervisors AS cas ON sd.ID = cas.SupervisorDelegateId INNER JOIN
CandidateAssessments AS ca ON cas.CandidateAssessmentID = ca.ID LEFT OUTER JOIN
Expand All @@ -579,20 +579,20 @@ FROM SupervisorDelegates AS sd INNER JOIN
public IEnumerable<SelfAssessmentSupervisor> GetOtherSupervisorsForCandidate(int selfAssessmentId, int candidateId)
{
return connection.Query<SelfAssessmentSupervisor>(
@"SELECT 0 AS ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, au.Forename + ' ' + au.Surname AS SupervisorName, 'Supervisor' AS RoleName
@"SELECT 0 AS ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, sd.NotificationSent, au.Forename + ' ' + au.Surname AS SupervisorName, 'Supervisor' AS RoleName
FROM SupervisorDelegates AS sd INNER JOIN
CandidateAssessmentSupervisors AS cas ON sd.ID = cas.SupervisorDelegateId INNER JOIN
CandidateAssessments AS ca ON cas.CandidateAssessmentID = ca.ID INNER JOIN
AdminUsers AS au ON sd.SupervisorAdminID = au.AdminID
WHERE (sd.Removed IS NULL) AND (sd.SupervisorAdminID IS NOT NULL) AND (sd.Confirmed IS NOT NULL) AND (sd.CandidateID = @candidateId)
EXCEPT
SELECT 0 AS ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, au.Forename + ' ' + au.Surname AS SupervisorName, 'Supervisor' AS RoleName
SELECT 0 AS ID, sd.ID AS SupervisorDelegateID, sd.SupervisorAdminID, sd.SupervisorEmail, sd.NotificationSent, au.Forename + ' ' + au.Surname AS SupervisorName, 'Supervisor' AS RoleName
FROM SupervisorDelegates AS sd INNER JOIN
CandidateAssessmentSupervisors AS cas ON sd.ID = cas.SupervisorDelegateId INNER JOIN
CandidateAssessments AS ca ON cas.CandidateAssessmentID = ca.ID INNER JOIN
AdminUsers AS au ON sd.SupervisorAdminID = au.AdminID
WHERE (sd.Removed IS NULL) AND (sd.Confirmed IS NOT NULL) AND (sd.CandidateID = @candidateId) AND (ca.SelfAssessmentID = @selfAssessmentId)
GROUP BY sd.ID, SupervisorAdminID, SupervisorEmail, au.Forename + ' ' + au.Surname", new { selfAssessmentId, candidateId }
GROUP BY sd.ID, SupervisorAdminID, SupervisorEmail, sd.NotificationSent, au.Forename + ' ' + au.Surname", new { selfAssessmentId, candidateId }
);
}
}
Expand Down
41 changes: 39 additions & 2 deletions DigitalLearningSolutions.Data/Services/SupervisorService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ public interface ISupervisorService
bool RemoveSupervisorDelegateById(int supervisorDelegateId, int candidateId, int adminId);
bool UpdateSelfAssessmentResultSupervisorVerifications(int selfAssessmentResultSupervisorVerificationId, string? comments, bool signedOff, int adminId);
bool RemoveCandidateAssessment(int candidateAssessmentId);
void UpdateNotificationSent(int supervisorDelegateId);
//INSERT DATA
int AddSuperviseDelegate(int? supervisorAdminId, int? delegateId, string delegateEmail, string supervisorEmail, int centreId);
int EnrolDelegateOnAssessment(int delegateId, int supervisorDelegateId, int selfAssessmentId, DateTime? completeByDate, int? selfAssessmentSupervisorRoleId, int adminId);
int InsertCandidateAssessmentSupervisor(int delegateId, int supervisorDelegateId, int selfAssessmentId, int? selfAssessmentSupervisorRoleId);
//DELETE DATA


bool RemoveCandidateAssessmentSupervisor(int candidateAssessmentSupervisorId);
}
public class SupervisorService : ISupervisorService
{
Expand Down Expand Up @@ -142,6 +142,10 @@ FROM SupervisorDelegates
@"SELECT AdminID FROM AdminUsers WHERE Email = @supervisorEmail AND Active = 1 AND CentreID = @centreId", new { supervisorEmail, centreId }
);
}
if (supervisorAdminId != null)
{
connection.Execute("@UPDATE AdminUsers SET Supervisor = 1 WHERE Admin ID = @supervisorAdminId AND Supervisor = 0");
}
var numberOfAffectedRows = connection.Execute(
@"INSERT INTO SupervisorDelegates (SupervisorAdminID, DelegateEmail, CandidateID, SupervisorEmail, AddedByDelegate)
VALUES (@supervisorAdminId, @delegateEmail, @delegateId, @supervisorEmail, @addedByDelegate)",
Expand Down Expand Up @@ -451,5 +455,38 @@ public bool RemoveCandidateAssessment(int candidateAssessmentId)
}
return true;
}

public bool RemoveCandidateAssessmentSupervisor(int candidateAssessmentSupervisorId)
{
var supervisorDelegateId = (int)connection.ExecuteScalar(
@"SELECT SupervisorDelegateId
FROM CandidateAssessmentSupervisors
WHERE (ID = @candidateAssessmentSupervisorId)",
new { candidateAssessmentSupervisorId });
var numberOfAffectedRows = connection.Execute(
@"DELETE CandidateAssessmentSupervisors
WHERE ID = @candidateAssessmentSupervisorId",
new { candidateAssessmentSupervisorId });
if (numberOfAffectedRows < 1)
{
logger.LogWarning(
$"Not removing Candidate Assessment Supervisor as db update failed. candidateAssessmentSupervisorId: {candidateAssessmentSupervisorId}"
);
return false;
}
connection.Execute(
@"UPDATE SupervisorDelegates SET Removed = getUTCDate()
WHERE ID = @supervisorDelegateId AND (SELECT COUNT(*) FROM CandidateAssessmentSupervisors WHERE SupervisorDelegateId = @supervisorDelegateId) = 0",
new { supervisorDelegateId });
return true;
}

public void UpdateNotificationSent(int supervisorDelegateId)
{
connection.Execute(
@"UPDATE SupervisorDelegates SET NotificationSent = getUTCDate()
WHERE ID = @supervisorDelegateId",
new { supervisorDelegateId });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -364,5 +364,27 @@ public IActionResult SubmitSummary()
frameworkNotificationService.SendDelegateSupervisorNominated(supervisorDelegateId, sessionAddSupervisor.SelfAssessmentID);
return RedirectToAction("ManageSupervisors", new { sessionAddSupervisor.SelfAssessmentID });
}
public IActionResult RemoveSupervisor(int selfAssessmentId, int candidateAssessmentSupervisorId)
{
supervisorService.RemoveCandidateAssessmentSupervisor(candidateAssessmentSupervisorId);
return RedirectToAction("ManageSupervisors", new { selfAssessmentId });
}
public IActionResult SendSupervisorReminder(int selfAssessmentId, int supervisorDelegateId)
{
frameworkNotificationService.SendDelegateSupervisorNominated(supervisorDelegateId, selfAssessmentId);
return RedirectToAction("ManageSupervisors", new { selfAssessmentId });
}
public IActionResult ConfirmSupervisor(int supervisorDelegateId, int selfAssessmentId)
{
supervisorService.ConfirmSupervisorDelegateById(supervisorDelegateId, GetCandidateId(), 0);
frameworkNotificationService.SendSupervisorDelegateConfirmed(supervisorDelegateId);
return RedirectToAction("ManageSupervisors", new { selfAssessmentId });
}
public IActionResult RejectSupervisor(int supervisorDelegateId, int selfAssessmentId)
{
supervisorService.RemoveSupervisorDelegateById(supervisorDelegateId, GetCandidateId(), 0);
frameworkNotificationService.SendSupervisorDelegateRejected(supervisorDelegateId);
return RedirectToAction("ManageSupervisors", new { selfAssessmentId });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class SetSupervisorRoleViewModel
[EmailAddress(ErrorMessage = "Enter a supervisor email address in the correct format, like name@example.com")]
[NoWhitespace("Supervisor email address must not contain any whitespace characters")]
public string SupervisorEmail { get; set; }
[Range(1, int.MaxValue, ErrorMessage = "Please choose a supervisor role")]
public int SelfAssessmentSupervisorRoleId { get; set; }
public IEnumerable<SelfAssessmentSupervisorRole>? SelfAssessmentSupervisorRoles { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,36 @@
<li class="nhsuk-breadcrumb__item">Add</li>
}
<link rel="stylesheet" href="@Url.Content("~/css/learningPortal/selfAssessment.css")" asp-append-version="true">
<h1>New activity supervisor</h1>
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-full">
<form method="post">
@if (errorHasOccurred)
{
<vc:error-summary order-of-property-names="@(new[] {nameof(Model.SupervisorEmail) })" />
}
<label class="nhsuk-label nhsuk-u-margin-top-6" for="add-user-hint">
<h1>Add supervisor</h1>
</label>
<div class="nhsuk-form-group">
<input type="hidden" asp-for="SelfAssessmentID" value="@Model.SelfAssessmentID" />
<input type="hidden" asp-for="SelfAssessmentName" value="@Model.SelfAssessmentName" />
<vc:text-input asp-for="SupervisorEmail"
label="Supervisor email"
populate-with-current-value="true"
type="text"
spell-check="false"
hint-text="Enter the work email address of your supervisor."
autocomplete="email"
css-class="nhsuk-u-width-one-half" />
</div>
<button class="nhsuk-button" type="submit">
Next
</button>
<fieldset class="nhsuk-fieldset">
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
<span class="nhsuk-fieldset__heading">
Add a supervisor
</span>
</legend>
<nhs-form-group nhs-validation-for="SelfAssessmentName">
<input type="hidden" asp-for="SelfAssessmentID" value="@Model.SelfAssessmentID" />
<input type="hidden" asp-for="SelfAssessmentName" value="@Model.SelfAssessmentName" />
<vc:text-input asp-for="SupervisorEmail"
label="Supervisor email"
populate-with-current-value="true"
type="text"
spell-check="false"
hint-text="Enter the work email address of your supervisor."
autocomplete="email"
css-class="nhsuk-u-width-one-half" />
</nhs-form-group>
</fieldset>
<button class="nhsuk-button" type="submit">
Next
</button>
</form>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,17 @@
}
else if (supervisor.Confirmed == null)
{
<a asp-action="ConfirmSupervisor" asp-route-supervisorDelegateId="@supervisor.ID">Confirm</a> <a asp-action="RejectSupervisor" asp-route-supervisorDelegateId="@supervisor.ID">Reject</a>
}
else
{
<a asp-action="RequestRemoveSupervisor" asp-route-supervisorDelegateId="@supervisor.ID">Request removal <span class="nhsuk-u-visually-hidden">of supervisor</span></a>
<a asp-action="ConfirmSupervisor" asp-route-supervisorDelegateId="@supervisor.SupervisorDelegateID">Confirm</a> <a asp-action="RejectSupervisor" asp-route-supervisorDelegateId="@supervisor.SupervisorDelegateID">Reject</a>
}
@if (supervisor.SupervisorAdminID == null)
{
<a asp-action="SendSupervisorReminder" asp-route-supervisorDelegateId="@supervisor.ID">Send reminder</a>
}
@if (supervisor.NotificationSent.ToShortDateString() != DateTime.UtcNow.ToShortDateString())
{
<a asp-action="SendSupervisorReminder" asp-route-selfAssessmentId="@Model.SelfAssessment.Id" asp-route-supervisorDelegateId="@supervisor.SupervisorDelegateID">Send reminder</a>
}
}

</td>
</td>
</tr>
}
</tbody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@
Supervisor Role
</h1>
<form method="post">
<div class="nhsuk-form-group">
@if (errorHasOccurred)
{
<vc:error-summary order-of-property-names="@(new[] {nameof(Model.SelfAssessmentSupervisorRoleId) })" />
}
<nhs-form-group nhs-validation-for="SelfAssessmentSupervisorRoleId">

<fieldset class="nhsuk-fieldset">
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
<span class="nhsuk-fieldset__heading">
Choose a role for this supervisor
</span>
</legend>
<input type="hidden" asp-for="SelfAssessmentID" value="@Model.SelfAssessmentID" />
<input type="hidden" asp-for="SelfAssessmentName" value="@Model.SelfAssessmentName" />
<input type="hidden" asp-for="SupervisorEmail" value="@Model.SupervisorEmail" />
<div class="nhsuk-radios">
@foreach (var role in Model.SelfAssessmentSupervisorRoles)
{
<fieldset class="nhsuk-fieldset">
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
<span class="nhsuk-fieldset__heading">
Choose a role for this supervisor
</span>
</legend>
<input type="hidden" asp-for="SelfAssessmentID" value="@Model.SelfAssessmentID" />
<input type="hidden" asp-for="SelfAssessmentName" value="@Model.SelfAssessmentName" />
<input type="hidden" asp-for="SupervisorEmail" value="@Model.SupervisorEmail" />
<div class="nhsuk-radios">
@foreach (var role in Model.SelfAssessmentSupervisorRoles)
{
<div class="nhsuk-radios__item">
<input class="nhsuk-radios__input" id="role-@role.ID" checked="@(Model.SelfAssessmentSupervisorRoleId == role.ID)" name="SelfAssessmentSupervisorRoleId" asp-for="SelfAssessmentSupervisorRoleId" type="radio" value="@role.ID">
<label class="nhsuk-label nhsuk-radios__label" for="role-@role.ID">
Expand All @@ -41,17 +45,18 @@
</div>
}
</div>
}
}

</div>
</fieldset>
<div class=" nhsuk-u-margin-top-5">
<a class="nhsuk-button nhsuk-button--secondary" asp-action="AddNewSupervisor" asp-route-selfAssessmentId="@Model.SelfAssessmentID" asp-route-supervisorEmail="@Model.SupervisorEmail">
Back
</a>
<button class="nhsuk-button" id="save-button" type="submit">Next</button>
</div>
</fieldset>
</nhs-form-group>
<div class=" nhsuk-u-margin-top-5">
<a class="nhsuk-button nhsuk-button--secondary" asp-action="AddNewSupervisor" asp-route-selfAssessmentId="@Model.SelfAssessmentID" asp-route-supervisorEmail="@Model.SupervisorEmail">
Back
</a>
<button class="nhsuk-button" id="save-button" type="submit">Next</button>
</div>

</form>
<div class="nhsuk-back-link">
<a class="nhsuk-back-link__link"
Expand Down