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); }
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); } }
/// <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); }
/// <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); } }
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 }); } }
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); }
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)); } }
/// <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); }
/// <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); }
public SaveProductOpDml(IProductOption productOp, IHelpers helper) : base(helper) { _productOp = productOp; }
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)); }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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; }
/// <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; } }