/// <summary>
        /// Удаляет дубликаты из фулкаталога по sku
        /// </summary>
        public static void DeleteDuplicateItems()
        {
            Program.Logger.Info("Delete duplicate for FullCatalog");
            var fullCatalog = LoadFullCatalogFromFtp();
            var itemsCount  = fullCatalog.records.Count;

            var newFullCatalog = new FullCatalogRoot();

            newFullCatalog.update_time = DateTime.Now;
            foreach (var record in fullCatalog.records)
            {
                var rec = newFullCatalog.records.Find(x => x.sku == record.sku);
                if (rec == null)
                {
                    newFullCatalog.records.Add(record);
                }
                else
                {
                    Program.Logger.Debug("Duplicate item. Sku: " + rec.sku);
                }
            }
            var countDeleteItems = itemsCount - newFullCatalog.records.Count;

            Program.Logger.Info("Items deleted: " + countDeleteItems);
            Program.Logger.Info("Delete duplicate completed. Items count: " + newFullCatalog.records.Count);

            if (countDeleteItems > 0)
            {
                SaveFullCatalogToFtp(newFullCatalog);
            }
        }
Esempio n. 2
0
        private void LoadAllItems(AllStockRoot allstock, FullCatalogRoot fullCatalog, VkGoodsRoot oldVkGoodsRoot)
        {
            var vkGoods = new VkGoodsRoot();

            //var i = 0;
            //const int lim = 10;
            foreach (var artikul in allstock.sneakers)
            {
                try
                {
                    var vkItem = PostItemToVk(fullCatalog, artikul, oldVkGoodsRoot);
                    if (vkItem == null)
                    {
                        continue;
                    }

                    vkGoods.Records.Add(vkItem);
                    //i++;
                    //if (i != lim) continue;
                    //
                    //i = 0;
                    vkGoods.UpdateTime = DateTime.Now;
                    SaveVkGoodsRootToYd(vkGoods);
                }
                catch (Exception e)
                {
                    _logger.Error(e, " Ошибка при добавлении товара ВК");
                    _logger.Error(e.Message);
                    _logger.Error(e.StackTrace);
                }
            }
        }
Esempio n. 3
0
        private static AvitoAds createAds(RootParsingObject discont, FullCatalogRoot fullCatalog,
                                          DateTime startTime)
        {
            var Ads = new AvitoAds();

            Ads.StartTime = startTime;

            var menWomenOnlyListings = discont.listings.FindAll(x => x.category != "kids");
            //var listingsMoreThan2SizesAvailable = menWomenOnlyListings.FindAll(x => x.sizes.Count > 2);
            var listings = menWomenOnlyListings;

            listings = listings.OrderBy(x => x.sku).ToList();
            var listingCount = listings.Count;

            for (int i = 0; i < listingCount; i++)
            {
                var     sneaker   = listings[i];
                var     fcSneaker = fullCatalog.records.Find(x => x.sku == sneaker.sku);
                AvitoAd Ad        = GetAdFromSneaker(sneaker, fcSneaker, Ads.StartTime, Ads.AdList.Count + 1, listingCount);
                if (Ad != null)
                {
                    Ads.AdList.Add(Ad);
                }
            }
            _logger.Info("Кол-во листингов: " + listingCount);
            _logger.Info("Кол-во объявлений: " + Ads.AdList.Count);
            return(Ads);
        }
        public void Run()
        {
            var discontSamara = DiscontSamaraParser.LoadLocalFileJson();

            fullCatalog = FullCatalog2.LoadLocalFile();

            var shopifyRecords = CreateShopifyRecords(discontSamara);
        }
        private static AvitoAds createAds(Model.AllStock.AllStockRoot allstock, FullCatalogRoot fullCatalog, DateTime startTime)
        {
            var Ads = new AvitoAds();

            Ads.StartTime = startTime;
            for (int i = 0; i < allstock.sneakers.Count; i++)
            {
                var     sneaker   = allstock.sneakers[i];
                var     fcSneaker = fullCatalog.records.Find(x => x.sku == sneaker.sku);
                AvitoAd Ad        = GetAdFromSneaker(sneaker, fcSneaker, Ads.StartTime, i + 1, allstock.sneakers.Count); //тут есть ошибка. У аллстока может быть больше позиций чем для авито, так как некоторые ад могут нул вернуть и не добавиться. По правильному нужно сначала сделать первый прогон, заполнить все объявления и только потом добавлять дату постинга (зная точно кол-во объявлений)
                if (Ad != null)
                {
                    Ads.AdList.Add(Ad);
                }
            }
            return(Ads);
        }
Esempio n. 6
0
        private static BonanzaRoot CreateBonanzaRecords(AllStockRoot allstock, FullCatalogRoot fullCatalog)
        {
            ShopCatalogRoot shopCatalog = ShopCatalogController.LoadShopCatalogFromFtp();
            BonanzaRoot     bonanza     = new BonanzaRoot();

            foreach (var asSneaker in allstock.sneakers)
            {
                foreach (var asSize in asSneaker.sizes)
                {
                    Model.BonanzaModel.BonanzaRecord bRecord = GetBonanzaRecord(asSize, asSneaker, fullCatalog, shopCatalog);
                    if (bRecord != null)
                    {
                        bonanza.Records.Add(bRecord);
                    }
                }
            }

            return(bonanza);
        }
        private static HotOffersRoot GetHotOffers(AllStockRoot allStock)
        {
            /* Как определить лучшее предолжение? Горячий пирожок? Как найти самые большие скидки в нашей базе данных?
             * Я думаю что для нас выгодными будут предложения, которые с учетом доставки и ват будут на 30% или даже дешевле чем ритейл цена.
             * Что такое горячий пирожок? Это артикул, у которого есть несколько размеров, удовлетворяющих этому условию
             * Что мы заносим в пирожок?
             * - артикул,
             * - цену себестоимости,
             * - размеры которые попадают под это условия.
             *  - на каждый размер:
             *   - ссылка на магазин, где можно купить по этой цене данный размер
             *   - ссылки на изображения с нашего сервака (несколько изображений)
             *   - цена этого размера
             * - максимальную цену среди всех размеров (какие-то размеры дешевле, какие-то дороже
             * чтобы определить ритейл цену, берем среднюю цену без учета скидки всех размеров всех офферов
             */

            double          minMargin      = MIN_NEED_MARGIN; //минимальная маржа в долларах с пирожка. То есть минимальная стоимость разницы между ритейл ценой и себест. с доставкой и вычетом ват
            double          minSalePercent = 0.3;             //минимальная скидка в процентах
            var             myHotOffers    = new HotOffersRoot();
            FullCatalogRoot fullCatalog    = FullCatalog2.LoadFullCatalogFromFtp();

            foreach (var sneaker in allStock.sneakers)
            {
                var hOffer = GetHotOfferFromAllStockSneaker(sneaker, fullCatalog, minMargin, minSalePercent);
                if (hOffer != null)
                {
                    myHotOffers.offers.Add(hOffer);
                }
            }

            if (myHotOffers.offers.Count > 0)
            {
                return(myHotOffers);
            }
            else
            {
                return(null);
            }
        }
        public static void PostNewTodayItems(FullCatalogRoot fullCatalog = null)
        {
            if (fullCatalog == null)
            {
                fullCatalog = FullCatalog2.LoadFullCatalogFromFtp();
            }
            var allstock = AllStockExporter2.LoadLocalFile();
            var items    = fullCatalog.records.FindAll(x => DateTime.Now - x.add_time < new TimeSpan(24, 0, 0));
            var chatId   = "-1001116441282"; //"@sneaker_icon_new_today"

            var message = "New items today: " + items.Count;

            _logger.Info(message);
            Helper.TelegramPost(message, chatId);
            System.Threading.Thread.Sleep(15000);

            var count = items.Count;

            for (int i = 0; i < count; i++)
            {
                var item = items[i];
                var ret  = "\n";
                var m    = "New model in our store:\n";
                m += item.title + ret;
                m += "SKU: " + item.sku + ret;
                m += "Category: " + item.category + "\n";
                m += "Add time: " + item.add_time + ret;
                //m += "Link: " + item.link + "\n\n";
                foreach (var image in item.images)
                {
                    m += image + "\n";
                }


                _logger.Info("NewToday post sku:" + item.sku);
                Helper.TelegramPost(m, chatId);
                System.Threading.Thread.Sleep(15000);
            }
        }
        public static void SaveFullCatalogToFtp(FullCatalogRoot fullCatalogJson)
        {
            Program.Logger.Info("Upload FullCatalog To Ftp...");
            var    appSettings = System.Configuration.ConfigurationManager.AppSettings;
            string ftpHost     = appSettings["ftpHostSneakerIcon"];
            string ftpUser     = appSettings["ftpUserSneakerIcon"];
            string ftpPass     = appSettings["ftpPassSneakerIcon"];
            //string path = appSettings["fullCatalogFtpPath"];

            var folder        = "FullCatalog";
            var filename      = "FullCatalog.json";
            var localFileName = Config.GetConfig().DirectoryPathParsing + folder + @"\" + filename;

            var textJson = JsonConvert.SerializeObject(fullCatalogJson);

            System.IO.File.WriteAllText(localFileName, textJson);

            var ftpFileName = folder + "/" + filename;

            Helper.LoadFileToFtp(localFileName, ftpFileName, ftpHost, ftpUser, ftpPass);
            Program.Logger.Info("Uploaded FullCatalog Complete");
        }
        private static int CountItemsWithoutImages(FullCatalogRoot fullCatalog)
        {
            var itemsWithoutImage = fullCatalog.records.FindAll(x => x.images.Count == 0);

            return(itemsWithoutImage.Count);
        }
        private static HotOffer GetHotOfferFromAllStockSneaker(AllStockSneaker sneaker, FullCatalogRoot fullCatalog, double minMargin, double minSalePercent)
        {
            //определяем среднюю ритейл цену этого кросса в долларах
            var averageSneakerRegularPrice = GetAverageRegularPrice(sneaker);

            //смотрим, есть ли офферы, которые удовлетворяютм минимальным требованиям
            var sizes = GetHotOfferSizes(sneaker, averageSneakerRegularPrice, minMargin, minSalePercent);

            //если офферов больше нуля (ну то есть такие офферы, которые удовлетворяют условиям), то добавляем этот горячий пирожок в список горячих пирожков
            if (sizes.Count > 0)
            {
                var hOffer = new HotOffer();
                hOffer.sizes    = sizes;
                hOffer.sku      = sneaker.sku;
                hOffer.brand    = sneaker.brand;
                hOffer.title    = sneaker.title;
                hOffer.category = sneaker.category;
                var fcRecord = fullCatalog.records.Find(x => x.sku == sneaker.sku);
                if (fcRecord != null)
                {
                    hOffer.images = fcRecord.images;
                }
                hOffer.our_price     = hOffer.GetOurPrice();
                hOffer.regular_price = averageSneakerRegularPrice;
                hOffer.add_time      = DateTime.Now;
                return(hOffer);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 12
0
        private static string GetBonanzaRecordDescription(AllStockSize asSize, AllStockSneaker asSneaker, FullCatalogRoot fullCatalog)
        {
            var boothUrl = System.Configuration.ConfigurationManager.AppSettings["bonanzaBoothUrl"];
            var title    = asSneaker.title;
            var sku      = asSneaker.sku;
            var size     = SizeChart.GetSizeStatic(new Size(asSneaker.brand, asSneaker.category, asSize.us, null, null, null, null));

            if (size == null)
            {
                _logger.Warn("Ошибка в размере. sku: " + asSneaker.sku);
                return(null);
            }

            var sizeString = size.GetSizeStringUsEuUkCm();

            string description =
                "<h3 style=\"text-align: center;\"><strong>" +
                title.ToUpper() +
                "</strong></h3>" +
                "<h3 style=\"text-align: center;\"><strong>" +
                "STYLE: " + sku +
                "</strong></h3>" +
                "<h3 style=\"text-align: center;\"><strong>" +
                "SIZE: " + sizeString +
                "</strong></h3>" +
                "<h3 style=\"text-align: center;\"><strong>" +
                "100% AUTHENTIC" +
                "</strong></h3>" +
                "<h3 style=\"text-align: center;\"><strong>" +
                "WORLDWIDE SHIPPING FOR 5-10 DAYS IN DOUBLE BOX WITH TRACKING NUMBER.<br>" +
                "</strong></h3>" +
                "<h3 style=\"text-align: center;\"><strong>" +
                "SHIP IN 2 BUSINESS DAY." +
                "</strong></h3>";

            //description += "<h3 style=\"text-align: center;\"><strong>All sizes of this model available in stock</strong></h3>";

            //if (sizeList != null)
            //{
            //    if (sizeList.Count > 0)
            //    {
            //        foreach (var size in sizeList)
            //        {
            //            //725076-301+6.5US
            //            description += "<h4 style=\"text-align: center;\"><strong><a href=\"" + boothUrl + "?utf8=%E2%9C%93&amp;item_sort_options%5Bfilter_string%5D=" + sku + "+" + size + "US&amp;item_sort_options%5Bfilter_category_id%5D=&amp;item_sort_options%5Bcustom_category_id%5D=&amp;commit=Go\" rel=\"nofollow\" target=\"_blank\">Size " + size + " US</a></strong></h4>";
            //        }
            //    }
            //}

            description += "<h3 style=\"text-align: center;\"><strong>" +
                           "Other sizes of this model available in out stock: " +
                           "<a href=\"" + boothUrl + "?utf8=%E2%9C%93&amp;item_sort_options%5Bfilter_string%5D=" + sku + "&amp;item_sort_options%5Bfilter_category_id%5D=&amp;item_sort_options%5Bcustom_category_id%5D=&amp;commit=Go\" rel=\"nofollow\" target=\"_blank\">Link</a>" +
                           "</strong></h3>";

            description += "<h3 style=\"text-align: center;\"><strong>" + "Please feel free to ask any questions and see <a href=\"" + boothUrl + "\" rel=\"nofollow\" target=\"_blank\">all our listings</a> for more great deals." + "</strong></h3>";

            //throw new NotImplementedException();
            return(description);
        }
Esempio n. 13
0
 public VkExporter()
 {
     Allstock    = AllStockExporter2.LoadLocalFile();
     FullCatalog = FullCatalog2.LoadLocalFile();
     Posting     = new VkPosting();
 }
Esempio n. 14
0
        private static Model.BonanzaModel.BonanzaRecord GetBonanzaRecord(AllStockSize asSize, AllStockSneaker asSneaker, FullCatalogRoot fullCatalog, ShopCatalogRoot shopCatalog)
        {
            var fcSneaker = fullCatalog.records.Find(x => x.sku == asSneaker.sku);

            if (fcSneaker == null)
            {
                _logger.Warn("Артикул не найден в фулкаталоге. sku:" + asSneaker.sku);
                return(null);
            }
            var bRecord = new Model.BonanzaModel.BonanzaRecord();

            //standart data
            bRecord.quantity     = 5;
            bRecord.condition    = "New with box";
            bRecord.force_update = "true";
            bRecord.brand        = fcSneaker.brand;
            //shipping
            bRecord.shipping_price   = 29;
            bRecord.shipping_type    = "flat";
            bRecord.shipping_carrier = "usps";
            bRecord.shipping_service = "EconomyShipping";
            bRecord.shipping_package = "normal";
            //bRecord.worldwide_shipping_type = "flat";
            //bRecord.worldwide_shipping_price = 29;

            bRecord.id          = asSize.sku2;
            bRecord.description = GetBonanzaRecordDescription(asSize, asSneaker, fullCatalog);
            if (bRecord.description == null)
            {
                _logger.Warn("Пустое описание. sku2:" + bRecord.id);
                return(null);
            }

            bRecord.category = GetBonanzaCategory(asSneaker.category, fcSneaker.sex);
            bRecord.width    = GetBonanzaWidth(asSneaker.category);
            bRecord.title    = GetTitle(asSneaker.brand, asSize.us, asSneaker.sku, asSneaker.title);

            //price
            var offer = GetFirstActiveOffer(asSize, shopCatalog);

            //var offer = GetNonRussianOffer(asSize); //отфильтруем русские магазы
            if (offer == null)
            {
                return(null);
            }
            bRecord.price = GetPrice(offer);
            //double priceWithMargin = offer.price_usd_with_delivery_to_usa_and_minus_vat + MARGIN_USD;
            //double priceWithFeeMinusBonanzaDelivery = (priceWithMargin * 1.18) - 29;
            //priceWithFeeMinusBonanzaDelivery = Math.Round(priceWithFeeMinusBonanzaDelivery, 2);
            //bRecord.price = priceWithFeeMinusBonanzaDelivery.ToString("F", System.Globalization.CultureInfo.CreateSpecificCulture("en-US"));

            //images
            if (fcSneaker.images.Count == 0)
            {
                _logger.Warn("Нет изображений. sku2:" + bRecord.id);
                return(null);
            }
            bRecord.image1 = fcSneaker.images[0];
            if (fcSneaker.images.Count > 1)
            {
                bRecord.image2 = fcSneaker.images[1];
            }
            if (fcSneaker.images.Count > 2)
            {
                bRecord.image3 = fcSneaker.images[2];
            }
            if (fcSneaker.images.Count > 3)
            {
                bRecord.image4 = fcSneaker.images[3];
            }


            bRecord.size    = asSize.us;
            bRecord.traits  = "[[US Size:" + asSize.us + "]] ";
            bRecord.upc     = asSize.upc;
            bRecord.MPN     = fcSneaker.sku; //это вроде не работает
            bRecord.traits += "[[MPN:" + fcSneaker.sku + "]] ";


            return(bRecord);
        }
Esempio n. 15
0
        private static Model.BonanzaModel.BonanzaRecord GetBonanzaRecord_MultiListing(AllStockSneaker asSneaker, FullCatalogRoot fullCatalog)
        {
            //валидации
            //sizes
            if (asSneaker.sizes.Count == 0)
            {
                return(null);
            }
            //description
            var description = GetBonanzaRecordDescription_MultiListing(asSneaker, fullCatalog);

            if (description == null)
            {
                _logger.Warn("Пустое описание. sku:" + asSneaker.sku);
                return(null);
            }

            //инициализация
            var fcSneaker = fullCatalog.records.Find(x => x.sku == asSneaker.sku);
            var bRecord   = new Model.BonanzaModel.BonanzaRecord();

            //standart data
            bRecord.quantity     = 5; //нужно доработать, кол-во равно 5*кол-во размеров
            bRecord.condition    = "New with box";
            bRecord.force_update = "true";
            bRecord.brand        = fcSneaker.brand;
            bRecord.MPN          = fcSneaker.sku; //это вроде не работает
            bRecord.traits       = "[[MPN:" + fcSneaker.sku + "]] ";

            //color  (русские цвета добавляются, пока убрал)
            //if (!string.IsNullOrWhiteSpace(fcSneaker.color))
            //    bRecord.traits += "[[Color:" + fcSneaker.color + "]] ";

            //shipping
            bRecord.shipping_price   = 29;
            bRecord.shipping_type    = "flat";
            bRecord.shipping_carrier = "usps";
            bRecord.shipping_service = "EconomyShipping";
            bRecord.shipping_package = "normal";
            //bRecord.worldwide_shipping_type = "flat";
            //bRecord.worldwide_shipping_price = 29;

            //main
            bRecord.id          = fcSneaker.sku;
            bRecord.category    = GetBonanzaCategory(asSneaker.category, fcSneaker.sex);
            bRecord.width       = GetBonanzaWidth(asSneaker.category);
            bRecord.title       = GetTitle_MultiListing(asSneaker.brand, asSneaker.sku, asSneaker.title);
            bRecord.description = description;

            //images
            bool hasImages = GetImages(fcSneaker, bRecord);

            if (!hasImages)
            {
                return(null);
            }

            //делаем вариации
            //все предложения из русских магазов уже удалены
            bRecord.price = String.Empty;
            foreach (var size in asSneaker.sizes)
            {
                if (size.offers.Count > 0)
                {
                    var price = GetPrice(size.offers[0]);
                    bRecord.traits += "[[US Size:" + size.us + "][quantity:" + 5 + "][price:" + price + "]]";
                    if (bRecord.price == String.Empty)
                    {
                        bRecord.price = price;
                    }
                    if (Double.Parse(bRecord.price.Replace(".", ",")) > Double.Parse(price.Replace(".", ",")))
                    {
                        bRecord.price = price;
                    }
                }
            }
            if (bRecord.price == String.Empty)
            {
                _logger.Warn("Цена бонанза рекорд пустая. Sku: " + asSneaker.sku);
                var offer = asSneaker.sizes.Find(x => x.offers.Count > 0);
                return(null);
            }



            //price
            //var offer = GetNonRussianOffer_MultiListing(asSneaker); //отфильтруем русские магазы
            //if (offer == null)
            //    return null;
            //bRecord.price = GetPrice(offer);

            //bRecord.size = asSize.us;
            //bRecord.traits = "[[US Size:" + asSize.us + "]] ";
            //bRecord.upc = asSize.upc;


            return(bRecord);
        }
Esempio n. 16
0
        private static BonanzaRoot CreateBonanzaRecords_MultiListing(AllStockRoot allstock, FullCatalogRoot fullCatalog)
        {
            BonanzaRoot bonanza = new BonanzaRoot();

            foreach (var asSneaker in allstock.sneakers)
            {
                Model.BonanzaModel.BonanzaRecord bRecord = GetBonanzaRecord_MultiListing(asSneaker, fullCatalog);
                if (bRecord != null)
                {
                    bonanza.Records.Add(bRecord);
                }
            }

            return(bonanza);
        }
Esempio n. 17
0
        private VkGoodsItem PostItemToVk(FullCatalogRoot fullCatalog, AllStockSneaker artikul, VkGoodsRoot oldVkGoodsRoot)
        {
            try
            {
                var task = new VkTask();

                var fcSneaker = fullCatalog.records.Find(x => x.sku == artikul.sku);
                if (fcSneaker.images == null)
                {
                    return(null);
                }
                if (fcSneaker.images.Count == 0)
                {
                    return(null);
                }
                if (string.IsNullOrWhiteSpace(artikul.category))
                {
                    return(null);
                }
                if (artikul.sizes == null)
                {
                    return(null);
                }
                if (artikul.sizes.Count == 0)
                {
                    return(null);
                }

                task.Header = artikul.title.ToUpper() + " " + fcSneaker.sku;

                var sizeBlock = "";

                foreach (var size in artikul.sizes)
                {
                    var scSize       = SizeChart.GetSizeStatic(new Size(artikul.brand, artikul.category, size.us, null, null, null, null));
                    var priceSize    = size.offers[0].price_usd_with_delivery_to_usa_and_minus_vat;
                    var priceSizeRub = (int)CurrencyRate.ConvertCurrency("USD", "RUB", priceSize) + Margin;
                    if (scSize != null)
                    {
                        sizeBlock += scSize.GetAllSizeString() + ". Цена:" + priceSizeRub + Environment.NewLine;
                    }
                }

                var start = fcSneaker.type.ToLower() + " " + artikul.title.ToUpper() + Environment.NewLine;
                task.Description  = start.Substring(0, 1).ToUpper() + start.Remove(0, 1);
                task.Description += "Артикул: " + artikul.sku + Environment.NewLine;
                task.Description += "В оригинальной упаковке Nike." + Environment.NewLine;
                task.Description += "БЕСПЛАТНАЯ доставка по Москве" + Environment.NewLine;
                task.Description += "Доставка по России 3-5 дней компанией СДЭК." + Environment.NewLine;
                task.Description += "Стоимость доставки по РФ - 300 рублей." + Environment.NewLine;
                task.Description += "Доставка в регионы только по 100% предоплате, наложенным платежом не отправляем" + Environment.NewLine;
                task.Description += "Работаем с 2012 года, более 4000 моделей в ассортименте. Можете перейти в группу Вконтакте, чтобы убедиться в том, что мы продаем только оригинальную обувь. Никаких подделок и реплик!" + Environment.NewLine;
                task.Description += "В нашей группе Вконтакте более 70 реальных отзывов от клиентов!" + Environment.NewLine;
                task.Description += "Размеры в наличии:" + Environment.NewLine;
                task.Description += sizeBlock;
                task.Description += "Уточняйте наличие размеров." + Environment.NewLine;
                task.Description += "Если размера нет в наличии, можем его привезти под заказ. Срок поставки товара под заказ: 7-10 дней." + Environment.NewLine;
                task.Description += "Sneaker Icon - это большой выбор оригинальной брендовой обуви Nike и Jordan. Кроссовки, кеды, бутсы, футзалки, шиповки, сланцы, ботинки и другие типы обуви" + Environment.NewLine;


                var priceUsd = artikul.GetMinPrice();
                var priceRub = (int)CurrencyRate.ConvertCurrency("USD", "RUB", priceUsd) + Margin;
                task.Price     = priceRub;
                task.ImageList = fcSneaker.images;

                task.CollectionList = GetCollectionsName(fcSneaker.sku);
                //todo пока так. Нормально удаление сделаю, как попросят.
                task.IsDeleted = false;
                task.SKU       = fcSneaker.sku;

                var oldItem = oldVkGoodsRoot.Records.Where(x => x.SKU != null).FirstOrDefault(x => x.SKU.Equals(fcSneaker.sku));

                var result = Posting.AddOrEditVkGoods(task, oldItem);
                if (result != null)
                {
                    //todo подумать над информативностью. Тут не только именно отправленные данные.
                    _logger.Debug($"В товары ВК отправлен SKU {fcSneaker.sku} ID {result.VkId}");
                }

                return(result);
            }
            catch (Exception e)
            {
                _logger.Error(e, "Ошибка при добавлении товара в ВК");
                _logger.Error(e.StackTrace);
                return(null);
            }
        }
        private static int CountItemsWithoutCategory(FullCatalogRoot fullCatalogJson)
        {
            var itemsWithoutCategory = fullCatalogJson.records.FindAll(x => string.IsNullOrWhiteSpace(x.category));

            return(itemsWithoutCategory.Count);
        }