Пример #1
0
        public void UpdateSavesExistingProductOption()
        {
            var name        = "Test Name";
            var description = "Test Description";

            var opt1 = new Mock <IProductOption>(MockBehavior.Strict);
            var opt2 = new Mock <IProductOption>(MockBehavior.Strict);

            opt2.SetupGet(p => p.Id).Returns(_id2);
            opt2.SetupGet(p => p.ProductId).Returns(_prodId);
            opt2.SetupGet(p => p.Name).Returns(name);
            opt2.SetupGet(p => p.Description).Returns(description);

            IProductOption prod3 = null;

            _repo.Setup(r => r.Get(_id1)).Returns(opt1.Object);
            _repo.Setup(r => r.Save(It.IsAny <IProductOption>(), false)).Verifiable();
            _repo.Setup(r => r.Save(It.IsAny <IProductOption>(), true)).Callback <IProductOption, bool>((p, _) => prod3 = p);

            _service.Update(_id1, opt2.Object);

            _repo.Verify(r => r.Get(_id1), Times.Once);
            _repo.Verify(r => r.Save(It.IsAny <IProductOption>(), false), Times.Never);
            _repo.Verify(r => r.Save(It.IsAny <IProductOption>(), true), Times.Once);

            prod3.Id.Should().Be(_id1);
            prod3.ProductId.Should().Be(_prodId);
            prod3.Name.Should().Be(name);
            prod3.Description.Should().Be(description);
        }
Пример #2
0
        public void CreateSavesNewProductOption()
        {
            var name        = "Test Name";
            var description = "Test Description";

            var opt1 = new Mock <IProductOption>(MockBehavior.Strict);

            opt1.SetupGet(p => p.Id).Returns(_id1);
            opt1.SetupGet(p => p.ProductId).Returns(_id2); //  Yes not _prodId
            opt1.SetupGet(p => p.Name).Returns(name);
            opt1.SetupGet(p => p.Description).Returns(description);

            IProductOption opt2 = null;

            _repo.Setup(r => r.Get(_id1)).Returns <IProductOption>(null);
            _repo.Setup(r => r.Save(It.IsAny <IProductOption>(), true)).Verifiable();
            _repo.Setup(r => r.Save(It.IsAny <IProductOption>(), false)).Callback <IProductOption, bool>((o, _) => opt2 = o);

            _service.Create(_prodId, opt1.Object);

            _repo.Verify(r => r.Get(_id1), Times.Once);
            _repo.Verify(r => r.Save(It.IsAny <IProductOption>(), true), Times.Never);
            _repo.Verify(r => r.Save(It.IsAny <IProductOption>(), false), Times.Once);

            opt2.Id.Should().Be(_id1);
            opt2.ProductId.Should().Be(_prodId);
            opt2.Name.Should().Be(name);
            opt2.Description.Should().Be(description);
        }
        /// <summary>
        /// Saves a single product option.
        /// </summary>
        /// <param name="option">
        /// The option to be saved
        /// </param>
        /// <param name="raiseEvents">
        /// Optional boolean indicating whether or not to raise events.
        /// </param>
        public void Save(IProductOption option, bool raiseEvents = true)
        {
            if (raiseEvents)
            {
                if (Saving.IsRaisedEventCancelled(new SaveEventArgs <IProductOption>(option), this))
                {
                    ((ProductOption)option).WasCancelled = true;
                    return;
                }
            }

            using (new WriteLock(Locker))
            {
                var uow = UowProvider.GetUnitOfWork();
                using (var repository = RepositoryFactory.CreateProductOptionRepository(uow))
                {
                    repository.AddOrUpdate(option);
                    uow.Commit();
                }
            }

            if (raiseEvents)
            {
                Saved.RaiseEvent(new SaveEventArgs <IProductOption>(option), this);
            }
        }
Пример #4
0
        /// <summary>
        /// create product option
        /// </summary>
        /// <param name="productId">product id</param>
        /// <param name="option">option</param>
        /// <returns></returns>
        public async Task CreateAsync(Guid productId, IProductOption option)
        {
            using (var conn = new SqlConnection(connString))
            {
                await conn.OpenAsync();

                var cmd = new SqlCommand("INSERT INTO productoption (Id,ProductId,Name,Description) " +
                                         "VALUES (@id,@productId,@name,@description)", conn);
                cmd.Parameters.AddWithValue("@id", option.Id);
                cmd.Parameters.AddWithValue("@productId", productId);
                cmd.Parameters.AddWithValue("@name", option.Name);
                if (string.IsNullOrWhiteSpace(option.Description))
                {
                    cmd.Parameters.AddWithValue("@description", DBNull.Value);
                }
                else
                {
                    cmd.Parameters.AddWithValue("@description", option.Description);
                }

                await cmd.ExecuteNonQueryAsync();

                conn.Close();
            }
        }
 /// <summary>
 /// Gets the number of occurrences that an option has been shared.
 /// </summary>
 /// <param name="option">
 /// The option.
 /// </param>
 /// <returns>
 /// The count of option shares.
 /// </returns>
 public int GetProductOptionShareCount(IProductOption option)
 {
     using (var repository = RepositoryFactory.CreateProductOptionRepository(UowProvider.GetUnitOfWork()))
     {
         return(repository.GetSharedProductOptionCount(option.Key));
     }
 }
        /// <summary>
        /// Deletes a product option
        /// </summary>
        /// <param name="option">
        /// The option to be deleted
        /// </param>
        /// <param name="raiseEvents">
        /// Optional boolean indicating whether or not to raise events.
        /// </param>
        /// <remarks>
        /// This performs a check to ensure the option is valid to be deleted
        /// </remarks>
        public void Delete(IProductOption option, bool raiseEvents = true)
        {
            if (!EnsureSafeOptionDelete(option))
            {
                MultiLogHelper.Warn <ProductOptionService>("A ProductOption delete attempt was aborted.  The option cannot be deleted due to it being shared with one or more products.");
                return;
            }

            if (raiseEvents)
            {
                if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs <IProductOption>(option), this))
                {
                    ((ProductOption)option).WasCancelled = true;
                    return;
                }
            }

            using (new WriteLock(Locker))
            {
                var uow = UowProvider.GetUnitOfWork();
                using (var repository = RepositoryFactory.CreateProductOptionRepository(uow))
                {
                    repository.Delete(option);
                    uow.Commit();
                }
            }

            if (raiseEvents)
            {
                Deleted.RaiseEvent(new DeleteEventArgs <IProductOption>(option), this);
            }
        }
 public ProductOption(IProductOption option)
 {
     Id          = option.Id;
     ProductId   = option.ProductId;
     Name        = option.Name;
     Description = option.Description;
 }
        public void Save(IProductOption option, bool exists)
        {
            var        idParam     = "@Id";
            var        prodIdParam = "@ProdId";
            var        nameParam   = "@Name";
            var        descrParam  = "@Descr";
            SqlCommand cmd;

            if (exists)
            {
                cmd = IdSqlCommand($"update productoption set name = {nameParam}, description = {descrParam} where id", option.Id);
            }
            else
            {
                var conn = Helpers.NewConnection();

                conn.Open();

                cmd = new SqlCommand($"insert into productoption (id, productid, name, description) values ({idParam}, {prodIdParam}, {nameParam}, {descrParam})", conn);

                cmd.Parameters.AddWithValue(idParam, option.Id);
                cmd.Parameters.AddWithValue(prodIdParam, option.ProductId);
            }

            cmd.Parameters.AddWithValue(nameParam, option.Name);
            cmd.Parameters.AddWithValue(descrParam, option.Description);

            cmd.ExecuteNonQuery();
        }
        /// <summary>
        /// The to product option display.
        /// </summary>
        /// <param name="productOption">
        /// The product option.
        /// </param>
        /// <param name="conversionType">
        /// The property editor conversion type.
        /// </param>
        /// <returns>
        /// The <see cref="ProductOptionDisplay"/>.
        /// </returns>
        internal static ProductOptionDisplay ToProductOptionDisplay(this IProductOption productOption, DetachedValuesConversionType conversionType = DetachedValuesConversionType.Db)
        {
            var display = AutoMapper.Mapper.Map <ProductOptionDisplay>(productOption);

            display.EnsureValueConversion(conversionType);
            display.Choices = display.Choices.OrderBy(x => x.SortOrder);
            return(display);
        }
Пример #10
0
 /// <summary>
 /// Populate a <paramref name="prodOp"/> from <paramref name="rdr"/>
 /// </summary>
 /// <param name="rdr"><see cref="SqlDataReader"/></param>
 /// <param name="prodOp"><see cref="IProductOption"/></param>
 public void PopulateProductOp(SqlDataReader rdr, IProductOption prodOp)
 {
     prodOp.IsNew       = false;
     prodOp.Id          = Guid.Parse(rdr["Id"].ToString());
     prodOp.ProductId   = Guid.Parse(rdr["ProductId"].ToString());
     prodOp.Name        = rdr["Name"].ToString();
     prodOp.Description = (DBNull.Value == rdr["Description"]) ? null : rdr["Description"].ToString();
 }
        /// <summary>
        /// Ensures the option is safe to delete.
        /// </summary>
        /// <param name="option">
        /// The option.
        /// </param>
        /// <returns>
        /// A value indicating whether or not the option can be deleted.
        /// </returns>
        private bool EnsureSafeOptionDelete(IProductOption option)
        {
            using (var repository = RepositoryFactory.CreateProductOptionRepository(UowProvider.GetUnitOfWork()))
            {
                var count = repository.GetSharedProductOptionCount(option.Key);

                return(option.Shared ? count == 0 : count == 1);
            }
        }
 public void Create(Guid productId, IProductOption option)
 {
     if (_repo.Get(option.Id) == null)
     {
         var toCreate = new ProductOption(option);
         toCreate.ProductId = productId;
         _repo.Save(toCreate, false);
     }
 }
        public void Update(Guid id, IProductOption option)
        {
            var existing = _repo.Get(id);

            if (existing != null)
            {
                var updated = new ProductOption(option);
                updated.Id = id;
                _repo.Save(updated, true);
            }
        }
Пример #14
0
        private void DeleteProductOption(IProductOption option)
        {
            var executeClauses = new[]
            {
                "DELETE FROM merchProductVariant2ProductAttribute WHERE productVariantKey IN (SELECT productVariantKey FROM merchProductVariant2ProductAttribute WHERE optionKey = @Key)",
                "DELETE FROM merchProduct2ProductOption WHERE optionKey = @Key",
                "DELETE FROM merchProductAttribute WHERE optionKey = @Key",
                "DELETE FROM merchProductOption WHERE pk = @Key"
            };

            foreach (var clause in executeClauses)
            {
                Database.Execute(clause, new { Key = option.Key });
            }
        }
Пример #15
0
        private void SaveProductOption(IProduct product, IProductOption productOption)
        {
            var factory = new ProductOptionFactory();

            if (!productOption.HasIdentity)
            {
                ((Entity)productOption).AddingEntity();
                var dto = factory.BuildDto(productOption);

                Database.Insert(dto);
                productOption.Key = dto.Key;

                // associate the product with the product option
                var association = new Product2ProductOptionDto()
                {
                    ProductKey = product.Key,
                    OptionKey  = productOption.Key,
                    SortOrder  = productOption.SortOrder,
                    CreateDate = DateTime.Now,
                    UpdateDate = DateTime.Now
                };

                Database.Insert(association);
            }
            else
            {
                ((Entity)productOption).UpdatingEntity();
                var dto = factory.BuildDto(productOption);
                Database.Update(dto);

                // TODO : this should be refactored
                const string update = "UPDATE merchProduct2ProductOption SET SortOrder = @So, updateDate = @Ud WHERE productKey = @pk AND optionKey = @OKey";

                Database.Execute(update,
                                 new
                {
                    So   = productOption.SortOrder,
                    Ud   = productOption.UpdateDate,
                    pk   = product.Key,
                    OKey = productOption.Key
                });
            }

            // now save the product attributes
            SaveProductAttributes(product, productOption);
        }
Пример #16
0
        private void SaveProductAttributes(IProduct product, IProductOption productOption)
        {
            if (!productOption.Choices.Any())
            {
                return;
            }

            var existing = GetProductAttributeCollection(productOption.Key);

            //ensure all ids are in the new list
            var resetSorts = false;

            foreach (var ex in existing)
            {
                if (productOption.Choices.Contains(ex.Sku))
                {
                    continue;
                }
                DeleteProductAttribute(ex);
                resetSorts = true;
            }
            if (resetSorts)
            {
                var count = 1;
                foreach (var o in productOption.Choices.OrderBy(x => x.SortOrder))
                {
                    o.SortOrder = count;
                    count       = count + 1;
                    productOption.Choices.Add(o);
                }
            }
            foreach (var att in productOption.Choices.OrderBy(x => x.SortOrder))
            {
                // ensure the id is set
                att.OptionKey = productOption.Key;
                SaveProductAttribute(att);
            }
            // this is required due to the special case relation between a product and product variants
            foreach (var variant in product.ProductVariants)
            {
                RuntimeCache.ClearCacheItem(Cache.CacheKeys.GetEntityCacheKey <IProductVariant>(variant.Key));
            }
        }
Пример #17
0
        /// <summary>
        /// get product option
        /// </summary>
        /// <param name="optionId">option id</param>
        /// <returns>product option</returns>
        public async Task <IProductOption> GetByIdAsync(Guid id)
        {
            IProductOption result = null;

            using (var conn = new SqlConnection(connString))
            {
                await conn.OpenAsync();

                var cmd = new SqlCommand("SELECT Id,ProductId,Name,Description FROM productoption WHERE Id=@id", conn);
                cmd.Parameters.AddWithValue("@id", id);
                var reader = await cmd.ExecuteReaderAsync();

                if (await reader.ReadAsync())
                {
                    result = new ProductOptionModel(reader);
                }

                reader.Close();
                conn.Close();
            }

            return(result);
        }
Пример #18
0
        /// <summary>
        /// update product option
        /// </summary>
        /// <param name="option">option</param>
        /// <returns></returns>
        public async Task UpdateAsync(IProductOption option)
        {
            using (var conn = new SqlConnection(connString))
            {
                await conn.OpenAsync();

                var cmd = new SqlCommand("UPDATE productoption SET Name=@name,Description=@description " +
                                         "WHERE Id=@id", conn);
                cmd.Parameters.AddWithValue("@id", option.Id);
                cmd.Parameters.AddWithValue("@name", option.Name);
                if (string.IsNullOrWhiteSpace(option.Description))
                {
                    cmd.Parameters.AddWithValue("@description", DBNull.Value);
                }
                else
                {
                    cmd.Parameters.AddWithValue("@description", option.Description);
                }

                await cmd.ExecuteNonQueryAsync();

                conn.Close();
            }
        }
        /// <summary>
        /// The to product option.
        /// </summary>
        /// <param name="productOptionDisplay">
        /// The product option display.
        /// </param>
        /// <param name="destination">
        /// The destination product option.
        /// </param>
        /// <returns>
        /// The <see cref="IProductOption"/>.
        /// </returns>
        internal static IProductOption ToProductOption(this ProductOptionDisplay productOptionDisplay, IProductOption destination)
        {
            if (productOptionDisplay.Key != Guid.Empty)
            {
                destination.Key = productOptionDisplay.Key;
            }

            destination.Name      = productOptionDisplay.Name;
            destination.Required  = productOptionDisplay.Required;
            destination.SortOrder = productOptionDisplay.SortOrder;
            destination.Shared    = productOptionDisplay.Shared;
            destination.UiOption  = productOptionDisplay.UiOption;
            destination.UseName   = productOptionDisplay.UseName.IsNullOrWhiteSpace()
                                      ? productOptionDisplay.Name
                                      : productOptionDisplay.UseName;

            if (!productOptionDisplay.DetachedContentTypeKey.Equals(Guid.Empty))
            {
                destination.DetachedContentTypeKey = productOptionDisplay.DetachedContentTypeKey;
            }
            else
            {
                destination.DetachedContentTypeKey = null;
            }


            // Fix with option deletion here #M-161 #M-150
            // remove any product choices that exist in destination and do not exist in productDisplay
            var removers = destination.Choices.Where(x => !productOptionDisplay.Choices.Select(pd => pd.Key).Contains(x.Key)).Select(x => x.Key).ToArray();

            foreach (var remove in removers)
            {
                destination.Choices.RemoveItem(remove);
            }

            foreach (var choice in productOptionDisplay.Choices)
            {
                // Sets the sku if it is empty - fixes M-170
                // http://issues.merchello.com/youtrack/issue/M-170
                if (string.IsNullOrEmpty(choice.Sku))
                {
                    choice.Sku = Regex.Replace(choice.Name, "[^0-9a-zA-Z]+", "");
                }

                IProductAttribute destinationProductAttribute;

                if (destination.Choices.Contains(choice.Sku))
                {
                    destinationProductAttribute = destination.Choices[choice.Key];

                    destinationProductAttribute = choice.ToProductAttribute(destinationProductAttribute);
                }
                else
                {
                    destinationProductAttribute = new ProductAttribute(choice.Name, choice.Sku);

                    destinationProductAttribute = choice.ToProductAttribute(destinationProductAttribute);
                }

                destinationProductAttribute.Name            = choice.Name;
                destinationProductAttribute.SortOrder       = choice.SortOrder;
                destinationProductAttribute.IsDefaultChoice = choice.IsDefaultChoice;
                destination.Choices.Add(destinationProductAttribute);
            }

            return(destination);
        }
Пример #20
0
 public SaveProductOpDml(IProductOption productOp, IHelpers helper) : base(helper)
 {
     _productOp = productOp;
 }
Пример #21
0
 private ProductOptionDisplay MapToProductOptionDisplayForEditor(IProductOption option)
 {
     return option.ToProductOptionDisplay(DetachedValuesConversionType.Editor);
 }
 internal static ProductOptionDisplay ToProductOptionDisplay(this IProductOption productOption)
 {
     return(AutoMapper.Mapper.Map <ProductOptionDisplay>(productOption));
 }
 private ProductOptionDisplay MapToProductOptionDisplayForEditor(IProductOption option)
 {
     return(option.ToProductOptionDisplay(DetachedValuesConversionType.Editor));
 }
Пример #24
0
        /// <summary>
        /// Saves a single product option.
        /// </summary>
        /// <param name="option">
        /// The option to be saved
        /// </param>
        /// <param name="raiseEvents">
        /// Optional boolean indicating whether or not to raise events.
        /// </param>
        public void Save(IProductOption option, bool raiseEvents = true)
        {
            if (raiseEvents)
                if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IProductOption>(option), this))
                {
                    ((ProductOption)option).WasCancelled = true;
                    return;
                }

            using (new WriteLock(Locker))
            {
                var uow = UowProvider.GetUnitOfWork();
                using (var repository = RepositoryFactory.CreateProductOptionRepository(uow))
                {
                    repository.AddOrUpdate(option);
                    uow.Commit();
                }
            }

            if (raiseEvents) Saved.RaiseEvent(new SaveEventArgs<IProductOption>(option), this);
        }
Пример #25
0
 /// <summary>
 /// Gets the usage information about the product option.
 /// </summary>
 /// <param name="option">
 /// The option.
 /// </param>
 /// <returns>
 /// The <see cref="IProductOptionUseCount"/>.
 /// </returns>
 public IProductOptionUseCount GetProductOptionUseCount(IProductOption option)
 {
     using (var repository = RepositoryFactory.CreateProductOptionRepository(UowProvider.GetUnitOfWork()))
     {
         return repository.GetProductOptionUseCount(option);
     }
 }
Пример #26
0
 /// <summary>
 /// Gets the number of occurrences that an option has been shared.
 /// </summary>
 /// <param name="option">
 /// The option.
 /// </param>
 /// <returns>
 /// The count of option shares.
 /// </returns>
 public int GetProductOptionShareCount(IProductOption option)
 {
     using (var repository = RepositoryFactory.CreateProductOptionRepository(UowProvider.GetUnitOfWork()))
     {
         return repository.GetSharedProductOptionCount(option.Key);
     }
 }
Пример #27
0
        /// <summary>
        /// Deletes a product option
        /// </summary>
        /// <param name="option">
        /// The option to be deleted
        /// </param>
        /// <param name="raiseEvents">
        /// Optional boolean indicating whether or not to raise events.
        /// </param>
        /// <remarks>
        /// This performs a check to ensure the option is valid to be deleted
        /// </remarks>
        public void Delete(IProductOption option, bool raiseEvents = true)
        {
            if (!EnsureSafeOptionDelete(option))
            {
                MultiLogHelper.Warn<ProductOptionService>("A ProductOption delete attempt was aborted.  The option cannot be deleted due to it being shared with one or more products.");
                return;
            }

            if (raiseEvents)
                if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IProductOption>(option), this))
                {
                    ((ProductOption)option).WasCancelled = true;
                    return;
                }

            using (new WriteLock(Locker))
            {
                var uow = UowProvider.GetUnitOfWork();
                using (var repository = RepositoryFactory.CreateProductOptionRepository(uow))
                {

                    repository.Delete(option);
                    uow.Commit();
                }
            }

            if (raiseEvents) Deleted.RaiseEvent(new DeleteEventArgs<IProductOption>(option), this);
        }
Пример #28
0
 /// <summary>
 /// Adds a new option choice.
 /// </summary>
 /// <param name="option">
 /// The option.
 /// </param>
 /// <param name="name">
 /// The name.
 /// </param>
 /// <param name="sku">
 /// The SKU.
 /// </param>
 public static void AddChoice(this IProductOption option, string name, string sku)
 {
     option.Choices.Add(new ProductAttribute(name, sku));
 }
 internal void Add(IProductOption option)
 {
     _items.Add(option);
 }
Пример #30
0
        /// <summary>
        /// The to product option.
        /// </summary>
        /// <param name="productOptionDisplay">
        /// The product option display.
        /// </param>
        /// <param name="destinationProductOption">
        /// The destination product option.
        /// </param>
        /// <returns>
        /// The <see cref="IProductOption"/>.
        /// </returns>
        internal static IProductOption ToProductOption(this ProductOptionDisplay productOptionDisplay, IProductOption destinationProductOption)
        {
            if (productOptionDisplay.Key != Guid.Empty)
            {
                destinationProductOption.Key = productOptionDisplay.Key;
            }
            destinationProductOption.Required = productOptionDisplay.Required;
            destinationProductOption.SortOrder = productOptionDisplay.SortOrder;

            // Fix with option deletion here #M-161 #M-150
            // remove any product choices that exist in destination and do not exist in productDisplay
            var removers = destinationProductOption.Choices.Where(x => !productOptionDisplay.Choices.Select(pd => pd.Key).Contains(x.Key)).Select(x => x.Key).ToArray();
            foreach (var remove in removers)
            {
                destinationProductOption.Choices.RemoveItem(remove);
            }

            foreach (var choice in productOptionDisplay.Choices)
            {
                // Sets the sku if it is empty - fixes M-170
                // http://issues.merchello.com/youtrack/issue/M-170
                if (string.IsNullOrEmpty(choice.Sku))
                {
                    choice.Sku = Regex.Replace(choice.Name, "[^0-9a-zA-Z]+", "");
                }

                IProductAttribute destinationProductAttribute;

                if (destinationProductOption.Choices.Contains(choice.Sku))
                {
                    destinationProductAttribute = destinationProductOption.Choices[choice.Key];

                    destinationProductAttribute = choice.ToProductAttribute(destinationProductAttribute);
                }
                else
                {
                    destinationProductAttribute = new ProductAttribute(choice.Name, choice.Sku);

                    destinationProductAttribute = choice.ToProductAttribute(destinationProductAttribute);
                }

                destinationProductOption.Choices.Add(destinationProductAttribute);
            }

            return destinationProductOption;
        }
Пример #31
0
        /// <summary>
        /// Ensures the option is safe to delete.
        /// </summary>
        /// <param name="option">
        /// The option.
        /// </param>
        /// <returns>
        /// A value indicating whether or not the option can be deleted.
        /// </returns>
        private bool EnsureSafeOptionDelete(IProductOption option)
        {
            using (var repository = RepositoryFactory.CreateProductOptionRepository(UowProvider.GetUnitOfWork()))
            {
                var count = repository.GetSharedProductOptionCount(option.Key);

                return option.Shared ? count == 0 : count == 1;
            }
        }