public ActionResult Create(ProductAttributeValue model, FormCollection form)
        {

            int tagId = int.Parse(form["tag"]);
            var tag = _repository.GetProductAttributeValueTag(tagId);

            _repository.LangId = CurrentLangId;
            var productAttributeValue = new ProductAttributeValue()
            {
                CurrentLang = model.CurrentLang,
                ProductAttributeId = model.ProductAttributeId,
                Title = model.Title,
                ProductAttributeValueTag = tag
            };
            try
            {
                _repository.AddProductAttributeValue(productAttributeValue);
                Cache.Default.Clear();
            }
            catch (Exception ex)
            {
                TempData["errorMessage"] = ex.Message;
            }
            return RedirectToAction("Index", new { id = productAttributeValue.ProductAttributeId });
        }
示例#2
0
 public int AddProductAttributeValue(ProductAttributeValue productAttributeValue)
 {
     _store.ProductAttributeValues.Add(productAttributeValue);
     CreateOrChangeEntityLanguage(productAttributeValue);
     _store.SaveChanges();
     return productAttributeValue.Id;
 }
示例#3
0
        private void CreateOrChangeEntityLanguage(ProductAttributeValue cache)
        {
            var categoryLang = _store.ProductAttributeValueLangs.FirstOrDefault(r => r.ProductAttributeValueId == cache.Id && r.LanguageId == LangId);
            if (categoryLang == null)
            {
                var entityLang = new ProductAttributeValueLang
                {
                    ProductAttributeValueId = cache.Id,
                    LanguageId = LangId,

                    Title = cache.Title,
                };
                _store.ProductAttributeValueLangs.Add(entityLang);
            }
            else
            {
                categoryLang.Title = cache.Title;
            }

        }
        public ActionResult Edit(ProductAttributeValue model, FormCollection form)
        {
            int tagId = int.Parse(form["tag"]);
            var tag = _repository.GetProductAttributeValueTag(tagId);

            _repository.LangId = CurrentLangId;
            try
            {
                var productAttributeValue = _repository.GetProductAttributeValue(model.Id);
                TryUpdateModel(productAttributeValue, new[] { "Title" });
                productAttributeValue.ProductAttributeValueTag = tag;
                _repository.SaveProductAttributeValue(productAttributeValue);
                Cache.Default.Clear();
                return RedirectToAction("Index", new { id = productAttributeValue.ProductAttributeId });
            }
            catch (Exception ex)
            {
                TempData["errorMessage"] = ex.Message;
                return View(model);
            }
        }
示例#5
0
 public void SaveProductAttributeValue(ProductAttributeValue productAttributeValue)
 {
     var cache = _store.ProductAttributeValues.Single(c => c.Id == productAttributeValue.Id);
     CreateOrChangeEntityLanguage(cache);
     _store.SaveChanges();
 }
示例#6
0
        public static ImportResult Execute(IShopRepository repository, StreamReader file, string categoryName, int currentLangId)
        {

            Log.DebugFormat("start importing products Execute");
            var res = new ImportResult { ErrorCode = 0, ProductErrors = new Dictionary<string, string>() };
            //var products = new List<ImportedProduct>();
            try
            {
                bool justAdded = false;
                int productCount = 0;

                Log.DebugFormat("read products from file");
                List<ImportedProduct> products = ReadProductsFromFile(file);
                var importedProductsCount = products.Count();
                Log.DebugFormat("total products {0}", importedProductsCount);

                var productStockToDelete = new List<int>();
                foreach (var importedProduct in products)
                {
                    productCount++;
                    if (string.IsNullOrEmpty(importedProduct.ExternalId))
                    {
                        res.ReadProductFailedCount++;
                        continue;
                    }



                    Log.DebugFormat("get product {0} of {1}", productCount, importedProductsCount);
                    var siteProduct = repository.GetProductByExternalId(importedProduct.ExternalId);

                    if (siteProduct == null)
                    {
                        try
                        {
                            // добавляем новый товар
                            var category = repository.GetCategory(categoryName);
                            var newProduct = new Product { Category = category };
                            newProduct.InjectFromImportProduct(importedProduct);
                            if (importedProduct.ImportedProductStocks != null)
                            {
                                foreach (var importedProductStock in importedProduct.ImportedProductStocks)
                                {
                                    newProduct.ProductStocks.Add(new ProductStock
                                    {
                                        StockNumber = importedProductStock.StockNumber,
                                        Color = importedProductStock.Color,
                                        Size = importedProductStock.Size,
                                        IsAvailable = importedProductStock.IsAvailable
                                    });

                                }
                            }
                            newProduct.SearchCriteriaAttributes = "";
                            repository.AddProduct(newProduct);
                            justAdded = true;
                            res.NewProductCount++;

                            //Log.Debug("get site product again");
                            siteProduct = repository.GetProductByExternalId(importedProduct.ExternalId);
                        }
                        catch (Exception ex)
                        {
                            res.ProductErrors.Add("Не удалось добавить " + importedProduct.ExternalId, ex.Message);
                            res.AddProductFailedCount++;

                            //Log.ErrorFormat("cannot add new product externalId:{0} exception message:{1}", importedProduct.ExternalId, ex.Message);
                        }
                    }




                    if (siteProduct != null)
                    {
                        try
                        {
                            siteProduct.InjectFromImportProduct(importedProduct);
                            if (siteProduct.ProductStocks == null)
                            {
                                siteProduct.ProductStocks = new LinkedList<ProductStock>();
                            }


                            //Log.DebugFormat("Updating product stocks started");
                            foreach (var productStock in siteProduct.ProductStocks)
                            {
                                var importedProductStock =
                                    importedProduct.ImportedProductStocks.FirstOrDefault(
                                        ips => ips.StockNumber == productStock.StockNumber && !ips.Imported);
                                if (importedProductStock != null)
                                {
                                    // update productStock in siteProduct.ProductStocks
                                    importedProductStock.Imported = true;
                                    productStock.Size = importedProductStock.Size;
                                    productStock.Color = importedProductStock.Color;
                                    productStock.IsAvailable = importedProductStock.IsAvailable;
                                    res.UpdatedArticles++;
                                }
                                else
                                {
                                    // remove productStock from siteProduct.ProductStocks
                                    //repository.DeleteProductStock(productStock.Id);
                                    productStockToDelete.Add(productStock.Id);
                                    res.DeletedArticles++;
                                }
                            }



                            foreach (
                                var importedProductStock in
                                    importedProduct.ImportedProductStocks.Where(ips => !ips.Imported))
                            {
                                siteProduct.ProductStocks.Add(new ProductStock
                                {
                                    StockNumber = importedProductStock.StockNumber,
                                    Color = importedProductStock.Color,
                                    Size = importedProductStock.Size,
                                    IsAvailable = importedProductStock.IsAvailable
                                });
                                res.AddedArticles++;
                            }
                            //Log.DebugFormat("Updating product stocks finished");


                            //Log.DebugFormat("Updating product attributes started");
                            foreach (var attributeGroup in importedProduct.ImportedProductAttibutes)
                            {
                                var attrToDelete = new List<int>();
                                var exId = attributeGroup.ExternalId;
                                //Log.DebugFormat("get site attr started");
                                var siteAttr =
                                    siteProduct.ProductAttributeValues.Where(
                                        pav => pav.ProductAttribute.ExternalId == exId).Select(a => a.Title).ToList();
                                //Log.DebugFormat("get site attr finished");

                                var xx = siteAttr.Except(attributeGroup.Values).ToList(); //  items to delete
                                var xy = attributeGroup.Values.Except(siteAttr).ToList(); //  items to add

                                List<string> addedAttr = new List<string>();

                                //Log.DebugFormat("get attr to delete started");
                                foreach (
                                    var attr in
                                        siteProduct.ProductAttributeValues.Where(
                                            pav => pav.ProductAttribute.ExternalId == exId))
                                {
                                    if (xx.Contains(attr.Title))
                                    {
                                        attrToDelete.Add(attr.Id);
                                    }
                                }
                                //Log.DebugFormat("get attr to delete finished");

                                //Log.DebugFormat("ProductAttributeValues.Remove started");
                                foreach (var id in attrToDelete)
                                {
                                    var a = repository.GetProductAttributeValue(id);
                                    siteProduct.ProductAttributeValues.Remove(a);
                                }
                                //Log.DebugFormat("ProductAttributeValues.Remove finished");

                                //Log.DebugFormat("repository.GetProductAttributes(siteProduct.CategoryId) started");
                                var productAttributes = repository.GetProductAttributes(siteProduct.CategoryId);
                                //Log.DebugFormat("repository.GetProductAttributes(siteProduct.CategoryId) finished");


                                //Log.DebugFormat("siteProduct.ProductAttributeValues.Add(attributeValue) started");
                                var productAttribute = productAttributes.FirstOrDefault(pa => pa.ExternalId == exId);
                                if (productAttribute == null)
                                {
                                    //Log.ErrorFormat("Атрибут с идентификатором {0} не найден", exId);
                                    throw new Exception("Атрибут с идентификатором " + exId + " не найден");
                                }
                                foreach (var attributeValue in productAttribute.ProductAttributeValues)
                                {
                                    if (xy.Contains(attributeValue.Title))
                                    {
                                        siteProduct.ProductAttributeValues.Add(attributeValue);
                                        addedAttr.Add(attributeValue.Title);
                                    }
                                }
                                //Log.DebugFormat("siteProduct.ProductAttributeValues.Add(attributeValue) finished");


                                //Log.DebugFormat("add new attributes started");
                                var attrNotFoundOnSite = xy.Except(addedAttr);
                                foreach (string s in attrNotFoundOnSite)
                                {
                                    var newProductAttributeValue = new ProductAttributeValue
                                    {
                                        CurrentLang = currentLangId,
                                        Title = s,
                                        ProductAttribute = productAttribute,
                                    };
                                    newProductAttributeValue.Products.Add(siteProduct);

                                    repository.AddProductAttributeValue(newProductAttributeValue);
                                }
                                //Log.DebugFormat("add new attributes finished");

                            }
                            //Log.DebugFormat("Updating product attributes finished");



                            Log.DebugFormat("save product {0} of {1}", productCount, importedProductsCount);
                            repository.SaveProduct(siteProduct);

                            //Log.DebugFormat("product saved {0} of {1}", productCount, importedProductsCount);

                            if (!justAdded)
                            {
                                res.UpdatedProductCount++;
                            }
                            else
                            {
                                justAdded = false;
                            }
                        }
                        catch (OutOfMemoryException ex)
                        {

                            Log.ErrorFormat("cannot update product externalId:{0} exception message:{1} exception{2}", siteProduct.ExternalId, ex.Message, ex);
                            throw new Exception(ex.Message);
                        }
                        catch (Exception ex)
                        {
                            res.ProductErrors.Add("Не удалось обновить " + siteProduct.ExternalId, ex.Message);
                            res.UpdateProductFailedCount++;

                            Log.ErrorFormat("cannot update product externalId:{0} exception message:{1}", siteProduct.ExternalId, ex.Message);

                        }
                    }
                }

                //Log.DebugFormat("deleting product stocks");
                foreach (var id in productStockToDelete)
                {
                    repository.DeleteProductStock(id);
                }
                //Log.DebugFormat("product stocks deleted");

                res.ProductCount = products.Count;
            }
            catch (Exception ex)
            {
                Log.DebugFormat("error while importing products {1}", ex.Message);
                res.ErrorMessage = ex.Message;
                res.ErrorCode = 1;
            }

            //Log.DebugFormat("finish importing products Execute");

            return res;
        }
示例#7
0
        private static void Run(string[] args)
        {
            int currentLangId = 1;
            IShopStore store = new ShopStore();

            IShopRepository repository = new ShopRepository(store);
            repository.LangId = currentLangId;


            string filename = args.Length == 0 ? "1 output.bikes.27.12.2014 13_15_56.csv" : args[0];

            int rowCounter = 0;
            string rowExternalId = string.Empty;
            var products = new List<ImportedProduct>();
            string oldId = string.Empty;
            ImportedProduct currentProduct = null;
            var fieldMapping = new Dictionary<string, int>();
            var attributeMapping = new Dictionary<string, int>();
            int failedProducts = 0;
            var failedProductsExternalIds = new List<string>();

            try
            {
                System.Console.WriteLine("Чтение файла {0}...", filename);
                var lines = System.IO.File.ReadLines(filename, Encoding.GetEncoding(1251)).ToList();
                System.Console.WriteLine("Всего строк: {0}", lines.Count);
                System.Console.WriteLine("Формирование списка товаров...");

                foreach (var line in lines)
                {
                    rowCounter++;
                    string[] x = line.Split(new[] { ";" }, StringSplitOptions.None);
                    if (rowCounter == 1)
                    {
                        System.Console.WriteLine("Чтение полей и атрибутов товара");
                        for (int i = 0; i < x.Length; i++)
                        {
                            if (string.IsNullOrEmpty(x[i]))
                                throw new Exception("Невозможно прочитать имя поля");

                            if (TransferData.ProductFields.ContainsKey(x[i]))
                            {
                                if (fieldMapping.ContainsKey(x[i]))
                                    throw new Exception("Дубль поля " + x[i] + ". Данное поле уже добавлено в коллекцию");
                                fieldMapping.Add(x[i], i);
                                System.Console.WriteLine("Добвлено поле {0}", x[i]);
                            }
                            else
                            {
                                if (attributeMapping.ContainsKey(x[i]))
                                    throw new Exception("Дубль атрибута " + x[i] + ". Данный атрибут уже добавлен в коллекцию");
                                attributeMapping.Add(x[i], i);
                                System.Console.WriteLine("Добвлен атрибут {0}", x[i]);
                            }
                        }

                        System.Console.WriteLine("Всего полей: {0}", fieldMapping.Count);
                        System.Console.WriteLine("Всего атрибутов: {0}", attributeMapping.Count);

                    }
                    if (rowCounter > 2)
                    {

                        //string newId = x[fieldMapping["ExternalId"]];

                        //rowExternalId = newId;

                        rowExternalId = x[fieldMapping["ExternalId"]];


                        ImportedProduct product = products.FirstOrDefault(p => p.ExternalId == rowExternalId);
                        if(product==null)
                        {
                            product = new ImportedProduct
                            {
                                ExternalId = ParseStringValue(x[fieldMapping["ExternalId"]]),
                                Name = ParseStringValue(x[fieldMapping["Name"]]),
                                Title = ParseStringValue(x[fieldMapping["Title"]]),
                                OldPrice = ConvertToDecimalValue(x[fieldMapping["OldPrice"]]),
                                Price = ConvertToDecimalValue(x[fieldMapping["Price"]]),
                                IsNew = ConvertToBooleanValue(x[fieldMapping["IsNew"]]),
                                IsDiscount = ConvertToBooleanValue(x[fieldMapping["IsDiscount"]]),
                                IsTopSale = ConvertToBooleanValue(x[fieldMapping["IsTopSale"]]),
                                //IsActive = ConvertToBooleanValue(x[fieldMapping["IsActive"]]),

                                //SeoDescription = x[fieldMapping["SeoDescription"]],
                                //SeoKeywords = x[fieldMapping["SeoKeywords"]],
                                //SeoText = x[fieldMapping["SeoText"]],

                                ImportedProductStocks = new List<ImportedProductStock>(),
                                //ImportedProductAttibutes = new Dictionary<string, string>()
                                ImportedProductAttibutes = new List<ImportedProductAttribute>()
                            };

                            if (fieldMapping.ContainsKey("SeoDescription"))
                            {
                                product.SeoDescription = ParseStringValue(x[fieldMapping["SeoDescription"]]);
                            }
                            if (fieldMapping.ContainsKey("SeoKeywords"))
                            {
                                product.SeoKeywords = ParseStringValue(x[fieldMapping["SeoKeywords"]]);
                            }
                            if (fieldMapping.ContainsKey("SeoText"))
                            {
                                product.SeoText = ParseStringValue(x[fieldMapping["SeoText"]]);
                            }

                            if (!string.IsNullOrEmpty(x[fieldMapping["ProductStock.StockNumber"]]))
                            {
                                product.ImportedProductStocks.Add(new ImportedProductStock
                                {
                                    StockNumber = ParseStringValue(x[fieldMapping["ProductStock.StockNumber"]]),
                                    Size = ParseStringValue(x[fieldMapping["ProductStock.Size"]]),
                                    Color = ParseStringValue(x[fieldMapping["ProductStock.Color"]]),
                                    IsAvailable = ConvertToBooleanValue(x[fieldMapping["ProductStock.IsAvailable"]]),
                                    Price = ConvertToDecimalValue(x[fieldMapping["Price"]]),
                                    OldPrice = ConvertToDecimalValue(x[fieldMapping["OldPrice"]])
                                });
                            }


                            foreach (var attr in attributeMapping)
                            {
                                var importedAttributes = x[attributeMapping[attr.Key]];
                                string[] attributes = importedAttributes.Split(new[] { "#" }, StringSplitOptions.RemoveEmptyEntries);
                                var importedProductAttribute = new ImportedProductAttribute
                                {
                                    ExternalId = attr.Key,
                                    Values = new List<string>()
                                };
                                foreach (var attribute in attributes)
                                {
                                    importedProductAttribute.Values.Add(ParseStringValue(attribute));
                                }
                                product.ImportedProductAttibutes.Add(importedProductAttribute);
                            }

                            products.Add(product);

                        }
                        else
                        {
                            if (!string.IsNullOrEmpty(x[fieldMapping["ProductStock.StockNumber"]]))
                            {
                                product.ImportedProductStocks.Add(new ImportedProductStock
                                {
                                    StockNumber = ParseStringValue(x[fieldMapping["ProductStock.StockNumber"]]),
                                    Size = ParseStringValue(x[fieldMapping["ProductStock.Size"]]),
                                    Color = ParseStringValue(x[fieldMapping["ProductStock.Color"]]),
                                    IsAvailable = ConvertToBooleanValue(x[fieldMapping["ProductStock.IsAvailable"]]),
                                    Price = ConvertToDecimalValue(x[fieldMapping["Price"]]),
                                    OldPrice = ConvertToDecimalValue(x[fieldMapping["OldPrice"]])
                                });
                            }

                            foreach (var attr in attributeMapping)
                            {
                                var importedAttributes = x[attributeMapping[attr.Key]];
                                string[] attributes = importedAttributes.Split(new[] { "#" }, StringSplitOptions.RemoveEmptyEntries);


                                var importedProductAttribute = product.ImportedProductAttibutes.FirstOrDefault(ipa => ipa.ExternalId == attr.Key);
                                if (importedProductAttribute == null)
                                {
                                    importedProductAttribute = new ImportedProductAttribute
                                    {
                                        ExternalId = attr.Key,
                                        Values = new List<string>()
                                    };
                                    foreach (var attribute in attributes)
                                    {
                                        var value = ParseStringValue(attribute);
                                        importedProductAttribute.Values.Add(value);
                                    }
                                    product.ImportedProductAttibutes.Add(importedProductAttribute);
                                }
                                else
                                {
                                    foreach (var attribute in attributes)
                                    {
                                        var value = ParseStringValue(attribute);
                                        if (!importedProductAttribute.Values.Contains(value))
                                        {
                                            importedProductAttribute.Values.Add(value);
                                        }
                                    }
                                }
                                
                            }
                        }


                       
                    }
                }

                foreach (var importedProduct in products)
                {
                    var price = importedProduct.ImportedProductStocks.FirstOrDefault(p => p.IsAvailable);
                    importedProduct.Price = price != null ? price.Price : 0;
                    importedProduct.OldPrice = price != null ? price.OldPrice : 0;
                }

                System.Console.ForegroundColor = ConsoleColor.Green;
                System.Console.WriteLine("Прочитано и создано товаров: {0}", products.Count);

                System.Console.ForegroundColor = ConsoleColor.Red;
                System.Console.WriteLine("Найдено дублей: {0}", failedProducts);
                foreach (var failedProductsExternalId in failedProductsExternalIds)
                {
                    System.Console.WriteLine(failedProductsExternalId);
                }
                System.Console.ForegroundColor = ConsoleColor.White;


                //foreach (var product in products)
                //{
                //    System.Console.WriteLine(product);
                //}

            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Ошибка чтения файла. {0}", ex.Message + " строка:" + rowCounter + " ExternalId:" + rowExternalId));
            }



            



            var categoryName = filename.Split(new[] { "." }, StringSplitOptions.None)[1];


            System.Console.ForegroundColor = ConsoleColor.Green;
            System.Console.WriteLine("Старт процедуры апдейта товаров:");
            System.Console.ForegroundColor = ConsoleColor.White;




            var res = new ImportResult { ErrorCode = 0, ProductErrors = new Dictionary<string, string>() };


            try
            {
                bool justAdded = false;
                int productCount = 0;


                List<int> productStockToDelete = new List<int>();


                System.Console.WriteLine("Всего товаров: {0}", products.Count);

                foreach (var importedProduct in products)
                {



                    productCount++;
                    if (string.IsNullOrEmpty(importedProduct.ExternalId))
                    {
                        res.ReadProductFailedCount++;
                        continue;
                    }


                    System.Console.ForegroundColor = ConsoleColor.Green;
                    System.Console.WriteLine("Обработка {0} из {1}", productCount, products.Count);
                    System.Console.ForegroundColor = ConsoleColor.White;

                    System.Console.Write("Ищем в базе товар с ExternalId: {0}...", importedProduct.ExternalId);
                    var siteProduct = repository.GetProductByExternalId(importedProduct.ExternalId);
                    System.Console.WriteLine("ОК");

                    if (siteProduct == null)
                    {
                        try
                        {
                            System.Console.Write(" Добавляем новый товар..");
                            var category = repository.GetCategory(categoryName);
                            var newProduct = new Product { Category = category };
                            newProduct.InjectFromImportProduct(importedProduct);
                            if (importedProduct.ImportedProductStocks != null)
                            {
                                foreach (var importedProductStock in importedProduct.ImportedProductStocks)
                                {
                                    newProduct.ProductStocks.Add(new ProductStock
                                    {
                                        StockNumber = importedProductStock.StockNumber,
                                        Color = importedProductStock.Color,
                                        Size = importedProductStock.Size,
                                        IsAvailable = importedProductStock.IsAvailable
                                    });

                                }
                            }
                            newProduct.SearchCriteriaAttributes = "";
                            repository.AddProduct(newProduct);
                            justAdded = true;
                            res.NewProductCount++;
                            System.Console.WriteLine("ОК");


                            siteProduct = repository.GetProductByExternalId(importedProduct.ExternalId);
                        }
                        catch (Exception ex)
                        {
                            System.Console.WriteLine(" Не удалось добавить {0}", importedProduct.ExternalId);
                            res.ProductErrors.Add("Не удалось добавить " + importedProduct.ExternalId, ex.Message);
                            res.AddProductFailedCount++;
                        }
                    }


                    //var siteProduct = repository.FindProduct(importedProduct.Id);
                    if (siteProduct != null)
                    {
                        try
                        {
                            System.Console.Write(" Обновление данных товара...");
                            siteProduct.InjectFromImportProduct(importedProduct);
                            System.Console.WriteLine("ОК");
                            if (siteProduct.ProductStocks == null)
                            {
                                siteProduct.ProductStocks = new LinkedList<ProductStock>();
                            }


                            System.Console.Write(" Обновление данных артикулов...");
                            foreach (var productStock in siteProduct.ProductStocks)
                            {
                                var importedProductStock = importedProduct.ImportedProductStocks.FirstOrDefault(ips => ips.StockNumber == productStock.StockNumber && !ips.Imported);
                                if (importedProductStock != null)
                                {
                                    // update productStock in siteProduct.ProductStocks
                                    importedProductStock.Imported = true;
                                    productStock.Size = importedProductStock.Size;
                                    productStock.Color = importedProductStock.Color;
                                    productStock.IsAvailable = importedProductStock.IsAvailable;
                                    res.UpdatedArticles++;
                                }
                                else
                                {
                                    // remove productStock from siteProduct.ProductStocks
                                    //repository.DeleteProductStock(productStock.Id);
                                    productStockToDelete.Add(productStock.Id);
                                    res.DeletedArticles++;
                                }
                            }

                            foreach (var importedProductStock in importedProduct.ImportedProductStocks.Where(ips => !ips.Imported))
                            {
                                siteProduct.ProductStocks.Add(new ProductStock
                                {
                                    StockNumber = importedProductStock.StockNumber,
                                    Color = importedProductStock.Color,
                                    Size = importedProductStock.Size,
                                    IsAvailable = importedProductStock.IsAvailable
                                });
                                res.AddedArticles++;
                            }
                            System.Console.WriteLine("ОК");


                            System.Console.Write(" Обновление атрибутов...");
                            foreach (var attributeGroup in importedProduct.ImportedProductAttibutes)
                            {
                                var attrToDelete = new List<int>();
                                var exId = attributeGroup.ExternalId;
                                var siteAttr = siteProduct.ProductAttributeValues.Where(pav => pav.ProductAttribute.ExternalId == exId).Select(a => a.Title).ToList();

                                var xx = siteAttr.Except(attributeGroup.Values).ToList(); //  items to delete
                                var xy = attributeGroup.Values.Except(siteAttr).ToList(); //  items to add

                                List<string> addedAttr = new List<string>();

                                foreach (var attr in siteProduct.ProductAttributeValues.Where(pav => pav.ProductAttribute.ExternalId == exId))
                                {
                                    if (xx.Contains(attr.Title))
                                    {
                                        //siteProduct.ProductAttributeValues.Remove(attr);
                                        attrToDelete.Add(attr.Id);
                                    }
                                }

                                foreach (var id in attrToDelete)
                                {
                                    var a = repository.GetProductAttributeValue(id);
                                    siteProduct.ProductAttributeValues.Remove(a);
                                }


                                var productAttributes = repository.GetProductAttributes(siteProduct.CategoryId);

                                var productAttribute = productAttributes.FirstOrDefault(pa => pa.ExternalId == exId);
                                if (productAttribute == null)
                                    throw new Exception("Атрибут с идентификатором " + exId + " не найден");
                                foreach (var attributeValue in productAttribute.ProductAttributeValues)
                                {
                                    if (xy.Contains(attributeValue.Title))
                                    {
                                        siteProduct.ProductAttributeValues.Add(attributeValue);
                                        addedAttr.Add(attributeValue.Title);
                                    }
                                }


                                var attrNotFoundOnSite = xy.Except(addedAttr);
                                foreach (string s in attrNotFoundOnSite)
                                {
                                    var newProductAttributeValue = new ProductAttributeValue
                                    {
                                        CurrentLang = currentLangId,
                                        Title = s,
                                        ProductAttribute = productAttribute,
                                    };
                                    newProductAttributeValue.Products.Add(siteProduct);

                                    repository.AddProductAttributeValue(newProductAttributeValue);
                                }


                            }
                            System.Console.WriteLine("ОК");

                            System.Console.Write(" Сохранение товара в базе...");
                            repository.SaveProduct(siteProduct);
                            System.Console.WriteLine("ОК");


                            if (!justAdded)
                            {
                                res.UpdatedProductCount++;
                            }
                            else
                            {
                                justAdded = false;
                            }


                        }
                        catch (Exception ex)
                        {
                            System.Console.ForegroundColor = ConsoleColor.Red;
                            System.Console.WriteLine("Не удалось обновить {0}, {1}", siteProduct.ExternalId, ex.Message);
                            res.ProductErrors.Add("Не удалось обновить " + siteProduct.ExternalId, ex.Message);
                            res.UpdateProductFailedCount++;
                            System.Console.ForegroundColor = ConsoleColor.White;
                        }
                    }


                }


                System.Console.Write(" Удаление несвуществующих артикулов...");
                foreach (var id in productStockToDelete)
                {
                    repository.DeleteProductStock(id);
                }
                System.Console.WriteLine("ОК");


                res.ProductCount = products.Count;
            }
            catch (Exception ex)
            {
                res.ErrorMessage = ex.Message;
                res.ErrorCode = 1;
            }
            finally
            {
                //file.Close();
            }





        }