示例#1
0
        public async Task <IActionResult> FindNonRegulated(UnRegulatedSearchViewModel request)
        {
            if (request == null)
            {
                return(BadRequest());
            }

            var result = await _searchClient.Search(new LarsLearnAimRefSearchQuery
            {
                LearnAimRef = request.Search,
                CertificationEndDateFilter = DateTimeOffset.UtcNow
            });

            if (!result.Items.Any())
            {
                return(ViewComponent(nameof(ZCodeFoundResult), new ZCodeFoundResultModel()));
            }

            var foundResult = result.Items.Select(r => r.Record).First();

            return(ViewComponent(nameof(ZCodeFoundResult), new ZCodeFoundResultModel
            {
                AwardOrgCode = foundResult.AwardOrgCode,
                AwardOrgName = foundResult.AwardOrgName,
                LearnAimRef = foundResult.LearnAimRef,
                LearnAimRefTitle = foundResult.LearnAimRefTitle,
                LearnAimRefTypeDesc = foundResult.LearnAimRefTypeDesc,
                NotionalNVQLevelv2 = foundResult.NotionalNVQLevelv2
            }));
        }
示例#2
0
        private async Task <SearchResults> SearchCore(SearchFilter filter, bool raw)
        {
            // Query!
            var result = await _searchClient.Search(
                filter.SearchTerm,
                projectTypeFilter : null,
                includePrerelease : filter.IncludePrerelease,
                packageType : filter.PackageType,
                sortBy : filter.SortOrder,
                skip : filter.Skip,
                take : filter.Take,
                isLuceneQuery : raw,
                countOnly : filter.CountOnly,
                explain : false,
                getAllVersions : filter.IncludeAllVersions,
                supportedFramework : filter.SupportedFramework,
                semVerLevel : filter.SemVerLevel,
                includeTestData : filter.IncludeTestData);

            SearchResults results = null;

            if (result.IsSuccessStatusCode)
            {
                var content = await result.ReadContent();

                if (content == null)
                {
                    results = new SearchResults(0, null, Enumerable.Empty <Package>().AsQueryable());
                }
                else if (filter.CountOnly || content.TotalHits == 0)
                {
                    results = new SearchResults(content.TotalHits, content.IndexTimestamp);
                }
                else
                {
                    results = new SearchResults(
                        content.TotalHits,
                        content.IndexTimestamp,
                        content.Data.Select(x => ReadPackage(x, filter.SemVerLevel)).AsQueryable());
                }
            }
            else
            {
                if (result.HttpResponse.Content != null)
                {
                    result.HttpResponse.Content.Dispose();
                }

                results = new SearchResults(0, null, Enumerable.Empty <Package>().AsQueryable(), responseMessage: result.HttpResponse);
            }

            return(results);
        }
        public async Task <IActionResult> Index([FromQuery] string keyword)
        {
            if (Session.GetInt32("UKPRN").HasValue)
            {
                Session.Remove("UKPRN");
            }

            if (string.IsNullOrWhiteSpace(keyword))
            {
                return(View(SearchProviderResultsViewModel.Empty()));
            }

            var result = await _searchClient.Search(new ProviderSearchQuery
            {
                SearchText = keyword
            });

            return(View(new SearchProviderResultsViewModel
            {
                Search = keyword,
                Providers = result.Results.Select(SearchProviderResultViewModel.FromProvider)
            }));
        }
示例#4
0
        public SearchResponse <QuerySuggesterDocument> TermSearch(string term, int page, int pagesize = 100)
        {
            var req = new SearchRequest()
            {
                QueryText   = "*:*",
                PageSize    = pagesize,
                CurrentPage = page,
                Sort        = new List <SortOrder>()
                {
                    new SortOrder("title", SortOrder.SortOption.Ascending),
                },
            };

            if (!string.IsNullOrEmpty(term))
            {
                req.QueryOptions.Add(new FilterQuery("title", FilterQuery.ConditionalTypes.Contains, term.Trim().ToLower()));
            }

            var resp = SrchClient.Search(req);

            return(resp);
            //return resp.Results
            //  .Select(r => r.title).ToList();
        }
        private async Task <Onspd> GetOnsPostcodeData(string postcode)
        {
            if (string.IsNullOrWhiteSpace(postcode))
            {
                return(new Onspd());
            }

            var searchResult = await _searchClient.Search(new OnspdSearchQuery
            {
                Postcode = postcode
            });

            return(searchResult.Results.Count > 0
                ? searchResult.Results.Single().Adapt <Onspd>()
                : new Onspd());
        }
        private async Task <(float lat, float lng)?> TryGetCoordinatesForPostcode(Postcode postcode)
        {
            var result = await _onspdSearchClient.Search(new OnspdSearchQuery()
            {
                Postcode = postcode
            });

            var doc = result.Items.SingleOrDefault();

            if (doc != null)
            {
                return((float)doc.Record.lat, (float)doc.Record.@long);
            }

            return(null);
        }
示例#7
0
        public async Task <ViewModel> Handle(Query request, CancellationToken cancellationToken)
        {
            // When no search query is in the request return null Providers so we don't show the results table
            if (request.SearchQuery == null)
            {
                return(new ViewModel
                {
                    ProviderSearchResults = null
                });
            }

            // Return empty results when they search query is empty or whitespace
            if (string.IsNullOrWhiteSpace(request.SearchQuery))
            {
                return(new ViewModel
                {
                    ProviderSearchResults = Array.Empty <ProviderSearchResultViewModel>()
                });
            }

            var result = await _providerSearchClient.Search(new ProviderSearchQuery
            {
                SearchText = request.SearchQuery
            });

            return(new ViewModel
            {
                ProviderSearchResults = result.Items.Select(r => r.Record).Select(p => new ProviderSearchResultViewModel
                {
                    ProviderId = p.ProviderId,
                    Name = p.ProviderName,
                    Postcode = p.Postcode,
                    Town = p.Town,
                    Ukprn = p.Ukprn,
                    Status = (ProviderStatus)p.ProviderStatus,
                    ProviderStatus = p.UkrlpProviderStatusDescription
                }).ToArray()
            });
        }
示例#8
0
        public async Task <IActionResult> Larsless()
        {
            var larlessErrors         = new Dictionary <string, string>();
            var ukprn                 = Session.GetInt32("UKPRN");
            var courseMigrationReport = await _courseService.GetCourseMigrationReport(ukprn.Value);

            if (!courseMigrationReport.IsSuccess)
            {
                throw new Exception(courseMigrationReport.Error + $"For UKPRN: {ukprn}");
            }

            var venues = await VenueHelper.GetVenueNames(courseMigrationReport.Value.LarslessCourses, _cosmosDbQueryDispatcher);

            var model = new LarslessViewModel
            {
                LarslessCourses = courseMigrationReport.Value
                                  .LarslessCourses
                                  .OrderBy(x => x.QualificationCourseTitle),
                Venues = venues
            };

            var errors         = new List <string>();
            var totalErrorList = new List <int>();

            var cachedQuals = new List <Lars>();

            foreach (var bulkUploadcourse in model.LarslessCourses)
            {
                if (!string.IsNullOrEmpty(bulkUploadcourse.LearnAimRef))
                {
                    var cachedResult = cachedQuals.FirstOrDefault(o => o.LearnAimRef == bulkUploadcourse.LearnAimRef);

                    List <Lars> results = null;

                    if (cachedResult == null)
                    {
                        results = _larsSearchClient.Search(new LarsLearnAimRefSearchQuery
                        {
                            LearnAimRef = bulkUploadcourse.LearnAimRef
                        }).GetAwaiter().GetResult().Items.Select(r => r.Record).ToList();

                        var qual = results.FirstOrDefault();

                        if (qual != null)
                        {
                            cachedQuals.Add(qual);
                        }
                    }
                    else
                    {
                        results = new List <Lars> {
                            cachedQuals.FirstOrDefault(o => o.LearnAimRef == bulkUploadcourse.LearnAimRef)
                        };
                    }

                    if (results.Count > 0)
                    {
                        if (results[0].CertificationEndDate != null && results[0].CertificationEndDate < DateTime.Now)
                        {
                            larlessErrors.Add(bulkUploadcourse.CourseId.Value.ToString(), "Expired LARS Code " + bulkUploadcourse.LearnAimRef);
                        }
                    }
                    else
                    {
                        larlessErrors.Add(bulkUploadcourse.CourseId.Value.ToString(), "Unrecognised LARS Code " + bulkUploadcourse.LearnAimRef);
                    }
                }
                else
                {
                    larlessErrors.Add(bulkUploadcourse.CourseId.Value.ToString(), "Missing LARS");
                }
            }

            model.Errors = larlessErrors;
            return(View("Report/larsless", model));
        }
示例#9
0
 public SearchResult <T> Search()
 {
     return(Source.Search());
 }
 public IEnumerable <string> Get(string keyword)
 {
     return(indexClient.Search(keyword));
 }
示例#11
0
        public async Task <IActionResult> Index([FromQuery] LarsSearchRequestModel request)
        {
            if (request == null)
            {
                return(BadRequest());
            }

            var results = await Task.WhenAll(
                // There's not currently support for multi-select faceted search, so we need to get all the results for the search term before filtering on facets.
                _searchClient.Search(new LarsSearchQuery
            {
                SearchText = request.SearchTerm,
                CertificationEndDateFilter = DateTimeOffset.UtcNow,
                Facets   = new[] { nameof(Lars.AwardOrgCode), nameof(Lars.NotionalNVQLevelv2) },
                PageSize = 0
            }),
                _searchClient.Search(new LarsSearchQuery
            {
                SearchText = request.SearchTerm,
                NotionalNVQLevelv2Filters  = request.NotionalNVQLevelv2Filter,
                AwardOrgCodeFilters        = request.AwardOrgCodeFilter,
                AwardOrgAimRefFilters      = request.AwardOrgAimRefFilter,
                CertificationEndDateFilter = DateTimeOffset.UtcNow,
                Facets     = new[] { nameof(Lars.AwardOrgCode), nameof(Lars.NotionalNVQLevelv2) },
                PageSize   = _larsSearchSettings.ItemsPerPage,
                PageNumber = request.PageNo
            }));

            var unfilteredResult = results[0];
            var result           = results[1];

            var viewModel = new LarsSearchResultModel
            {
                SearchTerm = request.SearchTerm,
                Items      = result.Items.Select(r => r.Record).Select(LarsSearchResultItemModel.FromLars),
                Filters    = new[]
                {
                    new LarsSearchFilterModel
                    {
                        Title = "Qualification level",
                        Items = unfilteredResult.Facets[nameof(Lars.NotionalNVQLevelv2)]
                                .Select((f, i) =>
                                        new LarsSearchFilterItemModel
                        {
                            Id         = $"{nameof(LarsSearchRequestModel.NotionalNVQLevelv2Filter)}-{i}",
                            Name       = nameof(LarsSearchRequestModel.NotionalNVQLevelv2Filter),
                            Text       = LarsSearchFilterItemModel.FormatAwardOrgCodeSearchFilterItemText(f.Key.ToString()),
                            Value      = f.Key.ToString(),
                            Count      = (int)(f.Value ?? 0),
                            IsSelected = request.NotionalNVQLevelv2Filter.Contains(f.Key.ToString())
                        })
                                .OrderBy(f => f.Text).ToArray()
                    },
                    new LarsSearchFilterModel
                    {
                        Title = "Awarding organisation",
                        Items = unfilteredResult.Facets[nameof(Lars.AwardOrgCode)]
                                .Select((f, i) =>
                                        new LarsSearchFilterItemModel
                        {
                            Id         = $"{nameof(LarsSearchRequestModel.AwardOrgCodeFilter)}-{i}",
                            Name       = nameof(LarsSearchRequestModel.AwardOrgCodeFilter),
                            Text       = f.Key.ToString(),
                            Value      = f.Key.ToString(),
                            Count      = (int)(f.Value ?? 0),
                            IsSelected = request.AwardOrgCodeFilter.Contains(f.Key.ToString())
                        })
                                .OrderBy(f => f.Text).ToArray()
                    }
                },
                TotalCount    = (int)(result.TotalCount ?? 0),
                PageNumber    = request.PageNo,
                ItemsPerPage  = _larsSearchSettings.ItemsPerPage,
                PageParamName = _larsSearchSettings.PageParamName,
                Url           = Request.GetDisplayUrl()
            };

            return(ViewComponent(nameof(LarsSearchResult), viewModel));
        }
        public List <BulkUploadCourse> PolulateLARSData(List <BulkUploadCourse> bulkUploadcourses, out List <string> errors)
        {
            errors = new List <string>();
            var totalErrorList = new List <int>();

            var cachedQuals = new List <Lars>();

            foreach (var bulkUploadcourse in bulkUploadcourses.Where(c => c.IsCourseHeader == true))
            {
                var cachedResult = cachedQuals.FirstOrDefault(o => o.LearnAimRef == bulkUploadcourse.LearnAimRef);

                List <Lars> results = null;

                if (cachedResult == null)
                {
                    results = _larsSearchClient.Search(new LarsLearnAimRefSearchQuery
                    {
                        LearnAimRef = bulkUploadcourse.LearnAimRef
                    }).GetAwaiter().GetResult().Results.ToList();

                    var qual = results.FirstOrDefault();

                    if (qual != null)
                    {
                        cachedQuals.Add(qual);
                    }
                }
                else
                {
                    results = new List <Lars> {
                        cachedQuals.FirstOrDefault(o => o.LearnAimRef == bulkUploadcourse.LearnAimRef)
                    };
                }

                if (results.Count > 0)
                {
                    if (results.Count.Equals(0))
                    {
                        List <int> invalidLARSLineNumbers = bulkUploadcourses.Where(c => c.LearnAimRef == bulkUploadcourse.LearnAimRef).Select(l => l.BulkUploadLineNumber).ToList();

                        invalidLARSLineNumbers = CheckForErrorDuplicates(ref totalErrorList, invalidLARSLineNumbers);

                        if (invalidLARSLineNumbers.Count > 0)
                        {
                            errors.Add($"{ InvalidLARSLineNumbersToString(invalidLARSLineNumbers) }, " + $"LARS_QAN = { bulkUploadcourse.LearnAimRef } invalid LARS");
                        }
                    }
                    else if (results.Count.Equals(1))
                    {
                        if (results[0].CertificationEndDate != null && results[0].CertificationEndDate < DateTime.Now)
                        {
                            List <int> invalidLARSLineNumbers = bulkUploadcourses.Where(c => c.LearnAimRef == bulkUploadcourse.LearnAimRef).Select(l => l.BulkUploadLineNumber).ToList();

                            invalidLARSLineNumbers = CheckForErrorDuplicates(ref totalErrorList, invalidLARSLineNumbers);

                            if (invalidLARSLineNumbers.Count > 0)
                            {
                                errors.Add($"{ InvalidLARSLineNumbersToString(invalidLARSLineNumbers) }, LARS_QAN = { bulkUploadcourse.LearnAimRef } expired LARS");
                            }
                        }
                        else
                        {
                            bulkUploadcourse.QualificationCourseTitle = results[0].LearnAimRefTitle;
                            bulkUploadcourse.NotionalNVQLevelv2       = results[0].NotionalNVQLevelv2;
                            bulkUploadcourse.AwardOrgCode             = results[0].AwardOrgCode;
                            bulkUploadcourse.QualificationType        = results[0].LearnAimRefTypeDesc;
                        }
                    }
                    else
                    {
                        string logMoreQualifications = string.Empty;
                        foreach (var qualification in results)
                        {
                            logMoreQualifications += "( '" + qualification.LearnAimRefTitle + "' with Level " + qualification.NotionalNVQLevelv2 + " and AwardOrgCode " + qualification.AwardOrgCode + " ) ";
                        }
                        errors.Add($"We retrieve multiple qualifications ( { results.Count } ) for the LARS { bulkUploadcourse.LearnAimRef }, which are { logMoreQualifications } ");
                    }
                }
                else
                {
                    errors.Add($"Line {bulkUploadcourse.BulkUploadLineNumber}, LARS_QAN = { bulkUploadcourse.LearnAimRef }, invalid LARS");
                }
            }

            return(bulkUploadcourses);
        }
        private async Task <SearchResults> SearchCore(SearchFilter filter, bool raw)
        {
            // Query!
            var sw = new Stopwatch();

            sw.Start();
            var result = await _searchClient.Search(
                filter.SearchTerm,
                projectTypeFilter : null,
                includePrerelease : filter.IncludePrerelease,
                sortBy : filter.SortOrder,
                skip : filter.Skip,
                take : filter.Take,
                isLuceneQuery : raw,
                countOnly : filter.CountOnly,
                explain : false,
                getAllVersions : filter.IncludeAllVersions,
                supportedFramework : filter.SupportedFramework,
                semVerLevel : filter.SemVerLevel);

            sw.Stop();

            SearchResults results = null;

            if (result.IsSuccessStatusCode)
            {
                var content = await result.ReadContent();

                if (content == null)
                {
                    results = new SearchResults(0, null, Enumerable.Empty <Package>().AsQueryable());
                }
                else if (filter.CountOnly || content.TotalHits == 0)
                {
                    results = new SearchResults(content.TotalHits, content.IndexTimestamp);
                }
                else
                {
                    results = new SearchResults(
                        content.TotalHits,
                        content.IndexTimestamp,
                        content.Data.Select(x => ReadPackage(x, filter.SemVerLevel)).AsQueryable());
                }
            }
            else
            {
                if (result.HttpResponse.Content != null)
                {
                    result.HttpResponse.Content.Dispose();
                }

                results = new SearchResults(0, null, Enumerable.Empty <Package>().AsQueryable(), responseMessage: result.HttpResponse);
            }

            Trace.PerfEvent(
                SearchRoundtripTimePerfCounter,
                sw.Elapsed,
                new Dictionary <string, object>()
            {
                { "Term", filter.SearchTerm },
                { "Context", filter.Context },
                { "Raw", raw },
                { "Hits", results == null ? -1 : results.Hits },
                { "StatusCode", (int)result.StatusCode },
                { "SortOrder", filter.SortOrder.ToString() },
                { "Url", TryGetUrl() }
            });

            return(results);
        }
示例#14
0
        public async Task <OneOf <ProblemDetails, SearchViewModel> > Handle(Query request, CancellationToken cancellationToken)
        {
            var filters = new List <string>();

            // If either lat or lng is specified then both must be specified
            if (request.Latitude.HasValue != request.Longitude.HasValue)
            {
                return(new ProblemDetails()
                {
                    Detail = "Latitude & longitude must both be specified.",
                    Status = 400,
                    Title = "InvalidLatLng"
                });
            }

            if (request.SortBy == SearchSortBy.Distance &&
                (string.IsNullOrWhiteSpace(request.Postcode) && (!request.Latitude.HasValue || !request.Longitude.HasValue)))
            {
                return(new ProblemDetails()
                {
                    Detail = "Postcode is required to sort by Distance.",
                    Status = 400,
                    Title = "PostcodeRequired"
                });
            }

            Postcode postcode = null;

            if (!string.IsNullOrWhiteSpace(request.Postcode))
            {
                if (!Postcode.TryParse(request.Postcode, out postcode))
                {
                    return(new ProblemDetails()
                    {
                        Detail = "Postcode is not valid.",
                        Status = 400,
                        Title = "InvalidPostcode"
                    });
                }
            }

            var geoFilterRequired = request.Distance.GetValueOrDefault(0) > 0 &&
                                    (postcode != null || (request.Latitude.HasValue && request.Longitude.HasValue));

            // lat/lng required if Distance filter is specified *or* sorting by Distance
            var    getPostcodeCoords = (geoFilterRequired || request.SortBy == SearchSortBy.Distance) && !request.Latitude.HasValue;
            double?latitude          = request.Latitude;
            double?longitude         = request.Longitude;

            if (getPostcodeCoords)
            {
                var coords = await TryGetCoordinatesForPostcode(postcode);

                if (!coords.HasValue)
                {
                    return(new ProblemDetails()
                    {
                        Detail = "Specified postcode cannot be found.",
                        Status = 400,
                        Title = "PostcodeNotFound"
                    });
                }

                latitude  = coords.Value.lat;
                longitude = coords.Value.lng;
            }

            if (request.StartDateFrom.HasValue ||
                request.StartDateTo.HasValue ||
                request.HideOutOfDateCourses.HasValue ||
                request.HideFlexiCourses.HasValue)
            {
                var dateFilter = TryGetDateFilters(
                    request.StartDateFrom,
                    request.StartDateTo,
                    request.HideOutOfDateCourses,
                    request.HideFlexiCourses);

                if (!string.IsNullOrEmpty(dateFilter))
                {
                    filters.Add(dateFilter);
                }
            }

            if (request.AttendancePatterns?.Any() ?? false)
            {
                // TODO Validate AttendancePatterns? Consider using enum instead of int

                filters.Add($"({string.Join(" or ", request.AttendancePatterns.Select(ap => $"{nameof(FindACourseOffering.AttendancePattern)} eq {ap}"))} or {nameof(FindACourseOffering.DeliveryMode)} ne {(int)CourseDeliveryMode.ClassroomBased})");
            }

            if (request.QualificationLevels?.Any() ?? false)
            {
                // TODO Validate QualificationLevels?

                filters.Add($"search.in({nameof(FindACourseOffering.NotionalNVQLevelv2)}, '{string.Join("|", request.QualificationLevels.Select(EscapeFilterValue))}', '|')");
            }

            if (geoFilterRequired)
            {
                var distanceInKm = Convert.ToDecimal(GeoHelper.MilesToKilometers(request.Distance.Value));

                filters.Add(
                    $"(geo.distance({nameof(FindACourseOffering.Position)}, geography'POINT({longitude.Value} {latitude.Value})') le {distanceInKm}" +
                    $" or {nameof(FindACourseOffering.National)} eq true" +
                    $" or {nameof(FindACourseOffering.DeliveryMode)} eq 2)");
            }

            if (!string.IsNullOrWhiteSpace(request.Town))
            {
                filters.Add($"search.ismatch('{EscapeFilterValue(request.Town)}', '{nameof(FindACourseOffering.VenueTown)}')");
            }

            if (request.StudyModes?.Any() ?? false)
            {
                filters.Add($"({string.Join(" or ", request.StudyModes.Select(sm => $"{nameof(FindACourseOffering.StudyMode)} eq {sm}"))} or {nameof(FindACourseOffering.DeliveryMode)} ne {(int)CourseDeliveryMode.ClassroomBased})");
            }

            if (request.DeliveryModes?.Any() ?? false)
            {
                filters.Add($"({string.Join(" or ", request.DeliveryModes.Select(dm => $"{nameof(FindACourseOffering.DeliveryMode)} eq {dm}"))})");
            }

            if (!string.IsNullOrWhiteSpace(request.ProviderName))
            {
                filters.Add($"search.ismatchscoring('{EscapeFilterValue(request.ProviderName)}', '{nameof(FindACourseOffering.ProviderDisplayName)}', 'simple', 'any')");
            }

            if (!string.IsNullOrWhiteSpace(request.CampaignCode))
            {
                filters.Add($"{nameof(FindACourseOffering.CampaignCodes)}/any(c: c eq '{EscapeFilterValue(request.CampaignCode)}')");
            }

            var orderBy = request.SortBy == SearchSortBy.StartDateDescending ?
                          "StartDate desc" : request.SortBy == SearchSortBy.StartDateAscending ?
                          "StartDate asc" : request.SortBy == SearchSortBy.Distance ?
                          $"geo.distance({nameof(FindACourseOffering.Position)}, geography'POINT({longitude.Value} {latitude.Value})')" :
                          "search.score() desc";

            if (!TryResolvePagingParams(request.Limit, request.Start, out var size, out var skip, out var problem))
            {
                return(problem);
            }

            var searchText = TranslateCourseSearchSubjectText(request.SubjectKeyword);

            var query = new FindACourseOfferingSearchQuery()
            {
                Facets = new[]
                {
                    "NotionalNVQLevelv2,count:100",
                    "StudyMode",
                    "AttendancePattern",
                    "DeliveryMode",
                    "ProviderDisplayName,count:100",
                    "RegionName,count:100"
                },
                Filters    = filters,
                CourseName = searchText,
                Size       = size,
                Skip       = skip,
                OrderBy    = orderBy
            };

            var result = await _courseSearchClient.Search(query);

            return(new SearchViewModel()
            {
                Limit = size,
                Start = skip,
                Total = Convert.ToInt32(result.TotalCount.Value),
                Facets = result.Facets.ToDictionary(
                    f => _courseSearchFacetMapping.GetValueOrDefault(f.Key, f.Key),
                    f => f.Value.Select(v => new FacetCountResultViewModel()
                {
                    Value = v.Key.ToString(),
                    Count = v.Value.Value
                })),
                Results = result.Items.Select(i =>
                {
                    return new SearchResultViewModel()
                    {
                        Cost = !string.IsNullOrEmpty(i.Record.Cost) ?
                               Convert.ToInt32(decimal.Parse(i.Record.Cost)) :
                               (int?)null,
                        CostDescription = HtmlEncode(i.Record.CostDescription),
                        CourseDescription = HtmlEncode(NormalizeCourseDataEncodedString(i.Record.CourseDescription)),
                        CourseName = NormalizeCourseRunDataEncodedString(i.Record.CourseName),
                        CourseId = i.Record.CourseId,
                        CourseRunId = i.Record.CourseRunId,
                        CourseText = HtmlEncode(NormalizeCourseDataEncodedString(i.Record.CourseDescription)),
                        DeliveryMode = ((int)i.Record.DeliveryMode).ToString(),
                        DeliveryModeDescription = (i.Record.DeliveryMode.GetValueOrDefault(0)).ToDescription(),
                        Distance = GetDistanceFromLatLngForResult(i),
                        DurationUnit = i.Record.DurationUnit ?? 0,
                        DurationValue = i.Record.DurationValue,
                        FlexibleStartDate = i.Record.FlexibleStartDate,
                        LearnAimRef = i.Record.LearnAimRef,
                        National = i.Record.National,
                        QualificationLevel = i.Record.NotionalNVQLevelv2,
                        OfferingType = i.Record.OfferingType,
                        ProviderName = i.Record.ProviderDisplayName,
                        QualificationCourseTitle = HtmlEncode(i.Record.QualificationCourseTitle),
                        Region = i.Record.RegionName,
                        SearchScore = i.Score.Value,
                        StartDate = !i.Record.FlexibleStartDate.GetValueOrDefault() ? i.Record.StartDate : null,
                        TLevelId = i.Record.TLevelId,
                        TLevelLocationId = i.Record.TLevelLocationId,
                        Ukprn = i.Record.ProviderUkprn.ToString(),
                        UpdatedOn = i.Record.UpdatedOn,
                        VenueAddress = HtmlEncode(i.Record.VenueAddress),
                        VenueAttendancePattern = ((int?)i.Record.AttendancePattern)?.ToString(),
                        VenueAttendancePatternDescription = i.Record.DeliveryMode == CourseDeliveryMode.ClassroomBased ?
                                                            i.Record.AttendancePattern?.ToDescription() :
                                                            null,
                        VenueLocation = i.Record.Position != null ?
                                        new CoordinatesViewModel()
                        {
                            Latitude = i.Record.Position.Latitude,
                            Longitude = i.Record.Position.Longitude
                        } :
                        null,
                        VenueName = HtmlEncode(i.Record.VenueName),
                        VenueStudyMode = ((int?)i.Record.StudyMode)?.ToString(),
                        VenueStudyModeDescription = i.Record.DeliveryMode == CourseDeliveryMode.ClassroomBased ?
                                                    i.Record.StudyMode?.ToDescription() :
                                                    null,
                        VenueTown = HtmlEncode(i.Record.VenueTown)
                    };
        public async Task <OneOf <NotFound, CourseRunDetailViewModel> > Handle(Query request, CancellationToken cancellationToken)
        {
            var course = await _sqlQueryDispatcher.ExecuteQuery(new GetCourse()
            {
                CourseId = request.CourseId
            });

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

            var courseRun = course.CourseRuns.SingleOrDefault(c => c.CourseRunId == request.CourseRunId && c.CourseRunStatus == CourseStatus.Live);

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

            var getProvider = _cosmosDbQueryDispatcher.ExecuteQuery(new Core.DataStore.CosmosDb.Queries.GetProviderByUkprn {
                Ukprn = course.ProviderUkprn
            });
            var getQualification = _larsSearchClient.Search(new LarsLearnAimRefSearchQuery {
                LearnAimRef = course.LearnAimRef
            });
            var getFeChoice = _cosmosDbQueryDispatcher.ExecuteQuery(new GetFeChoiceForProvider {
                ProviderUkprn = course.ProviderUkprn
            });

            await Task.WhenAll(getProvider, getQualification, getFeChoice);

            var provider      = getProvider.Result;
            var qualification = getQualification.Result.Items.SingleOrDefault();
            var feChoice      = getFeChoice.Result;

            var getSqlProvider = _sqlQueryDispatcher.ExecuteQuery(new Core.DataStore.Sql.Queries.GetProviderById {
                ProviderId = provider.Id
            });
            var getProviderVenues = _sqlQueryDispatcher.ExecuteQuery(new GetVenuesByProvider()
            {
                ProviderId = provider.Id
            });

            await Task.WhenAll(getSqlProvider, getProviderVenues);

            var sqlProvider = getSqlProvider.Result;
            var venues      = getProviderVenues.Result;

            var venue = courseRun.VenueId.HasValue
                ? venues.Single(v => v.VenueId == courseRun.VenueId)
                : null;

            var providerContact      = provider.ProviderContact.SingleOrDefault(c => c.ContactType == "P");
            var providerAddressLines = NormalizeAddress(providerContact?.ContactAddress);

            var alternativeCourseRuns = course.CourseRuns
                                        .Where(r => r.CourseRunId != request.CourseRunId && r.CourseRunStatus == CourseStatus.Live)
                                        .Select(r => new { CourseRun = r, Venue = venues.SingleOrDefault(v => v.VenueId == r.VenueId) });

            var regions = await _regionCache.GetAllRegions();

            return(new CourseRunDetailViewModel
            {
                CourseRunId = courseRun.CourseRunId,
                OfferingType = Core.Search.Models.FindACourseOfferingType.Course,
                AttendancePattern = courseRun.DeliveryMode == CourseDeliveryMode.ClassroomBased ? (CourseAttendancePattern?)courseRun.AttendancePattern : null,
                Cost = courseRun.Cost,
                CostDescription = HtmlEncode(courseRun.CostDescription),
                CourseName = HtmlEncode(courseRun.CourseName),
                CourseURL = ViewModelFormatting.EnsureHttpPrefixed(courseRun.CourseWebsite),
                CreatedDate = courseRun.CreatedOn,
                DeliveryMode = courseRun.DeliveryMode,
                DurationUnit = courseRun.DurationUnit,
                DurationValue = courseRun.DurationValue,
                FlexibleStartDate = courseRun.FlexibleStartDate,
                StartDate = !courseRun.FlexibleStartDate ? courseRun.StartDate : null,
                StudyMode = courseRun.StudyMode.HasValue ? courseRun.StudyMode.Value : 0,
                National = courseRun.National,
                Course = new CourseViewModel
                {
                    AwardOrgCode = qualification.Record.AwardOrgCode,
                    CourseDescription = HtmlEncode(course.CourseDescription),
                    CourseId = course.CourseId,
                    EntryRequirements = HtmlEncode(course.EntryRequirements),
                    HowYoullBeAssessed = HtmlEncode(course.HowYoullBeAssessed),
                    HowYoullLearn = HtmlEncode(course.HowYoullLearn),
                    LearnAimRef = course.LearnAimRef,
                    QualificationLevel = qualification.Record.NotionalNVQLevelv2,
                    WhatYoullLearn = HtmlEncode(course.WhatYoullLearn),
                    WhatYoullNeed = HtmlEncode(course.WhatYoullNeed),
                    WhereNext = HtmlEncode(course.WhereNext)
                },
                Venue = venue != null
                    ? new VenueViewModel
                {
                    AddressLine1 = HtmlEncode(venue.AddressLine1),
                    AddressLine2 = HtmlEncode(venue.AddressLine2),
                    County = HtmlEncode(venue.County),
                    Email = venue.Email,
                    Postcode = venue.Postcode,
                    Telephone = venue.Telephone,
                    Town = HtmlEncode(venue.Town),
                    VenueName = HtmlEncode(venue.VenueName),
                    Website = ViewModelFormatting.EnsureHttpPrefixed(venue.Website),
                    Latitude = Convert.ToDecimal(venue.Latitude),
                    Longitude = Convert.ToDecimal(venue.Longitude)
                }
                    : null,
                Provider = new ProviderViewModel
                {
                    ProviderName = sqlProvider.DisplayName,
                    TradingName = sqlProvider.DisplayName,
                    CourseDirectoryName = provider.CourseDirectoryName,
                    Alias = provider.Alias,
                    Ukprn = provider.UnitedKingdomProviderReferenceNumber,
                    AddressLine1 = HtmlEncode(providerAddressLines.AddressLine1),
                    AddressLine2 = HtmlEncode(providerAddressLines.AddressLine2),
                    Town = HtmlEncode(providerContact?.ContactAddress?.PostTown ?? providerContact?.ContactAddress?.Items?.FirstOrDefault()?.ToString()),
                    Postcode = providerContact?.ContactAddress?.PostCode,
                    County = HtmlEncode(providerContact?.ContactAddress?.County ?? providerContact?.ContactAddress?.Locality),
                    Telephone = providerContact?.ContactTelephone1,
                    Fax = providerContact?.ContactFax,
                    Website = ViewModelFormatting.EnsureHttpPrefixed(providerContact?.ContactWebsiteAddress),
                    Email = providerContact?.ContactEmail,
                    EmployerSatisfaction = feChoice?.EmployerSatisfaction,
                    LearnerSatisfaction = feChoice?.LearnerSatisfaction,
                },
                Qualification = new QualificationViewModel
                {
                    AwardOrgCode = qualification.Record.AwardOrgCode,
                    AwardOrgName = HtmlEncode(qualification.Record.AwardOrgName),
                    LearnAimRef = qualification.Record.LearnAimRef,
                    LearnAimRefTitle = HtmlEncode(qualification.Record.LearnAimRefTitle),
                    LearnAimRefTypeDesc = HtmlEncode(qualification.Record.LearnAimRefTypeDesc),
                    QualificationLevel = qualification.Record.NotionalNVQLevelv2,
                    SectorSubjectAreaTier1Desc = HtmlEncode(qualification.Record.SectorSubjectAreaTier1Desc),
                    SectorSubjectAreaTier2Desc = HtmlEncode(qualification.Record.SectorSubjectAreaTier2Desc)
                },
                AlternativeCourseRuns = alternativeCourseRuns.Select(c => new AlternativeCourseRunViewModel
                {
                    CourseRunId = c.CourseRun.CourseRunId,
                    AttendancePattern = c.CourseRun.DeliveryMode == CourseDeliveryMode.ClassroomBased ? (CourseAttendancePattern?)c.CourseRun.AttendancePattern : null,
                    Cost = c.CourseRun.Cost,
                    CostDescription = HtmlEncode(c.CourseRun.CostDescription),
                    CourseName = HtmlEncode(c.CourseRun.CourseName),
                    CourseURL = ViewModelFormatting.EnsureHttpPrefixed(c.CourseRun.CourseWebsite),
                    CreatedDate = c.CourseRun.CreatedOn,
                    DeliveryMode = c.CourseRun.DeliveryMode,
                    DurationUnit = c.CourseRun.DurationUnit,
                    DurationValue = c.CourseRun.DurationValue,
                    FlexibleStartDate = c.CourseRun.FlexibleStartDate,
                    StartDate = !c.CourseRun.FlexibleStartDate ? c.CourseRun.StartDate : null,
                    StudyMode = c.CourseRun.StudyMode.HasValue ? c.CourseRun.StudyMode.Value : 0,
                    Venue = c.Venue != null
                        ? new VenueViewModel
                    {
                        AddressLine1 = HtmlEncode(c.Venue.AddressLine1),
                        AddressLine2 = HtmlEncode(c.Venue.AddressLine2),
                        County = HtmlEncode(c.Venue.County),
                        Email = c.Venue.Email,
                        Postcode = c.Venue.Postcode,
                        Telephone = c.Venue.Telephone,
                        Town = HtmlEncode(c.Venue.Town),
                        VenueName = HtmlEncode(c.Venue.VenueName),
                        Website = ViewModelFormatting.EnsureHttpPrefixed(c.Venue.Website),
                        Latitude = Convert.ToDecimal(c.Venue.Latitude),
                        Longitude = Convert.ToDecimal(c.Venue.Longitude)
                    }
                        : null
                }).ToArray(),
                SubRegions = regions.SelectMany(
                    r => r.SubRegions.Where(sr => courseRun.SubRegionIds?.Contains(sr.Id) ?? false),
                    (r, sr) => new SubRegionViewModel
                {
                    SubRegionId = sr.Id,
                    Name = sr.Name,
                    ParentRegion = new RegionViewModel
                    {
                        Name = r.Name,
                        RegionId = r.Id
                    }
                }).ToArray()
            });
示例#16
0
        public void ShouldGetResults()
        {
            var result = _searchClient.Search("Oil");

            result.Should().HaveCount(10);
        }