예제 #1
0
        public async Task <AzureFileInfo> GetPartNumberThumbnailAsync(
            string brandName,
            string partNumber)
        {
            var imageKey       = PartNumberCleaner.GetCleanedBrandPartNumber(brandName, partNumber);
            var cachedImageUrl = await _ekImageCache.GetValueAsync(imageKey, CancellationToken.None);

            if (cachedImageUrl == null)
            {
                // try find in TecDoc
                var fileInfo = await FindAndUploadPartNumberThumbnailAsync(
                    brandName : brandName,
                    partNumber : partNumber,
                    imageKey : imageKey);

                // cache both success and not found
                var imageUrlValue = fileInfo?.Url ?? AbsentImageUrlValue;
                await _ekImageCache.SetValueAsync(imageKey, imageUrlValue, CancellationToken.None);

                return(fileInfo);
            }

            if (cachedImageUrl == AbsentImageUrlValue)
            {
                return(null);
            }

            return(new AzureFileInfo()
            {
                Url = cachedImageUrl,
            });
        }
예제 #2
0
        public static IndexAction ElitUaApiModelToIndexAction(
            ElitPriceListRecord apiProduct,
            long updatedOnUtcTimestamp)
        {
            if (apiProduct == null)
            {
                return(null);
            }

            var source     = EkProductSourceEnum.ElitUa;
            var productKey = new EkProductKey(source, ReplaceInvalidAzureSearchKeySymbolsWithDash(apiProduct.ActiveItemNo))
                             .ToKey();
            var nameRu  = GetValueOrFallback(apiProduct.EcatDescription, apiProduct.ItemDescription);
            var product = new Document()
            {
                ["key"] = productKey,
                ["updatedOnUtcTimestamp"] = updatedOnUtcTimestamp,
                ["source"]                 = (int)source,
                ["sourceId"]               = apiProduct.ActiveItemNo,
                ["partNumber"]             = apiProduct.PartNumber,
                ["cleanedPartNumber"]      = PartNumberCleaner.GetCleanedPartNumber(apiProduct.PartNumber),
                ["brandName"]              = apiProduct.Brand,
                ["cleanedBrandPartNumber"] = PartNumberCleaner.GetCleanedBrandPartNumber(
                    brandName: apiProduct.Brand,
                    partNumber: apiProduct.PartNumber),
                ["name_ru"] = SearchTextHelpers.TrimNameAndAddBrandIfMissed(
                    productName: nameRu,
                    brandName: apiProduct.Brand),
                ["price"] = (double)apiProduct.CustomerPrice,
            };

            return(IndexAction.MergeOrUpload(product));
        }
예제 #3
0
        public static IndexAction OmegaAutoBizApiModelToIndexAction(
            ProductSearchRecord apiProduct,
            long updatedOnUtcTimestamp)
        {
            if (apiProduct == null)
            {
                return(null);
            }

            var source     = EkProductSourceEnum.OmegaAutoBiz;
            var productKey = new EkProductKey(source, apiProduct.ProductId.ToString())
                             .ToKey();
            var price = GetValueOrFallback(apiProduct.CustomerPrice, apiProduct.Price);

            if (price == 0)
            {
                return(IndexAction.Delete(new Document()
                {
                    ["key"] = productKey,
                }));
            }

            var partNumber  = apiProduct.Number?.Trim();
            var brandName   = apiProduct.BrandDescription?.Trim();
            var nameRu      = apiProduct.Description?.Trim();
            var nameUk      = GetValueOrFallback(apiProduct.DescriptionUkr?.Trim(), nameRu);
            var description = apiProduct.Info?.Trim();

            var product = new Document()
            {
                ["key"] = productKey,
                ["updatedOnUtcTimestamp"] = updatedOnUtcTimestamp,
                ["source"]                 = (int)source,
                ["sourceId"]               = apiProduct.ProductId.ToString(),
                ["partNumber"]             = partNumber,
                ["cleanedPartNumber"]      = PartNumberCleaner.GetCleanedPartNumber(partNumber),
                ["brandName"]              = brandName,
                ["cleanedBrandPartNumber"] = PartNumberCleaner.GetCleanedBrandPartNumber(
                    brandName: brandName,
                    partNumber: partNumber),
                ["name_ru"] = SearchTextHelpers.TrimNameAndAddBrandIfMissed(
                    productName: nameRu,
                    brandName: brandName),
                ["name_uk"] = SearchTextHelpers.TrimNameAndAddBrandIfMissed(
                    productName: nameUk,
                    brandName: brandName),
                ["description_ru"] = description,
                ["description_uk"] = description,
                ["price"]          = (double)price,
            };

            return(IndexAction.MergeOrUpload(product));
        }
        public override async Task <EkKioskProductAndReplacementsByPartNumberGetResponse> ExecuteAsync(EkKioskProductAndReplacementsByPartNumberGetRequest request)
        {
            Assure.ArgumentNotNull(request.PartNumberBrand, nameof(request.PartNumberBrand));
            Assure.ArgumentNotNull(request.PartNumberBrand.ProductKey, nameof(request.PartNumberBrand.ProductKey));
            Assure.ArgumentNotNull(request.PartNumberBrand.PartNumber, nameof(request.PartNumberBrand.PartNumber));

            var response = new EkKioskProductAndReplacementsByPartNumberGetResponse();

            // cancellation token
            var cancellationToken = _httpContextAccessor.HttpContext?.RequestAborted ?? CancellationToken.None;

            using (var searchIndexClient = AzureSearchHelper.CreateSearchIndexClient(_ekSearchSettings.ServiceName, _ekSearchSettings.QueryKey))
            {
                searchIndexClient.IndexName = _ekSearchSettings.ProductsIndexName;

                // FIND PRODUCT
                try
                {
                    var indexProduct = await searchIndexClient.Documents.GetAsync <IndexProduct>(
                        request.PartNumberBrand.ProductKey,
                        cancellationToken : cancellationToken);

                    response.Product = EkConvertHelper.EkNewIndexProductToProduct(indexProduct);

                    // todo: add search by Brand/PartNumber to find all direct matches since many products sources are supported
                    // it's not done since new product search model is planned anyway
                }
                catch (CloudException)
                {
                    response.Product = EkConvertHelper.EkOmegaPartNumberBrandToProduct(request.PartNumberBrand);
                }

                // FIND REPLACEMENTS
                var cleanedPartNumber = PartNumberCleaner.GetCleanedPartNumber(request.PartNumberBrand.PartNumber);

                // TecDoc replacements
                // todo: add cancellationToken support to proxy based clients
                var tecDocReplacements = await _tecDocWsClient.SearchByArticleNumberAsync(cleanedPartNumber);

                tecDocReplacements = tecDocReplacements
                                     // except direct match
                                     .Where(x => x.NumberType != ArticleNumberTypeEnum.ArticleNumber)
                                     .ToArray();

                var replacementCleanedBrandPartNumbers = tecDocReplacements
                                                         .Select(x => PartNumberCleaner.GetCleanedBrandPartNumber(x.BrandName, x.ArticleNo))
                                                         .Take(100)
                                                         .ToArray();

                if (replacementCleanedBrandPartNumbers.Length > 0)
                {
                    var replacementsIndexSearchParameters = new SearchParameters()
                    {
                        Top          = 100,
                        SearchFields = new[] { "cleanedBrandPartNumber" },
                    };
                    var searchTerm   = string.Join("|", replacementCleanedBrandPartNumbers);
                    var searchResult = await searchIndexClient.Documents.SearchAsync <IndexProduct>(
                        searchTerm,
                        replacementsIndexSearchParameters,
                        cancellationToken : cancellationToken);

                    response.Replacements = searchResult.Results
                                            .Select(x => EkConvertHelper.EkNewIndexProductToProduct(x.Document))
                                            .ToArray();
                }
                else
                {
                    response.Replacements = new EkProduct[0];
                }

                return(response);
            }
        }
예제 #5
0
        public override async Task <EkKioskProductSearchByCategoryGetResponse> ExecuteAsync(EkKioskProductSearchByCategoryGetRequest request)
        {
            var response = new EkKioskProductSearchByCategoryGetResponse();

            // cancellation token
            var cancellationToken = _httpContextAccessor.HttpContext?.RequestAborted ?? CancellationToken.None;

            // todo: add cancellationToken support to proxy based clients

            // determine TecDoc car type of modification first
            CarTypeEnum carType;
            // request categories for cars first
            var categories = await _tecDocWsClient.GetCategoriesAsync(CarTypeEnum.Car, request.ModificationId, null, childNodes : false);

            if (categories?.Length > 0)
            {
                carType = CarTypeEnum.Car;
            }
            else
            {
                // then request for trucks
                categories = await _tecDocWsClient.GetCategoriesAsync(CarTypeEnum.Truck, request.ModificationId, null, childNodes : false);

                if (categories?.Length > 0)
                {
                    carType = CarTypeEnum.Truck;
                }
                else
                {
                    return(response);
                }
            }

            const int MaxProductCount = 200;

            // TecDoc articles
            var tecDocProducts = await _tecDocWsClient.GetArticlesCompactInfoAsync(carType, request.ModificationId, request.CategoryId);

            var productCleanedBrandPartNumbers = tecDocProducts
                                                 .Select(x => PartNumberCleaner.GetCleanedBrandPartNumber(x.BrandName, x.ArticleNo))
                                                 .Take(MaxProductCount)
                                                 .ToArray();

            if (productCleanedBrandPartNumbers.Length == 0)
            {
                return(response);
            }

            // FIND PRODUCTS IN STOCK
            using (var searchIndexClient = AzureSearchHelper.CreateSearchIndexClient(_ekSearchSettings.ServiceName, _ekSearchSettings.QueryKey))
            {
                searchIndexClient.IndexName = _ekSearchSettings.ProductsIndexName;

                var replacementsIndexSearchParameters = new SearchParameters()
                {
                    Top          = MaxProductCount,
                    SearchFields = new[] { "cleanedBrandPartNumber" },
                };
                var searchTerm   = string.Join("|", productCleanedBrandPartNumbers);
                var searchResult = await searchIndexClient.Documents.SearchAsync <IndexProduct>(
                    searchTerm,
                    replacementsIndexSearchParameters,
                    cancellationToken : cancellationToken);

                response.Products = searchResult.Results
                                    .Select(x => EkConvertHelper.EkNewIndexProductToProduct(x.Document))
                                    .ToArray();

                return(response);
            }
        }