Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

ProductService.cs

By: a guest on Sep 19th, 2011  |  syntax: C#  |  size: 146.71 KB  |  hits: 52  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. //------------------------------------------------------------------------------
  2. // The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
  3. // You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx.
  4. //
  5. // Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
  6. // See the License for the specific language governing rights and limitations under the License.
  7. //
  8. // The Original Code is nopCommerce.
  9. // The Initial Developer of the Original Code is NopSolutions.
  10. // All Rights Reserved.
  11. //
  12. // Contributor(s): _______.
  13. //------------------------------------------------------------------------------
  14.  
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Data.Objects;
  18. using System.Linq;
  19. using System.Web;
  20. using NopSolutions.NopCommerce.BusinessLogic.Audit;
  21. using NopSolutions.NopCommerce.BusinessLogic.Caching;
  22. using NopSolutions.NopCommerce.BusinessLogic.Categories;
  23. using NopSolutions.NopCommerce.BusinessLogic.Configuration.Settings;
  24. using NopSolutions.NopCommerce.BusinessLogic.CustomerManagement;
  25. using NopSolutions.NopCommerce.BusinessLogic.Data;
  26. using NopSolutions.NopCommerce.BusinessLogic.Directory;
  27. using NopSolutions.NopCommerce.BusinessLogic.Infrastructure;
  28. using NopSolutions.NopCommerce.BusinessLogic.Localization;
  29. using NopSolutions.NopCommerce.BusinessLogic.Manufacturers;
  30. using NopSolutions.NopCommerce.BusinessLogic.Media;
  31. using NopSolutions.NopCommerce.BusinessLogic.Messages;
  32. using NopSolutions.NopCommerce.BusinessLogic.NetC;
  33. using NopSolutions.NopCommerce.BusinessLogic.Orders;
  34. using NopSolutions.NopCommerce.BusinessLogic.Products.Attributes;
  35. using NopSolutions.NopCommerce.BusinessLogic.Products.Specs;
  36. using NopSolutions.NopCommerce.BusinessLogic.Promo.Discounts;
  37. using NopSolutions.NopCommerce.Common;
  38. using NopSolutions.NopCommerce.Common.Utils;
  39.  
  40. namespace NopSolutions.NopCommerce.BusinessLogic.Products
  41. {
  42.     /// <summary>
  43.     /// Product service
  44.     /// </summary>
  45.     public partial class ProductService : IProductService
  46.     {
  47.         #region Constants
  48.         private const string PRODUCTS_BY_ID_KEY = "Nop.product.id-{0}";
  49.         private const string PRODUCTVARIANTS_ALL_KEY = "Nop.productvariant.all-{0}-{1}";
  50.         private const string PRODUCTVARIANTS_BY_ID_KEY = "Nop.productvariant.id-{0}";
  51.         private const string TIERPRICES_ALLBYPRODUCTVARIANTID_KEY = "Nop.tierprice.allbyproductvariantid-{0}";
  52.         private const string CUSTOMERROLEPRICES_ALL_KEY = "Nop.customerroleproductprice.all-{0}";
  53.         private const string PRODUCTS_PATTERN_KEY = "Nop.product.";
  54.         private const string PRODUCTVARIANTS_PATTERN_KEY = "Nop.productvariant.";
  55.         private const string TIERPRICES_PATTERN_KEY = "Nop.tierprice.";
  56.         private const string CUSTOMERROLEPRICES_PATTERN_KEY = "Nop.customerroleproductprice.";
  57.         #endregion
  58.  
  59.         #region Fields
  60.  
  61.         /// <summary>
  62.         /// Object context
  63.         /// </summary>
  64.         private readonly NopObjectContext _context;
  65.  
  66.         /// <summary>
  67.         /// Cache manager
  68.         /// </summary>
  69.         private readonly ICacheManager _cacheManager;
  70.  
  71.         #endregion
  72.  
  73.         #region Ctor
  74.  
  75.         /// <summary>
  76.         /// Ctor
  77.         /// </summary>
  78.         /// <param name="context">Object context</param>
  79.         public ProductService(NopObjectContext context)
  80.         {
  81.             this._context = context;
  82.             this._cacheManager = new NopRequestCache();
  83.         }
  84.  
  85.         #endregion
  86.  
  87.         #region Methods
  88.  
  89.         #region Products
  90.  
  91.         /// <summary>
  92.         /// Marks a product as deleted
  93.         /// </summary>
  94.         /// <param name="productId">Product identifier</param>
  95.         public void MarkProductAsDeleted(int productId)
  96.         {
  97.             if (productId == 0) return;
  98.  
  99.             var product = GetProductById(productId);
  100.             if (product != null)
  101.             {
  102.                 product.Deleted = true;
  103.                 product.Published = false;
  104.                 UpdateProduct(product);
  105.  
  106.                 foreach (var productVariant in product.ProductVariants)
  107.                 {
  108.                     MarkProductVariantAsDeleted(productVariant.ProductVariantId);
  109.                 }
  110.             }
  111.         }
  112.  
  113.         /// <summary>
  114.         /// Gets all products
  115.         /// </summary>
  116.         /// <returns>Product collection</returns>
  117.         public List<Product> GetAllProducts()
  118.         {
  119.             bool showHidden = NopContext.Current.IsAdmin;
  120.             return GetAllProducts(showHidden);
  121.         }
  122.  
  123.         /// <summary>
  124.         /// Gets all products
  125.         /// </summary>
  126.         /// <param name="showHidden">A value indicating whether to show hidden records</param>
  127.         /// <returns>Product collection</returns>
  128.         public List<Product> GetAllProducts(bool showHidden)
  129.         {
  130.  
  131.             var query = from p in _context.Products
  132.                         orderby p.Name
  133.                         where (showHidden || p.Published) &&
  134.                         !p.Deleted
  135.                         select p;
  136.             var products = query.ToList();
  137.             return products;
  138.         }
  139.  
  140.         /// <summary>
  141.         /// Gets all products
  142.         /// </summary>
  143.         /// <param name="pageSize">Page size</param>
  144.         /// <param name="pageIndex">Page index</param>
  145.         /// <param name="totalRecords">Total records</param>
  146.         /// <returns>Product collection</returns>
  147.         public List<Product> GetAllProducts(int pageSize, int pageIndex,
  148.             out int totalRecords)
  149.         {
  150.             return GetAllProducts(0, 0, 0, null, null, null,
  151.                 string.Empty, false, pageSize, pageIndex, null,
  152.                 ProductSortingEnum.Position, out totalRecords);
  153.         }
  154.  
  155.         /// <summary>
  156.         /// Gets all products
  157.         /// </summary>
  158.         /// <param name="categoryId">Category identifier</param>
  159.         /// <param name="manufacturerId">Manufacturer identifier</param>
  160.         /// <param name="productTagId">Product tag identifier</param>
  161.         /// <param name="featuredProducts">A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers). 0 to load featured products only, 1 to load not featured products only, null to load all products</param>
  162.         /// <param name="pageSize">Page size</param>
  163.         /// <param name="pageIndex">Page index</param>
  164.         /// <param name="totalRecords">Total records</param>
  165.         /// <returns>Product collection</returns>
  166.         public List<Product> GetAllProducts(int categoryId,
  167.             int manufacturerId, int productTagId, bool? featuredProducts,
  168.             int pageSize, int pageIndex, out int totalRecords)
  169.         {
  170.             return GetAllProducts(categoryId, manufacturerId,
  171.                 productTagId, featuredProducts, null, null,
  172.                 string.Empty, false, pageSize, pageIndex, null,
  173.                 ProductSortingEnum.Position, out totalRecords);
  174.         }
  175.  
  176.         /// <summary>
  177.         /// Gets all products
  178.         /// </summary>
  179.         /// <param name="keywords">Keywords</param>
  180.         /// <param name="searchDescriptions">A value indicating whether to search in descriptions</param>
  181.         /// <param name="pageSize">Page size</param>
  182.         /// <param name="pageIndex">Page index</param>
  183.         /// <param name="totalRecords">Total records</param>
  184.         /// <returns>Product collection</returns>
  185.         public List<Product> GetAllProducts(string keywords,
  186.             bool searchDescriptions, int pageSize, int pageIndex, out int totalRecords)
  187.         {
  188.             return GetAllProducts(0, 0, 0, null, null, null,
  189.                 keywords, searchDescriptions, pageSize, pageIndex, null,
  190.                 ProductSortingEnum.Position, out totalRecords);
  191.         }
  192.  
  193.         /// <summary>
  194.         /// Gets all products
  195.         /// </summary>
  196.         /// <param name="categoryId">Category identifier</param>
  197.         /// <param name="manufacturerId">Manufacturer identifier</param>
  198.         /// <param name="productTagId">Product tag identifier</param>
  199.         /// <param name="featuredProducts">A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers). 0 to load featured products only, 1 to load not featured products only, null to load all products</param>
  200.         /// <param name="keywords">Keywords</param>
  201.         /// <param name="searchDescriptions">A value indicating whether to search in descriptions</param>
  202.         /// <param name="pageSize">Page size</param>
  203.         /// <param name="pageIndex">Page index</param>
  204.         /// <param name="filteredSpecs">Filtered product specification identifiers</param>
  205.         /// <param name="totalRecords">Total records</param>
  206.         /// <returns>Product collection</returns>
  207.         public List<Product> GetAllProducts(int categoryId,
  208.             int manufacturerId, int productTagId, bool? featuredProducts,
  209.             string keywords, bool searchDescriptions, int pageSize,
  210.             int pageIndex, List<int> filteredSpecs, out int totalRecords)
  211.         {
  212.             return GetAllProducts(categoryId, manufacturerId,
  213.                 productTagId, featuredProducts, null, null,
  214.                 keywords, searchDescriptions, pageSize, pageIndex,
  215.                 filteredSpecs, ProductSortingEnum.Position, out totalRecords);
  216.         }
  217.  
  218.         /// <summary>
  219.         /// Gets all products
  220.         /// </summary>
  221.         /// <param name="categoryId">Category identifier</param>
  222.         /// <param name="manufacturerId">Manufacturer identifier</param>
  223.         /// <param name="productTagId">Product tag identifier</param>
  224.         /// <param name="featuredProducts">A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers). 0 to load featured products only, 1 to load not featured products only, null to load all products</param>
  225.         /// <param name="priceMin">Minimum price</param>
  226.         /// <param name="priceMax">Maximum price</param>
  227.         /// <param name="pageSize">Page size</param>
  228.         /// <param name="pageIndex">Page index</param>
  229.         /// <param name="filteredSpecs">Filtered product specification identifiers</param>
  230.         /// <param name="totalRecords">Total records</param>
  231.         /// <returns>Product collection</returns>
  232.         public List<Product> GetAllProducts(int categoryId,
  233.             int manufacturerId, int productTagId, bool? featuredProducts,
  234.             decimal? priceMin, decimal? priceMax, int pageSize,
  235.             int pageIndex, List<int> filteredSpecs, out int totalRecords)
  236.         {
  237.             return GetAllProducts(categoryId, manufacturerId,
  238.                 productTagId, featuredProducts,
  239.                 priceMin, priceMax, string.Empty, false, pageSize, pageIndex,
  240.                 filteredSpecs, ProductSortingEnum.Position, out totalRecords);
  241.         }
  242.  
  243.         /// <summary>
  244.         /// Gets all products
  245.         /// </summary>
  246.         /// <param name="categoryId">Category identifier</param>
  247.         /// <param name="manufacturerId">Manufacturer identifier</param>
  248.         /// <param name="productTagId">Product tag identifier</param>
  249.         /// <param name="featuredProducts">A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers). 0 to load featured products only, 1 to load not featured products only, null to load all products</param>
  250.         /// <param name="priceMin">Minimum price</param>
  251.         /// <param name="priceMax">Maximum price</param>
  252.         /// <param name="keywords">Keywords</param>
  253.         /// <param name="searchDescriptions">A value indicating whether to search in descriptions</param>
  254.         /// <param name="pageSize">Page size</param>
  255.         /// <param name="pageIndex">Page index</param>
  256.         /// <param name="filteredSpecs">Filtered product specification identifiers</param>
  257.         /// <param name="totalRecords">Total records</param>
  258.         /// <returns>Product collection</returns>
  259.         public List<Product> GetAllProducts(int categoryId,
  260.             int manufacturerId, int productTagId, bool? featuredProducts,
  261.             decimal? priceMin, decimal? priceMax, string keywords,
  262.             bool searchDescriptions, int pageSize, int pageIndex,
  263.             List<int> filteredSpecs, out int totalRecords)
  264.         {
  265.             return GetAllProducts(categoryId, manufacturerId,
  266.                 productTagId, featuredProducts, priceMin,
  267.                 priceMax, keywords, searchDescriptions,
  268.                 pageSize, pageIndex, filteredSpecs,
  269.                 ProductSortingEnum.Position, out totalRecords);
  270.         }
  271.         /// <summary>
  272.         /// Gets all products
  273.         /// </summary>
  274.         /// <param name="categoryId">Category identifier</param>
  275.         /// <param name="manufacturerId">Manufacturer identifier</param>
  276.         /// <param name="productTagId">Product tag identifier</param>
  277.         /// <param name="featuredProducts">A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers). 0 to load featured products only, 1 to load not featured products only, null to load all products</param>
  278.         /// <param name="priceMin">Minimum price</param>
  279.         /// <param name="priceMax">Maximum price</param>
  280.         /// <param name="keywords">Keywords</param>
  281.         /// <param name="searchDescriptions">A value indicating whether to search in descriptions</param>
  282.         /// <param name="pageSize">Page size</param>
  283.         /// <param name="pageIndex">Page index</param>
  284.         /// <param name="filteredSpecs">Filtered product specification identifiers</param>
  285.         /// <param name="orderBy">Order by</param>
  286.         /// <param name="totalRecords">Total records</param>
  287.         /// <returns>Product collection</returns>
  288.         public List<Product> GetAllProducts(int categoryId,
  289.             int manufacturerId, int productTagId, bool? featuredProducts,
  290.             decimal? priceMin, decimal? priceMax, string keywords,
  291.             bool searchDescriptions, int pageSize, int pageIndex,
  292.             List<int> filteredSpecs, ProductSortingEnum orderBy, out int totalRecords)
  293.         {
  294.             int languageId = NopContext.Current.WorkingLanguage.LanguageId;
  295.  
  296.             return GetAllProducts(categoryId, manufacturerId, productTagId,
  297.                 featuredProducts, priceMin, priceMax, keywords, searchDescriptions,
  298.                 pageSize, pageIndex, filteredSpecs, languageId,
  299.                 orderBy, out totalRecords);
  300.         }
  301.  
  302.         /// <summary>
  303.         /// Gets all products
  304.         /// </summary>
  305.         /// <param name="categoryId">Category identifier</param>
  306.         /// <param name="manufacturerId">Manufacturer identifier</param>
  307.         /// <param name="productTagId">Product tag identifier</param>
  308.         /// <param name="featuredProducts">A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers). 0 to load featured products only, 1 to load not featured products only, null to load all products</param>
  309.         /// <param name="priceMin">Minimum price</param>
  310.         /// <param name="priceMax">Maximum price</param>
  311.         /// <param name="keywords">Keywords</param>
  312.         /// <param name="searchDescriptions">A value indicating whether to search in descriptions</param>
  313.         /// <param name="pageSize">Page size</param>
  314.         /// <param name="pageIndex">Page index</param>
  315.         /// <param name="filteredSpecs">Filtered product specification identifiers</param>
  316.         /// <param name="languageId">Language identifier</param>
  317.         /// <param name="orderBy">Order by</param>
  318.         /// <param name="totalRecords">Total records</param>
  319.         /// <returns>Product collection</returns>
  320.         public List<Product> GetAllProducts(int categoryId,
  321.             int manufacturerId, int productTagId, bool? featuredProducts,
  322.             decimal? priceMin, decimal? priceMax,
  323.             string keywords, bool searchDescriptions, int pageSize,
  324.             int pageIndex, List<int> filteredSpecs, int languageId,
  325.             ProductSortingEnum orderBy, out int totalRecords)
  326.         {
  327.             return GetAllProducts(categoryId,
  328.                 manufacturerId, productTagId, featuredProducts,
  329.                 priceMin, priceMax, 0,
  330.                 keywords, searchDescriptions, pageSize,
  331.                 pageIndex, filteredSpecs, languageId,
  332.                 orderBy, out totalRecords);
  333.         }
  334.  
  335.         /// <summary>
  336.         /// Gets all products
  337.         /// </summary>
  338.         /// <param name="categoryId">Category identifier; 0 to load all recordss</param>
  339.         /// <param name="manufacturerId">Manufacturer identifier; 0 to load all recordss</param>
  340.         /// <param name="productTagId">Product tag identifier; 0 to load all recordss</param>
  341.         /// <param name="featuredProducts">A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers). 0 to load featured products only, 1 to load not featured products only, null to load all products</param>
  342.         /// <param name="priceMin">Minimum price</param>
  343.         /// <param name="priceMax">Maximum price</param>
  344.         /// <param name="relatedToProductId">Filter by related product; 0 to load all recordss</param>
  345.         /// <param name="keywords">Keywords</param>
  346.         /// <param name="searchDescriptions">A value indicating whether to search in descriptions</param>
  347.         /// <param name="pageSize">Page size</param>
  348.         /// <param name="pageIndex">Page index</param>
  349.         /// <param name="filteredSpecs">Filtered product specification identifiers</param>
  350.         /// <param name="languageId">Language identifier</param>
  351.         /// <param name="orderBy">Order by</param>
  352.         /// <param name="totalRecords">Total records</param>
  353.         /// <returns>Product collection</returns>
  354.         public List<Product> GetAllProducts(int categoryId,
  355.             int manufacturerId, int productTagId, bool? featuredProducts,
  356.             decimal? priceMin, decimal? priceMax,
  357.             int relatedToProductId, string keywords, bool searchDescriptions, int pageSize,
  358.             int pageIndex, List<int> filteredSpecs, int languageId,
  359.             ProductSortingEnum orderBy, out int totalRecords)
  360.         {
  361.             if (pageSize <= 0)
  362.                 pageSize = 10;
  363.             if (pageSize == int.MaxValue)
  364.                 pageSize = int.MaxValue - 1;
  365.  
  366.             if (pageIndex < 0)
  367.                 pageIndex = 0;
  368.             if (pageIndex == int.MaxValue)
  369.                 pageIndex = int.MaxValue - 1;
  370.  
  371.             bool showHidden = NopContext.Current.IsAdmin;
  372.  
  373.             string commaSeparatedSpecIds = string.Empty;
  374.             if (filteredSpecs != null)
  375.             {
  376.                 filteredSpecs.Sort();
  377.                 for (int i = 0; i < filteredSpecs.Count; i++)
  378.                 {
  379.                     commaSeparatedSpecIds += filteredSpecs[i].ToString();
  380.                     if (i != filteredSpecs.Count - 1)
  381.                     {
  382.                         commaSeparatedSpecIds += ",";
  383.                     }
  384.                 }
  385.             }
  386.  
  387.  
  388.             ObjectParameter totalRecordsParameter = new ObjectParameter("TotalRecords", typeof(int));
  389.             var products = _context.Sp_ProductLoadAllPaged(categoryId,
  390.                manufacturerId, productTagId, featuredProducts,
  391.                priceMin, priceMax, relatedToProductId,
  392.                keywords, searchDescriptions, showHidden, pageIndex, pageSize, commaSeparatedSpecIds,
  393.                languageId, (int)orderBy, totalRecordsParameter).ToList();
  394.             totalRecords = Convert.ToInt32(totalRecordsParameter.Value);
  395.  
  396.             return products;
  397.         }
  398.  
  399.         /// <summary>
  400.         /// Gets all products displayed on the home page
  401.         /// </summary>
  402.         /// <returns>Product collection</returns>
  403.         public List<Product> GetAllProductsDisplayedOnHomePage()
  404.         {
  405.             bool showHidden = NopContext.Current.IsAdmin;
  406.  
  407.             var query = from p in _context.Products
  408.                         orderby p.Name
  409.                         where (showHidden || p.Published) &&
  410.                         !p.Deleted &&
  411.                         p.ShowOnHomePage
  412.                         select p;
  413.             var products = query.ToList();
  414.             return products;
  415.         }
  416.  
  417.         /// <summary>
  418.         /// Gets product
  419.         /// </summary>
  420.         /// <param name="productId">Product identifier</param>
  421.         /// <returns>Product</returns>
  422.         public Product GetProductById(int productId)
  423.         {
  424.             if (productId == 0)
  425.                 return null;
  426.  
  427.             string key = string.Format(PRODUCTS_BY_ID_KEY, productId);
  428.             object obj2 = _cacheManager.Get(key);
  429.             if (this.CacheEnabled && (obj2 != null))
  430.             {
  431.                 return (Product)obj2;
  432.             }
  433.  
  434.  
  435.             var query = from p in _context.Products
  436.                         where p.ProductId == productId
  437.                         select p;
  438.             var product = query.SingleOrDefault();
  439.  
  440.             if (this.CacheEnabled)
  441.             {
  442.                 _cacheManager.Add(key, product);
  443.             }
  444.             return product;
  445.         }
  446.  
  447.         /// <summary>
  448.         /// Inserts a product
  449.         /// </summary>
  450.         /// <param name="product">Product</param>
  451.         public void InsertProduct(Product product)
  452.         {
  453.             if (product == null)
  454.                 throw new ArgumentNullException("product");
  455.  
  456.             product.Name = CommonHelper.EnsureNotNull(product.Name);
  457.             product.Name = CommonHelper.EnsureMaximumLength(product.Name, 400);
  458.             product.ShortDescription = CommonHelper.EnsureNotNull(product.ShortDescription);
  459.             product.FullDescription = CommonHelper.EnsureNotNull(product.FullDescription);
  460.             product.AdminComment = CommonHelper.EnsureNotNull(product.AdminComment);
  461.             product.MetaKeywords = CommonHelper.EnsureNotNull(product.MetaKeywords);
  462.             product.MetaKeywords = CommonHelper.EnsureMaximumLength(product.MetaKeywords, 400);
  463.             product.MetaDescription = CommonHelper.EnsureNotNull(product.MetaDescription);
  464.             product.MetaDescription = CommonHelper.EnsureMaximumLength(product.MetaDescription, 4000);
  465.             product.MetaTitle = CommonHelper.EnsureNotNull(product.MetaTitle);
  466.             product.MetaTitle = CommonHelper.EnsureMaximumLength(product.MetaTitle, 400);
  467.             product.SEName = CommonHelper.EnsureNotNull(product.SEName);
  468.             product.SEName = CommonHelper.EnsureMaximumLength(product.SEName, 100);
  469.  
  470.  
  471.  
  472.             _context.Products.AddObject(product);
  473.             _context.SaveChanges();
  474.  
  475.             if (this.CacheEnabled)
  476.             {
  477.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  478.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  479.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  480.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  481.             }
  482.  
  483.             //raise event            
  484.             EventContext.Current.OnProductCreated(null,
  485.                 new ProductEventArgs() { Product = product });
  486.         }
  487.  
  488.         /// <summary>
  489.         /// Updates the product
  490.         /// </summary>
  491.         /// <param name="product">Product</param>
  492.         public void UpdateProduct(Product product)
  493.         {
  494.             if (product == null)
  495.                 throw new ArgumentNullException("product");
  496.  
  497.             product.Name = CommonHelper.EnsureNotNull(product.Name);
  498.             product.Name = CommonHelper.EnsureMaximumLength(product.Name, 400);
  499.             product.ShortDescription = CommonHelper.EnsureNotNull(product.ShortDescription);
  500.             product.FullDescription = CommonHelper.EnsureNotNull(product.FullDescription);
  501.             product.AdminComment = CommonHelper.EnsureNotNull(product.AdminComment);
  502.             product.MetaKeywords = CommonHelper.EnsureNotNull(product.MetaKeywords);
  503.             product.MetaKeywords = CommonHelper.EnsureMaximumLength(product.MetaKeywords, 400);
  504.             product.MetaDescription = CommonHelper.EnsureNotNull(product.MetaDescription);
  505.             product.MetaDescription = CommonHelper.EnsureMaximumLength(product.MetaDescription, 4000);
  506.             product.MetaTitle = CommonHelper.EnsureNotNull(product.MetaTitle);
  507.             product.MetaTitle = CommonHelper.EnsureMaximumLength(product.MetaTitle, 400);
  508.             product.SEName = CommonHelper.EnsureNotNull(product.SEName);
  509.             product.SEName = CommonHelper.EnsureMaximumLength(product.SEName, 100);
  510.  
  511.  
  512.             if (!_context.IsAttached(product))
  513.                 _context.Products.Attach(product);
  514.  
  515.             _context.SaveChanges();
  516.  
  517.             if (this.CacheEnabled)
  518.             {
  519.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  520.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  521.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  522.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  523.             }
  524.  
  525.             //raise event            
  526.             EventContext.Current.OnProductUpdated(null,
  527.                 new ProductEventArgs() { Product = product });
  528.         }
  529.  
  530.         /// <summary>
  531.         /// Gets localized product by id
  532.         /// </summary>
  533.         /// <param name="productLocalizedId">Localized product identifier</param>
  534.         /// <returns>Product content</returns>
  535.         public ProductLocalized GetProductLocalizedById(int productLocalizedId)
  536.         {
  537.             if (productLocalizedId == 0)
  538.                 return null;
  539.  
  540.  
  541.             var query = from pl in _context.ProductLocalized
  542.                         where pl.ProductLocalizedId == productLocalizedId
  543.                         select pl;
  544.             var productLocalized = query.SingleOrDefault();
  545.             return productLocalized;
  546.         }
  547.  
  548.         /// <summary>
  549.         /// Gets localized product by product id
  550.         /// </summary>
  551.         /// <param name="productId">Product identifier</param>
  552.         /// <returns>Product content</returns>
  553.         public List<ProductLocalized> GetProductLocalizedByProductId(int productId)
  554.         {
  555.             if (productId == 0)
  556.                 return new List<ProductLocalized>();
  557.  
  558.  
  559.             var query = from pl in _context.ProductLocalized
  560.                         where pl.ProductId == productId
  561.                         select pl;
  562.             var content = query.ToList();
  563.             return content;
  564.         }
  565.  
  566.         /// <summary>
  567.         /// Gets localized product by product id and language id
  568.         /// </summary>
  569.         /// <param name="productId">Product identifier</param>
  570.         /// <param name="languageId">Language identifier</param>
  571.         /// <returns>Product content</returns>
  572.         public ProductLocalized GetProductLocalizedByProductIdAndLanguageId(int productId, int languageId)
  573.         {
  574.             if (productId == 0 || languageId == 0)
  575.                 return null;
  576.  
  577.  
  578.             var query = from pl in _context.ProductLocalized
  579.                         orderby pl.ProductLocalizedId
  580.                         where pl.ProductId == productId &&
  581.                         pl.LanguageId == languageId
  582.                         select pl;
  583.             var productLocalized = query.FirstOrDefault();
  584.             return productLocalized;
  585.         }
  586.  
  587.         /// <summary>
  588.         /// Inserts a localized product
  589.         /// </summary>
  590.         /// <param name="productLocalized">Product content</param>
  591.         public void InsertProductLocalized(ProductLocalized productLocalized)
  592.         {
  593.             if (productLocalized == null)
  594.                 throw new ArgumentNullException("productLocalized");
  595.  
  596.             productLocalized.Name = CommonHelper.EnsureNotNull(productLocalized.Name);
  597.             productLocalized.Name = CommonHelper.EnsureMaximumLength(productLocalized.Name, 400);
  598.             productLocalized.ShortDescription = CommonHelper.EnsureNotNull(productLocalized.ShortDescription);
  599.             productLocalized.FullDescription = CommonHelper.EnsureNotNull(productLocalized.FullDescription);
  600.             productLocalized.MetaKeywords = CommonHelper.EnsureNotNull(productLocalized.MetaKeywords);
  601.             productLocalized.MetaKeywords = CommonHelper.EnsureMaximumLength(productLocalized.MetaKeywords, 400);
  602.             productLocalized.MetaDescription = CommonHelper.EnsureNotNull(productLocalized.MetaDescription);
  603.             productLocalized.MetaDescription = CommonHelper.EnsureMaximumLength(productLocalized.MetaDescription, 4000);
  604.             productLocalized.MetaTitle = CommonHelper.EnsureNotNull(productLocalized.MetaTitle);
  605.             productLocalized.MetaTitle = CommonHelper.EnsureMaximumLength(productLocalized.MetaTitle, 400);
  606.             productLocalized.SEName = CommonHelper.EnsureNotNull(productLocalized.SEName);
  607.             productLocalized.SEName = CommonHelper.EnsureMaximumLength(productLocalized.SEName, 100);
  608.  
  609.  
  610.  
  611.             _context.ProductLocalized.AddObject(productLocalized);
  612.             _context.SaveChanges();
  613.  
  614.             if (this.CacheEnabled)
  615.             {
  616.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  617.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  618.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  619.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  620.             }
  621.         }
  622.  
  623.         /// <summary>
  624.         /// Update a localized product
  625.         /// </summary>
  626.         /// <param name="productLocalized">Product content</param>
  627.         public void UpdateProductLocalized(ProductLocalized productLocalized)
  628.         {
  629.             if (productLocalized == null)
  630.                 throw new ArgumentNullException("productLocalized");
  631.  
  632.             productLocalized.Name = CommonHelper.EnsureNotNull(productLocalized.Name);
  633.             productLocalized.Name = CommonHelper.EnsureMaximumLength(productLocalized.Name, 400);
  634.             productLocalized.ShortDescription = CommonHelper.EnsureNotNull(productLocalized.ShortDescription);
  635.             productLocalized.FullDescription = CommonHelper.EnsureNotNull(productLocalized.FullDescription);
  636.             productLocalized.MetaKeywords = CommonHelper.EnsureNotNull(productLocalized.MetaKeywords);
  637.             productLocalized.MetaKeywords = CommonHelper.EnsureMaximumLength(productLocalized.MetaKeywords, 400);
  638.             productLocalized.MetaDescription = CommonHelper.EnsureNotNull(productLocalized.MetaDescription);
  639.             productLocalized.MetaDescription = CommonHelper.EnsureMaximumLength(productLocalized.MetaDescription, 4000);
  640.             productLocalized.MetaTitle = CommonHelper.EnsureNotNull(productLocalized.MetaTitle);
  641.             productLocalized.MetaTitle = CommonHelper.EnsureMaximumLength(productLocalized.MetaTitle, 400);
  642.             productLocalized.SEName = CommonHelper.EnsureNotNull(productLocalized.SEName);
  643.             productLocalized.SEName = CommonHelper.EnsureMaximumLength(productLocalized.SEName, 100);
  644.  
  645.             bool allFieldsAreEmpty = string.IsNullOrEmpty(productLocalized.Name) &&
  646.                string.IsNullOrEmpty(productLocalized.ShortDescription) &&
  647.                string.IsNullOrEmpty(productLocalized.FullDescription) &&
  648.                string.IsNullOrEmpty(productLocalized.MetaKeywords) &&
  649.                string.IsNullOrEmpty(productLocalized.MetaDescription) &&
  650.                string.IsNullOrEmpty(productLocalized.MetaTitle) &&
  651.                string.IsNullOrEmpty(productLocalized.SEName);
  652.  
  653.  
  654.             if (!_context.IsAttached(productLocalized))
  655.                 _context.ProductLocalized.Attach(productLocalized);
  656.  
  657.             if (allFieldsAreEmpty)
  658.             {
  659.                 //delete if all fields are empty
  660.                 _context.DeleteObject(productLocalized);
  661.                 _context.SaveChanges();
  662.             }
  663.             else
  664.             {
  665.                 _context.SaveChanges();
  666.             }
  667.  
  668.             if (this.CacheEnabled)
  669.             {
  670.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  671.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  672.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  673.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  674.             }
  675.         }
  676.  
  677.         /// <summary>
  678.         /// Gets a list of products purchased by other customers who purchased the above
  679.         /// </summary>
  680.         /// <param name="productId">Product identifier</param>
  681.         /// <returns>Product collection</returns>
  682.         public List<Product> GetProductsAlsoPurchasedById(int productId)
  683.         {
  684.             int totalRecords = 0;
  685.             var products = GetProductsAlsoPurchasedById(productId,
  686.                 this.ProductsAlsoPurchasedNumber, 0, out totalRecords);
  687.             return products;
  688.         }
  689.  
  690.         /// <summary>
  691.         /// Gets a list of products purchased by other customers who purchased the above
  692.         /// </summary>
  693.         /// <param name="productId">Product identifier</param>
  694.         /// <param name="pageSize">Page size</param>
  695.         /// <param name="pageIndex">Page index</param>
  696.         /// <param name="totalRecords">Total records</param>
  697.         /// <returns>Product collection</returns>
  698.         public List<Product> GetProductsAlsoPurchasedById(int productId,
  699.             int pageSize, int pageIndex, out int totalRecords)
  700.         {
  701.             if (pageSize <= 0)
  702.                 pageSize = 10;
  703.             if (pageSize == int.MaxValue)
  704.                 pageSize = int.MaxValue - 1;
  705.  
  706.             if (pageIndex < 0)
  707.                 pageIndex = 0;
  708.             if (pageIndex == int.MaxValue)
  709.                 pageIndex = int.MaxValue - 1;
  710.  
  711.             bool showHidden = NopContext.Current.IsAdmin;
  712.  
  713.  
  714.             ObjectParameter totalRecordsParameter = new ObjectParameter("TotalRecords", typeof(int));
  715.             var products = _context.Sp_ProductAlsoPurchasedLoadByProductID(productId,
  716.                showHidden, pageIndex, pageSize, totalRecordsParameter).ToList();
  717.             totalRecords = Convert.ToInt32(totalRecordsParameter.Value);
  718.             return products;
  719.         }
  720.  
  721.         /// <summary>
  722.         /// Sets a product rating
  723.         /// </summary>
  724.         /// <param name="productId">Product identifer</param>
  725.         /// <param name="rating">Rating</param>
  726.         public void SetProductRating(int productId, int rating)
  727.         {
  728.             if (NopContext.Current.User == null || (NopContext.Current.User.IsGuest && !IoC.Resolve<ICustomerService>().AllowAnonymousUsersToSetProductRatings))
  729.             {
  730.                 return;
  731.             }
  732.  
  733.             var product = GetProductById(productId);
  734.             if (product == null)
  735.                 throw new NopException("Product could not be loaded");
  736.  
  737.             if (rating < 1 || rating > 5)
  738.                 rating = 1;
  739.             var ratedOn = DateTime.UtcNow;
  740.  
  741.             //delete previous helpfulness
  742.  
  743.             var oldPr = (from pr in _context.ProductRatings
  744.                          where pr.ProductId == productId &&
  745.                          pr.CustomerId == NopContext.Current.User.CustomerId
  746.                          select pr).FirstOrDefault();
  747.             if (oldPr != null)
  748.             {
  749.                 _context.DeleteObject(oldPr);
  750.             }
  751.             _context.SaveChanges();
  752.  
  753.             //insert new rating
  754.             var newPr = _context.ProductRatings.CreateObject();
  755.             newPr.ProductId = productId;
  756.             newPr.CustomerId = NopContext.Current.User.CustomerId;
  757.             newPr.Rating = rating;
  758.             newPr.RatedOn = ratedOn;
  759.             _context.ProductRatings.AddObject(newPr);
  760.             _context.SaveChanges();
  761.  
  762.             //new totals
  763.             int ratingSum = Convert.ToInt32((from pr in _context.ProductRatings
  764.                                              where pr.ProductId == productId
  765.                                              select pr).Sum(p => (int?)p.Rating));
  766.             int totalRatingVotes = (from pr in _context.ProductRatings
  767.                                     where pr.ProductId == productId
  768.                                     select pr).Count();
  769.  
  770.             product.RatingSum = ratingSum;
  771.             product.TotalRatingVotes = totalRatingVotes;
  772.             UpdateProduct(product);
  773.         }
  774.  
  775.         /// <summary>
  776.         /// Clears a "compare products" list
  777.         /// </summary>
  778.         public void ClearCompareProducts()
  779.         {
  780.             HttpCookie compareCookie = HttpContext.Current.Request.Cookies.Get("NopCommerce.CompareProducts");
  781.             if (compareCookie != null)
  782.             {
  783.                 compareCookie.Values.Clear();
  784.                 compareCookie.Expires = DateTime.Now.AddYears(-1);
  785.                 HttpContext.Current.Response.Cookies.Set(compareCookie);
  786.             }
  787.         }
  788.  
  789.         /// <summary>
  790.         /// Gets a "compare products" list
  791.         /// </summary>
  792.         /// <returns>"Compare products" list</returns>
  793.         public List<Product> GetCompareProducts()
  794.         {
  795.             var products = new List<Product>();
  796.             var productIds = GetCompareProductsIds();
  797.             foreach (int productId in productIds)
  798.             {
  799.                 var product = GetProductById(productId);
  800.                 if (product != null && product.Published && !product.Deleted)
  801.                     products.Add(product);
  802.             }
  803.             return products;
  804.         }
  805.  
  806.         /// <summary>
  807.         /// Gets a "compare products" identifier list
  808.         /// </summary>
  809.         /// <returns>"compare products" identifier list</returns>
  810.         public List<int> GetCompareProductsIds()
  811.         {
  812.             var productIds = new List<int>();
  813.             HttpCookie compareCookie = HttpContext.Current.Request.Cookies.Get("NopCommerce.CompareProducts");
  814.             if ((compareCookie == null) || (compareCookie.Values == null))
  815.                 return productIds;
  816.             string[] values = compareCookie.Values.GetValues("CompareProductIds");
  817.             if (values == null)
  818.                 return productIds;
  819.             foreach (string productId in values)
  820.             {
  821.                 int prodId = int.Parse(productId);
  822.                 if (!productIds.Contains(prodId))
  823.                     productIds.Add(prodId);
  824.             }
  825.  
  826.             return productIds;
  827.         }
  828.  
  829.         /// <summary>
  830.         /// Removes a product from a "compare products" list
  831.         /// </summary>
  832.         /// <param name="productId">Product identifer</param>
  833.         public void RemoveProductFromCompareList(int productId)
  834.         {
  835.             var oldProductIds = GetCompareProductsIds();
  836.             var newProductIds = new List<int>();
  837.             newProductIds.AddRange(oldProductIds);
  838.             newProductIds.Remove(productId);
  839.  
  840.             HttpCookie compareCookie = HttpContext.Current.Request.Cookies.Get("NopCommerce.CompareProducts");
  841.             if ((compareCookie == null) || (compareCookie.Values == null))
  842.                 return;
  843.             compareCookie.Values.Clear();
  844.             foreach (int newProductId in newProductIds)
  845.                 compareCookie.Values.Add("CompareProductIds", newProductId.ToString());
  846.             compareCookie.Expires = DateTime.Now.AddDays(10.0);
  847.             HttpContext.Current.Response.Cookies.Set(compareCookie);
  848.         }
  849.  
  850.         /// <summary>
  851.         /// Adds a product to a "compare products" list
  852.         /// </summary>
  853.         /// <param name="productId">Product identifer</param>
  854.         public void AddProductToCompareList(int productId)
  855.         {
  856.             if (!this.CompareProductsEnabled)
  857.                 return;
  858.  
  859.             var oldProductIds = GetCompareProductsIds();
  860.             var newProductIds = new List<int>();
  861.             newProductIds.Add(productId);
  862.             foreach (int oldProductId in oldProductIds)
  863.                 if (oldProductId != productId)
  864.                     newProductIds.Add(oldProductId);
  865.  
  866.             HttpCookie compareCookie = HttpContext.Current.Request.Cookies.Get("NopCommerce.CompareProducts");
  867.             if (compareCookie == null)
  868.                 compareCookie = new HttpCookie("NopCommerce.CompareProducts");
  869.             compareCookie.Values.Clear();
  870.             int maxProducts = 4;
  871.             int i = 1;
  872.             foreach (int newProductId in newProductIds)
  873.             {
  874.                 compareCookie.Values.Add("CompareProductIds", newProductId.ToString());
  875.                 if (i == maxProducts)
  876.                     break;
  877.                 i++;
  878.             }
  879.             compareCookie.Expires = DateTime.Now.AddDays(10.0);
  880.             HttpContext.Current.Response.Cookies.Set(compareCookie);
  881.         }
  882.  
  883.         /// <summary>
  884.         /// Gets a "recently viewed products" list
  885.         /// </summary>
  886.         /// <param name="number">Number of products to load</param>
  887.         /// <returns>"recently viewed products" list</returns>
  888.         public List<Product> GetRecentlyViewedProducts(int number)
  889.         {
  890.             var products = new List<Product>();
  891.             var productIds = GetRecentlyViewedProductsIds(number);
  892.             foreach (int productId in productIds)
  893.             {
  894.                 Product product = GetProductById(productId);
  895.                 if (product != null && product.Published && !product.Deleted)
  896.                     products.Add(product);
  897.             }
  898.             return products;
  899.         }
  900.  
  901.         /// <summary>
  902.         /// Gets a "recently viewed products" identifier list
  903.         /// </summary>
  904.         /// <returns>"recently viewed products" list</returns>
  905.         public List<int> GetRecentlyViewedProductsIds()
  906.         {
  907.             return GetRecentlyViewedProductsIds(int.MaxValue);
  908.         }
  909.  
  910.         /// <summary>
  911.         /// Gets a "recently viewed products" identifier list
  912.         /// </summary>
  913.         /// <param name="number">Number of products to load</param>
  914.         /// <returns>"recently viewed products" list</returns>
  915.         public List<int> GetRecentlyViewedProductsIds(int number)
  916.         {
  917.             var productIds = new List<int>();
  918.             HttpCookie recentlyViewedCookie = HttpContext.Current.Request.Cookies.Get("NopCommerce.RecentlyViewedProducts");
  919.             if ((recentlyViewedCookie == null) || (recentlyViewedCookie.Values == null))
  920.                 return productIds;
  921.             string[] values = recentlyViewedCookie.Values.GetValues("RecentlyViewedProductIds");
  922.             if (values == null)
  923.                 return productIds;
  924.             foreach (string productId in values)
  925.             {
  926.                 int prodId = int.Parse(productId);
  927.                 if (!productIds.Contains(prodId))
  928.                 {
  929.                     productIds.Add(prodId);
  930.                     if (productIds.Count >= number)
  931.                         break;
  932.                 }
  933.  
  934.             }
  935.  
  936.             return productIds;
  937.         }
  938.  
  939.         /// <summary>
  940.         /// Adds a product to a recently viewed products list
  941.         /// </summary>
  942.         /// <param name="productId">Product identifier</param>
  943.         public void AddProductToRecentlyViewedList(int productId)
  944.         {
  945.             if (!this.RecentlyViewedProductsEnabled)
  946.                 return;
  947.  
  948.             var oldProductIds = GetRecentlyViewedProductsIds();
  949.             var newProductIds = new List<int>();
  950.             newProductIds.Add(productId);
  951.             foreach (int oldProductId in oldProductIds)
  952.                 if (oldProductId != productId)
  953.                     newProductIds.Add(oldProductId);
  954.  
  955.             HttpCookie recentlyViewedCookie = HttpContext.Current.Request.Cookies.Get("NopCommerce.RecentlyViewedProducts");
  956.             if (recentlyViewedCookie == null)
  957.                 recentlyViewedCookie = new HttpCookie("NopCommerce.RecentlyViewedProducts");
  958.             recentlyViewedCookie.Values.Clear();
  959.             int maxProducts = IoC.Resolve<ISettingManager>().GetSettingValueInteger("Display.RecentlyViewedProductCount");
  960.             if (maxProducts <= 0)
  961.                 maxProducts = 10;
  962.             int i = 1;
  963.             foreach (int newProductId in newProductIds)
  964.             {
  965.                 recentlyViewedCookie.Values.Add("RecentlyViewedProductIds", newProductId.ToString());
  966.                 if (i == maxProducts)
  967.                     break;
  968.                 i++;
  969.             }
  970.             recentlyViewedCookie.Expires = DateTime.Now.AddDays(10.0);
  971.             HttpContext.Current.Response.Cookies.Set(recentlyViewedCookie);
  972.         }
  973.  
  974.         /// <summary>
  975.         /// Gets a recently added products list
  976.         /// </summary>
  977.         /// <param name="number">Number of products to load</param>
  978.         /// <returns>Recently added products</returns>
  979.         public List<Product> GetRecentlyAddedProducts(int number)
  980.         {
  981.             int totalRecords = 0;
  982.             var products = this.GetAllProducts(0,
  983.                 0, 0, null, null, null, 0, string.Empty, false, number,
  984.                 0, null, NopContext.Current.WorkingLanguage.LanguageId,
  985.                 ProductSortingEnum.CreatedOn, out totalRecords);
  986.             return products;
  987.         }
  988.  
  989.         /// <summary>
  990.         /// Direct add to cart allowed
  991.         /// </summary>
  992.         /// <param name="productId">Product identifier</param>
  993.         /// <param name="productVariantId">Default product variant identifier for adding to cart</param>
  994.         /// <returns>A value indicating whether direct add to cart is allowed</returns>
  995.         public bool DirectAddToCartAllowed(int productId, out int productVariantId)
  996.         {
  997.             bool result = false;
  998.             productVariantId = 0;
  999.             var product = GetProductById(productId);
  1000.             if (product != null)
  1001.             {
  1002.                 var productVariants = product.ProductVariants;
  1003.                 if (productVariants.Count == 1)
  1004.                 {
  1005.                     var defaultProductVariant = productVariants[0];
  1006.                     if (!defaultProductVariant.CustomerEntersPrice)
  1007.                     {
  1008.                         var addToCartWarnings = IoC.Resolve<IShoppingCartService>().GetShoppingCartItemWarnings(ShoppingCartTypeEnum.ShoppingCart,
  1009.                             defaultProductVariant.ProductVariantId, string.Empty, decimal.Zero, 1);
  1010.  
  1011.                         if (addToCartWarnings.Count == 0)
  1012.                         {
  1013.                             productVariantId = defaultProductVariant.ProductVariantId;
  1014.                             result = true;
  1015.                         }
  1016.                     }
  1017.                 }
  1018.             }
  1019.             return result;
  1020.         }
  1021.  
  1022.         /// <summary>
  1023.         /// Creates a copy of product with all depended data
  1024.         /// </summary>
  1025.         /// <param name="productId">The product identifier</param>
  1026.         /// <param name="name">The name of product duplicate</param>
  1027.         /// <param name="isPublished">A value indicating whether the product duplicate should be published</param>
  1028.         /// <param name="copyImages">A value indicating whether the product images should be copied</param>
  1029.         /// <returns>Product entity</returns>
  1030.         public Product DuplicateProduct(int productId, string name,
  1031.             bool isPublished, bool copyImages)
  1032.         {
  1033.             var product = GetProductById(productId);
  1034.             if (product == null)
  1035.                 return null;
  1036.  
  1037.             Product productCopy = null;
  1038.             //uncomment this line to support transactions
  1039.             //using (var scope = new System.Transactions.TransactionScope())
  1040.             {
  1041.                 // product
  1042.                 productCopy = new Product()
  1043.                 {
  1044.                     Name = name,
  1045.                     ShortDescription = product.ShortDescription,
  1046.                     FullDescription = product.FullDescription,
  1047.                     AdminComment = product.AdminComment,
  1048.                     TemplateId = product.TemplateId,
  1049.                     ShowOnHomePage = product.ShowOnHomePage,
  1050.                     MetaKeywords = product.MetaKeywords,
  1051.                     MetaDescription = product.MetaDescription,
  1052.                     MetaTitle = product.MetaTitle,
  1053.                     SEName = product.SEName,
  1054.                     AllowCustomerReviews = product.AllowCustomerReviews,
  1055.                     AllowCustomerRatings = product.AllowCustomerRatings,
  1056.                     Published = isPublished,
  1057.                     Deleted = product.Deleted,
  1058.                     CreatedOn = DateTime.UtcNow,
  1059.                     UpdatedOn = DateTime.UtcNow
  1060.                 };
  1061.                 InsertProduct(productCopy);
  1062.  
  1063.                 if (productCopy == null)
  1064.                     return null;
  1065.  
  1066.                 var languages = IoC.Resolve<ILanguageService>().GetAllLanguages(true);
  1067.  
  1068.                 //localization
  1069.                 foreach (var lang in languages)
  1070.                 {
  1071.                     var productLocalized = GetProductLocalizedByProductIdAndLanguageId(product.ProductId, lang.LanguageId);
  1072.                     if (productLocalized != null)
  1073.                     {
  1074.                         var productLocalizedCopy = new ProductLocalized()
  1075.                         {
  1076.                             ProductId = productCopy.ProductId,
  1077.                             LanguageId = productLocalized.LanguageId,
  1078.                             Name = productLocalized.Name,
  1079.                             ShortDescription = productLocalized.ShortDescription,
  1080.                             FullDescription = productLocalized.FullDescription,
  1081.                             MetaKeywords = productLocalized.MetaKeywords,
  1082.                             MetaDescription = productLocalized.MetaDescription,
  1083.                             MetaTitle = productLocalized.MetaTitle,
  1084.                             SEName = productLocalized.SEName
  1085.                         };
  1086.                         InsertProductLocalized(productLocalizedCopy);
  1087.                     }
  1088.                 }
  1089.  
  1090.                 // product pictures
  1091.                 if (copyImages)
  1092.                 {
  1093.                     foreach (var productPicture in product.ProductPictures)
  1094.                     {
  1095.                         var picture = productPicture.Picture;
  1096.  
  1097.                         var pictureCopy = IoC.Resolve<IPictureService>().InsertPicture(picture.PictureBinary,
  1098.                             picture.MimeType,
  1099.                             picture.IsNew);
  1100.  
  1101.                         InsertProductPicture(new ProductPicture()
  1102.                         {
  1103.                             ProductId = productCopy.ProductId,
  1104.                             PictureId = pictureCopy.PictureId,
  1105.                             DisplayOrder = productPicture.DisplayOrder
  1106.                         });
  1107.                     }
  1108.                 }
  1109.  
  1110.                 // product <-> categories mappings
  1111.                 foreach (var productCategory in product.ProductCategories)
  1112.                 {
  1113.                     var productCategoryCopy = new ProductCategory()
  1114.                     {
  1115.                         ProductId = productCopy.ProductId,
  1116.                         CategoryId = productCategory.CategoryId,
  1117.                         IsFeaturedProduct = productCategory.IsFeaturedProduct,
  1118.                         DisplayOrder = productCategory.DisplayOrder
  1119.                     };
  1120.  
  1121.                     IoC.Resolve<ICategoryService>().InsertProductCategory(productCategoryCopy);
  1122.                 }
  1123.  
  1124.                 // product <-> manufacturers mappings
  1125.                 foreach (var productManufacturers in product.ProductManufacturers)
  1126.                 {
  1127.                     var productManufacturerCopy = new ProductManufacturer()
  1128.                     {
  1129.                         ProductId = productCopy.ProductId,
  1130.                         ManufacturerId = productManufacturers.ManufacturerId,
  1131.                         IsFeaturedProduct = productManufacturers.IsFeaturedProduct,
  1132.                         DisplayOrder = productManufacturers.DisplayOrder
  1133.                     };
  1134.  
  1135.                     IoC.Resolve<IManufacturerService>().InsertProductManufacturer(productManufacturerCopy);
  1136.                 }
  1137.  
  1138.                 // product <-> releated products mappings
  1139.                 foreach (var relatedProduct in product.RelatedProducts)
  1140.                 {
  1141.                     InsertRelatedProduct(
  1142.                         new RelatedProduct()
  1143.                         {
  1144.                             ProductId1 = productCopy.ProductId,
  1145.                             ProductId2 = relatedProduct.ProductId2,
  1146.                             DisplayOrder = relatedProduct.DisplayOrder
  1147.                         });
  1148.                 }
  1149.  
  1150.                 // product specifications
  1151.                 foreach (var productSpecificationAttribute in IoC.Resolve<ISpecificationAttributeService>().GetProductSpecificationAttributesByProductId(product.ProductId))
  1152.                 {
  1153.                     var psaCopy = new ProductSpecificationAttribute()
  1154.                     {
  1155.                         ProductId = productCopy.ProductId,
  1156.                         SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId,
  1157.                         AllowFiltering = productSpecificationAttribute.AllowFiltering,
  1158.                         ShowOnProductPage = productSpecificationAttribute.ShowOnProductPage,
  1159.                         DisplayOrder = productSpecificationAttribute.DisplayOrder
  1160.                     };
  1161.                     IoC.Resolve<ISpecificationAttributeService>().InsertProductSpecificationAttribute(psaCopy);
  1162.                 }
  1163.  
  1164.                 // product variants
  1165.                 var productVariants = GetProductVariantsByProductId(product.ProductId, true);
  1166.                 foreach (var productVariant in productVariants)
  1167.                 {
  1168.                     // product variant picture
  1169.                     int pictureId = 0;
  1170.                     if (copyImages)
  1171.                     {
  1172.                         var picture = productVariant.Picture;
  1173.                         if (picture != null)
  1174.                         {
  1175.                             var pictureCopy = IoC.Resolve<IPictureService>().InsertPicture(picture.PictureBinary, picture.MimeType, picture.IsNew);
  1176.                             pictureId = pictureCopy.PictureId;
  1177.                         }
  1178.                     }
  1179.  
  1180.                     // product variant download & sample download
  1181.                     int downloadId = productVariant.DownloadId;
  1182.                     int sampleDownloadId = productVariant.SampleDownloadId;
  1183.                     if (productVariant.IsDownload)
  1184.                     {
  1185.                         var download = productVariant.Download;
  1186.                         if (download != null)
  1187.                         {
  1188.                             var downloadCopy = new Download()
  1189.                                 {
  1190.                                     UseDownloadUrl = download.UseDownloadUrl,
  1191.                                     DownloadUrl = download.DownloadUrl,
  1192.                                     DownloadBinary = download.DownloadBinary,
  1193.                                     ContentType = download.ContentType,
  1194.                                     Filename = download.Filename,
  1195.                                     Extension = download.Extension,
  1196.                                     IsNew = download.IsNew
  1197.                                 };
  1198.                             IoC.Resolve<IDownloadService>().InsertDownload(downloadCopy);
  1199.                             downloadId = downloadCopy.DownloadId;
  1200.                         }
  1201.  
  1202.                         if (productVariant.HasSampleDownload)
  1203.                         {
  1204.                             var sampleDownload = productVariant.SampleDownload;
  1205.                             if (sampleDownload != null)
  1206.                             {
  1207.                                 var sampleDownloadCopy = new Download()
  1208.                                 {
  1209.                                     UseDownloadUrl = sampleDownload.UseDownloadUrl,
  1210.                                     DownloadUrl = sampleDownload.DownloadUrl,
  1211.                                     DownloadBinary = sampleDownload.DownloadBinary,
  1212.                                     ContentType = sampleDownload.ContentType,
  1213.                                     Filename = sampleDownload.Filename,
  1214.                                     Extension = sampleDownload.Extension,
  1215.                                     IsNew = sampleDownload.IsNew
  1216.                                 };
  1217.                                 IoC.Resolve<IDownloadService>().InsertDownload(sampleDownloadCopy);
  1218.                                 sampleDownloadId = sampleDownloadCopy.DownloadId;
  1219.                             }
  1220.                         }
  1221.                     }
  1222.  
  1223.                     // product variant
  1224.                     var productVariantCopy = new ProductVariant()
  1225.                     {
  1226.                         ProductId = productCopy.ProductId,
  1227.                         Name = productVariant.Name,
  1228.                         SKU = productVariant.SKU,
  1229.                         Description = productVariant.Description,
  1230.                         AdminComment = productVariant.AdminComment,
  1231.                         ManufacturerPartNumber = productVariant.ManufacturerPartNumber,
  1232.                         IsGiftCard = productVariant.IsGiftCard,
  1233.                         GiftCardType = productVariant.GiftCardType,
  1234.                         IsDownload = productVariant.IsDownload,
  1235.                         DownloadId = downloadId,
  1236.                         UnlimitedDownloads = productVariant.UnlimitedDownloads,
  1237.                         MaxNumberOfDownloads = productVariant.MaxNumberOfDownloads,
  1238.                         DownloadExpirationDays = productVariant.DownloadExpirationDays,
  1239.                         DownloadActivationType = productVariant.DownloadActivationType,
  1240.                         HasSampleDownload = productVariant.HasSampleDownload,
  1241.                         SampleDownloadId = sampleDownloadId,
  1242.                         HasUserAgreement = productVariant.HasUserAgreement,
  1243.                         UserAgreementText = productVariant.UserAgreementText,
  1244.                         IsRecurring = productVariant.IsRecurring,
  1245.                         CycleLength = productVariant.CycleLength,
  1246.                         CyclePeriod = productVariant.CyclePeriod,
  1247.                         TotalCycles = productVariant.TotalCycles,
  1248.                         IsShipEnabled = productVariant.IsShipEnabled,
  1249.                         IsFreeShipping = productVariant.IsFreeShipping,
  1250.                         AdditionalShippingCharge = productVariant.AdditionalShippingCharge,
  1251.                         IsTaxExempt = productVariant.IsTaxExempt,
  1252.                         TaxCategoryId = productVariant.TaxCategoryId,
  1253.                         ManageInventory = productVariant.ManageInventory,
  1254.                         StockQuantity = productVariant.StockQuantity,
  1255.                         DisplayStockAvailability = productVariant.DisplayStockAvailability,
  1256.                         DisplayStockQuantity = productVariant.DisplayStockQuantity,
  1257.                         MinStockQuantity = productVariant.MinStockQuantity,
  1258.                         LowStockActivityId = productVariant.LowStockActivityId,
  1259.                         NotifyAdminForQuantityBelow = productVariant.NotifyAdminForQuantityBelow,
  1260.                         Backorders = productVariant.Backorders,
  1261.                         OrderMinimumQuantity = productVariant.OrderMinimumQuantity,
  1262.                         OrderMaximumQuantity = productVariant.OrderMaximumQuantity,
  1263.                         WarehouseId = productVariant.WarehouseId,
  1264.                         DisableBuyButton = productVariant.DisableBuyButton,
  1265.                         CallForPrice = productVariant.CallForPrice,
  1266.                         Price = productVariant.Price,
  1267.                         OldPrice = productVariant.OldPrice,
  1268.                         ProductCost = productVariant.ProductCost,
  1269.                         CustomerEntersPrice = productVariant.CustomerEntersPrice,
  1270.                         MinimumCustomerEnteredPrice = productVariant.MinimumCustomerEnteredPrice,
  1271.                         MaximumCustomerEnteredPrice = productVariant.MaximumCustomerEnteredPrice,
  1272.                         Weight = productVariant.Weight,
  1273.                         Length = productVariant.Length,
  1274.                         Width = productVariant.Width,
  1275.                         Height = productVariant.Height,
  1276.                         PictureId = pictureId,
  1277.                         AvailableStartDateTime = productVariant.AvailableStartDateTime,
  1278.                         AvailableEndDateTime = productVariant.AvailableEndDateTime,
  1279.                         Published = productVariant.Published,
  1280.                         Deleted = productVariant.Deleted,
  1281.                         DisplayOrder = productVariant.DisplayOrder,
  1282.                         CreatedOn = DateTime.UtcNow,
  1283.                         UpdatedOn = DateTime.UtcNow
  1284.                     };
  1285.  
  1286.                     InsertProductVariant(productVariantCopy);
  1287.  
  1288.                     //localization
  1289.                     foreach (var lang in languages)
  1290.                     {
  1291.                         var productVariantLocalized = GetProductVariantLocalizedByProductVariantIdAndLanguageId(productVariant.ProductVariantId, lang.LanguageId);
  1292.                         if (productVariantLocalized != null)
  1293.                         {
  1294.                             var productVariantLocalizedCopy = new ProductVariantLocalized()
  1295.                             {
  1296.                                 ProductVariantId = productVariantCopy.ProductVariantId,
  1297.                                 LanguageId = productVariantLocalized.LanguageId,
  1298.                                 Name = productVariantLocalized.Name,
  1299.                                 Description = productVariantLocalized.Description
  1300.                             };
  1301.                             InsertProductVariantLocalized(productVariantLocalizedCopy);
  1302.                         }
  1303.                     }
  1304.  
  1305.                     // product variant <-> attributes mappings
  1306.                     foreach (var productVariantAttribute in IoC.Resolve<IProductAttributeService>().GetProductVariantAttributesByProductVariantId(productVariant.ProductVariantId))
  1307.                     {
  1308.                         var productVariantAttributeCopy = new ProductVariantAttribute()
  1309.                         {
  1310.                             ProductVariantId = productVariantCopy.ProductVariantId,
  1311.                             ProductAttributeId = productVariantAttribute.ProductAttributeId,
  1312.                             TextPrompt = productVariantAttribute.TextPrompt,
  1313.                             IsRequired = productVariantAttribute.IsRequired,
  1314.                             AttributeControlTypeId = productVariantAttribute.AttributeControlTypeId,
  1315.                             DisplayOrder = productVariantAttribute.DisplayOrder
  1316.                         };
  1317.                         IoC.Resolve<IProductAttributeService>().InsertProductVariantAttribute(productVariantAttributeCopy);
  1318.  
  1319.                         // product variant attribute values
  1320.                         var productVariantAttributeValues = IoC.Resolve<IProductAttributeService>().GetProductVariantAttributeValues(productVariantAttribute.ProductVariantAttributeId);
  1321.                         foreach (var productVariantAttributeValue in productVariantAttributeValues)
  1322.                         {
  1323.                             var pvavCopy = new ProductVariantAttributeValue()
  1324.                             {
  1325.                                 ProductVariantAttributeId = productVariantAttributeCopy.ProductVariantAttributeId,
  1326.                                 Name = productVariantAttributeValue.Name,
  1327.                                 PriceAdjustment = productVariantAttributeValue.PriceAdjustment,
  1328.                                 WeightAdjustment = productVariantAttributeValue.WeightAdjustment,
  1329.                                 IsPreSelected = productVariantAttributeValue.IsPreSelected,
  1330.                                 DisplayOrder = productVariantAttributeValue.DisplayOrder
  1331.                             };
  1332.                             IoC.Resolve<IProductAttributeService>().InsertProductVariantAttributeValue(pvavCopy);
  1333.  
  1334.                             //localization
  1335.                             foreach (var lang in languages)
  1336.                             {
  1337.                                 var pvavLocalized = IoC.Resolve<IProductAttributeService>().GetProductVariantAttributeValueLocalizedByProductVariantAttributeValueIdAndLanguageId(productVariantAttributeValue.ProductVariantAttributeValueId, lang.LanguageId);
  1338.                                 if (pvavLocalized != null)
  1339.                                 {
  1340.                                     var pvavLocalizedCopy = new ProductVariantAttributeValueLocalized()
  1341.                                     {
  1342.                                         ProductVariantAttributeValueId = pvavCopy.ProductVariantAttributeValueId,
  1343.                                         LanguageId = pvavLocalized.LanguageId,
  1344.                                         Name = pvavLocalized.Name
  1345.                                     };
  1346.                                     IoC.Resolve<IProductAttributeService>().InsertProductVariantAttributeValueLocalized(pvavLocalizedCopy);
  1347.                                 }
  1348.                             }
  1349.                         }
  1350.                     }
  1351.                     foreach (var combination in IoC.Resolve<IProductAttributeService>().GetAllProductVariantAttributeCombinations(productVariant.ProductVariantId))
  1352.                     {
  1353.                         var combinationCopy = new ProductVariantAttributeCombination()
  1354.                         {
  1355.                             ProductVariantId = productVariantCopy.ProductVariantId,
  1356.                             AttributesXml = combination.AttributesXml,
  1357.                             StockQuantity = combination.StockQuantity,
  1358.                             AllowOutOfStockOrders = combination.AllowOutOfStockOrders
  1359.                         };
  1360.                         IoC.Resolve<IProductAttributeService>().InsertProductVariantAttributeCombination(combinationCopy);
  1361.                     }
  1362.  
  1363.                     // product variant tier prices
  1364.                     foreach (var tierPrice in productVariant.TierPrices)
  1365.                     {
  1366.                         InsertTierPrice(
  1367.                             new TierPrice()
  1368.                             {
  1369.                                 ProductVariantId = productVariantCopy.ProductVariantId,
  1370.                                 Quantity = tierPrice.Quantity,
  1371.                                 Price = tierPrice.Price
  1372.                             });
  1373.                     }
  1374.  
  1375.                     // product variant <-> discounts mapping
  1376.                     foreach (var discount in productVariant.AllDiscounts)
  1377.                     {
  1378.                         IoC.Resolve<IDiscountService>().AddDiscountToProductVariant(productVariantCopy.ProductVariantId, discount.DiscountId);
  1379.                     }
  1380.  
  1381.                     // prices by customer role
  1382.                     foreach (var crpp in productVariant.CustomerRoleProductPrices)
  1383.                     {
  1384.                         this.InsertCustomerRoleProductPrice(
  1385.                             new CustomerRoleProductPrice()
  1386.                             {
  1387.                                 CustomerRoleId = crpp.CustomerRoleId,
  1388.                                 ProductVariantId = productVariantCopy.ProductVariantId,
  1389.                                 Price = crpp.Price
  1390.                             }
  1391.                             );
  1392.                     }
  1393.                 }
  1394.  
  1395.                 //uncomment this line to support transactions
  1396.                 //scope.Complete();
  1397.             }
  1398.  
  1399.             return productCopy;
  1400.         }
  1401.  
  1402.         /// <summary>
  1403.         /// Gets a cross-sells
  1404.         /// </summary>
  1405.         /// <param name="cart">Shopping cart</param>
  1406.         /// <returns>Cross-sells</returns>
  1407.         public List<Product> GetCrosssellProductsByShoppingCart(ShoppingCart cart)
  1408.         {
  1409.             List<Product> result = new List<Product>();
  1410.  
  1411.             if (this.CrossSellsNumber == 0)
  1412.                 return result;
  1413.  
  1414.             if (cart == null || cart.Count == 0)
  1415.                 return result;
  1416.  
  1417.             List<int> cartProductIds = new List<int>();
  1418.             foreach (var sci in cart)
  1419.             {
  1420.                 int prodId = sci.ProductVariant.ProductId;
  1421.                 if (!cartProductIds.Contains(prodId))
  1422.                 {
  1423.                     cartProductIds.Add(prodId);
  1424.                 }
  1425.             }
  1426.  
  1427.             for (int i = 0; i < cart.Count; i++)
  1428.             {
  1429.                 var sci = cart[i];
  1430.                 var crossSells = sci.ProductVariant.Product.CrossSellProducts;
  1431.                 foreach (var crossSell in crossSells)
  1432.                 {
  1433.                     //TODO create a helper method to validate product availability (dates, quantity) etc
  1434.  
  1435.  
  1436.                     //validate that this product is not added to result yet
  1437.                     //validate that this product is not in the cart
  1438.                     if (result.Find(p => p.ProductId == crossSell.ProductId2) == null &&
  1439.                         !cartProductIds.Contains(crossSell.ProductId2))
  1440.                     {
  1441.                         result.Add(crossSell.Product2);
  1442.                         if (result.Count >= this.CrossSellsNumber)
  1443.                             return result;
  1444.                     }
  1445.                 }
  1446.             }
  1447.             return result;
  1448.         }
  1449.  
  1450.         #endregion
  1451.  
  1452.         #region Product variants
  1453.  
  1454.         /// <summary>
  1455.         /// Get low stock product variants
  1456.         /// </summary>
  1457.         /// <returns>Result</returns>
  1458.         public List<ProductVariant> GetLowStockProductVariants()
  1459.         {
  1460.  
  1461.             var query = from pv in _context.ProductVariants
  1462.                         orderby pv.MinStockQuantity
  1463.                         where !pv.Deleted &&
  1464.                         pv.MinStockQuantity >= pv.StockQuantity
  1465.                         select pv;
  1466.             var productVariants = query.ToList();
  1467.             return productVariants;
  1468.         }
  1469.  
  1470.         /// <summary>
  1471.         /// Gets a product variant
  1472.         /// </summary>
  1473.         /// <param name="productVariantId">Product variant identifier</param>
  1474.         /// <returns>Product variant</returns>
  1475.         public ProductVariant GetProductVariantById(int productVariantId)
  1476.         {
  1477.             if (productVariantId == 0)
  1478.                 return null;
  1479.  
  1480.             string key = string.Format(PRODUCTVARIANTS_BY_ID_KEY, productVariantId);
  1481.             object obj2 = _cacheManager.Get(key);
  1482.             if (this.CacheEnabled && (obj2 != null))
  1483.             {
  1484.                 return (ProductVariant)obj2;
  1485.             }
  1486.  
  1487.  
  1488.             var query = from pv in _context.ProductVariants
  1489.                         where pv.ProductVariantId == productVariantId
  1490.                         select pv;
  1491.             var productVariant = query.SingleOrDefault();
  1492.  
  1493.             if (this.CacheEnabled)
  1494.             {
  1495.                 _cacheManager.Add(key, productVariant);
  1496.             }
  1497.             return productVariant;
  1498.         }
  1499.  
  1500.         /// <summary>
  1501.         /// Gets a product variant by SKU
  1502.         /// </summary>
  1503.         /// <param name="sku">SKU</param>
  1504.         /// <returns>Product variant</returns>
  1505.         public ProductVariant GetProductVariantBySKU(string sku)
  1506.         {
  1507.             if (string.IsNullOrEmpty(sku))
  1508.                 return null;
  1509.  
  1510.             sku = sku.Trim();
  1511.  
  1512.  
  1513.             var query = from pv in _context.ProductVariants
  1514.                         orderby pv.DisplayOrder, pv.ProductVariantId
  1515.                         where !pv.Deleted &&
  1516.                         pv.SKU == sku
  1517.                         select pv;
  1518.             var productVariant = query.FirstOrDefault();
  1519.             return productVariant;
  1520.         }
  1521.  
  1522.         /// <summary>
  1523.         /// Gets all product variants
  1524.         /// </summary>
  1525.         /// <param name="categoryId">Category identifier</param>
  1526.         /// <param name="manufacturerId">Manufacturer identifier</param>
  1527.         /// <param name="keywords">Keywords</param>
  1528.         /// <param name="pageSize">Page size</param>
  1529.         /// <param name="pageIndex">Page index</param>
  1530.         /// <param name="totalRecords">Total records</param>
  1531.         /// <returns>Product variants</returns>
  1532.         public List<ProductVariant> GetAllProductVariants(int categoryId,
  1533.             int manufacturerId, string keywords,
  1534.             int pageSize, int pageIndex, out int totalRecords)
  1535.         {
  1536.             if (pageSize <= 0)
  1537.                 pageSize = 10;
  1538.             if (pageSize == int.MaxValue)
  1539.                 pageSize = int.MaxValue - 1;
  1540.  
  1541.             if (pageIndex < 0)
  1542.                 pageIndex = 0;
  1543.             if (pageIndex == int.MaxValue)
  1544.                 pageIndex = int.MaxValue - 1;
  1545.  
  1546.             bool showHidden = NopContext.Current.IsAdmin;
  1547.  
  1548.  
  1549.             ObjectParameter totalRecordsParameter = new ObjectParameter("TotalRecords", typeof(int));
  1550.             var productVariants = _context.Sp_ProductVariantLoadAll(categoryId,
  1551.                 manufacturerId, keywords, showHidden,
  1552.                 pageIndex, pageSize, totalRecordsParameter).ToList();
  1553.             totalRecords = Convert.ToInt32(totalRecordsParameter.Value);
  1554.  
  1555.             return productVariants;
  1556.         }
  1557.  
  1558.         /// <summary>
  1559.         /// Inserts a product variant
  1560.         /// </summary>
  1561.         /// <param name="productVariant">The product variant</param>
  1562.         public void InsertProductVariant(ProductVariant productVariant)
  1563.         {
  1564.             if (productVariant == null)
  1565.                 throw new ArgumentNullException("productVariant");
  1566.  
  1567.             productVariant.Name = CommonHelper.EnsureNotNull(productVariant.Name);
  1568.             productVariant.Name = CommonHelper.EnsureMaximumLength(productVariant.Name, 400);
  1569.             productVariant.SKU = CommonHelper.EnsureNotNull(productVariant.SKU);
  1570.             productVariant.SKU = productVariant.SKU.Trim();
  1571.             productVariant.SKU = CommonHelper.EnsureMaximumLength(productVariant.SKU, 100);
  1572.             productVariant.Description = CommonHelper.EnsureNotNull(productVariant.Description);
  1573.             productVariant.Description = CommonHelper.EnsureMaximumLength(productVariant.Description, 4000);
  1574.             productVariant.AdminComment = CommonHelper.EnsureNotNull(productVariant.AdminComment);
  1575.             productVariant.AdminComment = CommonHelper.EnsureMaximumLength(productVariant.AdminComment, 4000);
  1576.             productVariant.ManufacturerPartNumber = CommonHelper.EnsureNotNull(productVariant.ManufacturerPartNumber);
  1577.             productVariant.ManufacturerPartNumber = CommonHelper.EnsureMaximumLength(productVariant.ManufacturerPartNumber, 100);
  1578.             productVariant.UserAgreementText = CommonHelper.EnsureNotNull(productVariant.UserAgreementText);
  1579.  
  1580.  
  1581.  
  1582.             _context.ProductVariants.AddObject(productVariant);
  1583.             _context.SaveChanges();
  1584.  
  1585.             if (this.CacheEnabled)
  1586.             {
  1587.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  1588.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  1589.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  1590.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  1591.             }
  1592.  
  1593.             //raise event            
  1594.             EventContext.Current.OnProductVariantCreated(null,
  1595.                 new ProductVariantEventArgs() { ProductVariant = productVariant });
  1596.         }
  1597.  
  1598.         /// <summary>
  1599.         /// Updates the product variant
  1600.         /// </summary>
  1601.         /// <param name="productVariant">The product variant</param>
  1602.         public void UpdateProductVariant(ProductVariant productVariant)
  1603.         {
  1604.             if (productVariant == null)
  1605.                 throw new ArgumentNullException("productVariant");
  1606.  
  1607.             productVariant.Name = CommonHelper.EnsureNotNull(productVariant.Name);
  1608.             productVariant.Name = CommonHelper.EnsureMaximumLength(productVariant.Name, 400);
  1609.             productVariant.SKU = CommonHelper.EnsureNotNull(productVariant.SKU);
  1610.             productVariant.SKU = productVariant.SKU.Trim();
  1611.             productVariant.SKU = CommonHelper.EnsureMaximumLength(productVariant.SKU, 100);
  1612.             productVariant.Description = CommonHelper.EnsureNotNull(productVariant.Description);
  1613.             productVariant.Description = CommonHelper.EnsureMaximumLength(productVariant.Description, 4000);
  1614.             productVariant.AdminComment = CommonHelper.EnsureNotNull(productVariant.AdminComment);
  1615.             productVariant.AdminComment = CommonHelper.EnsureMaximumLength(productVariant.AdminComment, 4000);
  1616.             productVariant.ManufacturerPartNumber = CommonHelper.EnsureNotNull(productVariant.ManufacturerPartNumber);
  1617.             productVariant.ManufacturerPartNumber = CommonHelper.EnsureMaximumLength(productVariant.ManufacturerPartNumber, 100);
  1618.             productVariant.UserAgreementText = CommonHelper.EnsureNotNull(productVariant.UserAgreementText);
  1619.  
  1620.  
  1621.             if (!_context.IsAttached(productVariant))
  1622.                 _context.ProductVariants.Attach(productVariant);
  1623.  
  1624.             _context.SaveChanges();
  1625.  
  1626.             if (this.CacheEnabled)
  1627.             {
  1628.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  1629.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  1630.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  1631.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  1632.             }
  1633.  
  1634.             //raise event            
  1635.             EventContext.Current.OnProductVariantUpdated(null,
  1636.                 new ProductVariantEventArgs() { ProductVariant = productVariant });
  1637.         }
  1638.  
  1639.         /// <summary>
  1640.         /// Gets product variants by product identifier
  1641.         /// </summary>
  1642.         /// <param name="productId">The product identifier</param>
  1643.         /// <returns>Product variant collection</returns>
  1644.         public List<ProductVariant> GetProductVariantsByProductId(int productId)
  1645.         {
  1646.             bool showHidden = NopContext.Current.IsAdmin;
  1647.             return GetProductVariantsByProductId(productId, showHidden);
  1648.         }
  1649.  
  1650.         /// <summary>
  1651.         /// Gets product variants by product identifier
  1652.         /// </summary>
  1653.         /// <param name="productId">The product identifier</param>
  1654.         /// <param name="showHidden">A value indicating whether to show hidden records</param>
  1655.         /// <returns>Product variant collection</returns>
  1656.         public List<ProductVariant> GetProductVariantsByProductId(int productId, bool showHidden)
  1657.         {
  1658.             string key = string.Format(PRODUCTVARIANTS_ALL_KEY, showHidden, productId);
  1659.             object obj2 = _cacheManager.Get(key);
  1660.             if (this.CacheEnabled && (obj2 != null))
  1661.             {
  1662.                 return (List<ProductVariant>)obj2;
  1663.             }
  1664.  
  1665.  
  1666.             var query = (IQueryable<ProductVariant>)_context.ProductVariants;
  1667.             if (!showHidden)
  1668.             {
  1669.                 query = query.Where(pv => pv.Published);
  1670.             }
  1671.             if (!showHidden)
  1672.             {
  1673.                 query = query.Where(pv => !pv.AvailableStartDateTime.HasValue || pv.AvailableStartDateTime <= DateTime.UtcNow);
  1674.                 query = query.Where(pv => !pv.AvailableEndDateTime.HasValue || pv.AvailableEndDateTime >= DateTime.UtcNow);
  1675.             }
  1676.             query = query.Where(pv => !pv.Deleted);
  1677.             query = query.Where(pv => pv.ProductId == productId);
  1678.             query = query.OrderBy(pv => pv.DisplayOrder);
  1679.  
  1680.             var productVariants = query.ToList();
  1681.  
  1682.             if (this.CacheEnabled)
  1683.             {
  1684.                 _cacheManager.Add(key, productVariants);
  1685.             }
  1686.             return productVariants;
  1687.         }
  1688.  
  1689.         /// <summary>
  1690.         /// Gets restricted product variants by discount identifier
  1691.         /// </summary>
  1692.         /// <param name="discountId">The discount identifier</param>
  1693.         /// <returns>Product variant collection</returns>
  1694.         public List<ProductVariant> GetProductVariantsRestrictedByDiscountId(int discountId)
  1695.         {
  1696.             if (discountId == 0)
  1697.                 return new List<ProductVariant>();
  1698.  
  1699.  
  1700.             var query = from pv in _context.ProductVariants
  1701.                         from d in pv.NpRestrictedDiscounts
  1702.                         where d.DiscountId == discountId
  1703.                         select pv;
  1704.             var productVariants = query.ToList();
  1705.             return productVariants;
  1706.         }
  1707.  
  1708.         /// <summary>
  1709.         /// Gets localized product variant by id
  1710.         /// </summary>
  1711.         /// <param name="productVariantLocalizedId">Localized product variant identifier</param>
  1712.         /// <returns>Product variant content</returns>
  1713.         public ProductVariantLocalized GetProductVariantLocalizedById(int productVariantLocalizedId)
  1714.         {
  1715.             if (productVariantLocalizedId == 0)
  1716.                 return null;
  1717.  
  1718.  
  1719.             var query = from pvl in _context.ProductVariantLocalized
  1720.                         where pvl.ProductVariantLocalizedId == productVariantLocalizedId
  1721.                         select pvl;
  1722.             var productVariantLocalized = query.SingleOrDefault();
  1723.             return productVariantLocalized;
  1724.         }
  1725.  
  1726.         /// <summary>
  1727.         /// Gets localized product variant by product variant id
  1728.         /// </summary>
  1729.         /// <param name="productVariantId">Product variant identifier</param>
  1730.         /// <returns>Product variant content</returns>
  1731.         public List<ProductVariantLocalized> GetProductVariantLocalizedByProductVariantId(int productVariantId)
  1732.         {
  1733.             if (productVariantId == 0)
  1734.                 return new List<ProductVariantLocalized>();
  1735.  
  1736.  
  1737.             var query = from pvl in _context.ProductVariantLocalized
  1738.                         where pvl.ProductVariantId == productVariantId
  1739.                         select pvl;
  1740.             var content = query.ToList();
  1741.             return content;
  1742.         }
  1743.  
  1744.         /// <summary>
  1745.         /// Gets localized product variant by product variant id and language id
  1746.         /// </summary>
  1747.         /// <param name="productVariantId">Product variant identifier</param>
  1748.         /// <param name="languageId">Language identifier</param>
  1749.         /// <returns>Product variant content</returns>
  1750.         public ProductVariantLocalized GetProductVariantLocalizedByProductVariantIdAndLanguageId(int productVariantId, int languageId)
  1751.         {
  1752.             if (productVariantId == 0 || languageId == 0)
  1753.                 return null;
  1754.  
  1755.  
  1756.             var query = from pvl in _context.ProductVariantLocalized
  1757.                         orderby pvl.ProductVariantLocalizedId
  1758.                         where pvl.ProductVariantId == productVariantId &&
  1759.                         pvl.LanguageId == languageId
  1760.                         select pvl;
  1761.             var productVariantLocalized = query.FirstOrDefault();
  1762.             return productVariantLocalized;
  1763.         }
  1764.  
  1765.         /// <summary>
  1766.         /// Inserts a localized product variant
  1767.         /// </summary>
  1768.         /// <param name="productVariantLocalized">Localized product variant</param>
  1769.         public void InsertProductVariantLocalized(ProductVariantLocalized productVariantLocalized)
  1770.         {
  1771.             if (productVariantLocalized == null)
  1772.                 throw new ArgumentNullException("productVariantLocalized");
  1773.  
  1774.             productVariantLocalized.Name = CommonHelper.EnsureNotNull(productVariantLocalized.Name);
  1775.             productVariantLocalized.Name = CommonHelper.EnsureMaximumLength(productVariantLocalized.Name, 400);
  1776.             productVariantLocalized.Description = CommonHelper.EnsureNotNull(productVariantLocalized.Description);
  1777.  
  1778.  
  1779.  
  1780.             _context.ProductVariantLocalized.AddObject(productVariantLocalized);
  1781.             _context.SaveChanges();
  1782.  
  1783.             if (this.CacheEnabled)
  1784.             {
  1785.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  1786.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  1787.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  1788.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  1789.             }
  1790.         }
  1791.  
  1792.         /// <summary>
  1793.         /// Update a localized product variant
  1794.         /// </summary>
  1795.         /// <param name="productVariantLocalized">Localized product variant</param>
  1796.         public void UpdateProductVariantLocalized(ProductVariantLocalized productVariantLocalized)
  1797.         {
  1798.             if (productVariantLocalized == null)
  1799.                 throw new ArgumentNullException("productVariantLocalized");
  1800.  
  1801.             productVariantLocalized.Name = CommonHelper.EnsureNotNull(productVariantLocalized.Name);
  1802.             productVariantLocalized.Name = CommonHelper.EnsureMaximumLength(productVariantLocalized.Name, 400);
  1803.             productVariantLocalized.Description = CommonHelper.EnsureNotNull(productVariantLocalized.Description);
  1804.  
  1805.             bool allFieldsAreEmpty = string.IsNullOrEmpty(productVariantLocalized.Name) &&
  1806.                string.IsNullOrEmpty(productVariantLocalized.Description);
  1807.  
  1808.  
  1809.             if (!_context.IsAttached(productVariantLocalized))
  1810.                 _context.ProductVariantLocalized.Attach(productVariantLocalized);
  1811.  
  1812.             if (allFieldsAreEmpty)
  1813.             {
  1814.                 //delete if all fields are empty
  1815.                 _context.DeleteObject(productVariantLocalized);
  1816.                 _context.SaveChanges();
  1817.             }
  1818.             else
  1819.             {
  1820.                 _context.SaveChanges();
  1821.             }
  1822.  
  1823.             if (this.CacheEnabled)
  1824.             {
  1825.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  1826.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  1827.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  1828.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  1829.             }
  1830.         }
  1831.  
  1832.         /// <summary>
  1833.         /// Marks a product variant as deleted
  1834.         /// </summary>
  1835.         /// <param name="productVariantId">Product variant identifier</param>
  1836.         public void MarkProductVariantAsDeleted(int productVariantId)
  1837.         {
  1838.             var productVariant = GetProductVariantById(productVariantId);
  1839.             if (productVariant != null)
  1840.             {
  1841.                 productVariant.Deleted = true;
  1842.                 productVariant.Published = false;
  1843.                 UpdateProductVariant(productVariant);
  1844.             }
  1845.  
  1846.             ProductTracker pt = NetC.Utils.FindProductTrackerByPVId(productVariantId);
  1847.             if (pt != null)
  1848.             {
  1849.                 pt.Delete();
  1850.             }
  1851.         }
  1852.  
  1853.         /// <summary>
  1854.         /// Adjusts inventory
  1855.         /// </summary>
  1856.         /// <param name="productVariantId">Product variant identifier</param>
  1857.         /// <param name="decrease">A value indicating whether to increase or descrease product variant stock quantity</param>
  1858.         /// <param name="quantity">Quantity</param>
  1859.         /// <param name="attributesXml">Attributes in XML format</param>
  1860.         public void AdjustInventory(int productVariantId, bool decrease,
  1861.             int quantity, string attributesXml)
  1862.         {
  1863.             var productVariant = GetProductVariantById(productVariantId);
  1864.             if (productVariant == null)
  1865.                 return;
  1866.  
  1867.             switch ((ManageInventoryMethodEnum)productVariant.ManageInventory)
  1868.             {
  1869.                 case ManageInventoryMethodEnum.DontManageStock:
  1870.                     {
  1871.                         //do nothing
  1872.                         return;
  1873.                     }
  1874.                 case ManageInventoryMethodEnum.ManageStock:
  1875.                     {
  1876.                         int newStockQuantity = 0;
  1877.                         if (decrease)
  1878.                             newStockQuantity = productVariant.StockQuantity - quantity;
  1879.                         else
  1880.                             newStockQuantity = productVariant.StockQuantity + quantity;
  1881.  
  1882.                         bool newPublished = productVariant.Published;
  1883.                         bool newDisableBuyButton = productVariant.DisableBuyButton;
  1884.  
  1885.                         //check if minimum quantity is reached
  1886.                         if (decrease)
  1887.                         {
  1888.                             if (productVariant.MinStockQuantity >= newStockQuantity)
  1889.                             {
  1890.                                 switch (productVariant.LowStockActivity)
  1891.                                 {
  1892.                                     case LowStockActivityEnum.DisableBuyButton:
  1893.                                         newDisableBuyButton = true;
  1894.                                         break;
  1895.                                     case LowStockActivityEnum.Unpublish:
  1896.                                         newPublished = false;
  1897.                                         break;
  1898.                                     default:
  1899.                                         break;
  1900.                                 }
  1901.                             }
  1902.                         }
  1903.  
  1904.                         if (decrease && productVariant.NotifyAdminForQuantityBelow > newStockQuantity)
  1905.                         {
  1906.                             IoC.Resolve<IMessageService>().SendQuantityBelowStoreOwnerNotification(productVariant, IoC.Resolve<ILocalizationManager>().DefaultAdminLanguage.LanguageId);
  1907.                         }
  1908.  
  1909.                         productVariant.StockQuantity = newStockQuantity;
  1910.                         productVariant.DisableBuyButton = newDisableBuyButton;
  1911.                         productVariant.Published = newPublished;
  1912.                         UpdateProductVariant(productVariant);
  1913.  
  1914.                         if (decrease)
  1915.                         {
  1916.                             var product = productVariant.Product;
  1917.                             bool allProductVariantsUnpublished = true;
  1918.                             foreach (var pv2 in product.ProductVariants)
  1919.                             {
  1920.                                 if (pv2.Published)
  1921.                                 {
  1922.                                     allProductVariantsUnpublished = false;
  1923.                                     break;
  1924.                                 }
  1925.                             }
  1926.  
  1927.                             if (allProductVariantsUnpublished)
  1928.                             {
  1929.                                 product.Published = false;
  1930.                                 UpdateProduct(product);
  1931.                             }
  1932.                         }
  1933.                     }
  1934.                     break;
  1935.                 case ManageInventoryMethodEnum.ManageStockByAttributes:
  1936.                     {
  1937.                         var combination = IoC.Resolve<IProductAttributeService>().FindProductVariantAttributeCombination(productVariant.ProductVariantId, attributesXml);
  1938.                         if (combination != null)
  1939.                         {
  1940.                             int newStockQuantity = 0;
  1941.                             if (decrease)
  1942.                                 newStockQuantity = combination.StockQuantity - quantity;
  1943.                             else
  1944.                                 newStockQuantity = combination.StockQuantity + quantity;
  1945.  
  1946.                             combination.StockQuantity = newStockQuantity;
  1947.                             IoC.Resolve<IProductAttributeService>().UpdateProductVariantAttributeCombination(combination);
  1948.                         }
  1949.                     }
  1950.                     break;
  1951.                 default:
  1952.                     break;
  1953.             }
  1954.         }
  1955.  
  1956.         #endregion
  1957.  
  1958.         #region Product pictures
  1959.  
  1960.         /// <summary>
  1961.         /// Deletes a product picture mapping
  1962.         /// </summary>
  1963.         /// <param name="productPictureId">Product picture mapping identifier</param>
  1964.         public void DeleteProductPicture(int productPictureId)
  1965.         {
  1966.             var productPicture = GetProductPictureById(productPictureId);
  1967.             if (productPicture == null)
  1968.                 return;
  1969.  
  1970.  
  1971.             if (!_context.IsAttached(productPicture))
  1972.                 _context.ProductPictures.Attach(productPicture);
  1973.             _context.DeleteObject(productPicture);
  1974.             _context.SaveChanges();
  1975.         }
  1976.  
  1977.         /// <summary>
  1978.         /// Gets a product picture mapping
  1979.         /// </summary>
  1980.         /// <param name="productPictureId">Product picture mapping identifier</param>
  1981.         /// <returns>Product picture mapping</returns>
  1982.         public ProductPicture GetProductPictureById(int productPictureId)
  1983.         {
  1984.             if (productPictureId == 0)
  1985.                 return null;
  1986.  
  1987.  
  1988.             var query = from pp in _context.ProductPictures
  1989.                         where pp.ProductPictureId == productPictureId
  1990.                         select pp;
  1991.             var productPicture = query.SingleOrDefault();
  1992.             return productPicture;
  1993.         }
  1994.  
  1995.         /// <summary>
  1996.         /// Inserts a product picture mapping
  1997.         /// </summary>
  1998.         /// <param name="productPicture">Product picture mapping</param>
  1999.         public void InsertProductPicture(ProductPicture productPicture)
  2000.         {
  2001.             if (productPicture == null)
  2002.                 throw new ArgumentNullException("productPicture");
  2003.  
  2004.  
  2005.  
  2006.             _context.ProductPictures.AddObject(productPicture);
  2007.             _context.SaveChanges();
  2008.         }
  2009.  
  2010.         /// <summary>
  2011.         /// Updates the product picture mapping
  2012.         /// </summary>
  2013.         /// <param name="productPicture">Product picture mapping</param>
  2014.         public void UpdateProductPicture(ProductPicture productPicture)
  2015.         {
  2016.             if (productPicture == null)
  2017.                 throw new ArgumentNullException("productPicture");
  2018.  
  2019.  
  2020.             if (!_context.IsAttached(productPicture))
  2021.                 _context.ProductPictures.Attach(productPicture);
  2022.  
  2023.             _context.SaveChanges();
  2024.         }
  2025.  
  2026.         /// <summary>
  2027.         /// Gets all product picture mappings by product identifier
  2028.         /// </summary>
  2029.         /// <param name="productId">Product identifier</param>
  2030.         /// <returns>Product picture mapping collection</returns>
  2031.         public List<ProductPicture> GetProductPicturesByProductId(int productId)
  2032.         {
  2033.  
  2034.             var query = (IQueryable<ProductPicture>)_context.ProductPictures;
  2035.             query = query.Where(pp => pp.ProductId == productId);
  2036.             query = query.OrderBy(pp => pp.DisplayOrder);
  2037.  
  2038.             var productPictures = query.ToList();
  2039.             return productPictures;
  2040.         }
  2041.         #endregion
  2042.  
  2043.         #region Product reviews
  2044.  
  2045.         /// <summary>
  2046.         /// Gets a product review
  2047.         /// </summary>
  2048.         /// <param name="productReviewId">Product review identifier</param>
  2049.         /// <returns>Product review</returns>
  2050.         public ProductReview GetProductReviewById(int productReviewId)
  2051.         {
  2052.             if (productReviewId == 0)
  2053.                 return null;
  2054.  
  2055.  
  2056.             var query = from pr in _context.ProductReviews
  2057.                         where pr.ProductReviewId == productReviewId
  2058.                         select pr;
  2059.             var productReview = query.SingleOrDefault();
  2060.             return productReview;
  2061.         }
  2062.  
  2063.         /// <summary>
  2064.         /// Gets a product review collection by product identifier
  2065.         /// </summary>
  2066.         /// <param name="productId">Product identifier</param>
  2067.         /// <returns>Product review collection</returns>
  2068.         public List<ProductReview> GetProductReviewByProductId(int productId)
  2069.         {
  2070.             bool showHidden = NopContext.Current.IsAdmin;
  2071.  
  2072.  
  2073.             var query = from pr in _context.ProductReviews
  2074.                         orderby pr.CreatedOn descending
  2075.                         where (showHidden || pr.IsApproved) &&
  2076.                         pr.ProductId == productId
  2077.                         select pr;
  2078.             var productReviews = query.ToList();
  2079.             return productReviews;
  2080.         }
  2081.  
  2082.         /// <summary>
  2083.         /// Deletes a product review
  2084.         /// </summary>
  2085.         /// <param name="productReviewId">Product review identifier</param>
  2086.         public void DeleteProductReview(int productReviewId)
  2087.         {
  2088.             var productReview = GetProductReviewById(productReviewId);
  2089.             if (productReview == null)
  2090.                 return;
  2091.  
  2092.  
  2093.             if (!_context.IsAttached(productReview))
  2094.                 _context.ProductReviews.Attach(productReview);
  2095.             _context.DeleteObject(productReview);
  2096.             _context.SaveChanges();
  2097.         }
  2098.  
  2099.         /// <summary>
  2100.         /// Gets all product reviews
  2101.         /// </summary>
  2102.         /// <returns>Product review collection</returns>
  2103.         public List<ProductReview> GetAllProductReviews()
  2104.         {
  2105.             bool showHidden = NopContext.Current.IsAdmin;
  2106.  
  2107.  
  2108.             var query = from pr in _context.ProductReviews
  2109.                         orderby pr.CreatedOn descending
  2110.                         where (showHidden || pr.IsApproved)
  2111.                         select pr;
  2112.             var productReviews = query.ToList();
  2113.             return productReviews;
  2114.         }
  2115.  
  2116.         /// <summary>
  2117.         /// Inserts a product review
  2118.         /// </summary>
  2119.         /// <param name="productId">The product identifier</param>
  2120.         /// <param name="customerId">The customer identifier</param>
  2121.         /// <param name="title">The review title</param>
  2122.         /// <param name="reviewText">The review text</param>
  2123.         /// <param name="rating">The review rating</param>
  2124.         /// <param name="helpfulYesTotal">Review helpful votes total</param>
  2125.         /// <param name="helpfulNoTotal">Review not helpful votes total</param>
  2126.         /// <param name="isApproved">A value indicating whether the product review is approved</param>
  2127.         /// <param name="createdOn">The date and time of instance creation</param>
  2128.         /// <returns>Product review</returns>
  2129.         public ProductReview InsertProductReview(int productId,
  2130.             int customerId, string title,
  2131.             string reviewText, int rating, int helpfulYesTotal,
  2132.             int helpfulNoTotal, bool isApproved, DateTime createdOn)
  2133.         {
  2134.             return InsertProductReview(productId, customerId,
  2135.              title, reviewText, rating, helpfulYesTotal,
  2136.              helpfulNoTotal, isApproved, createdOn,
  2137.              this.NotifyAboutNewProductReviews);
  2138.         }
  2139.  
  2140.         /// <summary>
  2141.         /// Inserts a product review
  2142.         /// </summary>
  2143.         /// <param name="productId">The product identifier</param>
  2144.         /// <param name="customerId">The customer identifier</param>
  2145.         /// <param name="title">The review title</param>
  2146.         /// <param name="reviewText">The review text</param>
  2147.         /// <param name="rating">The review rating</param>
  2148.         /// <param name="helpfulYesTotal">Review helpful votes total</param>
  2149.         /// <param name="helpfulNoTotal">Review not helpful votes total</param>
  2150.         /// <param name="isApproved">A value indicating whether the product review is approved</param>
  2151.         /// <param name="createdOn">The date and time of instance creation</param>
  2152.         /// <param name="notify">A value indicating whether to notify the store owner</param>
  2153.         /// <returns>Product review</returns>
  2154.         public ProductReview InsertProductReview(int productId,
  2155.             int customerId, string title,
  2156.             string reviewText, int rating, int helpfulYesTotal,
  2157.             int helpfulNoTotal, bool isApproved, DateTime createdOn, bool notify)
  2158.         {
  2159.             string IPAddress = NopContext.Current.UserHostAddress;
  2160.             return InsertProductReview(productId, customerId, IPAddress, title, reviewText, rating, helpfulYesTotal, helpfulNoTotal, isApproved, createdOn, notify);
  2161.         }
  2162.  
  2163.         /// <summary>
  2164.         /// Inserts a product review
  2165.         /// </summary>
  2166.         /// <param name="productId">The product identifier</param>
  2167.         /// <param name="customerId">The customer identifier</param>
  2168.         /// <param name="ipAddress">The IP address</param>
  2169.         /// <param name="title">The review title</param>
  2170.         /// <param name="reviewText">The review text</param>
  2171.         /// <param name="rating">The review rating</param>
  2172.         /// <param name="helpfulYesTotal">Review helpful votes total</param>
  2173.         /// <param name="helpfulNoTotal">Review not helpful votes total</param>
  2174.         /// <param name="isApproved">A value indicating whether the product review is approved</param>
  2175.         /// <param name="createdOn">The date and time of instance creation</param>
  2176.         /// <param name="notify">A value indicating whether to notify the store owner</param>
  2177.         /// <returns>Product review</returns>
  2178.         public ProductReview InsertProductReview(int productId,
  2179.             int customerId, string ipAddress, string title,
  2180.             string reviewText, int rating, int helpfulYesTotal,
  2181.             int helpfulNoTotal, bool isApproved, DateTime createdOn, bool notify)
  2182.         {
  2183.             if (rating < 1)
  2184.                 rating = 1;
  2185.             if (rating > 5)
  2186.                 rating = 5;
  2187.  
  2188.             ipAddress = CommonHelper.EnsureNotNull(ipAddress);
  2189.             ipAddress = CommonHelper.EnsureMaximumLength(ipAddress, 100);
  2190.             title = CommonHelper.EnsureNotNull(title);
  2191.             title = CommonHelper.EnsureMaximumLength(title, 1000);
  2192.             reviewText = CommonHelper.EnsureNotNull(reviewText);
  2193.  
  2194.  
  2195.  
  2196.             var productReview = _context.ProductReviews.CreateObject();
  2197.             productReview.ProductId = productId;
  2198.             productReview.CustomerId = customerId;
  2199.             productReview.IPAddress = ipAddress;
  2200.             productReview.Title = title;
  2201.             productReview.ReviewText = reviewText;
  2202.             productReview.Rating = rating;
  2203.             productReview.HelpfulYesTotal = helpfulYesTotal;
  2204.             productReview.HelpfulNoTotal = helpfulNoTotal;
  2205.             productReview.IsApproved = isApproved;
  2206.             productReview.CreatedOn = createdOn;
  2207.  
  2208.             _context.ProductReviews.AddObject(productReview);
  2209.             _context.SaveChanges();
  2210.  
  2211.             //activity log
  2212.             IoC.Resolve<ICustomerActivityService>().InsertActivity(
  2213.                 "WriteProductReview",
  2214.                 IoC.Resolve<ILocalizationManager>().GetLocaleResourceString("ActivityLog.WriteProductReview"),
  2215.                 productId);
  2216.  
  2217.             //notify store owner
  2218.             if (notify)
  2219.             {
  2220.                 IoC.Resolve<IMessageService>().SendProductReviewNotificationMessage(productReview, IoC.Resolve<ILocalizationManager>().DefaultAdminLanguage.LanguageId);
  2221.             }
  2222.  
  2223.             return productReview;
  2224.         }
  2225.  
  2226.         /// <summary>
  2227.         /// Updates the product review
  2228.         /// </summary>
  2229.         /// <param name="productReview">Product review</param>
  2230.         public void UpdateProductReview(ProductReview productReview)
  2231.         {
  2232.             if (productReview == null)
  2233.                 throw new ArgumentNullException("productReview");
  2234.  
  2235.             productReview.IPAddress = CommonHelper.EnsureNotNull(productReview.IPAddress);
  2236.             productReview.IPAddress = CommonHelper.EnsureMaximumLength(productReview.IPAddress, 100);
  2237.             productReview.Title = CommonHelper.EnsureNotNull(productReview.Title);
  2238.             productReview.Title = CommonHelper.EnsureMaximumLength(productReview.Title, 1000);
  2239.             productReview.ReviewText = CommonHelper.EnsureNotNull(productReview.ReviewText);
  2240.  
  2241.  
  2242.             if (!_context.IsAttached(productReview))
  2243.                 _context.ProductReviews.Attach(productReview);
  2244.  
  2245.             _context.SaveChanges();
  2246.         }
  2247.  
  2248.         /// <summary>
  2249.         /// Sets a product rating helpfulness
  2250.         /// </summary>
  2251.         /// <param name="productReviewId">Product review identifer</param>
  2252.         /// <param name="wasHelpful">A value indicating whether the product review was helpful or not </param>
  2253.         public void SetProductRatingHelpfulness(int productReviewId, bool wasHelpful)
  2254.         {
  2255.             if (NopContext.Current.User == null)
  2256.             {
  2257.                 return;
  2258.             }
  2259.             if (NopContext.Current.User.IsGuest && !IoC.Resolve<ICustomerService>().AllowAnonymousUsersToReviewProduct)
  2260.             {
  2261.                 return;
  2262.             }
  2263.  
  2264.             ProductReview productReview = GetProductReviewById(productReviewId);
  2265.             if (productReview == null)
  2266.                 return;
  2267.  
  2268.             //delete previous helpfulness            
  2269.             var oldPrh = (from prh in _context.ProductReviewHelpfulness
  2270.                           where prh.ProductReviewId == productReviewId &&
  2271.                           prh.CustomerId == NopContext.Current.User.CustomerId
  2272.                           select prh).FirstOrDefault();
  2273.             if (oldPrh != null)
  2274.             {
  2275.                 _context.DeleteObject(oldPrh);
  2276.             }
  2277.             _context.SaveChanges();
  2278.  
  2279.             //insert new helpfulness
  2280.             var newPrh = _context.ProductReviewHelpfulness.CreateObject();
  2281.             newPrh.ProductReviewId = productReviewId;
  2282.             newPrh.CustomerId = NopContext.Current.User.CustomerId;
  2283.             newPrh.WasHelpful = wasHelpful;
  2284.  
  2285.             _context.ProductReviewHelpfulness.AddObject(newPrh);
  2286.             _context.SaveChanges();
  2287.  
  2288.             //new totals
  2289.             int helpfulYesTotal = (from prh in _context.ProductReviewHelpfulness
  2290.                                    where prh.ProductReviewId == productReviewId &&
  2291.                                    prh.WasHelpful == true
  2292.                                    select prh).Count();
  2293.             int helpfulNoTotal = (from prh in _context.ProductReviewHelpfulness
  2294.                                   where prh.ProductReviewId == productReviewId &&
  2295.                                   prh.WasHelpful == false
  2296.                                   select prh).Count();
  2297.  
  2298.             productReview.HelpfulYesTotal = helpfulYesTotal;
  2299.             productReview.HelpfulNoTotal = helpfulNoTotal;
  2300.             UpdateProductReview(productReview);
  2301.         }
  2302.  
  2303.         #endregion
  2304.  
  2305.         #region Related products
  2306.  
  2307.         /// <summary>
  2308.         /// Deletes a related product
  2309.         /// </summary>
  2310.         /// <param name="relatedProductId">Related product identifer</param>
  2311.         public void DeleteRelatedProduct(int relatedProductId)
  2312.         {
  2313.             var relatedProduct = GetRelatedProductById(relatedProductId);
  2314.             if (relatedProduct == null)
  2315.                 return;
  2316.  
  2317.  
  2318.             if (!_context.IsAttached(relatedProduct))
  2319.                 _context.RelatedProducts.Attach(relatedProduct);
  2320.             _context.DeleteObject(relatedProduct);
  2321.             _context.SaveChanges();
  2322.         }
  2323.  
  2324.         /// <summary>
  2325.         /// Gets a related product collection by product identifier
  2326.         /// </summary>
  2327.         /// <param name="productId1">The first product identifier</param>
  2328.         /// <returns>Related product collection</returns>
  2329.         public List<RelatedProduct> GetRelatedProductsByProductId1(int productId1)
  2330.         {
  2331.             bool showHidden = NopContext.Current.IsAdmin;
  2332.  
  2333.  
  2334.             var query = from rp in _context.RelatedProducts
  2335.                         join p in _context.Products on rp.ProductId2 equals p.ProductId
  2336.                         where rp.ProductId1 == productId1 &&
  2337.                         !p.Deleted &&
  2338.                         (showHidden || p.Published)
  2339.                         orderby rp.DisplayOrder
  2340.                         select rp;
  2341.             var relatedProducts = query.ToList();
  2342.  
  2343.             return relatedProducts;
  2344.         }
  2345.  
  2346.         /// <summary>
  2347.         /// Gets a related product
  2348.         /// </summary>
  2349.         /// <param name="relatedProductId">Related product identifer</param>
  2350.         /// <returns>Related product</returns>
  2351.         public RelatedProduct GetRelatedProductById(int relatedProductId)
  2352.         {
  2353.             if (relatedProductId == 0)
  2354.                 return null;
  2355.  
  2356.  
  2357.             var query = from rp in _context.RelatedProducts
  2358.                         where rp.RelatedProductId == relatedProductId
  2359.                         select rp;
  2360.             var relatedProduct = query.SingleOrDefault();
  2361.             return relatedProduct;
  2362.         }
  2363.  
  2364.         /// <summary>
  2365.         /// Inserts a related product
  2366.         /// </summary>
  2367.         /// <param name="relatedProduct">Related product</param>
  2368.         public void InsertRelatedProduct(RelatedProduct relatedProduct)
  2369.         {
  2370.             if (relatedProduct == null)
  2371.                 throw new ArgumentNullException("relatedProduct");
  2372.  
  2373.  
  2374.  
  2375.             _context.RelatedProducts.AddObject(relatedProduct);
  2376.             _context.SaveChanges();
  2377.         }
  2378.  
  2379.         /// <summary>
  2380.         /// Updates a related product
  2381.         /// </summary>
  2382.         /// <param name="relatedProduct">Related product</param>
  2383.         public void UpdateRelatedProduct(RelatedProduct relatedProduct)
  2384.         {
  2385.             if (relatedProduct == null)
  2386.                 throw new ArgumentNullException("relatedProduct");
  2387.  
  2388.  
  2389.             if (!_context.IsAttached(relatedProduct))
  2390.                 _context.RelatedProducts.Attach(relatedProduct);
  2391.  
  2392.             _context.SaveChanges();
  2393.         }
  2394.  
  2395.         #endregion
  2396.  
  2397.         #region Cross-sell products
  2398.  
  2399.         /// <summary>
  2400.         /// Deletes a cross-sell product
  2401.         /// </summary>
  2402.         /// <param name="crossSellProductId">Cross-sell identifer</param>
  2403.         public void DeleteCrossSellProduct(int crossSellProductId)
  2404.         {
  2405.             var crossSellProduct = GetCrossSellProductById(crossSellProductId);
  2406.             if (crossSellProduct == null)
  2407.                 return;
  2408.  
  2409.  
  2410.             if (!_context.IsAttached(crossSellProduct))
  2411.                 _context.CrossSellProducts.Attach(crossSellProduct);
  2412.             _context.DeleteObject(crossSellProduct);
  2413.             _context.SaveChanges();
  2414.         }
  2415.  
  2416.         /// <summary>
  2417.         /// Gets a cross-sell product collection by product identifier
  2418.         /// </summary>
  2419.         /// <param name="productId1">The first product identifier</param>
  2420.         /// <returns>Cross-sell product collection</returns>
  2421.         public List<CrossSellProduct> GetCrossSellProductsByProductId1(int productId1)
  2422.         {
  2423.             bool showHidden = NopContext.Current.IsAdmin;
  2424.  
  2425.  
  2426.             var query = from csp in _context.CrossSellProducts
  2427.                         join p in _context.Products on csp.ProductId2 equals p.ProductId
  2428.                         where csp.ProductId1 == productId1 &&
  2429.                         !p.Deleted &&
  2430.                         (showHidden || p.Published)
  2431.                         orderby csp.CrossSellProductId
  2432.                         select csp;
  2433.             var crossSellProducts = query.ToList();
  2434.  
  2435.             return crossSellProducts;
  2436.         }
  2437.  
  2438.         /// <summary>
  2439.         /// Gets a cross-sell product
  2440.         /// </summary>
  2441.         /// <param name="crossSellProductId">Cross-sell product identifer</param>
  2442.         /// <returns>Cross-sell product</returns>
  2443.         public CrossSellProduct GetCrossSellProductById(int crossSellProductId)
  2444.         {
  2445.             if (crossSellProductId == 0)
  2446.                 return null;
  2447.  
  2448.  
  2449.             var query = from csp in _context.CrossSellProducts
  2450.                         where csp.CrossSellProductId == crossSellProductId
  2451.                         select csp;
  2452.             var crossSellProduct = query.SingleOrDefault();
  2453.             return crossSellProduct;
  2454.         }
  2455.  
  2456.         /// <summary>
  2457.         /// Inserts a cross-sell product
  2458.         /// </summary>
  2459.         /// <param name="crossSellProduct">Cross-sell product</param>
  2460.         public void InsertCrossSellProduct(CrossSellProduct crossSellProduct)
  2461.         {
  2462.             if (crossSellProduct == null)
  2463.                 throw new ArgumentNullException("crossSellProduct");
  2464.  
  2465.  
  2466.  
  2467.             _context.CrossSellProducts.AddObject(crossSellProduct);
  2468.             _context.SaveChanges();
  2469.         }
  2470.  
  2471.         /// <summary>
  2472.         /// Updates a cross-sell product
  2473.         /// </summary>
  2474.         /// <param name="crossSellProduct">Cross-sell product</param>
  2475.         public void UpdateCrossSellProduct(CrossSellProduct crossSellProduct)
  2476.         {
  2477.             if (crossSellProduct == null)
  2478.                 throw new ArgumentNullException("crossSellProduct");
  2479.  
  2480.  
  2481.             if (!_context.IsAttached(crossSellProduct))
  2482.                 _context.CrossSellProducts.Attach(crossSellProduct);
  2483.  
  2484.             _context.SaveChanges();
  2485.         }
  2486.  
  2487.         #endregion
  2488.  
  2489.         #region Pricelists
  2490.  
  2491.         /// <summary>
  2492.         /// Gets all product variants directly assigned to a pricelist
  2493.         /// </summary>
  2494.         /// <param name="pricelistId">Pricelist identifier</param>
  2495.         /// <returns>Product variants</returns>
  2496.         public List<ProductVariant> GetProductVariantsByPricelistId(int pricelistId)
  2497.         {
  2498.  
  2499.             var query = from pv in _context.ProductVariants
  2500.                         join pvpl in _context.ProductVariantPricelists on pv.ProductVariantId equals pvpl.ProductVariantId
  2501.                         where pvpl.PricelistId == pricelistId
  2502.                         select pv;
  2503.             var productVariants = query.ToList();
  2504.  
  2505.             return productVariants;
  2506.         }
  2507.  
  2508.         /// <summary>
  2509.         /// Deletes a pricelist
  2510.         /// </summary>
  2511.         /// <param name="pricelistId">The PricelistId of the item to be deleted</param>
  2512.         public void DeletePricelist(int pricelistId)
  2513.         {
  2514.             var pricelist = GetPricelistById(pricelistId);
  2515.             if (pricelist == null)
  2516.                 return;
  2517.  
  2518.  
  2519.             if (!_context.IsAttached(pricelist))
  2520.                 _context.Pricelists.Attach(pricelist);
  2521.             _context.DeleteObject(pricelist);
  2522.             _context.SaveChanges();
  2523.         }
  2524.  
  2525.         /// <summary>
  2526.         /// Gets a collection of all available pricelists
  2527.         /// </summary>
  2528.         /// <returns>Collection of pricelists</returns>
  2529.         public List<Pricelist> GetAllPricelists()
  2530.         {
  2531.  
  2532.             var query = from pl in _context.Pricelists
  2533.                         orderby pl.PricelistId
  2534.                         select pl;
  2535.             var pricelists = query.ToList();
  2536.  
  2537.             return pricelists;
  2538.         }
  2539.  
  2540.         /// <summary>
  2541.         /// Gets a pricelist
  2542.         /// </summary>
  2543.         /// <param name="pricelistId">Pricelist identifier</param>
  2544.         /// <returns>Pricelist</returns>
  2545.         public Pricelist GetPricelistById(int pricelistId)
  2546.         {
  2547.             if (pricelistId == 0)
  2548.                 return null;
  2549.  
  2550.  
  2551.             var query = from pl in _context.Pricelists
  2552.                         where pl.PricelistId == pricelistId
  2553.                         select pl;
  2554.             var pricelist = query.SingleOrDefault();
  2555.  
  2556.             return pricelist;
  2557.         }
  2558.  
  2559.         /// <summary>
  2560.         /// Gets a pricelist
  2561.         /// </summary>
  2562.         /// <param name="pricelistGuid">Pricelist GUId</param>
  2563.         /// <returns>Pricelist</returns>
  2564.         public Pricelist GetPricelistByGuid(string pricelistGuid)
  2565.         {
  2566.  
  2567.             var query = from pl in _context.Pricelists
  2568.                         where pl.PricelistGuid == pricelistGuid
  2569.                         select pl;
  2570.             var pricelist = query.FirstOrDefault();
  2571.  
  2572.             return pricelist;
  2573.         }
  2574.  
  2575.         /// <summary>
  2576.         /// Inserts a Pricelist
  2577.         /// </summary>
  2578.         /// <param name="pricelist">Pricelist</param>
  2579.         public void InsertPricelist(Pricelist pricelist)
  2580.         {
  2581.             if (pricelist == null)
  2582.                 throw new ArgumentNullException("pricelist");
  2583.  
  2584.             pricelist.DisplayName = CommonHelper.EnsureNotNull(pricelist.DisplayName);
  2585.             pricelist.DisplayName = CommonHelper.EnsureMaximumLength(pricelist.DisplayName, 100);
  2586.             pricelist.ShortName = CommonHelper.EnsureNotNull(pricelist.ShortName);
  2587.             pricelist.ShortName = CommonHelper.EnsureMaximumLength(pricelist.ShortName, 20);
  2588.             pricelist.PricelistGuid = CommonHelper.EnsureNotNull(pricelist.PricelistGuid);
  2589.             pricelist.PricelistGuid = CommonHelper.EnsureMaximumLength(pricelist.PricelistGuid, 40);
  2590.             pricelist.FormatLocalization = CommonHelper.EnsureNotNull(pricelist.FormatLocalization);
  2591.             pricelist.FormatLocalization = CommonHelper.EnsureMaximumLength(pricelist.FormatLocalization, 5);
  2592.             pricelist.Description = CommonHelper.EnsureNotNull(pricelist.Description);
  2593.             pricelist.Description = CommonHelper.EnsureMaximumLength(pricelist.Description, 500);
  2594.             pricelist.AdminNotes = CommonHelper.EnsureNotNull(pricelist.AdminNotes);
  2595.             pricelist.AdminNotes = CommonHelper.EnsureMaximumLength(pricelist.AdminNotes, 500);
  2596.             pricelist.Header = CommonHelper.EnsureNotNull(pricelist.Header);
  2597.             pricelist.Header = CommonHelper.EnsureMaximumLength(pricelist.Header, 500);
  2598.             pricelist.Body = CommonHelper.EnsureNotNull(pricelist.Body);
  2599.             pricelist.Body = CommonHelper.EnsureMaximumLength(pricelist.Body, 500);
  2600.             pricelist.Footer = CommonHelper.EnsureNotNull(pricelist.Footer);
  2601.             pricelist.Footer = CommonHelper.EnsureMaximumLength(pricelist.Footer, 500);
  2602.  
  2603.  
  2604.  
  2605.             _context.Pricelists.AddObject(pricelist);
  2606.             _context.SaveChanges();
  2607.         }
  2608.  
  2609.         /// <summary>
  2610.         /// Updates the Pricelist
  2611.         /// </summary>
  2612.         /// <param name="pricelist">Pricelist</param>
  2613.         public void UpdatePricelist(Pricelist pricelist)
  2614.         {
  2615.             if (pricelist == null)
  2616.                 throw new ArgumentNullException("pricelist");
  2617.  
  2618.             pricelist.DisplayName = CommonHelper.EnsureNotNull(pricelist.DisplayName);
  2619.             pricelist.DisplayName = CommonHelper.EnsureMaximumLength(pricelist.DisplayName, 100);
  2620.             pricelist.ShortName = CommonHelper.EnsureNotNull(pricelist.ShortName);
  2621.             pricelist.ShortName = CommonHelper.EnsureMaximumLength(pricelist.ShortName, 20);
  2622.             pricelist.PricelistGuid = CommonHelper.EnsureNotNull(pricelist.PricelistGuid);
  2623.             pricelist.PricelistGuid = CommonHelper.EnsureMaximumLength(pricelist.PricelistGuid, 40);
  2624.             pricelist.FormatLocalization = CommonHelper.EnsureNotNull(pricelist.FormatLocalization);
  2625.             pricelist.FormatLocalization = CommonHelper.EnsureMaximumLength(pricelist.FormatLocalization, 5);
  2626.             pricelist.Description = CommonHelper.EnsureNotNull(pricelist.Description);
  2627.             pricelist.Description = CommonHelper.EnsureMaximumLength(pricelist.Description, 500);
  2628.             pricelist.AdminNotes = CommonHelper.EnsureNotNull(pricelist.AdminNotes);
  2629.             pricelist.AdminNotes = CommonHelper.EnsureMaximumLength(pricelist.AdminNotes, 500);
  2630.             pricelist.Header = CommonHelper.EnsureNotNull(pricelist.Header);
  2631.             pricelist.Header = CommonHelper.EnsureMaximumLength(pricelist.Header, 500);
  2632.             pricelist.Body = CommonHelper.EnsureNotNull(pricelist.Body);
  2633.             pricelist.Body = CommonHelper.EnsureMaximumLength(pricelist.Body, 500);
  2634.             pricelist.Footer = CommonHelper.EnsureNotNull(pricelist.Footer);
  2635.             pricelist.Footer = CommonHelper.EnsureMaximumLength(pricelist.Footer, 500);
  2636.  
  2637.  
  2638.             if (!_context.IsAttached(pricelist))
  2639.                 _context.Pricelists.Attach(pricelist);
  2640.  
  2641.             _context.SaveChanges();
  2642.         }
  2643.  
  2644.         /// <summary>
  2645.         /// Deletes a ProductVariantPricelist
  2646.         /// </summary>
  2647.         /// <param name="productVariantPricelistId">ProductVariantPricelist identifier</param>
  2648.         public void DeleteProductVariantPricelist(int productVariantPricelistId)
  2649.         {
  2650.             if (productVariantPricelistId == 0)
  2651.                 return;
  2652.  
  2653.             var productVariantPricelist = GetProductVariantPricelistById(productVariantPricelistId);
  2654.             if (productVariantPricelist == null)
  2655.                 return;
  2656.  
  2657.  
  2658.             if (!_context.IsAttached(productVariantPricelist))
  2659.                 _context.ProductVariantPricelists.Attach(productVariantPricelist);
  2660.             _context.DeleteObject(productVariantPricelist);
  2661.             _context.SaveChanges();
  2662.         }
  2663.  
  2664.         /// <summary>
  2665.         /// Gets a ProductVariantPricelist
  2666.         /// </summary>
  2667.         /// <param name="productVariantPricelistId">ProductVariantPricelist identifier</param>
  2668.         /// <returns>ProductVariantPricelist</returns>
  2669.         public ProductVariantPricelist GetProductVariantPricelistById(int productVariantPricelistId)
  2670.         {
  2671.             if (productVariantPricelistId == 0)
  2672.                 return null;
  2673.  
  2674.  
  2675.             var query = from pvpl in _context.ProductVariantPricelists
  2676.                         where pvpl.ProductVariantPricelistId == productVariantPricelistId
  2677.                         select pvpl;
  2678.             var productVariantPricelist = query.SingleOrDefault();
  2679.             return productVariantPricelist;
  2680.         }
  2681.  
  2682.         /// <summary>
  2683.         /// Gets ProductVariantPricelist
  2684.         /// </summary>
  2685.         /// <param name="productVariantId">ProductVariant identifier</param>
  2686.         /// <param name="pricelistId">Pricelist identifier</param>
  2687.         /// <returns>ProductVariantPricelist</returns>
  2688.         public ProductVariantPricelist GetProductVariantPricelist(int productVariantId, int pricelistId)
  2689.         {
  2690.  
  2691.             var query = from pvpl in _context.ProductVariantPricelists
  2692.                         where pvpl.ProductVariantId == productVariantId &&
  2693.                         pvpl.PricelistId == pricelistId
  2694.                         select pvpl;
  2695.             var productVariantPricelist = query.FirstOrDefault();
  2696.             return productVariantPricelist;
  2697.         }
  2698.  
  2699.         /// <summary>
  2700.         /// Inserts a ProductVariantPricelist
  2701.         /// </summary>
  2702.         /// <param name="productVariantPricelist">The product variant pricelist</param>
  2703.         public void InsertProductVariantPricelist(ProductVariantPricelist productVariantPricelist)
  2704.         {
  2705.             if (productVariantPricelist == null)
  2706.                 throw new ArgumentNullException("productVariantPricelist");
  2707.  
  2708.  
  2709.  
  2710.             _context.ProductVariantPricelists.AddObject(productVariantPricelist);
  2711.             _context.SaveChanges();
  2712.         }
  2713.  
  2714.         /// <summary>
  2715.         /// Updates the ProductVariantPricelist
  2716.         /// </summary>
  2717.         /// <param name="productVariantPricelist">The product variant pricelist</param>
  2718.         public void UpdateProductVariantPricelist(ProductVariantPricelist productVariantPricelist)
  2719.         {
  2720.             if (productVariantPricelist == null)
  2721.                 throw new ArgumentNullException("productVariantPricelist");
  2722.  
  2723.  
  2724.             if (!_context.IsAttached(productVariantPricelist))
  2725.                 _context.ProductVariantPricelists.Attach(productVariantPricelist);
  2726.  
  2727.             _context.SaveChanges();
  2728.         }
  2729.  
  2730.         #endregion
  2731.  
  2732.         #region Tier prices
  2733.  
  2734.         /// <summary>
  2735.         /// Gets a tier price
  2736.         /// </summary>
  2737.         /// <param name="tierPriceId">Tier price identifier</param>
  2738.         /// <returns>Tier price</returns>
  2739.         public TierPrice GetTierPriceById(int tierPriceId)
  2740.         {
  2741.             if (tierPriceId == 0)
  2742.                 return null;
  2743.  
  2744.  
  2745.             var query = from tp in _context.TierPrices
  2746.                         where tp.TierPriceId == tierPriceId
  2747.                         select tp;
  2748.             var tierPrice = query.SingleOrDefault();
  2749.             return tierPrice;
  2750.         }
  2751.  
  2752.         /// <summary>
  2753.         /// Gets tier prices by product variant identifier
  2754.         /// </summary>
  2755.         /// <param name="productVariantId">Product variant identifier</param>
  2756.         /// <returns>Tier price collection</returns>
  2757.         public List<TierPrice> GetTierPricesByProductVariantId(int productVariantId)
  2758.         {
  2759.             if (productVariantId == 0)
  2760.                 return new List<TierPrice>();
  2761.  
  2762.             string key = string.Format(TIERPRICES_ALLBYPRODUCTVARIANTID_KEY, productVariantId);
  2763.             object obj2 = _cacheManager.Get(key);
  2764.             if (this.CacheEnabled && (obj2 != null))
  2765.             {
  2766.                 return (List<TierPrice>)obj2;
  2767.             }
  2768.  
  2769.  
  2770.             var query = from tp in _context.TierPrices
  2771.                         orderby tp.Quantity
  2772.                         where tp.ProductVariantId == productVariantId
  2773.                         select tp;
  2774.             var tierPrices = query.ToList();
  2775.  
  2776.             if (this.CacheEnabled)
  2777.             {
  2778.                 _cacheManager.Add(key, tierPrices);
  2779.             }
  2780.             return tierPrices;
  2781.         }
  2782.  
  2783.         /// <summary>
  2784.         /// Deletes a tier price
  2785.         /// </summary>
  2786.         /// <param name="tierPriceId">Tier price identifier</param>
  2787.         public void DeleteTierPrice(int tierPriceId)
  2788.         {
  2789.             var tierPrice = GetTierPriceById(tierPriceId);
  2790.             if (tierPrice == null)
  2791.                 return;
  2792.  
  2793.  
  2794.             if (!_context.IsAttached(tierPrice))
  2795.                 _context.TierPrices.Attach(tierPrice);
  2796.             _context.DeleteObject(tierPrice);
  2797.             _context.SaveChanges();
  2798.  
  2799.             if (this.CacheEnabled)
  2800.             {
  2801.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  2802.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  2803.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  2804.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  2805.             }
  2806.         }
  2807.  
  2808.         /// <summary>
  2809.         /// Inserts a tier price
  2810.         /// </summary>
  2811.         /// <param name="tierPrice">Tier price</param>
  2812.         public void InsertTierPrice(TierPrice tierPrice)
  2813.         {
  2814.             if (tierPrice == null)
  2815.                 throw new ArgumentNullException("tierPrice");
  2816.  
  2817.  
  2818.  
  2819.             _context.TierPrices.AddObject(tierPrice);
  2820.             _context.SaveChanges();
  2821.  
  2822.             if (this.CacheEnabled)
  2823.             {
  2824.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  2825.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  2826.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  2827.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  2828.             }
  2829.         }
  2830.  
  2831.         /// <summary>
  2832.         /// Updates the tier price
  2833.         /// </summary>
  2834.         /// <param name="tierPrice">Tier price</param>
  2835.         public void UpdateTierPrice(TierPrice tierPrice)
  2836.         {
  2837.             if (tierPrice == null)
  2838.                 throw new ArgumentNullException("tierPrice");
  2839.  
  2840.  
  2841.             if (!_context.IsAttached(tierPrice))
  2842.                 _context.TierPrices.Attach(tierPrice);
  2843.  
  2844.             _context.SaveChanges();
  2845.  
  2846.             if (this.CacheEnabled)
  2847.             {
  2848.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  2849.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  2850.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  2851.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  2852.             }
  2853.         }
  2854.  
  2855.         #endregion
  2856.  
  2857.         #region Product prices by customer role
  2858.  
  2859.         /// <summary>
  2860.         /// Deletes a product price by customer role by identifier
  2861.         /// </summary>
  2862.         /// <param name="customerRoleProductPriceId">The identifier</param>
  2863.         public void DeleteCustomerRoleProductPrice(int customerRoleProductPriceId)
  2864.         {
  2865.             var customerRoleProductPrice = GetCustomerRoleProductPriceById(customerRoleProductPriceId);
  2866.             if (customerRoleProductPrice == null)
  2867.                 return;
  2868.  
  2869.  
  2870.             if (!_context.IsAttached(customerRoleProductPrice))
  2871.                 _context.CustomerRoleProductPrices.Attach(customerRoleProductPrice);
  2872.             _context.DeleteObject(customerRoleProductPrice);
  2873.             _context.SaveChanges();
  2874.  
  2875.             if (this.CacheEnabled)
  2876.             {
  2877.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  2878.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  2879.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  2880.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  2881.             }
  2882.         }
  2883.  
  2884.         /// <summary>
  2885.         /// Gets a product price by customer role by identifier
  2886.         /// </summary>
  2887.         /// <param name="customerRoleProductPriceId">The identifier</param>
  2888.         /// <returns>Product price by customer role by identifier </returns>
  2889.         public CustomerRoleProductPrice GetCustomerRoleProductPriceById(int customerRoleProductPriceId)
  2890.         {
  2891.             if (customerRoleProductPriceId == 0)
  2892.                 return null;
  2893.  
  2894.  
  2895.             var query = from crpp in _context.CustomerRoleProductPrices
  2896.                         where crpp.CustomerRoleProductPriceId == customerRoleProductPriceId
  2897.                         select crpp;
  2898.             var customerRoleProductPrice = query.SingleOrDefault();
  2899.             return customerRoleProductPrice;
  2900.         }
  2901.  
  2902.         /// <summary>
  2903.         /// Gets a collection of product prices by customer role
  2904.         /// </summary>
  2905.         /// <param name="productVariantId">Product variant identifier</param>
  2906.         /// <returns>A collection of product prices by customer role</returns>
  2907.         public List<CustomerRoleProductPrice> GetAllCustomerRoleProductPrices(int productVariantId)
  2908.         {
  2909.             string key = string.Format(CUSTOMERROLEPRICES_ALL_KEY, productVariantId);
  2910.             object obj2 = _cacheManager.Get(key);
  2911.             if (this.CacheEnabled && (obj2 != null))
  2912.             {
  2913.                 return (List<CustomerRoleProductPrice>)obj2;
  2914.             }
  2915.  
  2916.             var query = from crpp in _context.CustomerRoleProductPrices
  2917.                         where crpp.ProductVariantId == productVariantId
  2918.                         select crpp;
  2919.             var collection = query.ToList();
  2920.  
  2921.             if (this.CacheEnabled)
  2922.             {
  2923.                 _cacheManager.Add(key, collection);
  2924.             }
  2925.             return collection;
  2926.         }
  2927.  
  2928.         /// <summary>
  2929.         /// Inserts a product price by customer role
  2930.         /// </summary>
  2931.         /// <param name="customerRoleProductPrice">A product price by customer role</param>
  2932.         public void InsertCustomerRoleProductPrice(CustomerRoleProductPrice customerRoleProductPrice)
  2933.         {
  2934.             if (customerRoleProductPrice == null)
  2935.                 throw new ArgumentNullException("customerRoleProductPrice");
  2936.  
  2937.  
  2938.  
  2939.             _context.CustomerRoleProductPrices.AddObject(customerRoleProductPrice);
  2940.             _context.SaveChanges();
  2941.  
  2942.             if (this.CacheEnabled)
  2943.             {
  2944.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  2945.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  2946.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  2947.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  2948.             }
  2949.         }
  2950.  
  2951.         /// <summary>
  2952.         /// Updates a product price by customer role
  2953.         /// </summary>
  2954.         /// <param name="customerRoleProductPrice">A product price by customer role</param>
  2955.         public void UpdateCustomerRoleProductPrice(CustomerRoleProductPrice customerRoleProductPrice)
  2956.         {
  2957.             if (customerRoleProductPrice == null)
  2958.                 throw new ArgumentNullException("customerRoleProductPrice");
  2959.  
  2960.  
  2961.             if (!_context.IsAttached(customerRoleProductPrice))
  2962.                 _context.CustomerRoleProductPrices.Attach(customerRoleProductPrice);
  2963.  
  2964.             _context.SaveChanges();
  2965.  
  2966.             if (this.CacheEnabled)
  2967.             {
  2968.                 _cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);
  2969.                 _cacheManager.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
  2970.                 _cacheManager.RemoveByPattern(TIERPRICES_PATTERN_KEY);
  2971.                 _cacheManager.RemoveByPattern(CUSTOMERROLEPRICES_PATTERN_KEY);
  2972.             }
  2973.         }
  2974.  
  2975.         #endregion
  2976.  
  2977.         #region Product tags
  2978.  
  2979.         /// <summary>
  2980.         /// Deletes a product tag
  2981.         /// </summary>
  2982.         /// <param name="productTagId">Product tag identifier</param>
  2983.         public void DeleteProductTag(int productTagId)
  2984.         {
  2985.             var productTag = GetProductTagById(productTagId);
  2986.             if (productTag == null)
  2987.                 return;
  2988.  
  2989.  
  2990.             if (!_context.IsAttached(productTag))
  2991.                 _context.ProductTags.Attach(productTag);
  2992.             _context.DeleteObject(productTag);
  2993.             _context.SaveChanges();
  2994.         }
  2995.  
  2996.         /// <summary>
  2997.         /// Gets a product tag
  2998.         /// </summary>
  2999.         /// <param name="productTagId">Product tag identifier</param>
  3000.         /// <returns>Product tag</returns>
  3001.         public ProductTag GetProductTagById(int productTagId)
  3002.         {
  3003.             if (productTagId == 0)
  3004.                 return null;
  3005.  
  3006.  
  3007.             var query = from pt in _context.ProductTags
  3008.                         where pt.ProductTagId == productTagId
  3009.                         select pt;
  3010.             var productTag = query.SingleOrDefault();
  3011.             return productTag;
  3012.         }
  3013.  
  3014.         /// <summary>
  3015.         /// Gets product tags by product identifier
  3016.         /// </summary>
  3017.         /// <param name="productId">Product identifier</param>
  3018.         /// <returns>Product tag collection</returns>
  3019.         public List<ProductTag> GetProductTagsByProductId(int productId)
  3020.         {
  3021.             if (productId == 0)
  3022.                 return new List<ProductTag>();
  3023.  
  3024.             var query = from pt in _context.ProductTags
  3025.                         from p in pt.NpProducts
  3026.                         where p.ProductId == productId
  3027.                         orderby pt.ProductCount descending
  3028.                         select pt;
  3029.  
  3030.             var productTags = query.ToList();
  3031.             return productTags;
  3032.         }
  3033.  
  3034.         /// <summary>
  3035.         /// Gets product tag by name
  3036.         /// </summary>
  3037.         /// <param name="name">Product tag name</param>
  3038.         /// <returns>Product tag</returns>
  3039.         public ProductTag GetProductTagByName(string name)
  3040.         {
  3041.             if (name == null)
  3042.                 name = string.Empty;
  3043.             name = name.Trim();
  3044.  
  3045.             var query = from pt in _context.ProductTags
  3046.                         where pt.Name == name
  3047.                         select pt;
  3048.  
  3049.             var productTag = query.FirstOrDefault();
  3050.             return productTag;
  3051.         }
  3052.  
  3053.         /// <summary>
  3054.         /// Gets all product tags
  3055.         /// </summary>
  3056.         /// <returns>Product tag collection</returns>
  3057.         public List<ProductTag> GetAllProductTags()
  3058.         {
  3059.             var query = from pt in _context.ProductTags
  3060.                         orderby pt.ProductCount descending
  3061.                         select pt;
  3062.  
  3063.             var productTags = query.ToList();
  3064.             return productTags;
  3065.         }
  3066.  
  3067.         /// <summary>
  3068.         /// Inserts a product tag
  3069.         /// </summary>
  3070.         /// <param name="productTag">Product tag</param>
  3071.         public void InsertProductTag(ProductTag productTag)
  3072.         {
  3073.             if (productTag == null)
  3074.                 throw new ArgumentNullException("productTag");
  3075.  
  3076.             productTag.Name = CommonHelper.EnsureNotNull(productTag.Name);
  3077.             productTag.Name = productTag.Name.Trim();
  3078.             productTag.Name = CommonHelper.EnsureMaximumLength(productTag.Name, 100);
  3079.  
  3080.  
  3081.  
  3082.             _context.ProductTags.AddObject(productTag);
  3083.             _context.SaveChanges();
  3084.         }
  3085.  
  3086.         /// <summary>
  3087.         /// Updates a product tag
  3088.         /// </summary>
  3089.         /// <param name="productTag">Product tag</param>
  3090.         public void UpdateProductTag(ProductTag productTag)
  3091.         {
  3092.             if (productTag == null)
  3093.                 throw new ArgumentNullException("productTag");
  3094.  
  3095.             productTag.Name = CommonHelper.EnsureNotNull(productTag.Name);
  3096.             productTag.Name = productTag.Name.Trim();
  3097.             productTag.Name = CommonHelper.EnsureMaximumLength(productTag.Name, 100);
  3098.  
  3099.  
  3100.  
  3101.             if (!_context.IsAttached(productTag))
  3102.                 _context.ProductTags.Attach(productTag);
  3103.  
  3104.             _context.SaveChanges();
  3105.         }
  3106.  
  3107.         /// <summary>
  3108.         /// Adds a discount tag mapping
  3109.         /// </summary>
  3110.         /// <param name="productId">Product identifier</param>
  3111.         /// <param name="productTagId">Product tag identifier</param>
  3112.         public void AddProductTagMapping(int productId, int productTagId)
  3113.         {
  3114.             Product product = GetProductById(productId);
  3115.             if (product == null)
  3116.                 return;
  3117.  
  3118.             ProductTag productTag = GetProductTagById(productTagId);
  3119.             if (productTag == null)
  3120.                 return;
  3121.  
  3122.             if (!_context.IsAttached(product))
  3123.                 _context.Products.Attach(product);
  3124.             if (!_context.IsAttached(productTag))
  3125.                 _context.ProductTags.Attach(productTag);
  3126.  
  3127.             //ensure that navigation property is loaded
  3128.             if (product.NpProductTags == null)
  3129.                 _context.LoadProperty(product, p => p.NpProductTags);
  3130.  
  3131.             product.NpProductTags.Add(productTag);
  3132.             _context.SaveChanges();
  3133.  
  3134.             //new totals                        
  3135.             if (productTag.NpProducts == null) //ensure that navigation property is loaded
  3136.                 _context.LoadProperty(productTag, pt => pt.NpProducts);
  3137.             int newTotal = productTag.NpProducts.Count();
  3138.             if (newTotal > 0)
  3139.             {
  3140.                 productTag.ProductCount = newTotal;
  3141.                 UpdateProductTag(productTag);
  3142.             }
  3143.             else
  3144.             {
  3145.                 DeleteProductTag(productTagId);
  3146.             }
  3147.         }
  3148.  
  3149.         /// <summary>
  3150.         /// Checking whether the product tag mapping exists
  3151.         /// </summary>
  3152.         /// <param name="productId">The product identifier</param>
  3153.         /// <param name="productTagId">The product tag identifier</param>
  3154.         /// <returns>True if mapping exist, otherwise false</returns>
  3155.         public bool DoesProductTagMappingExist(int productId, int productTagId)
  3156.         {
  3157.             ProductTag productTag = GetProductTagById(productTagId);
  3158.             if (productTag == null)
  3159.                 return false;
  3160.  
  3161.             //ensure that navigation property is loaded
  3162.             if (productTag.NpProducts == null)
  3163.                 _context.LoadProperty(productTag, pt => pt.NpProducts);
  3164.  
  3165.             bool result = productTag.NpProducts.ToList().Find(p => p.ProductId == productId) != null;
  3166.             return result;
  3167.         }
  3168.  
  3169.         /// <summary>
  3170.         /// Removes a discount tag mapping
  3171.         /// </summary>
  3172.         /// <param name="productId">Product identifier</param>
  3173.         /// <param name="productTagId">Product tag identifier</param>
  3174.         public void RemoveProductTagMapping(int productId, int productTagId)
  3175.         {
  3176.             Product product = GetProductById(productId);
  3177.             if (product == null)
  3178.                 return;
  3179.  
  3180.             ProductTag productTag = GetProductTagById(productTagId);
  3181.             if (productTag == null)
  3182.                 return;
  3183.  
  3184.             if (!_context.IsAttached(product))
  3185.                 _context.Products.Attach(product);
  3186.             if (!_context.IsAttached(productTag))
  3187.                 _context.ProductTags.Attach(productTag);
  3188.  
  3189.             //ensure that navigation property is loaded
  3190.             if (product.NpProductTags == null)
  3191.                 _context.LoadProperty(product, p => p.NpProductTags);
  3192.  
  3193.             product.NpProductTags.Remove(productTag);
  3194.             _context.SaveChanges();
  3195.  
  3196.             //new totals                        
  3197.             if (productTag.NpProducts == null) //ensure that navigation property is loaded
  3198.                 _context.LoadProperty(productTag, pt => pt.NpProducts);
  3199.             int newTotal = productTag.NpProducts.Count();
  3200.             if (newTotal > 0)
  3201.             {
  3202.                 productTag.ProductCount = newTotal;
  3203.                 UpdateProductTag(productTag);
  3204.             }
  3205.             else
  3206.             {
  3207.                 DeleteProductTag(productTagId);
  3208.             }
  3209.         }
  3210.  
  3211.         #endregion
  3212.  
  3213.         #endregion
  3214.  
  3215.         #region Properties
  3216.         /// <summary>
  3217.         /// Gets a value indicating whether cache is enabled
  3218.         /// </summary>
  3219.         public bool CacheEnabled
  3220.         {
  3221.             get
  3222.             {
  3223.                 return IoC.Resolve<ISettingManager>().GetSettingValueBoolean("Cache.ProductManager.CacheEnabled");
  3224.             }
  3225.         }
  3226.  
  3227.         /// <summary>
  3228.         /// Gets or sets a value indicating whether "Recently viewed products" feature is enabled
  3229.         /// </summary>
  3230.         public bool RecentlyViewedProductsEnabled
  3231.         {
  3232.             get
  3233.             {
  3234.                 bool recentlyViewedProductsEnabled = IoC.Resolve<ISettingManager>().GetSettingValueBoolean("Display.RecentlyViewedProductsEnabled");
  3235.                 return recentlyViewedProductsEnabled;
  3236.             }
  3237.             set
  3238.             {
  3239.                 IoC.Resolve<ISettingManager>().SetParam("Display.RecentlyViewedProductsEnabled", value.ToString());
  3240.             }
  3241.         }
  3242.  
  3243.         /// <summary>
  3244.         /// Gets or sets a number of "Recently viewed products"
  3245.         /// </summary>
  3246.         public int RecentlyViewedProductsNumber
  3247.         {
  3248.             get
  3249.             {
  3250.                 int recentlyViewedProductsNumber = IoC.Resolve<ISettingManager>().GetSettingValueInteger("Display.RecentlyViewedProductsNumber");
  3251.                 return recentlyViewedProductsNumber;
  3252.             }
  3253.             set
  3254.             {
  3255.                 IoC.Resolve<ISettingManager>().SetParam("Display.RecentlyViewedProductsNumber", value.ToString());
  3256.             }
  3257.         }
  3258.  
  3259.         /// <summary>
  3260.         /// Gets or sets a value indicating whether "Recently added products" feature is enabled
  3261.         /// </summary>
  3262.         public bool RecentlyAddedProductsEnabled
  3263.         {
  3264.             get
  3265.             {
  3266.                 bool recentlyAddedProductsEnabled = IoC.Resolve<ISettingManager>().GetSettingValueBoolean("Display.RecentlyAddedProductsEnabled");
  3267.                 return recentlyAddedProductsEnabled;
  3268.             }
  3269.             set
  3270.             {
  3271.                 IoC.Resolve<ISettingManager>().SetParam("Display.RecentlyAddedProductsEnabled", value.ToString());
  3272.             }
  3273.         }
  3274.  
  3275.         /// <summary>
  3276.         /// Gets or sets a number of "Recently added products"
  3277.         /// </summary>
  3278.         public int RecentlyAddedProductsNumber
  3279.         {
  3280.             get
  3281.             {
  3282.                 int recentlyAddedProductsNumber = IoC.Resolve<ISettingManager>().GetSettingValueInteger("Display.RecentlyAddedProductsNumber");
  3283.                 return recentlyAddedProductsNumber;
  3284.             }
  3285.             set
  3286.             {
  3287.                 IoC.Resolve<ISettingManager>().SetParam("Display.RecentlyAddedProductsNumber", value.ToString());
  3288.             }
  3289.         }
  3290.  
  3291.         /// <summary>
  3292.         /// Gets or sets a number of "Cross-sells"
  3293.         /// </summary>
  3294.         public int CrossSellsNumber
  3295.         {
  3296.             get
  3297.             {
  3298.                 int result = IoC.Resolve<ISettingManager>().GetSettingValueInteger("Display.CrossSellsNumber", 2);
  3299.                 return result;
  3300.             }
  3301.             set
  3302.             {
  3303.                 IoC.Resolve<ISettingManager>().SetParam("Display.CrossSellsNumber", value.ToString());
  3304.             }
  3305.         }
  3306.  
  3307.         /// <summary>
  3308.         /// Gets or sets a number of products per page on search products page
  3309.         /// </summary>
  3310.         public int SearchPageProductsPerPage
  3311.         {
  3312.             get
  3313.             {
  3314.                 int result = IoC.Resolve<ISettingManager>().GetSettingValueInteger("SearchPage.ProductsPerPage", 10);
  3315.                 return result;
  3316.             }
  3317.             set
  3318.             {
  3319.                 IoC.Resolve<ISettingManager>().SetParam("SearchPage.ProductsPerPage", value.ToString());
  3320.             }
  3321.         }
  3322.  
  3323.         /// <summary>
  3324.         /// Gets or sets a value indicating whether to displays a button from AddThis.com on your product pages
  3325.         /// </summary>
  3326.         public bool ShowShareButton
  3327.         {
  3328.             get
  3329.             {
  3330.                 bool showShareButton = IoC.Resolve<ISettingManager>().GetSettingValueBoolean("Products.AddThisSharing.Enabled");
  3331.                 return showShareButton;
  3332.             }
  3333.             set
  3334.             {
  3335.                 IoC.Resolve<ISettingManager>().SetParam("Products.AddThisSharing.Enabled", value.ToString());
  3336.             }
  3337.         }
  3338.  
  3339.         /// <summary>
  3340.         /// Gets or sets a value indicating whether "Compare products" feature is enabled
  3341.         /// </summary>
  3342.         public bool CompareProductsEnabled
  3343.         {
  3344.             get
  3345.             {
  3346.                 bool compareProductsEnabled = IoC.Resolve<ISettingManager>().GetSettingValueBoolean("Common.EnableCompareProducts");
  3347.                 return compareProductsEnabled;
  3348.             }
  3349.             set
  3350.             {
  3351.                 IoC.Resolve<ISettingManager>().SetParam("Common.EnableCompareProducts", value.ToString());
  3352.             }
  3353.         }
  3354.  
  3355.         /// <summary>
  3356.         /// Gets or sets "List of products purchased by other customers who purchased the above" option is enable
  3357.         /// </summary>
  3358.         public bool ProductsAlsoPurchasedEnabled
  3359.         {
  3360.             get
  3361.             {
  3362.                 bool productsAlsoPurchased = IoC.Resolve<ISettingManager>().GetSettingValueBoolean("Display.ListOfProductsAlsoPurchasedEnabled");
  3363.                 return productsAlsoPurchased;
  3364.             }
  3365.             set
  3366.             {
  3367.                 IoC.Resolve<ISettingManager>().SetParam("Display.ListOfProductsAlsoPurchasedEnabled", value.ToString());
  3368.             }
  3369.         }
  3370.  
  3371.         /// <summary>
  3372.         /// Gets or sets a number of products also purchased by other customers to display
  3373.         /// </summary>
  3374.         public int ProductsAlsoPurchasedNumber
  3375.         {
  3376.             get
  3377.             {
  3378.                 int productsAlsoPurchasedNumber = IoC.Resolve<ISettingManager>().GetSettingValueInteger("Display.ListOfProductsAlsoPurchasedNumberToDisplay");
  3379.                 return productsAlsoPurchasedNumber;
  3380.             }
  3381.             set
  3382.             {
  3383.                 IoC.Resolve<ISettingManager>().SetParam("Display.ListOfProductsAlsoPurchasedNumberToDisplay", value.ToString());
  3384.             }
  3385.         }
  3386.  
  3387.         /// <summary>
  3388.         /// Gets or sets a value indicating whether to notify about new product reviews
  3389.         /// </summary>
  3390.         public bool NotifyAboutNewProductReviews
  3391.         {
  3392.             get
  3393.             {
  3394.                 return IoC.Resolve<ISettingManager>().GetSettingValueBoolean("Product.NotifyAboutNewProductReviews");
  3395.             }
  3396.             set
  3397.             {
  3398.                 IoC.Resolve<ISettingManager>().SetParam("Product.NotifyAboutNewProductReviews", value.ToString());
  3399.             }
  3400.         }
  3401.         #endregion
  3402.     }
  3403. }