Beispiel #1
0
        private async Task MapCountryLocalities(string supplier, int countryId, string countryCode, string countryName, TelemetrySpan localityMappingSpan,
                                                CancellationToken cancellationToken)
        {
            _logger.LogMappingLocalitiesOfSpecifiedCountryStart(supplier, countryCode);

            var utcDate = DateTimeOffset.UtcNow;
            var changedLocalityPairs  = new Dictionary <int, int>();
            var localitiesToUpdate    = new List <Locality>();
            var newLocalities         = new List <Locality>();
            var normalizedCountryName = _locationNameNormalizer.GetNormalizedCountryName(countryName);

            var dbNormalizedLocalities = await _locationMapperDataRetrieveService.GetNormalizedLocalitiesByCountry(countryCode, cancellationToken);

            var notSuppliersLocalities = dbNormalizedLocalities
                                         .Where(l => !l.SupplierLocalityCodes.ContainsKey(supplier)).ToList();
            var suppliersLocalities = dbNormalizedLocalities
                                      .Where(l => l.SupplierLocalityCodes.ContainsKey(supplier)).ToList();

            var localities = await _context.RawAccommodations
                             .Where(ac => ac.Supplier == supplier && ac.LocalityNames != null && ac.CountryCode == countryCode)
                             .Select(ac
                                     => new
            {
                LocalityCode  = ac.SupplierLocalityCode,
                LocalityNames = ac.LocalityNames
            })
                             .Distinct().ToListAsync(cancellationToken);

            localities = localities.GroupBy(l => _locationNameNormalizer.GetNormalizedLocalityName(normalizedCountryName, l.LocalityNames.En))
                         .Select(l => l.First()).ToList();

            foreach (var locality in localities)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var defaultLocalityName    = locality.LocalityNames.GetValueOrDefault(Constants.DefaultLanguageCode);
                var normalizedLocalityName = _locationNameNormalizer.GetNormalizedLocalityName(countryName, defaultLocalityName);

                if (!_localityValidator.IsNormalizedValid(normalizedCountryName, normalizedLocalityName))
                {
                    _logger.LogMappingInvalidLocality(defaultLocalityName, normalizedCountryName, supplier,
                                                      JsonSerializer.Serialize(new { countryCode, countryId, countryName }), JsonSerializer.Serialize(locality));
                    continue;
                }

                var dbNotSuppliersLocality = notSuppliersLocalities.FirstOrDefault(l => l.Names.En == normalizedLocalityName);
                var dbSuppliersLocalities  = suppliersLocalities.Where(l => l.Names.En == normalizedLocalityName).ToList();

                var richLocality = new RichLocality(supplierCode: locality.LocalityCode,
                                                    defaultNormalizedName: normalizedLocalityName,
                                                    defaultNormalizedCountryName: normalizedCountryName,
                                                    names: locality.LocalityNames);

                if (dbSuppliersLocalities.Any())
                {
                    ProcessIfSupplierLocalitiesExist(richLocality, dbSuppliersLocalities, dbNotSuppliersLocality);
                }
                else if (dbNotSuppliersLocality != default)
                {
                    ProcessIfNotSupplierLocalityExists(richLocality, dbNotSuppliersLocality);
                }
                else
                {
                    ProcessNewLocality(richLocality);
                }
            }

            _context.UpdateRange(localitiesToUpdate);
            _context.AddRange(newLocalities);
            await ChangeLocalityDependencies(changedLocalityPairs, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            await _localityChangePublisher.PublishRemovedLocalities(changedLocalityPairs.Keys.ToList());

            await _localityChangePublisher.PublishAddedLocalities(newLocalities
                                                                  .Select(l => new LocalityData(l.Id, l.Names.En, countryName, countryCode))
                                                                  .ToList());

            _context.ChangeTracker.Entries()
            .Where(e => e.Entity != null)
            .Where(e => e.State != EntityState.Detached)
            .ToList()
            .ForEach(e => e.State = EntityState.Detached);

            localityMappingSpan.AddEvent($"Done mapping localities of country with code {countryCode}");

            _logger.LogMappingLocalitiesOfSpecifiedCountryFinish(supplier, countryCode);


            void ProcessIfSupplierLocalitiesExist(RichLocality locality, List <Locality> supplierLocalities, Locality?notSupplierLocality)
            {
                var dbSuppliersLocality = supplierLocalities.First();
                var dbSuppliersLocalitiesToDeactivate = supplierLocalities.GetRange(1, supplierLocalities.Count - 1);

                var names         = _multilingualDataHelper.NormalizeLocalityMultilingualNames(locality.DefaultNormalizedCountryName, locality.Names);
                var supplierCodes = dbSuppliersLocality.SupplierLocalityCodes;

                foreach (var supplierLocality in dbSuppliersLocalitiesToDeactivate)
                {
                    names = MultiLanguageHelpers.MergeMultilingualStrings(names, supplierLocality.Names);
                    foreach (var supplierCode in supplierLocality.SupplierLocalityCodes)
                    {
                        supplierCodes.TryAdd(supplierCode.Key, supplierCode.Value);
                    }

                    supplierLocality.IsActive = false;
                    supplierLocality.Modified = utcDate;

                    localitiesToUpdate.Add(supplierLocality);
                    changedLocalityPairs.Add(supplierLocality.Id, dbSuppliersLocality.Id);
                }

                if (notSupplierLocality != default)
                {
                    names = MultiLanguageHelpers.MergeMultilingualStrings(names, notSupplierLocality.Names);

                    changedLocalityPairs.Add(notSupplierLocality.Id, dbSuppliersLocality.Id);

                    foreach (var sup in notSupplierLocality.SupplierLocalityCodes)
                    {
                        supplierCodes.TryAdd(sup.Key, sup.Value);
                    }

                    notSupplierLocality.IsActive = false;
                    notSupplierLocality.Modified = utcDate;

                    localitiesToUpdate.Add(notSupplierLocality);
                }

                names = _multilingualDataHelper.NormalizeLocalityMultilingualNames(locality.DefaultNormalizedCountryName, names);

                var dbLocality = new Locality
                {
                    Id                    = dbSuppliersLocality.Id,
                    CountryId             = countryId,
                    Names                 = names,
                    SupplierLocalityCodes = supplierCodes,
                    Modified              = utcDate,
                    IsActive              = true
                };

                localitiesToUpdate.Add(dbLocality);
            }

            void ProcessIfNotSupplierLocalityExists(RichLocality locality, Locality notSupplierLocality)
            {
                var supplierCodes = new Dictionary <string, string?>(notSupplierLocality.SupplierLocalityCodes);

                supplierCodes.TryAdd(supplier, locality.SupplierCode);

                var names = _multilingualDataHelper.NormalizeLocalityMultilingualNames(locality.DefaultNormalizedCountryName,
                                                                                       MultiLanguageHelpers.MergeMultilingualStrings(locality.Names, notSupplierLocality.Names));

                var dbLocality = new Locality
                {
                    Id                    = notSupplierLocality !.Id,
                    CountryId             = countryId,
                    Names                 = names,
                    SupplierLocalityCodes = supplierCodes,
                    IsActive              = true,
                    Modified              = utcDate
                };

                localitiesToUpdate.Add(dbLocality);
            }

            void ProcessNewLocality(RichLocality locality)
            {
                var dbLocality = new Locality
                {
                    CountryId             = countryId,
                    Names                 = _multilingualDataHelper.NormalizeLocalityMultilingualNames(locality.DefaultNormalizedCountryName, locality.Names),
                    IsActive              = true,
                    Modified              = utcDate,
                    Created               = utcDate,
                    SupplierLocalityCodes = new Dictionary <string, string?>
                    {
                        { supplier, locality.SupplierCode }
                    }
                };

                newLocalities.Add(dbLocality);
            }
        }