예제 #1
0
        ExecutionResult <Address> IManager.SearchAddress(string address)
        {
            try
            {
                using (var db = this.CreateUnitOfWork())
                {
                    var DadataClient = GetDadataClient();

                    DaData.Entities.AddressData result = null;

                    if (result == null)
                    {
                        try
                        {
                            var found = db.Repo2.Where(x => x.NameAddressSearch.Equals(address, StringComparison.InvariantCultureIgnoreCase) && x.ServiceFound == "DaData").OrderByDescending(x => x.DateSearch).FirstOrDefault();
                            if (found != null)
                            {
                                if (found.IsSuccess)
                                {
                                    result = Newtonsoft.Json.JsonConvert.DeserializeObject <DaData.Entities.AddressData>(found.ServiceAnswer);
                                }
                                else
                                {
                                    var timeoutForNewSearch = TimeSpan.FromDays(5); //Время, в течение которого мы используем старый неудачный результат поиска, чтобы не тратить деньги ЛК DaData.
                                    if (DateTime.Now - found.DateSearch < timeoutForNewSearch)
                                    {
                                        return(new ExecutionResult <Address>(false, "Указанный адрес не найден."));
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            this.RegisterEvent(Journaling.EventType.Error, "Ошибка во время поиска кешированного результата.", $"Адрес: {address}", null, ex);
                        }
                    }

                    if (result == null)
                    {
                        var results = DadataClient.Clean <DaData.Entities.AddressData>(new string[] { address });
                        if (results.IsSuccess)
                        {
                            if (results.Data != null && results.Data.Count > 0)
                            {
                                var resultPre = results.Data.First();

                                var history = new AddressSearchHistory()
                                {
                                    NameAddressSearch = address,
                                    DateSearch        = DateTime.Now,
                                    IsSuccess         = false,
                                    AddressType       = AddressType.Country,
                                    ServiceFound      = "DaData",
                                    ServiceAnswer     = Newtonsoft.Json.JsonConvert.SerializeObject(resultPre)
                                };

                                var allowed = resultPre.qc == DaData.Constants.QC.QC_OK;//Разрешаем только точные совпадения.
                                if (!allowed && resultPre.qc == DaData.Constants.QC.QC_UNSURE)
                                {
                                    int fias_level;
                                    if (int.TryParse(resultPre.fias_level, out fias_level))
                                    {
                                        if (fias_level >= 7)
                                        {
                                            allowed = true;                   //Если точность совпадения - улица, тоже разрешаем.
                                        }
                                        if (fias_level == 6 && string.IsNullOrEmpty(resultPre.city_kladr_id) && !string.IsNullOrEmpty(resultPre.settlement_kladr_id))
                                        {
                                            allowed = true;                                                                                                                          //Если точность совпадения - некрупный населенный пункт, тоже разрешаем.
                                        }
                                    }
                                }

                                if (allowed)
                                {
                                    result = resultPre;

                                    history.IsSuccess     = true;
                                    history.KodAddress    = result.kladr_id;
                                    history.ServiceAnswer = Newtonsoft.Json.JsonConvert.SerializeObject(result);
                                }

                                db.Repo2.Add(history);
                                db.SaveChanges();
                            }
                        }
                        else
                        {
                            if (results.Code == 402)
                            {
                                _cachedEvents.GetOrAddWithExpiration("account_balance_empty", (k) =>
                                {
                                    this.RegisterServiceState(ServiceStatus.CannotRunBecouseOfErrors, "Пополните баланс на счете Дадаты - не работают стандартизация и подсказки.");
                                    return(DateTime.Now);
                                }, TimeSpan.FromMinutes(5));
                                return(new ExecutionResult <Address>(false, "Поиск недоступен - недостаточно средств на счете Дадаты."));
                            }
                            else
                            {
                                this.RegisterServiceState(ServiceStatus.CannotRunBecouseOfErrors, "Необработанная ошибка в ответе сервиса.", new Exception($"Код ответа {results.Code}, текст: {results.Detail}"));
                                return(new ExecutionResult <Address>(false, "Необработанная ошибка в ответе сервиса."));
                            }
                        }
                    }

                    var prepareResult = PrepareAddressDataIntoDB(address, result, db);
                    return(new ExecutionResult <Address>(prepareResult != null, null, prepareResult));
                }
            }
            catch (Exception ex)
            {
                this.RegisterEvent(Journaling.EventType.Error, "Ошибка во время обработки результата поиска.", $"SearchAddress: {address}", null, ex);
                return(new ExecutionResult <Address>(false, "Ошибка во время обработки результата поиска."));
            }
        }
예제 #2
0
        private ExecutionResult <Address> GetAddressByQuery(string addressString, Func <string, DaData.Entities.Suggestions.Suggestion <DaData.Entities.AddressData> > suggectionProvider)
        {
            try
            {
                using (var db = this.CreateUnitOfWork())
                {
                    DaData.Entities.AddressData result = null;

                    if (result == null)
                    {
                        try
                        {
                            var found = db.Repo2.Where(x => x.NameAddressSearch.Equals(addressString, StringComparison.InvariantCultureIgnoreCase) && x.ServiceFound == "DaData" && x.AddressType == AddressType.IP_Address).OrderByDescending(x => x.DateSearch).FirstOrDefault();
                            if (found != null)
                            {
                                if (found.IsSuccess)
                                {
                                    result = Newtonsoft.Json.JsonConvert.DeserializeObject <DaData.Entities.AddressData>(found.ServiceAnswer);
                                }
                                else
                                {
                                    var timeoutForNewSearch = TimeSpan.FromMinutes(5); //Время, в течение которого мы используем старый неудачный результат поиска, чтобы не тратить счетчик подсказок DaData.
                                    if (DateTime.Now - found.DateSearch < timeoutForNewSearch)
                                    {
                                        return(new ExecutionResult <Address>(false, "Указанный адрес не найден."));
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            this.RegisterEvent(Journaling.EventType.Error, "Ошибка во время поиска кешированного результата.", $"Адрес: {addressString}", null, ex);
                        }
                    }

                    AddressSearchHistory history = null;

                    if (result == null)
                    {
                        history = new AddressSearchHistory()
                        {
                            NameAddressSearch = addressString,
                            DateSearch        = DateTime.Now,
                            IsSuccess         = false,
                            AddressType       = AddressType.IP_Address,
                            ServiceFound      = "DaData"
                        };

                        var suggestion_result = suggectionProvider(addressString);
                        if (suggestion_result != null)
                        {
                            result = suggestion_result.data;

                            Debug.WriteLineNoLog("GetAddressByQuery: {0}", addressString);
                            Debug.WriteLineNoLog(Newtonsoft.Json.JsonConvert.SerializeObject(result));

                            history.IsSuccess     = true;
                            history.KodAddress    = result.kladr_id;
                            history.ServiceFound  = "DaData";
                            history.ServiceAnswer = Newtonsoft.Json.JsonConvert.SerializeObject(result);
                        }

                        db.Repo2.Add(history);
                        db.SaveChanges();
                    }

                    var prepareResult = PrepareAddressDataIntoDB(addressString, result, db);
                    if (prepareResult != null && history != null)
                    {
                        history.AddressType = prepareResult.AddressType;
                        db.SaveChanges();
                        throw new NotImplementedException("Здесь надо проверить корректность заполнения AddressType в базе после повторного вызова SaveChanges.");
                    }

                    return(new ExecutionResult <Address>(prepareResult != null, null, prepareResult));
                }
            }
            catch (NotImplementedException) { throw; }
            catch (Exception ex)
            {
                this.RegisterEvent(Journaling.EventType.Error, "Ошибка во время обработки результата поиска.", $"GetAddressByQuery: {addressString}", null, ex);
                return(new ExecutionResult <Address>(false, "Ошибка во время обработки результата поиска."));
            }
        }