public async Task <ViewModel> Handle(Query request, CancellationToken cancellationToken)
        {
            var provider = await _cosmosDbQueryDispatcher.ExecuteQuery(
                new Core.DataStore.CosmosDb.Queries.GetProviderById()
            {
                ProviderId = request.ProviderId
            });

            if (provider == null)
            {
                throw new InvalidStateException(InvalidStateReason.ProviderDoesNotExist);
            }

            var lastSubmission = await _sqlQueryDispatcher.ExecuteQuery(
                new GetLatestApprenticeshipQASubmissionForProvider()
            {
                ProviderId = request.ProviderId
            });

            var lastAssessedBy = (lastSubmission.Value as ApprenticeshipQASubmission)?.LastAssessedBy;
            var lastAssessedOn = (lastSubmission.Value as ApprenticeshipQASubmission)?.LastAssessedOn;

            var contact = provider.ProviderContact
                          .OrderByDescending(c => c.LastUpdated)
                          .SingleOrDefault(c => c.ContactType == "P");

            var contactName = contact?.ContactPersonalDetails?.PersonGivenName != null && contact?.ContactPersonalDetails?.PersonFamilyName != null?
                              string.Join(" ", contact.ContactPersonalDetails.PersonGivenName) + " " +
                              contact.ContactPersonalDetails.PersonFamilyName:
                              null;

            var latestSignIn = await _sqlQueryDispatcher.ExecuteQuery(
                new GetLatestUserSignInForProvider()
            {
                ProviderId = request.ProviderId
            });

            return(new ViewModel()
            {
                AddressParts = contact?.ContactAddress != null?
                               FormatAddress(contact.ContactAddress) :
                                   Array.Empty <string>(),
                                   ContactName = contactName,
                                   Email = contact?.ContactEmail,
                                   LastAssessedBy = lastAssessedBy,
                                   LastAssessedOn = lastAssessedOn,
                                   LastSignedIn = latestSignIn.Match(_ => null, signIn => signIn.User),
                                   LastSignedInDate = latestSignIn.Match(_ => (DateTime?)null, signIn => signIn.SignedInUtc),
                                   ProviderId = provider.Id,
                                   ProviderName = provider.ProviderName,
                                   Telephone = contact?.ContactTelephone1,
                                   Ukprn = int.Parse(provider.UnitedKingdomProviderReferenceNumber),
                                   Website = contact?.ContactWebsiteAddress != null?UrlUtil.EnsureHttpPrefixed(contact.ContactWebsiteAddress) : null
            });

            IReadOnlyCollection <string> FormatAddress(ProviderContactAddress address)
            {
                var parts = new List <string>()
                {
                    address.SAON?.Description,
                    address.PAON?.Description,
                    address.StreetDescription,
                    address.Locality
                };

                if (address.Items != null)
                {
                    parts.AddRange(address.Items);
                }

                parts.Add(address.PostCode);

                return(parts.Where(p => !string.IsNullOrEmpty(p)).ToList());
            }
        }
        public async Task <ActionResult> CourseRunDetail([FromQuery] CourseRunDetailRequest request)
        {
            var result = await _service.CourseDetail(request.CourseId, request.CourseRunId);

            if (result != null)
            {
                var courseRun       = result.Course.CourseRuns.Single(r => r.id == request.CourseRunId);
                var venue           = courseRun.VenueId.HasValue ? result.CourseRunVenues.Single(v => v.id == courseRun.VenueId) : null;
                var providerContact = ((JArray)result.Provider.ProviderContact)
                                      .Select(t => t.ToObject <Providercontact>())
                                      .SingleOrDefault(c => c.ContactType == "P");

                var alternativeCourseRuns = result.Course.CourseRuns.Where(r => r.id != request.CourseRunId)
                                            .Where(r => r.RecordStatus == RecordStatus.Live)
                                            .Select(r => new { CourseRun = r, Venue = result.CourseRunVenues.SingleOrDefault(v => v.id == r.VenueId) });

                var response = new CourseRunDetailResponse()
                {
                    CourseRunId       = courseRun.id,
                    AttendancePattern = courseRun.DeliveryMode == DeliveryMode.ClassroomBased ? (AttendancePattern?)courseRun.AttendancePattern : null,
                    Cost              = courseRun.Cost,
                    CostDescription   = courseRun.CostDescription,
                    CourseName        = courseRun.CourseName,
                    CourseURL         = courseRun.CourseURL,
                    CreatedDate       = courseRun.CreatedDate,
                    DeliveryMode      = courseRun.DeliveryMode,
                    DurationUnit      = courseRun.DurationUnit,
                    DurationValue     = courseRun.DurationValue,
                    FlexibleStartDate = courseRun.FlexibleStartDate,
                    StartDate         = !courseRun.FlexibleStartDate ? courseRun.StartDate : null,
                    StudyMode         = courseRun.StudyMode,
                    National          = courseRun.National,
                    Course            = new CourseDetailResponseCourse()
                    {
                        AdvancedLearnerLoan = result.Course.AdvancedLearnerLoan,
                        AwardOrgCode        = result.Course.AwardOrgCode,
                        CourseDescription   = result.Course.CourseDescription,
                        CourseId            = result.Course.id,
                        EntryRequirements   = result.Course.EntryRequirements,
                        HowYoullBeAssessed  = result.Course.HowYoullBeAssessed,
                        HowYoullLearn       = result.Course.HowYoullLearn,
                        LearnAimRef         = result.Course.LearnAimRef,
                        QualificationLevel  = result.Course.NotionalNVQLevelv2,
                        WhatYoullLearn      = result.Course.WhatYoullLearn,
                        WhatYoullNeed       = result.Course.WhatYoullNeed,
                        WhereNext           = result.Course.WhereNext
                    },
                    Venue = venue != null ?
                            new CourseDetailResponseVenue()
                    {
                        AddressLine1 = venue.ADDRESS_1,
                        AddressLine2 = venue.ADDRESS_2,
                        County       = venue.COUNTY,
                        Email        = venue.Email,
                        Postcode     = venue.POSTCODE,
                        Telephone    = venue.Telephone,
                        Town         = venue.TOWN,
                        VenueName    = venue.VENUE_NAME,
                        Website      = UrlUtil.EnsureHttpPrefixed(venue.WEBSITE),
                        Latitude     = venue.Latitude,
                        Longitude    = venue.Longitude
                    } :
                    null,
                    Provider = new CourseDetailResponseProvider()
                    {
                        ProviderName        = result.Provider.ProviderName,
                        TradingName         = result.Provider.TradingName,
                        CourseDirectoryName = result.Provider.CourseDirectoryName,
                        Alias                = result.Provider.Alias,
                        UKPRN                = result.Provider.UnitedKingdomProviderReferenceNumber,
                        AddressLine1         = providerContact?.ContactAddress?.SAON?.Description,
                        AddressLine2         = providerContact?.ContactAddress?.PAON?.Description,
                        Town                 = providerContact?.ContactAddress?.Items?.FirstOrDefault()?.ToString(),
                        Postcode             = providerContact?.ContactAddress?.PostCode,
                        County               = providerContact?.ContactAddress?.Locality,
                        Telephone            = providerContact?.ContactTelephone1,
                        Fax                  = providerContact?.ContactFax,
                        Website              = UrlUtil.EnsureHttpPrefixed(providerContact?.ContactWebsiteAddress),
                        Email                = providerContact?.ContactEmail,
                        EmployerSatisfaction = result.FeChoice?.EmployerSatisfaction,
                        LearnerSatisfaction  = result.FeChoice?.LearnerSatisfaction,
                    },
                    Qualification = new CourseDetailResponseQualification()
                    {
                        AwardOrgCode               = result.Qualification.AwardOrgCode,
                        AwardOrgName               = result.Qualification.AwardOrgName,
                        LearnAimRef                = result.Qualification.LearnAimRef,
                        LearnAimRefTitle           = result.Qualification.LearnAimRefTitle,
                        LearnAimRefTypeDesc        = result.Qualification.LearnAimRefTypeDesc,
                        QualificationLevel         = result.Qualification.NotionalNVQLevelv2,
                        SectorSubjectAreaTier1Desc = result.Qualification.SectorSubjectAreaTier1Desc,
                        SectorSubjectAreaTier2Desc = result.Qualification.SectorSubjectAreaTier2Desc
                    },
                    AlternativeCourseRuns = alternativeCourseRuns.Select(ar => new CourseDetailResponseAlternativeCourseRun()
                    {
                        CourseRunId       = ar.CourseRun.id,
                        AttendancePattern = ar.CourseRun.DeliveryMode == DeliveryMode.ClassroomBased ? (AttendancePattern?)ar.CourseRun.AttendancePattern : null,
                        Cost              = ar.CourseRun.Cost,
                        CostDescription   = ar.CourseRun.CostDescription,
                        CourseName        = ar.CourseRun.CourseName,
                        CourseURL         = ar.CourseRun.CourseURL,
                        CreatedDate       = ar.CourseRun.CreatedDate,
                        DeliveryMode      = ar.CourseRun.DeliveryMode,
                        DurationUnit      = ar.CourseRun.DurationUnit,
                        DurationValue     = ar.CourseRun.DurationValue,
                        FlexibleStartDate = ar.CourseRun.FlexibleStartDate,
                        StartDate         = !ar.CourseRun.FlexibleStartDate ? ar.CourseRun.StartDate : null,
                        StudyMode         = ar.CourseRun.StudyMode,
                        Venue             = ar.Venue != null ?
                                            new CourseDetailResponseVenue()
                        {
                            AddressLine1 = ar.Venue.ADDRESS_1,
                            AddressLine2 = ar.Venue.ADDRESS_2,
                            County       = ar.Venue.COUNTY,
                            Email        = ar.Venue.Email,
                            Postcode     = ar.Venue.POSTCODE,
                            Telephone    = ar.Venue.Telephone,
                            Town         = ar.Venue.TOWN,
                            VenueName    = ar.Venue.VENUE_NAME,
                            Website      = UrlUtil.EnsureHttpPrefixed(ar.Venue.WEBSITE),
                            Latitude     = ar.Venue.Latitude,
                            Longitude    = ar.Venue.Longitude
                        } :
                        null
                    }).ToList(),
                    SubRegions = (from region in RegionInfo.All
                                  from subRegion in region.SubRegions
                                  let sr = new { subRegion, region }
                                  join r in (courseRun.Regions ?? Enumerable.Empty <string>()) on sr.subRegion.Id equals r
                                  select new CourseDetailResponseSubRegion()
                    {
                        SubRegionId = r,
                        Name = sr.subRegion.Name,
                        ParentRegion = new CourseDetailResponseRegion()
                        {
                            Name = sr.region.Name,
                            RegionId = sr.region.Id
                        }
                    }).ToList()
                };

                return(new OkObjectResult(response));
            }
            else
            {
                return(new NotFoundResult());
            }
        }
        public async Task <IViewComponentResult> InvokeAsync(Guid providerId)
        {
            var provider = await _cosmosDbQueryDispatcher.ExecuteQuery(
                new GetProviderById()
            {
                ProviderId = providerId
            });

            if (provider == null)
            {
                throw new ResourceDoesNotExistException(ResourceType.Provider, providerId);
            }

            var contact = provider.ProviderContact
                          .OrderByDescending(c => c.LastUpdated)
                          .SingleOrDefault(c => c.ContactType == "P"); // 'P' == Primary

            ProviderInfoPanelViewModel vm;

            if (contact == null)
            {
                vm = new ProviderInfoPanelViewModel()
                {
                    ProviderId = providerId,
                    GotContact = false
                };
            }
            else
            {
                var contactName = contact.ContactPersonalDetails?.PersonGivenName != null && contact.ContactPersonalDetails?.PersonFamilyName != null ?
                                  $"{string.Join(" ", contact.ContactPersonalDetails.PersonGivenName)} {contact.ContactPersonalDetails.PersonFamilyName}" :
                                  null;

                vm = new ProviderInfoPanelViewModel()
                {
                    AddressParts = contact.ContactAddress != null?
                                   FormatAddress(contact.ContactAddress) :
                                       Array.Empty <string>(),
                                       ContactName = contactName,
                                       Email       = contact.ContactEmail,
                                       GotContact  = true,
                                       ProviderId  = provider.Id,
                                       Telephone   = contact.ContactTelephone1,
                                       Website     = contact.ContactWebsiteAddress != null?UrlUtil.EnsureHttpPrefixed(contact.ContactWebsiteAddress) : null
                };
            }

            return(View("~/SharedViews/Components/ProviderInfoPanel.cshtml", vm));