Skip to content

Commit 8130860

Browse files
committed
Revert Revert "TD-2180- feature - Delegate Courses list to use SQL filtering an…
1 parent dc1d2f4 commit 8130860

File tree

6 files changed

+256
-99
lines changed

6 files changed

+256
-99
lines changed

DigitalLearningSolutions.Data/DataServices/CourseDataService.cs

Lines changed: 126 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,30 +115,30 @@ public class CourseDataService : ICourseDataService
115115
{
116116
private const string DelegateCountQuery =
117117
@"(SELECT COUNT(pr.CandidateID)
118-
FROM dbo.Progress AS pr
119-
INNER JOIN dbo.Candidates AS can ON can.CandidateID = pr.CandidateID
118+
FROM dbo.Progress AS pr WITH (NOLOCK)
119+
INNER JOIN dbo.Candidates AS can WITH (NOLOCK) ON can.CandidateID = pr.CandidateID
120120
WHERE pr.CustomisationID = cu.CustomisationID
121121
AND can.CentreID = @centreId
122122
AND RemovedDate IS NULL) AS DelegateCount";
123123

124124
private const string CompletedCountQuery =
125125
@"(SELECT COUNT(pr.CandidateID)
126-
FROM dbo.Progress AS pr
127-
INNER JOIN dbo.Candidates AS can ON can.CandidateID = pr.CandidateID
126+
FROM dbo.Progress AS pr WITH (NOLOCK)
127+
INNER JOIN dbo.Candidates AS can WITH (NOLOCK) ON can.CandidateID = pr.CandidateID
128128
WHERE pr.CustomisationID = cu.CustomisationID AND pr.Completed IS NOT NULL
129129
AND can.CentreID = @centreId) AS CompletedCount";
130130

131131
private const string AllAttemptsQuery =
132132
@"(SELECT COUNT(aa.AssessAttemptID)
133-
FROM dbo.AssessAttempts AS aa
134-
INNER JOIN dbo.Candidates AS can ON can.CandidateID = aa.CandidateID
133+
FROM dbo.AssessAttempts AS aa WITH (NOLOCK)
134+
INNER JOIN dbo.Candidates AS can WITH (NOLOCK) ON can.CandidateID = aa.CandidateID
135135
WHERE aa.CustomisationID = cu.CustomisationID AND aa.[Status] IS NOT NULL
136136
AND can.CentreID = @centreId) AS AllAttempts";
137137

138138
private const string AttemptsPassedQuery =
139139
@"(SELECT COUNT(aa.AssessAttemptID)
140-
FROM dbo.AssessAttempts AS aa
141-
INNER JOIN dbo.Candidates AS can ON can.CandidateID = aa.CandidateID
140+
FROM dbo.AssessAttempts AS aa WITH (NOLOCK)
141+
INNER JOIN dbo.Candidates AS can WITH (NOLOCK) ON can.CandidateID = aa.CandidateID
142142
WHERE aa.CustomisationID = cu.CustomisationID AND aa.[Status] = 1
143143
AND can.CentreID = @centreId) AS AttemptsPassed";
144144

@@ -623,6 +623,124 @@ public IEnumerable<CourseStatistics> GetCourseStatisticsAtCentreFilteredByCatego
623623
);
624624
}
625625

626+
public (IEnumerable<CourseStatistics>, int) GetCourseStatisticsAtCentre(string searchString, int offSet, int itemsPerPage, string sortBy, string sortDirection, int centreId, int? categoryId,
627+
string isActive, string categoryName, string courseTopic, string hasAdminFields
628+
)
629+
{
630+
string courseStatisticsSelect = @$" SELECT
631+
cu.CustomisationID,
632+
cu.CentreID,
633+
cu.Active,
634+
CASE WHEN ap.ArchivedDate IS NOT NULL THEN 0 ELSE cu.Active END AS Active,
635+
cu.AllCentres,
636+
ap.ApplicationId,
637+
ap.ApplicationName,
638+
cu.CustomisationName,
639+
{DelegateCountQuery},
640+
{CompletedCountQuery},
641+
{AllAttemptsQuery},
642+
{AttemptsPassedQuery},
643+
cu.HideInLearnerPortal,
644+
cc.CategoryName,
645+
ct.CourseTopic,
646+
cu.LearningTimeMins AS LearningMinutes,
647+
cu.IsAssessed,
648+
CASE WHEN ap.ArchivedDate IS NOT NULL THEN 1 ELSE 0 END AS Archived,
649+
((SELECT COUNT(pr.CandidateID)
650+
FROM dbo.Progress AS pr WITH (NOLOCK)
651+
INNER JOIN dbo.Candidates AS can WITH (NOLOCK) ON can.CandidateID = pr.CandidateID
652+
WHERE pr.CustomisationID = cu.CustomisationID
653+
AND can.CentreID = @centreId
654+
AND RemovedDate IS NULL) -
655+
(SELECT COUNT(pr.CandidateID)
656+
FROM dbo.Progress AS pr WITH (NOLOCK)
657+
INNER JOIN dbo.Candidates AS can WITH (NOLOCK) ON can.CandidateID = pr.CandidateID
658+
WHERE pr.CustomisationID = cu.CustomisationID AND pr.Completed IS NOT NULL
659+
AND can.CentreID = @centreId)) AS InProgressCount ";
660+
string courseStatisticsFromTable = @$" FROM dbo.Customisations AS cu WITH (NOLOCK)
661+
INNER JOIN dbo.CentreApplications AS ca WITH (NOLOCK) ON ca.ApplicationID = cu.ApplicationID
662+
INNER JOIN dbo.Applications AS ap WITH (NOLOCK) ON ap.ApplicationID = ca.ApplicationID
663+
INNER JOIN dbo.CourseCategories AS cc WITH (NOLOCK) ON cc.CourseCategoryID = ap.CourseCategoryID
664+
INNER JOIN dbo.CourseTopics AS ct WITH (NOLOCK) ON ct.CourseTopicID = ap.CourseTopicId
665+
666+
LEFT JOIN CoursePrompts AS cp1 WITH (NOLOCK)
667+
ON cu.CourseField1PromptID = cp1.CoursePromptID
668+
LEFT JOIN CoursePrompts AS cp2 WITH (NOLOCK)
669+
ON cu.CourseField2PromptID = cp2.CoursePromptID
670+
LEFT JOIN CoursePrompts AS cp3 WITH (NOLOCK)
671+
ON cu.CourseField3PromptID = cp3.CoursePromptID
672+
673+
WHERE (ap.CourseCategoryID = @categoryId OR @categoryId IS NULL)
674+
AND (cu.CentreID = @centreId OR (cu.AllCentres = 1 AND ca.Active = 1))
675+
AND ca.CentreID = @centreId
676+
AND ap.DefaultContentTypeID <> 4
677+
AND ( ap.ApplicationName + ' ' + ' ' + cu.CustomisationName LIKE N'%' + @searchString + N'%')
678+
AND ((@isActive = 'Any') OR (@isActive = 'true' AND (cu.Active = 1 AND ap.ArchivedDate IS NULL)) OR (@isActive = 'false' AND ((cu.Active = 0 OR ap.ArchivedDate IS NOT NULL))))
679+
AND ((@categoryName = 'Any') OR (cc.CategoryName = @categoryName))
680+
AND ((@courseTopic = 'Any') OR (ct.CourseTopic = @courseTopic))
681+
AND ((@hasAdminFields = 'Any') OR (@hasAdminFields = 'true' AND (cp1.CoursePrompt IS NOT NULL OR cp2.CoursePrompt IS NOT NULL OR cp3.CoursePrompt IS NOT NULL))
682+
OR (@hasAdminFields = 'false' AND (cp1.CoursePrompt IS NULL AND cp2.CoursePrompt IS NULL AND cp3.CoursePrompt IS NULL)))";
683+
684+
685+
string orderBy;
686+
string sortOrder;
687+
688+
if (sortDirection == "Ascending")
689+
sortOrder = " ASC ";
690+
else
691+
sortOrder = " DESC ";
692+
693+
if (sortBy == "CourseName" || sortBy == "SearchableName")
694+
orderBy = " ORDER BY ap.ApplicationName + cu.CustomisationName " + sortOrder;
695+
else
696+
orderBy = " ORDER BY " + sortBy;
697+
698+
orderBy += " OFFSET " + offSet + " ROWS FETCH NEXT " + itemsPerPage + " ROWS ONLY ";
699+
700+
var courseStatisticsQuery = courseStatisticsSelect + courseStatisticsFromTable + orderBy;
701+
702+
IEnumerable<CourseStatistics> courseStatistics = connection.Query<CourseStatistics>(
703+
courseStatisticsQuery,
704+
new
705+
{
706+
searchString,
707+
offSet,
708+
itemsPerPage,
709+
sortBy,
710+
sortDirection,
711+
centreId,
712+
categoryId,
713+
isActive,
714+
categoryName,
715+
courseTopic,
716+
hasAdminFields
717+
},
718+
commandTimeout: 3000
719+
);
720+
721+
var courseStatisticsCountQuery = @$"SELECT COUNT(*) AS Matches " + courseStatisticsFromTable ;
722+
723+
int resultCount = connection.ExecuteScalar<int>(
724+
courseStatisticsCountQuery,
725+
new
726+
{
727+
searchString,
728+
offSet,
729+
itemsPerPage,
730+
sortBy,
731+
sortDirection,
732+
centreId,
733+
categoryId,
734+
isActive,
735+
categoryName,
736+
courseTopic,
737+
hasAdminFields
738+
},
739+
commandTimeout: 3000
740+
);
741+
return (courseStatistics, resultCount);
742+
}
743+
626744
public IEnumerable<CourseStatistics> GetNonArchivedCourseStatisticsAtCentreFilteredByCategory(
627745
int centreId,
628746
int? categoryId

DigitalLearningSolutions.Web.Tests/Controllers/TrackingSystem/Delegates/DelegateCoursesControllerTests.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace DigitalLearningSolutions.Web.Tests.Controllers.TrackingSystem.Delegates
22
{
33
using System.Collections.Generic;
4+
using DigitalLearningSolutions.Data.DataServices;
45
using DigitalLearningSolutions.Data.Models.Courses;
56
using DigitalLearningSolutions.Data.Models.SearchSortFilterPaginate;
67
using DigitalLearningSolutions.Web.Controllers.TrackingSystem.Delegates;
@@ -41,21 +42,27 @@ public class DelegateCoursesControllerTests
4142
.And(x => x.Topics = new List<string> { "Topic 1", "Topic 2" })
4243
.Build();
4344

45+
46+
4447
private DelegateCoursesController controllerWithCookies = null!;
4548
private ICourseDelegatesDownloadFileService courseDelegatesDownloadFileService = null!;
4649
private ICourseService courseService = null!;
4750
private HttpRequest httpRequest = null!;
4851
private HttpResponse httpResponse = null!;
49-
private ISearchSortFilterPaginateService searchSortFilterPaginateService = null!;
52+
private IPaginateService paginateService = null!;
5053
private IActivityService activityService = null;
54+
private ICourseCategoriesDataService courseCategoriesDataService = null;
55+
private ICourseTopicsDataService courseTopicsDataService = null;
5156

5257
[SetUp]
5358
public void Setup()
5459
{
5560
courseService = A.Fake<ICourseService>();
5661
courseDelegatesDownloadFileService = A.Fake<ICourseDelegatesDownloadFileService>();
5762
activityService = A.Fake<IActivityService>();
58-
searchSortFilterPaginateService = A.Fake<ISearchSortFilterPaginateService>();
63+
paginateService = A.Fake<IPaginateService>();
64+
courseCategoriesDataService = A.Fake<ICourseCategoriesDataService>();
65+
courseTopicsDataService = A.Fake<ICourseTopicsDataService>();
5966
A.CallTo(() => activityService.GetCourseCategoryNameForActivityFilter(A<int>._))
6067
.Returns("All");
6168
A.CallTo(() => courseService.GetCentreCourseDetailsWithAllCentreCourses(A<int>._, A<int?>._))
@@ -71,8 +78,10 @@ public void Setup()
7178
controllerWithCookies = new DelegateCoursesController(
7279
courseService,
7380
courseDelegatesDownloadFileService,
74-
searchSortFilterPaginateService,
75-
activityService
81+
paginateService,
82+
activityService,
83+
courseCategoriesDataService,
84+
courseTopicsDataService
7685
)
7786
.WithMockHttpContext(httpRequest, CookieName, cookieValue, httpResponse)
7887
.WithMockUser(true, 101)
@@ -88,11 +97,13 @@ public void Index_calls_expected_methods_and_returns_view()
8897
// Then
8998
using (new AssertionScope())
9099
{
91-
A.CallTo(() => courseService.GetCentreCourseDetailsWithAllCentreCourses(A<int>._, A<int?>._)).MustHaveHappened();
100+
A.CallTo(() => courseService.GetCentreCourses(A<string>._, A<int>._, A<int>._, A<string>._, A<string>._, A<int>._, A<int?>._,
101+
A<string>._, A<string>._, A<string>._, A<string>._)).MustHaveHappened();
92102
A.CallTo(
93-
() => searchSortFilterPaginateService.SearchFilterSortAndPaginate(
103+
() => paginateService.Paginate(
94104
A<IEnumerable<CourseStatisticsWithAdminFieldResponseCounts>>._,
95-
A<SearchSortFilterAndPaginateOptions>._
105+
A<int>._,
106+
A<PaginationOptions>._, A<FilterOptions>._, A<string>._, A<string>._, A<string>._
96107
)
97108
).MustHaveHappened();
98109
A.CallTo(

0 commit comments

Comments
 (0)