Skip to content

Commit 2200599

Browse files
authored
Merge pull request #2141 from TechnologyEnhancedLearning/Develop/Features/TD-2492-Restrict-the-number-of-rows-that-can-be-uploaded-for-bulk-update-in-Excel_
TD-2492 restrict the number of rows that can be uploaded for bulk update in excel
2 parents 4dd393b + 5aa26e0 commit 2200599

File tree

13 files changed

+44
-13
lines changed

13 files changed

+44
-13
lines changed

DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public static class ConfigurationExtensions
3737
private const string LearningHubReportAPIClientId = "LearningHubReportAPIConfig:ClientId";
3838
private const string LearningHubReportAPIClientIdentityKey = "LearningHubReportAPIConfig:ClientIdentityKey";
3939
private const string ExportQueryRowLimitKey = "FeatureManagement:ExportQueryRowLimit";
40+
private const string MaxBulkUploadRowsLimitKey = "FeatureManagement:MaxBulkUploadRows";
4041
public static string GetAppRootPath(this IConfiguration config)
4142
{
4243
return config[AppRootPathName];
@@ -152,6 +153,9 @@ public static int GetExportQueryRowLimit(this IConfiguration config)
152153
{
153154
return int.Parse(config[ExportQueryRowLimitKey]);
154155
}
155-
156+
public static int GetMaxBulkUploadRowsLimit(this IConfiguration config)
157+
{
158+
return int.Parse(config[MaxBulkUploadRowsLimitKey]);
159+
}
156160
}
157161
}

DigitalLearningSolutions.Web/Controllers/TrackingSystem/Delegates/BulkUploadController.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
using Microsoft.AspNetCore.Authorization;
1313
using Microsoft.AspNetCore.Mvc;
1414
using Microsoft.FeatureManagement.Mvc;
15-
15+
using Microsoft.Extensions.Configuration;
16+
using ConfigurationExtensions = DigitalLearningSolutions.Data.Extensions.ConfigurationExtensions;
1617
[FeatureGate(FeatureFlags.RefactoredTrackingSystem)]
1718
[Authorize(Policy = CustomPolicies.UserCentreAdmin)]
1819
[SetDlsSubApplication(nameof(DlsSubApplication.TrackingSystem))]
@@ -23,23 +24,30 @@ public class BulkUploadController : Controller
2324
private readonly IDelegateDownloadFileService delegateDownloadFileService;
2425
private readonly IDelegateUploadFileService delegateUploadFileService;
2526
private readonly IClockUtility clockUtility;
26-
27+
private readonly IConfiguration configuration;
2728
public BulkUploadController(
2829
IDelegateDownloadFileService delegateDownloadFileService,
2930
IDelegateUploadFileService delegateUploadFileService,
30-
IClockUtility clockUtility
31+
IClockUtility clockUtility, IConfiguration configuration
3132
)
3233
{
3334
this.delegateDownloadFileService = delegateDownloadFileService;
3435
this.delegateUploadFileService = delegateUploadFileService;
3536
this.clockUtility = clockUtility;
37+
this.configuration = configuration;
3638
}
3739

3840
public IActionResult Index()
3941
{
42+
int MaxBulkUploadRows = GetMaxBulkUploadRowsLimit();
43+
TempData["MaxBulkUploadRows"] = MaxBulkUploadRows;
4044
return View();
4145
}
46+
private int GetMaxBulkUploadRowsLimit()
47+
{
48+
return ConfigurationExtensions.GetMaxBulkUploadRowsLimit(configuration);
4249

50+
}
4351
[Route("DownloadDelegates")]
4452
public IActionResult DownloadDelegates()
4553
{
@@ -61,13 +69,20 @@ public IActionResult StartUpload()
6169
{
6270
TempData.Clear();
6371
var model = new UploadDelegatesViewModel(clockUtility.UtcToday);
72+
model.MaxBulkUploadRows = GetMaxBulkUploadRowsLimit();
6473
return View("StartUpload", model);
6574
}
6675

6776
[Route("StartUpload")]
6877
[HttpPost]
6978
public IActionResult StartUpload(UploadDelegatesViewModel model)
7079
{
80+
int MaxBulkUploadRows = GetMaxBulkUploadRowsLimit();
81+
int ExcelRowsCount = delegateUploadFileService.GetBulkUploadExcelRowCount(model.DelegatesFile);
82+
if (ExcelRowsCount > MaxBulkUploadRows)
83+
{
84+
ModelState.AddModelError("MaxBulkUploadRows", string.Format(CommonValidationErrorMessages.MaxBulkUploadRowsLimit, MaxBulkUploadRows));
85+
}
7186
if (!ModelState.IsValid)
7287
{
7388
return View("StartUpload", model);

DigitalLearningSolutions.Web/Helpers/CommonValidationErrorMessages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ public static class CommonValidationErrorMessages
3434
public const string PrimaryEmailInUseDuringDelegateRegistration =
3535
"A user with this email address is already registered";
3636
public const string CentreNameAlreadyExist = "The centre name you have entered already exists, please enter a different centre name";
37+
public const string MaxBulkUploadRowsLimit = "File must contain no more than {0} rows";
3738
}
3839
}

DigitalLearningSolutions.Web/Services/DelegateUploadFileService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace DigitalLearningSolutions.Web.Services
2020
{
2121
public interface IDelegateUploadFileService
2222
{
23+
public int GetBulkUploadExcelRowCount(IFormFile delegatesFile);
2324
public BulkUploadResult ProcessDelegatesFile(IFormFile file, int centreId, DateTime welcomeEmailDate);
2425
}
2526

@@ -310,5 +311,9 @@ private static bool ValidateHeaders(IXLTable table)
310311
var actualHeaders = table.Fields.Select(x => x.Name).OrderBy(x => x);
311312
return actualHeaders.SequenceEqual(expectedHeaders);
312313
}
314+
public int GetBulkUploadExcelRowCount(IFormFile delegatesFile)
315+
{
316+
return OpenDelegatesTable(delegatesFile).AsNativeDataTable().Rows.Count;
317+
}
313318
}
314319
}

DigitalLearningSolutions.Web/ViewModels/TrackingSystem/Delegates/UploadDelegatesViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public UploadDelegatesViewModel(DateTime welcomeEmailDate)
2121
[AllowedExtensions(new[] { ".xlsx" }, "Delegates update file must be in xlsx format")]
2222
[MaxFileSize(5 * 1024 * 1024, "Maximum allowed file size is 5MB")]
2323
public IFormFile? DelegatesFile { get; set; }
24-
24+
public int MaxBulkUploadRows { get; set; }
2525
public DateTime GetWelcomeEmailDate()
2626
{
2727
return new DateTime(Year!.Value, Month!.Value, Day!.Value);

DigitalLearningSolutions.Web/Views/TrackingSystem/Delegates/BulkUpload/Index.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<p class="nhsuk-body-m">
2929
Once you have downloaded, amended and saved the Excel delegates sheet above, start the upload to process your changes.
3030
</p>
31-
31+
<p class="nhsuk-body-m">If your spreadsheet is large, you must split it so that each uploaded sheet contains no more than @TempData["MaxBulkUploadRows"] rows.</p>
3232
<a class="nhsuk-button nhsuk-u-margin-bottom-7" role="button" asp-controller="BulkUpload" asp-action="StartUpload">
3333
Start upload
3434
</a>

DigitalLearningSolutions.Web/Views/TrackingSystem/Delegates/BulkUpload/StartUpload.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
css-class="@(errorHasOccurred ? " nhsuk-u-padding-left-5 nhsuk-u-margin-bottom-3" : "")"
3030
hint-text-lines="@hintTextLines" />
3131

32-
<vc:file-input asp-for="@nameof(Model.DelegatesFile)" label="File with updated information" hint-text="" css-class="nhsuk-u-width-one-half" />
32+
<vc:file-input asp-for="@nameof(Model.DelegatesFile)" label="File with updated information (max @(Model.MaxBulkUploadRows) rows)" hint-text="" css-class="nhsuk-u-width-one-half" />
3333

3434
<button class="nhsuk-button" type="submit">Upload and process</button>
3535
</form>

DigitalLearningSolutions.Web/appSettings.UAT.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"PricingPage": false,
2121
"RefactoredFindYourCentrePage": true,
2222
"UserFeedbackBar": true,
23-
"ExportQueryRowLimit": 250
23+
"ExportQueryRowLimit": 250,
24+
"MaxBulkUploadRows": 200
2425
},
2526
"LearningHubOpenAPIBaseUrl": "https://uks-learninghubnhsuk-openapi-test.azurewebsites.net"
2627
}

DigitalLearningSolutions.Web/appsettings.Development.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"PricingPage": true,
2121
"RefactoredFindYourCentrePage": true,
2222
"UserFeedbackBar": true,
23-
"ExportQueryRowLimit": 250
23+
"ExportQueryRowLimit": 250,
24+
"MaxBulkUploadRows": 200
2425
},
2526
"LearningHubOpenAPIBaseUrl": "https://uks-learninghubnhsuk-openapi-test.azurewebsites.net",
2627
"LearningHubReportAPIConfig": {

DigitalLearningSolutions.Web/appsettings.Production.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"PricingPage": false,
2121
"RefactoredFindYourCentrePage": true,
2222
"UserFeedbackBar": true,
23-
"ExportQueryRowLimit": 250
23+
"ExportQueryRowLimit": 250,
24+
"MaxBulkUploadRows": 200
2425
},
2526
"LearningHubOpenAPIBaseUrl": "https://learninghubnhsuk-openapi-prod.azurewebsites.net",
2627
"LearningHubReportAPIConfig": {

0 commit comments

Comments
 (0)