public async Task GetSectionAndPage(Guid applicationId, Guid sectionId, string pageId) { Application = await _dataContext.Applications.SingleOrDefaultAsync(app => app.Id == applicationId); Section = await _dataContext.ApplicationSections.SingleOrDefaultAsync(sec => sec.Id == sectionId && sec.ApplicationId == applicationId); if (Section != null) { QnaData = new QnAData(Section.QnAData); Page = QnaData.Pages.SingleOrDefault(p => p.PageId == pageId); } }
private void OnQnABundlesTab() { GUILayout.Label(new GUIContent("Generate QnA Bundle")); category = (QuestionCategory)EditorGUILayout.EnumPopup(new GUIContent("Select Category"), category); questionsCount = EditorGUILayout.IntField(new GUIContent("Question Fields To Add"), questionsCount); if (GUILayout.Button(new GUIContent("Generate"))) { string dirPath = string.Concat(Paths.RESOURCES_PATH, "/", Paths.DEFAULT_QnABUNDLES_PATH); if (!Directory.Exists(string.Concat(Application.dataPath, "/", dirPath))) { Assets.CreateFolder(dirPath); } var filePath = string.Concat(Application.dataPath, "/", dirPath, "/", category.ToString(), "_Bundle.json"); if (File.Exists(filePath)) { Debug.Log("Bundle with this category already exists, please edit it directly to add more questions!"); return; } using (var sr = File.CreateText(filePath)) { if (jsonAdapter == null) { jsonAdapter = new UnityJsonAdapter(); } var bundle = new QnADataBundle() { category = category, QnADatas = new QnAData[questionsCount] }; for (int i = 0; i < questionsCount; i++) { bundle.QnADatas[i] = QnAData.GetEmpty(); } var json = jsonAdapter.Serialize(bundle); sr.Write(json); AssetDatabase.Refresh(); Debug.LogFormat("Bundle successfuly created at {0}", filePath); } } }
public static QnAData GetEmpty() { var data = new QnAData(); data.question = ""; data.rightAnswer = ""; data.wrongAnswer = new string[Settings.ANSWERS_COUNT - 1]; for (int i = 0; i < data.wrongAnswer.Length; i++) { data.wrongAnswer[i] = ""; } return(data); }
public async Task <HandlerResponse <Page> > Handle(UpsertFeedbackRequest request, CancellationToken cancellationToken) { var section = await _dataContext.ApplicationSections.SingleOrDefaultAsync(sec => sec.ApplicationId == request.ApplicationId && sec.Id == request.SectionId, cancellationToken); if (section is null) { return(new HandlerResponse <Page>(success: false, message: $"SectionId {request.SectionId} does not exist in ApplicationId {request.ApplicationId}")); } var qnaData = new QnAData(section.QnAData); var page = qnaData.Pages.SingleOrDefault(p => p.PageId == request.PageId); if (page is null) { return(new HandlerResponse <Page>(success: false, message: $"PageId {request.PageId} does not exist")); } if (page.Feedback is null) { page.Feedback = new List <Feedback>(); } if (page.Feedback.All(f => f.Id != request.Feedback.Id)) { request.Feedback.Date = SystemTime.UtcNow(); request.Feedback.IsNew = true; page.Feedback.Add(request.Feedback); } else { var existingFeedback = page.Feedback.Single(f => f.Id == request.Feedback.Id); existingFeedback.Date = request.Feedback.Date; existingFeedback.From = request.Feedback.From; existingFeedback.Message = request.Feedback.Message; existingFeedback.IsCompleted = request.Feedback.IsCompleted; existingFeedback.IsNew = request.Feedback.IsNew; } section.QnAData = qnaData; await _dataContext.SaveChangesAsync(cancellationToken); return(new HandlerResponse <Page>(page)); }
public void ClearDeactivatedTags(Guid applicationId, Guid sectionId) { var section = _dataContext.ApplicationSections.AsNoTracking().SingleOrDefault(sec => sec.Id == sectionId && sec.ApplicationId == applicationId); if (section == null) { return; } var pages = new QnAData(section.QnAData).Pages; var pagesActive = pages.Where(p => p.Active); var pagesInactive = pages.Where(p => !p.Active); var deactivatedTags = (from page in pagesInactive from question in page.Questions.Where(p => !string.IsNullOrEmpty(p.QuestionTag)) select question.QuestionTag).Distinct().ToList(); var activeTags = (from page in pagesActive from question in page.Questions.Where(p => !string.IsNullOrEmpty(p.QuestionTag)) select question.QuestionTag).Distinct().ToList(); // remove any activetags within deactivatedTags as some branches use tagnames twice for distinct branches foreach (var tag in activeTags.Where(tag => deactivatedTags.Contains(tag))) { deactivatedTags.Remove(tag); } if (deactivatedTags.Count < 1) { return; } var application = _dataContext.Applications.SingleOrDefault(app => app.Id == applicationId); if (application == null) { return; } var applicationData = JObject.Parse(application.ApplicationData ?? "{}"); foreach (var tag in deactivatedTags) { applicationData.Remove(tag); } application.ApplicationData = applicationData.ToString(Formatting.None); _dataContext.SaveChanges(); }
public async Task <HandlerResponse <SkipPageResponse> > Handle(SkipPageRequest request, CancellationToken cancellationToken) { var application = await _dataContext.Applications.SingleOrDefaultAsync(app => app.Id == request.ApplicationId, cancellationToken : cancellationToken); if (application is null) { return(new HandlerResponse <SkipPageResponse>(false, "Application does not exist")); } var section = await _dataContext.ApplicationSections.SingleOrDefaultAsync(sec => sec.Id == request.SectionId && sec.ApplicationId == request.ApplicationId, cancellationToken); if (section is null) { return(new HandlerResponse <SkipPageResponse>(false, "Section does not exist")); } var qnaData = new QnAData(section.QnAData); var page = qnaData.Pages.SingleOrDefault(p => p.PageId == request.PageId); if (page is null) { return(new HandlerResponse <SkipPageResponse>(false, "Page does not exist")); } try { var nextAction = GetNextActionForPage(section, application, page.PageId); var checkboxListAllNexts = GetCheckboxListMatchingNextActionsForPage(section, application, page.PageId); SetStatusOfNextPagesBasedOnDeemedNextActions(section, page.PageId, nextAction, checkboxListAllNexts); await _dataContext.SaveChangesAsync(cancellationToken); return(new HandlerResponse <SkipPageResponse>(new SkipPageResponse(nextAction.Action, nextAction.ReturnId))); } catch (ApplicationException) { if (page.Next is null || !page.Next.Any()) { return(new HandlerResponse <SkipPageResponse>(new SkipPageResponse())); }
public async Task <HandlerResponse <bool> > Handle(CompleteFeedbackWithinSequenceRequest request, CancellationToken cancellationToken) { var application = await _dataContext.Applications.FirstOrDefaultAsync(app => app.Id == request.ApplicationId, cancellationToken : cancellationToken); if (application is null) { return(new HandlerResponse <bool>(false, "Application does not exist")); } var sequence = await _dataContext.ApplicationSequences.FirstOrDefaultAsync(seq => seq.Id == request.SequenceId, cancellationToken : cancellationToken); if (sequence is null) { return(new HandlerResponse <bool>(false, "Sequence does not exist")); } var sections = await _dataContext.ApplicationSections.Where(section => section.SequenceId == request.SequenceId).ToListAsync(cancellationToken); foreach (var section in sections) { var qnaData = new QnAData(section.QnAData); foreach (var page in qnaData.Pages) { if (page.HasNewFeedback) { page.Feedback.ForEach(f => f.IsNew = false); page.Feedback.ForEach(f => f.IsCompleted = true); } } section.QnAData = qnaData; } await _dataContext.SaveChangesAsync(cancellationToken); return(new HandlerResponse <bool>(true)); }
private static void GatherListOfPages(Page page, QnAData selectedSectionQnAData, ICollection <Page> pages) { pages.Add(page); if (page.Next.All(x => x.Action != NextAction.NextPage)) { return; } foreach (var nxt in page.Next.Where(x => x.Action == NextAction.NextPage)) { var pageId = nxt.ReturnId; var pageNext = selectedSectionQnAData.Pages.FirstOrDefault(x => x.PageId == pageId && x.Active); if (pageNext == null) { return; } GatherListOfPages(pageNext, selectedSectionQnAData, pages); } }
public async Task <HandlerResponse <Page> > Handle(DeleteFeedbackRequest request, CancellationToken cancellationToken) { var section = await _dataContext.ApplicationSections.SingleOrDefaultAsync(sec => sec.ApplicationId == request.ApplicationId && sec.Id == request.SectionId, cancellationToken); if (section is null) { return(new HandlerResponse <Page>(success: false, message: $"SectionId {request.SectionId} does not exist in ApplicationId {request.ApplicationId}")); } var qnaData = new QnAData(section.QnAData); var page = qnaData.Pages.SingleOrDefault(p => p.PageId == request.PageId); if (page is null) { return(new HandlerResponse <Page>(success: false, message: $"PageId {request.PageId} does not exist")); } if (page.Feedback is null) { return(new HandlerResponse <Page>(success: false, message: $"Feedback {request.FeedbackId} does not exist")); } var existingFeedback = page.Feedback.SingleOrDefault(f => f.Id == request.FeedbackId); if (existingFeedback is null) { return(new HandlerResponse <Page>(success: false, message: $"Feedback {request.FeedbackId} does not exist")); } page.Feedback.Remove(existingFeedback); section.QnAData = qnaData; await _dataContext.SaveChangesAsync(cancellationToken); return(new HandlerResponse <Page>(page)); }
protected void SaveAnswersIntoPage(ApplicationSection section, string pageId, List <Answer> submittedAnswers) { if (section != null) { // Have to force QnAData a new object and reassign for Entity Framework to pick up changes var qnaData = new QnAData(section.QnAData); var page = qnaData?.Pages.SingleOrDefault(p => p.PageId == pageId); if (page != null) { var answers = GetAnswersFromRequest(submittedAnswers); page.PageOfAnswers = new List <PageOfAnswers>(new[] { new PageOfAnswers() { Answers = answers } }); MarkPageAsComplete(page); MarkPageFeedbackAsComplete(page); // Assign QnAData back so Entity Framework will pick up changes section.QnAData = qnaData; } } }
private string AssociatedPagesWithSectionStatus(Page page, QnAData selectedSectionQnAData, bool isFirstPage) { if (isFirstPage && !page.Complete) { return(""); } if (page.Next.All(x => x.Action != NextAction.NextPage)) { return(TaskListSectionStatus.Completed); } foreach (var nxt in page.Next.Where(x => x.Action == NextAction.NextPage)) { var pageId = nxt.ReturnId; var pageNext = selectedSectionQnAData.Pages.FirstOrDefault(x => x.PageId == pageId && x.Active); if (pageNext != null) { return(!pageNext.Complete ? TaskListSectionStatus.InProgress : AssociatedPagesWithSectionStatus(pageNext, selectedSectionQnAData, false)); } } return(TaskListSectionStatus.Completed); }
public virtual void Arrange() { ApplicationId = Guid.NewGuid(); UserId = new Guid(); QnAData = new QnAData() { Pages = new List <Page> { new Page { PageId = "1", Questions = new List <Question> { new Question() { QuestionId = "Q1", Input = new Input { Type = "ComplexRadio", Options = new List <Option> { new Option { Label = "Yes", Value = "Yes", FurtherQuestions = new List <Question> { new Question { QuestionId = "Q1.1", Input = new Input { Type = "Text", Validations = new List <ValidationDefinition> { new ValidationDefinition { Name = "Required", ErrorMessage = "Enter Q1.1" } } } } } }, new Option { Label = "No", Value = "No" } } } }, }, PageOfAnswers = new List <PageOfAnswers> { new PageOfAnswers { Answers = new List <Answer> { new Answer { QuestionId = "Q1", Value = "Yes" }, new Answer { QuestionId = "Q1.1", Value = "SomeAnswer" } } } }, Next = new List <Next>() { new Next { Action = "NextPage", ReturnId = "2", Condition = new Condition() { QuestionId = "Q1", MustEqual = "Yes" }, ConditionMet = false }, new Next { Action = "NextPage", ReturnId = "3", Condition = new Condition() { QuestionId = "Q1", MustEqual = "No" }, ConditionMet = false } } }, new Page { PageId = "2", Questions = new List <Question> { new Question { QuestionId = "Q2", Input = new Input { Type = "Text" } }, new Question { QuestionId = "Q3", Input = new Input { Type = "Text" } } }, PageOfAnswers = new List <PageOfAnswers>(), Next = new List <Next> { new Next { Action = "NextPage", ReturnId = "3" } } }, new Page { PageId = "3", AllowMultipleAnswers = true, Questions = new List <Question> { new Question { QuestionId = "Q4", Input = new Input { Type = "Text" } }, new Question { QuestionId = "Q5", Input = new Input { Type = "Text" } } }, PageOfAnswers = new List <PageOfAnswers>(), Next = new List <Next> { new Next { Action = "NextPage", ReturnId = "4" } } }, new Page { PageId = "4", Questions = new List <Question> { new Question { QuestionId = "Q6", Input = new Input { Type = "Text" } } }, PageOfAnswers = new List <PageOfAnswers>(), Next = new List <Next> { new Next { Action = "NextPage", ReturnId = "5" } } }, new Page { PageId = "5", Questions = new List <Question> { new Question() { QuestionId = "Q7", Input = new Input { Type = "ComplexRadio", Options = new List <Option> { new Option { Label = "Yes", Value = "Yes", }, new Option { Label = "No", Value = "No" } } } }, }, PageOfAnswers = new List <PageOfAnswers>(), Next = new List <Next> { new Next { Action = "ReturnToSection", ReturnId = "1" } } }, }, FinancialApplicationGrade = null }; ApplyRepository = new Mock <IApplyRepository>(); ApplyRepository.Setup(r => r.GetSection(ApplicationId, 1, 1, UserId)).ReturnsAsync(new ApplicationSection() { Status = ApplicationSectionStatus.Draft, QnAData = QnAData }); ValidatorFactory = new Mock <IValidatorFactory>(); ValidatorFactory.Setup(vf => vf.Build(It.IsAny <Question>())).Returns(new List <IValidator>()); Validator = new Mock <IValidator>(); ValidatorFactory.Setup(vf => vf.Build(It.IsAny <Question>())) .Returns(new List <IValidator> { Validator.Object }); Handler = new UpdatePageAnswersHandler(ApplyRepository.Object, ValidatorFactory.Object); }
public async Task <HandlerResponse <bool> > Handle(DeleteFileRequest request, CancellationToken cancellationToken) { var section = await _dataContext.ApplicationSections.FirstOrDefaultAsync(sec => sec.Id == request.SectionId && sec.ApplicationId == request.ApplicationId, cancellationToken); if (section == null) { return(new HandlerResponse <bool>(success: false, message: $"Section {request.SectionId} in Application {request.ApplicationId} does not exist.")); } var qnaData = new QnAData(section.QnAData); var page = qnaData.Pages.FirstOrDefault(p => p.PageId == request.PageId); if (page == null) { return(new HandlerResponse <bool>(success: false, message: $"Page {request.PageId} in Application {request.ApplicationId} does not exist.")); } if (page.Questions.All(q => q.Input.Type != "FileUpload")) { return(new HandlerResponse <bool>(success: false, message: $"Page {request.PageId} in Application {request.ApplicationId} does not contain any File Upload questions.")); } if (page.PageOfAnswers == null || !page.PageOfAnswers.Any()) { return(new HandlerResponse <bool>(success: false, message: $"Page {request.PageId} in Application {request.ApplicationId} does not contain any uploads.")); } var container = await ContainerHelpers.GetContainer(_fileStorageConfig.Value.StorageConnectionString, _fileStorageConfig.Value.ContainerName); var directory = ContainerHelpers.GetDirectory(request.ApplicationId, section.SequenceId, request.SectionId, request.PageId, request.QuestionId, container); var answer = page.PageOfAnswers.SingleOrDefault(poa => poa.Answers.Any(a => a.QuestionId == request.QuestionId && a.Value == request.FileName)); if (answer is null) { return(new HandlerResponse <bool>(success: false, message: $"Question {request.QuestionId} on Page {request.PageId} in Application {request.ApplicationId} does not contain an upload named {request.FileName}.")); } page.PageOfAnswers.Remove(answer); if (page.PageOfAnswers.Count == 0) { page.Complete = false; if (page.HasFeedback) { foreach (var feedback in page.Feedback.Where(feedback => feedback.IsNew).Select(feedback => feedback)) { feedback.IsCompleted = false; } } } else { var answers = page.PageOfAnswers?.SelectMany(p => p.Answers); if (answers != null) { var validationErrors = _answerValidator.Validate(answers.ToList(), page); if (validationErrors != null && validationErrors.Any()) { page.Complete = false; } } } section.QnAData = qnaData; await _dataContext.SaveChangesAsync(cancellationToken); var blobRef = directory.GetBlobReference(request.FileName); await blobRef.DeleteAsync(cancellationToken); await RemoveApplicationDataForThisQuestion(request.ApplicationId, request.QuestionId, page); return(new HandlerResponse <bool>(true)); }