public async Task When_PostingWithdrawalDateCheckSaveForOrganisationWithdrawal_Then_RedirectToConfirmation()
        {
            // Arrange
            ArrangeMocksWithIrrelevantData();
            var withdrawalDate      = new DateTime(2021, 10, 1);
            var applicationId       = Guid.NewGuid();
            var sequenceNumber      = 0;
            var backModel           = new BackViewModel();
            var dateApproved        = "YES";
            var currentVersionIndex = 0;

            _qnaApiClient.Setup(x => x.GetSequence(It.IsAny <Guid>(), It.IsAny <Guid>()))
            .ReturnsAsync(new QnA.Api.Types.Sequence()
            {
                SequenceNo = ApplyConst.ORGANISATION_WITHDRAWAL_SEQUENCE_NO,
            });

            _qnaApiClient.Setup(x => x.GetSections(It.IsAny <Guid>(), It.IsAny <Guid>()))
            .ReturnsAsync(new List <QnA.Api.Types.Section>()
            {
                new QnA.Api.Types.Section()
                {
                    SequenceNo = ApplyConst.ORGANISATION_WITHDRAWAL_SEQUENCE_NO,
                    QnAData    = new QnA.Api.Types.Page.QnAData()
                    {
                        Pages = new List <QnA.Api.Types.Page.Page>()
                        {
                            new QnA.Api.Types.Page.Page()
                            {
                                LinkTitle     = "WITHDRAWAL DATE",
                                PageOfAnswers = new List <QnA.Api.Types.Page.PageOfAnswers>()
                                {
                                    new QnA.Api.Types.Page.PageOfAnswers()
                                    {
                                        Answers = new List <QnA.Api.Types.Page.Answer>()
                                        {
                                            new QnA.Api.Types.Page.Answer()
                                            {
                                                Value = withdrawalDate.ToString()
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            });

            // Act
            var viewResult = await _controller.WithdrawalDateCheckSave(applicationId, sequenceNumber, backModel, dateApproved, currentVersionIndex);

            // Assert
            _apiClient.Verify(m => m.WithdrawOrganisation(It.Is <WithdrawOrganisationRequest>(x => x.WithdrawalDate == withdrawalDate &&
                                                                                              x.UpdatedBy == "JOHN DUNHILL")));
        }
        public async Task When_RequestingWithdrawalDateCheckPage_Then_WithdrawalDateCheckViewIsReturned()
        {
            // Arrange

            ArrangeMocksWithIrrelevantData();
            var applicationId       = Guid.NewGuid();
            var sequenceNumber      = 0;
            var backModel           = new BackViewModel();
            var currentVersionIndex = 0;

            // Act

            ViewResult viewResult = await _controller.WithdrawalDateCheck(applicationId, sequenceNumber, backModel, currentVersionIndex) as ViewResult;

            // Assert

            viewResult.ViewName.Should().Be("WithdrawalDateCheck");
        }
        public async Task <IActionResult> ActiveSequence(Guid applicationId, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var organisation = await _apiClient.GetOrganisation(application.OrganisationId);

            var activeApplySequence = application.ApplyData.Sequences.Where(seq => seq.IsActive && !seq.NotRequired).OrderBy(seq => seq.SequenceNo).FirstOrDefault();

            var sequence = await _qnaApiClient.GetSequence(application.ApplicationId, activeApplySequence.SequenceId);

            var sections = await _qnaApiClient.GetSections(application.ApplicationId, sequence.Id);

            var sequenceVm = new SequenceViewModel(application, organisation, sequence, sections,
                                                   activeApplySequence.Sections,
                                                   backViewModel.BackAction,
                                                   backViewModel.BackController,
                                                   backViewModel.BackOrganisationId);

            return(View(nameof(Sequence), sequenceVm));
        }
        public async Task When_RequestingWithdrawalDateChangePageForStandardWithdrawal_Then_RedirectToConfirmation()
        {
            // Arrange

            ArrangeMocksWithIrrelevantData();
            var applicationId       = Guid.NewGuid();
            var sequenceNumber      = 0;
            var backModel           = new BackViewModel();
            var effectiveToDay      = "01";
            var effectiveToMonth    = "01";
            var effectiveToYear     = "2021";
            var currentVersionIndex = 0;

            // Act

            var viewResult = await _controller.WithdrawalDateChange(applicationId, sequenceNumber, backModel, effectiveToDay, effectiveToMonth, effectiveToYear, currentVersionIndex);

            // Assert

            viewResult.Should().NotBeNull();
            viewResult.Should().BeOfType <RedirectToActionResult>();
            ((RedirectToActionResult)viewResult).ActionName.Should().Be("Assessment");  // Confirmation page is generated by the Assessment action
        }
        public async Task <IActionResult> Sequence(Guid applicationId, int sequenceNo, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var organisation = await _apiClient.GetOrganisation(application.OrganisationId);

            var applySequence = application.ApplyData.Sequences.Single(x => x.SequenceNo == sequenceNo);

            var sequence = await _qnaApiClient.GetSequence(application.ApplicationId, applySequence.SequenceId);

            var sections = await _qnaApiClient.GetSections(application.ApplicationId, sequence.Id);

            var sequenceVm = new SequenceViewModel(application, organisation, sequence, sections,
                                                   applySequence.Sections, backViewModel.BackAction, backViewModel.BackController,
                                                   backViewModel.BackOrganisationId);

            var activeApplicationStatuses = new List <string> {
                ApplicationStatus.Submitted, ApplicationStatus.Resubmitted
            };
            var activeSequenceStatuses = new List <string> {
                ApplicationSequenceStatus.Submitted, ApplicationSequenceStatus.Resubmitted
            };

            if (activeApplicationStatuses.Contains(application.ApplicationStatus) && activeSequenceStatuses.Contains(applySequence?.Status))
            {
                return(View(nameof(Sequence), sequenceVm));
            }
            else
            {
                return(View($"{nameof(Sequence)}_ReadOnly", sequenceVm));
            }
        }
        public async Task <IActionResult> Return(Guid applicationId, int sequenceNo, string returnType, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var activeApplicationSequence = application.ApplyData.Sequences.Where(seq => seq.IsActive && !seq.NotRequired).OrderBy(seq => seq.SequenceNo).FirstOrDefault();

            var organisation = await _apiClient.GetOrganisation(application.OrganisationId);

            _logger.LogInformation($"APPROVING_STANDARD - ApplicationId: {application.Id} - Got Organisation {organisation.EndPointAssessorName} RoEPAOApproved: {organisation.OrganisationData.RoEPAOApproved}");


            if (activeApplicationSequence is null || activeApplicationSequence.SequenceNo != sequenceNo || activeApplicationSequence.Sections.Any(s => s.Status != ApplicationSectionStatus.Evaluated && !s.NotRequired))
            {
                // This is to stop the wrong sequence being returned, or if not all sections are Evaluated
                return(RedirectToApplicationsFromSequence(sequenceNo));
            }
        public async Task <IActionResult> WithdrawalDateCheckSave(Guid applicationId, int sequenceNo, BackViewModel backViewModel, string dateApproved, int currentVersionIndex)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var organisation = await _apiClient.GetOrganisation(application.OrganisationId);

            var activeApplySequence = application.ApplyData.Sequences.Where(seq => seq.IsActive && !seq.NotRequired).OrderBy(seq => seq.SequenceNo).FirstOrDefault();

            var sequence = await _qnaApiClient.GetSequence(application.ApplicationId, activeApplySequence.SequenceId);

            var sections = await _qnaApiClient.GetSections(application.ApplicationId, sequence.Id);

            var sequenceVm = new WithdrawalDateCheckViewModel(application, organisation, sequence, sections,
                                                              activeApplySequence.Sections,
                                                              backViewModel.BackAction,
                                                              backViewModel.BackController,
                                                              backViewModel.BackOrganisationId,
                                                              currentVersionIndex);

            var errorMessages = new Dictionary <string, string>();

            if (string.IsNullOrWhiteSpace(dateApproved) || (dateApproved.Trim().ToUpper() != "NO" && dateApproved.Trim().ToUpper() != "YES"))
            {
                errorMessages["RequestedWithdrawalDate"] = "Select Yes or No";
            }

            if (errorMessages.Any())
            {
                foreach (var error in errorMessages)
                {
                    ModelState.AddModelError(error.Key, error.Value);
                }

                return(View(nameof(WithdrawalDateCheck), sequenceVm));
            }

            if (dateApproved?.Trim().ToUpper() == "NO")
            {
                return(View(nameof(WithdrawalDateChange), sequenceVm));
            }

            if (sequenceVm.RequestedWithdrawalDate.HasValue)
            {
                if (sequenceVm.SequenceNo == ApplyConst.ORGANISATION_WITHDRAWAL_SEQUENCE_NO)
                {
                    await WithdrawalOrganisation(application, organisation.EndPointAssessorOrganisationId, sequenceVm.RequestedWithdrawalDate.Value);
                }
                else if (null == sequenceVm.Versions || !sequenceVm.Versions.Any())
                {
                    // No versions supplied in the withdrawal application means they are withdrawing from the standard completely
                    await UpdateOrganisationStandardWithdrawalDate(organisation.EndPointAssessorOrganisationId, sequenceVm.StandardReference, null, sequenceVm.RequestedWithdrawalDate.Value);
                }
                else
                {
                    await UpdateOrganisationStandardWithdrawalDate(organisation.EndPointAssessorOrganisationId, sequenceVm.StandardReference, sequenceVm.Versions[sequenceVm.CurrentVersionIndex.Value], sequenceVm.RequestedWithdrawalDate.Value);
                }


                sequenceVm.IncrementCurrentVersionIndex();
                if (sequenceVm.CurrentVersionIndex.HasValue)
                {
                    return(RedirectToAction(nameof(WithdrawalDateCheck), new { currentVersionIndex = sequenceVm.CurrentVersionIndex.Value }));
                }
            }

            return(RedirectToAction(nameof(Assessment)));
        }
        public async Task <IActionResult> WithdrawalDateChange(Guid applicationId, int sequenceNo, BackViewModel backViewModel, string effectiveToDay, string effectiveToMonth, string effectiveToYear, int currentVersionIndex)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var organisation = await _apiClient.GetOrganisation(application.OrganisationId);

            var activeApplySequence = application.ApplyData.Sequences.Where(seq => seq.IsActive && !seq.NotRequired).OrderBy(seq => seq.SequenceNo).FirstOrDefault();

            var sequence = await _qnaApiClient.GetSequence(application.ApplicationId, activeApplySequence.SequenceId);

            var sections = await _qnaApiClient.GetSections(application.ApplicationId, sequence.Id);

            var sequenceVm = new WithdrawalDateCheckViewModel(application, organisation, sequence, sections,
                                                              activeApplySequence.Sections,
                                                              backViewModel.BackAction,
                                                              backViewModel.BackController,
                                                              backViewModel.BackOrganisationId,
                                                              currentVersionIndex);

            var errorMessages = new Dictionary <string, string>();

            string effectiveToDateText = $"{effectiveToDay}/{effectiveToMonth}/{effectiveToYear}";

            if (!DateTime.TryParse(effectiveToDateText, out DateTime effectiveToDate))
            {
                errorMessages["RequestedWithdrawalDate"] = "Enter a valid date";
            }
            if (string.IsNullOrWhiteSpace(effectiveToDay) && string.IsNullOrWhiteSpace(effectiveToMonth) && string.IsNullOrWhiteSpace(effectiveToYear))
            {
                errorMessages["RequestedWithdrawalDate"] = "Enter a date";
            }

            if (errorMessages.Any())
            {
                foreach (var error in errorMessages)
                {
                    ModelState.AddModelError(error.Key, error.Value);
                }

                return(View(nameof(WithdrawalDateChange), sequenceVm));
            }

            if (sequenceVm.SequenceNo == ApplyConst.ORGANISATION_WITHDRAWAL_SEQUENCE_NO)
            {
                await WithdrawalOrganisation(application, organisation.EndPointAssessorOrganisationId, effectiveToDate);
            }
            else if (null == sequenceVm.Versions || !sequenceVm.Versions.Any())
            {
                // No versions supplied in the withdrawal application means they are withdrawing from the standard completely
                await UpdateOrganisationStandardWithdrawalDate(organisation.EndPointAssessorOrganisationId, sequenceVm.StandardReference, null, effectiveToDate);
            }
            else
            {
                await UpdateOrganisationStandardWithdrawalDate(organisation.EndPointAssessorOrganisationId, sequenceVm.StandardReference, sequenceVm.Versions[sequenceVm.CurrentVersionIndex.Value], effectiveToDate);
            }

            sequenceVm.IncrementCurrentVersionIndex();
            if (sequenceVm.CurrentVersionIndex.HasValue)
            {
                return(RedirectToAction(nameof(WithdrawalDateCheck), new { currentVersionIndex = sequenceVm.CurrentVersionIndex.Value }));
            }

            return(RedirectToAction(nameof(Assessment)));
        }
        public async Task <IActionResult> DeleteFeedback(Guid applicationId, int sequenceNo, int sectionNo, string pageId, string feedbackId, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var section = await _qnaApiClient.GetSectionBySectionNo(application.ApplicationId, sequenceNo, sectionNo);

            if (!string.IsNullOrEmpty(feedbackId))
            {
                await _qnaApiClient.DeleteFeedback(application.ApplicationId, section.Id, pageId, Guid.Parse(feedbackId));
            }
            else
            {
                _logger.LogError($"Feedback Id is null or empty - {feedbackId}");
            }

            return(RedirectToAction(nameof(Page), new { applicationId, backViewModel.BackAction, backViewModel.BackController, sequenceNo, sectionNo, pageId, backViewModel.BackOrganisationId }));
        }
        public async Task <IActionResult> Assessment(Guid applicationId, int sequenceNo, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var activeApplicationSequence = application.ApplyData.Sequences.Where(seq => seq.IsActive && !seq.NotRequired).OrderBy(seq => seq.SequenceNo).FirstOrDefault();

            if (activeApplicationSequence is null || activeApplicationSequence.SequenceNo != sequenceNo ||
                activeApplicationSequence.Sections.Any(s => s.Status != ApplicationSectionStatus.Evaluated && !s.NotRequired))
            {
                // This is to stop the wrong sequence being assessed, or if not all sections are Evaluated
                return(RedirectToApplicationsFromSequence(sequenceNo));
            }

            var sequence = await _qnaApiClient.GetSequence(application.ApplicationId, activeApplicationSequence.SequenceId);

            var sections = await _qnaApiClient.GetSections(application.ApplicationId, activeApplicationSequence.SequenceId);

            var viewModel = new ApplicationSequenceAssessmentViewModel(application, sequence, sections, backViewModel.BackAction, backViewModel.BackController, backViewModel.BackOrganisationId);

            return(View(nameof(Assessment), viewModel));
        }
        public async Task <IActionResult> Feedback(Guid applicationId, int sequenceNo, int sectionNo, string pageId, string feedbackMessage, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var section = await _qnaApiClient.GetSectionBySectionNo(application.ApplicationId, sequenceNo, sectionNo);

            var errorMessages = new Dictionary <string, string>();

            if (string.IsNullOrWhiteSpace(feedbackMessage))
            {
                errorMessages["FeedbackMessage"] = "Please enter a feedback comment";
            }

            if (errorMessages.Any())
            {
                foreach (var error in errorMessages)
                {
                    ModelState.AddModelError(error.Key, error.Value);
                }

                var page = await _qnaApiClient.GetPage(application.ApplicationId, section.Id, pageId);

                var pageVm = new PageViewModel(applicationId, sequenceNo, sectionNo, pageId, section, page, backViewModel.BackAction, backViewModel.BackController, backViewModel.BackOrganisationId);
                return(View(nameof(Page), pageVm));
            }

            var feedback = new QnA.Api.Types.Page.Feedback {
                Id = Guid.NewGuid(), Message = feedbackMessage, From = "Staff member", Date = DateTime.UtcNow, IsNew = true
            };

            await _qnaApiClient.UpdateFeedback(application.ApplicationId, section.Id, pageId, feedback);

            return(RedirectToAction(nameof(Section), new { applicationId, backViewModel.BackAction, backViewModel.BackController, sequenceNo, sectionNo, backViewModel.BackOrganisationId }));
        }
        public async Task <IActionResult> Page(Guid applicationId, int sequenceNo, int sectionNo, string pageId, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var applySequence = application.ApplyData.Sequences.Single(x => x.SequenceNo == sequenceNo);
            var applySection  = applySequence.Sections.Single(x => x.SectionNo == sectionNo);

            var section = await _qnaApiClient.GetSection(application.ApplicationId, applySection.SectionId);

            var page = await _qnaApiClient.GetPage(application.ApplicationId, section.Id, pageId);

            if (page?.Active is false)
            {
                // DO NOT show any information
                page = null;
            }

            var pageVm = new PageViewModel(applicationId, sequenceNo, sectionNo, pageId, section, page, backViewModel.BackAction, backViewModel.BackController, backViewModel.BackOrganisationId);

            var activeApplicationStatuses = new List <string> {
                ApplicationStatus.Submitted, ApplicationStatus.Resubmitted
            };
            var activeSequenceStatuses = new List <string> {
                ApplicationSequenceStatus.Submitted, ApplicationSequenceStatus.Resubmitted
            };

            if (activeApplicationStatuses.Contains(application.ApplicationStatus) && activeSequenceStatuses.Contains(applySequence?.Status))
            {
                return(View(nameof(Page), pageVm));
            }
            else
            {
                return(View($"{nameof(Page)}_ReadOnly", pageVm));
            }
        }
        public async Task <IActionResult> EvaluateSection(Guid applicationId, int sequenceNo, int sectionNo, bool?isSectionComplete, BackViewModel backViewModel)
        {
            var errorMessages = new Dictionary <string, string>();

            if (!isSectionComplete.HasValue)
            {
                errorMessages["IsSectionComplete"] = "Please state if this section is completed";
            }

            if (errorMessages.Any())
            {
                foreach (var error in errorMessages)
                {
                    ModelState.AddModelError(error.Key, error.Value);
                }

                var application = await _applyApiClient.GetApplication(applicationId);

                var organisation = await _apiClient.GetOrganisation(application.OrganisationId);

                var applySequence = application.ApplyData.Sequences.Single(x => x.SequenceNo == sequenceNo);
                var applySection  = applySequence.Sections.Single(x => x.SectionNo == sectionNo);

                var section = await _qnaApiClient.GetSection(application.ApplicationId, applySection.SectionId);

                var applicationData = await _qnaApiClient.GetApplicationDataDictionary(application.ApplicationId);

                var sectionVm = new SectionViewModel(application, organisation, section, applySection, applicationData, backViewModel.BackAction, backViewModel.BackController, backViewModel.BackOrganisationId);

                return(View(nameof(Section), sectionVm));
            }

            await _applyApiClient.EvaluateSection(applicationId, sequenceNo, sectionNo, isSectionComplete.Value, _contextAccessor.HttpContext.User.UserDisplayName());

            return(RedirectToAction(nameof(ActiveSequence), new { applicationId, backViewModel.BackAction, backViewModel.BackController, backViewModel.BackOrganisationId }));
        }
        public async Task <IActionResult> Section(Guid applicationId, int sequenceNo, int sectionNo, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var organisation = await _apiClient.GetOrganisation(application.OrganisationId);

            var applySequence = application.ApplyData.Sequences.Single(x => x.SequenceNo == sequenceNo);
            var applySection  = applySequence.Sections.Single(x => x.SectionNo == sectionNo);

            var sequence = await _qnaApiClient.GetSequence(application.ApplicationId, applySequence.SequenceId);

            var section = await _qnaApiClient.GetSection(application.ApplicationId, applySection.SectionId);

            var applicationData = await _qnaApiClient.GetApplicationDataDictionary(application.ApplicationId);

            var sectionVm = new SectionViewModel(application, organisation, section, applySection, applicationData, backViewModel.BackAction, backViewModel.BackController, backViewModel.BackOrganisationId);

            var activeApplicationStatuses = new List <string> {
                ApplicationStatus.Submitted, ApplicationStatus.Resubmitted
            };
            var activeSequenceStatuses = new List <string> {
                ApplicationSequenceStatus.Submitted, ApplicationSequenceStatus.Resubmitted
            };

            if (activeApplicationStatuses.Contains(application.ApplicationStatus) && activeSequenceStatuses.Contains(applySequence?.Status))
            {
                if (applySection.Status != ApplicationSectionStatus.Evaluated)
                {
                    await _applyApiClient.StartApplicationSectionReview(applicationId, sequence.SequenceNo, section.SectionNo, _contextAccessor.HttpContext.User.UserDisplayName());
                }

                return(View(nameof(Section), sectionVm));
            }
            else
            {
                return(View($"{nameof(Section)}_ReadOnly", sectionVm));
            }
        }
        public async Task <IActionResult> Return(Guid applicationId, int sequenceNo, string returnType, BackViewModel backViewModel)
        {
            var application = await _applyApiClient.GetApplication(applicationId);

            var activeApplicationSequence = application.ApplyData.Sequences.Where(seq => seq.IsActive && !seq.NotRequired).OrderBy(seq => seq.SequenceNo).FirstOrDefault();

            if (activeApplicationSequence is null || activeApplicationSequence.SequenceNo != sequenceNo || activeApplicationSequence.Sections.Any(s => s.Status != ApplicationSectionStatus.Evaluated && !s.NotRequired))
            {
                // This is to stop the wrong sequence being returned, or if not all sections are Evaluated
                return(RedirectToApplicationsFromSequence(sequenceNo));
            }