diff --git a/DigitalLearningSolutions.Web/Controllers/FrameworksController/ImportCompetencies.cs b/DigitalLearningSolutions.Web/Controllers/FrameworksController/ImportCompetencies.cs index dad1bbd4c1..1e77c8f05c 100644 --- a/DigitalLearningSolutions.Web/Controllers/FrameworksController/ImportCompetencies.cs +++ b/DigitalLearningSolutions.Web/Controllers/FrameworksController/ImportCompetencies.cs @@ -4,9 +4,14 @@ using DigitalLearningSolutions.Web.Models; using DigitalLearningSolutions.Web.Services; using DigitalLearningSolutions.Web.ViewModels.Frameworks.Import; +using DocumentFormat.OpenXml.Office2010.ExcelAc; using GDS.MultiPageFormData.Enums; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.DotNet.Scaffolding.Shared.Project; +using System.Collections.Generic; using System.IO; +using System.Linq; namespace DigitalLearningSolutions.Web.Controllers.FrameworksController { @@ -87,15 +92,69 @@ public IActionResult ImportCompleted() catch (InvalidHeadersException) { FileHelper.DeleteFile(webHostEnvironment, data.CompetenciesFileName); - return View("ImportFailed"); + return View("Developer/Import/ImportFailed"); } } [Route("/Framework/{frameworkId}/{tabname}/Import/AssessmentQuestions")] public IActionResult AddAssessmentQuestions() { var data = GetBulkUploadData(); - - return View(); + var adminId = GetAdminId(); + var defaultQuestions = frameworkService.GetFrameworkDefaultQuestionsById(data.FrameworkId, adminId); + if (!data.DefaultQuestionIDs.Any() && defaultQuestions.Any() && data.AddDefaultAssessmentQuestions == true) + { + var defaultQuestionsList = new List(); + foreach (var question in defaultQuestions) + { + defaultQuestionsList.Add(question.ID); + } + data.DefaultQuestionIDs = defaultQuestionsList; + setBulkUploadData(data); + } + var questionList = frameworkService.GetAssessmentQuestions(data.FrameworkId, adminId).ToList(); + var questionSelectList = new SelectList(questionList, "ID", "Label"); + var model = new AddAssessmentQuestionsViewModel + ( + data.FrameworkId, + data.FrameworkName, + data.FrameworkVocubulary, + data.PublishStatusID, + data.CompetenciesToAddCount, + data.CompetenciesToUpdateCount, + defaultQuestions, + questionSelectList + ); + model.AddDefaultAssessmentQuestions = data.AddDefaultAssessmentQuestions; + model.AddCustomAssessmentQuestion = data.AddCustomAssessmentQuestion; + model.DefaultAssessmentQuestionIDs = data.DefaultQuestionIDs; + model.CustomAssessmentQuestionID = data.CustomAssessmentQuestionID; + return View("Developer/Import/AddAssessmentQuestions", model); + } + [HttpPost] + [Route("/Framework/{frameworkId}/{tabname}/Import/AssessmentQuestions")] + public IActionResult AddAssessmentQuestions(AddAssessmentQuestionsFormData model) + { + var data = GetBulkUploadData(); + data.AddDefaultAssessmentQuestions = model.AddDefaultAssessmentQuestions; + if (model.AddDefaultAssessmentQuestions) + { + data.DefaultQuestionIDs = model.DefaultAssessmentQuestionIDs; + } + else + { + data.DefaultQuestionIDs = []; + } + data.AddCustomAssessmentQuestion = model.AddCustomAssessmentQuestion; + if (model.AddCustomAssessmentQuestion) + { + data.CustomAssessmentQuestionID = model.CustomAssessmentQuestionID; + } + else + { + data.CustomAssessmentQuestionID = null; + } + setBulkUploadData(data); + return RedirectToAction("AddQuestionsToWhichCompetencies"); } private void setupBulkUploadData(int frameworkId, int adminUserID, string competenciessFileName, string tabName, bool isNotBlank) { diff --git a/DigitalLearningSolutions.Web/Models/BulkCompetenciesData.cs b/DigitalLearningSolutions.Web/Models/BulkCompetenciesData.cs index 44ae69f92b..bf7cb9b61d 100644 --- a/DigitalLearningSolutions.Web/Models/BulkCompetenciesData.cs +++ b/DigitalLearningSolutions.Web/Models/BulkCompetenciesData.cs @@ -27,8 +27,10 @@ public BulkCompetenciesData(DetailFramework framework, int adminUserId, string c public int AdminUserId { get; set; } public bool IsNotBlank { get; set; } public string CompetenciesFileName { get; set; } - public List AssessmentQuestionIDs { get; set; } - public int? AddAssessmentQuestionOption { get; set; } + public List DefaultQuestionIDs { get; set; } = []; + public int? CustomAssessmentQuestionID { get; set; } + public bool AddDefaultAssessmentQuestions { get; set; } = true; + public bool AddCustomAssessmentQuestion { get; set; } = false; public int CompetenciesToProcessCount { get; set; } public int CompetenciesToAddCount { get; set; } public int CompetenciesToUpdateCount { get; set; } diff --git a/DigitalLearningSolutions.Web/ViewModels/Frameworks/Import/AddAssessmentQuestionsFormData.cs b/DigitalLearningSolutions.Web/ViewModels/Frameworks/Import/AddAssessmentQuestionsFormData.cs new file mode 100644 index 0000000000..4b90f1198c --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/Frameworks/Import/AddAssessmentQuestionsFormData.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace DigitalLearningSolutions.Web.ViewModels.Frameworks.Import +{ + public class AddAssessmentQuestionsFormData + { + public bool AddDefaultAssessmentQuestions { get; set; } + public bool AddCustomAssessmentQuestion { get; set; } + public List DefaultAssessmentQuestionIDs { get; set; } + public int? CustomAssessmentQuestionID { get; set; } + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/Frameworks/Import/AddAssessmentQuestionsViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Frameworks/Import/AddAssessmentQuestionsViewModel.cs new file mode 100644 index 0000000000..bfd1cf3d12 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/Frameworks/Import/AddAssessmentQuestionsViewModel.cs @@ -0,0 +1,29 @@ +using DigitalLearningSolutions.Data.Models.Frameworks; +using DigitalLearningSolutions.Web.Helpers; +using Microsoft.AspNetCore.Mvc.Rendering; +using System.Collections.Generic; + +namespace DigitalLearningSolutions.Web.ViewModels.Frameworks.Import +{ + public class AddAssessmentQuestionsViewModel( + int frameworkId, + string frameworkName, + string frameworkVocabulary, + int publishStatusId, + int newCompetencies, + int existingCompetencies, + IEnumerable defaultQuestions, + SelectList questionSelectList + ) : AddAssessmentQuestionsFormData + { + public int FrameworkID { get; set; } = frameworkId; + public string FrameworkName { get; set; } = frameworkName; + public string FrameworkVocabularySingular { get; set; } = FrameworkVocabularyHelper.VocabularySingular(frameworkVocabulary); + public string FrameworkVocabularyPlural { get; set; } = FrameworkVocabularyHelper.VocabularyPlural(frameworkVocabulary); + public int PublishStatusID { get; set; } = publishStatusId; + public int NewCompetencies { get; set; } = newCompetencies; + public int ExistingCompetencies { get; set; } = existingCompetencies; + public IEnumerable? DefaultQuestions { get; set; } = defaultQuestions; + public SelectList? QuestionSelectList { get; set; } = questionSelectList; + } +} diff --git a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/AddAssessmentQuestions.cshtml b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/AddAssessmentQuestions.cshtml new file mode 100644 index 0000000000..ae9cdec7c2 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/AddAssessmentQuestions.cshtml @@ -0,0 +1,104 @@ +@using DigitalLearningSolutions.Web.Extensions +@using DigitalLearningSolutions.Web.ViewModels.Frameworks.Import + +@model AddAssessmentQuestionsViewModel + +@{ + ViewData["Application"] = "Framework Service"; + ViewData["HeaderPathName"] = "Framework Service"; + var errorHasOccurred = !ViewData.ModelState.IsValid; + var checkListErrorClass = !ViewData.ModelState.IsValid && Model.AddDefaultAssessmentQuestions == null ? "nhsuk-form-group nhsuk-form-group--error" : "nhsuk-form-group"; + ViewData["Title"] = errorHasOccurred ? "Error: Add Assessment Questions" : "Add Assessment Questions"; + var cancelLinkData = Html.GetRouteValues(); + var hintTextString = Model.NewCompetencies != 0 && Model.ExistingCompetencies != 0 ? "new and/or updated " : (Model.NewCompetencies == 0 ? "updated " : "new "); +} + +@section NavMenuItems { + +} +@section NavBreadcrumbs { + +} +
+
+
+ @if (errorHasOccurred) + { + + } +
+
+
+ +

+ @ViewData["Title"] +

+
+
+ Which assessment questions would you like to attach to the @hintTextString @Model.FrameworkVocabularyPlural.ToLower()? +
+
+ @if (Model.DefaultQuestions.Any()) + { +
+ + +
+ choose which default questions associated with this framework to add to the imported and/or updated @Model.FrameworkVocabularyPlural.ToLower() +
+
+ +
+
+ @foreach (var (defaultQuestion, index) in Model.DefaultQuestions.Select((t, i) => (t, i))) + { +
+ + +
+ } +
+
+
+
+ } +
+ + +
+
+ + + +
+
+
+
+ +
+ +
+
+
diff --git a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportCompleted.cshtml b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportCompleted.cshtml index 1db1e511ba..fcabc89014 100644 --- a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportCompleted.cshtml +++ b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportCompleted.cshtml @@ -26,60 +26,64 @@ } -

Delegate file uploaded

-
-

@(Model.ErrorCount == 0 ? "Your file is error free and ready to be processed. Check the information below looks, correct before processing" : "Your file contains the following, including some errors:")

-
    -
  • @Model.ToProcessCount @(Model.ToProcessCount == 1 ? "row" : "rows") to process
  • -
  • @Model.CompetenciesToAddCount new @(Model.CompetenciesToAddCount == 1 ? Model.FrameworkVocabularySingular.ToLower() : Model.FrameworkVocabularyPlural.ToLower()) to add
  • -
  • @Model.ToUpdateOrSkipCount @Model.FrameworkVocabularySingular.ToLower() @(Model.ToUpdateOrSkipCount == 1 ? "record" : "records") to update (or skip if unchanged)
  • - @if (Model.ErrorCount > 0) - { -
  • @Model.ErrorCount @(Model.ErrorCount == 1 ? "row" : "rows") containing errors that cannot be processed
  • - } - else - { -
  • No errors
  • - } -
- @if (Model.ErrorCount == 0) - { - Continue - } - else - { -

Check the information below. You will need fix these errors before continuing or remove the rows with errors from your spreadsheet:

-
- - Error: @Model.ErrorCount @Model.FrameworkVocabularySingular.ToLower() @(Model.ErrorCount == 1 ? "row" : "rows") contain errors and cannot be processed - -
- @foreach (var (rowNumber, errorMessage) in Model.Errors) +
+
+

Delegate file uploaded

+
+

@(Model.ErrorCount == 0 ? "Your file is error free and ready to be processed. Check the information below looks, correct before processing" : "Your file contains the following, including some errors:")

+
    +
  • @Model.ToProcessCount @(Model.ToProcessCount == 1 ? "row" : "rows") to process
  • +
  • @Model.CompetenciesToAddCount new @(Model.CompetenciesToAddCount == 1 ? Model.FrameworkVocabularySingular.ToLower() : Model.FrameworkVocabularyPlural.ToLower()) to add
  • +
  • @Model.ToUpdateOrSkipCount @Model.FrameworkVocabularySingular.ToLower() @(Model.ToUpdateOrSkipCount == 1 ? "record" : "records") to update (or skip if unchanged)
  • + @if (Model.ErrorCount > 0) { -
    -
    - Row @rowNumber -
    -
    - @errorMessage -
    - -
    +
  • @Model.ErrorCount @(Model.ErrorCount == 1 ? "row" : "rows") containing errors that cannot be processed
  • } -
-
-

Upload corrected file

-

- Once you have made corrections to the Excel competency workbook to address the errors above, save and restart the upload process. -

-
+ else + { +
  • No errors
  • + } + + @if (Model.ErrorCount == 0) + { + Continue + } + else + { +

    Check the information below. You will need fix these errors before continuing or remove the rows with errors from your spreadsheet:

    +
    + + Error: @Model.ErrorCount @Model.FrameworkVocabularySingular.ToLower() @(Model.ErrorCount == 1 ? "row" : "rows") contain errors and cannot be processed + +
    + @foreach (var (rowNumber, errorMessage) in Model.Errors) + { +
    +
    + Row @rowNumber +
    +
    + @errorMessage +
    + +
    + } +
    +
    +

    Upload corrected file

    +

    + Once you have made corrections to the Excel competency workbook to address the errors above, save and restart the upload process. +

    + - - - + + + - - - } - + + + } + +
    + diff --git a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportFailed.cshtml b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportFailed.cshtml index c16803e9df..1001851c70 100644 --- a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportFailed.cshtml +++ b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/ImportFailed.cshtml @@ -30,7 +30,7 @@

    Import failed

    -
    +

    The file that you uploaded either does not have the correct column headers on the first row or is not formatted as a table.

    diff --git a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/Index.cshtml b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/Index.cshtml index 649f7a608f..a11a391b24 100644 --- a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/Index.cshtml +++ b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/Index.cshtml @@ -31,7 +31,7 @@ }

    Bulk upload @(Model.IsNotBlank ? "or update" : "") @Model.FrameworkVocabularyPlural.ToLower()

    -
    +
    @if (Model.PublishStatusID == 3) { diff --git a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/UploadResults.cshtml b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/UploadResults.cshtml index 16aac10fde..d83d3ca428 100644 --- a/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/UploadResults.cshtml +++ b/DigitalLearningSolutions.Web/Views/Frameworks/Developer/Import/UploadResults.cshtml @@ -30,7 +30,7 @@

    Import competencies complete

    -
    +

    Summary of results:

    • @Model.ProcessedCount @(Model.ProcessedCount == 1 ? "line" : "lines") processed