コード例 #1
0
        public async Task <IActionResult> Index(
            string form,
            string path,
            Dictionary <string, string[]> formData)
        {
            var viewModel      = formData.ToNormaliseDictionary(string.Empty);
            var queryParamters = Request.Query;
            var baseForm       = await _schemaFactory.Build(form);

            if (baseForm == null)
            {
                throw new ApplicationException($"Requested form '{form}' could not be found.");
            }

            var page = baseForm.GetPage(_pageHelper, path);

            if (page == null)
            {
                throw new ApplicationException($"Requested path '{path}' object could not be found for form '{form}'");
            }

            var sessionGuid = _sessionHelper.GetSessionGuid();

            await _bookingService.ProcessMonthRequest(viewModel, baseForm, page, sessionGuid);

            var routeValuesDictionary = new RouteValueDictionaryBuilder()
                                        .WithValue("path", path)
                                        .WithValue("form", form)
                                        .WithQueryValues(queryParamters)
                                        .Build();

            return(RedirectToAction("Index", "Home", routeValuesDictionary));
        }
コード例 #2
0
        public async Task Process(List <IAction> actions, FormSchema formSchema, string formName)
        {
            var sessionGuid = _sessionHelper.GetSessionGuid();
            var mappingData = await _mappingService.Map(sessionGuid, formName);

            foreach (var action in actions)
            {
                var response   = new HttpResponseMessage();
                var submitSlug = action.Properties.PageActionSlugs.FirstOrDefault(_ =>
                                                                                  _.Environment.ToLower().Equals(_environment.EnvironmentName.ToS3EnvPrefix().ToLower()));

                if (submitSlug == null)
                {
                    throw new ApplicationException("ValidateService::Process, there is no PageActionSlug defined for this environment");
                }

                var entity = _actionHelper.GenerateUrl(submitSlug.URL, mappingData.FormAnswers);

                if (!string.IsNullOrEmpty(submitSlug.AuthToken))
                {
                    _gateway.ChangeAuthenticationHeader(submitSlug.AuthToken);
                }

                response = await _gateway.GetAsync(entity.Url);

                if (!response.IsSuccessStatusCode)
                {
                    throw new ApplicationException($"ValidateService::Process, http request to {entity.Url} returned an unsuccessful status code, Response: {JsonConvert.SerializeObject(response)}");
                }
            }
        }
コード例 #3
0
        public async Task <IActionResult> PaymentFailure(string form, [FromQuery] string reference)
        {
            var sessionGuid = _sessionHelper.GetSessionGuid();
            var data        = await _mappingService.Map(sessionGuid, form);

            var url = await _payService.ProcessPayment(data, form, "payment", reference, sessionGuid);

            var paymentFailureViewModel = new PaymentFailureViewModel
            {
                FormName     = form,
                PageTitle    = "Failure",
                Reference    = reference,
                PaymentUrl   = url,
                StartPageUrl = data.BaseForm.StartPageUrl
            };

            return(View("./Failure", paymentFailureViewModel));
        }
コード例 #4
0
        public FormAnswers GetFormAnswers()
        {
            string sessionGuid   = _sessionHelper.GetSessionGuid();
            string cachedAnswers = _distributedCache.GetString(sessionGuid);

            return(cachedAnswers is null
                ? new FormAnswers {
                Pages = new List <PageAnswers>()
            }
                : JsonConvert.DeserializeObject <FormAnswers>(cachedAnswers));
        }
コード例 #5
0
        public async Task <string> Submit(string form)
        {
            var sessionGuid = _sessionHelper.GetSessionGuid();

            if (string.IsNullOrEmpty(sessionGuid))
            {
                throw new ApplicationException($"A Session GUID was not provided.");
            }

            var data = await _mappingService.Map(sessionGuid, form);

            return(await _submitService.ProcessSubmission(data, form, sessionGuid));
        }
コード例 #6
0
        public Page GetPageWithMatchingRenderConditions(List <Page> pages)
        {
            var guid             = _sessionHelper.GetSessionGuid();
            var formData         = _distributedCache.GetString(guid);
            var convertedAnswers = !string.IsNullOrEmpty(formData)
                ? JsonConvert.DeserializeObject <FormAnswers>(formData)
                : new FormAnswers {
                Pages = new List <PageAnswers>()
            };

            var answers = convertedAnswers.Pages.SelectMany(_ => _.Answers).ToDictionary(_ => _.QuestionId, _ => _.Response);

            return(pages.FirstOrDefault(page => page.CheckPageMeetsConditions(answers)));
        }
コード例 #7
0
        public async Task <string> ProcessPaymentResponse(string form, string responseCode, string reference)
        {
            var sessionGuid   = _sessionHelper.GetSessionGuid();
            var mappingEntity = await _mappingService.Map(sessionGuid, form);

            if (mappingEntity == null)
            {
                throw new Exception($"PayService:: No mapping entity found for {form}");
            }

            var currentPage        = mappingEntity.BaseForm.GetPage(_pageHelper, mappingEntity.FormAnswers.Path);
            var paymentInformation = await GetFormPaymentInformation(mappingEntity, form, currentPage);

            var postUrl         = currentPage.GetSubmitFormEndpoint(mappingEntity.FormAnswers, _hostingEnvironment.EnvironmentName.ToS3EnvPrefix());
            var paymentProvider = GetFormPaymentProvider(paymentInformation);

            if (string.IsNullOrWhiteSpace(postUrl.CallbackUrl))
            {
                throw new ArgumentException("PayService::ProcessPaymentResponse, Callback url has not been specified");
            }

            _gateway.ChangeAuthenticationHeader(postUrl.AuthToken);
            try
            {
                paymentProvider.VerifyPaymentResponse(responseCode);
                await _gateway.PostAsync(postUrl.CallbackUrl,
                                         new { CaseReference = reference, PaymentStatus = EPaymentStatus.Success.ToString() });

                return(reference);
            }
            catch (PaymentDeclinedException)
            {
                await _gateway.PostAsync(postUrl.CallbackUrl,
                                         new { CaseReference = reference, PaymentStatus = EPaymentStatus.Declined.ToString() });

                throw new PaymentDeclinedException("PayService::ProcessPaymentResponse, PaymentProvider declined payment");
            }
            catch (PaymentFailureException)
            {
                await _gateway.PostAsync(postUrl.CallbackUrl,
                                         new { CaseReference = reference, PaymentStatus = EPaymentStatus.Failure.ToString() });

                throw new PaymentFailureException("PayService::ProcessPaymentResponse, PaymentProvider failed payment");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "The payment callback failed");
                throw new Exception(ex.Message);
            }
        }
コード例 #8
0
        public async Task <string> Submit(string form, string path)
        {
            var sessionGuid = _sessionHelper.GetSessionGuid();

            if (string.IsNullOrEmpty(sessionGuid))
            {
                throw new ApplicationException("A Session GUID was not provided.");
            }

            var data = await _mappingService.Map(sessionGuid, form);

            var paymentReference = await _submitService.PaymentSubmission(data, form, sessionGuid);

            return(await _payService.ProcessPayment(data, form, path, paymentReference, sessionGuid));
        }
コード例 #9
0
        public async Task Process(List <IAction> actions)
        {
            var sessionGuid = _sessionHelper.GetSessionGuid();

            if (string.IsNullOrEmpty(sessionGuid))
            {
                throw new Exception("EmailService::Process: Session has expired");
            }

            var formData    = _distributedCache.GetString(sessionGuid);
            var formAnswers = JsonConvert.DeserializeObject <FormAnswers>(formData);

            foreach (var action in actions)
            {
                await action.Process(_actionHelper, _emailProvider, formAnswers);
            }
        }
コード例 #10
0
        public Task ProcessTemplatedEmail(List <IAction> actions)
        {
            var sessionGuid = _sessionHelper.GetSessionGuid();

            if (string.IsNullOrEmpty(sessionGuid))
            {
                throw new Exception("TemplatedEmailService::Process: Session has expired");
            }

            var formData    = _distributedCache.GetString(sessionGuid);
            var formAnswers = JsonConvert.DeserializeObject <FormAnswers>(formData);

            foreach (var action in actions)
            {
                var templatedEmailProvider = _templatedEmailProviders.Get(action.Properties.EmailTemplateProvider);
                var convertedAnswers       = formAnswers.AllAnswers.ToDictionary(x => x.QuestionId, x => x.Response);
                var personalisation        = new Dictionary <string, dynamic>();

                if (action.Properties.IncludeCaseReference)
                {
                    personalisation.Add("reference", formAnswers.CaseReference);
                }

                if (action.Properties.Personalisation is not null && !convertedAnswers.Count.Equals(0))
                {
                    action.Properties.Personalisation.ForEach(field => { personalisation.Add(field, convertedAnswers[field]); });
                }

                action.ProcessTemplatedEmail(
                    _actionHelper,
                    templatedEmailProvider,
                    personalisation,
                    formAnswers);
            }
            return(null);
        }
コード例 #11
0
        public ValidationResult Validate(Element element, Dictionary <string, dynamic> viewModel, FormSchema baseForm)
        {
            if (element.Type != EElementType.MultipleFileUpload)
            {
                return new ValidationResult {
                           IsValid = true
                }
            }
            ;

            var key = $"{element.Properties.QuestionId}{FileUploadConstants.SUFFIX}";

            if (!viewModel.ContainsKey(key))
            {
                return new ValidationResult {
                           IsValid = true
                }
            }
            ;

            List <DocumentModel> documentModel = viewModel[key];

            if (documentModel == null)
            {
                return new ValidationResult {
                           IsValid = true
                }
            }
            ;

            var maxCombinedFileSize = element.Properties.MaxCombinedFileSize > 0 ? element.Properties.MaxCombinedFileSize * SystemConstants.OneMBInBinaryBytes : SystemConstants.DefaultMaxCombinedFileSize;

            var sessionGuid   = _sessionHelper.GetSessionGuid();
            var cachedAnswers = _distributedCache.GetString(sessionGuid);

            var convertedAnswers = cachedAnswers == null
                ? new FormAnswers {
                Pages = new List <PageAnswers>()
            }
                : JsonConvert.DeserializeObject <FormAnswers>(cachedAnswers);

            var path = viewModel.FirstOrDefault(_ => _.Key.Equals("Path")).Value;

            var pageAnswersString = convertedAnswers.Pages.FirstOrDefault(_ => _.PageSlug.Equals(path))?.Answers.FirstOrDefault(_ => _.QuestionId == key);
            var response          = new List <FileUploadModel>();

            if (pageAnswersString != null)
            {
                response = JsonConvert.DeserializeObject <List <FileUploadModel> >(pageAnswersString.Response.ToString());
            }

            if (documentModel.Sum(_ => _.FileSize) + response?.Sum(_ => _.FileSize) < maxCombinedFileSize)
            {
                return new ValidationResult {
                           IsValid = true
                }
            }
            ;

            return(new ValidationResult
            {
                IsValid = false,
                Message = $"The total size of all your added files must not be more than {maxCombinedFileSize.ToReadableMaxFileSize()}MB"
            });
        }
    }
}
コード例 #12
0
        public async Task ProcessMonthRequest(Dictionary <string, object> viewModel, string form, string path)
        {
            var baseForm = await _schemaFactory.Build(form);

            if (baseForm is null)
            {
                throw new ApplicationException($"Requested form '{form}' could not be found.");
            }

            var currentPage = baseForm.GetPage(_pageHelper, path);

            if (currentPage is null)
            {
                throw new ApplicationException($"Requested path '{path}' object could not be found for form '{form}'");
            }

            if (!viewModel.ContainsKey(BookingConstants.BOOKING_MONTH_REQUEST))
            {
                throw new ApplicationException("BookingService::ProcessMonthRequest, request for appointment did not contain requested month");
            }

            var requestedMonth = DateTime.Parse(viewModel[BookingConstants.BOOKING_MONTH_REQUEST].ToString());

            var currentDate    = DateTime.Now;
            var bookingElement = (Booking)currentPage.Elements
                                 .First(element => element.Type.
                                        Equals(EElementType.Booking));

            if (requestedMonth.Month.Equals(currentDate.Month) && requestedMonth.Year.Equals(currentDate.Year))
            {
                requestedMonth = currentDate;
            }

            if (requestedMonth > new DateTime(currentDate.Year, currentDate.Month, 1).AddMonths(bookingElement.Properties.SearchPeriod))
            {
                throw new ApplicationException("BookingService::ProcessMonthRequest, Invalid request for appointment search, Start date provided is after allowed search period");
            }

            if (requestedMonth < currentDate)
            {
                throw new ApplicationException("BookingService::ProcessMonthRequest, Invalid request for appointment search, Start date provided is before today");
            }

            var guid = _sessionHelper.GetSessionGuid();

            if (string.IsNullOrEmpty(guid))
            {
                throw new ApplicationException("BookingService::ProcessMonthRequest Session has expired");
            }

            var cachedAnswers = _distributedCache.GetString(guid);

            if (cachedAnswers is null)
            {
                throw new ApplicationException("BookingService::ProcessMonthRequest, Session data is null");
            }

            var bookingInformationCacheKey = $"{bookingElement.Properties.QuestionId}{BookingConstants.APPOINTMENT_TYPE_SEARCH_RESULTS}";
            var convertedAnswers           = JsonConvert.DeserializeObject <FormAnswers>(cachedAnswers);

            var appointmentType = bookingElement.Properties.AppointmentTypes
                                  .GetAppointmentTypeForEnvironment(_environment.EnvironmentName);

            if (appointmentType.NeedsAppointmentIdMapping)
            {
                _mappingService.MapAppointmentId(appointmentType, convertedAnswers);
            }

            var appointmentTimes = await _bookingProviders.Get(bookingElement.Properties.BookingProvider)
                                   .GetAvailability(new AvailabilityRequest
            {
                StartDate         = requestedMonth.Date,
                EndDate           = requestedMonth.Date.LastDayOfTheMonth(),
                AppointmentId     = appointmentType.AppointmentId,
                OptionalResources = appointmentType.OptionalResources
            });

            var cachedBookingInformation          = JsonConvert.DeserializeObject <BookingInformation>(convertedAnswers.FormData[bookingInformationCacheKey].ToString());
            BookingInformation bookingInformation = new()
            {
                AppointmentTypeId    = appointmentType.AppointmentId,
                Appointments         = appointmentTimes,
                CurrentSearchedMonth = requestedMonth,
                FirstAvailableMonth  = cachedBookingInformation.FirstAvailableMonth,
                IsFullDayAppointment = cachedBookingInformation.IsFullDayAppointment,
                AppointmentEndTime   = cachedBookingInformation.AppointmentEndTime,
                AppointmentStartTime = cachedBookingInformation.AppointmentStartTime
            };

            _pageHelper.SaveFormData(bookingInformationCacheKey, bookingInformation, guid, baseForm.BaseURL);
        }
コード例 #13
0
        public async Task Process(List <IAction> actions, FormSchema formSchema, string formName)
        {
            var answers     = new List <Answers>();
            var sessionGuid = _sessionHelper.GetSessionGuid();
            var mappingData = await _mappingService.Map(sessionGuid, formName);

            foreach (var action in actions)
            {
                var response   = new HttpResponseMessage();
                var submitSlug = action.Properties.PageActionSlugs.FirstOrDefault(_ =>
                                                                                  _.Environment.ToLower().Equals(_environment.EnvironmentName.ToS3EnvPrefix().ToLower()));

                if (submitSlug == null)
                {
                    throw new ApplicationException("RetrieveExternalDataService::Process, there is no PageActionSlug defined for this environment");
                }

                var entity = _actionHelper.GenerateUrl(submitSlug.URL, mappingData.FormAnswers);

                if (!string.IsNullOrEmpty(submitSlug.AuthToken))
                {
                    _gateway.ChangeAuthenticationHeader(submitSlug.AuthToken);
                }

                if (entity.IsPost)
                {
                    response = await _gateway.PostAsync(entity.Url, mappingData.Data);
                }
                else
                {
                    response = await _gateway.GetAsync(entity.Url);
                }

                if (!response.IsSuccessStatusCode)
                {
                    throw new ApplicationException($"RetrieveExternalDataService::Process, http request to {entity.Url} returned an unsuccessful status code, Response: {JsonConvert.SerializeObject(response)}");
                }

                if (response.Content == null)
                {
                    throw new ApplicationException($"RetrieveExternalDataService::Process, response content from {entity.Url} is null.");
                }

                var content = await response.Content.ReadAsStringAsync();

                if (string.IsNullOrWhiteSpace(content))
                {
                    throw new ApplicationException($"RetrieveExternalDataService::Process, Gateway {entity.Url} responded with empty reference");
                }

                answers.Add(new Answers
                {
                    QuestionId = action.Properties.TargetQuestionId,
                    Response   = JsonConvert.DeserializeObject <string>(content)
                });
            }

            mappingData.FormAnswers.Pages.FirstOrDefault(_ => _.PageSlug.ToLower().Equals(mappingData.FormAnswers.Path.ToLower())).Answers.AddRange(answers);

            await _distributedCache.SetStringAsync(sessionGuid, JsonConvert.SerializeObject(mappingData.FormAnswers), CancellationToken.None);
        }
コード例 #14
0
        public ValidationResult Validate(Element element, Dictionary <string, dynamic> viewModel, FormSchema baseForm)
        {
            if (!element.Type.Equals(EElementType.MultipleFileUpload))
            {
                return new ValidationResult {
                           IsValid = true
                }
            }
            ;

            if (element.Properties.Optional && viewModel.ContainsKey(ButtonConstants.SUBMIT))
            {
                return new ValidationResult {
                           IsValid = true
                }
            }
            ;

            var key     = $"{ element.Properties.QuestionId}{FileUploadConstants.SUFFIX}";
            var isValid = false;

            List <DocumentModel> value = viewModel.ContainsKey(key)
                ? viewModel[key]
                : null;

            isValid = !(value is null);

            if (value is null)
            {
                var sessionGuid = _sessionHelper.GetSessionGuid();

                var cachedAnswers = _distributedCache.GetString(sessionGuid);

                var convertedAnswers = cachedAnswers is null
                    ? new FormAnswers {
                    Pages = new List <PageAnswers>()
                }
                    : JsonConvert.DeserializeObject <FormAnswers>(cachedAnswers);

                var path = viewModel.FirstOrDefault(_ => _.Key.Equals("Path")).Value;

                var pageAnswersString = convertedAnswers.Pages.FirstOrDefault(_ => _.PageSlug.Equals(path))?.Answers.FirstOrDefault(_ => _.QuestionId.Equals(key));
                var response          = new List <FileUploadModel>();
                if (pageAnswersString is not null)
                {
                    response = JsonConvert.DeserializeObject <List <FileUploadModel> >(pageAnswersString.Response.ToString());

                    if (response.Any())
                    {
                        isValid = true;
                    }
                }
            }

            return(new ValidationResult
            {
                IsValid = isValid,
                Message = ValidationConstants.FILEUPLOAD_EMPTY
            });
        }
    }
}
コード例 #15
0
        public async Task <ProcessPageEntity> ProcessPage(string form, string path, string subPath, IQueryCollection queryParamters)
        {
            if (string.IsNullOrEmpty(path))
            {
                _sessionHelper.RemoveSessionGuid();
            }

            var sessionGuid = _sessionHelper.GetSessionGuid();

            if (string.IsNullOrEmpty(sessionGuid))
            {
                sessionGuid = Guid.NewGuid().ToString();
                _sessionHelper.SetSessionGuid(sessionGuid);
            }

            var baseForm = await _schemaFactory.Build(form);

            if (baseForm == null)
            {
                return(null);
            }

            if (!baseForm.IsAvailable(_environment.EnvironmentName))
            {
                throw new ApplicationException($"Form: {form} is not available in this Environment: {_environment.EnvironmentName.ToS3EnvPrefix()}");
            }

            var formData = _distributedCache.GetString(sessionGuid);

            if (formData == null && path != baseForm.FirstPageSlug && (!baseForm.HasDocumentUpload || path != FileUploadConstants.DOCUMENT_UPLOAD_URL_PATH))
            {
                return new ProcessPageEntity
                       {
                           ShouldRedirect = true,
                           TargetPage     = baseForm.FirstPageSlug
                       }
            }
            ;

            if (string.IsNullOrEmpty(path))
            {
                return new ProcessPageEntity
                       {
                           ShouldRedirect = true,
                           TargetPage     = baseForm.FirstPageSlug
                       }
            }
            ;

            if (formData != null && path == baseForm.FirstPageSlug)
            {
                var convertedFormData = JsonConvert.DeserializeObject <FormAnswers>(formData);

                if (form.ToLower() != convertedFormData.FormName.ToLower())
                {
                    _distributedCache.Remove(sessionGuid);
                }
            }

            var page = baseForm.GetPage(_pageHelper, path);

            if (page == null)
            {
                throw new ApplicationException($"Requested path '{path}' object could not be found for form '{form}'");
            }

            await baseForm.ValidateFormSchema(_pageHelper, form, path);

            List <object> searchResults = null;

            if (subPath.Equals(LookUpConstants.Automatic) || subPath.Equals(LookUpConstants.Manual))
            {
                var convertedAnswers = new FormAnswers {
                    Pages = new List <PageAnswers>()
                };

                if (!string.IsNullOrEmpty(formData))
                {
                    convertedAnswers = JsonConvert.DeserializeObject <FormAnswers>(formData);
                }

                if (convertedAnswers.FormData.ContainsKey($"{path}{LookUpConstants.SearchResultsKeyPostFix}"))
                {
                    searchResults = ((IEnumerable <object>)convertedAnswers.FormData[$"{path}{LookUpConstants.SearchResultsKeyPostFix}"])?.ToList();
                }
            }

            if (page.Elements.Any(_ => _.Type == EElementType.PaymentSummary))
            {
                var data = await _mappingService.Map(sessionGuid, form);

                var paymentAmount = await _payService.GetFormPaymentInformation(data, form, page);

                page.Elements.First(_ => _.Type == EElementType.PaymentSummary).Properties.Value = paymentAmount.Settings.Amount;
            }

            if (page.HasIncomingGetValues)
            {
                var convertedAnswers = new FormAnswers {
                    Pages = new List <PageAnswers>()
                };
                if (!string.IsNullOrEmpty(formData))
                {
                    convertedAnswers = JsonConvert.DeserializeObject <FormAnswers>(formData);
                }

                var result = _incomingDataHelper.AddIncomingFormDataValues(page, queryParamters, convertedAnswers);
                _pageHelper.SaveNonQuestionAnswers(result, form, path, sessionGuid);
            }

            if (page.HasPageActionsGetValues)
            {
                await _actionsWorkflow.Process(page.PageActions, null, form);
            }

            if (page.Elements.Any(_ => _.Type.Equals(EElementType.Booking)))
            {
                var bookingProcessEntity = await _bookingService.Get(baseForm.BaseURL, page, sessionGuid);

                if (bookingProcessEntity.BookingHasNoAvailableAppointments)
                {
                    return(new ProcessPageEntity
                    {
                        ShouldRedirect = true,
                        TargetPage = BookingConstants.NO_APPOINTMENT_AVAILABLE
                    });
                }

                searchResults = bookingProcessEntity.BookingInfo;
            }

            var viewModel = await GetViewModel(page, baseForm, path, sessionGuid, subPath, searchResults);

            return(new ProcessPageEntity
            {
                ViewModel = viewModel
            });
        }
コード例 #16
0
        public async Task <ProcessPageEntity> ProcessPage(string form, string path, string subPath, IQueryCollection queryParameters)
        {
            if (string.IsNullOrEmpty(path))
            {
                _sessionHelper.RemoveSessionGuid();
            }

            var sessionGuid = _sessionHelper.GetSessionGuid();

            if (string.IsNullOrEmpty(sessionGuid))
            {
                sessionGuid = Guid.NewGuid().ToString();
                _sessionHelper.SetSessionGuid(sessionGuid);
            }

            var baseForm = await _schemaFactory.Build(form);

            if (baseForm is null)
            {
                return(null);
            }

            if (!_formAvailabilityService.IsAvailable(baseForm.EnvironmentAvailabilities, _environment.EnvironmentName))
            {
                _logger.LogWarning($"Form: {form} is not available in this Environment: {_environment.EnvironmentName.ToS3EnvPrefix()}");
                return(null);
            }

            if (string.IsNullOrEmpty(path))
            {
                return new ProcessPageEntity {
                           ShouldRedirect = true, TargetPage = baseForm.FirstPageSlug
                }
            }
            ;

            var formData = _distributedCache.GetString(sessionGuid);

            if (string.IsNullOrEmpty(formData) && !path.Equals(baseForm.FirstPageSlug) && (!baseForm.HasDocumentUpload || !path.Equals(FileUploadConstants.DOCUMENT_UPLOAD_URL_PATH)))
            {
                return new ProcessPageEntity {
                           ShouldRedirect = true, TargetPage = baseForm.FirstPageSlug
                }
            }
            ;

            if (!string.IsNullOrEmpty(formData) && path.Equals(baseForm.FirstPageSlug))
            {
                var convertedFormData = JsonConvert.DeserializeObject <FormAnswers>(formData);

                if (!form.Equals(convertedFormData.FormName, StringComparison.OrdinalIgnoreCase))
                {
                    _distributedCache.Remove(sessionGuid);
                }
            }

            var page = baseForm.GetPage(_pageHelper, path);

            if (page is null)
            {
                throw new ApplicationException($"Requested path '{path}' object could not be found for form '{form}'");
            }

            List <object> searchResults    = null;
            var           convertedAnswers = new FormAnswers {
                Pages = new List <PageAnswers>()
            };

            if (!string.IsNullOrEmpty(formData))
            {
                convertedAnswers = JsonConvert.DeserializeObject <FormAnswers>(formData);
            }

            if (page.Elements.Any(_ => _.Type.Equals(EElementType.Summary)))
            {
                var journeyPages = baseForm.GetReducedPages(convertedAnswers);
                foreach (var schemaPage in journeyPages)
                {
                    await _schemaFactory.TransformPage(schemaPage, convertedAnswers);
                }
            }
            else
            {
                await _schemaFactory.TransformPage(page, convertedAnswers);
            }

            if (subPath.Equals(LookUpConstants.Automatic) || subPath.Equals(LookUpConstants.Manual))
            {
                if (convertedAnswers.FormData.ContainsKey($"{path}{LookUpConstants.SearchResultsKeyPostFix}"))
                {
                    searchResults = ((IEnumerable <object>)convertedAnswers.FormData[$"{path}{LookUpConstants.SearchResultsKeyPostFix}"])?.ToList();
                }
            }

            if (page.HasIncomingGetValues)
            {
                var result = _incomingDataHelper.AddIncomingFormDataValues(page, queryParameters, convertedAnswers);
                _pageHelper.SaveNonQuestionAnswers(result, form, path, sessionGuid);
            }

            if (page.HasPageActionsGetValues)
            {
                await _actionsWorkflow.Process(page.PageActions, null, form);
            }

            if (page.Elements.Any(_ => _.Type.Equals(EElementType.Booking)))
            {
                var bookingProcessEntity = await _bookingService.Get(baseForm.BaseURL, page, sessionGuid);

                if (bookingProcessEntity.BookingHasNoAvailableAppointments)
                {
                    return(new ProcessPageEntity
                    {
                        ShouldRedirect = true,
                        TargetPage = BookingConstants.NO_APPOINTMENT_AVAILABLE
                    });
                }

                searchResults = bookingProcessEntity.BookingInfo;
            }

            var viewModel = await GetViewModel(page, baseForm, path, sessionGuid, subPath, searchResults);

            return(new ProcessPageEntity {
                ViewModel = viewModel
            });
        }