Skip to content

Commit 28853e3

Browse files
authored
Merge pull request #3049 from TechnologyEnhancedLearning/Develop/Features/TD-5219-ImproveFileUploaded
TD-5219 Improvements file uploaded summary and error messages
2 parents 4adbdbd + c53cbe3 commit 28853e3

File tree

7 files changed

+59
-16
lines changed

7 files changed

+59
-16
lines changed

DigitalLearningSolutions.Data/Models/Frameworks/Import/BulkCompetency.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace DigitalLearningSolutions.Data.Models.Frameworks.Import
88
{
99
public class BulkCompetency
1010
{
11-
public int? id { get; set; }
11+
public int? ID { get; set; }
1212
public string? CompetencyGroup { get; set; }
1313
public string? GroupDescription { get; set; }
1414
public string? Competency { get; set; }

DigitalLearningSolutions.Data/Models/Frameworks/Import/CompetencyTableRow.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ public enum RowStatus
1212
CompetencyGroupInserted,
1313
CompetencyGroupUpdated,
1414
CompetencyGroupAndCompetencyUpdated,
15-
InvalidAlwaysShowDescription
15+
InvalidAlwaysShowDescription,
16+
InvalidId
1617
}
1718
public class CompetencyTableRow : BulkCompetency
1819
{
@@ -25,7 +26,7 @@ public CompetencyTableRow(IXLTable table, IXLRangeRow row)
2526
}
2627

2728
RowNumber = row.RowNumber();
28-
id = row.Cell(1).GetValue<int?>();
29+
ID = row.Cell(1).GetValue<int?>();
2930
CompetencyGroup = row.Cell(2).GetValue<string?>();
3031
GroupDescription = row.Cell(3).GetValue<string?>();
3132
Competency = row.Cell(4).GetValue<string?>();
@@ -57,6 +58,10 @@ public bool Validate()
5758
{
5859
Error = ImportCompetenciesResult.ErrorReason.InvalidAlwaysShowDescription;
5960
}
61+
else if (RowStatus == RowStatus.InvalidId)
62+
{
63+
Error = ImportCompetenciesResult.ErrorReason.InvalidId;
64+
}
6065

6166
return !Error.HasValue;
6267
}

DigitalLearningSolutions.Data/Models/Frameworks/Import/ImportCompetenciesResult.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ IReadOnlyCollection<CompetencyTableRow> competencyTableRows
2626
GroupAddedCount = competencyTableRows.Count(dr => dr.RowStatus == RowStatus.CompetencyGroupInserted | dr.RowStatus == RowStatus.CompetencyGroupAndCompetencyInserted);
2727
SkippedCount = competencyTableRows.Count(dr => dr.RowStatus == RowStatus.Skipped);
2828
Errors = competencyTableRows.Where(dr => dr.Error.HasValue).Select(dr => (dr.RowNumber, dr.Error!.Value));
29+
FlagCount = competencyTableRows
30+
.Where(row => !string.IsNullOrWhiteSpace(row.FlagsCsv))
31+
.SelectMany(static row => row.FlagsCsv.Split(',', StringSplitOptions.RemoveEmptyEntries))
32+
.Count();
33+
DistinctFlagsCount = competencyTableRows
34+
.Where(row => !string.IsNullOrWhiteSpace(row.FlagsCsv))
35+
.SelectMany(row => row.FlagsCsv.Split(',', StringSplitOptions.RemoveEmptyEntries))
36+
.Select(flag => flag.Trim())
37+
.Distinct()
38+
.Count();
39+
CompetencyGroupCount = competencyTableRows
40+
.Where(row => !string.IsNullOrWhiteSpace(row.CompetencyGroup))
41+
.Select(static row => row.CompetencyGroup)
42+
.Distinct()
43+
.Count();
2944
}
3045

3146
public IEnumerable<(int RowNumber, ErrorReason Reason)>? Errors { get; set; }
@@ -35,5 +50,8 @@ IReadOnlyCollection<CompetencyTableRow> competencyTableRows
3550
public int GroupAddedCount { get; set; }
3651
public int GroupUpdatedCount { get; set; }
3752
public int SkippedCount { get; set; }
53+
public int FlagCount { get; set; }
54+
public int DistinctFlagsCount { get; set; }
55+
public int CompetencyGroupCount { get; set; }
3856
}
3957
}

DigitalLearningSolutions.Web/Controllers/FrameworksController/ImportCompetencies.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public IActionResult ImportCompleted()
7979
var workbook = new XLWorkbook(filePath);
8080
try
8181
{
82-
var results = importCompetenciesFromFileService.PreProcessCompetenciesTable(workbook, data.FrameworkVocubulary);
82+
var results = importCompetenciesFromFileService.PreProcessCompetenciesTable(workbook, data.FrameworkVocubulary, data.FrameworkId);
8383
var resultsModel = new ImportCompetenciesPreProcessViewModel(results, data) { IsNotBlank = data.IsNotBlank, TabName = data.TabName };
8484
data.CompetenciesToProcessCount = resultsModel.ToProcessCount;
8585
data.CompetenciesToAddCount = resultsModel.CompetenciesToAddCount;

DigitalLearningSolutions.Web/Services/ImportCompetenciesFromFileService.cs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace DigitalLearningSolutions.Web.Services
1616
public interface IImportCompetenciesFromFileService
1717
{
1818
byte[] GetCompetencyFileForFramework(int frameworkId, bool isBlank, string vocabulary);
19-
public ImportCompetenciesResult PreProcessCompetenciesTable(IXLWorkbook workbook, string vocabulary);
19+
public ImportCompetenciesResult PreProcessCompetenciesTable(IXLWorkbook workbook, string vocabulary, int frameworkId);
2020
public ImportCompetenciesResult ProcessCompetenciesFromFile(IXLWorkbook workbook, int adminUserId, int frameworkId, string vocabulary);
2121
}
2222
public class ImportCompetenciesFromFileService : IImportCompetenciesFromFileService
@@ -30,27 +30,36 @@ IFrameworkService frameworkService
3030
{
3131
this.frameworkService = frameworkService;
3232
}
33-
public ImportCompetenciesResult PreProcessCompetenciesTable(IXLWorkbook workbook, string vocabulary)
33+
public ImportCompetenciesResult PreProcessCompetenciesTable(IXLWorkbook workbook, string vocabulary, int frameworkId)
3434
{
3535
var table = OpenCompetenciesTable(workbook, vocabulary);
3636
var competencyRows = table.Rows().Skip(1).Select(row => new CompetencyTableRow(table, row)).ToList();
37+
var existingCompetencies = frameworkService.GetBulkCompetenciesForFramework(frameworkId);
38+
var existingIds = existingCompetencies.Select(bc => (int)bc.ID).ToList();
3739
foreach (var competencyRow in competencyRows)
3840
{
39-
PreProcessCompetencyRow(competencyRow);
41+
PreProcessCompetencyRow(competencyRow, existingIds);
4042
}
4143
return new ImportCompetenciesResult(competencyRows);
4244
}
43-
private void PreProcessCompetencyRow(CompetencyTableRow competencyRow)
45+
private void PreProcessCompetencyRow(CompetencyTableRow competencyRow, List<int> existingIds)
4446
{
45-
competencyRow.Validate();
46-
if (competencyRow.id == null)
47+
if (competencyRow.ID == null)
4748
{
4849
competencyRow.RowStatus = RowStatus.CompetencyInserted;
4950
}
5051
else
5152
{
52-
competencyRow.RowStatus = RowStatus.CompetencyUpdated;
53+
if (!existingIds.Contains((int)(competencyRow?.ID)))
54+
{
55+
competencyRow.RowStatus = RowStatus.InvalidId;
56+
}
57+
else
58+
{
59+
competencyRow.RowStatus = RowStatus.CompetencyUpdated;
60+
}
5361
}
62+
competencyRow.Validate();
5463
}
5564
public ImportCompetenciesResult ProcessCompetenciesFromFile(IXLWorkbook workbook, int adminUserId, int frameworkId, string vocabulary)
5665
{
@@ -77,7 +86,12 @@ internal IXLTable OpenCompetenciesTable(IXLWorkbook workbook, string vocabulary)
7786
internal ImportCompetenciesResult ProcessCompetenciesTable(IXLTable table, int adminUserId, int frameworkId, int maxFrameworkCompetencyId, int maxFrameworkCompetencyGroupId)
7887
{
7988
var competenciesRows = table.Rows().Skip(1).Select(row => new CompetencyTableRow(table, row)).ToList();
80-
89+
90+
var competencyGroupCount = competenciesRows
91+
.Where(row => !string.IsNullOrWhiteSpace(row.CompetencyGroup))
92+
.Select(row => row.CompetencyGroup)
93+
.Distinct()
94+
.Count();
8195
foreach (var competencyRow in competenciesRows)
8296
{
8397
maxFrameworkCompetencyGroupId = ProcessCompetencyRow(adminUserId, frameworkId, maxFrameworkCompetencyId, maxFrameworkCompetencyGroupId, competencyRow);
@@ -167,13 +181,11 @@ public byte[] GetCompetencyFileForFramework(int frameworkId, bool blank, string
167181
}
168182
private void PopulateCompetenciesSheet(IXLWorkbook workbook, int frameworkId, bool blank, string vocabulary)
169183
{
170-
171-
172184
var competencyRecords = frameworkService.GetBulkCompetenciesForFramework(blank ? 0 : frameworkId);
173185
var competencies = competencyRecords.Select(
174186
x => new
175187
{
176-
ID = x.id,
188+
x.ID,
177189
x.CompetencyGroup,
178190
x.GroupDescription,
179191
x.Competency,

DigitalLearningSolutions.Web/ViewModels/Frameworks/Import/ImportCompetenciesPreProcessViewModel.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public ImportCompetenciesPreProcessViewModel(ImportCompetenciesResult bulkCompet
1919
CompetenciesToAddCount = bulkCompetenciesResult.CompetencyAddedCount;
2020
ToUpdateOrSkipCount = bulkCompetenciesResult.CompetencyUpdatedCount;
2121
Errors = bulkCompetenciesResult.Errors.Select(x => (x.RowNumber, MapReasonToErrorMessage(x.Reason, FrameworkVocabularyHelper.VocabularySingular(bulkCompetenciesData.FrameworkVocubulary))));
22+
FlagCount = bulkCompetenciesResult.FlagCount;
23+
DistinctFlagsCount = bulkCompetenciesResult.DistinctFlagsCount;
24+
CompetencyGroupCount = bulkCompetenciesResult.CompetencyGroupCount;
2225
}
2326
public string? FrameworkName { get; set; }
2427
public int PublishStatusID { get; set; }
@@ -32,6 +35,9 @@ public ImportCompetenciesPreProcessViewModel(ImportCompetenciesResult bulkCompet
3235
public string? ImportFile { get; set; }
3336
public bool IsNotBlank { get; set; }
3437
public string TabName { get; set; }
38+
public int FlagCount { get; set; }
39+
public int DistinctFlagsCount { get; set; }
40+
public int CompetencyGroupCount { get; set; }
3541

3642
private static string MapReasonToErrorMessage(ImportCompetenciesResult.ErrorReason reason, string vocabularySingular)
3743
{
@@ -42,7 +48,7 @@ private static string MapReasonToErrorMessage(ImportCompetenciesResult.ErrorReas
4248
ImportCompetenciesResult.ErrorReason.MissingCompetencyName =>
4349
vocabularySingular + " is blank. " + vocabularySingular + " is a required field and cannot be left blank",
4450
ImportCompetenciesResult.ErrorReason.InvalidId =>
45-
"The ID provided does not match a " + vocabularySingular + " ID in this Framework",
51+
"The ID provided does not match a " + vocabularySingular + " ID in this Framework. Leave the ID column blank for new competencies.",
4652
ImportCompetenciesResult.ErrorReason.TooLongCompetencyName =>
4753
vocabularySingular + " must be 500 characters or less.",
4854
ImportCompetenciesResult.ErrorReason.InvalidAlwaysShowDescription =>

DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportCompleted.cshtml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
<li>@Model.ToProcessCount @(Model.ToProcessCount == 1 ? "row" : "rows") to process</li>
3636
<li>@Model.CompetenciesToAddCount new @(Model.CompetenciesToAddCount == 1 ? Model.FrameworkVocabularySingular.ToLower() : Model.FrameworkVocabularyPlural.ToLower()) to add</li>
3737
<li>@Model.ToUpdateOrSkipCount @Model.FrameworkVocabularySingular.ToLower() @(Model.ToUpdateOrSkipCount == 1 ? "record" : "records") to update (or skip if unchanged)</li>
38+
<li>In @Model.CompetencyGroupCount @Model.FrameworkVocabularySingular.ToLower() groups</li>
39+
<li>With a total of @Model.FlagCount flags assigned to @Model.FrameworkVocabularyPlural.ToLower() (@Model.DistinctFlagsCount distinct flags)</li>
3840
@if (Model.ErrorCount > 0)
3941
{
4042
<li>@Model.ErrorCount @(Model.ErrorCount == 1 ? "row" : "rows") containing errors that cannot be processed</li>

0 commit comments

Comments
 (0)