public async Task CalculateProviderLocationDistanceInMiles_Calculate_Distance_In_Miles_From_StudentPostcode_To_ProviderLocation_Using_LocationApi( string studentPostcode, double studentLat, double studentLon, double providerLat, double providerLon, int expectedMileageInMilesAfterRounding) { var postcodeLookupResultDto = new PostcodeLookupResultDto { Postcode = studentPostcode, Latitude = studentLat, Longitude = studentLon }; _locationApiClient.GetGeoLocationDataAsync(studentPostcode).Returns(postcodeLookupResultDto); var providerLocation = new ProviderLocation { Latitude = providerLat, Longitude = providerLon }; var providerLocations = new List <ProviderLocation> { providerLocation }; await _distanceCalculationService.CalculateProviderLocationDistanceInMiles(new PostcodeLocation { Postcode = studentPostcode }, providerLocations.AsQueryable()); var roundedDistanceInMiles = (int)Math.Round(providerLocation.DistanceInMiles, MidpointRounding.AwayFromZero); roundedDistanceInMiles.Should().Be(expectedMileageInMilesAfterRounding); await _locationApiClient.Received(1).GetGeoLocationDataAsync(studentPostcode); }
public async Task <IList <ProviderLocation> > CalculateProviderLocationDistanceInMiles(PostcodeLocation origin, IQueryable <ProviderLocation> providerLocations) { double originLatitude; double originLongitude; if (!origin.Latitude.HasValue || !origin.Longitude.HasValue) { var originGeoLocation = await _locationApiClient.GetGeoLocationDataAsync(origin.Postcode); originLatitude = originGeoLocation.Latitude; originLongitude = originGeoLocation.Longitude; } else { originLatitude = origin.Latitude.Value; originLongitude = origin.Longitude.Value; } var results = new List <ProviderLocation>(); foreach (var providerLocation in providerLocations) { providerLocation.DistanceInMiles = CalculateDistanceInMiles( originLatitude, originLongitude, providerLocation.Latitude, providerLocation.Longitude); results.Add(providerLocation); } return(results); }
private async Task GetGeoLocationDataAsync(AddProviderVenueViewModel viewModel, ProviderVenue providerVenue) { var geoLocationData = await _locationApiClient.GetGeoLocationDataAsync(viewModel.Postcode, true); providerVenue.Postcode = geoLocationData.Postcode; providerVenue.Latitude = geoLocationData.Latitude.ToDecimal(); providerVenue.Longitude = geoLocationData.Longitude.ToDecimal(); var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(4326); providerVenue.Location = geometryFactory.CreatePoint(new Coordinate(double.Parse(geoLocationData.Longitude), double.Parse(geoLocationData.Latitude))); }
public When_Proximity_BackFillProximityData_Function_Fires() { var opportunityItemRepository = Substitute.For <IRepository <OpportunityItem> >(); _providerVenueRepository = Substitute.For <IRepository <ProviderVenue> >(); var mockProviderVenueDbSet = new List <ProviderVenue> { new ProviderVenue { Postcode = "CV1 2WT", Town = null } } .AsQueryable() .BuildMockDbSet(); _providerVenueRepository.GetManyAsync(Arg.Any <Expression <Func <ProviderVenue, bool> > >()) .Returns(mockProviderVenueDbSet); _functionLogRepository = Substitute.For <IRepository <FunctionLog> >(); var googleMapsApiClient = Substitute.For <IGoogleMapApiClient>(); googleMapsApiClient.GetAddressDetailsAsync("CV1 2WT").Returns("Coventry"); _locationApiClient = Substitute.For <ILocationApiClient>(); _locationApiClient.GetGeoLocationDataAsync(Arg.Any <string>(), Arg.Any <bool>()) .Returns(new PostcodeLookupResultDto { Postcode = "CV1 2WT", Latitude = "52.400997", Longitude = "-1.508122" }); var proximityFunctions = new Functions.Proximity( _locationApiClient, googleMapsApiClient, opportunityItemRepository, _providerVenueRepository, _functionLogRepository); proximityFunctions.BackFillProximityDataAsync( new TimerInfo(new ConstantSchedule(TimeSpan.Zero), null), new ExecutionContext(), new NullLogger <Functions.Proximity>() ).GetAwaiter().GetResult(); }
public When_ProviderVenueService_Is_Called_To_Create_Venue() { var httpContextAccessor = Substitute.For <IHttpContextAccessor>(); var config = new MapperConfiguration(c => { c.AddMaps(typeof(ProviderVenueMapper).Assembly); c.ConstructServicesUsing(type => type.Name.Contains("LoggedInUserEmailResolver") ? new LoggedInUserEmailResolver <AddProviderVenueViewModel, Domain.Models.ProviderVenue>(httpContextAccessor) : type.Name.Contains("LoggedInUserNameResolver") ? (object)new LoggedInUserNameResolver <AddProviderVenueViewModel, Domain.Models.ProviderVenue>(httpContextAccessor) : type.Name.Contains("UtcNowResolver") ? new UtcNowResolver <AddProviderVenueViewModel, Domain.Models.ProviderVenue>(new DateTimeProvider()) : null); }); var mapper = new Mapper(config); _providerVenueRepository = Substitute.For <IProviderVenueRepository>(); _providerVenueRepository.GetSingleOrDefaultAsync(Arg.Any <Expression <Func <Domain.Models.ProviderVenue, bool> > >()) .Returns(new Domain.Models.ProviderVenue()); _locationApiClient = Substitute.For <ILocationApiClient>(); _locationApiClient.GetGeoLocationDataAsync(UnFormattedPostcode, true).Returns(new PostcodeLookupResultDto { Postcode = FormattedPostcode, Longitude = "1.2", Latitude = "1.2" }); _googleMapApiClient = Substitute.For <IGoogleMapApiClient>(); _googleMapApiClient.GetAddressDetailsAsync(Arg.Is <string>(s => s == FormattedPostcode)).Returns("Coventry"); var providerVenueService = new ProviderVenueService(mapper, _providerVenueRepository, _locationApiClient, _googleMapApiClient); var viewModel = new AddProviderVenueViewModel { Postcode = UnFormattedPostcode }; providerVenueService.CreateVenueAsync(viewModel).GetAwaiter().GetResult(); }
public async Task <PostcodeLookupResultDto> GetGeoLocationDataAsync(string postcode) { return(await _locationApiClient.GetGeoLocationDataAsync(postcode)); }
public async Task BackFillProximityDataAsync( #pragma warning disable IDE0060 // Remove unused parameter [TimerTrigger("0 0 0 1 1 *", RunOnStartup = true)] TimerInfo timer, #pragma warning restore IDE0060 // Remove unused parameter ExecutionContext context, ILogger logger) { try { var stopwatch = Stopwatch.StartNew(); logger.LogInformation($"Function {context.FunctionName} triggered"); var providerVenues = await _providerVenueRepository.GetManyAsync(venue => venue.Location == null || venue.Longitude == null || venue.Latitude == null || !EF.Functions.Like(venue.Postcode, "% %") || venue.Postcode.ToUpper() != venue.Postcode) .ToListAsync(); if (!providerVenues.Any()) { return; } foreach (var venue in providerVenues) { try { var geoLocationData = await _locationApiClient.GetGeoLocationDataAsync(venue.Postcode, true); venue.Postcode = geoLocationData.Postcode; venue.Latitude = geoLocationData.Latitude.ToDecimal(); venue.Longitude = geoLocationData.Longitude.ToDecimal(); var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(4326); venue.Location = geometryFactory.CreatePoint(new Coordinate(double.Parse(geoLocationData.Longitude), double.Parse(geoLocationData.Latitude))); } catch (Exception e) { var errorMessage = $"Error Back Filling Provider Venue Data. Invalid Postcode. Internal Error Message {e}"; logger.LogError(errorMessage); await _functionLogRepository.CreateAsync(new FunctionLog { ErrorMessage = errorMessage, FunctionName = context.FunctionName, RowNumber = venue.Id }); } } await _providerVenueRepository.UpdateManyAsync(providerVenues); stopwatch.Stop(); logger.LogInformation($"Function {context.FunctionName} finished processing\n" + $"\tRows saved: {providerVenues.Count}\n" + $"\tTime taken: {stopwatch.ElapsedMilliseconds: #,###}ms"); } catch (Exception e) { var errorMessage = $"Error Back Filling Proximity Data. Internal Error Message {e}"; logger.LogError(errorMessage); await _functionLogRepository.CreateAsync(new FunctionLog { ErrorMessage = errorMessage, FunctionName = context.FunctionName, RowNumber = -1 }); throw; } }