Beispiel #1
0
        static void SetAddress(StagedPerson person, string fullAddress, string address1, string address2, ref string company)
        {
            // If we already parsed an address, skip all of the work.
            // We check this here to make sure the address fields are
            // still added to usedValues to avoid duplicate comments.
            if (person.Address != null)
            {
                return;
            }
            if (fullAddress == null)
            {
                company        = null;
                person.Address = "";
                return;
            }
            fullAddress = fullAddress.Replace(",", ", ").NormalizeSpaces().Trim();
            address1    = address1?.Trim().NormalizeSpaces();
            address2    = address2?.Trim().NormalizeSpaces();

            if (address2 == null || addressPartDetector.IsMatch(address2 ?? "") || address1.StartsWith("PO Box"))
            {
                // If the second field is a continuation of the first, combine them.
                person.Address = (address1 + " " + address2).Trim();
                company        = null;
            }
            else
            {
                // Otherwise, assume it's 'Company Address'.
                if (!char.IsNumber(address2[0]))
                {
                    throw new InvalidOperationException($"Weird address for {person.FullName}: '{address1}', '{address2}' ({fullAddress})");
                }
                company        = address1;
                person.Address = address2;
            }

            var firstParts = (address1 + " " + address2).Trim();

            if (!fullAddress.StartsWith(firstParts))
            {
                throw new InvalidOperationException($"Unrecognized address format for {person.FullName}: '{fullAddress}' expected to start with '{firstParts}'");
            }
            var parsed = addressParser.Match(fullAddress.Substring(firstParts.Length).Trim());

            person.City  = parsed.Groups[1].Value;
            person.State = UsStates.Abbreviate(parsed.Groups[2].Value.Replace(".", ""));
            person.Zip   = parsed.Groups[3].Value;
        }
Beispiel #2
0
        static IEnumerable <Person> Fuzzy(IImportingPerson source)
        {
            IEnumerable <Person> candidates = AppFramework.Table <Person>().Rows;

            // Filter by each field, but only if that field has any matches.

            if (!string.IsNullOrEmpty(source.Address))
            {
                var sourceAddress = AddressInfo.Parse(source.Address);
                var sourceState   = UsStates.Abbreviate(source.State);
                candidates = candidates.Where(p =>
                                              IsMatch(p.Zip, source.Zip) && IsMatch(p.State, sourceState) &&
                                              IsMatch(p.City, source.City) && AddressInfo.Parse(p.Address) == sourceAddress)
                             .DefaultIfEmpty(candidates);
            }

            candidates = candidates.Where(p => p.LastName.Equals(source.LastName, StringComparison.CurrentCultureIgnoreCase))
                         .DefaultIfEmpty(candidates);

            if (!string.IsNullOrWhiteSpace(source.LastName))
            {
                candidates = candidates.LevenshteinDistanceOf(p => p.LastName).ComparedTo(source.LastName)
                             .BestMatches()
                             .DefaultIfEmpty(candidates);
            }

            // Match the imported first name against either HisName or HerName.
            if (!string.IsNullOrWhiteSpace(source.FirstName))
            {
                candidates = candidates.LevenshteinDistanceOf(p => p.HisName).ComparedTo(source.FirstName)
                             .Union(candidates.LevenshteinDistanceOf(p => p.HerName).ComparedTo(source.FirstName))
                             .BestMatches()
                             .Distinct()
                             .DefaultIfEmpty(candidates);
            }

            // If none of the matches found anything, give up.
            if (candidates == AppFramework.Table <Person>().Rows)
            {
                return(Enumerable.Empty <Person>());
            }
            return(candidates);
        }