public async Task <IActionResult> SearchResults([FromQuery] SearchResultsQuery searchQuery, string orderBy = "relevance")
        {
            //When never searched in this session
            if (string.IsNullOrWhiteSpace(SearchViewService.LastSearchParameters))
            {
                //If no compare employers in session then load employers from the cookie
                if (CompareViewService.BasketItemCount == 0)
                {
                    CompareViewService.LoadComparedEmployersFromCookie();
                }
            }

            //Clear the default back url of the employer hub pages
            EmployerBackUrl = null;
            ReportBackUrl   = null;

            // ensure parameters are valid
            if (!searchQuery.TryValidateSearchParams(out HttpStatusViewResult result))
            {
                return(result);
            }

            // generate result view model
            var             searchParams = SearchResultsQueryToEmployerSearchParameters(searchQuery);
            SearchViewModel model        = await ViewingService.SearchAsync(searchParams, orderBy);

            ViewBag.ReturnUrl = SearchViewService.GetLastSearchUrl();

            ViewBag.BasketViewModel = new CompareBasketViewModel {
                CanAddEmployers = false, CanViewCompare = CompareViewService.BasketItemCount > 1, CanClearCompare = true
            };

            return(View("Finder/SearchResults", model));
        }
Exemple #2
0
        public virtual async Task <IHttpActionResult> AutoComplete(AutoCompleteSearchViewModel request, int limit = MAXIMUM_AUTOCOMPLETE_RESULT)
        {
            var originalSearchTerms = request.Query.Trim();
            var searchTerms         = SearchTermsTransformationProvider.TransformSearchTerm(originalSearchTerms, ComposerContext.CultureInfo.Name);

            var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(searchTerms, RequestUtils.GetBaseUrl(Request).ToString(), false).ConfigureAwait(false);

            searchCriteria.NumberOfItemsPerPage = limit;

            var searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false);

            if (searchResultsViewModel.ProductSearchResults?.TotalCount == 0 && originalSearchTerms != searchTerms)
            {
                searchCriteria.Keywords = originalSearchTerms;
                searchResultsViewModel  = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false);
            }

            var vm = new AutoCompleteViewModel()
            {
                Suggestions = new List <ProductSearchViewModel>()
            };

            if (searchResultsViewModel.ProductSearchResults?.SearchResults?.Count > 0)
            {
                vm.Suggestions = searchResultsViewModel.ProductSearchResults.SearchResults.Take(limit)
                                 .Select(p => { p.SearchTerm = searchTerms; return(p); })
                                 .ToList();
            }

            return(Ok(vm));
        }
Exemple #3
0
        public virtual async Task <IHttpActionResult> SuggestCategories(AutoCompleteSearchViewModel request, int limit = MAXIMUM_CATEGORIES_SUGGESTIONS)
        {
            string language   = ComposerContext.CultureInfo.Name;
            string searchTerm = request.Query.Trim().ToLower();

            List <Category> categories = await SearchViewService.GetAllCategories();

            List <Facet> categoryCounts = await SearchViewService.GetCategoryProductCounts(language);

            List <CategorySuggestionViewModel> categorySuggestionList = new List <CategorySuggestionViewModel>();

            foreach (var category in categories)
            {
                if (!category.DisplayName.TryGetValue(language, out string displayName))
                {
                    continue;
                }

                // Find the parents of the category
                List <Category> parents     = new List <Category>();
                Category        currentNode = category;
                while (!string.IsNullOrWhiteSpace(currentNode.PrimaryParentCategoryId) && currentNode.PrimaryParentCategoryId != RootCategoryId)
                {
                    Category parent = categories.Single((cat) => cat.Id == currentNode.PrimaryParentCategoryId);
                    parents.Add(parent);
                    currentNode = parent;
                }
                parents.Reverse();

                FacetValue categoryCount = categoryCounts
                                           .Where((facet) => int.TryParse(CategoryFieldName.Match(facet.FieldName).Groups[1].Value, out int n) && parents.Count == n - 1)
                                           .FirstOrDefault()?
                                           .Values
                                           .Where((facetValue) => facetValue.Value == category.DisplayName[language]).SingleOrDefault();

                if (categoryCount != null)
                {
                    categorySuggestionList.Add(new CategorySuggestionViewModel
                    {
                        DisplayName = displayName,
                        Parents     = parents.Select((parent) => parent.DisplayName[language]).ToList(),
                        Quantity    = categoryCount.Count
                    });
                }
            }
            ;

            List <CategorySuggestionViewModel> finalSuggestions = categorySuggestionList
                                                                  .OrderByDescending((category) => category.Quantity)
                                                                  .Where((suggestion) => suggestion.DisplayName.ToLower().Contains(searchTerm))
                                                                  .Take(limit)
                                                                  .ToList();

            CategorySuggestionsViewModel vm = new CategorySuggestionsViewModel
            {
                Suggestions = finalSuggestions
            };

            return(Ok(vm));
        }
Exemple #4
0
        public async Task WHEN_one_selected_facet_SHOULD_facets_count_should_be_1()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();
            var facetName             = GetRandom.String(5);

            SetupFacets(new FacetSetting(facetName));

            // Act
            SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria
            {
                Keywords       = "any",
                CultureInfo    = new CultureInfo(CultureName),
                Scope          = Scope,
                SelectedFacets =
                {
                    new Composer.Parameters.SearchFilter {
                        Name = facetName
                    }
                }
            });

            // Assert
            model.SelectedFacets.Facets.Count.Should().Be(1);
        }
Exemple #5
0
        public void WHEN_param_is_null_SHOULD_throw_argument_null_exception()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();

            // Act & Assert
            Assert.ThrowsAsync <ArgumentNullException>(() => service.GetSearchViewModelAsync(null));
        }
Exemple #6
0
        public virtual async Task <PageHeaderViewModel> GetPageHeaderViewModelAsync(GetPageHeaderParam param)
        {
            if (param == null)
            {
                throw new ArgumentNullException(nameof(param));
            }

            return(await SearchViewService.GetPageHeaderViewModelAsync(param).ConfigureAwait(false));
        }
Exemple #7
0
        public void WHEN_scope_is_empty_SHOULD_throw_argument_exception()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();

            // Act & Assert
            Assert.ThrowsAsync <ArgumentException>(() => service.GetSearchViewModelAsync(
                                                       new SearchCriteria
            {
                Keywords    = "any",
                CultureInfo = new CultureInfo(CultureName),
                Scope       = string.Empty
            }
                                                       ));
        }
Exemple #8
0
        public void WHEN_culture_info_is_null_SHOULD_throw_argument_exception()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();

            // Act & Assert
            Assert.ThrowsAsync <ArgumentException>(() => service.GetSearchViewModelAsync(
                                                       new SearchCriteria
            {
                Keywords    = "any",
                CultureInfo = null,
                Scope       = "global"
            }
                                                       ));
        }
Exemple #9
0
        public async Task WHEN_keywords_is_not_null_or_whitespace_SHOULD_returned_model_contain_keywords()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();

            // Act
            SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria
            {
                Keywords    = "any",
                CultureInfo = new CultureInfo(CultureName),
                Scope       = Scope
            });

            // Assert
            model.Keywords.Should().Be("any");
        }
Exemple #10
0
        public async Task WHEN_keywords_is_empty_SHOULD_return_no_product()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();

            // Act
            var model = await service.GetSearchViewModelAsync(new SearchCriteria
            {
                Keywords    = string.Empty,
                CultureInfo = new CultureInfo(CultureName),
                Scope       = Scope
            });

            //Assert
            model.ProductSearchResults.TotalCount.Should().Be(0);
        }
Exemple #11
0
        public virtual async Task <IHttpActionResult> GetFacets(GetFacetsRequest request)
        {
            var queryString = HttpUtility.ParseQueryString(request.QueryString);

            var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(queryString["keywords"], RequestUtils.GetBaseUrl(Request).ToString(), true).ConfigureAwait(false);

            searchCriteria.NumberOfItemsPerPage = 0;

            searchCriteria.SelectedFacets.AddRange(SearchUrlProvider.BuildSelectedFacets(queryString));

            var searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false);

            searchResultsViewModel.ProductSearchResults.Facets = searchResultsViewModel.ProductSearchResults.Facets.Where(f => !f.FieldName.StartsWith(SearchConfiguration.CategoryFacetFiledNamePrefix)).ToList();

            return(Ok(searchResultsViewModel));
        }
Exemple #12
0
        public SearchRequestContext(
            ISearchViewService searchViewService,
            ISearchUrlProvider searchUrlProvider,
            HttpRequestBase request,
            IBaseSearchCriteriaProvider baseSearchCriteriaProvider)
        {
            SearchViewService          = searchViewService ?? throw new ArgumentNullException(nameof(searchViewService));
            SearchUrlProvider          = searchUrlProvider ?? throw new ArgumentNullException(nameof(searchUrlProvider));
            Request                    = request;
            BaseSearchCriteriaProvider = baseSearchCriteriaProvider ?? throw new ArgumentNullException(nameof(baseSearchCriteriaProvider));

            _viewModel = new Lazy <SearchViewModel>(() =>
            {
                var criteria = BuildProductsSearchCriteria();
                return(SearchViewService.GetSearchViewModelAsync(criteria).Result);
            });
        }
Exemple #13
0
        public async Task WHEN_no_selected_facet_SHOULD_returned_model_contain_no_facet()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();

            // Act
            SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria
            {
                Keywords       = "any",
                CultureInfo    = new CultureInfo(CultureName),
                Scope          = Scope,
                SelectedFacets = { }
            });

            // Assert
            model.SelectedFacets.Facets.Count.Should().Be(0);
        }
Exemple #14
0
        public SearchRequestContext(IComposerContext composerContext,
                                    ISearchViewService searchViewService,
                                    IInventoryLocationProvider inventoryLocationProvider,
                                    ISearchUrlProvider searchUrlProvider,
                                    HttpRequestBase request)
        {
            ComposerContext           = composerContext ?? throw new ArgumentNullException(nameof(composerContext));
            SearchViewService         = searchViewService ?? throw new ArgumentNullException(nameof(searchViewService));
            InventoryLocationProvider = inventoryLocationProvider ?? throw new ArgumentNullException(nameof(inventoryLocationProvider));
            SearchUrlProvider         = searchUrlProvider ?? throw new ArgumentNullException(nameof(searchUrlProvider));
            Request = request;

            _viewModel = new Lazy <SearchViewModel>(() =>
            {
                var criteria = BuildProductsSearchCriteria();
                return(SearchViewService.GetSearchViewModelAsync(criteria).Result);
            });
        }
Exemple #15
0
        public virtual async Task <IHttpActionResult> GetSearchResults(GetSearchResultsRequest request)
        {
            var queryString    = HttpUtility.ParseQueryString(request.QueryString ?? "");
            var SelectedFacets = SearchUrlProvider.BuildSelectedFacets(queryString).ToList();
            var CurrentPage    = int.TryParse(queryString[SearchRequestParams.Page], out int page) && page > 0 ? page : 1;
            var SortDirection  = queryString[SearchRequestParams.SortDirection] ?? SearchRequestParams.DefaultSortDirection;
            var SortBy         = queryString[SearchRequestParams.SortBy] ?? SearchRequestParams.DefaultSortBy;
            var BaseUrl        = RequestUtils.GetBaseUrl(Request).ToString();
            var Keywords       = queryString[SearchRequestParams.Keywords];
            BaseSearchViewModel viewModel;

            if (!string.IsNullOrEmpty(request.CategoryId))
            {
                var param = new GetCategoryBrowsingViewModelParam
                {
                    CategoryId           = request.CategoryId,
                    CategoryName         = string.Empty,
                    BaseUrl              = BaseUrl,
                    IsAllProducts        = false,
                    NumberOfItemsPerPage = SearchConfiguration.MaxItemsPerPage,
                    Page                 = CurrentPage,
                    SortBy               = SortBy,
                    SortDirection        = SortDirection,
                    InventoryLocationIds = await InventoryLocationProvider.GetInventoryLocationIdsForSearchAsync().ConfigureAwait(false),
                    SelectedFacets       = SelectedFacets,
                    CultureInfo          = ComposerContext.CultureInfo,
                };

                viewModel = await CategoryBrowsingViewService.GetCategoryBrowsingViewModelAsync(param).ConfigureAwait(false);
            }
            else
            {
                var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(Keywords, BaseUrl, true, CurrentPage).ConfigureAwait(false);

                searchCriteria.SortBy        = SortBy;
                searchCriteria.SortDirection = SortDirection;
                searchCriteria.SelectedFacets.AddRange(SelectedFacets);

                viewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false);
            }

            viewModel.ProductSearchResults.Facets = viewModel.ProductSearchResults.Facets.Where(f => !f.FieldName.StartsWith(SearchConfiguration.CategoryFacetFiledNamePrefix)).ToList();
            return(Ok(viewModel));
        }
Exemple #16
0
        public virtual async Task <IHttpActionResult> AutoComplete(AutoCompleteSearchViewModel request, int limit = MAXIMUM_AUTOCOMPLETE_RESULT)
        {
            var originalSearchTerms = request.Query.Trim();
            var searchTerms         = SearchTermsTransformationProvider.TransformSearchTerm(originalSearchTerms, ComposerContext.CultureInfo.Name);;

            var searchCriteria = new SearchCriteria
            {
                Keywords             = searchTerms,
                NumberOfItemsPerPage = limit,
                IncludeFacets        = false,
                StartingIndex        = 0,
                SortBy               = "score",
                SortDirection        = "desc",
                Page                 = 1,
                BaseUrl              = RequestUtils.GetBaseUrl(Request).ToString(),
                Scope                = ComposerContext.Scope,
                CultureInfo          = ComposerContext.CultureInfo,
                InventoryLocationIds = await InventoryLocationProvider.GetInventoryLocationIdsForSearchAsync().ConfigureAwait(false),
            };

            var searchResultsViewModel = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false);

            if (searchResultsViewModel.ProductSearchResults?.TotalCount == 0 && originalSearchTerms != searchTerms)
            {
                searchCriteria.Keywords = originalSearchTerms;
                searchResultsViewModel  = await SearchViewService.GetSearchViewModelAsync(searchCriteria).ConfigureAwait(false);
            }

            var vm = new AutoCompleteViewModel()
            {
                Suggestions = new List <ProductSearchViewModel>()
            };

            if (searchResultsViewModel.ProductSearchResults?.SearchResults?.Count > 0)
            {
                vm.Suggestions = searchResultsViewModel.ProductSearchResults.SearchResults.Take(limit)
                                 .Select(p => { p.SearchTerm = searchTerms; return(p); })
                                 .ToList();
            }

            return(Ok(vm));
        }
Exemple #17
0
        public async Task WHEN_one_selected_facet_SHOULD_facets_are_not_all_removable()
        {
            // Arrange
            SearchViewService service = _container.CreateInstance <SearchViewService>();

            // Act
            SearchViewModel model = await service.GetSearchViewModelAsync(new SearchCriteria
            {
                Keywords       = "any",
                CultureInfo    = new CultureInfo(CultureName),
                Scope          = Scope,
                SelectedFacets =
                {
                    new Composer.Parameters.SearchFilter()
                }
            });

            // Assert
            model.SelectedFacets.IsAllRemovable.Should().BeFalse();
        }
Exemple #18
0
        public virtual async Task <IHttpActionResult> GetSearchResultsBySkus(GetSearchResultsBySkusRequest request)
        {
            if (request.Skus == null)
            {
                return(BadRequest($"{nameof(request.Skus)} cannot be empty"));
            }

            var queryString    = HttpUtility.ParseQueryString(request.QueryString ?? "");
            var SelectedFacets = SearchUrlProvider.BuildSelectedFacets(queryString).ToList();
            var Keywords       = queryString[SearchRequestParams.Keywords];
            var BaseUrl        = RequestUtils.GetBaseUrl(Request).ToString();
            var IncludeFactes  = request.IncludeFacets;

            var searchCriteria = await BaseSearchCriteriaProvider.GetSearchCriteriaAsync(Keywords, BaseUrl, IncludeFactes).ConfigureAwait(false);

            var searchBySkusCriteria = new SearchBySkusCriteria
            {
                Skus                 = request.Skus,
                Keywords             = searchCriteria.Keywords,
                NumberOfItemsPerPage = request.Skus.Length,
                StartingIndex        = searchCriteria.StartingIndex,
                Page                 = searchCriteria.Page,
                BaseUrl              = searchCriteria.BaseUrl,
                Scope                = searchCriteria.Scope,
                CultureInfo          = searchCriteria.CultureInfo,
                InventoryLocationIds = searchCriteria.InventoryLocationIds,
                AvailabilityDate     = searchCriteria.AvailabilityDate,
                IncludeFacets        = searchCriteria.IncludeFacets
            };

            searchBySkusCriteria.SelectedFacets.AddRange(SelectedFacets);

            var viewModel = await SearchViewService.GetSearchViewModelAsync(searchBySkusCriteria).ConfigureAwait(false);

            if (IncludeFactes)
            {
                viewModel.ProductSearchResults.Facets = viewModel.ProductSearchResults.Facets.Where(f => !f.FieldName.StartsWith(SearchConfiguration.CategoryFacetFiledNamePrefix)).ToList();
            }

            return(Ok(viewModel));
        }
Exemple #19
0
        public virtual async Task <IHttpActionResult> SuggestBrands(AutoCompleteSearchViewModel request, int limit = MAXIMUM_BRAND_SUGGESTIONS)
        {
            string searchTerm = request.Query.Trim().ToLower();

            List <Facet> facets = await SearchViewService.GetBrandProductCounts(ComposerContext.CultureInfo.Name).ConfigureAwait(false);

            List <BrandSuggestionViewModel> brandList = facets.Single().Values.Select(facetValue => new BrandSuggestionViewModel
            {
                DisplayName = facetValue.DisplayName
            }).ToList();

            BrandSuggestionsViewModel vm = new BrandSuggestionsViewModel()
            {
                Suggestions = brandList
                              .Where((suggestion) => suggestion.DisplayName.ToLower().Contains(searchTerm))
                              .OrderBy(x => x.DisplayName)
                              .Take(limit).ToList()
            };

            return(Ok(vm));
        }
        // used to generate suggestions for the search on the landing page
        public async Task <IActionResult> SearchResultsJs([FromQuery] SearchResultsQuery searchQuery)
        {
            //Clear the default back url of the employer hub pages
            EmployerBackUrl = null;
            ReportBackUrl   = null;


            // ensure parameters are valid
            if (!searchQuery.TryValidateSearchParams(out HttpStatusViewResult result))
            {
                return(result);
            }

            // generate result view model
            var             searchParams = SearchResultsQueryToEmployerSearchParameters(searchQuery);
            SearchViewModel model        = await ViewingService.SearchAsync(searchParams, "relevance");

            ViewBag.ReturnUrl = SearchViewService.GetLastSearchUrl();

            return(PartialView("Finder/Parts/MainContent", model));
        }
        public IActionResult Employer(string employerIdentifier)
        {
            if (string.IsNullOrWhiteSpace(employerIdentifier))
            {
                return(new HttpBadRequestResult("Missing employer identifier"));
            }

            CustomResult <Organisation> organisationLoadingOutcome;

            try
            {
                organisationLoadingOutcome = OrganisationBusinessLogic.LoadInfoFromActiveEmployerIdentifier(employerIdentifier);

                if (organisationLoadingOutcome.Failed)
                {
                    return(organisationLoadingOutcome.ErrorMessage.ToHttpStatusViewResult());
                }
            }
            catch (Exception ex)
            {
                CustomLogger.Error($"Cannot decrypt return employerIdentifier from '{employerIdentifier}'", ex);
                return(View("CustomError", new ErrorViewModel(400)));
            }

            //Clear the default back url of the report page
            ReportBackUrl = null;

            ViewBag.BasketViewModel = new CompareBasketViewModel {
                CanAddEmployers = true, CanViewCompare = true
            };

            return(View(
                       "EmployerDetails/Employer",
                       new EmployerDetailsViewModel {
                Organisation = organisationLoadingOutcome.Result,
                LastSearchUrl = SearchViewService.GetLastSearchUrl(),
                EmployerBackUrl = EmployerBackUrl,
                ComparedEmployers = CompareViewService.ComparedEmployers.Value
            }));
        }
Exemple #22
0
        public async Task <IActionResult> Step1Task2([FromQuery] SearchResultsQuery searchQuery, string orderBy = "relevance")
        {
            if (FeatureFlagHelper.IsFeatureEnabled(FeatureFlag.ReportingStepByStep))
            {
                //When never searched in this session
                if (string.IsNullOrWhiteSpace(SearchViewService.LastSearchParameters))
                {
                    //If no compare employers in session then load employers from the cookie
                    if (CompareViewService.BasketItemCount == 0)
                    {
                        CompareViewService.LoadComparedEmployersFromCookie();
                    }
                }

                // ensure parameters are valid
                if (!searchQuery.TryValidateSearchParams(out HttpStatusViewResult result))
                {
                    return(result);
                }

                // generate result view model
                var             searchParams = SearchResultsQueryToEmployerSearchParameters(searchQuery);
                SearchViewModel model        = await ViewingService.SearchAsync(searchParams, orderBy);

                ViewBag.ReturnUrl = SearchViewService.GetLastSearchUrl();

                ViewBag.BasketViewModel = new CompareBasketViewModel {
                    CanAddEmployers = false, CanViewCompare = CompareViewService.BasketItemCount > 1, CanClearCompare = true
                };
                return(View("../ReportingStepByStep/Step1Task2", model));
            }
            else
            {
                return(new HttpNotFoundResult());
            }
        }
        public IActionResult CompareEmployers(int year, string employers = null)
        {
            if (year == 0)
            {
                CompareViewService.SortColumn    = null;
                CompareViewService.SortAscending = true;
                year = ReportingYearsHelper.GetTheMostRecentCompletedReportingYear();
            }

            //Load employers from querystring (via shared email)
            if (!string.IsNullOrWhiteSpace(employers))
            {
                string[] comparedEmployers = employers.SplitI("-");
                if (comparedEmployers.Any())
                {
                    CompareViewService.ClearBasket();
                    CompareViewService.AddRangeToBasket(comparedEmployers);
                    CompareViewService.SortAscending = true;
                    CompareViewService.SortColumn    = null;
                    return(RedirectToAction("CompareEmployers", new { year }));
                }
            }

            //If the session is lost then load employers from the cookie
            else if (CompareViewService.BasketItemCount == 0)
            {
                CompareViewService.LoadComparedEmployersFromCookie();
            }

            ViewBag.ReturnUrl = Url.Action("CompareEmployers", new { year });

            //Clear the default back url of the employer hub pages
            EmployerBackUrl = null;
            ReportBackUrl   = null;

            //Get the compare basket organisations
            IEnumerable <CompareReportModel> compareReports = OrganisationBusinessLogic.GetCompareData(
                CompareViewService.ComparedEmployers.Value.AsEnumerable(),
                year,
                CompareViewService.SortColumn,
                CompareViewService.SortAscending);

            //Track the compared employers
            string lastComparedEmployerList = CompareViewService.ComparedEmployers.Value.ToList().ToSortedSet().ToDelimitedString();

            if (CompareViewService.LastComparedEmployerList != lastComparedEmployerList && IsAction("CompareEmployers"))
            {
                SortedSet <string> employerIds = compareReports.Select(r => r.EncOrganisationId).ToSortedSet();
                WebTracker.TrackPageView(
                    this,
                    $"compare-employers: {employerIds.ToDelimitedString()}",
                    $"{ViewBag.ReturnUrl}?{employerIds.ToEncapsulatedString("e=", null, "&", "&", false)}");
                foreach (CompareReportModel employer in compareReports)
                {
                    WebTracker.TrackPageView(
                        this,
                        $"{employer.EncOrganisationId}: {employer.OrganisationName}",
                        $"{ViewBag.ReturnUrl}?{employer.EncOrganisationId}={employer.OrganisationName}");
                }

                CompareViewService.LastComparedEmployerList = lastComparedEmployerList;
            }

            //Generate the shared links
            string shareEmailUrl = Url.Action(
                nameof(CompareEmployers),
                "Compare",
                new { year, employers = CompareViewService.ComparedEmployers.Value.ToList().ToDelimitedString("-") },
                Request.Scheme);

            ViewBag.BasketViewModel = new CompareBasketViewModel {
                CanAddEmployers = true, CanViewCompare = false, CanClearCompare = true
            };

            return(View(
                       "CompareEmployers",
                       new CompareViewModel {
                LastSearchUrl = SearchViewService.GetLastSearchUrl(),
                CompareReports = compareReports,
                CompareBasketCount = CompareViewService.BasketItemCount,
                ShareEmailUrl =
                    CompareViewService.BasketItemCount <= CompareViewService.MaxCompareBasketShareCount ? shareEmailUrl : null,
                Year = year,
                SortAscending = CompareViewService.SortAscending,
                SortColumn = CompareViewService.SortColumn
            }));
        }