Skip to content

Commit 7d77546

Browse files
TD-4632 As a centre manager at a new centre, I should be able to register using a predetermined email address without additional approval steps
1 parent a8682c5 commit 7d77546

File tree

16 files changed

+152
-13
lines changed

16 files changed

+152
-13
lines changed

DigitalLearningSolutions.Data/DataServices/CentresDataService.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public int ResultCount(string search, int region, int centreType, int contractTy
114114

115115
public IEnumerable<CentresExport> GetAllCentresForSuperAdminExport(string search, int region,
116116
int centreType, int contractType, string centreStatus, int exportQueryRowLimit, int currentRun);
117+
Centre? CountRegisterUserByCentreId(int centreId);
117118
}
118119

119120
public class CentresDataService : ICentresDataService
@@ -325,6 +326,27 @@ FROM Centres AS c
325326
return (centreEntity, resultCount);
326327
}
327328

329+
public Centre? CountRegisterUserByCentreId(int centreId)
330+
{
331+
return connection.QueryFirstOrDefault<Centre>(
332+
$@"SELECT c.CentreID,
333+
c.CentreName,
334+
c.ContactForename,
335+
c.ContactSurname,
336+
c.ContactEmail,
337+
c.ContactTelephone,
338+
c.Active,
339+
c.CentreTypeId,
340+
c.RegionID,
341+
c.AutoRegisterManagerEmail,
342+
(SELECT COUNT(da.ID) AS RegisterUser
343+
FROM DelegateAccounts da WHERE (da.CentreID = c.CentreID) AND (da.Active = 1)) AS RegisterUser
344+
FROM Centres AS c
345+
WHERE c.CentreID = @centreId",
346+
new { centreId }
347+
);
348+
}
349+
328350
public IEnumerable<CentreSummaryForFindYourCentre> GetAllCentreSummariesForFindCentre()
329351
{
330352
return connection.Query<CentreSummaryForFindYourCentre>(

DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public static class ConfigurationExtensions
6060
private const string TableauViewName = "ViewName";
6161
private const string TableauSiteName = "SiteName";
6262
private const string TableauAuthApi = "AuthApiPath";
63+
private const string EmailInvite = "EmailInvite";
6364
public static string GetAppRootPath(this IConfiguration config)
6465
{
6566
return config[AppRootPathName]!;
@@ -268,6 +269,9 @@ public static string GetTableauViewName(this IConfiguration config)
268269
{
269270
return config[$"{TableauSectionKey}:{TableauViewName}"]!;
270271
}
271-
272+
public static string GetEmailInvite(this IConfiguration config)
273+
{
274+
return config[EmailInvite]!;
275+
}
272276
}
273277
}

DigitalLearningSolutions.Data/Models/Centres/Centre.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,9 @@ public class Centre
4343
public DateTime? ContractReviewDate { get; set; }
4444
public string? RegistrationEmail { get; set; }
4545
public bool AddITSPcourses { get; set; }
46+
public int RegisterUser { get; set; }
47+
public string? AutoRegisterManagerEmail { get; set; }
48+
public string? EmailInvite { get; set; }
49+
4650
}
4751
}

DigitalLearningSolutions.Web.Tests/Controllers/SuperAdmin/CentresControllerTests.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
using NUnit.Framework;
1515
using System;
1616
using System.Collections.Generic;
17+
using Microsoft.Extensions.Configuration;
18+
using DigitalLearningSolutions.Data.DataServices;
1719

1820
namespace DigitalLearningSolutions.Web.Tests.Controllers.SuperAdmin
1921
{
@@ -29,6 +31,9 @@ public class CentresControllerTests
2931
private readonly ICentresDownloadFileService centresDownloadFileService = A.Fake<ICentresDownloadFileService>();
3032
private readonly ICentreSelfAssessmentsService centreSelfAssessmentsService = A.Fake<ICentreSelfAssessmentsService>();
3133
private CentresController controller = null!;
34+
private readonly IPasswordResetService passwordResetService = A.Fake<IPasswordResetService>();
35+
private IConfiguration config = A.Fake<IConfiguration>();
36+
private readonly IConfigService configService = A.Fake<IConfigService>();
3237

3338
[SetUp]
3439
public void Setup()
@@ -41,7 +46,10 @@ public void Setup()
4146
contractTypesService,
4247
courseService,
4348
centresDownloadFileService,
44-
centreSelfAssessmentsService
49+
centreSelfAssessmentsService,
50+
passwordResetService,
51+
config,
52+
configService
4553
)
4654
.WithDefaultContext()
4755
.WithMockUser(true);

DigitalLearningSolutions.Web/Controllers/SuperAdmin/Centres/CentresController.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using DigitalLearningSolutions.Data.Enums;
2+
using DigitalLearningSolutions.Data.Extensions;
23
using DigitalLearningSolutions.Data.Helpers;
34
using DigitalLearningSolutions.Data.Models.Centres;
45
using DigitalLearningSolutions.Data.Models.Courses;
6+
using DigitalLearningSolutions.Data.Models.Email;
57
using DigitalLearningSolutions.Data.Models.SearchSortFilterPaginate;
68
using DigitalLearningSolutions.Web.Attributes;
79
using DigitalLearningSolutions.Web.Extensions;
@@ -13,6 +15,7 @@
1315
using Microsoft.AspNetCore.Authorization;
1416
using Microsoft.AspNetCore.Mvc;
1517
using Microsoft.CodeAnalysis.CSharp.Syntax;
18+
using Microsoft.Extensions.Configuration;
1619
using Microsoft.FeatureManagement.Mvc;
1720
using Org.BouncyCastle.Asn1.Misc;
1821
using System;
@@ -35,8 +38,14 @@ public class CentresController : Controller
3538
private readonly ICourseService courseService;
3639
private readonly ICentresDownloadFileService centresDownloadFileService;
3740
private readonly ICentreSelfAssessmentsService centreSelfAssessmentsService;
41+
private readonly IPasswordResetService passwordResetService;
42+
private readonly IConfiguration config;
43+
private readonly IConfigService configService;
44+
45+
3846
public CentresController(ICentresService centresService, ICentreApplicationsService centreApplicationsService, ISearchSortFilterPaginateService searchSortFilterPaginateService,
39-
IRegionService regionService, IContractTypesService contractTypesService, ICourseService courseService, ICentresDownloadFileService centresDownloadFileService, ICentreSelfAssessmentsService centreSelfAssessmentsService)
47+
IRegionService regionService, IContractTypesService contractTypesService, ICourseService courseService, ICentresDownloadFileService centresDownloadFileService,
48+
ICentreSelfAssessmentsService centreSelfAssessmentsService, IPasswordResetService passwordResetService, IConfiguration config, IConfigService configService)
4049
{
4150
this.centresService = centresService;
4251
this.centreApplicationsService = centreApplicationsService;
@@ -46,6 +55,9 @@ public CentresController(ICentresService centresService, ICentreApplicationsServ
4655
this.courseService = courseService;
4756
this.centresDownloadFileService = centresDownloadFileService;
4857
this.centreSelfAssessmentsService = centreSelfAssessmentsService;
58+
this.passwordResetService = passwordResetService;
59+
this.config = config;
60+
this.configService = configService;
4961
}
5062

5163
[Route("SuperAdmin/Centres/{page=0:int}")]
@@ -121,7 +133,20 @@ public IActionResult Index(
121133
null,
122134
new PaginationOptions(page, itemsPerPage)
123135
);
124-
136+
var modifiedCentres = centres.Select(item =>
137+
{
138+
var centreEntity = this.centresService.UpdateCentreWithCounts(item);
139+
if (centreEntity.Centre.RegisterUser == 0 && centreEntity.Centre.AutoRegisterManagerEmail != null)
140+
{
141+
var baseUrl = config.GetEmailInvite();
142+
var supportEmail = this.configService.GetConfigValue("SupportEmail");
143+
baseUrl = baseUrl.Replace("{centreId}", item.Centre.CentreId.ToString());
144+
Email welcomeEmail = this.passwordResetService.GenerateEmailInviteForCentreManager(centreEntity.Centre.CentreName, centreEntity.Centre.AutoRegisterManagerEmail, baseUrl, supportEmail);
145+
centreEntity.Centre.EmailInvite = "mailto:" + string.Join(",", welcomeEmail.To) + "?subject=" + welcomeEmail.Subject + "&body=" + welcomeEmail.Body.TextBody.Replace("&", "%26");
146+
}
147+
return centreEntity;
148+
}).ToList();
149+
centres = modifiedCentres;
125150
var result = searchSortFilterPaginateService.SearchFilterSortAndPaginate(
126151
centres,
127152
searchSortPaginationOptions

DigitalLearningSolutions.Web/Services/CentresService.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ void UpdateCentreDetails(
100100
byte[]? centreSignature,
101101
byte[]? centreLogo
102102
);
103+
CentreEntity UpdateCentreWithCounts(CentreEntity item);
103104
}
104105

105106
public class CentresService : ICentresService
@@ -264,5 +265,12 @@ public void UpdateCentreDetails(int centreId, string? notifyEmail, string banner
264265
{
265266
centresDataService.UpdateCentreDetails(centreId, notifyEmail, bannerText, centreSignature, centreLogo);
266267
}
268+
public CentreEntity UpdateCentreWithCounts(CentreEntity item)
269+
{
270+
var count = this.centresDataService.CountRegisterUserByCentreId(item.Centre.CentreId);
271+
item.Centre.RegisterUser = count.RegisterUser;
272+
item.Centre.AutoRegisterManagerEmail = count.AutoRegisterManagerEmail;
273+
return item;
274+
}
267275
}
268276
}

DigitalLearningSolutions.Web/Services/PasswordResetService.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using DigitalLearningSolutions.Data.Models.Email;
1313
using DigitalLearningSolutions.Data.Models.User;
1414
using DigitalLearningSolutions.Data.Utilities;
15+
using FreshdeskApi.Client.Contacts.Models;
1516
using MimeKit;
1617

1718
public interface IPasswordResetService
@@ -48,6 +49,12 @@ string baseUrl
4849
);
4950

5051
Email GenerateDelegateWelcomeEmail(int delegateId, string baseUrl);
52+
Email GenerateEmailInviteForCentreManager(
53+
string centreName,
54+
string email,
55+
string baseUrl,
56+
string SupportEmail
57+
);
5158
}
5259

5360
public class PasswordResetService : IPasswordResetService
@@ -199,7 +206,21 @@ string baseUrl
199206
);
200207
emailService.ScheduleEmails(emails, addedByProcess, deliveryDate);
201208
}
202-
209+
public Email GenerateEmailInviteForCentreManager(
210+
string centreName,
211+
string email,
212+
string baseUrl,
213+
string SupportEmail
214+
)
215+
{
216+
var emailInvite = GenerateEmailInvite(
217+
centreName,
218+
email,
219+
baseUrl,
220+
SupportEmail
221+
);
222+
return emailInvite;
223+
}
203224
private string GenerateResetPasswordHash(int userId)
204225
{
205226
var hash = Guid.NewGuid().ToString();
@@ -300,5 +321,32 @@ string baseUrl
300321
};
301322
return new Email(emailSubject, body, emailAddress);
302323
}
324+
325+
private static Email GenerateEmailInvite(
326+
string centreName,
327+
string email,
328+
string baseUrl,
329+
string SupportEmail
330+
)
331+
{
332+
var completeRegistrationUrl = new UriBuilder(baseUrl);
333+
const string emailSubject = "Welcome to the Digital Learning Solutions (DLS) Platform";
334+
335+
var body = new BodyBuilder
336+
{
337+
TextBody = $@"Dear Colleague,%0D%0DYour centre, {centreName}, has been successfully registered on the Digital Learning Solutions (DLS), and you’ve been pre-registered as the Centre Manager.%0D%0DTo activate your Centre Manager and Learner accounts, please complete your registration by selecting the link below:%0D%0DComplete Your Registration {completeRegistrationUrl.Uri}%0D%0DPlease use {email} during the registration process to ensure it’s successful.%0D%0DFor any questions or assistance, contact us at {SupportEmail}.%0D%0DKind regards,%0D%0D DLS Support Team",
338+
HtmlBody = $@"<body style= 'font-family: Calibri; font-size: small;'>
339+
<p>Dear Colleague,</p>
340+
<p>Your centre, {centreName}, has been successfully registered on the Digital Learning Solutions (DLS), and you’ve been pre-registered as the Centre Manager.</p>
341+
<p>To activate your Centre Manager and Learner accounts, please complete your registration by selecting the link below:</p>
342+
<p><a href=""{completeRegistrationUrl.Uri}"">Complete Your Registration </a></p>
343+
<p>Please use {email} during the registration process to ensure it’s successful.</p>
344+
<p>For any questions or assistance, contact us at {SupportEmail}.</p>
345+
<p>Kind regards,</p>
346+
<p>DLS Support Team</p>
347+
</body>",
348+
};
349+
return new Email(emailSubject, body, email);
350+
}
303351
}
304352
}

DigitalLearningSolutions.Web/ViewModels/SuperAdmin/Centres/SearchableCentreViewModel.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace DigitalLearningSolutions.Web.ViewModels.SuperAdmin.Centres
22
{
33
using DigitalLearningSolutions.Data.Models.Centres;
4+
using DigitalLearningSolutions.Data.Models.Email;
45
using DigitalLearningSolutions.Data.Models.SearchSortFilterPaginate;
56
using DigitalLearningSolutions.Web.ViewModels.Common.SearchablePage;
67

@@ -21,6 +22,9 @@ ReturnPageQuery returnPageQuery
2122
CentreType = centre.CentreTypes.CentreType;
2223
Active =centre.Centre.Active;
2324
ReturnPageQuery = returnPageQuery;
25+
RegisterUser = centre.Centre.RegisterUser;
26+
AutoRegisterManagerEmail = centre.Centre.AutoRegisterManagerEmail;
27+
EmailInvite = centre.Centre.EmailInvite;
2428
}
2529

2630
public int CentreId { get; set; }
@@ -33,5 +37,8 @@ ReturnPageQuery returnPageQuery
3337
public string CentreType { get; set; }
3438
public bool Active { get; set; }
3539
public ReturnPageQuery ReturnPageQuery { get; set; }
40+
public string EmailInvite { get; set; }
41+
public int RegisterUser { get; set; }
42+
public string AutoRegisterManagerEmail { get; set; }
3643
}
3744
}

DigitalLearningSolutions.Web/Views/SuperAdmin/Centres/_CentreCard.cshtml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@
9494
Reactivate centre
9595
</a>
9696
}
97+
@if (Model.RegisterUser == 0 && Model.AutoRegisterManagerEmail != null)
98+
{
99+
<a class="nhsuk-button nhsuk-button--secondary nhsuk-u-margin-bottom-2" href="@Model.EmailInvite">
100+
Email Invite
101+
</a>
102+
}
97103
</div>
98104
</details>
99105
</div>

DigitalLearningSolutions.Web/appSettings.UAT.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@
2828
"FreshdeskAPIConfig": {
2929
"GroupId": "80000650208",
3030
"ProductId": "80000003097"
31-
}
31+
},
32+
"EmailInvite": "https://www.dls.nhs.uk/dls-uar-uat/RegisterAdmin?centreId={centreId}"
3233
}

0 commit comments

Comments
 (0)