diff --git a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Maturity/CmmcBusiness.cs b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Maturity/CmmcBusiness.cs
index efd6045581..8a3cb50353 100644
--- a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Maturity/CmmcBusiness.cs
+++ b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Maturity/CmmcBusiness.cs
@@ -24,11 +24,6 @@ public class CmmcBusiness
private CSETContext _context;
private readonly IAssessmentUtil _assessmentUtil;
private readonly IAdminTabBusiness _adminTabBusiness;
-
- private int _maturityModelId;
-
- private static object myLock = new object();
-
private TranslationOverlay _overlay;
private AdditionalSupplemental _addlSuppl;
@@ -107,12 +102,12 @@ public int GetScoreForLevel(int assessmentId, int level)
var levelId = _context.MATURITY_LEVELS
.Where(x => x.Level == level && x.Maturity_Model_Id == modelIdCmmc2)
.Select(x => x.Maturity_Level_Id)
- .FirstOrDefault();
+ .FirstOrDefault();
var query = from a in _context.ANSWER
- join q in _context.MATURITY_QUESTIONS on a.Question_Or_Requirement_Id equals q.Mat_Question_Id
- where q.Maturity_Level_Id == levelId && a.Assessment_Id == assessmentId
- select a;
+ join q in _context.MATURITY_QUESTIONS on a.Question_Or_Requirement_Id equals q.Mat_Question_Id
+ where q.Maturity_Level_Id == levelId && a.Assessment_Id == assessmentId
+ select a;
var answerList = query.ToList().Select(x => x.Answer_Text).ToList();
diff --git a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/CieReportsData.cs b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/CieReportsData.cs
new file mode 100644
index 0000000000..84539a2f48
--- /dev/null
+++ b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/CieReportsData.cs
@@ -0,0 +1,678 @@
+////////////////////////////////
+//
+// Copyright 2024 Battelle Energy Alliance, LLC
+//
+//
+////////////////////////////////
+using CSETWebCore.DataLayer.Model;
+using CSETWebCore.Interfaces.Reports;
+using CSETWebCore.Model.Document;
+using CSETWebCore.Model.Maturity;
+using CSETWebCore.Model.Question;
+using Microsoft.EntityFrameworkCore;
+using System.Collections.Generic;
+using System.Linq;
+
+
+namespace CSETWebCore.Business.Reports
+{
+ public partial class ReportsDataBusiness : IReportsDataBusiness
+ {
+
+ ///
+ /// Formats the Title for CIE observations the way they want
+ ///
+ ///
+ private void GetQuestionTitleAndTextForCie(dynamic f,
+ List stdList, List compList,
+ int answerId,
+ out string identifier, out string questionText)
+ {
+ identifier = "";
+ questionText = "";
+ var lang = _tokenManager.GetCurrentLanguage();
+
+ identifier = f.mq.Question_Title;
+ questionText = f.mq.Question_Text;
+ int groupId = f.mq.Grouping_Id ?? 0;
+
+ var groupRow = _context.MATURITY_GROUPINGS.Where(x => x.Grouping_Id == groupId).FirstOrDefault();
+ int principleNumber = 0;
+ int phaseNumber = 0;
+
+ if (groupRow.Group_Level == 2)
+ {
+ // tracking the principle number
+ principleNumber = groupRow.Sequence;
+ identifier = "Principle " + principleNumber + " - " + identifier;
+ }
+ else if (groupRow.Group_Level == 3)
+ {
+ // tracking the phase number
+ // the -1 is because the "General" grouping is first at Sequence = 1, but it's hidden from the user for now (request from the client)
+ phaseNumber = groupRow.Sequence - 1;
+
+ // finding the principle number
+ groupRow = _context.MATURITY_GROUPINGS.Where(x => x.Grouping_Id == groupRow.Parent_Id).FirstOrDefault();
+ principleNumber = groupRow.Sequence;
+
+ identifier = "Principle " + principleNumber + " - Phase " + phaseNumber + " - " + identifier;
+ }
+ }
+
+
+ public List GetCieQuestionList(int matLevel, bool filterForNa = false)
+ {
+ List controls = new List();
+
+
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ //var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+ List questions = new List();
+
+ questions = _context.MATURITY_QUESTIONS.Where(q =>
+ myModel.model_id == q.Maturity_Model_Id).ToList();
+
+ // Get all MATURITY answers for the assessment
+ //IQueryable answers = new IQueryable();
+
+ var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
+ from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
+ select new FullAnswer() { a = a, b = b };
+
+ if (filterForNa)
+ {
+ answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity" && x.Answer_Text == "NA")
+ from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
+ select new FullAnswer() { a = a, b = b };
+ }
+
+ Dictionary> docDictionary = new Dictionary>();
+
+ List documentList = new List();
+
+ var results = (from f in _context.DOCUMENT_FILE
+ join da in _context.DOCUMENT_ANSWERS on f.Document_Id equals da.Document_Id
+ join a in _context.ANSWER on da.Answer_Id equals a.Answer_Id
+ join q in _context.MATURITY_QUESTIONS on a.Question_Or_Requirement_Id equals q.Mat_Question_Id
+ where f.Assessment_Id == _assessmentId
+ select new { f, da, a, q }).ToList();
+
+ var questionIds = results.DistinctBy(x => x.q.Mat_Question_Id).ToList();
+
+ results.ForEach(doc =>
+ {
+ DocumentWithAnswerId newDoc = new DocumentWithAnswerId()
+ {
+ Answer_Id = doc.da.Answer_Id,
+ Title = doc.f.Title,
+ FileName = doc.f.Name,
+ Document_Id = doc.da.Document_Id,
+ Question_Id = doc.a.Question_Or_Requirement_Id,
+ Question_Title = doc.q.Question_Title
+ };
+ documentList.Add(newDoc);
+ if (docDictionary.ContainsKey(newDoc.Question_Id))
+ {
+ docDictionary[newDoc.Question_Id].Add(newDoc);
+ }
+ else
+ {
+ docDictionary.Add(newDoc.Question_Id, [newDoc]);
+ }
+ });
+
+ // Get all subgroupings for this maturity model
+ var allGroupings = _context.MATURITY_GROUPINGS
+ .Include(x => x.Type)
+ .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ //Get All the Observations and issues with the Observations.
+
+
+ // Recursively build the grouping/question hierarchy
+ var questionGrouping = new MaturityGrouping();
+ BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
+
+ var maturityDomains = new List();
+
+ // ToDo: Refactor the following stucture of loops
+ foreach (var domain in questionGrouping.SubGroupings)
+ {
+ var newDomain = new MatAnsweredQuestionDomain()
+ {
+ Title = domain.Title,
+ IsDeficient = false,
+ AssessmentFactors = new List()
+ };
+ foreach (var assesmentFactor in domain.SubGroupings)
+ {
+ var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
+ {
+ Title = assesmentFactor.Title,
+ IsDeficient = false,
+ Components = new List(),
+ Questions = new List()
+ };
+
+
+ if (assesmentFactor.Questions.Count > 0)
+ {
+ foreach (var question in assesmentFactor.Questions)
+ {
+ // if the report shows N/A only, make sure the answer's included are only "NA"
+ if (question.Answer != null && (filterForNa ? question.Answer == "NA" : true))
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = question.MaturityLevel.ToString(),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer,
+ Documents = docDictionary.ContainsKey(question.QuestionId) ? docDictionary[question.QuestionId] : null,
+ Visible = true
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+ if (newQuestion.MaturityLevel == "5")
+ {
+ newAssesmentFactor.Questions.Add(newQuestion);
+ }
+ }
+ }
+ }
+ foreach (var component in assesmentFactor.SubGroupings)
+ {
+ var newComponent = new MaturityAnsweredQuestionsComponent()
+ {
+ Title = component.Title,
+ IsDeficient = false,
+ Questions = new List(),
+ };
+
+ foreach (var question in component.Questions)
+ {
+ if (question.Answer != null)
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = question.MaturityLevel.ToString(),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer,
+ Documents = docDictionary.ContainsKey(question.QuestionId) ? docDictionary[question.QuestionId] : null,
+ Visible = true
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ newComponent.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+
+ newComponent.Questions.Add(newQuestion);
+ }
+ }
+ if (newComponent.Questions.Count > 0)
+ {
+ newAssesmentFactor.Components.Add(newComponent);
+ //newAssesmentFactor.Questions.AddRange(newComponent.Questions);
+ }
+ }
+ if (newAssesmentFactor.Components.Count > 0)
+ {
+ newDomain.AssessmentFactors.Add(newAssesmentFactor);
+ }
+ //}
+
+ }
+ if (newDomain.AssessmentFactors.Count > 0)
+ {
+ maturityDomains.Add(newDomain);
+ }
+ }
+
+ return maturityDomains;
+ }
+
+ public List GetCieMfrQuestionList()
+ {
+ List controls = new List();
+
+
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ //var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+ List questions = new List();
+
+ questions = _context.MATURITY_QUESTIONS.Where(q =>
+ myModel.model_id == q.Maturity_Model_Id).ToList();
+
+ // Get all MATURITY answers for the assessment
+ //IQueryable answers = new IQueryable();
+
+ var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
+ from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
+ select new FullAnswer() { a = a, b = b };
+
+ Dictionary> docDictionary = new Dictionary>();
+
+ List documentList = new List();
+
+ var results = (from f in _context.DOCUMENT_FILE
+ join da in _context.DOCUMENT_ANSWERS on f.Document_Id equals da.Document_Id
+ join a in _context.ANSWER on da.Answer_Id equals a.Answer_Id
+ join q in _context.MATURITY_QUESTIONS on a.Question_Or_Requirement_Id equals q.Mat_Question_Id
+ where f.Assessment_Id == _assessmentId
+ select new { f, da, a, q }).ToList();
+
+ var questionIds = results.DistinctBy(x => x.q.Mat_Question_Id).ToList();
+
+ results.ForEach(doc =>
+ {
+ DocumentWithAnswerId newDoc = new DocumentWithAnswerId()
+ {
+ Answer_Id = doc.da.Answer_Id,
+ Title = doc.f.Title,
+ FileName = doc.f.Name,
+ Document_Id = doc.da.Document_Id,
+ Question_Id = doc.a.Question_Or_Requirement_Id,
+ Question_Title = doc.q.Question_Title
+ };
+ documentList.Add(newDoc);
+ if (docDictionary.ContainsKey(newDoc.Question_Id))
+ {
+ docDictionary[newDoc.Question_Id].Add(newDoc);
+ }
+ else
+ {
+ docDictionary.Add(newDoc.Question_Id, [newDoc]);
+ }
+ });
+
+ // Get all subgroupings for this maturity model
+ var allGroupings = _context.MATURITY_GROUPINGS
+ .Include(x => x.Type)
+ .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ //Get All the Observations and issues with the Observations.
+
+
+ // Recursively build the grouping/question hierarchy
+ var questionGrouping = new MaturityGrouping();
+ BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
+
+ var maturityDomains = new List();
+
+ // ToDo: Refactor the following stucture of loops
+ foreach (var domain in questionGrouping.SubGroupings)
+ {
+ var newDomain = new MatAnsweredQuestionDomain()
+ {
+ Title = domain.Title,
+ IsDeficient = false,
+ AssessmentFactors = new List()
+ };
+ foreach (var assesmentFactor in domain.SubGroupings)
+ {
+ var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
+ {
+ Title = assesmentFactor.Title,
+ IsDeficient = false,
+ Components = new List(),
+ Questions = new List()
+ };
+
+
+ if (assesmentFactor.Questions.Count > 0)
+ {
+ foreach (var question in assesmentFactor.Questions)
+ {
+ // make sure only MarkForReview quest6ions are included
+ if (question.Answer != null && question.MarkForReview)
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = question.MaturityLevel.ToString(),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer,
+ Documents = docDictionary.ContainsKey(question.QuestionId) ? docDictionary[question.QuestionId] : null,
+ Visible = true
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+ if (newQuestion.MaturityLevel == "5")
+ {
+ newAssesmentFactor.Questions.Add(newQuestion);
+ }
+ }
+ }
+ }
+ foreach (var component in assesmentFactor.SubGroupings)
+ {
+ var newComponent = new MaturityAnsweredQuestionsComponent()
+ {
+ Title = component.Title,
+ IsDeficient = false,
+ Questions = new List(),
+ };
+
+ foreach (var question in component.Questions)
+ {
+ if (question.Answer != null && question.MarkForReview)
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = question.MaturityLevel.ToString(),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer,
+ Documents = docDictionary.ContainsKey(question.QuestionId) ? docDictionary[question.QuestionId] : null,
+ Visible = true
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ newComponent.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+
+ newComponent.Questions.Add(newQuestion);
+ }
+ }
+ if (newComponent.Questions.Count > 0)
+ {
+ newAssesmentFactor.Components.Add(newComponent);
+ //newAssesmentFactor.Questions.AddRange(newComponent.Questions);
+ }
+ }
+ if (newAssesmentFactor.Components.Count > 0)
+ {
+ newDomain.AssessmentFactors.Add(newAssesmentFactor);
+ }
+ //}
+
+ }
+ if (newDomain.AssessmentFactors.Count > 0)
+ {
+ maturityDomains.Add(newDomain);
+ }
+ }
+
+ return maturityDomains;
+ }
+ //
+
+ public List GetCieDocumentsForAssessment()
+ {
+ Dictionary> docDictionary = new Dictionary>();
+
+ List documentList = new List();
+
+ var results = (from f in _context.DOCUMENT_FILE
+ join da in _context.DOCUMENT_ANSWERS on f.Document_Id equals da.Document_Id
+ join a in _context.ANSWER on da.Answer_Id equals a.Answer_Id
+ join q in _context.MATURITY_QUESTIONS on a.Question_Or_Requirement_Id equals q.Mat_Question_Id
+ where f.Assessment_Id == _assessmentId
+ select new { f, da, a, q }).ToList();
+
+ var questionIds = results.DistinctBy(x => x.q.Mat_Question_Id).ToList();
+
+ results.ForEach(doc =>
+ {
+ DocumentWithAnswerId newDoc = new DocumentWithAnswerId()
+ {
+ Answer_Id = doc.da.Answer_Id,
+ Title = doc.f.Title,
+ FileName = doc.f.Name,
+ Document_Id = doc.da.Document_Id,
+ Question_Id = doc.a.Question_Or_Requirement_Id,
+ Question_Title = doc.q.Question_Title
+ };
+ documentList.Add(newDoc);
+ if (docDictionary.ContainsKey(newDoc.Question_Id))
+ {
+ docDictionary[newDoc.Question_Id].Add(newDoc);
+ }
+ else
+ {
+ docDictionary.Add(newDoc.Question_Id, [newDoc]);
+ }
+ });
+
+ //
+ List controls = new List();
+
+
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ List questions = new List();
+
+ questions = _context.MATURITY_QUESTIONS.Where(q =>
+ myModel.model_id == q.Maturity_Model_Id).ToList();
+
+
+ // Get all MATURITY answers for the assessment
+ //IQueryable answers = new IQueryable();
+
+ var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
+ from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
+ select new FullAnswer() { a = a, b = b };
+
+ // Get all subgroupings for this maturity model
+ var allGroupings = _context.MATURITY_GROUPINGS
+ .Include(x => x.Type)
+ .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ //Get All the Observations and issues with the Observations.
+
+
+ // Recursively build the grouping/question hierarchy
+ var questionGrouping = new MaturityGrouping();
+ BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
+
+ var maturityDomains = new List();
+
+ // ToDo: Refactor the following stucture of loops
+ foreach (var domain in questionGrouping.SubGroupings)
+ {
+ var newDomain = new MatAnsweredQuestionDomain()
+ {
+ Title = domain.Title,
+ IsDeficient = false,
+ AssessmentFactors = new List()
+ };
+ foreach (var assesmentFactor in domain.SubGroupings)
+ {
+ var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
+ {
+ Title = assesmentFactor.Title,
+ IsDeficient = false,
+ AreQuestionsDeficient = false,
+ Components = new List(),
+ Questions = new List()
+ };
+
+
+ if (assesmentFactor.Questions.Count > 0)
+ {
+ foreach (var question in assesmentFactor.Questions)
+ {
+ // if the report shows N/A only, make sure the answer's included are only "NA"
+ if (docDictionary.ContainsKey(question.QuestionId))
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = question.MaturityLevel.ToString(),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer,
+ Documents = docDictionary[question.QuestionId],
+ Visible = true
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+ if (newQuestion.MaturityLevel == "5")
+ {
+ newAssesmentFactor.Questions.Add(newQuestion);
+ }
+ }
+ }
+ }
+ foreach (var component in assesmentFactor.SubGroupings)
+ {
+ var newComponent = new MaturityAnsweredQuestionsComponent()
+ {
+ Title = component.Title,
+ IsDeficient = false,
+ Questions = new List(),
+ };
+
+ foreach (var question in component.Questions)
+ {
+ if (docDictionary.ContainsKey(question.QuestionId))
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = question.MaturityLevel.ToString(),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer,
+ Documents = docDictionary[question.QuestionId],
+ Visible = true
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ newComponent.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+
+ newComponent.Questions.Add(newQuestion);
+ }
+ }
+ if (newComponent.Questions.Count > 0)
+ {
+ newAssesmentFactor.Components.Add(newComponent);
+ //newAssesmentFactor.Questions.AddRange(newComponent.Questions);
+ }
+ }
+ if (newAssesmentFactor.Components.Count > 0)
+ {
+ newDomain.AssessmentFactors.Add(newAssesmentFactor);
+ }
+ //}
+
+ }
+ if (newDomain.AssessmentFactors.Count > 0)
+ {
+ maturityDomains.Add(newDomain);
+ }
+ }
+ //
+
+ return maturityDomains;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/NCUAReportsData.cs b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/NCUAReportsData.cs
new file mode 100644
index 0000000000..7e9390068f
--- /dev/null
+++ b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/NCUAReportsData.cs
@@ -0,0 +1,552 @@
+////////////////////////////////
+//
+// Copyright 2024 Battelle Energy Alliance, LLC
+//
+//
+////////////////////////////////
+using CSETWebCore.Business.Maturity;
+using CSETWebCore.DataLayer.Model;
+using CSETWebCore.Interfaces.Reports;
+using CSETWebCore.Model.Maturity;
+using CSETWebCore.Model.Question;
+using Microsoft.EntityFrameworkCore;
+using Nelibur.ObjectMapper;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+
+namespace CSETWebCore.Business.Reports
+{
+ public partial class ReportsDataBusiness : IReportsDataBusiness
+ {
+
+ ///
+ /// Returns a list of answered maturity questions. This was built for ACET
+ /// but could be used by other maturity models with some work.
+ ///
+ ///
+ public List GetAnsweredQuestionList()
+ {
+ List controls = new List();
+
+ var lang = _tokenManager.GetCurrentLanguage();
+
+
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ // get the target maturity level IDs
+ var targetRange = new ACETMaturityBusiness(_context, _assessmentUtil, _adminTabBusiness).GetMaturityRangeIds(_assessmentId);
+
+ var questions = _context.MATURITY_QUESTIONS.Where(q =>
+ myModel.model_id == q.Maturity_Model_Id
+ && targetRange.Contains(q.Maturity_Level_Id)).ToList();
+
+
+ // apply overlay
+ foreach (var q in questions)
+ {
+ var o = _overlay.GetMaturityQuestion(q.Mat_Question_Id, lang);
+ if (o != null)
+ {
+ q.Question_Title = o.QuestionTitle ?? q.Question_Title;
+ q.Question_Text = o.QuestionText;
+ q.Supplemental_Info = o.SupplementalInfo;
+ q.Examination_Approach = o.ExaminationApproach;
+ }
+ }
+
+
+ // Get all MATURITY answers for the assessment
+ var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
+ from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
+ select new FullAnswer() { a = a, b = b };
+
+
+ // Get all subgroupings for this maturity model
+ var allGroupings = _context.MATURITY_GROUPINGS
+ .Include(x => x.Type)
+ .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+
+ // apply translation overlay
+ foreach (var g in allGroupings)
+ {
+ var o = _overlay.GetMaturityGrouping(g.Grouping_Id, lang);
+ if (o != null)
+ {
+ g.Title = o.Title;
+ g.Description = o.Description;
+ }
+ }
+
+
+ // Recursively build the grouping/question hierarchy
+ var questionGrouping = new MaturityGrouping();
+ BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
+
+ var maturityDomains = new List();
+
+ foreach (var domain in questionGrouping.SubGroupings)
+ {
+ var newDomain = new MatAnsweredQuestionDomain()
+ {
+ Title = domain.Title,
+ IsDeficient = false,
+ AssessmentFactors = new List()
+ };
+ foreach (var assesmentFactor in domain.SubGroupings)
+ {
+ var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
+ {
+ Title = assesmentFactor.Title,
+ IsDeficient = false,
+ Components = new List()
+ };
+
+ foreach (var componenet in assesmentFactor.SubGroupings)
+ {
+ var newComponent = new MaturityAnsweredQuestionsComponent()
+ {
+ Title = componenet.Title,
+ IsDeficient = false,
+ Questions = new List()
+ };
+
+ foreach (var question in componenet.Questions)
+ {
+ if (question.Answer != null)
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = GetLevelLabel(question.MaturityLevel, myMaturityLevels),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview
+ };
+
+
+ // overlay
+ var o = _overlay.GetMaturityQuestion(question.QuestionId, lang);
+ if (o != null)
+ {
+ newQuestion.QuestionText = o.QuestionText;
+ }
+
+
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ newComponent.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+
+ newComponent.Questions.Add(newQuestion);
+ }
+ }
+ if (newComponent.Questions.Count > 0)
+ {
+ newAssesmentFactor.Components.Add(newComponent);
+ }
+ }
+ if (newAssesmentFactor.Components.Count > 0)
+ {
+ newDomain.AssessmentFactors.Add(newAssesmentFactor);
+ }
+ }
+ if (newDomain.AssessmentFactors.Count > 0)
+ {
+ maturityDomains.Add(newDomain);
+ }
+ }
+
+ return maturityDomains;
+ }
+
+
+ ///
+ /// Primarily used for ACET which uses strings to describe their levels
+ ///
+ ///
+ ///
+ private string GetLevelLabel(int maturityLevel, List levels)
+ {
+ return levels.FirstOrDefault(x => x.Maturity_Level_Id == maturityLevel)?.Level_Name ?? "";
+ }
+
+
+ ///
+ /// Returns a list of answered maturity questions. This was built for ACET ISE
+ /// but could be used by other maturity models with some work.
+ ///
+ ///
+ public List GetIseAnsweredQuestionList()
+ {
+ List controls = new List();
+
+
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ // get the target maturity level IDs
+ var targetRange = new ACETMaturityBusiness(_context, _assessmentUtil, _adminTabBusiness).GetIseMaturityRangeIds(_assessmentId);
+
+ var questions = _context.MATURITY_QUESTIONS.Where(q =>
+ myModel.model_id == q.Maturity_Model_Id
+ && targetRange.Contains(q.Maturity_Level_Id)).ToList();
+
+
+ // Get all MATURITY answers for the assessment
+ var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
+ from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
+ select new FullAnswer() { a = a, b = b };
+
+
+ // Get all subgroupings for this maturity model
+ var allGroupings = _context.MATURITY_GROUPINGS
+ .Include(x => x.Type)
+ .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ //Get All the Observations and issues with the Observations.
+
+
+ // Recursively build the grouping/question hierarchy
+ var questionGrouping = new MaturityGrouping();
+ BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
+
+ var maturityDomains = new List();
+
+ // ToDo: Refactor the following stucture of loops
+ foreach (var domain in questionGrouping.SubGroupings)
+ {
+ var newDomain = new MatAnsweredQuestionDomain()
+ {
+ Title = domain.Title,
+ IsDeficient = false,
+ AssessmentFactors = new List()
+ };
+ foreach (var assesmentFactor in domain.SubGroupings)
+ {
+ var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
+ {
+ Title = assesmentFactor.Title,
+ IsDeficient = false,
+ Components = new List()
+ };
+
+ foreach (var componenet in assesmentFactor.SubGroupings)
+ {
+ var newComponent = new MaturityAnsweredQuestionsComponent()
+ {
+ Title = componenet.Title,
+ IsDeficient = false,
+ Questions = new List()
+ };
+
+ foreach (var question in componenet.Questions)
+ {
+ if (question.Answer != null)
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = GetLevelLabel(question.MaturityLevel, myMaturityLevels),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ newComponent.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+
+ newComponent.Questions.Add(newQuestion);
+ }
+ }
+ if (newComponent.Questions.Count > 0)
+ {
+ newAssesmentFactor.Components.Add(newComponent);
+ }
+ }
+ if (newAssesmentFactor.Components.Count > 0)
+ {
+ newDomain.AssessmentFactors.Add(newAssesmentFactor);
+ }
+ }
+ if (newDomain.AssessmentFactors.Count > 0)
+ {
+ maturityDomains.Add(newDomain);
+ }
+ }
+
+ return maturityDomains;
+ }
+
+ ///
+ /// Returns a list of answered maturity questions. This was built for ACET ISE
+ /// but could be used by other maturity models with some work.
+ ///
+ ///
+ public List GetIseAllQuestionList()
+ {
+ List controls = new List();
+
+
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ // get the target maturity level IDs
+ var targetRange = new ACETMaturityBusiness(_context, _assessmentUtil, _adminTabBusiness).GetIseMaturityRangeIds(_assessmentId);
+
+ var questions = _context.MATURITY_QUESTIONS.Where(q =>
+ myModel.model_id == q.Maturity_Model_Id).ToList();
+
+
+ // Get all MATURITY answers for the assessment
+ var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
+ from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
+ select new FullAnswer() { a = a, b = b };
+
+
+ // Get all subgroupings for this maturity model
+ var allGroupings = _context.MATURITY_GROUPINGS
+ .Include(x => x.Type)
+ .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
+
+ //Get All the Observations and issues with the Observations.
+
+
+ // Recursively build the grouping/question hierarchy
+ var questionGrouping = new MaturityGrouping();
+ BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
+
+ var maturityDomains = new List();
+
+ // ToDo: Refactor the following stucture of loops
+ foreach (var domain in questionGrouping.SubGroupings)
+ {
+ var newDomain = new MatAnsweredQuestionDomain()
+ {
+ Title = domain.Title,
+ IsDeficient = false,
+ AssessmentFactors = new List()
+ };
+ foreach (var assesmentFactor in domain.SubGroupings)
+ {
+ var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
+ {
+ Title = assesmentFactor.Title,
+ IsDeficient = false,
+ Components = new List()
+ };
+
+ foreach (var componenet in assesmentFactor.SubGroupings)
+ {
+ var newComponent = new MaturityAnsweredQuestionsComponent()
+ {
+ Title = componenet.Title,
+ IsDeficient = false,
+ Questions = new List()
+ };
+
+ foreach (var question in componenet.Questions)
+ {
+ if (question.Answer != null)
+ {
+ var newQuestion = new MaturityAnsweredQuestions()
+ {
+ Title = question.DisplayNumber,
+ QuestionText = question.QuestionText,
+ MaturityLevel = GetLevelLabel(question.MaturityLevel, myMaturityLevels),
+ AnswerText = question.Answer,
+ Comment = question.Comment,
+ MarkForReview = question.MarkForReview,
+ MatQuestionId = question.QuestionId,
+ FreeResponseText = question.FreeResponseAnswer
+ };
+
+ if (question.Answer == "N")
+ {
+ newDomain.IsDeficient = true;
+ newAssesmentFactor.IsDeficient = true;
+ newComponent.IsDeficient = true;
+ }
+
+ if (question.Comment != null)
+ {
+ newQuestion.Comments = "Yes";
+ }
+ else
+ {
+ newQuestion.Comments = "No";
+ }
+
+ newComponent.Questions.Add(newQuestion);
+ }
+ }
+ if (newComponent.Questions.Count > 0)
+ {
+ newAssesmentFactor.Components.Add(newComponent);
+ }
+ }
+ if (newAssesmentFactor.Components.Count > 0)
+ {
+ newDomain.AssessmentFactors.Add(newAssesmentFactor);
+ }
+ }
+ if (newDomain.AssessmentFactors.Count > 0)
+ {
+ maturityDomains.Add(newDomain);
+ }
+ }
+
+ return maturityDomains;
+ }
+
+
+ ///
+ /// Returns a block of data generally from the INFORMATION table plus a few others.
+ ///
+ ///
+ public BasicReportData.INFORMATION GetIseInformation()
+ {
+ INFORMATION infodb = _context.INFORMATION.Where(x => x.Id == _assessmentId).FirstOrDefault();
+
+ TinyMapper.Bind(config =>
+ {
+ config.Ignore(x => x.Additional_Contacts);
+ });
+ var info = TinyMapper.Map(infodb);
+
+ var assessment = _context.ASSESSMENTS.FirstOrDefault(x => x.Assessment_Id == _assessmentId);
+ info.Assessment_Date = assessment.Assessment_Date;
+
+ info.Assessment_Effective_Date = assessment.AssessmentEffectiveDate;
+ info.Assessment_Creation_Date = assessment.AssessmentCreatedDate;
+
+ // Primary Assessor
+ var user = _context.USERS.FirstOrDefault(x => x.UserId == assessment.AssessmentCreatorId);
+ info.Assessor_Name = user != null ? FormatName(user.FirstName, user.LastName) : string.Empty;
+
+
+ // Other Contacts
+ info.Additional_Contacts = new List();
+ var contacts = _context.ASSESSMENT_CONTACTS
+ .Where(ac => ac.Assessment_Id == _assessmentId
+ && ac.UserId != assessment.AssessmentCreatorId)
+ .Include(u => u.User)
+ .ToList();
+ foreach (var c in contacts)
+ {
+ info.Additional_Contacts.Add(FormatName(c.FirstName, c.LastName));
+ }
+
+ // Include anything that was in the INFORMATION record's Additional_Contacts column
+ if (infodb.Additional_Contacts != null)
+ {
+ string[] acLines = infodb.Additional_Contacts.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (string c in acLines)
+ {
+ info.Additional_Contacts.Add(c);
+ }
+ }
+
+ info.UseStandard = assessment.UseStandard;
+ info.UseMaturity = assessment.UseMaturity;
+ info.UseDiagram = assessment.UseDiagram;
+
+ // ACET properties
+ info.Credit_Union_Name = assessment.CreditUnionName;
+ info.Charter = assessment.Charter;
+
+ info.Assets = 0;
+ bool a = long.TryParse(assessment.Assets, out long assets);
+ if (a)
+ {
+ info.Assets = assets;
+ }
+
+ // Maturity properties
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .FirstOrDefault(x => x.Assessment_Id == _assessmentId);
+ if (myModel != null)
+ {
+ info.QuestionsAlias = myModel.model.Questions_Alias;
+ }
+
+ return info;
+ }
+
+
+ public List GetIseSourceFiles()
+ {
+
+ var data = (from g in _context.GEN_FILE
+ join a in _context.MATURITY_REFERENCES
+ on g.Gen_File_Id equals a.Gen_File_Id
+ join q in _context.MATURITY_QUESTIONS
+ on a.Mat_Question_Id equals q.Mat_Question_Id
+ where q.Maturity_Model_Id == 10 && a.Source
+ select new { a, q, g }).ToList();
+
+ List result = new List();
+ SourceFiles file = new SourceFiles();
+ foreach (var item in data)
+ {
+ try
+ {
+ file.Mat_Question_Id = item.q.Mat_Question_Id;
+ file.Gen_File_Id = item.g.Gen_File_Id;
+ file.Title = item.g.Title;
+ }
+ catch
+ {
+
+ }
+ result.Add(file);
+
+ }
+
+ return result;
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/ReportsDataBusiness.cs b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/ReportsDataBusiness.cs
new file mode 100644
index 0000000000..2398d2a4da
--- /dev/null
+++ b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/ReportsDataBusiness.cs
@@ -0,0 +1,1292 @@
+////////////////////////////////
+//
+// Copyright 2024 Battelle Energy Alliance, LLC
+//
+//
+////////////////////////////////
+using CSETWebCore.Business.Maturity.Configuration;
+using CSETWebCore.Business.Sal;
+using CSETWebCore.DataLayer.Model;
+using CSETWebCore.Helpers;
+using CSETWebCore.Interfaces.AdminTab;
+using CSETWebCore.Interfaces.Helpers;
+using CSETWebCore.Interfaces.Maturity;
+using CSETWebCore.Interfaces.Question;
+using CSETWebCore.Interfaces.Reports;
+using CSETWebCore.Model.Diagram;
+using CSETWebCore.Model.Maturity;
+using CSETWebCore.Model.Question;
+using CSETWebCore.Model.Reports;
+using Microsoft.EntityFrameworkCore;
+using Nelibur.ObjectMapper;
+using Snickler.EFCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+
+namespace CSETWebCore.Business.Reports
+{
+ public partial class ReportsDataBusiness : IReportsDataBusiness
+ {
+ private readonly CSETContext _context;
+ private readonly IAssessmentUtil _assessmentUtil;
+ private int _assessmentId;
+ private readonly IAdminTabBusiness _adminTabBusiness;
+ private readonly IMaturityBusiness _maturityBusiness;
+ private readonly IQuestionRequirementManager _questionRequirement;
+ private readonly ITokenManager _tokenManager;
+
+ public List OutOfScopeQuestions = new List();
+
+ private TranslationOverlay _overlay;
+
+
+
+ ///
+ /// Constructor.
+ ///
+ ///
+ public ReportsDataBusiness(CSETContext context, IAssessmentUtil assessmentUtil, IAdminTabBusiness adminTabBusiness, IAssessmentModeData assessmentMode,
+ IMaturityBusiness maturityBusiness, IQuestionRequirementManager questionRequirement, ITokenManager tokenManager)
+ {
+ _context = context;
+ _assessmentUtil = assessmentUtil;
+ _adminTabBusiness = adminTabBusiness;
+ _maturityBusiness = maturityBusiness;
+ _questionRequirement = questionRequirement;
+ _tokenManager = tokenManager;
+
+ _overlay = new TranslationOverlay();
+ }
+
+
+ ///
+ /// Returns an unfiltered list of MatRelevantAnswers for the current assessment.
+ /// The optional modelId parameter is used to get a specific model's questions. If not
+ /// supplied, the default model's questions are retrieved.
+ ///
+ ///
+ public List GetQuestionsList(int? modelId = null)
+ {
+ int targetModelId = 0;
+
+ if (modelId == null)
+ {
+ var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+ if (myModel == null)
+ {
+ return new List();
+ }
+
+ targetModelId = myModel.model_id;
+ }
+ else
+ {
+ targetModelId = (int)modelId;
+ }
+
+
+ var lang = _tokenManager.GetCurrentLanguage();
+
+ _context.FillEmptyMaturityQuestionsForAnalysis(_assessmentId);
+
+ // flesh out model-specific questions
+ if (modelId != null)
+ {
+ _context.FillEmptyMaturityQuestionsForModel(_assessmentId, (int)modelId);
+ }
+
+ var query = from a in _context.ANSWER
+ join m in _context.MATURITY_QUESTIONS.Include(x => x.Maturity_Level)
+ on a.Question_Or_Requirement_Id equals m.Mat_Question_Id
+ where a.Assessment_Id == _assessmentId
+ && m.Maturity_Model_Id == targetModelId
+ && a.Question_Type == "Maturity"
+ && !this.OutOfScopeQuestions.Contains(m.Mat_Question_Id)
+ orderby m.Grouping_Id, m.Maturity_Level_Id, m.Mat_Question_Id ascending
+ select new MatRelevantAnswers()
+ {
+ ANSWER = a,
+ Mat = m
+ };
+
+ var responseList = query.ToList();
+ var childQuestions = responseList.FindAll(x => x.Mat.Parent_Question_Id != null);
+
+ // Set IsParentWithChildren property for all parent questions that have child questions
+ foreach (var matAns in responseList)
+ {
+ if (childQuestions.Exists(x => x.Mat.Parent_Question_Id == matAns.Mat.Mat_Question_Id))
+ {
+ matAns.IsParentWithChildren = true;
+ }
+ }
+
+ foreach (var matAns in responseList)
+ {
+ var o = _overlay.GetMaturityQuestion(matAns.Mat.Mat_Question_Id, lang);
+ if (o != null)
+ {
+ matAns.Mat.Question_Title = o.QuestionTitle ?? matAns.Mat.Question_Title;
+ matAns.Mat.Question_Text = o.QuestionText;
+ matAns.Mat.Supplemental_Info = o.SupplementalInfo;
+ }
+ }
+
+
+ // if a maturity level is defined, only report on questions at or below that level
+ int? selectedLevel = _context.ASSESSMENT_SELECTED_LEVELS.Where(x => x.Assessment_Id == _assessmentId
+ && x.Level_Name == Constants.Constants.MaturityLevel).Select(x => int.Parse(x.Standard_Specific_Sal_Level)).FirstOrDefault();
+
+ NullOutNavigationPropeties(responseList);
+
+ // RRA should be always be defaulted to its maximum available level (3)
+ // since the user can't configure it
+ if (targetModelId == 5)
+ {
+ selectedLevel = 3;
+ }
+
+ if (selectedLevel != null && selectedLevel != 0)
+ {
+ responseList = responseList.Where(x => x.Mat.Maturity_Level.Level <= selectedLevel).ToList();
+ }
+
+
+ return responseList;
+ }
+
+
+ ///
+ /// Returns a list of MatRelevantAnswers that are considered deficient for the assessment.
+ ///
+ ///
+ public List GetMaturityDeficiencies(int? modelId = null)
+ {
+ var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ var targetModel = myModel.model;
+
+
+ // if a model was explicitly requested, do that one
+ if (modelId != null)
+ {
+ targetModel = _context.MATURITY_MODELS.Where(x => x.Maturity_Model_Id == modelId).FirstOrDefault();
+ }
+
+
+ bool ignoreParentQuestions = false;
+
+ // default answer values that are considered 'deficient' (in case we can't find a model config profile)
+ List deficientAnswerValues = new List() { "N", "U" };
+
+
+ // try to get a configuration for the actual model
+ var modelProperties = new ModelProfile().GetModelProperties(targetModel.Maturity_Model_Id);
+ if (modelProperties != null)
+ {
+ deficientAnswerValues = modelProperties.DeficientAnswers;
+ ignoreParentQuestions = modelProperties.IgnoreParentQuestions;
+ }
+
+
+ var responseList = GetQuestionsList(targetModel.Maturity_Model_Id).Where(x => deficientAnswerValues.Contains(x.ANSWER.Answer_Text)).ToList();
+
+
+ // We don't consider parent questions that have children to be unanswered for certain maturity models
+ // (i.e. for CRR, EDM since they just house the question extras)
+ if (ignoreParentQuestions)
+ {
+ responseList = responseList.Where(x => !x.IsParentWithChildren).ToList();
+ }
+
+
+ // If the assessment is using a submodel, only keep the submodel's subset of questions
+ var maturitySubmodel = _context.DETAILS_DEMOGRAPHICS.Where(x => x.Assessment_Id == _assessmentId && x.DataItemName == "MATURITY-SUBMODEL").FirstOrDefault();
+ if (maturitySubmodel != null)
+ {
+ var whitelist = _context.MATURITY_SUB_MODEL_QUESTIONS.Where(x => x.Sub_Model_Name == maturitySubmodel.StringValue).Select(q => q.Mat_Question_Id).ToList();
+ responseList = responseList.Where(x => whitelist.Contains(x.Mat.Mat_Question_Id)).ToList();
+ }
+
+ return responseList;
+ }
+
+
+
+ ///
+ /// Returns a list of MatRelevantAnswers that contain comments.
+ ///
+ ///
+ public List GetCommentsList(int? modelId = null)
+ {
+ var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ var targetModel = myModel.model;
+
+ // if a model was explicitly requested, do that one
+ if (modelId != null)
+ {
+ targetModel = _context.MATURITY_MODELS.Where(x => x.Maturity_Model_Id == modelId).FirstOrDefault();
+ }
+
+ var responseList = GetQuestionsList(targetModel.Maturity_Model_Id).Where(x => !string.IsNullOrWhiteSpace(x.ANSWER.Comment)).ToList();
+
+ return responseList;
+ }
+
+
+ ///
+ /// Returns a list of MatRelevantAnswers that are marked for review.
+ ///
+ ///
+ ///
+ public List GetMarkedForReviewList(int? modelId = null)
+ {
+ var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ var targetModel = myModel.model;
+
+ // if a model was explicitly requested, do that one
+ if (modelId != null)
+ {
+ targetModel = _context.MATURITY_MODELS.Where(x => x.Maturity_Model_Id == modelId).FirstOrDefault();
+ }
+
+ var responseList = GetQuestionsList(targetModel.Maturity_Model_Id).Where(x => x.ANSWER.Mark_For_Review ?? false).ToList();
+
+ return responseList;
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void BuildSubGroupings(MaturityGrouping g, int? parentID,
+ List allGroupings,
+ List questions,
+ List answers)
+ {
+ var mySubgroups = allGroupings.Where(x => x.Parent_Id == parentID).OrderBy(x => x.Sequence).ToList();
+
+ if (mySubgroups.Count == 0)
+ {
+ return;
+ }
+
+ foreach (var sg in mySubgroups)
+ {
+ var newGrouping = new MaturityGrouping()
+ {
+ GroupingID = sg.Grouping_Id,
+ GroupingType = sg.Type.Grouping_Type_Name,
+ Title = sg.Title,
+ Description = sg.Description,
+ Abbreviation = sg.Abbreviation
+ };
+
+ g.SubGroupings.Add(newGrouping);
+
+
+ // are there any questions that belong to this grouping?
+ var myQuestions = questions.Where(x => x.Grouping_Id == newGrouping.GroupingID).ToList();
+
+ var parentQuestionIDs = myQuestions.Select(x => x.Parent_Question_Id).Distinct().ToList();
+
+ foreach (var myQ in myQuestions)
+ {
+ FullAnswer answer = answers.Where(x => x.a.Question_Or_Requirement_Id == myQ.Mat_Question_Id).FirstOrDefault();
+
+ var qa = new QuestionAnswer()
+ {
+ DisplayNumber = myQ.Question_Title,
+ QuestionId = myQ.Mat_Question_Id,
+ ParentQuestionId = myQ.Parent_Question_Id,
+ QuestionType = "Maturity",
+ QuestionText = myQ.Question_Text.Replace("\r\n", "
").Replace("\n", "
").Replace("\r", "
"),
+ Answer = answer?.a.Answer_Text,
+ AltAnswerText = answer?.a.Alternate_Justification,
+ //freeResponseAnswer= answer?.a.Free_Response_Answer,
+ Comment = answer?.a.Comment,
+ Feedback = answer?.a.FeedBack,
+ MarkForReview = answer?.a.Mark_For_Review ?? false,
+ Reviewed = answer?.a.Reviewed ?? false,
+ Is_Maturity = true,
+ MaturityLevel = myQ.Maturity_Level_Id,
+ IsParentQuestion = parentQuestionIDs.Contains(myQ.Mat_Question_Id),
+ SetName = string.Empty,
+ FreeResponseAnswer = answer?.a.Free_Response_Answer
+ };
+
+ if (answer != null)
+ {
+ TinyMapper.Bind();
+ TinyMapper.Map(answer.b, qa);
+
+ // db view still uses the term "HasDiscovery" - map to "HasObservation"
+ qa.HasObservation = answer.b.HasDiscovery ?? false;
+ }
+
+ newGrouping.Questions.Add(qa);
+ }
+
+ // Recurse down to build subgroupings
+ BuildSubGroupings(newGrouping, newGrouping.GroupingID, allGroupings, questions, answers);
+ }
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ public List GetControlsDiagram(string applicationMode)
+
+ {
+
+ List controls = new List();
+ _questionRequirement.InitializeManager(_assessmentId);
+
+ _context.FillEmptyQuestionsForAnalysis(_assessmentId);
+
+ string level = _questionRequirement.StandardLevel == null ? "L" : _questionRequirement.StandardLevel;
+
+ List controlRows = new List();
+
+ var qQ = (from rs in _context.Answer_Components_Default
+ orderby rs.Question_Group_Heading
+ where rs.Assessment_Id == _assessmentId
+ select new { rs }).ToList();
+
+ foreach (var q in qQ)
+ {
+ controlRows.Add(new ControlRow()
+ {
+ Requirement_Id = q.rs.heading_pair_id,
+ Requirement_Text = q.rs.Sub_Heading_Question_Description,
+ Answer_Text = q.rs.Answer_Text,
+ Comment = q.rs.Comment,
+ Question_Id = q.rs.Question_Id,
+ Requirement_Title = q.rs.Question_Group_Heading,
+ Short_Name = q.rs.ComponentName,
+ Simple_Question = q.rs.QuestionText,
+ Standard_Category = q.rs.Question_Group_Heading,
+ Standard_Sub_Category = q.rs.Universal_Sub_Category,
+ Standard_Level = q.rs.SAL
+ });
+ }
+
+ //get all the questions for this control
+ //determine the percent implemented.
+ int prev_requirement_id = 0;
+ int questionCount = 0;
+ int questionsAnswered = 0;
+ BasicReportData.RequirementControl control = null;
+ List questions = null;
+
+ foreach (var a in controlRows)
+ {
+ if (prev_requirement_id != a.Requirement_Id)
+ {
+ questionCount = 0;
+ questionsAnswered = 0;
+ questions = new List();
+ control = new BasicReportData.RequirementControl()
+ {
+ ControlDescription = a.Requirement_Text,
+ RequirementTitle = a.Requirement_Title,
+ Level = a.Standard_Level,
+ StandardShortName = a.Short_Name,
+ Standard_Category = a.Standard_Category,
+ SubCategory = a.Standard_Sub_Category,
+ Control_Questions = questions
+ };
+ controls.Add(control);
+ }
+ questionCount++;
+
+ switch (a.Answer_Text)
+ {
+ case Constants.Constants.ALTERNATE:
+ case Constants.Constants.YES:
+ questionsAnswered++;
+ break;
+ }
+
+ questions.Add(new BasicReportData.Control_Questions()
+ {
+ Answer = a.Answer_Text,
+ Comment = a.Comment,
+ Simple_Question = a.Simple_Question
+ });
+
+ control.ImplementationStatus = StatUtils.Percentagize(questionsAnswered, questionCount, 2).ToString("##.##");
+ prev_requirement_id = a.Requirement_Id;
+ }
+
+ return controls;
+ }
+
+ public List> GetDiagramZones()
+ {
+ var level = _context.STANDARD_SELECTION.Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+
+ var rval1 = (from c in _context.ASSESSMENT_DIAGRAM_COMPONENTS
+ join s in _context.COMPONENT_SYMBOLS on c.Component_Symbol_Id equals s.Component_Symbol_Id
+ where c.Assessment_Id == _assessmentId && c.Zone_Id == null
+ orderby s.Symbol_Name, c.label
+ select new DiagramZones
+ {
+ Diagram_Component_Type = s.Symbol_Name,
+ label = c.label,
+ Zone_Name = "No Assigned Zone",
+ Universal_Sal_Level = level == null ? "Low" : level.Selected_Sal_Level
+ }).ToList();
+
+ var rval = (from c in _context.ASSESSMENT_DIAGRAM_COMPONENTS
+ join z in _context.DIAGRAM_CONTAINER on c.Zone_Id equals z.Container_Id
+ join s in _context.COMPONENT_SYMBOLS on c.Component_Symbol_Id equals s.Component_Symbol_Id
+ where c.Assessment_Id == _assessmentId
+ orderby s.Symbol_Name, c.label
+ select new DiagramZones
+ {
+ Diagram_Component_Type = s.Symbol_Name,
+ label = c.label,
+ Zone_Name = z.Name,
+ Universal_Sal_Level = z.Universal_Sal_Level
+ }).ToList();
+
+ return rval.Union(rval1).GroupBy(u => u.Zone_Name).Select(grp => grp.ToList()).ToList();
+ }
+
+
+ public List GetFinancialQuestions()
+ {
+ return _context.usp_getFinancialQuestions(_assessmentId).ToList();
+ }
+
+
+ public List GetQuestionsForEachStandard()
+ {
+ var dblist = from a in _context.AVAILABLE_STANDARDS
+ join b in _context.NEW_QUESTION_SETS on a.Set_Name equals b.Set_Name
+ join c in _context.Answer_Questions on b.Question_Id equals c.Question_Or_Requirement_Id
+ join q in _context.NEW_QUESTION on c.Question_Or_Requirement_Id equals q.Question_Id
+ join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
+ join s in _context.SETS on b.Set_Name equals s.Set_Name
+ where a.Selected == true && a.Assessment_Id == _assessmentId
+ && c.Assessment_Id == _assessmentId
+ orderby s.Short_Name, h.Question_Group_Heading, c.Question_Number
+ select new SimpleStandardQuestions()
+ {
+ ShortName = s.Short_Name,
+ Answer = c.Answer_Text,
+ CategoryAndNumber = h.Question_Group_Heading + " #" + c.Question_Number,
+ Question = q.Simple_Question,
+ QuestionId = q.Question_Id
+ };
+
+ List list = new List();
+ string lastshortname = "";
+ List qlist = new List();
+ foreach (var a in dblist.ToList())
+ {
+ if (a.ShortName != lastshortname)
+ {
+ qlist = new List();
+ list.Add(new StandardQuestions()
+ {
+ Questions = qlist,
+ StandardShortName = a.ShortName
+ });
+ }
+ lastshortname = a.ShortName;
+ qlist.Add(a);
+ }
+
+ return list;
+ }
+
+
+ public async Task> GetStandardQuestionAnswers(int assessId)
+ {
+ CsetwebContextProcedures context = new CsetwebContextProcedures(_context);
+ var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
+ var dblist = await context.usp_GetQuestionsAsync(assessId);
+
+ List list = new List();
+ string lastshortname = "";
+ List qlist = new List();
+ foreach (var a in dblist.ToList())
+ {
+ if (a.ShortName != lastshortname)
+ {
+ qlist = new List();
+ list.Add(new StandardQuestions()
+ {
+ Questions = qlist,
+ StandardShortName = a.ShortName
+ });
+ }
+ lastshortname = a.ShortName;
+ qlist.Add(new SimpleStandardQuestions()
+ {
+ ShortName = a.ShortName,
+
+ Question = rm.ResolveParameters(a.QuestionOrRequirementID, a.AnswerID, a.QuestionText),
+ QuestionId = a.QuestionOrRequirementID,
+ Answer = a.AnswerText,
+ CategoryAndNumber = a.CategoryAndNumber
+ });
+ }
+
+ return list;
+ }
+
+
+ ///
+ /// Returns a list of questions generated by components in the network.
+ /// The questions correspond to the SAL level of each component's Zone level.
+ /// Questions for components in hidden layers are not included.
+ ///
+ ///
+ public List GetComponentQuestions()
+ {
+ var l = new List();
+
+ List results = null;
+
+ _context.LoadStoredProc("[usp_getExplodedComponent]")
+ .WithSqlParam("assessment_id", _assessmentId)
+ .ExecuteStoredProc((handler) =>
+ {
+ results = handler.ReadToList().OrderBy(c => c.ComponentName).ThenBy(c => c.QuestionText).ToList();
+ });
+
+ foreach (usp_getExplodedComponent q in results)
+ {
+ l.Add(new ComponentQuestion
+ {
+ Answer = q.Answer_Text,
+ ComponentName = q.ComponentName,
+ Component_Symbol_Id = q.Component_Symbol_Id,
+ Question = q.QuestionText,
+ QuestionId = q.Question_Id,
+ LayerName = q.LayerName,
+ SAL = q.SAL,
+ Zone = q.ZoneName,
+ IsOverride = (q.Answer_Id != null)
+ });
+ }
+
+ return l;
+ }
+
+
+ public List GetTop5Categories()
+ {
+ var lang = _tokenManager.GetCurrentLanguage();
+
+ var categories = _context.usp_GetOverallRankedCategoriesPage(_assessmentId).Take(5).ToList();
+
+ for (var i = 0; i < categories.Count; i++)
+ {
+ var cat = categories[i];
+ cat.Question_Group_Heading = _overlay.GetValue("QUESTION_GROUP_HEADING", cat.QGH_Id.ToString(), lang)?.Value ?? cat.Question_Group_Heading;
+ }
+
+ return categories;
+ }
+
+
+ public List GetTop5Questions()
+ {
+ return GetRankedQuestions().Take(5).ToList();
+ }
+
+
+ ///
+ /// Returns a list of questions that have been answered "Alt"
+ ///
+ ///
+ public List GetQuestionsWithAlternateJustification()
+ {
+
+ var results = new List();
+
+ // get any "A" answers that currently apply
+
+ var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
+ .Where(ans => ans.Answer_Text == "A").ToList();
+
+ if (relevantAnswers.Count == 0)
+ {
+ return results;
+ }
+
+ bool requirementMode = relevantAnswers[0].Is_Requirement;
+
+ // include Question or Requirement contextual information
+ if (requirementMode)
+ {
+ var query = from ans in relevantAnswers
+ join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
+ select new QuestionsWithAltJust()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
+ AlternateJustification = ans.Alternate_Justification,
+ Question = req.Requirement_Text
+ };
+
+ return query.ToList();
+ }
+ else
+ {
+ var query = from ans in relevantAnswers
+ join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
+ join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
+ orderby h.Question_Group_Heading
+ select new QuestionsWithAltJust()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
+ AlternateJustification = ans.Alternate_Justification,
+ Question = q.Simple_Question
+ };
+
+ return query.ToList();
+ }
+
+ }
+
+
+ ///
+ /// Returns a list of questions that have comments.
+ ///
+ ///
+ public List GetQuestionsWithComments()
+ {
+
+ var results = new List();
+
+ var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
+ // get any "marked for review" or commented answers that currently apply
+ var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
+ .Where(ans => !string.IsNullOrEmpty(ans.Comment))
+ .ToList();
+
+ if (relevantAnswers.Count == 0)
+ {
+ return results;
+ }
+
+ bool requirementMode = relevantAnswers[0].Is_Requirement;
+
+ // include Question or Requirement contextual information
+ if (requirementMode)
+ {
+ var query = from ans in relevantAnswers
+ join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
+ select new QuestionsWithComments()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
+ Question = rm.ResolveParameters(ans.Question_Or_Requirement_ID, ans.Answer_ID, req.Requirement_Text),
+ Comment = ans.Comment
+ };
+
+ return query.ToList();
+ }
+ else
+ {
+ var query = from ans in relevantAnswers
+ join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
+ join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
+ orderby h.Question_Group_Heading
+ select new QuestionsWithComments()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
+ Question = q.Simple_Question,
+ Comment = ans.Comment
+ };
+
+ return query.ToList();
+ }
+ }
+
+
+ ///
+ /// Returns a list of questions that have been marked for review.
+ ///
+ ///
+ public List GetQuestionsMarkedForReview()
+ {
+
+ var results = new List();
+
+ // get any "marked for review" or commented answers that currently apply
+ var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
+ .Where(ans => ans.Mark_For_Review)
+ .ToList();
+
+ if (relevantAnswers.Count == 0)
+ {
+ return results;
+ }
+
+ bool requirementMode = relevantAnswers[0].Is_Requirement;
+
+ // include Question or Requirement contextual information
+ if (requirementMode)
+ {
+ var query = from ans in relevantAnswers
+ join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
+ select new QuestionsMarkedForReview()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
+ Question = req.Requirement_Text
+ };
+
+ return query.ToList();
+ }
+ else
+ {
+ var query = from ans in relevantAnswers
+ join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
+ join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
+ orderby h.Question_Group_Heading
+ select new QuestionsMarkedForReview()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
+ Question = q.Simple_Question
+ };
+
+ return query.ToList();
+ }
+
+ }
+
+
+ ///
+ /// Returns a list of questions that have been reviewed.
+ ///
+ ///
+ public List GetQuestionsReviewed()
+ {
+
+ var results = new List();
+ var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
+
+ // get any "marked for review" or commented answers that currently apply
+ var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
+ .Where(ans => ans.Reviewed)
+ .ToList();
+
+ if (relevantAnswers.Count == 0)
+ {
+ return results;
+ }
+
+ bool requirementMode = relevantAnswers[0].Is_Requirement;
+
+ // include Question or Requirement contextual information
+ if (requirementMode)
+ {
+ var query = from ans in relevantAnswers
+ join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
+ select new QuestionsMarkedForReview()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
+ Question = rm.ResolveParameters(ans.Question_Or_Requirement_ID, ans.Answer_ID, req.Requirement_Text)
+ };
+
+ return query.ToList();
+ }
+ else
+ {
+ var query = from ans in relevantAnswers
+ join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
+ join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
+ orderby h.Question_Group_Heading
+ select new QuestionsMarkedForReview()
+ {
+ Answer = ans.Answer_Text,
+ CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
+ Question = q.Simple_Question
+ };
+
+ return query.ToList();
+ }
+ }
+
+
+ public List GetRankedQuestions()
+ {
+ var lang = _tokenManager.GetCurrentLanguage();
+
+ var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
+
+ List list = new List();
+ List rankedQuestionList = _context.usp_GetRankedQuestions(_assessmentId).ToList();
+ foreach (usp_GetRankedQuestions_Result q in rankedQuestionList)
+ {
+ if (q.RequirementId != null)
+ {
+ var reqOverlay = _overlay.GetRequirement((int)q.RequirementId, lang);
+ if (reqOverlay != null)
+ {
+ q.QuestionText = reqOverlay.RequirementText;
+ }
+ }
+
+
+ q.QuestionText = rm.ResolveParameters(q.QuestionOrRequirementID, q.AnswerID, q.QuestionText);
+
+ q.Category = _overlay.GetPropertyValue("STANDARD_CATEGORY", q.Category.ToLower(), lang) ?? q.Category;
+
+ list.Add(new RankedQuestions()
+ {
+ Answer = q.AnswerText,
+ CategoryAndNumber = q.Category + " #" + q.QuestionRef,
+ Level = q.Level,
+ Question = q.QuestionText,
+ Rank = q.Rank ?? 0
+ });
+ }
+
+ return list;
+ }
+
+ public List GetQuestionsWithSupplementals()
+ {
+ var lang = _tokenManager.GetCurrentLanguage();
+
+ var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
+
+ List list = new List();
+ List rankedQuestionList = _context.usp_GetRankedQuestions(_assessmentId).ToList();
+
+
+ var supplementalLookups = (from a in _context.NEW_REQUIREMENT
+ join b in _context.REQUIREMENT_SETS on a.Requirement_Id equals b.Requirement_Id
+ where b.Set_Name == "MOPhysical"
+ select a).ToDictionary(x => x.Requirement_Id, x => x);
+
+ foreach (usp_GetRankedQuestions_Result q in rankedQuestionList)
+ {
+ if (q.RequirementId != null)
+ {
+ var reqOverlay = _overlay.GetRequirement((int)q.RequirementId, lang);
+ if (reqOverlay != null)
+ {
+ q.QuestionText = reqOverlay.RequirementText;
+ }
+
+ }
+
+
+ q.QuestionText = rm.ResolveParameters(q.QuestionOrRequirementID, q.AnswerID, q.QuestionText);
+
+ q.Category = _overlay.GetPropertyValue("STANDARD_CATEGORY", q.Category.ToLower(), lang) ?? q.Category;
+ var comment = _context.Answer_Requirements.Where(x => x.Question_Or_Requirement_Id == q.QuestionOrRequirementID).FirstOrDefault()?.Comment;
+ var supplemental = supplementalLookups[q.RequirementId ?? 0].Supplemental_Info;
+ list.Add(new PhysicalQuestions()
+ {
+ Answer = q.AnswerText,
+ CategoryAndNumber = q.Category + " #" + q.QuestionRef,
+ Level = q.Level,
+ Question = q.QuestionText,
+ Rank = q.Rank ?? 0,
+ Supplemental = supplemental,
+ Comment = comment
+ });
+ }
+
+ return list;
+ }
+
+
+ public BasicReportData.OverallSALTable GetNistSals()
+ {
+ var manager = new NistSalBusiness(_context, _assessmentUtil, _tokenManager);
+ var sals = manager.CalculatedNist(_assessmentId);
+ List list = new List();
+ var infos = _context.CNSS_CIA_JUSTIFICATIONS.Where(x => x.Assessment_Id == _assessmentId).ToList();
+ Dictionary typeToLevel = _context.CNSS_CIA_JUSTIFICATIONS.Where(x => x.Assessment_Id == _assessmentId).ToDictionary(x => x.CIA_Type, x => x.DropDownValueLevel);
+
+ BasicReportData.OverallSALTable overallSALTable = new BasicReportData.OverallSALTable()
+ {
+ OSV = sals.Selected_Sal_Level,
+ Q_AV = sals.ALevel,
+ Q_CV = sals.CLevel,
+ Q_IV = sals.ILevel
+ };
+
+ bool ok;
+ string l;
+ ok = typeToLevel.TryGetValue(Constants.Constants.Availabilty, out l);
+ overallSALTable.IT_AV = ok ? l : "Low";
+ ok = typeToLevel.TryGetValue(Constants.Constants.Confidentiality, out l);
+ overallSALTable.IT_CV = ok ? l : "Low";
+ ok = typeToLevel.TryGetValue(Constants.Constants.Integrity, out l);
+ overallSALTable.IT_IV = ok ? l : "Low";
+
+ return overallSALTable;
+ }
+
+
+ public List GetNistInfoTypes()
+ {
+ List list = new List();
+ var infos = _context.CNSS_CIA_JUSTIFICATIONS.Where(x => x.Assessment_Id == _assessmentId).ToList();
+ foreach (CNSS_CIA_JUSTIFICATIONS info in infos)
+ {
+ list.Add(new BasicReportData.CNSSSALJustificationsTable()
+ {
+ CIA_Type = info.CIA_Type,
+ Justification = info.Justification
+ });
+ }
+
+ return list;
+ }
+
+
+ ///
+ /// Returns SAL CIA values for the assessment.
+ ///
+ ///
+ public BasicReportData.OverallSALTable GetSals()
+ {
+ var sals = (from a in _context.STANDARD_SELECTION
+ join b in _context.ASSESSMENT_SELECTED_LEVELS on a.Assessment_Id equals b.Assessment_Id
+ where a.Assessment_Id == _assessmentId
+ select new { a, b }).ToList();
+
+ string OSV = "Low";
+ string Q_CV = "Low";
+ string Q_IV = "Low";
+ string Q_AV = "Low";
+ foreach (var s in sals)
+ {
+ OSV = s.a.Selected_Sal_Level;
+ switch (s.b.Level_Name)
+ {
+ case "Confidence_Level":
+ Q_CV = s.b.Standard_Specific_Sal_Level;
+ break;
+ case "Integrity_Level":
+ Q_IV = s.b.Standard_Specific_Sal_Level;
+ break;
+ case "Availability_Level":
+ Q_AV = s.b.Standard_Specific_Sal_Level;
+ break;
+ }
+ }
+
+ // get active SAL type
+ var standardSelection = _context.STANDARD_SELECTION.Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ return new BasicReportData.OverallSALTable()
+ {
+ OSV = OSV,
+ Q_CV = Q_CV,
+ Q_AV = Q_AV,
+ Q_IV = Q_IV,
+ LastSalDeterminationType = standardSelection.Last_Sal_Determination_Type
+ };
+ }
+
+
+ ///
+ /// Returns a block of data generally from the INFORMATION table plus a few others.
+ ///
+ ///
+ public BasicReportData.INFORMATION GetInformation()
+ {
+ INFORMATION infodb = _context.INFORMATION.Where(x => x.Id == _assessmentId).FirstOrDefault();
+
+ TinyMapper.Bind(config =>
+ {
+ config.Ignore(x => x.Additional_Contacts);
+ });
+ var info = TinyMapper.Map(infodb);
+
+ var assessment = _context.ASSESSMENTS.FirstOrDefault(x => x.Assessment_Id == _assessmentId);
+ info.Assessment_Date = assessment.Assessment_Date;
+
+ info.Assessment_Effective_Date = assessment.AssessmentEffectiveDate;
+ info.Assessment_Creation_Date = assessment.AssessmentCreatedDate;
+
+ // Primary Assessor
+ var user = _context.USERS.FirstOrDefault(x => x.UserId == assessment.AssessmentCreatorId);
+ info.Assessor_Name = user != null ? FormatName(user.FirstName, user.LastName) : string.Empty;
+
+
+ // Other Contacts
+ info.Additional_Contacts = new List();
+ var contacts = _context.ASSESSMENT_CONTACTS
+ .Where(ac => ac.Assessment_Id == _assessmentId
+ && ac.UserId != assessment.AssessmentCreatorId)
+ .Include(u => u.User)
+ .ToList();
+ foreach (var c in contacts)
+ {
+ info.Additional_Contacts.Add(FormatName(c.FirstName, c.LastName));
+ }
+
+ // Include anything that was in the INFORMATION record's Additional_Contacts column
+ if (infodb.Additional_Contacts != null)
+ {
+ string[] acLines = infodb.Additional_Contacts.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (string c in acLines)
+ {
+ info.Additional_Contacts.Add(c);
+ }
+ }
+
+ info.UseStandard = assessment.UseStandard;
+ info.UseMaturity = assessment.UseMaturity;
+ info.UseDiagram = assessment.UseDiagram;
+
+ // ACET properties
+ info.Credit_Union_Name = assessment.CreditUnionName;
+ info.Charter = assessment.Charter;
+
+ info.Assets = 0;
+ bool a = long.TryParse(assessment.Assets, out long assets);
+ if (a)
+ {
+ info.Assets = assets;
+ }
+
+ // Maturity properties
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .FirstOrDefault(x => x.Assessment_Id == _assessmentId);
+ if (myModel != null)
+ {
+ info.QuestionsAlias = myModel.model.Questions_Alias;
+ }
+
+ return info;
+ }
+
+
+ ///
+ /// Returns a list of individuals assigned to observations.
+ ///
+ ///
+ public List GetObservationIndividuals()
+ {
+ var observations = (from a in _context.FINDING_CONTACT
+ join b in _context.FINDING on a.Finding_Id equals b.Finding_Id
+ join c in _context.ANSWER on b.Answer_Id equals c.Answer_Id
+ join mq in _context.MATURITY_QUESTIONS on c.Question_Or_Requirement_Id equals mq.Mat_Question_Id into mq1
+ from mq in mq1.DefaultIfEmpty()
+ join r in _context.NEW_REQUIREMENT on c.Question_Or_Requirement_Id equals r.Requirement_Id into r1
+ from r in r1.DefaultIfEmpty()
+ join d in _context.ASSESSMENT_CONTACTS on a.Assessment_Contact_Id equals d.Assessment_Contact_Id
+ join i in _context.IMPORTANCE on b.Importance_Id equals i.Importance_Id into i1
+ from i in i1.DefaultIfEmpty()
+ where c.Assessment_Id == _assessmentId
+ orderby a.Assessment_Contact_Id, b.Answer_Id, b.Finding_Id
+ select new { a, b, c, mq, r, d, i.Value }).ToList();
+
+
+ // Get any associated questions to get their display reference
+ var standardQuestions = GetQuestionsForEachStandard();
+ var componentQuestions = GetComponentQuestions();
+
+
+ List individualList = new List();
+
+ int contactId = 0;
+ Individual individual = null;
+
+ foreach (var f in observations)
+ {
+ if (contactId != f.a.Assessment_Contact_Id)
+ {
+ individual = new Individual()
+ {
+ Observations = new List(),
+ INDIVIDUALFULLNAME = FormatName(f.d.FirstName, f.d.LastName)
+ };
+
+ individualList.Add(individual);
+ }
+ contactId = f.a.Assessment_Contact_Id;
+
+
+ TinyMapper.Bind();
+ Observations obs = TinyMapper.Map(f.b);
+ obs.Observation = f.b.Summary;
+ obs.ResolutionDate = f.b.Resolution_Date;
+ obs.Importance = f.Value;
+
+
+ // get the question identifier and text
+ GetQuestionTitleAndText(f, standardQuestions, componentQuestions, f.c.Answer_Id,
+ out string qid, out string qtxt);
+
+ if (_maturityBusiness.GetMaturityModel(_assessmentId)?.ModelName == "CIE")
+ {
+ GetQuestionTitleAndTextForCie(f, standardQuestions, componentQuestions, f.c.Answer_Id,
+ out qid, out qtxt);
+ }
+
+ obs.QuestionIdentifier = qid;
+ obs.QuestionText = qtxt;
+
+
+
+ var othersList = (from a in f.b.FINDING_CONTACT
+ join b in _context.ASSESSMENT_CONTACTS on a.Assessment_Contact_Id equals b.Assessment_Contact_Id
+ select FormatName(b.FirstName, b.LastName)).ToList();
+ obs.OtherContacts = string.Join(",", othersList);
+
+ individual.Observations.Add(obs);
+ }
+
+ return individualList;
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ public GenSALTable GetGenSals()
+ {
+ var gensalnames = _context.GEN_SAL_NAMES.ToList();
+ var actualvalues = (from a in _context.GENERAL_SAL.Where(x => x.Assessment_Id == _assessmentId)
+ join b in _context.GEN_SAL_WEIGHTS on new { a.Sal_Name, a.Slider_Value } equals new { b.Sal_Name, b.Slider_Value }
+ select b).ToList();
+ GenSALTable genSALTable = new GenSALTable();
+ foreach (var a in gensalnames)
+ {
+ genSALTable.setValue(a.Sal_Name, "None");
+ }
+ foreach (var a in actualvalues)
+ {
+ genSALTable.setValue(a.Sal_Name, a.Display);
+ }
+ return genSALTable;
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ public MaturityReportData.MaturityModel GetBasicMaturityModel()
+ {
+ var query = (
+ from amm in _context.AVAILABLE_MATURITY_MODELS
+ join mm in _context.MATURITY_MODELS on amm.model_id equals mm.Maturity_Model_Id
+ where amm.Assessment_Id == _assessmentId
+ select new { amm, mm }
+ ).FirstOrDefault();
+
+
+ var response = new MaturityReportData.MaturityModel()
+ {
+ MaturityModelName = query.mm.Model_Name,
+ TargetLevel = null
+ };
+
+ var asl = _context.ASSESSMENT_SELECTED_LEVELS
+ .Where(x => x.Assessment_Id == _assessmentId && x.Level_Name == Constants.Constants.MaturityLevel)
+ .FirstOrDefault();
+
+ if (asl != null)
+ {
+ response.TargetLevel = int.Parse(asl.Standard_Specific_Sal_Level);
+ }
+
+ return response;
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ public List GetMaturityModelData()
+ {
+ List mat_questions = new List();
+ List mat_models = new List();
+
+ _context.FillEmptyMaturityQuestionsForAnalysis(_assessmentId);
+
+ var query = (
+ from amm in _context.AVAILABLE_MATURITY_MODELS
+ join mm in _context.MATURITY_MODELS on amm.model_id equals mm.Maturity_Model_Id
+ join mq in _context.MATURITY_QUESTIONS on mm.Maturity_Model_Id equals mq.Maturity_Model_Id
+ join ans in _context.ANSWER on mq.Mat_Question_Id equals ans.Question_Or_Requirement_Id
+ join asl in _context.ASSESSMENT_SELECTED_LEVELS on amm.Assessment_Id equals asl.Assessment_Id
+ where amm.Assessment_Id == _assessmentId
+ && ans.Assessment_Id == _assessmentId
+ && ans.Is_Maturity == true
+ && asl.Level_Name == Constants.Constants.MaturityLevel
+ select new { amm, mm, mq, ans, asl }
+ ).ToList();
+ var models = query.Select(x => new { x.mm, x.asl }).Distinct();
+ foreach (var model in models)
+ {
+ MaturityReportData.MaturityModel newModel = new MaturityReportData.MaturityModel();
+ newModel.MaturityModelName = model.mm.Model_Name;
+ newModel.MaturityModelID = model.mm.Maturity_Model_Id;
+ if (Int32.TryParse(model.asl.Standard_Specific_Sal_Level, out int lvl))
+ {
+ newModel.TargetLevel = lvl;
+ }
+ else
+ {
+ newModel.TargetLevel = null;
+ }
+ mat_models.Add(newModel);
+ }
+
+ foreach (var queryItem in query)
+ {
+ MaturityQuestion newQuestion = new MaturityQuestion();
+ newQuestion.Mat_Question_Id = queryItem.mq.Mat_Question_Id;
+ newQuestion.Question_Title = queryItem.mq.Question_Title;
+ newQuestion.Question_Text = queryItem.mq.Question_Text;
+ newQuestion.Supplemental_Info = queryItem.mq.Supplemental_Info;
+ newQuestion.Examination_Approach = queryItem.mq.Examination_Approach;
+ newQuestion.Grouping_Id = queryItem.mq.Grouping_Id ?? 0;
+ newQuestion.Parent_Question_Id = queryItem.mq.Parent_Question_Id;
+ newQuestion.Maturity_Level = queryItem.mq.Maturity_Level_Id;
+ newQuestion.Set_Name = queryItem.mm.Model_Name;
+ newQuestion.Sequence = queryItem.mq.Sequence;
+ newQuestion.Maturity_Model_Id = queryItem.mm.Maturity_Model_Id;
+ newQuestion.Answer = queryItem.ans;
+
+ mat_models.Where(x => x.MaturityModelID == newQuestion.Maturity_Model_Id)
+ .FirstOrDefault()
+ .MaturityQuestions.Add(newQuestion);
+
+ mat_questions.Add(newQuestion);
+ }
+
+ return mat_models;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/ReportsUtils.cs b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/ReportsUtils.cs
new file mode 100644
index 0000000000..a3da3ccb49
--- /dev/null
+++ b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsData/ReportsUtils.cs
@@ -0,0 +1,398 @@
+////////////////////////////////
+//
+// Copyright 2024 Battelle Energy Alliance, LLC
+//
+//
+////////////////////////////////
+using CSETWebCore.Business.Question;
+using CSETWebCore.DataLayer.Model;
+using CSETWebCore.Helpers;
+using CSETWebCore.Interfaces.Reports;
+using CSETWebCore.Model.Maturity;
+using CSETWebCore.Model.Question;
+using CSETWebCore.Model.Reports;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+
+namespace CSETWebCore.Business.Reports
+{
+ public partial class ReportsDataBusiness : IReportsDataBusiness
+ {
+
+ ///
+ ///
+ ///
+ ///
+ public void SetReportsAssessmentId(int assessmentId)
+ {
+ _assessmentId = assessmentId;
+ }
+
+
+ ///
+ /// Returns a list of MatRelevantAnswers that have been answered "A".
+ ///
+ ///
+ public List GetAlternatesList()
+ {
+ var responseList = GetQuestionsList().Where(x => (x.ANSWER.Answer_Text == "A")).ToList();
+ return responseList;
+ }
+
+ ///
+ /// Returns a list of domains for the assessment.
+ ///
+ ///
+ public List GetDomains()
+ {
+ var myModel = _context.AVAILABLE_MATURITY_MODELS
+ .Include(x => x.model)
+ .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
+
+ // Get all domains for this maturity model
+ var domains = _context.MATURITY_GROUPINGS
+ .Include(x => x.Type)
+ .Where(x => x.Maturity_Model_Id == myModel.model_id && x.Type_Id == 1).ToList();
+
+ return domains.Select(d => d.Title).ToList();
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ public List GetControls(string applicationMode)
+ {
+ var lang = _tokenManager.GetCurrentLanguage();
+ var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
+
+ _questionRequirement.InitializeManager(_assessmentId);
+
+ _context.FillEmptyQuestionsForAnalysis(_assessmentId);
+
+ string level = _questionRequirement.StandardLevel == null ? "L" : _questionRequirement.StandardLevel;
+
+ List controlRows = new List();
+
+ if (applicationMode == CSETWebCore.Business.Assessment.AssessmentMode.QUESTIONS_BASED_APPLICATION_MODE)
+ {
+ var qQ = (from rs in _context.REQUIREMENT_SETS
+ join r in _context.NEW_REQUIREMENT on rs.Requirement_Id equals r.Requirement_Id
+ join rl in _context.REQUIREMENT_LEVELS on r.Requirement_Id equals rl.Requirement_Id
+ join s in _context.SETS on rs.Set_Name equals s.Set_Name
+ join av in _context.AVAILABLE_STANDARDS on s.Set_Name equals av.Set_Name
+ join rqs in _context.REQUIREMENT_QUESTIONS_SETS on new { r.Requirement_Id, s.Set_Name } equals new { rqs.Requirement_Id, rqs.Set_Name }
+ join qu in _context.NEW_QUESTION on rqs.Question_Id equals qu.Question_Id
+ join a in _context.Answer_Questions_No_Components on qu.Question_Id equals a.Question_Or_Requirement_Id
+ where rl.Standard_Level == level && av.Selected == true && rl.Level_Type == "NST"
+ && av.Assessment_Id == _assessmentId && a.Assessment_Id == _assessmentId
+ orderby r.Standard_Category, r.Standard_Sub_Category, rs.Requirement_Sequence
+ select new { r, rl, s, qu, a }).ToList();
+
+ foreach (var q in qQ)
+ {
+ controlRows.Add(new ControlRow()
+ {
+ Requirement_Id = q.r.Requirement_Id,
+ Requirement_Text = q.r.Requirement_Text,
+ Answer_Text = q.a.Answer_Text,
+ Comment = q.a.Comment,
+ Question_Id = q.qu.Question_Id,
+ Requirement_Title = q.r.Requirement_Title,
+ Short_Name = q.s.Short_Name,
+ Simple_Question = q.qu.Simple_Question,
+ Standard_Category = q.r.Standard_Category,
+ Standard_Sub_Category = q.r.Standard_Sub_Category,
+ Standard_Level = q.rl.Standard_Level
+ });
+ }
+ }
+ else
+ {
+ var qR = (from rs in _context.REQUIREMENT_SETS
+ join r in _context.NEW_REQUIREMENT on rs.Requirement_Id equals r.Requirement_Id
+ join rl in _context.REQUIREMENT_LEVELS on r.Requirement_Id equals rl.Requirement_Id
+ join s in _context.SETS on rs.Set_Name equals s.Set_Name
+ join av in _context.AVAILABLE_STANDARDS on s.Set_Name equals av.Set_Name
+ join rqs in _context.REQUIREMENT_QUESTIONS_SETS on new { r.Requirement_Id, s.Set_Name } equals new { rqs.Requirement_Id, rqs.Set_Name }
+ join qu in _context.NEW_QUESTION on rqs.Question_Id equals qu.Question_Id
+ join a in _context.Answer_Requirements on r.Requirement_Id equals a.Question_Or_Requirement_Id
+ where rl.Standard_Level == level && av.Selected == true && rl.Level_Type == "NST"
+ && av.Assessment_Id == _assessmentId && a.Assessment_Id == _assessmentId
+ orderby r.Standard_Category, r.Standard_Sub_Category, rs.Requirement_Sequence
+ select new { r, rl, s, qu, a }).ToList();
+
+ foreach (var q in qR)
+ {
+ controlRows.Add(new ControlRow()
+ {
+ Requirement_Id = q.a.Question_Or_Requirement_Id,
+ Requirement_Text = q.r.Requirement_Text,
+ Answer_Text = q.a.Answer_Text,
+ Comment = q.a.Comment,
+ Question_Id = q.qu.Question_Id,
+ Requirement_Title = q.r.Requirement_Title,
+ Short_Name = q.s.Short_Name,
+ Simple_Question = q.qu.Simple_Question,
+ Standard_Category = q.r.Standard_Category,
+ Standard_Sub_Category = q.r.Standard_Sub_Category,
+ Standard_Level = q.rl.Standard_Level,
+ Answer_Id = q.a.Answer_Id
+ });
+ }
+ }
+
+
+
+ //get all the questions for this control
+ //determine the percent implemented.
+ int prev_requirement_id = 0;
+ int questionCount = 0;
+ int questionsAnswered = 0;
+ BasicReportData.RequirementControl control = null;
+ List questions = null;
+
+ // The response
+ List controls = [];
+
+ foreach (var a in controlRows)
+ {
+ if (prev_requirement_id != a.Requirement_Id)
+ {
+ questionCount = 0;
+ questionsAnswered = 0;
+ questions = new List();
+
+
+ // look for translations
+ var r = _overlay.GetRequirement(a.Requirement_Id, lang);
+ var c = _overlay.GetPropertyValue("STANDARD_CATEGORY", a.Standard_Category.ToLower(), lang);
+ var s = _overlay.GetPropertyValue("STANDARD_CATEGORY", a.Standard_Sub_Category.ToLower(), lang);
+
+
+ // Replace parameter in requirement text if custom parameter is found
+ a.Requirement_Text = rm.ResolveParameters(a.Requirement_Id, a.Answer_Id, a.Requirement_Text);
+
+ control = new BasicReportData.RequirementControl()
+ {
+ ControlDescription = r?.RequirementText ?? a.Requirement_Text,
+ RequirementTitle = a.Requirement_Title,
+ Level = a.Standard_Level,
+ StandardShortName = a.Short_Name,
+ Standard_Category = c ?? a.Standard_Category,
+ SubCategory = s ?? a.Standard_Sub_Category,
+ Control_Questions = questions
+ };
+
+
+
+ controls.Add(control);
+ }
+
+ questionCount++;
+
+ switch (a.Answer_Text)
+ {
+ case Constants.Constants.ALTERNATE:
+ case Constants.Constants.YES:
+ questionsAnswered++;
+ break;
+ }
+
+ questions.Add(new BasicReportData.Control_Questions()
+ {
+ Answer = a.Answer_Text,
+ Comment = a.Comment,
+ Simple_Question = a.Simple_Question
+ });
+
+ control.ImplementationStatus = StatUtils.Percentagize(questionsAnswered, questionCount, 2).ToString("##.##");
+ prev_requirement_id = a.Requirement_Id;
+ }
+
+ return controls;
+ }
+
+
+ public List GetDocumentLibrary()
+ {
+ List list = new List();
+ var docs = from a in _context.DOCUMENT_FILE
+ where a.Assessment_Id == _assessmentId
+ select a;
+ foreach (var doc in docs)
+ {
+ var dlt = new DocumentLibraryTable()
+ {
+ DocumentTitle = doc.Title,
+ FileName = doc.Path
+ };
+
+ if (dlt.DocumentTitle == "click to edit title")
+ {
+ dlt.DocumentTitle = "(untitled)";
+ }
+
+ list.Add(dlt);
+ }
+
+ return list;
+ }
+
+
+ ///
+ /// Formats an identifier for the corresponding question.
+ /// Also returns the question text with parameters applied, in the
+ /// case of a requirement.
+ ///
+ /// If the user's language is non-English, attempts to overlay the
+ /// question text with the translated version.
+ ///
+ ///
+ private void GetQuestionTitleAndText(dynamic f,
+ List stdList, List compList,
+ int answerId,
+ out string identifier, out string questionText)
+ {
+ identifier = "";
+ questionText = "";
+ var lang = _tokenManager.GetCurrentLanguage();
+
+ switch (f.c.Question_Type)
+ {
+ case "Question":
+ foreach (var s in stdList)
+ {
+ var q1 = s.Questions.FirstOrDefault(x => x.QuestionId == f.c.Question_Or_Requirement_Id);
+ if (q1 != null)
+ {
+ identifier = q1.CategoryAndNumber;
+ questionText = q1.Question;
+ return;
+ }
+ }
+
+ return;
+
+ case "Component":
+ var q2 = compList.FirstOrDefault(x => x.QuestionId == f.c.Question_Or_Requirement_Id);
+ if (q2 != null)
+ {
+ identifier = q2.ComponentName;
+ questionText = q2.Question;
+ }
+
+ return;
+
+ case "Requirement":
+ identifier = f.r.Requirement_Title;
+ var rb = new RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
+ questionText = rb.ResolveParameters(f.r.Requirement_Id, answerId, f.r.Requirement_Text);
+
+ // translate
+ questionText = _overlay.GetRequirement(f.r.Requirement_Id, lang)?.RequirementText ?? questionText;
+
+ return;
+
+ case "Maturity":
+
+ identifier = f.mq.Question_Title;
+ questionText = f.mq.Question_Text;
+
+ // CPG is a special case
+ if (!String.IsNullOrEmpty(f.mq.Security_Practice))
+ {
+ questionText = f.mq.Security_Practice;
+ }
+
+ // overlay
+ MaturityQuestionOverlay o = _overlay.GetMaturityQuestion(f.mq.Mat_Question_Id, lang);
+ if (o != null)
+ {
+ identifier = o.QuestionTitle;
+ questionText = o.QuestionText;
+ }
+ return;
+
+ default:
+ return;
+ }
+ }
+
+
+ ///
+ /// Formats first and last name. If the name is believed to be a domain\userid,
+ /// the userid is returned with the domain removed.
+ ///
+ ///
+ ///
+ ///
+ public string FormatName(string firstName, string lastName)
+ {
+ firstName = firstName.Trim();
+ lastName = lastName.Trim();
+
+ if (firstName.Length > 0 && lastName.Length > 0)
+ {
+ return string.Format("{0} {1}", firstName, lastName);
+ }
+
+ // if domain-qualified userid, remove domain
+ if (firstName.IndexOf('\\') >= 0 && firstName.IndexOf(' ') < 0 && lastName.Length == 0)
+ {
+ return firstName.Substring(firstName.LastIndexOf('\\') + 1);
+ }
+
+ return string.Format("{0} {1}", firstName, lastName);
+ }
+
+
+ ///
+ /// Gets all confidential types for report generation
+ ///
+ ///
+ public IEnumerable GetConfidentialTypes()
+ {
+ return _context.CONFIDENTIAL_TYPE.OrderBy(x => x.ConfidentialTypeOrder);
+ }
+
+ private void NullOutNavigationPropeties(List list)
+ {
+ // null out a few navigation properties to avoid circular references that blow up the JSON stringifier
+ foreach (MatRelevantAnswers a in list)
+ {
+ a.ANSWER.Assessment = null;
+ a.Mat.Maturity_Model = null;
+ a.Mat.InverseParent_Question = null;
+ a.Mat.Parent_Question = null;
+
+ if (a.Mat.Grouping != null)
+ {
+ a.Mat.Grouping.Maturity_Model = null;
+ a.Mat.Grouping.MATURITY_QUESTIONS = null;
+ a.Mat.Grouping.Type = null;
+ }
+
+ if (a.Mat.Maturity_Level != null)
+ {
+ a.Mat.Maturity_Level.MATURITY_QUESTIONS = null;
+ a.Mat.Maturity_Level.Maturity_Model = null;
+ }
+ }
+ }
+
+ public string GetCsetVersion()
+ {
+ return _context.CSET_VERSION.Select(x => x.Cset_Version1).FirstOrDefault();
+ }
+
+ public string GetAssessmentGuid(int assessmentId)
+ {
+ return _context.ASSESSMENTS.Where(x => x.Assessment_Id == assessmentId).Select(x => x.Assessment_GUID).FirstOrDefault().ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsDataBusiness.cs b/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsDataBusiness.cs
deleted file mode 100644
index bd04e89d69..0000000000
--- a/CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Reports/ReportsDataBusiness.cs
+++ /dev/null
@@ -1,2861 +0,0 @@
-////////////////////////////////
-//
-// Copyright 2024 Battelle Energy Alliance, LLC
-//
-//
-////////////////////////////////
-using CSETWebCore.Business.Acet;
-using CSETWebCore.Business.Maturity;
-using CSETWebCore.Business.Maturity.Configuration;
-using CSETWebCore.Business.Question;
-using CSETWebCore.Business.Sal;
-using CSETWebCore.DataLayer.Manual;
-using CSETWebCore.DataLayer.Model;
-using CSETWebCore.Helpers;
-using CSETWebCore.Interfaces.AdminTab;
-using CSETWebCore.Interfaces.Helpers;
-using CSETWebCore.Interfaces.Maturity;
-using CSETWebCore.Interfaces.Question;
-using CSETWebCore.Interfaces.Reports;
-using CSETWebCore.Model.Diagram;
-using CSETWebCore.Model.Document;
-using CSETWebCore.Model.Maturity;
-using CSETWebCore.Model.Question;
-using CSETWebCore.Model.Reports;
-using CSETWebCore.Model.Set;
-using Microsoft.AspNetCore.Components;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.EntityFrameworkCore;
-using Nelibur.ObjectMapper;
-using Snickler.EFCore;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Runtime.Intrinsics.Arm;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using static Lucene.Net.Util.Fst.Util;
-
-
-namespace CSETWebCore.Business.Reports
-{
- public class ReportsDataBusiness : IReportsDataBusiness
- {
- private readonly CSETContext _context;
- private readonly IAssessmentUtil _assessmentUtil;
- private int _assessmentId;
- private readonly IAdminTabBusiness _adminTabBusiness;
- private readonly IMaturityBusiness _maturityBusiness;
- private readonly IQuestionRequirementManager _questionRequirement;
- private readonly ITokenManager _tokenManager;
-
- public List OutOfScopeQuestions = new List();
-
- private TranslationOverlay _overlay;
-
-
-
- ///
- /// Constructor.
- ///
- ///
- public ReportsDataBusiness(CSETContext context, IAssessmentUtil assessmentUtil, IAdminTabBusiness adminTabBusiness, IAssessmentModeData assessmentMode,
- IMaturityBusiness maturityBusiness, IQuestionRequirementManager questionRequirement, ITokenManager tokenManager)
- {
- _context = context;
- _assessmentUtil = assessmentUtil;
- _adminTabBusiness = adminTabBusiness;
- _maturityBusiness = maturityBusiness;
- _questionRequirement = questionRequirement;
- _tokenManager = tokenManager;
-
- _overlay = new TranslationOverlay();
- }
-
-
- ///
- ///
- ///
- ///
- public void SetReportsAssessmentId(int assessmentId)
- {
- _assessmentId = assessmentId;
- }
-
-
- ///
- /// Returns an unfiltered list of MatRelevantAnswers for the current assessment.
- /// The optional modelId parameter is used to get a specific model's questions. If not
- /// supplied, the default model's questions are retrieved.
- ///
- ///
- public List GetQuestionsList(int? modelId = null)
- {
- int targetModelId = 0;
-
- if (modelId == null)
- {
- var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
- if (myModel == null)
- {
- return new List();
- }
-
- targetModelId = myModel.model_id;
- }
- else
- {
- targetModelId = (int)modelId;
- }
-
-
- var lang = _tokenManager.GetCurrentLanguage();
-
- _context.FillEmptyMaturityQuestionsForAnalysis(_assessmentId);
-
- // flesh out model-specific questions
- if (modelId != null)
- {
- _context.FillEmptyMaturityQuestionsForModel(_assessmentId, (int)modelId);
- }
-
- var query = from a in _context.ANSWER
- join m in _context.MATURITY_QUESTIONS.Include(x => x.Maturity_Level)
- on a.Question_Or_Requirement_Id equals m.Mat_Question_Id
- where a.Assessment_Id == _assessmentId
- && m.Maturity_Model_Id == targetModelId
- && a.Question_Type == "Maturity"
- && !this.OutOfScopeQuestions.Contains(m.Mat_Question_Id)
- orderby m.Grouping_Id, m.Maturity_Level_Id, m.Mat_Question_Id ascending
- select new MatRelevantAnswers()
- {
- ANSWER = a,
- Mat = m
- };
-
- var responseList = query.ToList();
- var childQuestions = responseList.FindAll(x => x.Mat.Parent_Question_Id != null);
-
- // Set IsParentWithChildren property for all parent questions that have child questions
- foreach (var matAns in responseList)
- {
- if (childQuestions.Exists(x => x.Mat.Parent_Question_Id == matAns.Mat.Mat_Question_Id))
- {
- matAns.IsParentWithChildren = true;
- }
- }
-
- foreach (var matAns in responseList)
- {
- var o = _overlay.GetMaturityQuestion(matAns.Mat.Mat_Question_Id, lang);
- if (o != null)
- {
- matAns.Mat.Question_Title = o.QuestionTitle ?? matAns.Mat.Question_Title;
- matAns.Mat.Question_Text = o.QuestionText;
- matAns.Mat.Supplemental_Info = o.SupplementalInfo;
- }
- }
-
-
- // if a maturity level is defined, only report on questions at or below that level
- int? selectedLevel = _context.ASSESSMENT_SELECTED_LEVELS.Where(x => x.Assessment_Id == _assessmentId
- && x.Level_Name == Constants.Constants.MaturityLevel).Select(x => int.Parse(x.Standard_Specific_Sal_Level)).FirstOrDefault();
-
- NullOutNavigationPropeties(responseList);
-
- // RRA should be always be defaulted to its maximum available level (3)
- // since the user can't configure it
- if (targetModelId == 5)
- {
- selectedLevel = 3;
- }
-
- if (selectedLevel != null && selectedLevel != 0)
- {
- responseList = responseList.Where(x => x.Mat.Maturity_Level.Level <= selectedLevel).ToList();
- }
-
-
- return responseList;
- }
-
-
- ///
- /// Returns a list of MatRelevantAnswers that are considered deficient for the assessment.
- ///
- ///
- public List GetMaturityDeficiencies(int? modelId = null)
- {
- var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
- var targetModel = myModel.model;
-
-
- // if a model was explicitly requested, do that one
- if (modelId != null)
- {
- targetModel = _context.MATURITY_MODELS.Where(x => x.Maturity_Model_Id == modelId).FirstOrDefault();
- }
-
-
- bool ignoreParentQuestions = false;
-
- // default answer values that are considered 'deficient' (in case we can't find a model config profile)
- List deficientAnswerValues = new List() { "N", "U" };
-
-
- // try to get a configuration for the actual model
- var modelProperties = new ModelProfile().GetModelProperties(targetModel.Maturity_Model_Id);
- if (modelProperties != null)
- {
- deficientAnswerValues = modelProperties.DeficientAnswers;
- ignoreParentQuestions = modelProperties.IgnoreParentQuestions;
- }
-
-
- var responseList = GetQuestionsList(targetModel.Maturity_Model_Id).Where(x => deficientAnswerValues.Contains(x.ANSWER.Answer_Text)).ToList();
-
-
- // We don't consider parent questions that have children to be unanswered for certain maturity models
- // (i.e. for CRR, EDM since they just house the question extras)
- if (ignoreParentQuestions)
- {
- responseList = responseList.Where(x => !x.IsParentWithChildren).ToList();
- }
-
-
- // If the assessment is using a submodel, only keep the submodel's subset of questions
- var maturitySubmodel = _context.DETAILS_DEMOGRAPHICS.Where(x => x.Assessment_Id == _assessmentId && x.DataItemName == "MATURITY-SUBMODEL").FirstOrDefault();
- if (maturitySubmodel != null)
- {
- var whitelist = _context.MATURITY_SUB_MODEL_QUESTIONS.Where(x => x.Sub_Model_Name == maturitySubmodel.StringValue).Select(q => q.Mat_Question_Id).ToList();
- responseList = responseList.Where(x => whitelist.Contains(x.Mat.Mat_Question_Id)).ToList();
- }
-
- return responseList;
- }
-
-
-
- ///
- /// Returns a list of MatRelevantAnswers that contain comments.
- ///
- ///
- public List GetCommentsList(int? modelId = null)
- {
- var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
- var targetModel = myModel.model;
-
- // if a model was explicitly requested, do that one
- if (modelId != null)
- {
- targetModel = _context.MATURITY_MODELS.Where(x => x.Maturity_Model_Id == modelId).FirstOrDefault();
- }
-
- var responseList = GetQuestionsList(targetModel.Maturity_Model_Id).Where(x => !string.IsNullOrWhiteSpace(x.ANSWER.Comment)).ToList();
-
- return responseList;
- }
-
-
- ///
- /// Returns a list of MatRelevantAnswers that are marked for review.
- ///
- ///
- ///
- public List GetMarkedForReviewList(int? modelId = null)
- {
- var myModel = _context.AVAILABLE_MATURITY_MODELS.Include(x => x.model).Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
- var targetModel = myModel.model;
-
- // if a model was explicitly requested, do that one
- if (modelId != null)
- {
- targetModel = _context.MATURITY_MODELS.Where(x => x.Maturity_Model_Id == modelId).FirstOrDefault();
- }
-
- var responseList = GetQuestionsList(targetModel.Maturity_Model_Id).Where(x => x.ANSWER.Mark_For_Review ?? false).ToList();
-
- return responseList;
- }
-
-
- ///
- /// Returns a list of MatRelevantAnswers that have been answered "A".
- ///
- ///
- public List GetAlternatesList()
- {
- var responseList = GetQuestionsList().Where(x => (x.ANSWER.Answer_Text == "A")).ToList();
- return responseList;
- }
-
-
- ///
- /// Returns a list of answered maturity questions. This was built for ACET
- /// but could be used by other maturity models with some work.
- ///
- ///
- public List GetAnsweredQuestionList()
- {
- List controls = new List();
-
- var lang = _tokenManager.GetCurrentLanguage();
-
-
- var myModel = _context.AVAILABLE_MATURITY_MODELS
- .Include(x => x.model)
- .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
- var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
-
- // get the target maturity level IDs
- var targetRange = new ACETMaturityBusiness(_context, _assessmentUtil, _adminTabBusiness).GetMaturityRangeIds(_assessmentId);
-
- var questions = _context.MATURITY_QUESTIONS.Where(q =>
- myModel.model_id == q.Maturity_Model_Id
- && targetRange.Contains(q.Maturity_Level_Id)).ToList();
-
-
- // apply overlay
- foreach (var q in questions)
- {
- var o = _overlay.GetMaturityQuestion(q.Mat_Question_Id, lang);
- if (o != null)
- {
- q.Question_Title = o.QuestionTitle ?? q.Question_Title;
- q.Question_Text = o.QuestionText;
- q.Supplemental_Info = o.SupplementalInfo;
- q.Examination_Approach = o.ExaminationApproach;
- }
- }
-
-
- // Get all MATURITY answers for the assessment
- var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
- from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
- select new FullAnswer() { a = a, b = b };
-
-
- // Get all subgroupings for this maturity model
- var allGroupings = _context.MATURITY_GROUPINGS
- .Include(x => x.Type)
- .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
-
-
- // apply translation overlay
- foreach (var g in allGroupings)
- {
- var o = _overlay.GetMaturityGrouping(g.Grouping_Id, lang);
- if (o != null)
- {
- g.Title = o.Title;
- g.Description = o.Description;
- }
- }
-
-
- // Recursively build the grouping/question hierarchy
- var questionGrouping = new MaturityGrouping();
- BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
-
- var maturityDomains = new List();
-
- foreach (var domain in questionGrouping.SubGroupings)
- {
- var newDomain = new MatAnsweredQuestionDomain()
- {
- Title = domain.Title,
- IsDeficient = false,
- AssessmentFactors = new List()
- };
- foreach (var assesmentFactor in domain.SubGroupings)
- {
- var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
- {
- Title = assesmentFactor.Title,
- IsDeficient = false,
- Components = new List()
- };
-
- foreach (var componenet in assesmentFactor.SubGroupings)
- {
- var newComponent = new MaturityAnsweredQuestionsComponent()
- {
- Title = componenet.Title,
- IsDeficient = false,
- Questions = new List()
- };
-
- foreach (var question in componenet.Questions)
- {
- if (question.Answer != null)
- {
- var newQuestion = new MaturityAnsweredQuestions()
- {
- Title = question.DisplayNumber,
- QuestionText = question.QuestionText,
- MaturityLevel = GetLevelLabel(question.MaturityLevel, myMaturityLevels),
- AnswerText = question.Answer,
- Comment = question.Comment,
- MarkForReview = question.MarkForReview
- };
-
-
- // overlay
- var o = _overlay.GetMaturityQuestion(question.QuestionId, lang);
- if (o != null)
- {
- newQuestion.QuestionText = o.QuestionText;
- }
-
-
-
- if (question.Answer == "N")
- {
- newDomain.IsDeficient = true;
- newAssesmentFactor.IsDeficient = true;
- newComponent.IsDeficient = true;
- }
-
- if (question.Comment != null)
- {
- newQuestion.Comments = "Yes";
- }
- else
- {
- newQuestion.Comments = "No";
- }
-
- newComponent.Questions.Add(newQuestion);
- }
- }
- if (newComponent.Questions.Count > 0)
- {
- newAssesmentFactor.Components.Add(newComponent);
- }
- }
- if (newAssesmentFactor.Components.Count > 0)
- {
- newDomain.AssessmentFactors.Add(newAssesmentFactor);
- }
- }
- if (newDomain.AssessmentFactors.Count > 0)
- {
- maturityDomains.Add(newDomain);
- }
- }
-
- return maturityDomains;
- }
-
-
- ///
- /// Primarily used for ACET which uses strings to describe their levels
- ///
- ///
- ///
- private string GetLevelLabel(int maturityLevel, List levels)
- {
- return levels.FirstOrDefault(x => x.Maturity_Level_Id == maturityLevel)?.Level_Name ?? "";
- }
-
-
- ///
- /// Returns a list of answered maturity questions. This was built for ACET ISE
- /// but could be used by other maturity models with some work.
- ///
- ///
- public List GetIseAnsweredQuestionList()
- {
- List controls = new List();
-
-
- var myModel = _context.AVAILABLE_MATURITY_MODELS
- .Include(x => x.model)
- .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
- var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
-
- // get the target maturity level IDs
- var targetRange = new ACETMaturityBusiness(_context, _assessmentUtil, _adminTabBusiness).GetIseMaturityRangeIds(_assessmentId);
-
- var questions = _context.MATURITY_QUESTIONS.Where(q =>
- myModel.model_id == q.Maturity_Model_Id
- && targetRange.Contains(q.Maturity_Level_Id)).ToList();
-
-
- // Get all MATURITY answers for the assessment
- var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
- from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
- select new FullAnswer() { a = a, b = b };
-
-
- // Get all subgroupings for this maturity model
- var allGroupings = _context.MATURITY_GROUPINGS
- .Include(x => x.Type)
- .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
-
- //Get All the Observations and issues with the Observations.
-
-
- // Recursively build the grouping/question hierarchy
- var questionGrouping = new MaturityGrouping();
- BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
-
- var maturityDomains = new List();
-
- // ToDo: Refactor the following stucture of loops
- foreach (var domain in questionGrouping.SubGroupings)
- {
- var newDomain = new MatAnsweredQuestionDomain()
- {
- Title = domain.Title,
- IsDeficient = false,
- AssessmentFactors = new List()
- };
- foreach (var assesmentFactor in domain.SubGroupings)
- {
- var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
- {
- Title = assesmentFactor.Title,
- IsDeficient = false,
- Components = new List()
- };
-
- foreach (var componenet in assesmentFactor.SubGroupings)
- {
- var newComponent = new MaturityAnsweredQuestionsComponent()
- {
- Title = componenet.Title,
- IsDeficient = false,
- Questions = new List()
- };
-
- foreach (var question in componenet.Questions)
- {
- if (question.Answer != null)
- {
- var newQuestion = new MaturityAnsweredQuestions()
- {
- Title = question.DisplayNumber,
- QuestionText = question.QuestionText,
- MaturityLevel = GetLevelLabel(question.MaturityLevel, myMaturityLevels),
- AnswerText = question.Answer,
- Comment = question.Comment,
- MarkForReview = question.MarkForReview,
- MatQuestionId = question.QuestionId,
- FreeResponseText = question.FreeResponseAnswer
- };
-
- if (question.Answer == "N")
- {
- newDomain.IsDeficient = true;
- newAssesmentFactor.IsDeficient = true;
- newComponent.IsDeficient = true;
- }
-
- if (question.Comment != null)
- {
- newQuestion.Comments = "Yes";
- }
- else
- {
- newQuestion.Comments = "No";
- }
-
- newComponent.Questions.Add(newQuestion);
- }
- }
- if (newComponent.Questions.Count > 0)
- {
- newAssesmentFactor.Components.Add(newComponent);
- }
- }
- if (newAssesmentFactor.Components.Count > 0)
- {
- newDomain.AssessmentFactors.Add(newAssesmentFactor);
- }
- }
- if (newDomain.AssessmentFactors.Count > 0)
- {
- maturityDomains.Add(newDomain);
- }
- }
-
- return maturityDomains;
- }
-
- ///
- /// Returns a list of answered maturity questions. This was built for ACET ISE
- /// but could be used by other maturity models with some work.
- ///
- ///
- public List GetIseAllQuestionList()
- {
- List controls = new List();
-
-
- var myModel = _context.AVAILABLE_MATURITY_MODELS
- .Include(x => x.model)
- .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
- var myMaturityLevels = _context.MATURITY_LEVELS.Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
-
- // get the target maturity level IDs
- var targetRange = new ACETMaturityBusiness(_context, _assessmentUtil, _adminTabBusiness).GetIseMaturityRangeIds(_assessmentId);
-
- var questions = _context.MATURITY_QUESTIONS.Where(q =>
- myModel.model_id == q.Maturity_Model_Id).ToList();
-
-
- // Get all MATURITY answers for the assessment
- var answers = from a in _context.ANSWER.Where(x => x.Assessment_Id == _assessmentId && x.Question_Type == "Maturity")
- from b in _context.VIEW_QUESTIONS_STATUS.Where(x => x.Answer_Id == a.Answer_Id).DefaultIfEmpty()
- select new FullAnswer() { a = a, b = b };
-
-
- // Get all subgroupings for this maturity model
- var allGroupings = _context.MATURITY_GROUPINGS
- .Include(x => x.Type)
- .Where(x => x.Maturity_Model_Id == myModel.model_id).ToList();
-
- //Get All the Observations and issues with the Observations.
-
-
- // Recursively build the grouping/question hierarchy
- var questionGrouping = new MaturityGrouping();
- BuildSubGroupings(questionGrouping, null, allGroupings, questions, answers.ToList());
-
- var maturityDomains = new List();
-
- // ToDo: Refactor the following stucture of loops
- foreach (var domain in questionGrouping.SubGroupings)
- {
- var newDomain = new MatAnsweredQuestionDomain()
- {
- Title = domain.Title,
- IsDeficient = false,
- AssessmentFactors = new List()
- };
- foreach (var assesmentFactor in domain.SubGroupings)
- {
- var newAssesmentFactor = new MaturityAnsweredQuestionsAssesment()
- {
- Title = assesmentFactor.Title,
- IsDeficient = false,
- Components = new List()
- };
-
- foreach (var componenet in assesmentFactor.SubGroupings)
- {
- var newComponent = new MaturityAnsweredQuestionsComponent()
- {
- Title = componenet.Title,
- IsDeficient = false,
- Questions = new List()
- };
-
- foreach (var question in componenet.Questions)
- {
- if (question.Answer != null)
- {
- var newQuestion = new MaturityAnsweredQuestions()
- {
- Title = question.DisplayNumber,
- QuestionText = question.QuestionText,
- MaturityLevel = GetLevelLabel(question.MaturityLevel, myMaturityLevels),
- AnswerText = question.Answer,
- Comment = question.Comment,
- MarkForReview = question.MarkForReview,
- MatQuestionId = question.QuestionId,
- FreeResponseText = question.FreeResponseAnswer
- };
-
- if (question.Answer == "N")
- {
- newDomain.IsDeficient = true;
- newAssesmentFactor.IsDeficient = true;
- newComponent.IsDeficient = true;
- }
-
- if (question.Comment != null)
- {
- newQuestion.Comments = "Yes";
- }
- else
- {
- newQuestion.Comments = "No";
- }
-
- newComponent.Questions.Add(newQuestion);
- }
- }
- if (newComponent.Questions.Count > 0)
- {
- newAssesmentFactor.Components.Add(newComponent);
- }
- }
- if (newAssesmentFactor.Components.Count > 0)
- {
- newDomain.AssessmentFactors.Add(newAssesmentFactor);
- }
- }
- if (newDomain.AssessmentFactors.Count > 0)
- {
- maturityDomains.Add(newDomain);
- }
- }
-
- return maturityDomains;
- }
-
-
- ///
- /// Returns a block of data generally from the INFORMATION table plus a few others.
- ///
- ///
- public BasicReportData.INFORMATION GetIseInformation()
- {
- INFORMATION infodb = _context.INFORMATION.Where(x => x.Id == _assessmentId).FirstOrDefault();
-
- TinyMapper.Bind(config =>
- {
- config.Ignore(x => x.Additional_Contacts);
- });
- var info = TinyMapper.Map(infodb);
-
- var assessment = _context.ASSESSMENTS.FirstOrDefault(x => x.Assessment_Id == _assessmentId);
- info.Assessment_Date = assessment.Assessment_Date;
-
- info.Assessment_Effective_Date = assessment.AssessmentEffectiveDate;
- info.Assessment_Creation_Date = assessment.AssessmentCreatedDate;
-
- // Primary Assessor
- var user = _context.USERS.FirstOrDefault(x => x.UserId == assessment.AssessmentCreatorId);
- info.Assessor_Name = user != null ? FormatName(user.FirstName, user.LastName) : string.Empty;
-
-
- // Other Contacts
- info.Additional_Contacts = new List();
- var contacts = _context.ASSESSMENT_CONTACTS
- .Where(ac => ac.Assessment_Id == _assessmentId
- && ac.UserId != assessment.AssessmentCreatorId)
- .Include(u => u.User)
- .ToList();
- foreach (var c in contacts)
- {
- info.Additional_Contacts.Add(FormatName(c.FirstName, c.LastName));
- }
-
- // Include anything that was in the INFORMATION record's Additional_Contacts column
- if (infodb.Additional_Contacts != null)
- {
- string[] acLines = infodb.Additional_Contacts.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- foreach (string c in acLines)
- {
- info.Additional_Contacts.Add(c);
- }
- }
-
- info.UseStandard = assessment.UseStandard;
- info.UseMaturity = assessment.UseMaturity;
- info.UseDiagram = assessment.UseDiagram;
-
- // ACET properties
- info.Credit_Union_Name = assessment.CreditUnionName;
- info.Charter = assessment.Charter;
-
- info.Assets = 0;
- bool a = long.TryParse(assessment.Assets, out long assets);
- if (a)
- {
- info.Assets = assets;
- }
-
- // Maturity properties
- var myModel = _context.AVAILABLE_MATURITY_MODELS
- .Include(x => x.model)
- .FirstOrDefault(x => x.Assessment_Id == _assessmentId);
- if (myModel != null)
- {
- info.QuestionsAlias = myModel.model.Questions_Alias;
- }
-
- return info;
- }
-
-
- ///
- /// Returns a list of domains for the assessment.
- ///
- ///
- public List GetDomains()
- {
- var myModel = _context.AVAILABLE_MATURITY_MODELS
- .Include(x => x.model)
- .Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
- // Get all domains for this maturity model
- var domains = _context.MATURITY_GROUPINGS
- .Include(x => x.Type)
- .Where(x => x.Maturity_Model_Id == myModel.model_id && x.Type_Id == 1).ToList();
-
- return domains.Select(d => d.Title).ToList();
- }
-
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public void BuildSubGroupings(MaturityGrouping g, int? parentID,
- List allGroupings,
- List questions,
- List answers)
- {
- var mySubgroups = allGroupings.Where(x => x.Parent_Id == parentID).OrderBy(x => x.Sequence).ToList();
-
- if (mySubgroups.Count == 0)
- {
- return;
- }
-
- foreach (var sg in mySubgroups)
- {
- var newGrouping = new MaturityGrouping()
- {
- GroupingID = sg.Grouping_Id,
- GroupingType = sg.Type.Grouping_Type_Name,
- Title = sg.Title,
- Description = sg.Description,
- Abbreviation = sg.Abbreviation
- };
-
- g.SubGroupings.Add(newGrouping);
-
-
- // are there any questions that belong to this grouping?
- var myQuestions = questions.Where(x => x.Grouping_Id == newGrouping.GroupingID).ToList();
-
- var parentQuestionIDs = myQuestions.Select(x => x.Parent_Question_Id).Distinct().ToList();
-
- foreach (var myQ in myQuestions)
- {
- FullAnswer answer = answers.Where(x => x.a.Question_Or_Requirement_Id == myQ.Mat_Question_Id).FirstOrDefault();
-
- var qa = new QuestionAnswer()
- {
- DisplayNumber = myQ.Question_Title,
- QuestionId = myQ.Mat_Question_Id,
- ParentQuestionId = myQ.Parent_Question_Id,
- QuestionType = "Maturity",
- QuestionText = myQ.Question_Text.Replace("\r\n", "
").Replace("\n", "
").Replace("\r", "
"),
- Answer = answer?.a.Answer_Text,
- AltAnswerText = answer?.a.Alternate_Justification,
- //freeResponseAnswer= answer?.a.Free_Response_Answer,
- Comment = answer?.a.Comment,
- Feedback = answer?.a.FeedBack,
- MarkForReview = answer?.a.Mark_For_Review ?? false,
- Reviewed = answer?.a.Reviewed ?? false,
- Is_Maturity = true,
- MaturityLevel = myQ.Maturity_Level_Id,
- IsParentQuestion = parentQuestionIDs.Contains(myQ.Mat_Question_Id),
- SetName = string.Empty,
- FreeResponseAnswer = answer?.a.Free_Response_Answer
- };
-
- if (answer != null)
- {
- TinyMapper.Bind();
- TinyMapper.Map(answer.b, qa);
-
- // db view still uses the term "HasDiscovery" - map to "HasObservation"
- qa.HasObservation = answer.b.HasDiscovery ?? false;
- }
-
- newGrouping.Questions.Add(qa);
- }
-
- // Recurse down to build subgroupings
- BuildSubGroupings(newGrouping, newGrouping.GroupingID, allGroupings, questions, answers);
- }
- }
-
-
- ///
- ///
- ///
- ///
- public List GetControls(string applicationMode)
- {
- var lang = _tokenManager.GetCurrentLanguage();
- var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
-
- _questionRequirement.InitializeManager(_assessmentId);
-
- _context.FillEmptyQuestionsForAnalysis(_assessmentId);
-
- string level = _questionRequirement.StandardLevel == null ? "L" : _questionRequirement.StandardLevel;
-
- List controlRows = new List();
-
- if (applicationMode == CSETWebCore.Business.Assessment.AssessmentMode.QUESTIONS_BASED_APPLICATION_MODE)
- {
- var qQ = (from rs in _context.REQUIREMENT_SETS
- join r in _context.NEW_REQUIREMENT on rs.Requirement_Id equals r.Requirement_Id
- join rl in _context.REQUIREMENT_LEVELS on r.Requirement_Id equals rl.Requirement_Id
- join s in _context.SETS on rs.Set_Name equals s.Set_Name
- join av in _context.AVAILABLE_STANDARDS on s.Set_Name equals av.Set_Name
- join rqs in _context.REQUIREMENT_QUESTIONS_SETS on new { r.Requirement_Id, s.Set_Name } equals new { rqs.Requirement_Id, rqs.Set_Name }
- join qu in _context.NEW_QUESTION on rqs.Question_Id equals qu.Question_Id
- join a in _context.Answer_Questions_No_Components on qu.Question_Id equals a.Question_Or_Requirement_Id
- where rl.Standard_Level == level && av.Selected == true && rl.Level_Type == "NST"
- && av.Assessment_Id == _assessmentId && a.Assessment_Id == _assessmentId
- orderby r.Standard_Category, r.Standard_Sub_Category, rs.Requirement_Sequence
- select new { r, rl, s, qu, a }).ToList();
-
- foreach (var q in qQ)
- {
- controlRows.Add(new ControlRow()
- {
- Requirement_Id = q.r.Requirement_Id,
- Requirement_Text = q.r.Requirement_Text,
- Answer_Text = q.a.Answer_Text,
- Comment = q.a.Comment,
- Question_Id = q.qu.Question_Id,
- Requirement_Title = q.r.Requirement_Title,
- Short_Name = q.s.Short_Name,
- Simple_Question = q.qu.Simple_Question,
- Standard_Category = q.r.Standard_Category,
- Standard_Sub_Category = q.r.Standard_Sub_Category,
- Standard_Level = q.rl.Standard_Level
- });
- }
- }
- else
- {
- var qR = (from rs in _context.REQUIREMENT_SETS
- join r in _context.NEW_REQUIREMENT on rs.Requirement_Id equals r.Requirement_Id
- join rl in _context.REQUIREMENT_LEVELS on r.Requirement_Id equals rl.Requirement_Id
- join s in _context.SETS on rs.Set_Name equals s.Set_Name
- join av in _context.AVAILABLE_STANDARDS on s.Set_Name equals av.Set_Name
- join rqs in _context.REQUIREMENT_QUESTIONS_SETS on new { r.Requirement_Id, s.Set_Name } equals new { rqs.Requirement_Id, rqs.Set_Name }
- join qu in _context.NEW_QUESTION on rqs.Question_Id equals qu.Question_Id
- join a in _context.Answer_Requirements on r.Requirement_Id equals a.Question_Or_Requirement_Id
- where rl.Standard_Level == level && av.Selected == true && rl.Level_Type == "NST"
- && av.Assessment_Id == _assessmentId && a.Assessment_Id == _assessmentId
- orderby r.Standard_Category, r.Standard_Sub_Category, rs.Requirement_Sequence
- select new { r, rl, s, qu, a }).ToList();
-
- foreach (var q in qR)
- {
- controlRows.Add(new ControlRow()
- {
- Requirement_Id = q.a.Question_Or_Requirement_Id,
- Requirement_Text = q.r.Requirement_Text,
- Answer_Text = q.a.Answer_Text,
- Comment = q.a.Comment,
- Question_Id = q.qu.Question_Id,
- Requirement_Title = q.r.Requirement_Title,
- Short_Name = q.s.Short_Name,
- Simple_Question = q.qu.Simple_Question,
- Standard_Category = q.r.Standard_Category,
- Standard_Sub_Category = q.r.Standard_Sub_Category,
- Standard_Level = q.rl.Standard_Level,
- Answer_Id = q.a.Answer_Id
- });
- }
- }
-
-
-
- //get all the questions for this control
- //determine the percent implemented.
- int prev_requirement_id = 0;
- int questionCount = 0;
- int questionsAnswered = 0;
- BasicReportData.RequirementControl control = null;
- List questions = null;
-
- // The response
- List controls = [];
-
- foreach (var a in controlRows)
- {
- if (prev_requirement_id != a.Requirement_Id)
- {
- questionCount = 0;
- questionsAnswered = 0;
- questions = new List();
-
-
- // look for translations
- var r = _overlay.GetRequirement(a.Requirement_Id, lang);
- var c = _overlay.GetPropertyValue("STANDARD_CATEGORY", a.Standard_Category.ToLower(), lang);
- var s = _overlay.GetPropertyValue("STANDARD_CATEGORY", a.Standard_Sub_Category.ToLower(), lang);
-
-
- // Replace parameter in requirement text if custom parameter is found
- a.Requirement_Text = rm.ResolveParameters(a.Requirement_Id, a.Answer_Id, a.Requirement_Text);
-
- control = new BasicReportData.RequirementControl()
- {
- ControlDescription = r?.RequirementText ?? a.Requirement_Text,
- RequirementTitle = a.Requirement_Title,
- Level = a.Standard_Level,
- StandardShortName = a.Short_Name,
- Standard_Category = c ?? a.Standard_Category,
- SubCategory = s ?? a.Standard_Sub_Category,
- Control_Questions = questions
- };
-
-
-
- controls.Add(control);
- }
-
- questionCount++;
-
- switch (a.Answer_Text)
- {
- case Constants.Constants.ALTERNATE:
- case Constants.Constants.YES:
- questionsAnswered++;
- break;
- }
-
- questions.Add(new BasicReportData.Control_Questions()
- {
- Answer = a.Answer_Text,
- Comment = a.Comment,
- Simple_Question = a.Simple_Question
- });
-
- control.ImplementationStatus = StatUtils.Percentagize(questionsAnswered, questionCount, 2).ToString("##.##");
- prev_requirement_id = a.Requirement_Id;
- }
-
- return controls;
- }
-
-
- ///
- ///
- ///
- ///
- public List GetControlsDiagram(string applicationMode)
-
- {
-
- List controls = new List();
- _questionRequirement.InitializeManager(_assessmentId);
-
- _context.FillEmptyQuestionsForAnalysis(_assessmentId);
-
- string level = _questionRequirement.StandardLevel == null ? "L" : _questionRequirement.StandardLevel;
-
- List controlRows = new List();
-
- var qQ = (from rs in _context.Answer_Components_Default
- orderby rs.Question_Group_Heading
- where rs.Assessment_Id == _assessmentId
- select new { rs }).ToList();
-
- foreach (var q in qQ)
- {
- controlRows.Add(new ControlRow()
- {
- Requirement_Id = q.rs.heading_pair_id,
- Requirement_Text = q.rs.Sub_Heading_Question_Description,
- Answer_Text = q.rs.Answer_Text,
- Comment = q.rs.Comment,
- Question_Id = q.rs.Question_Id,
- Requirement_Title = q.rs.Question_Group_Heading,
- Short_Name = q.rs.ComponentName,
- Simple_Question = q.rs.QuestionText,
- Standard_Category = q.rs.Question_Group_Heading,
- Standard_Sub_Category = q.rs.Universal_Sub_Category,
- Standard_Level = q.rs.SAL
- });
- }
-
- //get all the questions for this control
- //determine the percent implemented.
- int prev_requirement_id = 0;
- int questionCount = 0;
- int questionsAnswered = 0;
- BasicReportData.RequirementControl control = null;
- List questions = null;
-
- foreach (var a in controlRows)
- {
- if (prev_requirement_id != a.Requirement_Id)
- {
- questionCount = 0;
- questionsAnswered = 0;
- questions = new List();
- control = new BasicReportData.RequirementControl()
- {
- ControlDescription = a.Requirement_Text,
- RequirementTitle = a.Requirement_Title,
- Level = a.Standard_Level,
- StandardShortName = a.Short_Name,
- Standard_Category = a.Standard_Category,
- SubCategory = a.Standard_Sub_Category,
- Control_Questions = questions
- };
- controls.Add(control);
- }
- questionCount++;
-
- switch (a.Answer_Text)
- {
- case Constants.Constants.ALTERNATE:
- case Constants.Constants.YES:
- questionsAnswered++;
- break;
- }
-
- questions.Add(new BasicReportData.Control_Questions()
- {
- Answer = a.Answer_Text,
- Comment = a.Comment,
- Simple_Question = a.Simple_Question
- });
-
- control.ImplementationStatus = StatUtils.Percentagize(questionsAnswered, questionCount, 2).ToString("##.##");
- prev_requirement_id = a.Requirement_Id;
- }
-
- return controls;
- }
-
- public List> GetDiagramZones()
- {
- var level = _context.STANDARD_SELECTION.Where(x => x.Assessment_Id == _assessmentId).FirstOrDefault();
-
-
- var rval1 = (from c in _context.ASSESSMENT_DIAGRAM_COMPONENTS
- join s in _context.COMPONENT_SYMBOLS on c.Component_Symbol_Id equals s.Component_Symbol_Id
- where c.Assessment_Id == _assessmentId && c.Zone_Id == null
- orderby s.Symbol_Name, c.label
- select new DiagramZones
- {
- Diagram_Component_Type = s.Symbol_Name,
- label = c.label,
- Zone_Name = "No Assigned Zone",
- Universal_Sal_Level = level == null ? "Low" : level.Selected_Sal_Level
- }).ToList();
-
- var rval = (from c in _context.ASSESSMENT_DIAGRAM_COMPONENTS
- join z in _context.DIAGRAM_CONTAINER on c.Zone_Id equals z.Container_Id
- join s in _context.COMPONENT_SYMBOLS on c.Component_Symbol_Id equals s.Component_Symbol_Id
- where c.Assessment_Id == _assessmentId
- orderby s.Symbol_Name, c.label
- select new DiagramZones
- {
- Diagram_Component_Type = s.Symbol_Name,
- label = c.label,
- Zone_Name = z.Name,
- Universal_Sal_Level = z.Universal_Sal_Level
- }).ToList();
-
- return rval.Union(rval1).GroupBy(u => u.Zone_Name).Select(grp => grp.ToList()).ToList();
- }
-
-
- public List GetFinancialQuestions()
- {
- return _context.usp_getFinancialQuestions(_assessmentId).ToList();
- }
-
-
- public List GetQuestionsForEachStandard()
- {
- var dblist = from a in _context.AVAILABLE_STANDARDS
- join b in _context.NEW_QUESTION_SETS on a.Set_Name equals b.Set_Name
- join c in _context.Answer_Questions on b.Question_Id equals c.Question_Or_Requirement_Id
- join q in _context.NEW_QUESTION on c.Question_Or_Requirement_Id equals q.Question_Id
- join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
- join s in _context.SETS on b.Set_Name equals s.Set_Name
- where a.Selected == true && a.Assessment_Id == _assessmentId
- && c.Assessment_Id == _assessmentId
- orderby s.Short_Name, h.Question_Group_Heading, c.Question_Number
- select new SimpleStandardQuestions()
- {
- ShortName = s.Short_Name,
- Answer = c.Answer_Text,
- CategoryAndNumber = h.Question_Group_Heading + " #" + c.Question_Number,
- Question = q.Simple_Question,
- QuestionId = q.Question_Id
- };
-
- List list = new List();
- string lastshortname = "";
- List qlist = new List();
- foreach (var a in dblist.ToList())
- {
- if (a.ShortName != lastshortname)
- {
- qlist = new List();
- list.Add(new StandardQuestions()
- {
- Questions = qlist,
- StandardShortName = a.ShortName
- });
- }
- lastshortname = a.ShortName;
- qlist.Add(a);
- }
-
- return list;
- }
-
-
- public async Task> GetStandardQuestionAnswers(int assessId)
- {
- CsetwebContextProcedures context = new CsetwebContextProcedures(_context);
- var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
- var dblist = await context.usp_GetQuestionsAsync(assessId);
-
- List list = new List();
- string lastshortname = "";
- List qlist = new List();
- foreach (var a in dblist.ToList())
- {
- if (a.ShortName != lastshortname)
- {
- qlist = new List();
- list.Add(new StandardQuestions()
- {
- Questions = qlist,
- StandardShortName = a.ShortName
- });
- }
- lastshortname = a.ShortName;
- qlist.Add(new SimpleStandardQuestions()
- {
- ShortName = a.ShortName,
-
- Question = rm.ResolveParameters(a.QuestionOrRequirementID, a.AnswerID, a.QuestionText),
- QuestionId = a.QuestionOrRequirementID,
- Answer = a.AnswerText,
- CategoryAndNumber = a.CategoryAndNumber
- });
- }
-
- return list;
- }
-
-
- ///
- /// Returns a list of questions generated by components in the network.
- /// The questions correspond to the SAL level of each component's Zone level.
- /// Questions for components in hidden layers are not included.
- ///
- ///
- public List GetComponentQuestions()
- {
- var l = new List();
-
- List results = null;
-
- _context.LoadStoredProc("[usp_getExplodedComponent]")
- .WithSqlParam("assessment_id", _assessmentId)
- .ExecuteStoredProc((handler) =>
- {
- results = handler.ReadToList().OrderBy(c => c.ComponentName).ThenBy(c => c.QuestionText).ToList();
- });
-
- foreach (usp_getExplodedComponent q in results)
- {
- l.Add(new ComponentQuestion
- {
- Answer = q.Answer_Text,
- ComponentName = q.ComponentName,
- Component_Symbol_Id = q.Component_Symbol_Id,
- Question = q.QuestionText,
- QuestionId = q.Question_Id,
- LayerName = q.LayerName,
- SAL = q.SAL,
- Zone = q.ZoneName,
- IsOverride = (q.Answer_Id != null)
- });
- }
-
- return l;
- }
-
-
- public List GetTop5Categories()
- {
- var lang = _tokenManager.GetCurrentLanguage();
-
- var categories = _context.usp_GetOverallRankedCategoriesPage(_assessmentId).Take(5).ToList();
-
- for (var i = 0; i < categories.Count; i++)
- {
- var cat = categories[i];
- cat.Question_Group_Heading = _overlay.GetValue("QUESTION_GROUP_HEADING", cat.QGH_Id.ToString(), lang)?.Value ?? cat.Question_Group_Heading;
- }
-
- return categories;
- }
-
-
- public List GetTop5Questions()
- {
- return GetRankedQuestions().Take(5).ToList();
- }
-
-
- ///
- /// Returns a list of questions that have been answered "Alt"
- ///
- ///
- public List GetQuestionsWithAlternateJustification()
- {
-
- var results = new List();
-
- // get any "A" answers that currently apply
-
- var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
- .Where(ans => ans.Answer_Text == "A").ToList();
-
- if (relevantAnswers.Count == 0)
- {
- return results;
- }
-
- bool requirementMode = relevantAnswers[0].Is_Requirement;
-
- // include Question or Requirement contextual information
- if (requirementMode)
- {
- var query = from ans in relevantAnswers
- join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
- select new QuestionsWithAltJust()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
- AlternateJustification = ans.Alternate_Justification,
- Question = req.Requirement_Text
- };
-
- return query.ToList();
- }
- else
- {
- var query = from ans in relevantAnswers
- join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
- join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
- orderby h.Question_Group_Heading
- select new QuestionsWithAltJust()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
- AlternateJustification = ans.Alternate_Justification,
- Question = q.Simple_Question
- };
-
- return query.ToList();
- }
-
- }
-
-
- ///
- /// Returns a list of questions that have comments.
- ///
- ///
- public List GetQuestionsWithComments()
- {
-
- var results = new List();
-
- var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
- // get any "marked for review" or commented answers that currently apply
- var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
- .Where(ans => !string.IsNullOrEmpty(ans.Comment))
- .ToList();
-
- if (relevantAnswers.Count == 0)
- {
- return results;
- }
-
- bool requirementMode = relevantAnswers[0].Is_Requirement;
-
- // include Question or Requirement contextual information
- if (requirementMode)
- {
- var query = from ans in relevantAnswers
- join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
- select new QuestionsWithComments()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
- Question = rm.ResolveParameters(ans.Question_Or_Requirement_ID, ans.Answer_ID, req.Requirement_Text),
- Comment = ans.Comment
- };
-
- return query.ToList();
- }
- else
- {
- var query = from ans in relevantAnswers
- join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
- join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
- orderby h.Question_Group_Heading
- select new QuestionsWithComments()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
- Question = q.Simple_Question,
- Comment = ans.Comment
- };
-
- return query.ToList();
- }
- }
-
-
- ///
- /// Returns a list of questions that have been marked for review.
- ///
- ///
- public List GetQuestionsMarkedForReview()
- {
-
- var results = new List();
-
- // get any "marked for review" or commented answers that currently apply
- var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
- .Where(ans => ans.Mark_For_Review)
- .ToList();
-
- if (relevantAnswers.Count == 0)
- {
- return results;
- }
-
- bool requirementMode = relevantAnswers[0].Is_Requirement;
-
- // include Question or Requirement contextual information
- if (requirementMode)
- {
- var query = from ans in relevantAnswers
- join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
- select new QuestionsMarkedForReview()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
- Question = req.Requirement_Text
- };
-
- return query.ToList();
- }
- else
- {
- var query = from ans in relevantAnswers
- join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
- join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
- orderby h.Question_Group_Heading
- select new QuestionsMarkedForReview()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
- Question = q.Simple_Question
- };
-
- return query.ToList();
- }
-
- }
-
-
- ///
- /// Returns a list of questions that have been reviewed.
- ///
- ///
- public List GetQuestionsReviewed()
- {
-
- var results = new List();
- var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
-
- // get any "marked for review" or commented answers that currently apply
- var relevantAnswers = new RelevantAnswers().GetAnswersForAssessment(_assessmentId, _context)
- .Where(ans => ans.Reviewed)
- .ToList();
-
- if (relevantAnswers.Count == 0)
- {
- return results;
- }
-
- bool requirementMode = relevantAnswers[0].Is_Requirement;
-
- // include Question or Requirement contextual information
- if (requirementMode)
- {
- var query = from ans in relevantAnswers
- join req in _context.NEW_REQUIREMENT on ans.Question_Or_Requirement_ID equals req.Requirement_Id
- select new QuestionsMarkedForReview()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = req.Standard_Category + " - " + req.Requirement_Title,
- Question = rm.ResolveParameters(ans.Question_Or_Requirement_ID, ans.Answer_ID, req.Requirement_Text)
- };
-
- return query.ToList();
- }
- else
- {
- var query = from ans in relevantAnswers
- join q in _context.NEW_QUESTION on ans.Question_Or_Requirement_ID equals q.Question_Id
- join h in _context.vQUESTION_HEADINGS on q.Heading_Pair_Id equals h.Heading_Pair_Id
- orderby h.Question_Group_Heading
- select new QuestionsMarkedForReview()
- {
- Answer = ans.Answer_Text,
- CategoryAndNumber = h.Question_Group_Heading + " #" + ans.Question_Number,
- Question = q.Simple_Question
- };
-
- return query.ToList();
- }
- }
-
-
- public List GetRankedQuestions()
- {
- var lang = _tokenManager.GetCurrentLanguage();
-
- var rm = new Question.RequirementBusiness(_assessmentUtil, _questionRequirement, _context, _tokenManager);
-
- List list = new List();
- List rankedQuestionList = _context.usp_GetRankedQuestions(_assessmentId).ToList();
- foreach (usp_GetRankedQuestions_Result q in rankedQuestionList)
- {
- if (q.RequirementId != null)
- {
- var reqOverlay = _overlay.GetRequirement((int)q.RequirementId, lang);
- if (reqOverlay != null)
- {
- q.QuestionText = reqOverlay.RequirementText;
- }
- }
-
-
- q.QuestionText = rm.ResolveParameters(q.QuestionOrRequirementID, q.AnswerID, q.QuestionText);
-
- q.Category = _overlay.GetPropertyValue("STANDARD_CATEGORY", q.Category.ToLower(), lang) ?? q.Category;
-
- list.Add(new RankedQuestions()
- {
- Answer = q.AnswerText,
- CategoryAndNumber = q.Category + " #" + q.QuestionRef,
- Level = q.Level,
- Question = q.QuestionText,
- Rank = q.Rank ?? 0
- });
- }
-
- return list;
- }
-
- public List