Example #1
0
        public async Task <IEnumerable <PlantInfo> > Process(IEnumerable <PlantInfo> plantInfos)
        {
            var newOrigins    = new List <Origin>();
            var newPlantInfos = new List <PlantInfo>();
            var newTaxons     = new List <Taxon>();

            foreach (var plantInfo in plantInfos)
            {
                var lifeform = Lifeforms.FirstOrDefault(l => l.ScientificName == plantInfo.ScientificName);

                if (lifeform == null)
                {
                    lifeform = await _lifeformService.AddOrUpdateLifeformAsync(plantInfo.Lifeform);

                    Lifeforms.Add(lifeform);
                }

                plantInfo.Lifeform = lifeform;

                var taxon = Taxons.FirstOrDefault(t => t.Kingdom == plantInfo.Taxon.Kingdom &&
                                                  t.Genus == plantInfo.Taxon.Genus &&
                                                  t.Species == plantInfo.Taxon.Species &&
                                                  (t.Subspecies == plantInfo.Taxon.Subspecies || !string.IsNullOrEmpty(plantInfo.Taxon.Variety)) &&
                                                  t.Variety == plantInfo.Taxon.Variety);

                if (taxon == null)
                {
                    // Do we already have the same taxon in our insert list?
                    var taxonResult = newTaxons.FirstOrDefault(t => t.Kingdom == plantInfo.Taxon.Kingdom &&
                                                               t.Genus == plantInfo.Taxon.Genus &&
                                                               t.Species == plantInfo.Taxon.Species &&
                                                               (t.Subspecies == plantInfo.Taxon.Subspecies || !string.IsNullOrEmpty(plantInfo.Taxon.Variety)) &&
                                                               t.Variety == plantInfo.Taxon.Variety);

                    if (taxonResult == null)
                    {
                        newTaxons.Add(plantInfo.Taxon);
                    }
                }

                // Do we already have the same origin in our insert list?
                var originResult = newOrigins.FirstOrDefault(o => o.ParentOrigin.OriginId == Origin.OriginId &&
                                                             o.ExternalId == plantInfo.Origin.ExternalId &&
                                                             o.AltExternalId == plantInfo.Origin.AltExternalId);
                if (originResult == null)
                {
                    // See if it already exists, if not, add it to the insert list
                    originResult = Origins.FirstOrDefault(o => o.ExternalId == plantInfo.Origin.ExternalId && o.AltExternalId == plantInfo.Origin.AltExternalId);
                    if (originResult == null)
                    {
                        newOrigins.Add(plantInfo.Origin);
                    }
                }
            }

            if (newOrigins.Any())
            {
                newOrigins = (await _originService.AddOriginsAsync(newOrigins)).ToList();
                Origins.AddRange(newOrigins);
            }

            if (newTaxons.Any())
            {
                newTaxons = (await _taxonService.AddTaxonsAsync(newTaxons)).ToList();
                Taxons.AddRange(newTaxons);
            }

            foreach (var plantInfo in plantInfos)
            {
                var origin = Origins.FirstOrDefault(o => o.ExternalId == plantInfo.Origin.ExternalId &&
                                                    o.AltExternalId == plantInfo.Origin.AltExternalId);
                if (origin == null)
                {
                    origin = await _originService.GetOriginAsync(Origin.OriginId, plantInfo.Origin.ExternalId, plantInfo.Origin.AltExternalId);
                }

                plantInfo.Origin = origin;

                if (plantInfo.Taxon != null)
                {
                    var taxon = Taxons.FirstOrDefault(t => t.Kingdom == plantInfo.Taxon.Kingdom &&
                                                      t.Genus == plantInfo.Taxon.Genus &&
                                                      t.Species == plantInfo.Taxon.Species &&
                                                      (t.Subspecies == plantInfo.Taxon.Subspecies || !string.IsNullOrEmpty(plantInfo.Taxon.Variety)) &&
                                                      t.Variety == plantInfo.Taxon.Variety);

                    plantInfo.Taxon = taxon;
                }

                newPlantInfos.Add(plantInfo);
            }

            if (newPlantInfos.Any())
            {
                newPlantInfos = (await _plantInfoService.AddPlantInfosAsync(newPlantInfos)).ToList();
            }

            foreach (var newPlantInfo in newPlantInfos)
            {
                var plantInfo = plantInfos.First(p => p.Origin.OriginId == newPlantInfo.Origin.OriginId);

                plantInfo.PlantInfoId = newPlantInfo.PlantInfoId;
                newPlantInfo.Taxon    = plantInfo.Taxon;
                newPlantInfo.Origin   = plantInfo.Origin;
                newPlantInfo.Lifeform = plantInfo.Lifeform;
            }

            var plantInfoLocations = plantInfos.Where(p => p.Locations != null && p.Locations.Any())
                                     .SelectMany(p => p.Locations)
                                     .DistinctBy(pl => new { pl.PlantInfo.Origin.AltExternalId, pl.Location.StateOrProvince })
                                     .ToList();

            if (plantInfoLocations.Any() && newPlantInfos.Any())
            {
                var states    = plantInfos.SelectMany(p => p.Locations).Select(l => l.Location.StateOrProvince).Distinct();
                var countries = plantInfos.SelectMany(p => p.Locations).Select(l => l.Location.Country).Distinct();
                var locations = (await _locationService.GetLocationsAsync(l =>
                                                                          (countries.Contains(l.Country) || states.Contains(l.StateOrProvince)) &&
                                                                          l.PostalCode == null && l.Region == null && l.AddressLine1 == null & l.City == null)).ToList();

                var missingLocations = plantInfoLocations.Select(pl => pl.Location)
                                       .GroupJoin(locations,
                                                  pl => new { pl.StateOrProvince, pl.Country },
                                                  l => new { l.StateOrProvince, l.Country },
                                                  (pl, l) => new { pl, l })
                                       .Where(pll => !pll.l.Any())
                                       .Select(pll => pll.pl).DistinctBy(pl => new { pl.StateOrProvince, pl.Country })
                                       .ToList();

                if (missingLocations.Any())
                {
                    var locationResult = await _locationService.AddLocationsAsync(missingLocations);

                    locations.AddRange(locationResult.ToList());
                }

                var plantLocationsToAdd = new List <PlantLocation>();
                foreach (var plantInfoLocation in plantInfoLocations)
                {
                    var newPlantInfo = newPlantInfos.FirstOrDefault(npl => npl.Origin.AltExternalId == plantInfoLocation.PlantInfo.Origin.AltExternalId);
                    if (newPlantInfo != null)
                    {
                        var location = locations.First(l => l.Country == plantInfoLocation.Location.Country &&
                                                       l.StateOrProvince == plantInfoLocation.Location.StateOrProvince);

                        plantLocationsToAdd.Add(new PlantLocation
                        {
                            PlantInfo          = newPlantInfo,
                            Location           = location,
                            Status             = plantInfoLocation.Status,
                            ConservationStatus = plantInfoLocation.ConservationStatus
                        });
                    }
                }

                if (plantInfoLocations.Any())
                {
                    var plantLocationsResult = (await _plantInfoService.AddPlantLocations(plantLocationsToAdd)).ToList();

                    foreach (var newPlantInfo in newPlantInfos)
                    {
                        var newPlantInfoLocations = plantLocationsResult.Where(pl => pl.PlantInfo.PlantInfoId == newPlantInfo.PlantInfoId);

                        // Hydrate Locations
                        foreach (var newPlantInfoLocation in newPlantInfoLocations)
                        {
                            newPlantInfoLocation.Location = locations.Where(l => l.LocationId == newPlantInfoLocation.Location.LocationId).First();
                        }

                        newPlantInfo.Locations = newPlantInfoLocations.Any() ? newPlantInfoLocations : null;
                    }
                }
            }

            var indexResult = await _plantInfoIndex.IndexManyAsync(newPlantInfos.Select(p => p.AsSearchModel(null, null)));

            return(newPlantInfos);
        }