internal static void Import(КоммерческаяИнформация source,
                                    IShippingService shippingService,
                                    IDbContext dbContext,
                                    string warehouseMappingsFile,
                                    string mappingsFile,
                                    string logFile)
        {
            var warehouseMappings = ImportWarehouses(source, shippingService, warehouseMappingsFile, logFile);

            ImportOffers(source, dbContext, warehouseMappings, mappingsFile, logFile);
        }
 /// <summary>
 /// Импорт предложений
 /// </summary>
 /// <param name="logFile"></param>
 /// <param name="dir"></param>
 /// <param name="source"></param>
 private void ImportOffers(string logFile,
                           string dir,
                           КоммерческаяИнформация source)
 {
     XmlOffersImportService.Import(source,
                                   _shippingService,
                                   _dbContext,
                                   $"{dir}\\WarehouseMappings.json",
                                   $"{dir}\\ProductsMappings.json",
                                   logFile);
 }
        private static Dictionary <string, int> ImportWarehouses(КоммерческаяИнформация source,
                                                                 IShippingService shippingService,
                                                                 string warehouseMappingsFile,
                                                                 string logFile)
        {
            var stats = new[] { 0 };

            logFile.Log("Начало импорта складов");
            var warehouseMappings = File.Exists(warehouseMappingsFile)
                ? JsonConvert.DeserializeObject <Dictionary <string, int> >(File.ReadAllText(warehouseMappingsFile))
                : new Dictionary <string, int>();

            //todo: скорее всего класс изменится, когда будет больше складов, поэтому делаю коллекцию
            var whs = new[] { source.ПакетПредложений.Склады.Склад }.ToList();
            var warehouses = shippingService.GetAllWarehouses();

            foreach (var wh in whs)
            {
                if (!warehouseMappings.ContainsKey(wh.Ид) ||
                    warehouses.All(w => w.Id != warehouseMappings[wh.Ид]))
                {
                    var warehouse = new Warehouse
                    {
                        Name         = wh.Наименование,
                        AdminComment = wh.Ид
                    };
                    shippingService.InsertWarehouse(warehouse);
                    warehouseMappings[wh.Ид] = warehouse.Id;
                    stats[0]++;
                }
            }

            File.WriteAllText(warehouseMappingsFile, JsonConvert.SerializeObject(warehouseMappings, Formatting.Indented),
                              Encoding.UTF8);

            logFile.Log($"Импорт складов завершен. Добавлено: {stats[0]}.");
            return(warehouseMappings);
        }
        internal static List <Category> Import(КоммерческаяИнформация source,
                                               ICategoryService categoryService,
                                               IUrlRecordService urlRecordService,
                                               string mappingsFile,
                                               out Dictionary <string, int> outMappings,
                                               string logFile)
        {
            logFile.Log("Начало импорта категорий");

            var stats = new[] { 0, 0 };

            // key = 1c id, value = nopcommerce id
            var mappings = File.Exists(mappingsFile)
                ? JsonConvert.DeserializeObject <Dictionary <string, int> >(File.ReadAllText(mappingsFile))
                : new Dictionary <string, int>();

            var categories = categoryService.GetAllCategories(showHidden: true).ToList();

            var rootCategory = source.Классификатор.Группы.Группа;

            var rootItem = GetCategoryItem(rootCategory);

            if (rootItem.Items != null)
            {
                foreach (var child in rootItem.Items)
                {
                    ImportCategory(child, null, categoryService, urlRecordService, categories, mappings, stats, logFile);
                }
            }

            File.WriteAllText(mappingsFile, JsonConvert.SerializeObject(mappings, Formatting.Indented), Encoding.UTF8);
            logFile.Log($"Импорт категорий завершен. Привязано: {stats[0]}. Добавлено: {stats[1]}.");

            outMappings = mappings;
            return(categories);
        }
        /// <summary>
        /// Импорт
        /// </summary>
        /// <param name="updateExisting">обновлять существующие товары или игнорировать</param>
        /// <param name="importSpecificationAttributes">импортировать атрибуты</param>
        /// <param name="overwriteCategories">перезаписывать существующие категории или игнорировать</param>
        /// <param name="overwriteManufacturers">перезаписывать существующих производителей или игнорировать</param>
        /// <param name="logFile"></param>
        /// <param name="dir"></param>
        /// <param name="source"></param>
        private void Import(bool updateExisting,
                            bool importSpecificationAttributes,
                            bool overwriteCategories,
                            bool overwriteManufacturers,
                            string logFile,
                            string dir,
                            КоммерческаяИнформация source)
        {
            // add categories
            Dictionary <string, int> categoryMappings;
            var categories = XmlCategoryImportService.Import(
                source,
                _categoryService,
                _urlRecordService,
                $"{dir}\\CategoryMappings.json",
                out categoryMappings,
                logFile);

            // add attributes
            Dictionary <string, int>      attributesMappings;
            List <SpecificationAttribute> attributes;

            if (importSpecificationAttributes)
            {
                attributes = XmlSpecificationAttributesImportService.Import(
                    source,
                    _specificationAttributeService,
                    $"{dir}\\SpecificationAttributesMappings.json",
                    out attributesMappings,
                    logFile);
            }
            else
            {
                attributesMappings = new Dictionary <string, int>();
                attributes         = new List <SpecificationAttribute>();
            }

            // add manufacturers
            Dictionary <string, int> manufacturersMappings;
            var manufacturers = XmlManufacturerImportService.Import(
                source,
                _manufacturerService,
                _urlRecordService,
                $"{dir}\\ManufacturerMappings.json",
                out manufacturersMappings,
                logFile);

            XmlCatalogImportService.Import(source,
                                           _categoryService,
                                           _specificationAttributeService,
                                           _manufacturerService,
                                           _productService,
                                           _urlRecordService,
                                           _pictureService,
                                           categories,
                                           categoryMappings,
                                           attributes,
                                           attributesMappings,
                                           manufacturers,
                                           manufacturersMappings,
                                           $"{dir}\\ProductsMappings.json",
                                           logFile,
                                           new XmlCatalogImportService.ImportCatalogSettings
            {
                UpdateExisting = updateExisting,
                ImportSpecificationAttributes = importSpecificationAttributes,
                OverwriteCategories           = overwriteCategories,
                OverwriteManufacturers        = overwriteManufacturers
            });

            logFile.Log("Импорт завершен");
        }
        internal static List <SpecificationAttribute> Import(КоммерческаяИнформация source,
                                                             ISpecificationAttributeService specificationAttributeService,
                                                             string mappingsFile,
                                                             out Dictionary <string, int> outMappings,
                                                             string logFile)
        {
            logFile.Log("Начало импорта свойств");
            var stats = new[] { 0, 0, 0, 0 };

            // attribute: key = 1c id, value = nopcommerce id
            // attribute value: key = <1c attribute id>.<1c value id>, value = nopcommerce id
            var mappings = File.Exists(mappingsFile)
                ? JsonConvert.DeserializeObject <Dictionary <string, int> >(File.ReadAllText(mappingsFile))
                : new Dictionary <string, int>();;

            var attributes = specificationAttributeService.GetSpecificationAttributes().ToList();

            foreach (var attr in source.Классификатор.Свойства)
            {
                // ищем соответствие только по маппингу
                // потому что может быть несколько атрибутов с одинаковым названием

                var attribute = mappings.ContainsKey(attr.Ид)
                    ? attributes.FirstOrDefault(a => a.Id == mappings[attr.Ид])
                    : null;
                if (attribute != null)
                {
                    // для существующего только добавляем новые значения
                    if (attr.ТипЗначений == AttrTypeDictionary)
                    {
                        foreach (var attrOption in attr.ВариантыЗначений)
                        {
                            var key = $"{attr.Ид}.{attrOption.ИдЗначения}";

                            var option = mappings.ContainsKey(key)
                                ? attribute.SpecificationAttributeOptions.FirstOrDefault(o => o.Id == mappings[key])
                                : null;

                            if (option == null)
                            {
                                // ищем по имени
                                option = attribute.SpecificationAttributeOptions.FirstOrDefault(o => o.Name == attrOption.Значение);
                                if (option == null)
                                {
                                    // добавляем новое значение
                                    option = new Core.Domain.Catalog.SpecificationAttributeOption
                                    {
                                        SpecificationAttributeId = attribute.Id,
                                        Name = attrOption.Значение
                                    };
                                    specificationAttributeService.InsertSpecificationAttributeOption(option);
                                    attribute.SpecificationAttributeOptions.Add(option);
                                    //logFile.Log($"В существующий атрибут {attribute.Name} ({attribute.Id}) добавлено значение {option.Name}");
                                    stats[0]++;
                                }
                                else
                                {
                                    // мапим существующее значение
                                    //logFile.Log($"В существующем атрибуте {attribute.Name} ({attribute.Id}) добавлено сопоставление для значения {option.Name}");
                                    stats[1]++;
                                }
                                mappings[key] = option.Id;
                            }
                        }
                    }
                    continue;
                }

                // new attribute
                attribute = new Core.Domain.Catalog.SpecificationAttribute
                {
                    Name = attr.Наименование
                };
                specificationAttributeService.InsertSpecificationAttribute(attribute);
                attributes.Add(attribute);
                mappings[attr.Ид] = attribute.Id;
                //logFile.Log($"Новый атрибут {attribute.Name} ({attribute.Id})");
                stats[2]++;

                if (attr.ТипЗначений == AttrTypeDictionary)
                {
                    foreach (var attrOption in attr.ВариантыЗначений)
                    {
                        var key = $"{attr.Ид}.{attrOption.ИдЗначения}";

                        var option = new Core.Domain.Catalog.SpecificationAttributeOption
                        {
                            SpecificationAttributeId = attribute.Id,
                            Name = attrOption.Значение
                        };
                        specificationAttributeService.InsertSpecificationAttributeOption(option);
                        attribute.SpecificationAttributeOptions.Add(option);

                        mappings[key] = option.Id;
                        //logFile.Log($"В новый атрибут {attribute.Name} ({attribute.Id}) добавлено значение {option.Name}");
                        stats[3]++;
                    }
                }
                else
                {
                    var key    = $"{attr.Ид}.";
                    var option = new Core.Domain.Catalog.SpecificationAttributeOption
                    {
                        SpecificationAttributeId = attribute.Id,
                        Name = string.Empty
                    };
                    specificationAttributeService.InsertSpecificationAttributeOption(option);
                    attribute.SpecificationAttributeOptions.Add(option);

                    mappings[key] = option.Id;
                }
            }

            File.WriteAllText(mappingsFile, JsonConvert.SerializeObject(mappings, Formatting.Indented), Encoding.UTF8);
            logFile.Log($"Импорт свойств завершен. Привязано: {stats[0]} атрибутов и {stats[1]} значений. Добавлено: {stats[2]} атрибутов и {stats[3]} значений.");

            outMappings = mappings;
            return(attributes);
        }
Ejemplo n.º 7
0
        internal static void Import(КоммерческаяИнформация source,
                                    ICategoryService categoryService,
                                    ISpecificationAttributeService specificationAttributeService,
                                    IManufacturerService manufacturerService,
                                    IProductService productService,
                                    IUrlRecordService urlRecordService,
                                    IPictureService pictureService,
                                    List <Category> categories,
                                    Dictionary <string, int> categoryMappings,
                                    List <SpecificationAttribute> attributes,
                                    Dictionary <string, int> attributesMappings,
                                    List <Manufacturer> manufacturers,
                                    Dictionary <string, int> manufacturersMappings,
                                    string mappingsFile,
                                    string logFile,
                                    ImportCatalogSettings importSettings)

        {
            logFile.Log("Начало импорта товаров");
            var stats = new[] { 0, 0 };

            var mappings = File.Exists(mappingsFile)
                ? JsonConvert.DeserializeObject <Dictionary <string, int> >(File.ReadAllText(mappingsFile))
                : new Dictionary <string, int>();

            foreach (var prod in source.Каталог.Товары)
            {
                try
                {
                    var product = mappings.ContainsKey(prod.Ид)
                        ? productService.GetProductById(mappings[prod.Ид])
                        : null;

                    var deleted = prod.Статус == "Удален";
                    if (product == null)
                    {
                        product = new Product
                        {
                            CreatedOnUtc        = DateTime.Now,
                            UpdatedOnUtc        = DateTime.Now,
                            ProductType         = ProductType.SimpleProduct,
                            ProductTemplateId   = 1,
                            VisibleIndividually = true,
                            Name                 = prod.Наименование,
                            Sku                  = prod.Артикул,
                            ShortDescription     = prod.Описание,
                            FullDescription      = prod.Описание,
                            AllowCustomerReviews = true,
                            Deleted              = deleted,
                            Published            = !deleted,
                            OrderMinimumQuantity = 1,
                            OrderMaximumQuantity = 10000
                        };
                        productService.InsertProduct(product);
                        var seName = product.ValidateSeName(null, product.Name, true);
                        urlRecordService.SaveSlug(product, seName, 0);
                        //logFile.Log($"Новый товар {product.Name} ({product.Id}): {prod.Ид}");
                        stats[0]++;
                    }
                    else
                    {
                        if (!importSettings.UpdateExisting)
                        {
                            //logFile.Log($"Пропущен товар {product.Name} ({product.Id}): {prod.Ид}");
                            stats[1]++;
                            continue;
                        }
                        product.UpdatedOnUtc = DateTime.Now;
                        product.Deleted      = deleted;
                        product.Published    = !deleted;
                        productService.UpdateProduct(product);
                        //logFile.Log($"Обновлен товар {product.Name} ({product.Id}): {prod.Ид}");
                        stats[1]++;
                    }
                    mappings[prod.Ид] = product.Id;

                    if (importSettings.OverwriteManufacturers)
                    {
                        foreach (var manufacturer in product.ProductManufacturers.ToList())
                        {
                            manufacturerService.DeleteProductManufacturer(manufacturer);
                        }
                    }
                    if (prod.Изготовитель != null && manufacturersMappings.ContainsKey(prod.Изготовитель.Ид))
                    {
                        var manufacturerId = manufacturersMappings[prod.Изготовитель.Ид];
                        var manufacturer   = product.ProductManufacturers.FirstOrDefault(m => m.ManufacturerId == manufacturerId);
                        if (manufacturer == null)
                        {
                            manufacturer = new ProductManufacturer
                            {
                                ProductId      = product.Id,
                                ManufacturerId = manufacturerId
                            };
                            manufacturerService.InsertProductManufacturer(manufacturer);
                            product.ProductManufacturers.Add(manufacturer);
                        }
                    }

                    if (importSettings.OverwriteCategories)
                    {
                        foreach (var category in product.ProductCategories.ToList())
                        {
                            categoryService.DeleteProductCategory(category);
                        }
                    }
                    if (prod.Группы != null && categoryMappings.ContainsKey(prod.Группы.Ид))
                    {
                        var categoryId = categoryMappings[prod.Группы.Ид];
                        var category   = product.ProductCategories.FirstOrDefault(c => c.CategoryId == categoryId);
                        if (category == null)
                        {
                            category = new ProductCategory
                            {
                                ProductId  = product.Id,
                                CategoryId = categoryId
                            };
                            categoryService.InsertProductCategory(category);
                            product.ProductCategories.Add(category);
                        }
                    }

                    if (importSettings.ImportSpecificationAttributes && prod.ЗначенияСвойств != null)
                    {
                        foreach (var attr in prod.ЗначенияСвойств)
                        {
                            if (attributesMappings.ContainsKey(attr.Ид))
                            {
                                var emptyOptionKey = $"{attr.Ид}.";
                                if (attributesMappings.ContainsKey(emptyOptionKey))
                                {
                                    var option = product.ProductSpecificationAttributes
                                                 .FirstOrDefault(a => a.SpecificationAttributeOptionId == attributesMappings[emptyOptionKey]);
                                    if (option == null)
                                    {
                                        option = new ProductSpecificationAttribute
                                        {
                                            ProductId         = product.Id,
                                            ShowOnProductPage = true,
                                            AllowFiltering    = false,
                                            SpecificationAttributeOptionId = attributesMappings[emptyOptionKey],
                                            AttributeType = SpecificationAttributeType.CustomText,
                                            CustomValue   = attr.Значение
                                        };
                                        specificationAttributeService.InsertProductSpecificationAttribute(option);
                                        product.ProductSpecificationAttributes.Add(option);
                                    }
                                    else if (option.CustomValue != attr.Значение)
                                    {
                                        option.CustomValue = attr.Значение;
                                        specificationAttributeService.UpdateProductSpecificationAttribute(option);
                                    }
                                }
                                else
                                {
                                    var optionKey = $"{attr.Ид}.{attr.Значение}";

                                    var option = product.ProductSpecificationAttributes
                                                 .FirstOrDefault(o => o.SpecificationAttributeOptionId == attributesMappings[optionKey]);
                                    if (option == null)
                                    {
                                        var attribute = attributes.FirstOrDefault(a => a.Id == attributesMappings[attr.Ид]);
                                        var optionIds = attribute.SpecificationAttributeOptions.Select(o => o.Id);
                                        var options   = product.ProductSpecificationAttributes
                                                        .Where(a => optionIds.Contains(a.SpecificationAttributeOptionId)).ToList();
                                        if (options != null && options.Count > 0)
                                        {
                                            foreach (var opt in options)
                                            {
                                                product.ProductSpecificationAttributes.Remove(opt);
                                                specificationAttributeService.DeleteProductSpecificationAttribute(opt);
                                            }
                                        }

                                        option = new ProductSpecificationAttribute
                                        {
                                            ProductId         = product.Id,
                                            ShowOnProductPage = true,
                                            AllowFiltering    = true,
                                            SpecificationAttributeOptionId = attributesMappings[optionKey],
                                            AttributeType = SpecificationAttributeType.Option
                                        };
                                        specificationAttributeService.InsertProductSpecificationAttribute(option);
                                        product.ProductSpecificationAttributes.Add(option);
                                    }
                                }
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(prod.Картинка))
                    {
                        // todo: compare with existing images
                        var picturePath = HttpContext.Current.Request.MapPath($"~/Content/{prod.Картинка}");
                        var picture     = LoadPicture(pictureService, picturePath, product.Name);
                        if (picture != null)
                        {
                            product.ProductPictures.Add(new ProductPicture
                            {
                                DisplayOrder = 1,
                                PictureId    = picture.Id,
                                ProductId    = product.Id
                            });
                        }
                    }

                    File.WriteAllText(mappingsFile, JsonConvert.SerializeObject(mappings, Formatting.Indented), Encoding.UTF8);
                }
                catch (Exception ex)
                {
                    logFile.Log($"Ошибка при обработке товара {prod.Ид} ({prod.Наименование}): {ex}");
                }
            }

            logFile.Log($"Импорт товаров завершен. Добавлено: {stats[0]}. Обновлено: {stats[1]}.");
        }
Ejemplo n.º 8
0
        internal static List <Manufacturer> Import(КоммерческаяИнформация source,
                                                   IManufacturerService manufacturerService,
                                                   IUrlRecordService urlRecordService,
                                                   string mappingsFile,
                                                   out Dictionary <string, int> outMappings,
                                                   string logFile)
        {
            logFile.Log("Начало импорта производителей");
            var stats = new[] { 0, 0 };

            var mappings = File.Exists(mappingsFile)
                ? JsonConvert.DeserializeObject <Dictionary <string, int> >(File.ReadAllText(mappingsFile))
                : new Dictionary <string, int>();

            var manufacturers = manufacturerService.GetAllManufacturers(showHidden: true).ToList();

            var sourceManufacturers = source.Каталог.Товары
                                      .Where(t => t.Изготовитель != null)
                                      .Select(t => new { Id = t.Изготовитель.Ид, Name = t.Изготовитель.Наименование })
                                      .Distinct()
                                      .ToList();

            foreach (var man in sourceManufacturers)
            {
                var manufacturer = mappings.ContainsKey(man.Id)
                    ? manufacturers.FirstOrDefault(m => m.Id == mappings[man.Id])
                    : null;

                if (manufacturer == null)
                {
                    manufacturer = manufacturers.FirstOrDefault(m => m.Name == man.Name && !mappings.ContainsValue(m.Id));
                    if (manufacturer == null)
                    {
                        manufacturer = new Manufacturer
                        {
                            Name            = man.Name,
                            CreatedOnUtc    = DateTime.UtcNow,
                            UpdatedOnUtc    = DateTime.UtcNow,
                            Published       = true,
                            PageSize        = 6,
                            PageSizeOptions = "6, 3, 9",
                            AllowCustomersToSelectPageSize = true,
                            ManufacturerTemplateId         = 1
                        };
                        manufacturerService.InsertManufacturer(manufacturer);
                        var seName = manufacturer.ValidateSeName(null, manufacturer.Name, true);
                        urlRecordService.SaveSlug(manufacturer, seName, 0);
                        manufacturers.Add(manufacturer);
                        //logFile.Log($"Новый бренд {manufacturer.Name} ({manufacturer.Id}): {man.Id}");
                        stats[0]++;
                    }
                    else
                    {
                        //logFile.Log($"Существующий бренд {manufacturer.Name} ({manufacturer.Id}): {man.Id}");
                        stats[1]++;
                    }
                    mappings[man.Id] = manufacturer.Id;
                }
            }

            File.WriteAllText(mappingsFile, JsonConvert.SerializeObject(mappings, Formatting.Indented), Encoding.UTF8);
            logFile.Log($"Импорт производителей завершен. Привязано: {stats[1]}. Добавлено: {stats[0]}.");

            outMappings = mappings;
            return(manufacturers);
        }
        private static void ImportOffers(КоммерческаяИнформация source,
                                         IDbContext dbContext,
                                         Dictionary <string, int> warehouseMappings,
                                         string mappingsFile,
                                         string logFile)
        {
            var stats = new[] { 0 };

            logFile.Log("Начало импорта предложений");

            var mappings = File.Exists(mappingsFile)
                ? JsonConvert.DeserializeObject <Dictionary <string, int> >(File.ReadAllText(mappingsFile))
                : new Dictionary <string, int>();

            var sitePrice = new[] { source.ПакетПредложений.ТипыЦен.ТипЦены }.ToList()
            .FirstOrDefault(t => t.Наименование == "Для сайта");

            var sqlBuilder = new StringBuilder();

            foreach (var offer in source.ПакетПредложений.Предложения)
            {
                // только те продукты, которые были ранее добавлены
                if (!mappings.ContainsKey(offer.Ид))
                {
                    continue;
                }

                var productId = mappings[offer.Ид];

                //todo: скорее всего их будет потом несколько
                var whs = new[] { offer.Склад }.ToList();
                var whId     = 0;
                var quantity = 0;
                //todo: пока поддерживаем только 1 склад, потом нужно будет написать отдельный код для нескольких складов
                if (whs.Count > 0)
                {
                    var wh = whs[0];
                    whId     = warehouseMappings.ContainsKey(wh.ИдСклада) ? warehouseMappings[wh.ИдСклада] : 0;
                    quantity = wh.КоличествоНаСкладе;
                }

                decimal price = 0;
                if (sitePrice != null)
                {
                    var offerPrice = new[] { offer.Цены.Цена }.ToList().FirstOrDefault(p => p.ИдТипаЦены == sitePrice.Ид);
                    if (offerPrice != null)
                    {
                        price = offerPrice.ЦенаЗаЕдиницу;
                    }
                }

                stats[0]++;

                sqlBuilder.AppendLine($"UPDATE [{ProductTableName}] SET [WarehouseId]={whId}, [StockQuantity]={quantity}, [Price]={price.ToString(CultureInfo.InvariantCulture)} WHERE [Id]={productId};");

                // выполняем обновление БД пакетами по <packageSize> штук
                const int packageSize = 1000;
                if (stats[0] % packageSize == 0)
                {
                    try
                    {
                        dbContext.ExecuteSqlCommand(sqlBuilder.ToString(), true);
                        sqlBuilder.Clear();
                    }
                    catch (Exception ex)
                    {
                        logFile.Log($"Ошибка при обновлении пакета предложений: {stats[0] / packageSize}. {ex}");
                    }
                }
            }

            logFile.Log($"Импорт предложений завершен. Обновлено: {stats[0]}.");
        }