private RedirectToRouteResult RedirectToSignAgreement(ReservationsRouteModel routeModel, string previousRouteName)
        {
            if (_userClaimsService.UserIsInRole(routeModel.EmployerAccountId,
                                                EmployerUserRole.Owner, User.Claims))
            {
                routeModel.PreviousPage = previousRouteName;
                return(RedirectToRoute(RouteNames.EmployerOwnerSignAgreement, routeModel));
            }

            routeModel.PreviousPage = previousRouteName;
            return(RedirectToRoute(RouteNames.EmployerTransactorSignAgreement, routeModel));
        }
        public async Task <IActionResult> SelectReservation(
            ReservationsRouteModel routeModel,
            SelectReservationViewModel viewModel)
        {
            var backUrl = _urlHelper.GenerateCohortDetailsUrl(routeModel.UkPrn, routeModel.EmployerAccountId,
                                                              viewModel.CohortReference, journeyData: viewModel.JourneyData);

            try
            {
                var apprenticeshipTrainingRouteName = RouteNames.EmployerSelectCourseRuleCheck;
                CacheReservationEmployerCommand cacheReservationEmployerCommand;
                Guid?userId = null;
                if (routeModel.UkPrn.HasValue)
                {
                    var response = await _mediator.Send(new GetProviderCacheReservationCommandQuery
                    {
                        AccountLegalEntityPublicHashedId = routeModel.AccountLegalEntityPublicHashedId,
                        CohortRef = routeModel.CohortReference,
                        CohortId  = _encodingService.Decode(routeModel.CohortReference, EncodingType.CohortReference),
                        UkPrn     = routeModel.UkPrn.Value
                    });

                    cacheReservationEmployerCommand = response.Command;

                    apprenticeshipTrainingRouteName = RouteNames.ProviderApprenticeshipTrainingRuleCheck;
                }
                else
                {
                    var userAccountIdClaim = HttpContext.User.Claims.First(c =>
                                                                           c.Type.Equals(EmployerClaims.IdamsUserIdClaimTypeIdentifier));
                    userId = Guid.Parse(userAccountIdClaim.Value);

                    cacheReservationEmployerCommand = await BuildEmployerReservationCacheCommand(
                        routeModel.EmployerAccountId, routeModel.AccountLegalEntityPublicHashedId,
                        viewModel.CohortReference, viewModel.ProviderId, viewModel.JourneyData);
                }

                var redirectResult = await CheckCanAutoReserve(cacheReservationEmployerCommand.AccountId,
                                                               viewModel.TransferSenderId, viewModel.JourneyData,
                                                               cacheReservationEmployerCommand.AccountLegalEntityPublicHashedId,
                                                               routeModel.UkPrn ?? viewModel.ProviderId, viewModel.CohortReference,
                                                               routeModel.EmployerAccountId, userId);

                if (!string.IsNullOrEmpty(redirectResult))
                {
                    if (redirectResult == RouteNames.Error500)
                    {
                        return(RedirectToRoute(redirectResult));
                    }

                    return(Redirect(redirectResult));
                }

                var availableReservationsResult = await _mediator.Send(
                    new GetAvailableReservationsQuery { AccountId = cacheReservationEmployerCommand.AccountId });

                if (availableReservationsResult.Reservations != null &&
                    availableReservationsResult.Reservations.Any())
                {
                    viewModel.AvailableReservations = availableReservationsResult.Reservations
                                                      .Select(reservation => new AvailableReservationViewModel(reservation));
                    viewModel.AccountId = cacheReservationEmployerCommand.AccountId;
                    viewModel.BackLink  = backUrl;
                    return(View(ViewNames.Select, viewModel));
                }

                await _mediator.Send(cacheReservationEmployerCommand);

                routeModel.Id = cacheReservationEmployerCommand.Id;

                return(RedirectToRoute(apprenticeshipTrainingRouteName, routeModel));
            }
            catch (ValidationException e)
            {
                _logger.LogWarning(e, "Validation error trying to render select reservation.");
                return(RedirectToRoute(RouteNames.Error500));
            }
            catch (ProviderNotAuthorisedException e)
            {
                _logger.LogWarning(e,
                                   $"Provider (UKPRN: {e.UkPrn}) does not has access to create a reservation for legal entity for account (Id: {e.AccountId}).");
                return(View("NoPermissions", backUrl));
            }
            catch (ReservationLimitReachedException)
            {
                return(View("ReservationLimitReached", backUrl));
            }
            catch (GlobalReservationRuleException)
            {
                if (routeModel.UkPrn.HasValue)
                {
                    return(View("ProviderFundingPaused", backUrl));
                }

                return(View("EmployerFundingPaused", backUrl));
            }
            catch (AccountLegalEntityNotFoundException e)
            {
                _logger.LogWarning($"Account legal entity not found [{e.AccountLegalEntityPublicHashedId}].");
                return(RedirectToRoute(RouteNames.Error404));
            }
            catch (AccountLegalEntityInvalidException ex)
            {
                _logger.LogWarning(ex.Message);
                return(RedirectToRoute(RouteNames.Error500));
            }
            catch (TransferSenderNotAllowedException e)
            {
                _logger.LogWarning(e,
                                   $"AccountId: {e.AccountId} does not have sender id {e.TransferSenderId} allowed).");
                return(RedirectToRoute(RouteNames.Error500));
            }
            catch (EmployerAgreementNotSignedException e)
            {
                _logger.LogWarning(e, $"AccountId: {e.AccountId} does not have a signed agreement for ALE {e.AccountLegalEntityId}).");

                var routeName = RouteNames.EmployerTransactorSignAgreement;
                if (routeModel.UkPrn.HasValue)
                {
                    routeName = RouteNames.ProviderEmployerAgreementNotSigned;
                }
                else
                {
                    if (_userClaimsService.UserIsInRole(routeModel.EmployerAccountId,
                                                        EmployerUserRole.Owner, User.Claims))
                    {
                        routeName = RouteNames.EmployerOwnerSignAgreement;
                    }
                }

                routeModel.IsFromSelect = true;
                routeModel.PreviousPage = backUrl;

                return(RedirectToRoute(routeName, routeModel));
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Error trying to render select reservation.");
                return(RedirectToRoute(RouteNames.Error500));
            }
        }