Esempio n. 1
0
        public async Task <IActionResult> Index(Guid?apprenticeshipId, string message)
        {
            int?UKPRN = Session.GetInt32("UKPRN");

            if (!UKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }

            var liveApprenticeships = await _sqlQueryDispatcher.ExecuteQuery(new GetApprenticeshipsForProvider()
            {
                ProviderId = _providerContextProvider.GetProviderId(withLegacyFallback: true)
            });

            if (apprenticeshipId.HasValue)
            {
                var linkMessage = $"<a id=\"apprenticeshiplink\" class=\"govuk-link\" href=\"#\" data-apprenticeshipid=\"{apprenticeshipId.Value}\">{message}</a>";

                if (!string.IsNullOrEmpty(message))
                {
                    ViewBag.Message = linkMessage;
                }

                ViewBag.ApprenticeshipId = apprenticeshipId.Value;
            }

            return(View(new ProviderApprenticeshipsViewModel
            {
                Apprenticeships = liveApprenticeships.Select(Apprenticeship.FromSqlModel).ToList()
            }));
        }
        public async Task <OneOf <UploadHasNoErrors, ViewModel> > Handle(Query request, CancellationToken cancellationToken)
        {
            var errorRows = await _fileUploadProcessor.GetCourseUploadRowsWithErrorsForProvider(
                _providerContextProvider.GetProviderId());

            if (errorRows.Count == 0)
            {
                return(new UploadHasNoErrors());
            }

            return(await CreateViewModel(errorRows));
        }
        public async Task <OneOf <ModelWithErrors <ViewModel>, UploadStatus> > Handle(Command request, CancellationToken cancellationToken)
        {
            if (!request.Confirm)
            {
                var validationResult = new ValidationResult(new[]
                {
                    new ValidationFailure(nameof(request.Confirm), "Confirm you want to delete the course")
                });
                return(new ModelWithErrors <ViewModel>(await CreateViewModel(request.RowNumber), validationResult));
            }

            return(await _fileUploadProcessor.DeleteCourseUploadRowForProvider(_providerContextProvider.GetProviderId(), request.RowNumber));
        }
        public async Task <IViewComponentResult> InvokeAsync(ChooseLocationModel model)
        {
            var providerId = _providerContextProvider.GetProviderId(withLegacyFallback: true);

            List <SelectListItem> venues = new List <SelectListItem>();

            var result = await _sqlQueryDispatcher.ExecuteQuery(new GetVenuesByProvider()
            {
                ProviderId = providerId
            });

            foreach (var venue in result)
            {
                if (model.DeliveryLocations == null || !model.DeliveryLocations.Any(x => x.VenueId == venue.VenueId))
                {
                    var item = new SelectListItem {
                        Text = venue.VenueName, Value = venue.VenueId.ToString()
                    };
                    venues.Add(item);
                }
            }
            ;

            model.Locations = venues;
            return(View("~/ViewComponents/Apprenticeships/ChooseLocation/Default.cshtml", model));
        }
Esempio n. 5
0
        public async Task <IViewComponentResult> InvokeAsync(ChooseVenueModel model)
        {
            var providerId = _providerContextProvider.GetProviderId(withLegacyFallback: true);

            List <SelectListItem> venues = new List <SelectListItem>();

            var result = await _sqlQueryDispatcher.ExecuteQuery(new GetVenuesByProvider()
            {
                ProviderId = providerId
            });

            var defaultItem = new SelectListItem {
                Text = "Select", Value = ""
            };

            foreach (var venue in result)
            {
                var item = new SelectListItem {
                    Text = venue.VenueName, Value = venue.VenueId.ToString()
                };
                venues.Add(item);
            }
            ;

            venues.Insert(0, defaultItem);

            model.Venues = venues;
            return(View("~/ViewComponents/Courses/ChooseVenue/Default.cshtml", model));
        }
        public async Task <OneOf <UploadHasErrors, ViewModel> > Handle(Query request, CancellationToken cancellationToken)
        {
            var(uploadRows, uploadStatus) = await _fileUploadProcessor.GetCourseUploadRowsForProvider(_providerContextProvider.GetProviderId());

            if (uploadStatus == UploadStatus.ProcessedWithErrors)
            {
                return(new UploadHasErrors());
            }

            return(await CreateViewModel(uploadRows));
        }
Esempio n. 7
0
        public async Task <OneOf <ModelWithErrors <ViewModel>, UploadStatus> > Handle(Command request, CancellationToken cancellationToken)
        {
            if (!request.Confirm)
            {
                var validationResult = new ValidationResult(new[]
                {
                    new ValidationFailure(nameof(request.Confirm), "Confirm you want to delete the course")
                });
                return(new ModelWithErrors <ViewModel>(await CreateViewModel(request.RowNumber), validationResult));
            }

            var providerId = _providerContextProvider.GetProviderId();
            var row        = await _fileUploadProcessor.GetCourseUploadRowDetailForProvider(providerId, request.RowNumber);

            if (row == null)
            {
                throw new ResourceDoesNotExistException(ResourceType.CourseUploadRow, request.RowNumber);
            }

            return(await _fileUploadProcessor.DeleteCourseUploadRowGroupForProvider(providerId, row.CourseId));
        }
Esempio n. 8
0
        public async Task <OneOf <ModelWithErrors <ViewModel>, ViewModel> > Handle(
            Query request,
            CancellationToken cancellationToken)
        {
            ValidateFlowState();

            var providerId = _providerContextProvider.GetProviderId();

            ViewModel vm = await CreateViewModel(providerId);

            var validator        = new CompleteValidator();
            var validationResult = await validator.ValidateAsync(_flow.State);

            if (!validationResult.IsValid)
            {
                return(new ModelWithErrors <ViewModel>(vm, validationResult));
            }
            else
            {
                return(vm);
            }
        }
        public async Task <OneOf <ModelWithErrors <Command>, Success> > Handle(Command request, CancellationToken cancellationToken)
        {
            if (!request.Confirm)
            {
                var validationResult = new ValidationResult(new[]
                {
                    new ValidationFailure(nameof(request.Confirm), "Confirm you want to delete course data upload")
                });
                return(new ModelWithErrors <Command>(new Command(), validationResult));
            }

            await _fileUploadProcessor.DeleteCourseUploadForProvider(_providerContextProvider.GetProviderId());

            return(new Success());
        }
Esempio n. 10
0
        public ChannelReader <UploadStatus> StatusUpdates(CancellationToken cancellationToken)
        {
            var channel = Channel.CreateUnbounded <UploadStatus>();

            var obs = _fileUploadProcessor.GetCourseUploadStatusUpdatesForProvider(_providerContextProvider.GetProviderId())
                      .TakeWhile(v => v == UploadStatus.Created || v == UploadStatus.Processing);

            var subscription = obs.Subscribe(
                v => channel.Writer.WriteAsync(v),
                onCompleted: () => channel.Writer.Complete());

            cancellationToken.Register(() => subscription.Dispose());

            return(channel.Reader);
        }
Esempio n. 11
0
        public async Task <OneOf <NotFound, UploadStatus> > Handle(Query request, CancellationToken cancellationToken)
        {
            var providerId = _providerContextProvider.GetProviderId();

            var courseUpload = await _sqlQueryDispatcher.ExecuteQuery(new GetLatestUnpublishedCourseUploadForProvider()
            {
                ProviderId = providerId
            });

            if (courseUpload == null)
            {
                return(new NotFound());
            }

            return(courseUpload.UploadStatus);
        }
Esempio n. 12
0
        public async Task <CommandResponse> Handle(
            Command request,
            CancellationToken cancellationToken)
        {
            var currentUser = _currentUserProvider.GetCurrentUser();

            if (currentUser.IsHelpdesk)
            {
                throw new NotAuthorizedException();
            }

            var latestSubmission = await _sqlQueryDispatcher.ExecuteQuery(
                new GetLatestApprenticeshipQASubmissionForProvider()
            {
                ProviderId = _providerContextProvider.GetProviderId()
            });

            if (latestSubmission == null)
            {
                throw new InvalidStateException(InvalidStateReason.InvalidApprenticeshipQASubmission);
            }

            // Cannot hide passed notification if qa status is not passed
            if (latestSubmission.Passed != true)
            {
                throw new InvalidStateException(InvalidStateReason.InvalidApprenticeshipQAStatus);
            }

            // Cannot hide notification if it has already been hidden
            if (latestSubmission.HidePassedNotification)
            {
                throw new InvalidStateException();
            }

            // Hide notification
            await _sqlQueryDispatcher.ExecuteQuery(
                new UpdateHidePassedNotification()
            {
                ApprenticeshipQASubmissionId = latestSubmission.ApprenticeshipQASubmissionId,
                HidePassedNotification       = true
            });

            return(new Success());
        }
Esempio n. 13
0
        public async Task <OneOf <ModelWithErrors <ViewModel>, UploadStatus> > Handle(Command request, CancellationToken cancellationToken)
        {
            var row = await GetRow(request.RowNumber);

            NormalizeCommand();

            var allRegions = await _regionCache.GetAllRegions();

            var validator        = new CommandValidator(_clock, allRegions);
            var validationResult = await validator.ValidateAsync(request);

            if (!validationResult.IsValid)
            {
                var vm = await CreateViewModel(request.DeliveryMode, row);

                request.Adapt(vm);
                return(new ModelWithErrors <ViewModel>(vm, validationResult));
            }

            return(await _fileUploadProcessor.UpdateCourseUploadRowForProvider(
                       _providerContextProvider.GetProviderId(),
                       row.RowNumber,
                       new CourseUploadRowUpdate()
            {
                DeliveryMode = request.DeliveryMode,
                CourseName = request.CourseName,
                ProviderCourseRef = request.ProviderCourseRef,
                StartDate = request.StartDate.ToDateTime(),
                FlexibleStartDate = request.FlexibleStartDate.Value,
                NationalDelivery = request.NationalDelivery,
                SubRegionIds = request.SubRegionIds?.ToArray(),
                CourseWebPage = request.CourseWebPage,
                Cost = decimal.TryParse(request.Cost, out var cost) ? cost : (decimal?)null,
                CostDescription = request.CostDescription,
                Duration = request.Duration.Value,
                DurationUnit = request.DurationUnit.Value,
                StudyMode = request.StudyMode,
                AttendancePattern = request.AttendancePattern,
                VenueId = request.VenueId
            }));
Esempio n. 14
0
        public async Task <ViewModel> Handle(Query request, CancellationToken cancellationToken)
        {
            var results = await _sqlQueryDispatcher.ExecuteQuery(new GetExpiredCourseRunsForProvider()
            {
                ProviderId = _providerContextProvider.GetProviderId(),
                Today      = _clock.UtcNow.Date
            });

            var allRegions = await _regionCache.GetAllRegions();

            var allSubRegions = allRegions.SelectMany(r => r.SubRegions).ToDictionary(sr => sr.Id, sr => sr);

            return(new ViewModel()
            {
                Rows = results
                       .Select(r => new ViewModelRow()
                {
                    CourseId = r.CourseId,
                    CourseRunId = r.CourseRunId,
                    CourseName = r.CourseName,
                    ProviderCourseRef = r.ProviderCourseId,
                    LearnAimRef = r.LearnAimRef,
                    DeliveryMode = r.DeliveryMode,
                    VenueName = r.VenueName,
                    National = r.National,
                    SubRegionNames = r.SubRegionIds.Select(id => allSubRegions[id].Name).ToArray(),
                    StudyMode = r.StudyMode,
                    LearnAimRefTitle = r.LearnAimRefTitle,
                    NotionalNVQLevelv2 = r.NotionalNVQLevelv2,
                    AwardOrgCode = r.AwardOrgCode,
                    LearnAimRefTypeDesc = r.LearnAimRefTypeDesc,
                    StartDate = r.StartDate
                })
                       .ToArray(),
                Total = results.Count
            });
        }
Esempio n. 15
0
        public async Task <Success> Handle(Command request, CancellationToken cancellationToken)
        {
            ThrowIfFlowStateNotValid();

            var journeyInstance = _journeyInstanceProvider.GetInstance <AddVenueJourneyModel>();

            var venueId    = Guid.NewGuid();
            var providerId = _providerContextProvider.GetProviderId();

            await _sqlQueryDispatcher.ExecuteQuery(new CreateVenue()
            {
                VenueId          = venueId,
                ProviderId       = providerId,
                ProviderVenueRef = journeyInstance.State.ProviderVenueRef,
                Name             = journeyInstance.State.Name,
                Email            = journeyInstance.State.Email,
                Telephone        = journeyInstance.State.Telephone,
                Website          = journeyInstance.State.Website,
                AddressLine1     = journeyInstance.State.AddressLine1,
                AddressLine2     = journeyInstance.State.AddressLine2,
                Town             = journeyInstance.State.Town,
                County           = journeyInstance.State.County,
                Postcode         = journeyInstance.State.Postcode,
                Latitude         = Convert.ToDecimal(journeyInstance.State.Latitude),
                Longitude        = Convert.ToDecimal(journeyInstance.State.Longitude),
                CreatedBy        = _currentUserProvider.GetCurrentUser(),
                CreatedOn        = _clock.UtcNow
            });

            journeyInstance.UpdateState(state => state.VenueId = venueId);

            // Complete JourneyInstance so state can no longer be changed
            journeyInstance.Complete();

            return(new Success());
        }
Esempio n. 16
0
        public async Task <OneOf <UploadHasNoErrors, ViewModel> > Handle(Query request, CancellationToken cancellationToken)
        {
            var(uploadRows, uploadStatus) = await _fileUploadProcessor.GetVenueUploadRowsForProvider(
                _providerContextProvider.GetProviderId());

            if (uploadStatus == UploadStatus.ProcessedSuccessfully)
            {
                return(new UploadHasNoErrors());
            }

            return(new ViewModel()
            {
                ErrorRows = uploadRows
                            .Where(row => !row.IsValid)
                            .Select(row => new ViewModelRow()
                {
                    RowNumber = row.RowNumber,
                    ProviderVenueReference = row.ProviderVenueRef,
                    VenueName = row.VenueName,
                    AddressParts =
                        new[]
                    {
                        row.AddressLine1,
                        row.AddressLine2,
                        row.Town,
                        row.County,
                        row.Postcode
                    }
                    .Where(part => !string.IsNullOrWhiteSpace(part))
                    .ToArray(),
                    ErrorFields = row.Errors.Select(e => Core.DataManagement.Errors.MapVenueErrorToFieldGroup(e)).Distinct().ToArray(),
                    IsDeletable = row.IsDeletable
                })
                            .ToArray()
            });
        }
        public async Task <OneOf <UploadFailedResult, UploadSucceededResult> > Handle(
            Command request,
            CancellationToken cancellationToken)
        {
            var validator = new CommandValidator();
            var result    = await validator.ValidateAsync(request);

            if (!result.IsValid)
            {
                return(new UploadFailedResult(await CreateViewModel(), result));
            }

            var providerId = _providerContextProvider.GetProviderId();

            using var stream = request.File.OpenReadStream();

            var saveFileResult = await _fileUploadProcessor.SaveVenueFile(
                providerId,
                stream,
                _currentUserProvider.GetCurrentUser());

            if (saveFileResult.Status == SaveVenueFileResultStatus.InvalidFile)
            {
                return(new UploadFailedResult(
                           await CreateViewModel(),
                           "The selected file must be a CSV"));
            }
            else if (saveFileResult.Status == SaveVenueFileResultStatus.InvalidRows)
            {
                return(new UploadFailedResult(
                           await CreateViewModel(),
                           "The selected file must use the template"));
            }
            else if (saveFileResult.Status == SaveVenueFileResultStatus.InvalidHeader)
            {
                return(new UploadFailedResult(
                           await CreateViewModel(),
                           "Enter headings in the correct format",
                           saveFileResult.MissingHeaders));
            }
            else if (saveFileResult.Status == SaveVenueFileResultStatus.EmptyFile)
            {
                return(new UploadFailedResult(
                           await CreateViewModel(),
                           "The selected file is empty"));
            }
            else if (saveFileResult.Status == SaveVenueFileResultStatus.ExistingFileInFlight)
            {
                // UI Should stop us getting here so a generic error is sufficient
                throw new InvalidStateException();
            }

            Debug.Assert(saveFileResult.Status == SaveVenueFileResultStatus.Success);

            // Wait for a little bit to see if the file gets processed quickly
            // (so we can skip the In Progress UI)

            try
            {
                using var cts = new CancellationTokenSource(_optionsAccessor.Value.ProcessedImmediatelyThreshold);
                var uploadStatus = await _fileUploadProcessor.WaitForVenueProcessingToCompleteForProvider(providerId, cts.Token);

                return(uploadStatus == UploadStatus.ProcessedWithErrors ?
                       UploadSucceededResult.ProcessingCompletedWithErrors :
                       UploadSucceededResult.ProcessingCompletedSuccessfully);
            }
            catch (OperationCanceledException)
            {
                return(UploadSucceededResult.ProcessingInProgress);
            }
        }
Esempio n. 18
0
        public async Task <OneOf <UploadHasNoErrors, ViewModel> > Handle(Query request, CancellationToken cancellationToken)
        {
            var errorRows = await _fileUploadProcessor.GetCourseUploadRowsWithErrorsForProvider(
                _providerContextProvider.GetProviderId());

            if (errorRows.Count == 0)
            {
                return(new UploadHasNoErrors());
            }

            var learnAimRefs       = errorRows.Select(r => r.LearnAimRef).Distinct();
            var learningDeliveries = await _sqlQueryDispatcher.ExecuteQuery(new GetLearningDeliveries()
            {
                LearnAimRefs = learnAimRefs
            });

            return(new ViewModel()
            {
                ErrorRows = errorRows
                            .Select(r =>
                {
                    var errorsByComponent = r.Errors
                                            .Select(e => (ErrorCode: e, Field: Core.DataManagement.Errors.MapCourseErrorToFieldGroup(e)))
                                            .GroupBy(t => Core.DataManagement.Errors.GetCourseErrorComponent(t.ErrorCode))
                                            .ToDictionary(g => g.Key, g => g.Select(i => i.Field).ToArray());

                    return (
                        Row: r,
                        GroupErrorFields: errorsByComponent.GetValueOrDefault(CourseErrorComponent.Course, Array.Empty <string>()),
                        NonGroupErrorFields: errorsByComponent.GetValueOrDefault(CourseErrorComponent.CourseRun, Array.Empty <string>())
                        );
                })
                            .GroupBy(t => t.Row.CourseId)
                            .Select(g =>
                {
                    var learnAimRef = g.Select(r => r.Row.LearnAimRef).Distinct().Single();

                    return new ViewModelErrorRowGroup()
                    {
                        RowNumber = g.First().Row.RowNumber,
                        CourseId = g.Key,
                        LearnAimRef = learnAimRef,
                        LearnAimRefTitle = learningDeliveries[learnAimRef].LearnAimRefTitle,
                        CourseRows = g
                                     .Select(r => new ViewModelErrorRow()
                        {
                            RowNumber = r.Row.RowNumber,
                            CourseName = r.Row.CourseName,
                            ProviderCourseRef = r.Row.ProviderCourseRef,
                            StartDate = r.Row.StartDate,
                            VenueName = r.Row.VenueName,
                            DeliveryMode = r.Row.DeliveryMode,
                            ErrorFields = r.NonGroupErrorFields,
                            HasDeliveryModeError = r.NonGroupErrorFields.Contains("Delivery mode"),
                            HasDetailErrors = r.NonGroupErrorFields.Except(new[] { "Delivery mode" }).Any()
                        })
                                     .Where(r => r.ErrorFields.Count > 0)
                                     .OrderByDescending(r => r.ErrorFields.Contains("Delivery mode") ? 1 : 0)
                                     .ThenBy(r => r.StartDate)
                                     .ThenBy(r => r.DeliveryMode)
                                     .ToArray(),
                        ErrorFields = g.First().GroupErrorFields,
                        HasDescriptionErrors = g.First().GroupErrorFields.Any()
                    };
                })
                            .OrderByDescending(g => g.CourseRows.Any(r => r.ErrorFields.Contains("Delivery mode")) ? 1 : 0)
                            .ThenByDescending(g => g.ErrorFields.Contains("Course description") ? 1 : 0)
                            .ThenBy(g => g.LearnAimRef)
                            .ThenBy(g => g.CourseId)
                            .ToArray()
            });
Esempio n. 19
0
        public async Task <IActionResult> Index(
            Guid?courseRunId,
            string notificationTitle,
            string notificationMessage)
        {
            Session.SetString("Option", "Courses");
            int?UKPRN = Session.GetInt32("UKPRN");

            var providerId = _providerContextProvider.GetProviderId(withLegacyFallback: true);

            if (!UKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }

            var providerCourses = (await _sqlQueryDispatcher.ExecuteQuery(new GetCoursesForProvider()
            {
                ProviderId = providerId
            }))
                                  .OrderBy(c => c.LearnAimRefTypeDesc)
                                  .ThenBy(c => c.LearnAimRef)
                                  .ToArray();

            var providerVenues = await _sqlQueryDispatcher.ExecuteQuery(new GetVenuesByProvider()
            {
                ProviderId = providerId
            });

            var allRegions = _courseService.GetRegions().RegionItems;

            var model = new ProviderCoursesViewModel()
            {
                PendingCoursesCount = 0,
                ProviderCourseRuns  = new List <ProviderCourseRunViewModel>()
            };

            List <ProviderCoursesFilterItemModel> levelFilterItems          = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> deliveryModelFilterItems  = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> venueFilterItems          = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> regionFilterItems         = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> attendanceModeFilterItems = new List <ProviderCoursesFilterItemModel>();

            foreach (var course in providerCourses)
            {
                var filteredLiveCourseRuns = new List <CourseRun>();

                filteredLiveCourseRuns = course.CourseRuns.ToList();

                foreach (var cr in filteredLiveCourseRuns)
                {
                    var national = cr.DeliveryMode == CourseDeliveryMode.WorkBased & !cr.National.HasValue ||
                                   cr.National.GetValueOrDefault();

                    ProviderCourseRunViewModel courseRunModel = new ProviderCourseRunViewModel()
                    {
                        AwardOrgCode             = course.AwardOrgCode,
                        LearnAimRef              = course.LearnAimRef,
                        NotionalNVQLevelv2       = course.NotionalNVQLevelv2,
                        QualificationType        = course.LearnAimRefTitle,
                        CourseId                 = course.CourseId,
                        QualificationCourseTitle = course.LearnAimRefTypeDesc,
                        CourseRunId              = cr.CourseRunId.ToString(),
                        CourseTextId             = cr.ProviderCourseId,
                        AttendancePattern        = cr.AttendancePattern.ToDescription(),
                        Cost         = cr.Cost.HasValue ? $"£ {cr.Cost.Value:0.00}" : string.Empty,
                        CourseName   = cr.CourseName,
                        DeliveryMode = cr.DeliveryMode.ToDescription(),
                        Duration     = cr.DurationValue.HasValue
                                                        ? $"{cr.DurationValue.Value} {cr.DurationUnit.ToDescription()}"
                                                        : $"0 {cr.DurationUnit.ToDescription()}",
                        Venue = cr.VenueId.HasValue
                                                        ? FormatAddress(GetVenueByIdFrom(providerVenues, cr.VenueId.Value))
                                                        : string.Empty,
                        StartDate = cr.FlexibleStartDate
                                                        ? "Flexible start date"
                                                        : cr.StartDate?.ToString("dd MMM yyyy"),
                        StudyMode = !cr.StudyMode.HasValue
                                                        ? string.Empty
                                                        : cr.StudyMode.ToDescription(),
                        Url      = cr.CourseWebsite,
                        National = national
                    };
                    //If National
                    if (national)
                    {
                        courseRunModel.Region       = string.Join(", ", allRegions.Select(x => x.RegionName).ToList());
                        courseRunModel.RegionIdList = string.Join(", ", allRegions.Select(x => x.Id).ToList());
                    }
                    else
                    {
                        courseRunModel.Region       = cr.SubRegionIds?.Count() > 0 ? FormattedRegionsByIds(allRegions, cr.SubRegionIds) : string.Empty;
                        courseRunModel.RegionIdList = cr.SubRegionIds?.Count() > 0 ? FormattedRegionIds(allRegions, cr.SubRegionIds) : string.Empty;
                    }
                    model.ProviderCourseRuns.Add(courseRunModel);
                }
            }

            Session.SetObject("ProviderCourses", model.ProviderCourseRuns);

            int s           = 0;
            var textValue   = string.Empty;
            var levelFilter = model.ProviderCourseRuns.GroupBy(x => x.NotionalNVQLevelv2).OrderBy(x => x.Key).ToList();

            foreach (var level in levelFilter)
            {
                textValue = string.Empty;

                switch (level.Key.ToLower())
                {
                case "e":
                    textValue = "Entry level";
                    break;

                case "x":
                    textValue = "X - Not applicable/unknown";
                    break;

                case "h":
                    textValue = "Higher";
                    break;

                case "m":
                    textValue = "Mixed";
                    break;

                default:
                    textValue = "Level " + level.Key;
                    break;
                }

                ProviderCoursesFilterItemModel itemModel = new ProviderCoursesFilterItemModel()
                {
                    Id    = "level-" + s++.ToString(),
                    Value = level.Key,
                    Text  = textValue,
                    Name  = "level"
                };

                levelFilterItems.Add(itemModel);
            }

            var entryItem = levelFilterItems.Where(x => x.Text.ToLower().Contains("entry")).SingleOrDefault();

            if (entryItem != null)
            {
                levelFilterItems.Remove(entryItem);
                levelFilterItems.Insert(0, entryItem);
            }

            s = 0;
            deliveryModelFilterItems = model.ProviderCourseRuns.GroupBy(x => x.DeliveryMode).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id    = "deliverymode-" + s++.ToString(),
                Value = r.Key,
                Text  = r.Key,
                Name  = "deliverymode"
            }).ToList();

            s = 0;
            venueFilterItems = model.ProviderCourseRuns.Where(x => !string.IsNullOrEmpty(x.Venue)).GroupBy(x => x.Venue).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id    = "venue-" + s++.ToString(),
                Value = r.Key,
                Text  = r.Key,
                Name  = "venue"
            }).ToList();

            attendanceModeFilterItems = model.ProviderCourseRuns.Where(x => x.AttendancePattern != string.Empty).GroupBy(x => x.AttendancePattern).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id    = "attendancepattern-" + s++.ToString(),
                Value = r.Key,
                Text  = r.Key,
                Name  = "attendancepattern"
            }).ToList();

            List <string> allRegionsList = new List <string>();

            var regionsForCourse = model.ProviderCourseRuns.GroupBy(x => x.Region).Where(x => !string.IsNullOrEmpty(x.Key)).OrderBy(x => x.Key).ToList();

            foreach (var regions in regionsForCourse)
            {
                var regionsList = regions.Key.Split(",");
                foreach (var region in regionsList)
                {
                    allRegionsList.Add(region.Trim());
                }
            }

            allRegionsList = allRegionsList.Distinct().ToList();

            s = 0;
            foreach (var regionValue in allRegionsList)
            {
                var regionId = _courseService.GetRegions().RegionItems
                               .Where(x => string.Equals(x.RegionName, regionValue, StringComparison.CurrentCultureIgnoreCase))
                               .Select(d => d.Id).FirstOrDefault();

                var regionFilterItem = new ProviderCoursesFilterItemModel
                {
                    Value = regionId,
                    Text  = regionValue,
                    Id    = "region-" + s++,
                    Name  = "region"
                };

                regionFilterItems.Add(regionFilterItem);
            }

            var notificationCourseName = string.Empty;
            var notificationAnchorTag  = string.Empty;

            if (courseRunId.HasValue && courseRunId.Value != Guid.Empty)
            {
                model.CourseRunId = courseRunId.Value.ToString();
                bool courseRunExists = model.ProviderCourseRuns.Any(x => x.CourseRunId == courseRunId.ToString());

                if (courseRunExists == false)
                {
                    model.NotificationTitle   = notificationTitle;
                    model.NotificationMessage = notificationMessage;
                }
                else
                {
                    notificationCourseName = Regex.Replace(
                        model.ProviderCourseRuns.Where(x => x.CourseRunId == courseRunId.Value.ToString()).Select(x => x.CourseName).FirstOrDefault().ToString(), "<.*?>"
                        , String.Empty);

                    notificationAnchorTag = courseRunId.HasValue
                  ? $"<a id=\"courseeditlink\" class=\"govuk-link\" href=\"#\" data-courserunid=\"{courseRunId}\" >{notificationMessage} {notificationCourseName}</a>"
                  : $"<a id=\"courseeditlink\" class=\"govuk-link\" href=\"#\">{notificationMessage} {notificationCourseName}</a>";
                    model.NotificationTitle   = notificationTitle;
                    model.NotificationMessage = notificationAnchorTag;
                }
            }
            else
            {
                notificationTitle     = string.Empty;
                notificationAnchorTag = string.Empty;
            }



            model.HasFilters        = false;
            model.Levels            = levelFilterItems;
            model.DeliveryModes     = deliveryModelFilterItems;
            model.Venues            = venueFilterItems;
            model.AttendancePattern = attendanceModeFilterItems;
            model.Regions           = regionFilterItems;

            //Setup backlink to go to the dashboard
            ViewBag.BackLinkController = "Home";
            ViewBag.BackLinkAction     = "Index";

            return(View(model));
        }