Skip to content

Commit d22f00a

Browse files
authored
Merge pull request #3309 from TechnologyEnhancedLearning/Develop/Fixes/TD-5759-RefactorSelfAssessmentReportQueries
TD-5759 Refactors self assessment report sql to use SP, CTE and TVF
2 parents d7e07a6 + 4efaeda commit d22f00a

File tree

5 files changed

+194
-88
lines changed

5 files changed

+194
-88
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace DigitalLearningSolutions.Data.Migrations
2+
{
3+
using FluentMigrator;
4+
[Migration(20250703091)]
5+
public class CreateOrAlterGetSelfAssessmentReport : Migration
6+
{
7+
public override void Up()
8+
{
9+
Execute.Sql(Properties.Resources.TD_5759_CreateOrAlterSelfAssessmentReportSPandTVF_UP);
10+
}
11+
public override void Down()
12+
{
13+
Execute.Sql("DROP PROCEDURE IF EXISTS [dbo].[usp_GetSelfAssessmentReport]");
14+
Execute.Sql("DROP FUNCTION IF EXISTS [dbo].[GetOtherCentresForSelfAssessmentTVF]");
15+
}
16+
}
17+
}

DigitalLearningSolutions.Data.Migrations/Properties/Resources.Designer.cs

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

DigitalLearningSolutions.Data.Migrations/Properties/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,4 +487,7 @@
487487
<data name="TD_5447_Alter_ReorderFrameworkCompetency_Up" type="System.Resources.ResXFileRef, System.Windows.Forms">
488488
<value>..\Scripts\TD-5447-Alter_ReorderFrameworkCompetency_Up.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
489489
</data>
490+
<data name="TD-5759_CreateOrAlterSelfAssessmentReportSPandTVF_UP" type="System.Resources.ResXFileRef, System.Windows.Forms">
491+
<value>..\Scripts\TD-5759_CreateOrAlterSelfAssessmentReportSPandTVF_UP.sql;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
492+
</data>
490493
</root>
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
CREATE OR ALTER FUNCTION dbo.GetOtherCentresForSelfAssessmentTVF
2+
(
3+
@UserID INT,
4+
@SelfAssessmentID INT,
5+
@ExcludeCentreID INT
6+
)
7+
RETURNS TABLE
8+
AS
9+
RETURN
10+
(
11+
SELECT
12+
STUFF((
13+
SELECT DISTINCT
14+
', ' + c.CentreName
15+
FROM Users AS u
16+
INNER JOIN DelegateAccounts AS da ON u.ID = da.UserID
17+
INNER JOIN Centres AS c ON da.CentreID = c.CentreID
18+
INNER JOIN CentreSelfAssessments AS csa ON c.CentreID = csa.CentreID
19+
WHERE u.ID = @UserID
20+
AND da.Active = 1
21+
AND da.Approved = 1
22+
AND csa.SelfAssessmentID = @SelfAssessmentID
23+
AND c.CentreID <> @ExcludeCentreID
24+
FOR XML PATH(''), TYPE
25+
).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS OtherCentres
26+
);
27+
GO
28+
29+
CREATE OR ALTER PROCEDURE [dbo].[usp_GetSelfAssessmentReport]
30+
@SelfAssessmentID INT,
31+
@CentreID INT
32+
AS
33+
BEGIN
34+
SET NOCOUNT ON;
35+
36+
-- Step 1: Materialize the LatestAssessmentResults into a temp table
37+
IF OBJECT_ID('tempdb..#LatestAssessmentResults') IS NOT NULL
38+
DROP TABLE #LatestAssessmentResults;
39+
40+
SELECT
41+
s.DelegateUserID,
42+
CASE WHEN COALESCE(rr.LevelRAG, 0) = 3 THEN s.ID ELSE NULL END AS SelfAssessed,
43+
CASE
44+
WHEN sv.Verified IS NOT NULL AND sv.SignedOff = 1 AND COALESCE(rr.LevelRAG, 0) = 3
45+
THEN s.ID ELSE NULL
46+
END AS Confirmed,
47+
CASE WHEN sas.Optional = 1 THEN s.CompetencyID ELSE NULL END AS Optional
48+
INTO #LatestAssessmentResults
49+
FROM SelfAssessmentResults AS s
50+
LEFT JOIN SelfAssessmentStructure AS sas
51+
ON sas.SelfAssessmentID = @SelfAssessmentID
52+
AND s.CompetencyID = sas.CompetencyID
53+
LEFT JOIN SelfAssessmentResultSupervisorVerifications AS sv
54+
ON s.ID = sv.SelfAssessmentResultId
55+
AND sv.Superceded = 0
56+
LEFT JOIN CompetencyAssessmentQuestionRoleRequirements AS rr
57+
ON s.CompetencyID = rr.CompetencyID
58+
AND s.AssessmentQuestionID = rr.AssessmentQuestionID
59+
AND sas.SelfAssessmentID = rr.SelfAssessmentID
60+
AND s.Result = rr.LevelValue
61+
WHERE sas.SelfAssessmentID = @SelfAssessmentID;
62+
63+
CREATE NONCLUSTERED INDEX IX_LAR_DelegateUserID ON #LatestAssessmentResults(DelegateUserID);
64+
65+
-- Step 2: Run the main query
66+
SELECT
67+
sa.Name AS SelfAssessment,
68+
u.LastName + ', ' + u.FirstName AS Learner,
69+
da.Active AS LearnerActive,
70+
u.ProfessionalRegistrationNumber AS PRN,
71+
jg.JobGroupName AS JobGroup,
72+
da.Answer1,
73+
da.Answer2,
74+
da.Answer3,
75+
da.Answer4,
76+
da.Answer5,
77+
da.Answer6,
78+
oc.OtherCentres,
79+
CASE
80+
WHEN aa.ID IS NULL THEN 'Learner'
81+
WHEN aa.IsCentreManager = 1 THEN 'Centre Manager'
82+
WHEN aa.IsCentreAdmin = 1 AND aa.IsCentreManager = 0 THEN 'Centre Admin'
83+
WHEN aa.IsSupervisor = 1 THEN 'Supervisor'
84+
WHEN aa.IsNominatedSupervisor = 1 THEN 'Nominated supervisor'
85+
END AS DLSRole,
86+
da.DateRegistered AS Registered,
87+
ca.StartedDate,
88+
ca.LastAccessed,
89+
COUNT(DISTINCT LAR.Optional) AS [OptionalProficienciesAssessed],
90+
COUNT(DISTINCT LAR.SelfAssessed) AS [SelfAssessedAchieved],
91+
COUNT(DISTINCT LAR.Confirmed) AS [ConfirmedResults],
92+
MAX(casv.Requested) AS SignOffRequested,
93+
MAX(1 * casv.SignedOff) AS SignOffAchieved,
94+
MIN(casv.Verified) AS ReviewedDate
95+
FROM CandidateAssessments AS ca
96+
INNER JOIN DelegateAccounts AS da
97+
ON ca.DelegateUserID = da.UserID
98+
AND da.CentreID = @CentreID
99+
INNER JOIN Users AS u
100+
ON u.ID = da.UserID
101+
INNER JOIN SelfAssessments AS sa
102+
ON ca.SelfAssessmentID = sa.ID
103+
INNER JOIN CentreSelfAssessments AS csa
104+
ON sa.ID = csa.SelfAssessmentID
105+
INNER JOIN Centres AS c
106+
ON csa.CentreID = c.CentreID
107+
AND da.CentreID = c.CentreID
108+
INNER JOIN JobGroups AS jg
109+
ON u.JobGroupID = jg.JobGroupID
110+
LEFT JOIN AdminAccounts AS aa
111+
ON da.UserID = aa.UserID
112+
AND aa.CentreID = da.CentreID
113+
AND aa.Active = 1
114+
LEFT JOIN CandidateAssessmentSupervisors AS cas
115+
ON ca.ID = cas.CandidateAssessmentID
116+
LEFT JOIN CandidateAssessmentSupervisorVerifications AS casv
117+
ON casv.CandidateAssessmentSupervisorID = cas.ID
118+
LEFT JOIN SupervisorDelegates AS sd
119+
ON cas.SupervisorDelegateId = sd.ID
120+
LEFT JOIN #LatestAssessmentResults AS LAR
121+
ON LAR.DelegateUserID = ca.DelegateUserID
122+
OUTER APPLY dbo.GetOtherCentresForSelfAssessmentTVF(da.UserID, @SelfAssessmentID, c.CentreID) AS oc
123+
WHERE
124+
sa.ID = @SelfAssessmentID
125+
AND sa.ArchivedDate IS NULL
126+
AND c.Active = 1
127+
AND ca.RemovedDate IS NULL
128+
AND ca.NonReportable = 0
129+
GROUP BY
130+
sa.Name,
131+
u.LastName + ', ' + u.FirstName,
132+
da.Active,
133+
u.ProfessionalRegistrationNumber,
134+
jg.JobGroupName,
135+
da.Answer1, da.Answer2, da.Answer3, da.Answer4, da.Answer5, da.Answer6,
136+
da.DateRegistered,
137+
ca.StartedDate,
138+
ca.LastAccessed,
139+
oc.OtherCentres,
140+
aa.ID, aa.IsCentreManager, aa.IsCentreAdmin, aa.IsSupervisor, aa.IsNominatedSupervisor
141+
ORDER BY
142+
sa.Name, u.LastName + ', ' + u.FirstName;
143+
144+
END;
145+
GO

DigitalLearningSolutions.Data/DataServices/SelfAssessmentDataService/SelfAsssessmentReportDataService.cs

Lines changed: 3 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -45,94 +45,9 @@ FROM CentreSelfAssessments AS csa INNER JOIN
4545

4646
public IEnumerable<SelfAssessmentReportData> GetSelfAssessmentReportDataForCentre(int centreId, int selfAssessmentId)
4747
{
48-
return connection.Query<SelfAssessmentReportData>(
49-
@"WITH LatestAssessmentResults AS
50-
(
51-
SELECT s.DelegateUserID
52-
, CASE WHEN COALESCE (rr.LevelRAG, 0) = 3 THEN s.ID ELSE NULL END AS SelfAssessed
53-
, CASE WHEN sv.Verified IS NOT NULL AND sv.SignedOff = 1 AND COALESCE (rr.LevelRAG, 0) = 3 THEN s.ID ELSE NULL END AS Confirmed
54-
, CASE WHEN sas.Optional = 1 THEN s.CompetencyID ELSE NULL END AS Optional
55-
FROM SelfAssessmentResults AS s LEFT OUTER JOIN
56-
SelfAssessmentStructure AS sas ON sas.SelfAssessmentID = @selfAssessmentId AND s.CompetencyID = sas.CompetencyID LEFT OUTER JOIN
57-
SelfAssessmentResultSupervisorVerifications AS sv ON s.ID = sv.SelfAssessmentResultId AND sv.Superceded = 0 LEFT OUTER JOIN
58-
CompetencyAssessmentQuestionRoleRequirements AS rr ON s.CompetencyID = rr.CompetencyID AND s.AssessmentQuestionID = rr.AssessmentQuestionID AND sas.SelfAssessmentID = rr.SelfAssessmentID AND s.Result = rr.LevelValue
59-
WHERE (sas.SelfAssessmentID = @selfAssessmentId)
60-
)
61-
SELECT
62-
sa.Name AS SelfAssessment
63-
, u.LastName + ', ' + u.FirstName AS Learner
64-
, da.Active AS LearnerActive
65-
, u.ProfessionalRegistrationNumber AS PRN
66-
, jg.JobGroupName AS JobGroup
67-
, da.Answer1 AS RegistrationAnswer1
68-
, da.Answer2 AS RegistrationAnswer2
69-
, da.Answer3 AS RegistrationAnswer3
70-
, da.Answer4 AS RegistrationAnswer4
71-
, da.Answer5 AS RegistrationAnswer5
72-
, da.Answer6 AS RegistrationAnswer6
73-
, dbo.GetOtherCentresForSelfAssessment(da.UserID, @SelfAssessmentID, c.CentreID) AS OtherCentres
74-
, CASE
75-
WHEN aa.ID IS NULL THEN 'Learner'
76-
WHEN aa.IsCentreManager = 1 THEN 'Centre Manager'
77-
WHEN aa.IsCentreAdmin = 1 AND aa.IsCentreManager = 0 THEN 'Centre Admin'
78-
WHEN aa.IsSupervisor = 1 THEN 'Supervisor'
79-
WHEN aa.IsNominatedSupervisor = 1 THEN 'Nominated supervisor'
80-
END AS DLSRole
81-
, da.DateRegistered AS Registered
82-
, ca.StartedDate AS Started
83-
, ca.LastAccessed
84-
, COALESCE(COUNT(DISTINCT LAR.Optional), NULL) AS [OptionalProficienciesAssessed]
85-
, COALESCE(COUNT(DISTINCT LAR.SelfAssessed), NULL) AS [SelfAssessedAchieved]
86-
, COALESCE(COUNT(DISTINCT LAR.Confirmed), NULL) AS [ConfirmedResults]
87-
, max(casv.Requested) AS SignOffRequested
88-
, max(1*casv.SignedOff) AS SignOffAchieved
89-
, min(casv.Verified) AS ReviewedDate
90-
FROM
91-
CandidateAssessments AS ca INNER JOIN
92-
DelegateAccounts AS da ON ca.DelegateUserID = da.UserID and da.CentreID = @centreId INNER JOIN
93-
Users as u ON u.ID = da.UserID INNER JOIN
94-
SelfAssessments AS sa INNER JOIN
95-
CentreSelfAssessments AS csa ON sa.ID = csa.SelfAssessmentID INNER JOIN
96-
Centres AS c ON csa.CentreID = c.CentreID ON da.CentreID = c.CentreID AND ca.SelfAssessmentID = sa.ID INNER JOIN
97-
JobGroups AS jg ON u.JobGroupID = jg.JobGroupID LEFT OUTER JOIN
98-
AdminAccounts AS aa ON da.UserID = aa.UserID AND aa.CentreID = da.CentreID AND aa.Active = 1 LEFT OUTER JOIN
99-
CandidateAssessmentSupervisors AS cas ON ca.ID = cas.CandidateAssessmentID left JOIN
100-
CandidateAssessmentSupervisorVerifications AS casv ON casv.CandidateAssessmentSupervisorID = cas.ID LEFT JOIN
101-
SupervisorDelegates AS sd ON cas.SupervisorDelegateId = sd.ID
102-
LEFT OUTER JOIN LatestAssessmentResults AS LAR ON LAR.DelegateUserID = ca.DelegateUserID
103-
WHERE
104-
(sa.ID = @SelfAssessmentID) AND (sa.ArchivedDate IS NULL) AND (c.Active = 1) AND (ca.RemovedDate IS NULL AND ca.NonReportable = 0)
105-
Group by sa.Name
106-
, u.LastName + ', ' + u.FirstName
107-
, da.Active
108-
, u.ProfessionalRegistrationNumber
109-
, c.CustomField1PromptID
110-
, c.CustomField2PromptID
111-
, c.CustomField3PromptID
112-
, c.CustomField4PromptID
113-
, c.CustomField5PromptID
114-
, c.CustomField6PromptID
115-
, c.CentreID
116-
, jg.JobGroupName
117-
, da.ID
118-
, da.Answer1
119-
, da.Answer2
120-
, da.Answer3
121-
, da.Answer4
122-
, da.Answer5
123-
, da.Answer6
124-
, da.DateRegistered
125-
, da.UserID
126-
, aa.ID
127-
, aa.IsCentreManager
128-
, aa.IsCentreAdmin
129-
, aa.IsSupervisor
130-
, aa.IsNominatedSupervisor
131-
, ca.StartedDate
132-
, ca.LastAccessed
133-
ORDER BY
134-
SelfAssessment, u.LastName + ', ' + u.FirstName",
135-
new { centreId, selfAssessmentId }
48+
return connection.Query<SelfAssessmentReportData>("usp_GetSelfAssessmentReport",
49+
new { selfAssessmentId, centreId },
50+
commandType: CommandType.StoredProcedure
13651
);
13752
}
13853
}

0 commit comments

Comments
 (0)