Skip to content
Open
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
110 changes: 78 additions & 32 deletions DigitalLearningSolutions.Data/DataServices/SupervisorDataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ public interface ISupervisorDataService
IEnumerable<CandidateAssessmentSupervisorVerificationSummary> GetCandidateAssessmentSupervisorVerificationSummaries(int candidateAssessmentId);
IEnumerable<SupervisorForEnrolDelegate> GetSupervisorForEnrolDelegate(int CentreID, int CategoryID);
IEnumerable<SupervisorDelegateDetail> GetSupervisorDelegateDetailsForAdminIdWithoutRemovedClause(int adminId);
SupervisorDelegateDetail GetSupervisorDelegateDetailsByIdWithoutRemoveClause(int supervisorDelegateId, int adminId, int delegateUserId);
SupervisorDelegateDetail GetSupervisorDelegateDetailsByIdWithoutRemoveClause(int supervisorDelegateId, int adminId, int delegateUserId);
List<int> GetCandidateAssessmentSupervisorVerifications(int supervisorDelegateId);
List<int> GetSelfAssessmentResultSupervisorVerifications(int supervisorDelegateId, int selfAssessmentId);

//UPDATE DATA
bool ConfirmSupervisorDelegateById(int supervisorDelegateId, int candidateId, int adminId);
bool RemoveSupervisorDelegateById(int supervisorDelegateId, int delegateUserId, int adminId);
Expand All @@ -46,7 +49,10 @@ public interface ISupervisorDataService
int RemoveSelfAssessmentResultSupervisorVerificationById(int id);
bool RemoveCandidateAssessment(int candidateAssessmentId);
void UpdateNotificationSent(int supervisorDelegateId);
void UpdateCandidateAssessmentSupervisorVerificationById(int? candidateAssessmentSupervisorVerificationId, string? supervisorComments, bool signedOff);
void UpdateCandidateAssessmentSupervisorVerificationById(int? candidateAssessmentSupervisorVerificationId, string? supervisorComments, bool signedOff);


bool UpdateCandidateAssessmentSupervisorRoleByIds(int candidateAssessmentId, int supervisorDelegateId, int selfAssessmentSupervisorRoleId);
//INSERT DATA
int AddSuperviseDelegate(int? supervisorAdminId, int? delegateUserId, string delegateEmail, string supervisorEmail, int centreId);
int EnrolDelegateOnAssessment(int delegateUserId, int supervisorDelegateId, int selfAssessmentId, DateTime? completeByDate, int? selfAssessmentSupervisorRoleId, int adminId, int centreId, bool isLoggedInUser);
Expand Down Expand Up @@ -105,7 +111,7 @@ INNER JOIN AdminAccounts AS aa
INNER JOIN Users AS au ON aa.UserID = au.ID
";

private const string delegateSelfAssessmentFields = "ca.ID, sa.ID AS SelfAssessmentID, sa.Name AS RoleName, sa.SupervisorSelfAssessmentReview, sa.SupervisorResultsReview, COALESCE (sasr.RoleName, 'Supervisor') AS SupervisorRoleTitle, ca.StartedDate";
private const string delegateSelfAssessmentFields = "ca.ID, sa.ID AS SelfAssessmentID, sa.Name AS RoleName, sa.SupervisorSelfAssessmentReview, sa.SupervisorResultsReview, ca.StartedDate, sasr.AllowSupervisorRoleSelection";
private const string signedOffFields = @"(SELECT TOP (1) casv.Verified
FROM CandidateAssessmentSupervisorVerifications AS casv INNER JOIN
CandidateAssessmentSupervisors AS cas ON casv.CandidateAssessmentSupervisorID = cas.ID
Expand All @@ -116,6 +122,13 @@ FROM CandidateAssessmentSupervisorVerifications AS casv INNER JOIN
CandidateAssessmentSupervisors AS cas ON casv.CandidateAssessmentSupervisorID = cas.ID
WHERE(cas.CandidateAssessmentID = ca.ID) AND(casv.Requested IS NOT NULL) AND(casv.Verified IS NOT NULL)
ORDER BY casv.Requested DESC) AS SignedOff,";

// adding new property select subqueries to the existing delegateSelfAssessmentFields for the changeRole functionality
private const string rolecount = @"(SELECT COUNT(*) as RoleCount From SelfAssessmentSupervisorRoles AS sasr where sa.ID = sasr.SelfAssessmentID ) as RoleCount,";

// adding new property select subqueries to the existing delegateSelfAssessmentFields for the changeRole functionality
private const string supervisorRoleTitle = @"(SELECT SASR.RoleName FROM SelfAssessmentSupervisorRoles AS sasr Where sasr.id = cas.SelfAssessmentSupervisorRoleID),";


public SupervisorDataService(IDbConnection connection, ILogger<SupervisorDataService> logger)
{
Expand Down Expand Up @@ -587,6 +600,8 @@ public IEnumerable<DelegateSelfAssessment> GetSelfAssessmentsForSupervisorDelega
(SELECT COUNT(*) AS Expr1
FROM CandidateAssessmentSupervisorVerifications AS casv
WHERE (CandidateAssessmentSupervisorID = cas.ID) AND (Requested IS NOT NULL) AND (Verified IS NULL)) AS SignOffRequested,
{rolecount}
{supervisorRoleTitle}
{signedOffFields}
(SELECT COUNT(*) AS Expr1
FROM SelfAssessmentResultSupervisorVerifications AS sarsv
Expand Down Expand Up @@ -1059,9 +1074,9 @@ public bool RemoveCandidateAssessmentSupervisor(int selfAssessmentId, int superv
AND cas.Removed IS NULL AND sarsv.Verified IS NULL
AND sa.ID = @selfAssessmentId", new { supervisorDelegateId, selfAssessmentId }
);

var deletedCandidateAssessmentSupervisors = connection.Execute(
@"DELETE FROM cas
connection.Execute(
@"DELETE FROM casv
FROM CandidateAssessmentSupervisors AS cas
INNER JOIN CandidateAssessments AS ca ON cas.CandidateAssessmentID = ca.ID
LEFT JOIN CandidateAssessmentSupervisorVerifications AS casv ON cas.ID = casv.CandidateAssessmentSupervisorID
Expand All @@ -1070,36 +1085,17 @@ FROM CandidateAssessmentSupervisors AS cas
AND (cas.Removed IS NULL)
AND (casv.ID IS NULL)
AND (sarsr.ID IS NULL)",
new { selfAssessmentId, supervisorDelegateId });
if (deletedCandidateAssessmentSupervisors < 1)
{
deletedCandidateAssessmentSupervisors = connection.Execute(
new { selfAssessmentId, supervisorDelegateId });

connection.Execute(
@"UPDATE cas SET Removed = getUTCDate()
FROM CandidateAssessmentSupervisors AS cas
INNER JOIN CandidateAssessments AS ca ON cas.CandidateAssessmentID = ca.ID
WHERE (ca.SelfAssessmentID = @selfAssessmentId) AND (cas.SupervisorDelegateId = @supervisorDelegateId)",
new { selfAssessmentId, supervisorDelegateId });
}

if (deletedCandidateAssessmentSupervisors >= 1)
{
connection.Execute(
@"UPDATE SupervisorDelegates SET Removed = getUTCDate()
WHERE ID = @supervisorDelegateId AND NOT EXISTS(
SELECT *
FROM CandidateAssessmentSupervisors
WHERE (SupervisorDelegateId = @supervisorDelegateId) AND (Removed IS NULL))",
new { supervisorDelegateId });
}

if (deletedCandidateAssessmentSupervisors < 1)
{
logger.LogWarning(
$"Not removing Candidate Assessment Supervisor as db update failed. selfAssessmentId: {selfAssessmentId}, supervisorDelegateId: {supervisorDelegateId}"
);
return false;
}

new { selfAssessmentId, supervisorDelegateId });



return true;
}

Expand Down Expand Up @@ -1366,6 +1362,56 @@ FROM CandidateAssessments AS CA
INNER JOIN SupervisorDelegates AS SD ON SD.ID = CAS.SupervisorDelegateId
INNER JOIN AdminAccounts AS AA ON AA.ID = SD.SupervisorAdminID AND AA.UserID = SD.DelegateUserID
WHERE CA.ID = @candidateAssessmentId AND NonReportable = 0 ", new { candidateAssessmentId });
}

public List<int> GetSelfAssessmentResultSupervisorVerifications(int supervisorDelegateId, int selfAssessmentId)
{
var verificationIds = new List<int>();
verificationIds = connection.Query<int>(
$@"SELECT sarsv.ID FROM SelfAssessmentResultSupervisorVerifications as sarsv
LEFT JOIN CandidateAssessmentSupervisors AS cas ON cas.ID = sarsv.CandidateAssessmentSupervisorID
INNER JOIN SelfAssessmentResults AS srs ON sarsv.SelfAssessmentResultId = srs.ID
INNER JOIN SelfAssessments AS sa ON srs.SelfAssessmentID = sa.ID
WHERE cas.SupervisorDelegateId = @supervisorDelegateId
AND cas.Removed IS NULL AND sarsv.Verified IS NULL
AND sa.ID = @selfAssessmentId", new { supervisorDelegateId, selfAssessmentId }
).ToList();

return verificationIds;
}

public List<int> GetCandidateAssessmentSupervisorVerifications(int supervisorDelegateId)
{
var verificationIds = new List<int>();
verificationIds = [.. connection.Query<int>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a typo here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not a typo, [..] is a list shorthand operator. Hope you were referring to this.

$@"SELECT casv.ID FROM CandidateAssessmentSupervisorVerifications as casv
LEFT JOIN CandidateAssessmentSupervisors AS cas ON cas.ID = casv.CandidateAssessmentSupervisorID
Inner JOIN CandidateAssessments AS ca ON ca.ID = cas.CandidateAssessmentID
WHERE cas.SupervisorDelegateId = 445
AND cas.Removed IS NULL AND casv.Verified IS NULL AND casv.SignedOff = 0
", new { supervisorDelegateId}
)];

return verificationIds;
}

public bool UpdateCandidateAssessmentSupervisorRoleByIds(int candidateAssessmentId, int supervisorDelegateId, int selfAssessmentSupervisorRoleId)
{
var numberOfAffectedRows = connection.Execute(
@"UPDATE CandidateAssessmentSupervisors
SET SelfAssessmentSupervisorRoleID = @selfAssessmentSupervisorRoleId
WHERE CandidateAssessmentID = @candidateAssessmentId
AND SupervisorDelegateId = @supervisorDelegateId
AND Removed IS NULL",
new { candidateAssessmentId, supervisorDelegateId, selfAssessmentSupervisorRoleId });
if (numberOfAffectedRows < 1)
{
logger.LogWarning(
$"Not updating Candidate Assessment Supervisor Role as db update failed. candidateAssessmentId: {candidateAssessmentId}, supervisorDelegateId: {supervisorDelegateId}, selfAssessmentSupervisorRoleId: {selfAssessmentSupervisorRoleId}"
);
return false;
}
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class DelegateSelfAssessment
public bool IsSupervisorResultsReviewed { get; set; }
public bool IsAssignedToSupervisor { get; set; }
public bool NonReportable { get; set; }
public string? Vocabulary { get; set; }
public string? Vocabulary { get; set; }
public bool AllowSupervisorRoleSelection { get; set; }
public int RoleCount { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,25 @@ public IActionResult DelegateProfileAssessments(int supervisorDelegateId, int de
SupervisorDelegateDetail = superviseDelegate,
DelegateSelfAssessments = delegateSelfAssessments
};

// Dictionary to map SupervisorRoleTitle to new titles now or in the future
var roleMappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase){
{ "EDUCATOR/MANAGER", "Supervising" },
{ "SUPERVISOR", "Supervising" },
{ "ASSESSOR", "Not Supervising" },
{ "NOMINATED SUPERVISOR", "Not Supervising" }
};
foreach (var item in model.DelegateSelfAssessments)
{
if (item.SupervisorRoleTitle != null)
{
if (roleMappings.ContainsKey(item.SupervisorRoleTitle?.ToUpper()))
{
item.SupervisorRoleTitle = roleMappings[item.SupervisorRoleTitle.ToUpper()];
}
}

}
return View("DelegateProfileAssessments", model);
}

Expand Down Expand Up @@ -1569,6 +1588,117 @@ public async Task<IActionResult> DownloadCertificate(int candidateAssessmentId)
}
return View("SelfAssessments/CompetencySelfAssessmentCertificate", model);
}

public IActionResult ChangeRoleDelegateSelection(int selfAssessmentId, int supervisorDelegateId, int candidateAssessmentId, IDictionary<string, string> routeModelValues)
{

var supervisorRoles = supervisorService.GetSupervisorRolesForSelfAssessment(selfAssessmentId);
var roleOptions = new List<SelectOption<string>>();
if (supervisorRoles.Any())
{
foreach (var role in supervisorRoles)
{
roleOptions.Add(new SelectOption<string> { Value = role.RoleName, Text = role.RoleName });
}

roleOptions.Add(new SelectOption<string>
{
Value = "RemoveAsSupervisor",
Text = "Remove me as a supervisor from this self assessment"
});
}

var model = new ChangeRoleSelectionViewModel()
{
DelegateFirstName = routeModelValues["firstName"],
DelegateLastName = routeModelValues["lastName"],
SelfAssessmentID = selfAssessmentId,
CandidateAssessmentID = candidateAssessmentId,
SupervisorDelegateID = supervisorDelegateId,
SupervisorRoleOptions = new OptionViewModel<string>()
{
Options = roleOptions,
GroupName = "ChangeRoleRadioButtons"
},
};
return View("ChangeRoleDelegateSelfAssessment", model);

}

public IActionResult ConfirmChangeRoleDelegateSelection(ChangeRoleSelectionViewModel model)
{
if (String.IsNullOrEmpty(model.SupervisorRoleOptions.SelectedValue))
{
ModelState.AddModelError("SupervisorRoleOptions", "You must select a Role");

var supervisorRoles = supervisorService.GetSupervisorRolesForSelfAssessment(model.SelfAssessmentID);
var roleOptions = new List<SelectOption<string>>();
if (supervisorRoles.Any())
{
foreach (var role in supervisorRoles)
{
roleOptions.Add(new SelectOption<string> { Value = role.RoleName, Text = role.RoleName });
}

roleOptions.Add(new SelectOption<string>
{
Value = "RemoveAsSupervisor",
Text = "Remove me as a supervisor from this self assessment"
});
}
model.SupervisorRoleOptions = new OptionViewModel<string>()
{
Options = roleOptions,
GroupName = "ChangeRoleRadioButtons"
};

return View("ChangeRoleDelegateSelfAssessment", model);
}
if (model.SupervisorRoleOptions.SelectedValue == "RemoveAsSupervisor")
{
supervisorService.RemoveCandidateAssessmentSupervisor(model.SelfAssessmentID, model.SupervisorDelegateID);
}
else
{
var supervisorRoles = supervisorService.GetSupervisorRolesForSelfAssessment(model.SelfAssessmentID);

var selectedRole = supervisorRoles.Where(x => x.RoleName == model.SupervisorRoleOptions.SelectedValue).FirstOrDefault();

if (selectedRole != null)
{

// update the candidate assessment supervisor tables with the role selected from the UI
var affected = supervisorService.UpdateCandidateAssessmentSupervisorRoleByIds(model.CandidateAssessmentID, model.SupervisorDelegateID, selectedRole.ID);
if (!selectedRole.ResultsReview)
{
//fetch the associated selfAssessmentResultSupervisorVerificationsIds and remove them as stated
var selfAssessmentVerifications = supervisorService.GetSelfAssessmentResultSupervisorVerifications(model.SupervisorDelegateID, model.SelfAssessmentID);
foreach (var verificationId in selfAssessmentVerifications)
{
supervisorService.RemoveSelfAssessmentResultSupervisorVerificationById(verificationId);
}
}

if (!selectedRole.SelfAssessmentReview)
{
//fetch the associated candidateAssessmentSupervisorVerificationsIds and remove them as stated
var supervisorVerifications = supervisorService.GetCandidateAssessmentSupervisorVerifications(model.SupervisorDelegateID);
foreach (var verificationId in supervisorVerifications)
{
supervisorService.RemoveCandidateAssessmentSupervisorVerification(verificationId);
}
}
}


}

return RedirectToAction("DelegateProfileAssessments", new { supervisorDelegateId = model.SupervisorDelegateID });

}



private static string RenderRazorViewToString(Controller controller, string viewName, object model = null)
{
controller.ViewData.Model = model;
Expand Down
Loading
Loading