private Contractor GetBMContractorForFunction(Func <RawBMContractor, bool> func) { Contractor result = null; LocatorSearchOptions searchOptions = new LocatorSearchOptions() { LocatorBusinessType = LocatorBusinessTypes.All }; using (ContractorLocatorDataContext dataContext = new ContractorLocatorDataContext()) { var rawResults = dataContext.RawBMContractors.Where(func).ToList(); if (rawResults.Count > 0) { result = BuildContractorLocatorResult(rawResults.First(), 0.0, searchOptions); } } return(result); }
private IEnumerable <ILocatorResult> GetContractorLocatorResults(LocatorSearchOptions searchOptions) { int[] typesToSearchFor = new int[0]; if ((searchOptions.LocatorResultType & LocatorResultTypes.Installer) == LocatorResultTypes.Installer) { if ((searchOptions.LocatorBusinessType & LocatorBusinessTypes.Roofing) == LocatorBusinessTypes.Roofing) { typesToSearchFor = CombineIdArrays(typesToSearchFor, ROOFING_INSTALLER_TYPE_IDS); } if ((searchOptions.LocatorBusinessType & LocatorBusinessTypes.ResidentialInsulation) == LocatorBusinessTypes.ResidentialInsulation) { typesToSearchFor = CombineIdArrays(typesToSearchFor, INSULATION_ALL_TYPE_IDS); } } if ((searchOptions.LocatorResultType & LocatorResultTypes.Builder) == LocatorResultTypes.Builder) { typesToSearchFor = CombineIdArrays(typesToSearchFor, BUILDER_ALL_TYPE_IDS); } double searchLatitude = searchOptions.Latitude; double searchLongitude = searchOptions.Longitude * -1; using (ContractorLocatorDataContext dataContext = new ContractorLocatorDataContext()) { List <Contractor> contractors; if (searchOptions.SearchType != SearchType.Advanced) { var searchResults = (from contractor in dataContext.RawBMContractors join location in dataContext.RawBMLocations on contractor.zip equals location.PostalCode let distance = //TODO find some way to abstract this out into an expression JGK DistanceCalculationUtil.EARTH_RADIUS * ( Math.Atan( Math.Sqrt(1 - Math.Pow( Math.Sin(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Sin(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) + Math.Cos(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Longitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN - searchLongitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) , 2)) / (Math.Sin(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Sin(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) + Math.Cos(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Longitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN - searchLongitude / DistanceCalculationUtil.DEGREES_PER_RADIAN)) ) ) where distance <= searchOptions.Radius && (searchOptions.RequireEmailAddress ? (contractor.MemberEmailID != null && contractor.MemberEmailID.Length > 5) : true) && contractor.RawBMContractorTypes.Any(type => typesToSearchFor.Contains(type.type_id)) select new { Contractor = contractor, Distance = distance }).ToList(); contractors = searchResults.ConvertAll <Contractor>(a => BuildContractorLocatorResult(a.Contractor, a.Distance, searchOptions)); } else { var searchResults = from contractor in dataContext.RawBMContractors join location in dataContext.RawBMLocations on contractor.zip equals location.PostalCode let distance = //TODO find some way to abstract this out into an expression JGK DistanceCalculationUtil.EARTH_RADIUS * ( Math.Atan( Math.Sqrt(1 - Math.Pow( Math.Sin(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Sin(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) + Math.Cos(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Longitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN - searchLongitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) , 2)) / (Math.Sin(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Sin(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) + Math.Cos(searchLatitude / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Latitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN) * Math.Cos(location.Longitude.Value / DistanceCalculationUtil.DEGREES_PER_RADIAN - searchLongitude / DistanceCalculationUtil.DEGREES_PER_RADIAN)) ) ) where contractor.RawBMContractorTypes.Any(type => typesToSearchFor.Contains(type.type_id)) select new { Contractor = contractor, Distance = distance }; if (!String.IsNullOrEmpty(searchOptions.Company)) { searchResults = searchResults.Where(result => result.Contractor.store.Contains(searchOptions.Company)); } if (!String.IsNullOrEmpty(searchOptions.City)) { searchResults = searchResults.Where(result => result.Contractor.city.Contains(searchOptions.City)); } if (!String.IsNullOrEmpty(searchOptions.State)) { searchResults = searchResults.Where(result => result.Contractor.state == searchOptions.State); } if (searchOptions.RequireEmailAddress) { searchResults = searchResults.Where(result => result.Contractor.MemberEmailID != null && result.Contractor.MemberEmailID.Length > 5); } contractors = searchResults.Take(250).ToList() .ConvertAll <Contractor>(a => BuildContractorLocatorResult(a.Contractor, a.Distance, searchOptions)); } contractors = contractors.Where(c => !c.ContractorPrograms.Includes(ContractorPrograms.IsSilverRewards)).ToList(); var sortedResults = (from contractor in contractors //where (contractor.LocatorResultType & searchOptions.LocatorResultType) == contractor.LocatorResultType orderby contractor.BusinessType descending, contractor.LocatorResultType descending, GetContractorSortOrder(contractor) descending, contractor.Distance, contractor.Company select contractor); var finalResults = sortedResults .Where(c => c.LocatorResultType == LocatorResultTypes.Installer) .Take(searchOptions.MaxResultsPerType).ToList(); finalResults.AddRange( sortedResults .Where(c => c.LocatorResultType == LocatorResultTypes.Builder) .Take(searchOptions.MaxResultsPerType)); return(finalResults.ConvertAll(c => c as ILocatorResult)); } }