Skip to content

Commit dc23e97

Browse files
swapnamol-abrahamAnjuJose011
authored andcommitted
Merge pull request #1680 from TechnologyEnhancedLearning/Develop/Fixes/TD-6848-Certificate-Generation-Does-Not-Trigger-After-Successful-Completion-of-the-Resources
Develop/fixes/td 6848 certificate generation does not trigger after successful completion of the resources
1 parent a46550b commit dc23e97

8 files changed

Lines changed: 119 additions & 9 deletions

File tree

LearningHub.Nhs.WebUI/Controllers/Api/ScormController.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ private async Task<bool> Commit(SCO scoObject)
261261
// Persist update.
262262
await this.activityService.UpdateScormActivityAsync(scoObject);
263263

264+
// Create Activity Complete event. (TODO process event using service bus queue - perform any longer running async status re-calc).
265+
await this.activityService.ScormCompleteActivity(scoObject);
266+
264267
return true;
265268
}
266269
catch (Exception ex)

LearningHub.Nhs.WebUI/Interfaces/IActivityService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ public interface IActivityService
6666
/// <returns>The <see cref="Task{LearningHubValidationResult}"/>.</returns>
6767
Task<LearningHubValidationResult> CompleteScormActivity(ScormActivityViewModel scormActivityViewModel);
6868

69+
/// <summary>
70+
/// The CompleteScormActivity.
71+
/// </summary>
72+
/// <param name="scormActivityViewModel">The updateScormActivityViewModel<see cref="ScormActivityViewModel"/>.</param>
73+
/// <returns>The <see cref="Task{LearningHubValidationResult}"/>.</returns>
74+
Task<LearningHubValidationResult> ScormCompleteActivity(ScormActivityViewModel scormActivityViewModel);
75+
6976
/// <summary>
7077
/// The ResolveScormActivity.
7178
/// </summary>

LearningHub.Nhs.WebUI/Services/ActivityService.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,39 @@ public async Task<LearningHubValidationResult> CompleteScormActivity(ScormActivi
294294
return validationResult;
295295
}
296296

297+
/// <summary>
298+
/// The CompleteScormActivity.
299+
/// </summary>
300+
/// <param name="scormActivityViewModel">The updateScormActivityViewModel<see cref="ScormActivityViewModel"/>.</param>
301+
/// <returns>The <see cref="Task{LearningHubValidationResult}"/>.</returns>
302+
public async Task<LearningHubValidationResult> ScormCompleteActivity(ScormActivityViewModel scormActivityViewModel)
303+
{
304+
var json = JsonConvert.SerializeObject(scormActivityViewModel);
305+
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
306+
307+
var client = await this.LearningHubHttpClient.GetClientAsync();
308+
309+
var request = $"Activity/ScormCompleteActivity";
310+
var response = await client.PostAsync(request, stringContent).ConfigureAwait(false);
311+
312+
LearningHubValidationResult validationResult;
313+
if (response.IsSuccessStatusCode)
314+
{
315+
var result = response.Content.ReadAsStringAsync().Result;
316+
validationResult = JsonConvert.DeserializeObject<LearningHubValidationResult>(result);
317+
}
318+
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || response.StatusCode == System.Net.HttpStatusCode.Forbidden)
319+
{
320+
throw new Exception("AccessDenied");
321+
}
322+
else
323+
{
324+
throw new Exception("Complete Scorm Activity failed!");
325+
}
326+
327+
return validationResult;
328+
}
329+
297330
/// <summary>
298331
/// The ResolveScormActivity.
299332
/// </summary>

WebAPI/LearningHub.Nhs.API/Controllers/ActivityController.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,27 @@ public async Task<IActionResult> CompleteScormActivity(ScormActivityViewModel co
211211
}
212212
}
213213

214+
/// <summary>
215+
/// Complete Scorm Activity.
216+
/// </summary>
217+
/// <param name="completeScormActivityViewModel">The scorm activity.</param>
218+
/// <returns>The <see cref="IActionResult"/>.</returns>
219+
[HttpPost]
220+
[Route("ScormCompleteActivity")]
221+
public async Task<IActionResult> ScormCompleteActivity(ScormActivityViewModel completeScormActivityViewModel)
222+
{
223+
var vr = await this.activityService.ScormCompleteActivity(this.CurrentUserId, completeScormActivityViewModel);
224+
225+
if (vr.IsValid)
226+
{
227+
return this.Ok(new ApiResponse(true, vr));
228+
}
229+
else
230+
{
231+
return this.BadRequest(new ApiResponse(false, vr));
232+
}
233+
}
234+
214235
/// <summary>
215236
/// Launch Scorm Activity.
216237
/// </summary>

WebAPI/LearningHub.Nhs.Database/Stored Procedures/Activity/ScormActivityComplete.sql

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
--
88
-- 11-06-2021 Killian Davies Initial Revision
99
-- 17-04-2024 Swapna Abraham Reverted TD-1325 changes
10+
-- 10-02-2026 Swapna Abraham TD-6848 Certificate Generation Does Not Trigger After Successful Completion of the Resources
1011
-------------------------------------------------------------------------------
1112
CREATE PROCEDURE [activity].[ScormActivityComplete]
1213
(
@@ -45,13 +46,14 @@ BEGIN
4546
IF EXISTS (SELECT 'X' FROM activity.ResourceActivity WHERE LaunchResourceActivityId = @ScormResourceActivityId AND ActivityStatusId IN (3, 4, 5))
4647
BEGIN
4748
DECLARE @ActivityStatusErrorMessage nvarchar(1024)
48-
SELECT @ActivityStatusErrorMessage = 'ResourceActivity entry with Completed status already exists for ScormActivityId=' + @ScormActivityId
49+
SELECT @ActivityStatusErrorMessage = 'ResourceActivity entry with Completed status already exists for ScormActivityId=' + CONVERT(nvarchar(20), @ScormActivityId);
4950
RAISERROR (@ActivityStatusErrorMessage,
5051
16, -- Severity.
5152
1 -- State.
5253
);
5354
END
54-
55+
ELSE
56+
BEGIN
5557
-- Validation ported from e-LfH: completed status requires duration > 0
5658
IF (@ActivityStatusId IN (3, 4, 5) AND @DurationSeconds > 0)
5759
BEGIN TRY
@@ -123,5 +125,6 @@ BEGIN
123125
);
124126
END CATCH
125127
END
128+
END
126129

127130
GO

WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetUsercertificateDetails.sql

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,14 @@ BEGIN
4848
AND mar.PercentComplete = 100
4949
)
5050
OR (r.ResourceTypeId = 6 AND (
51-
EXISTS (
52-
SELECT 1
53-
FROM activity.ScormActivity sa
54-
WHERE sa.ResourceActivityId = ra.Id
55-
AND sa.CmiCoreLesson_status IN (3,5)
56-
)
57-
OR ra.ActivityStatusId IN (3,5)
51+
--EXISTS (
52+
-- SELECT 1
53+
-- FROM activity.ScormActivity sa
54+
-- WHERE sa.ResourceActivityId = ra.Id
55+
-- AND sa.CmiCoreLesson_status IN (3,5)
56+
--)
57+
--OR
58+
ra.ActivityStatusId IN (3,5)
5859
))
5960
OR (
6061
r.ResourceTypeId = 11

WebAPI/LearningHub.Nhs.Services.Interface/IActivityService.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ public interface IActivityService
106106
/// <returns>The <see cref="Task"/>.</returns>
107107
Task<LearningHubValidationResult> CompleteScormActivity(int currentUserId, ScormActivityViewModel completeScormActivityViewModel);
108108

109+
/// <summary>
110+
/// Complete scorm activity.
111+
/// </summary>
112+
/// <param name="currentUserId">The user Id.</param>
113+
/// <param name="completeScormActivityViewModel">The update scorm Activity View Model.</param>
114+
/// <returns>The <see cref="Task"/>.</returns>
115+
Task<LearningHubValidationResult> ScormCompleteActivity(int currentUserId, ScormActivityViewModel completeScormActivityViewModel);
116+
109117
/// <summary>
110118
/// The resolve scorm activity.
111119
/// Resolves any completed active content that does not have associated completion events.

WebAPI/LearningHub.Nhs.Services/ActivityService.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using LearningHub.Nhs.Repository.Interface.Resources;
1919
using LearningHub.Nhs.Services.Helpers;
2020
using LearningHub.Nhs.Services.Interface;
21+
using Microsoft.Data.SqlClient;
2122
using Microsoft.EntityFrameworkCore;
2223
using Microsoft.Extensions.Logging;
2324
using Microsoft.Rest;
@@ -526,6 +527,39 @@ public async Task<LearningHubValidationResult> CompleteScormActivity(int current
526527
return new LearningHubValidationResult(true);
527528
}
528529

530+
/// <summary>
531+
/// Complete scorm activity.
532+
/// </summary>
533+
/// <param name="currentUserId">The user Id.</param>
534+
/// <param name="completeScormActivityViewModel">The update scorm Activity View Model.</param>
535+
/// <returns>The <see cref="Task"/>.</returns>
536+
public async Task<LearningHubValidationResult> ScormCompleteActivity(int currentUserId, ScormActivityViewModel completeScormActivityViewModel)
537+
{
538+
try
539+
{
540+
if (completeScormActivityViewModel.LessonStatusId.HasValue
541+
&& (completeScormActivityViewModel.LessonStatusId.Value == (int)ActivityStatusEnum.Completed
542+
|| completeScormActivityViewModel.LessonStatusId == (int)ActivityStatusEnum.Passed
543+
|| completeScormActivityViewModel.LessonStatusId == (int)ActivityStatusEnum.Failed))
544+
{
545+
// Handle activity "complete" event - create new ResourceActivity record & perform any re-calc status updates.
546+
this.scormActivityRepository.Complete(currentUserId, completeScormActivityViewModel.InstanceId);
547+
}
548+
}
549+
catch (SqlException ex)
550+
{
551+
if (!ex.Message.Contains(
552+
"ResourceActivity entry with Completed status already exists",
553+
StringComparison.OrdinalIgnoreCase))
554+
{
555+
throw;
556+
}
557+
// else: intentionally ignore
558+
}
559+
560+
return new LearningHubValidationResult(true);
561+
}
562+
529563
/// <summary>
530564
/// The resolve scorm activity.
531565
/// Resolves any completed active content that does not have associated completion events.

0 commit comments

Comments
 (0)