public ActionResult Add([Bind(Prefix = "AddForm")] ProductsAddForm form) { var model = new ProductsAddViewModel { AddForm = form }; if (ModelState.IsValid) { using (var transaction = _session.BeginTransaction()) { var product = new Product { Name = form.Name, Description = form.Description ?? string.Empty }; var primaryVariant = new ProductVariant { Price = form.Price.Value, Sku = form.Sku ?? string.Empty, Product = product }; product.Variants = new[] { primaryVariant }; _session.Save(product); transaction.Commit(); return RedirectToAction("View", new { id = product.Id }); } } SetupAddViewModel(model); return View(model); }
public void Setup() { IOC.IntegrationTest(); _product = new Product {OriginalPriceInCents = 1000, Id = 12234, Ranges = new List<Range>(), Vat = 21m}; _variant = new ProductVariant {OriginalPriceInCents = 100}; _product.VariantGroups = new List<IProductVariantGroup>{ new ProductVariantGroup("",new List<ProductVariant> {_variant},1)}; _variant.Product = _product; }
/// <summary> /// Gets discount amount /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="customer">The customer</param> /// <returns>Discount amount</returns> public virtual decimal GetDiscountAmount(ProductVariant productVariant, Customer customer, bool showHiddenDiscounts = true) { return(GetDiscountAmount(productVariant, customer, decimal.Zero, showHiddenDiscounts)); }
/// <summary> /// Creates and saves a <see cref="IProduct"/> to the database /// </summary> /// <param name="name"> /// The name. /// </param> /// <param name="sku"> /// The SKU. /// </param> /// <param name="price"> /// The price. /// </param> /// <returns> /// The <see cref="IProduct"/>. /// </returns> public IProduct CreateProductWithKey(string name, string sku, decimal price) { var templateVariant = new ProductVariant(name, sku, price); var product = new Product(templateVariant); if (Creating.IsRaisedEventCancelled(new Events.NewEventArgs<IProduct>(product), this)) { product.WasCancelled = true; return product; } using (new WriteLock(Locker)) { var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateProductRepository(uow)) { repository.AddOrUpdate(product); uow.Commit(); } } Created.RaiseEvent(new Events.NewEventArgs<IProduct>(product), this); return product; }
/// <summary> /// Add a product variant to shopping cart /// </summary> /// <param name="customer">Customer</param> /// <param name="productVariant">Product variant</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">The price enter by a customer</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param> /// <returns>Warnings</returns> public virtual IList <string> AddToCart(Customer customer, ProductVariant productVariant, ShoppingCartType shoppingCartType, string selectedAttributes, decimal customerEnteredPrice, int quantity, bool automaticallyAddRequiredProductVariantsIfEnabled) { if (customer == null) { throw new ArgumentNullException("customer"); } if (productVariant == null) { throw new ArgumentNullException("productVariant"); } var warnings = new List <string>(); if (shoppingCartType == ShoppingCartType.ShoppingCart && !_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart, customer)) { warnings.Add("Shopping cart is disabled"); return(warnings); } if (shoppingCartType == ShoppingCartType.Wishlist && !_permissionService.Authorize(StandardPermissionProvider.EnableWishlist, customer)) { warnings.Add("Wishlist is disabled"); return(warnings); } //reset checkout info _customerService.ResetCheckoutData(customer, false); var cart = customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == shoppingCartType).ToList(); ShoppingCartItem shoppingCartItem = FindShoppingCartItemInTheCart(cart, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice); if (shoppingCartItem != null) { //update existing shopping cart item int newQuantity = shoppingCartItem.Quantity + quantity; warnings.AddRange(GetShoppingCartItemWarnings(customer, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice, newQuantity, automaticallyAddRequiredProductVariantsIfEnabled)); if (warnings.Count == 0) { shoppingCartItem.AttributesXml = selectedAttributes; shoppingCartItem.Quantity = newQuantity; shoppingCartItem.UpdatedOnUtc = DateTime.UtcNow; _customerService.UpdateCustomer(customer); //event notification _eventPublisher.EntityUpdated(shoppingCartItem); } } else { //new shopping cart item warnings.AddRange(GetShoppingCartItemWarnings(customer, shoppingCartType, productVariant, selectedAttributes, customerEnteredPrice, quantity, automaticallyAddRequiredProductVariantsIfEnabled)); if (warnings.Count == 0) { //maximum items validation switch (shoppingCartType) { case ShoppingCartType.ShoppingCart: { if (cart.Count >= _shoppingCartSettings.MaximumShoppingCartItems) { return(warnings); } } break; case ShoppingCartType.Wishlist: { if (cart.Count >= _shoppingCartSettings.MaximumWishlistItems) { return(warnings); } } break; default: break; } DateTime now = DateTime.UtcNow; shoppingCartItem = new ShoppingCartItem() { ShoppingCartType = shoppingCartType, ProductVariant = productVariant, AttributesXml = selectedAttributes, CustomerEnteredPrice = customerEnteredPrice, Quantity = quantity, CreatedOnUtc = now, UpdatedOnUtc = now }; customer.ShoppingCartItems.Add(shoppingCartItem); _customerService.UpdateCustomer(customer); //event notification _eventPublisher.EntityInserted(shoppingCartItem); } } return(warnings); }
protected virtual IList <Discount> GetAllowedDiscounts(ProductVariant productVariant, Customer customer, bool showHiddenDiscounts, Discount excludedDiscount) { var allowedDiscounts = new List <Discount>(); if (_catalogSettings.IgnoreDiscounts) { return(allowedDiscounts); } foreach (var discount in productVariant.AppliedDiscounts) { if (excludedDiscount.Id == discount.Id) { continue; } if (_discountService.IsDiscountValid(discount, customer, productVariant) && discount.DiscountType == DiscountType.AssignedToSkus && !allowedDiscounts.ContainsDiscount(discount) && (!discount.ShowInCatalog.HasValue || (showHiddenDiscounts || discount.ShowInCatalog.Value))) { allowedDiscounts.Add(discount); } } var productCategories = _categoryService.GetProductCategoriesByProductId(productVariant.ProductId); if (productCategories != null) { foreach (var productCategory in productCategories) { var categoryDiscounts = productCategory.Category.AppliedDiscounts; foreach (var discount in categoryDiscounts) { if (excludedDiscount.Id == discount.Id) { continue; } if (_discountService.IsDiscountValid(discount, customer, productVariant) && discount.DiscountType == DiscountType.AssignedToCategories && !allowedDiscounts.ContainsDiscount(discount) && (!discount.ShowInCatalog.HasValue || (showHiddenDiscounts || discount.ShowInCatalog.Value))) { allowedDiscounts.Add(discount); } } } } var productManufacturers = _manufacturerService.GetProductManufacturersByProductId(productVariant.ProductId); if (productManufacturers != null) { foreach (var productManufacturer in productManufacturers) { var manufacturerDiscounts = productManufacturer.Manufacturer.AppliedDiscounts; foreach (var discount in manufacturerDiscounts) { if (excludedDiscount.Id == discount.Id) { continue; } if (_discountService.IsDiscountValid(discount, customer, productVariant) && discount.DiscountType == DiscountType.AssignedToManufacturers && !allowedDiscounts.ContainsDiscount(discount) && (!discount.ShowInCatalog.HasValue || (showHiddenDiscounts || discount.ShowInCatalog.Value))) { allowedDiscounts.Add(discount); } } } } //AF var globalDiscounts = _discountService.GetAllDiscounts(DiscountType.AssignedToAll); foreach (var discount in globalDiscounts) { if (excludedDiscount.Id == discount.Id) { continue; } if (_discountService.IsDiscountValid(discount, customer, productVariant) && !allowedDiscounts.ContainsDiscount(discount) && (!discount.ShowInCatalog.HasValue || (showHiddenDiscounts || discount.ShowInCatalog.Value))) { allowedDiscounts.Add(discount); } } return(allowedDiscounts); }
/// <summary> /// Validates required product variants /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param> /// <returns>Warnings</returns> public virtual IList <string> GetRequiredProductVariantWarnings(Customer customer, ShoppingCartType shoppingCartType, ProductVariant productVariant, bool automaticallyAddRequiredProductVariantsIfEnabled) { if (customer == null) { throw new ArgumentNullException("customer"); } if (productVariant == null) { throw new ArgumentNullException("productVariant"); } var cart = customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == shoppingCartType).ToList(); var warnings = new List <string>(); if (productVariant.RequireOtherProducts) { var requiredProductVariants = GetRequiredProductVariants(productVariant); foreach (var rpv in requiredProductVariants) { //ensure that product is in the cart bool alreadyInTheCart = false; foreach (var sci in cart) { if (sci.ProductVariantId == rpv.Id) { alreadyInTheCart = true; break; } } //not in the cart if (!alreadyInTheCart) { string fullProductName = ""; if (!String.IsNullOrEmpty(rpv.GetLocalized(x => x.Name))) { fullProductName = string.Format("{0} ({1})", rpv.Product.GetLocalized(x => x.Name), rpv.GetLocalized(x => x.Name)); } else { fullProductName = rpv.Product.GetLocalized(x => x.Name); } if (productVariant.AutomaticallyAddRequiredProductVariants) { //add to cart (if possible) if (automaticallyAddRequiredProductVariantsIfEnabled) { //pass 'false' for 'automaticallyAddRequiredProductVariantsIfEnabled' to prevent circular references var addToCartWarnings = AddToCart(customer, rpv, shoppingCartType, "", decimal.Zero, 1, false); if (addToCartWarnings.Count > 0) { //a product wasn't atomatically added for some reasons //don't display specific errors from 'addToCartWarnings' variable //display only geenric error warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), fullProductName)); } } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), fullProductName)); } } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.RequiredProductWarning"), fullProductName)); } } } } return(warnings); }
/// <summary> /// Validates shopping cart item /// </summary> /// <param name="customer">Customer</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">Customer entered price</param> /// <param name="quantity">Quantity</param> /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param> /// <returns>Warnings</returns> public virtual IList <string> GetShoppingCartItemWarnings(Customer customer, ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes, decimal customerEnteredPrice, int quantity, bool automaticallyAddRequiredProductVariantsIfEnabled) { if (productVariant == null) { throw new ArgumentNullException("productVariant"); } var warnings = new List <string>(); //TODO: include some warnings if (shoppingCartType == ShoppingCartType.Wishlist) { return(warnings); } var product = productVariant.Product; if (product == null) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CannotLoadProduct"), productVariant.ProductId)); return(warnings); } if (product.Deleted || productVariant.Deleted) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductDeleted")); return(warnings); } if (!product.Published || !productVariant.Published) { warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished")); } if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.DisableBuyButton) { warnings.Add(_localizationService.GetResource("ShoppingCart.BuyingDisabled")); } if (shoppingCartType == ShoppingCartType.Wishlist && productVariant.DisableWishlistButton) { warnings.Add(_localizationService.GetResource("ShoppingCart.WishlistDisabled")); } if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.CallForPrice && !productVariant.CallforPriceRequested(customer)) { warnings.Add(_localizationService.GetResource("ShoppingCart.CallForPriceNotAllowed")); } if (productVariant.CustomerEntersPrice) { if (customerEnteredPrice < productVariant.MinimumCustomerEnteredPrice || customerEnteredPrice > productVariant.MaximumCustomerEnteredPrice) { decimal minimumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MinimumCustomerEnteredPrice, _workContext.WorkingCurrency); decimal maximumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MaximumCustomerEnteredPrice, _workContext.WorkingCurrency); warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CustomerEnteredPrice.RangeError"), _priceFormatter.FormatPrice(minimumCustomerEnteredPrice, false, false), _priceFormatter.FormatPrice(maximumCustomerEnteredPrice, false, false))); } } if (quantity < productVariant.OrderMinimumQuantity) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MinimumQuantity"), productVariant.OrderMinimumQuantity)); } if (quantity > productVariant.OrderMaximumQuantity) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumQuantity"), productVariant.OrderMaximumQuantity)); } switch (productVariant.ManageInventoryMethod) { case ManageInventoryMethod.DontManageStock: { } break; case ManageInventoryMethod.ManageStock: { if ((BackorderMode)productVariant.BackorderMode == BackorderMode.NoBackorders) { if (productVariant.StockQuantity < quantity) { int maximumQuantityCanBeAdded = productVariant.StockQuantity; if (maximumQuantityCanBeAdded <= 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock")); } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded)); } } } } break; case ManageInventoryMethod.ManageStockByAttributes: { var combinations = productVariant.ProductVariantAttributeCombinations; ProductVariantAttributeCombination combination = null; foreach (var comb1 in combinations) { if (_productAttributeParser.AreProductAttributesEqual(comb1.AttributesXml, selectedAttributes)) { combination = comb1; } } if (combination != null) { if (!combination.AllowOutOfStockOrders) { if (combination.StockQuantity < quantity) { int maximumQuantityCanBeAdded = combination.StockQuantity; if (maximumQuantityCanBeAdded <= 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock")); } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded)); } } } } } break; default: break; } //availability dates bool availableStartDateError = false; if (productVariant.AvailableStartDateTimeUtc.HasValue) { DateTime now = DateTime.UtcNow; DateTime availableStartDateTime = DateTime.SpecifyKind(productVariant.AvailableStartDateTimeUtc.Value, DateTimeKind.Utc); if (availableStartDateTime.CompareTo(now) > 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); availableStartDateError = true; } } if (productVariant.AvailableEndDateTimeUtc.HasValue && !availableStartDateError) { DateTime now = DateTime.UtcNow; DateTime availableEndDateTime = DateTime.SpecifyKind(productVariant.AvailableEndDateTimeUtc.Value, DateTimeKind.Utc); if (availableEndDateTime.CompareTo(now) < 0) { warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable")); } } //selected attributes warnings.AddRange(GetShoppingCartItemAttributeWarnings(shoppingCartType, productVariant, selectedAttributes)); //gift cards warnings.AddRange(GetShoppingCartItemGiftCardWarnings(shoppingCartType, productVariant, selectedAttributes)); //required product variants warnings.AddRange(GetRequiredProductVariantWarnings(customer, shoppingCartType, productVariant, automaticallyAddRequiredProductVariantsIfEnabled)); return(warnings); }
/// <summary> /// Import products from XLSX file /// </summary> /// <param name="stream">Stream</param> public virtual void ImportProductsFromXlsx(Stream stream) { // ok, we can run the real code of the sample now using (var xlPackage = new ExcelPackage(stream)) { // get the first worksheet in the workbook var worksheet = xlPackage.Workbook.Worksheets.FirstOrDefault(); if (worksheet == null) { throw new NopException("No worksheet found"); } //the columns var properties = new string[] { "Name", "ShortDescription", "FullDescription", "ProductTemplateId", "ShowOnHomePage", "MetaKeywords", "MetaDescription", "MetaTitle", "SeName", "AllowCustomerReviews", "Published", "ProductVariantName", "SKU", "ManufacturerPartNumber", "Gtin", "IsGiftCard", "GiftCardTypeId", "RequireOtherProducts", "RequiredProductVariantIds", "AutomaticallyAddRequiredProductVariants", "IsDownload", "DownloadId", "UnlimitedDownloads", "MaxNumberOfDownloads", "DownloadActivationTypeId", "HasSampleDownload", "SampleDownloadId", "HasUserAgreement", "UserAgreementText", "IsRecurring", "RecurringCycleLength", "RecurringCyclePeriodId", "RecurringTotalCycles", "IsShipEnabled", "IsFreeShipping", "AdditionalShippingCharge", "IsTaxExempt", "TaxCategoryId", "ManageInventoryMethodId", "StockQuantity", "DisplayStockAvailability", "DisplayStockQuantity", "MinStockQuantity", "LowStockActivityId", "NotifyAdminForQuantityBelow", "BackorderModeId", "AllowBackInStockSubscriptions", "OrderMinimumQuantity", "OrderMaximumQuantity", "AllowedQuantities", "DisableBuyButton", "DisableWishlistButton", "CallForPrice", "Price", "OldPrice", "ProductCost", "SpecialPrice", "SpecialPriceStartDateTimeUtc", "SpecialPriceEndDateTimeUtc", "CustomerEntersPrice", "MinimumCustomerEnteredPrice", "MaximumCustomerEnteredPrice", "Weight", "Length", "Width", "Height", "CreatedOnUtc", "CategoryIds", "ManufacturerIds", "Picture1", "Picture2", "Picture3", }; int iRow = 2; while (true) { bool allColumnsAreEmpty = true; for (var i = 1; i <= properties.Length; i++) { if (worksheet.Cells[iRow, i].Value != null && !String.IsNullOrEmpty(worksheet.Cells[iRow, i].Value.ToString())) { allColumnsAreEmpty = false; break; } } if (allColumnsAreEmpty) { break; } string name = worksheet.Cells[iRow, GetColumnIndex(properties, "Name")].Value as string; string shortDescription = worksheet.Cells[iRow, GetColumnIndex(properties, "ShortDescription")].Value as string; string fullDescription = worksheet.Cells[iRow, GetColumnIndex(properties, "FullDescription")].Value as string; int productTemplateId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "ProductTemplateId")].Value); bool showOnHomePage = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "ShowOnHomePage")].Value); string metaKeywords = worksheet.Cells[iRow, GetColumnIndex(properties, "MetaKeywords")].Value as string; string metaDescription = worksheet.Cells[iRow, GetColumnIndex(properties, "MetaDescription")].Value as string; string metaTitle = worksheet.Cells[iRow, GetColumnIndex(properties, "MetaTitle")].Value as string; string seName = worksheet.Cells[iRow, GetColumnIndex(properties, "SeName")].Value as string; bool allowCustomerReviews = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "AllowCustomerReviews")].Value); bool published = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "Published")].Value); string productVariantName = worksheet.Cells[iRow, GetColumnIndex(properties, "ProductVariantName")].Value as string; string sku = worksheet.Cells[iRow, GetColumnIndex(properties, "SKU")].Value as string; string manufacturerPartNumber = worksheet.Cells[iRow, GetColumnIndex(properties, "ManufacturerPartNumber")].Value as string; string gtin = worksheet.Cells[iRow, GetColumnIndex(properties, "Gtin")].Value as string; bool isGiftCard = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "IsGiftCard")].Value); int giftCardTypeId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "GiftCardTypeId")].Value); bool requireOtherProducts = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "RequireOtherProducts")].Value); string requiredProductVariantIds = worksheet.Cells[iRow, GetColumnIndex(properties, "RequiredProductVariantIds")].Value as string; bool automaticallyAddRequiredProductVariants = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "AutomaticallyAddRequiredProductVariants")].Value); bool isDownload = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "IsDownload")].Value); int downloadId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "DownloadId")].Value); bool unlimitedDownloads = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "UnlimitedDownloads")].Value); int maxNumberOfDownloads = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "MaxNumberOfDownloads")].Value); int downloadActivationTypeId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "DownloadActivationTypeId")].Value); bool hasSampleDownload = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "HasSampleDownload")].Value); int sampleDownloadId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "SampleDownloadId")].Value); bool hasUserAgreement = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "HasUserAgreement")].Value); string userAgreementText = worksheet.Cells[iRow, GetColumnIndex(properties, "UserAgreementText")].Value as string; bool isRecurring = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "IsRecurring")].Value); int recurringCycleLength = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "RecurringCycleLength")].Value); int recurringCyclePeriodId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "RecurringCyclePeriodId")].Value); int recurringTotalCycles = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "RecurringTotalCycles")].Value); bool isShipEnabled = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "IsShipEnabled")].Value); bool isFreeShipping = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "IsFreeShipping")].Value); decimal additionalShippingCharge = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "AdditionalShippingCharge")].Value); bool isTaxExempt = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "IsTaxExempt")].Value); int taxCategoryId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "TaxCategoryId")].Value); int manageInventoryMethodId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "ManageInventoryMethodId")].Value); int stockQuantity = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "StockQuantity")].Value); bool displayStockAvailability = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "DisplayStockAvailability")].Value); bool displayStockQuantity = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "DisplayStockQuantity")].Value); int minStockQuantity = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "MinStockQuantity")].Value); int lowStockActivityId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "LowStockActivityId")].Value); int notifyAdminForQuantityBelow = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "NotifyAdminForQuantityBelow")].Value); int backorderModeId = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "BackorderModeId")].Value); bool allowBackInStockSubscriptions = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "AllowBackInStockSubscriptions")].Value); int orderMinimumQuantity = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "OrderMinimumQuantity")].Value); int orderMaximumQuantity = Convert.ToInt32(worksheet.Cells[iRow, GetColumnIndex(properties, "OrderMaximumQuantity")].Value); string allowedQuantities = worksheet.Cells[iRow, GetColumnIndex(properties, "AllowedQuantities")].Value as string; bool disableBuyButton = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "DisableBuyButton")].Value); bool disableWishlistButton = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "DisableWishlistButton")].Value); bool callForPrice = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "CallForPrice")].Value); decimal price = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "Price")].Value); decimal oldPrice = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "OldPrice")].Value); decimal productCost = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "ProductCost")].Value); decimal?specialPrice = null; var specialPriceExcel = worksheet.Cells[iRow, GetColumnIndex(properties, "SpecialPrice")].Value; if (specialPriceExcel != null) { specialPrice = Convert.ToDecimal(specialPriceExcel); } DateTime?specialPriceStartDateTimeUtc = null; var specialPriceStartDateTimeUtcExcel = worksheet.Cells[iRow, GetColumnIndex(properties, "SpecialPriceStartDateTimeUtc")].Value; if (specialPriceStartDateTimeUtcExcel != null) { specialPriceStartDateTimeUtc = DateTime.FromOADate(Convert.ToDouble(specialPriceStartDateTimeUtcExcel)); } DateTime?specialPriceEndDateTimeUtc = null; var specialPriceEndDateTimeUtcExcel = worksheet.Cells[iRow, GetColumnIndex(properties, "SpecialPriceEndDateTimeUtc")].Value; if (specialPriceEndDateTimeUtcExcel != null) { specialPriceEndDateTimeUtc = DateTime.FromOADate(Convert.ToDouble(specialPriceEndDateTimeUtcExcel)); } bool customerEntersPrice = Convert.ToBoolean(worksheet.Cells[iRow, GetColumnIndex(properties, "CustomerEntersPrice")].Value); decimal minimumCustomerEnteredPrice = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "MinimumCustomerEnteredPrice")].Value); decimal maximumCustomerEnteredPrice = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "MaximumCustomerEnteredPrice")].Value); decimal weight = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "Weight")].Value); decimal length = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "Length")].Value); decimal width = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "Width")].Value); decimal height = Convert.ToDecimal(worksheet.Cells[iRow, GetColumnIndex(properties, "Height")].Value); DateTime createdOnUtc = DateTime.FromOADate(Convert.ToDouble(worksheet.Cells[iRow, GetColumnIndex(properties, "CreatedOnUtc")].Value)); string categoryIds = worksheet.Cells[iRow, GetColumnIndex(properties, "CategoryIds")].Value as string; string manufacturerIds = worksheet.Cells[iRow, GetColumnIndex(properties, "ManufacturerIds")].Value as string; string picture1 = worksheet.Cells[iRow, GetColumnIndex(properties, "Picture1")].Value as string; string picture2 = worksheet.Cells[iRow, GetColumnIndex(properties, "Picture2")].Value as string; string picture3 = worksheet.Cells[iRow, GetColumnIndex(properties, "Picture3")].Value as string; var productVariant = _productService.GetProductVariantBySku(sku); if (productVariant != null) { //product var product = productVariant.Product; product.Name = name; product.ShortDescription = shortDescription; product.FullDescription = fullDescription; product.ProductTemplateId = productTemplateId; product.ShowOnHomePage = showOnHomePage; product.MetaKeywords = metaKeywords; product.MetaDescription = metaDescription; product.MetaTitle = metaTitle; product.AllowCustomerReviews = allowCustomerReviews; product.Published = published; product.CreatedOnUtc = createdOnUtc; product.UpdatedOnUtc = DateTime.UtcNow; _productService.UpdateProduct(product); //search engine name _urlRecordService.SaveSlug(product, product.ValidateSeName(seName, product.Name, true), 0); //variant productVariant.Name = productVariantName; productVariant.Sku = sku; productVariant.ManufacturerPartNumber = manufacturerPartNumber; productVariant.Gtin = gtin; productVariant.IsGiftCard = isGiftCard; productVariant.GiftCardTypeId = giftCardTypeId; productVariant.RequireOtherProducts = requireOtherProducts; productVariant.RequiredProductVariantIds = requiredProductVariantIds; productVariant.AutomaticallyAddRequiredProductVariants = automaticallyAddRequiredProductVariants; productVariant.IsDownload = isDownload; productVariant.DownloadId = downloadId; productVariant.UnlimitedDownloads = unlimitedDownloads; productVariant.MaxNumberOfDownloads = maxNumberOfDownloads; productVariant.DownloadActivationTypeId = downloadActivationTypeId; productVariant.HasSampleDownload = hasSampleDownload; productVariant.SampleDownloadId = sampleDownloadId; productVariant.HasUserAgreement = hasUserAgreement; productVariant.UserAgreementText = userAgreementText; productVariant.IsRecurring = isRecurring; productVariant.RecurringCycleLength = recurringCycleLength; productVariant.RecurringCyclePeriodId = recurringCyclePeriodId; productVariant.RecurringTotalCycles = recurringTotalCycles; productVariant.IsShipEnabled = isShipEnabled; productVariant.IsFreeShipping = isFreeShipping; productVariant.AdditionalShippingCharge = additionalShippingCharge; productVariant.IsTaxExempt = isTaxExempt; productVariant.TaxCategoryId = taxCategoryId; productVariant.ManageInventoryMethodId = manageInventoryMethodId; productVariant.StockQuantity = stockQuantity; productVariant.DisplayStockAvailability = displayStockAvailability; productVariant.DisplayStockQuantity = displayStockQuantity; productVariant.MinStockQuantity = minStockQuantity; productVariant.LowStockActivityId = lowStockActivityId; productVariant.NotifyAdminForQuantityBelow = notifyAdminForQuantityBelow; productVariant.BackorderModeId = backorderModeId; productVariant.AllowBackInStockSubscriptions = allowBackInStockSubscriptions; productVariant.OrderMinimumQuantity = orderMinimumQuantity; productVariant.OrderMaximumQuantity = orderMaximumQuantity; productVariant.AllowedQuantities = allowedQuantities; productVariant.DisableBuyButton = disableBuyButton; productVariant.DisableWishlistButton = disableWishlistButton; productVariant.CallForPrice = callForPrice; productVariant.Price = price; productVariant.OldPrice = oldPrice; productVariant.ProductCost = productCost; productVariant.SpecialPrice = specialPrice; productVariant.SpecialPriceStartDateTimeUtc = specialPriceStartDateTimeUtc; productVariant.SpecialPriceEndDateTimeUtc = specialPriceEndDateTimeUtc; productVariant.CustomerEntersPrice = customerEntersPrice; productVariant.MinimumCustomerEnteredPrice = minimumCustomerEnteredPrice; productVariant.MaximumCustomerEnteredPrice = maximumCustomerEnteredPrice; productVariant.Weight = weight; productVariant.Length = length; productVariant.Width = width; productVariant.Height = height; productVariant.Published = published; productVariant.CreatedOnUtc = createdOnUtc; productVariant.UpdatedOnUtc = DateTime.UtcNow; _productService.UpdateProductVariant(productVariant); } else { //product var product = new Product() { Name = name, ShortDescription = shortDescription, FullDescription = fullDescription, ShowOnHomePage = showOnHomePage, MetaKeywords = metaKeywords, MetaDescription = metaDescription, MetaTitle = metaTitle, AllowCustomerReviews = allowCustomerReviews, Published = published, CreatedOnUtc = createdOnUtc, UpdatedOnUtc = DateTime.UtcNow }; _productService.InsertProduct(product); //search engine name _urlRecordService.SaveSlug(product, product.ValidateSeName(seName, product.Name, true), 0); //variant productVariant = new ProductVariant() { ProductId = product.Id, Name = productVariantName, Sku = sku, ManufacturerPartNumber = manufacturerPartNumber, Gtin = gtin, IsGiftCard = isGiftCard, GiftCardTypeId = giftCardTypeId, RequireOtherProducts = requireOtherProducts, RequiredProductVariantIds = requiredProductVariantIds, AutomaticallyAddRequiredProductVariants = automaticallyAddRequiredProductVariants, IsDownload = isDownload, DownloadId = downloadId, UnlimitedDownloads = unlimitedDownloads, MaxNumberOfDownloads = maxNumberOfDownloads, DownloadActivationTypeId = downloadActivationTypeId, HasSampleDownload = hasSampleDownload, SampleDownloadId = sampleDownloadId, HasUserAgreement = hasUserAgreement, UserAgreementText = userAgreementText, IsRecurring = isRecurring, RecurringCycleLength = recurringCycleLength, RecurringCyclePeriodId = recurringCyclePeriodId, RecurringTotalCycles = recurringTotalCycles, IsShipEnabled = isShipEnabled, IsFreeShipping = isFreeShipping, AdditionalShippingCharge = additionalShippingCharge, IsTaxExempt = isTaxExempt, TaxCategoryId = taxCategoryId, ManageInventoryMethodId = manageInventoryMethodId, StockQuantity = stockQuantity, DisplayStockAvailability = displayStockAvailability, DisplayStockQuantity = displayStockQuantity, MinStockQuantity = minStockQuantity, LowStockActivityId = lowStockActivityId, NotifyAdminForQuantityBelow = notifyAdminForQuantityBelow, BackorderModeId = backorderModeId, AllowBackInStockSubscriptions = allowBackInStockSubscriptions, OrderMinimumQuantity = orderMinimumQuantity, OrderMaximumQuantity = orderMaximumQuantity, AllowedQuantities = allowedQuantities, DisableBuyButton = disableBuyButton, CallForPrice = callForPrice, Price = price, OldPrice = oldPrice, ProductCost = productCost, SpecialPrice = specialPrice, SpecialPriceStartDateTimeUtc = specialPriceStartDateTimeUtc, SpecialPriceEndDateTimeUtc = specialPriceEndDateTimeUtc, CustomerEntersPrice = customerEntersPrice, MinimumCustomerEnteredPrice = minimumCustomerEnteredPrice, MaximumCustomerEnteredPrice = maximumCustomerEnteredPrice, Weight = weight, Length = length, Width = width, Height = height, Published = published, CreatedOnUtc = createdOnUtc, UpdatedOnUtc = DateTime.UtcNow }; _productService.InsertProductVariant(productVariant); } //category mappings if (!String.IsNullOrEmpty(categoryIds)) { foreach (var id in categoryIds.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x.Trim()))) { if (productVariant.Product.ProductCategories.FirstOrDefault(x => x.CategoryId == id) == null) { //ensure that category exists var category = _categoryService.GetCategoryById(id); if (category != null) { var productCategory = new ProductCategory() { ProductId = productVariant.Product.Id, CategoryId = category.Id, IsFeaturedProduct = false, DisplayOrder = 1 }; _categoryService.InsertProductCategory(productCategory); } } } } //manufacturer mappings if (!String.IsNullOrEmpty(manufacturerIds)) { foreach (var id in manufacturerIds.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x.Trim()))) { if (productVariant.Product.ProductManufacturers.FirstOrDefault(x => x.ManufacturerId == id) == null) { //ensure that manufacturer exists var manufacturer = _manufacturerService.GetManufacturerById(id); if (manufacturer != null) { var productManufacturer = new ProductManufacturer() { ProductId = productVariant.Product.Id, ManufacturerId = manufacturer.Id, IsFeaturedProduct = false, DisplayOrder = 1 }; _manufacturerService.InsertProductManufacturer(productManufacturer); } } } } //pictures foreach (var picture in new string[] { picture1, picture2, picture3 }) { if (String.IsNullOrEmpty(picture)) { continue; } productVariant.Product.ProductPictures.Add(new ProductPicture() { Picture = _pictureService.InsertPicture(File.ReadAllBytes(picture), "image/jpeg", _pictureService.GetPictureSeName(name), true), DisplayOrder = 1, }); _productService.UpdateProduct(productVariant.Product); } //update "HasTierPrices" and "HasDiscountsApplied" properties _productService.UpdateHasTierPricesProperty(productVariant); _productService.UpdateHasDiscountsApplied(productVariant); //next product iRow++; } } }
/// <summary> /// Formats attributes /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="attributes">Attributes</param> /// <param name="customer">Customer</param> /// <param name="serapator">Serapator</param> /// <param name="htmlEncode">A value indicating whether to encode (HTML) values</param> /// <param name="renderPrices">A value indicating whether to render prices</param> /// <param name="renderProductAttributes">A value indicating whether to render product attributes</param> /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</param> /// <returns>Attributes</returns> public static string FormatAttributes(ProductVariant productVariant, string attributes, Customer customer, string serapator, bool htmlEncode, bool renderPrices, bool renderProductAttributes, bool renderGiftCardAttributes) { var result = new StringBuilder(); //attributes if (renderProductAttributes) { var pvaCollection = ParseProductVariantAttributes(attributes); for (int i = 0; i < pvaCollection.Count; i++) { var pva = pvaCollection[i]; var valuesStr = ParseValues(attributes, pva.ProductVariantAttributeId); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string pvaAttribute = string.Empty; if (!pva.ShouldHaveValues) { if (pva.AttributeControlType == AttributeControlTypeEnum.MultilineTextbox) { pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.LocalizedName, HtmlHelper.FormatText(valueStr, false, true, true, false, false, false)); } else { pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.LocalizedName, valueStr); } } else { var pvaValue = ProductAttributeManager.GetProductVariantAttributeValueById(Convert.ToInt32(valueStr)); if (pvaValue != null) { pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.LocalizedName, pvaValue.LocalizedName); if (renderPrices) { decimal taxRate = decimal.Zero; decimal priceAdjustmentBase = TaxManager.GetPrice(productVariant, pvaValue.PriceAdjustment, customer, out taxRate); decimal priceAdjustment = CurrencyManager.ConvertCurrency(priceAdjustmentBase, CurrencyManager.PrimaryStoreCurrency, NopContext.Current.WorkingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = PriceHelper.FormatPrice(priceAdjustment, false, false); pvaAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } } } } if (!String.IsNullOrEmpty(pvaAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } //we don't encode multiline textbox input if (htmlEncode && pva.AttributeControlType != AttributeControlTypeEnum.MultilineTextbox) { result.Append(HttpUtility.HtmlEncode(pvaAttribute)); } else { result.Append(pvaAttribute); } } } } } //gift cards if (renderGiftCardAttributes) { if (productVariant.IsGiftCard) { string giftCardRecipientName = string.Empty; string giftCardRecipientEmail = string.Empty; string giftCardSenderName = string.Empty; string giftCardSenderEmail = string.Empty; string giftCardMessage = string.Empty; GetGiftCardAttribute(attributes, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); if (!String.IsNullOrEmpty(result.ToString())) { result.Append(serapator); } if (htmlEncode) { result.Append(HttpUtility.HtmlEncode(string.Format(LocalizationManager.GetLocaleResourceString("GiftCardAttribute.For"), giftCardRecipientName))); result.Append(serapator); result.Append(HttpUtility.HtmlEncode(string.Format(LocalizationManager.GetLocaleResourceString("GiftCardAttribute.From"), giftCardSenderName))); } else { result.Append(string.Format(LocalizationManager.GetLocaleResourceString("GiftCardAttribute.For"), giftCardRecipientName)); result.Append(serapator); result.Append(string.Format(LocalizationManager.GetLocaleResourceString("GiftCardAttribute.From"), giftCardSenderName)); } } } return result.ToString(); }
private static IList <Variant> GetAvailableVariants(Product product) { IList <Variant> variants = new List <Variant>(); List <Option> relatedOptions = new List <Option>(); int lastIndex = -1, colorOptionIndex = -1, sizeOptionIndex = -1, materialOptionIndex = -1, patternOptionIndex = -1; Option colorOption = null, sizeOption = null, materialOption = null, patternOption = null; string optionListPattern = string.Empty; if (product.ProductOptions.Count > 0) { // check variants and options IList <ProductOption> options = product.ProductOptions; foreach (ProductOption pOption in options) { if (!string.IsNullOrEmpty(optionListPattern)) { optionListPattern += ","; } string optionName = pOption.Option.Name.ToLowerInvariant(); if (optionName == "color") { colorOption = pOption.Option; colorOptionIndex = ++lastIndex; relatedOptions.Add(colorOption); optionListPattern += "{C}"; } else if (optionName == "size") { sizeOption = pOption.Option; sizeOptionIndex = ++lastIndex; relatedOptions.Add(sizeOption); optionListPattern += "{S}"; } else if (optionName == "material") { materialOption = pOption.Option; materialOptionIndex = ++lastIndex; relatedOptions.Add(materialOption); optionListPattern += "{M}"; } else if (optionName == "pattern") { patternOption = pOption.Option; patternOptionIndex = ++lastIndex; relatedOptions.Add(patternOption); optionListPattern += "{P}"; } else { optionListPattern += "0"; // fill the options list pattern with zero } } } if (relatedOptions.Count > 0) { Store store = AbleContext.Current.Store; string storeUrl = store.StoreUrl; if (!storeUrl.EndsWith("/")) { storeUrl += "/"; } // calculate all valid combinations using the option choices List <int[]> choiceCombinations = GetAllChoicesCombinations(relatedOptions); ProductVariantManager variantManager = new ProductVariantManager(product.Id); IList <string> imageUrlList = new List <string>(); // require to keep track of unique images for variants foreach (int[] choicesCombination in choiceCombinations) { // collect the choice id values int colorChoiceId = 0, sizeChoiceId = 0, materialChoiceId = 0, patternChoiceId = 0; if (colorOptionIndex >= 0) { colorChoiceId = choicesCombination[colorOptionIndex]; } if (sizeOptionIndex >= 0) { sizeChoiceId = choicesCombination[sizeOptionIndex]; } if (materialOptionIndex >= 0) { materialChoiceId = choicesCombination[materialOptionIndex]; } if (patternOptionIndex >= 0) { patternChoiceId = choicesCombination[patternOptionIndex]; } // build option list, fill the color, size, material, and pattern choice id values while for rest of options fill in zero value string optionList = optionListPattern; optionList = optionList.Replace("{C}", colorChoiceId.ToString()); optionList = optionList.Replace("{S}", sizeChoiceId.ToString()); optionList = optionList.Replace("{M}", materialChoiceId.ToString()); optionList = optionList.Replace("{P}", patternChoiceId.ToString()); ProductVariant productVariant = variantManager.GetVariantFromOptions(optionList); if (productVariant != null) { // check availability if (!productVariant.Available) { continue; } Variant variant = new Variant(); variant.Product = product; string variantNamePart = string.Empty; string variantoptionsList = string.Empty; if (colorChoiceId > 0) { variant.Color = EntityLoader.Load <OptionChoice>(colorChoiceId).Name; variantNamePart += string.IsNullOrEmpty(variantNamePart) ? variant.Color : "," + variant.Color; variantoptionsList += string.IsNullOrEmpty(variantoptionsList) ? colorChoiceId.ToString() : "," + colorChoiceId.ToString(); } if (sizeChoiceId > 0) { variant.Size = EntityLoader.Load <OptionChoice>(sizeChoiceId).Name; variantNamePart += string.IsNullOrEmpty(variantNamePart) ? variant.Size : "," + variant.Size; variantoptionsList += string.IsNullOrEmpty(variantoptionsList) ? sizeChoiceId.ToString() : "," + sizeChoiceId.ToString(); } if (materialChoiceId > 0) { variant.Material = EntityLoader.Load <OptionChoice>(materialChoiceId).Name; variantNamePart += string.IsNullOrEmpty(variantNamePart) ? variant.Material : "," + variant.Material; variantoptionsList += string.IsNullOrEmpty(variantoptionsList) ? materialChoiceId.ToString() : "," + materialChoiceId.ToString(); } if (patternChoiceId > 0) { variant.Pattern = EntityLoader.Load <OptionChoice>(patternChoiceId).Name; variantNamePart += string.IsNullOrEmpty(variantNamePart) ? variant.Pattern : "," + variant.Pattern; variantoptionsList += string.IsNullOrEmpty(variantoptionsList) ? patternChoiceId.ToString() : "," + patternChoiceId.ToString(); } variant.Name = string.Format("{0} - {1}", product.Name, variantNamePart); variant.Link = ResolveUrl(product.NavigateUrl, storeUrl) + string.Format("?Options={0}", variantoptionsList); // WE CAN ONLY USE ALPHANUMERIC CHARACTERS FOR ID, CREATE ID VALUE USING THE APAREL OPTIONS // [Product_Id]C[COLOR_CHOICE_ID]S[SIZE_CHOICE_ID]M[MATERIAL_CHOICE_ID]P[PATTERN_CHOICE_ID] variant.Id = string.Format("{0}C{1}S{2}M{3}P{4}", product.Id, (colorOptionIndex > -1 ? colorChoiceId.ToString() : string.Empty), (sizeOptionIndex > -1 ? sizeChoiceId.ToString() : string.Empty), (materialOptionIndex > -1 ? materialChoiceId.ToString() : string.Empty), (patternOptionIndex > -1 ? patternChoiceId.ToString() : string.Empty)); // VERIFY UNIQUE IMAGE LINK CONSIDERING FOLLOWING GOOGLE FEED REQUIREMENTS // For products that fall under “Apparel & Accessories” and all corresponding sub-categories in feeds targeting the US, UK, DE, FR, and JP: // If you are submitting product variants that differ in ‘‘color’, or ‘pattern’, or ‘material’, // we require you to submit specific images corresponding to each of these variants. // If you do not have the correct image for the variation of the product, you may not submit that variant. // We recommend specific images for ‘size’ variants too. However, if these are not available you may submit the same image URL for items that differ in ‘size’. string imageUrl = string.Empty; if (!string.IsNullOrEmpty(productVariant.ImageUrl)) { imageUrl = productVariant.ImageUrl.ToLowerInvariant(); } if (string.IsNullOrEmpty(imageUrl) && !string.IsNullOrEmpty(product.ImageUrl)) { imageUrl = product.ImageUrl.ToLowerInvariant(); // use product image if no image } if (string.IsNullOrEmpty(imageUrl)) { continue; // skip if no image } if (!IsAbsoluteURL(imageUrl)) { imageUrl = ResolveUrl(imageUrl, storeUrl); } // verify unique image for each combination of ‘color’, ‘pattern’, and ‘material’ if (imageUrlList.Contains(imageUrl)) { bool isUniqueImage = true; // MAKE SURE OTHER VARIANTS ONLY DIFFER BY SIZE, OTHERWISE SKIP THIS foreach (Variant otherVariant in variants) { if (imageUrl == otherVariant.ImageUrl) { if (!(variant.Color == otherVariant.Color && variant.Pattern == otherVariant.Pattern && variant.Material == otherVariant.Material && variant.Size != otherVariant.Size)) { isUniqueImage = false; break; } } } // SKIP THIS VARIANT, AS WE DO NOT HAVE A UNIQUE IMAGE FOR THIS VARIANT AS THIS IMAGE ALREADY USED FOR ANOTHER VARIANT, WHICH DIFFERS FOR MORE THEN SIZE if (!isUniqueImage) { continue; } } // else add to variant image dictionary to keep track of rest of variants imageUrlList.Add(imageUrl); variant.ImageUrl = imageUrl; // use product id as item group id, this must be same for all variants of same product, but must be unique for variants of each product variant.ItemGroupId = product.Id.ToString(); ProductCalculator productCalculator = ProductCalculator.LoadForProduct(product.Id, 1, productVariant.OptionList, string.Empty, 0); variant.Weight = productCalculator.Weight; variant.Price = productCalculator.Price; variant.Sku = productCalculator.Sku; string gtin = productVariant.GTIN; if (string.IsNullOrEmpty(gtin)) { // for compatibility with AC7 data check if SKU is a UPC gtin = IsUpcCode(productVariant.Sku) ? productVariant.Sku : string.Empty; } variant.GTIN = gtin; variant.ModelNumber = productVariant.ModelNumber; variant.InStock = productVariant.InStock; variants.Add(variant); } } } return(variants); }
/// <summary> /// The calculation of the total customer discount. /// </summary> /// <param name="tradeAgreements">Trade agreement collection to calculate on. If null, uses the pricing data manager to find agreements.</param> /// <param name="retailTransaction">The retail transaction which needs total discounts.</param> /// <returns> /// The retail transaction. /// </returns> public SalesTransaction CalcTotalCustomerDiscount( List <TradeAgreement> tradeAgreements, SalesTransaction retailTransaction) { if (tradeAgreements != null && tradeAgreements.Any()) { decimal totalAmount = 0; // Find the total amount as a basis for the total discount // Consider calculable lines only. Ignore voided or return-by-receipt lines. var clonedTransaction = retailTransaction.Clone <SalesTransaction>(); foreach (var clonedSalesLine in clonedTransaction.PriceCalculableSalesLines) { if (this.IsTotalDiscountAllowed(clonedSalesLine.ItemId)) { SalesLineTotaller.CalculateLine(clonedTransaction, clonedSalesLine, d => this.priceContext.CurrencyAndRoundingHelper.Round(d)); totalAmount += clonedSalesLine.NetAmountWithAllInclusiveTax; } } decimal absTotalAmount = Math.Abs(totalAmount); // Find the total discounts. PriceDiscountType relation = PriceDiscountType.EndDiscountSales; // Total sales discount - 7 PriceDiscountItemCode itemCode = PriceDiscountItemCode.AllItems; // All items - 2 PriceDiscountAccountCode accountCode = 0; string itemRelation = string.Empty; decimal percent1 = 0m; decimal percent2 = 0m; decimal discountAmount = 0m; ProductVariant dimension = new ProductVariant(); int idx = 0; while (idx < /* Max(PriceDiscAccountCode) */ 3) { // Check discounts for Store Currency accountCode = (PriceDiscountAccountCode)idx; string accountRelation = string.Empty; if (accountCode == PriceDiscountAccountCode.Customer) { accountRelation = retailTransaction.CustomerId; } else if (accountCode == PriceDiscountAccountCode.CustomerGroup) { accountRelation = this.priceContext.CustomerTotalPriceGroup; } accountRelation = accountRelation ?? string.Empty; // Only get Active discount combinations if (this.discountParameters.Activation(relation, (PriceDiscountAccountCode)accountCode, (PriceDiscountItemCode)itemCode)) { var priceDiscTable = Discount.GetPriceDiscData(tradeAgreements, relation, itemRelation, accountRelation, itemCode, accountCode, absTotalAmount, this.priceContext, dimension, false); foreach (TradeAgreement row in priceDiscTable) { percent1 += row.PercentOne; percent2 += row.PercentTwo; discountAmount += row.Amount; if (!row.ShouldSearchAgain) { idx = 3; } } } idx++; } decimal totalPercentage = DiscountLine.GetCompoundedPercentage(percent1, percent2); if (discountAmount != decimal.Zero) { this.AddTotalDiscAmountLines(retailTransaction, DiscountLineType.CustomerDiscount, discountAmount); } if (totalPercentage != 0) { // Update the sale items. // Consider calculable lines only. Ignore voided or return-by-receipt lines. foreach (var saleItem in retailTransaction.PriceCalculableSalesLines) { if (this.IsTotalDiscountAllowed(saleItem.ItemId)) { DiscountLine discountItem = GetCustomerDiscountItem(saleItem, CustomerDiscountType.TotalDiscount, DiscountLineType.CustomerDiscount); discountItem.Percentage = totalPercentage; } } } } return(retailTransaction); }
/// <summary> /// Gets price /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="price">Price</param> /// <param name="customer">Customer</param> /// <returns>Price</returns> public static decimal GetPrice(ProductVariant productVariant, decimal price, Customer customer) { string Error = string.Empty; return(GetPrice(productVariant, price, customer, ref Error)); }
/// <summary> /// Gets price /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="price">Price</param> /// <param name="Error">Error</param> /// <returns>Price</returns> public static decimal GetPrice(ProductVariant productVariant, decimal price, ref string Error) { Customer customer = NopContext.Current.User; return(GetPrice(productVariant, price, customer, ref Error)); }
/// <summary> /// Gets tax rate /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="customer">Customer</param> /// <param name="Error">Error</param> /// <returns>Tax rate</returns> public static decimal GetTaxRate(ProductVariant productVariant, Customer customer, ref string Error) { return(GetTaxRate(productVariant, 0, customer, ref Error)); }
/// <summary> /// Set product variant info based on a product variant in the catalog /// </summary> /// <param name="productVariant">The product variant.</param> /// <param name="product">The product.</param> /// <param name="itemCount">The item count.</param> public ProductVariantInfo(ProductVariant productVariant, ProductInfo product, int itemCount) { Product = product; Id = productVariant.Id; Title = productVariant.Title; SKU = productVariant.SKU; var groupname = string.Empty; if (string.IsNullOrEmpty(productVariant.Group)) { var productVariantGroup = DomainHelper.GetProductVariantGroupById(productVariant.ParentId); if (productVariantGroup != null) { groupname = productVariantGroup.Title; } } else { groupname = productVariant.Group; } Group = groupname; Weight = productVariant.Weight; Length = productVariant.Length; Height = productVariant.Height; Width = productVariant.Width; PriceInCents = productVariant.OriginalPriceInCents; Ranges = productVariant.Ranges; // = localized ChangedOn = DateTime.Now; Vat = productVariant.Vat; if (productVariant.IsDiscounted) { DiscountId = productVariant.ProductVariantDiscount.Id; if (productVariant.ProductVariantDiscount.DiscountType == DiscountType.Amount) DiscountAmountInCents = productVariant.ProductVariantDiscount.RangedDiscountValue(itemCount); else if (productVariant.ProductVariantDiscount.DiscountType == DiscountType.Percentage) DiscountPercentage = productVariant.ProductVariantDiscount.RangedDiscountValue(itemCount)/100m; else if (productVariant.ProductVariantDiscount.DiscountType == DiscountType.NewPrice) PriceInCents = productVariant.ProductVariantDiscount.RangedDiscountValue(itemCount); } DocTypeAlias = productVariant.NodeTypeAlias; }
public WarehouseStockBuilder(ProductVariant productVariant, Warehouse warehouse) { _productVariant = productVariant; _warehouse = warehouse; }
/// <summary> /// Formats attributes /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="attributes">Attributes</param> /// <param name="customer">Customer</param> /// <param name="serapator">Serapator</param> /// <returns>Attributes</returns> public static string FormatAttributes(ProductVariant productVariant, string attributes, Customer customer, string serapator) { return FormatAttributes(productVariant, attributes, customer, serapator, true); }
public IActionResult AddToCart(CartItemModel cartItemModel) { //check if we need to redirect user to login page. This will happen in the following cases. //1. Either user is trying to add to his wishlist //2. Order settings don't allow guest checkout var currentUser = ApplicationEngine.CurrentUser; if (currentUser == null || currentUser.IsVisitor()) { if (cartItemModel.IsWishlist || !_orderSettings.AllowGuestCheckout) { var loginUrl = ApplicationEngine.RouteUrl(RouteNames.Login, new { ReturnUrl = ApplicationEngine.CurrentHttpContext.GetReferer() }); return(R.Redirect(loginUrl).Result); } } //first get the product var product = _productService.Get(cartItemModel.ProductId); if (product == null || !product.IsPublic(CurrentStore.Id)) { return(R.Fail.Result); } if (product.RequireLoginToPurchase && CurrentUser.IsVisitor()) { return(R.Fail.WithError(ErrorCodes.RequiresAuthenticatedUser, T("Please login to purchase this product.")).Result); } //check appropriate attributes if not wishlist ProductVariant variant = null; IActionResult validationResult = null; string attributeJson = string.Empty; if (!cartItemModel.IsWishlist) { if (product.ProductAttributes?.Any() ?? false) { //use attributes which are valid var allowedAttributes = product.ProductAttributes.Select(x => x.Label).ToList(); cartItemModel.Attributes = cartItemModel.Attributes.Where(x => allowedAttributes.Contains(x.Name)).ToList(); //exclude attributes without any values cartItemModel.Attributes = cartItemModel.Attributes .Where(x => x.SelectedValues != null && x.SelectedValues.Count > 0 && x.SelectedValues.Count(y => y.Name == "-1") == 0) .ToList(); //check if required attributes have been passed var requiredAttributes = product.ProductAttributes.Where(x => x.IsRequired); foreach (var ra in requiredAttributes) { if (cartItemModel.Attributes.All(x => x.Name != ra.Label)) { return(R.Fail.With("error", T("{0} is required", arguments: ra.AvailableAttribute.Name)).Result); } } //check if valid values for attributes has been passed foreach (var ca in cartItemModel.Attributes) { var pa = product.ProductAttributes.First(x => x.Label == ca.Name); if (!pa.InputFieldType.RequireValues()) { //if it's a file upload or image upload type, better provide a download url if (pa.InputFieldType == InputFieldType.FileUpload || pa.InputFieldType == InputFieldType.ImageUpload) { //put a download link so it'll be included everywhere var uploadUid = ca.SelectedValues.FirstOrDefault()?.Name; var uploadUrl = ApplicationEngine.RouteUrl(RouteNames.DownloadUploadFile, new { guid = uploadUid }); var link = $"<a href='{uploadUrl}' target='_blank' style='display: inline;font-size: 0.8em;'>[Download]</a>"; ca.SelectedValues[0].Name = link; } continue; //as we don't need to validate the values now } var allowedAttributeValues = product.ProductAttributes.First(x => x.Label == ca.Name).AvailableAttribute .AvailableAttributeValues.Select(x => x.Value).ToList(); var invalidValues = ca.SelectedValues.Where(x => !allowedAttributeValues.Contains(x.Name)).Select(x => x.Name).ToList(); if (invalidValues.Any()) { return(R.Fail.With("error", T("'{0}' is not valid value for '{1}'", arguments: new object[] { string.Join(T(" or "), invalidValues), ca.Name })).Result); } } } //validate the quantity ValidateQuantityRange(cartItemModel.Quantity, product, null, out validationResult); if (validationResult != null) { return(validationResult); } //should we check for availability if (product.TrackInventory || product.HasVariants) { if (!product.HasVariants) { ValidateProductQuantity(product, out validationResult); if (validationResult != null) { return(validationResult); } } else { var passedPairs = cartItemModel.Attributes .ToDictionary(x => x.Name, x => x.SelectedValues.Select(y => y.Name).ToList()); var attributeNames = cartItemModel.Attributes.Select(x => x.Name).ToList(); var attributeIds = product.ProductAttributes?.Where(x => x.InputFieldType.RequireValues() && attributeNames.Contains(x.Label)) .Select(x => x.Id) .ToList() ?? new List <int>(); //if the product has variants only variants should be allowed to be added var variants = _productVariantService.GetByProductId(product.Id); //first filter out by attributes variants = variants.Where(x => { var variantAttributeIds = x.ProductVariantAttributes.Select(y => y.ProductAttributeId).ToList(); return(!attributeIds.Except(variantAttributeIds).Any()); }).ToList(); variant = variants.FirstOrDefault(x => { var variantAttributes = x.ProductVariantAttributes; foreach (var passedKv in passedPairs) { if (variantAttributes.Any(y => y.ProductAttribute.Label == passedKv.Key && y.ProductAttributeValue.Label != passedKv.Value.First())) { return(false); } } return(true); }); //is the variant available? ValidateVariantQuantity(cartItemModel.Quantity, variant, out validationResult); if (validationResult != null) { return(validationResult); } } } var productAttributes = new Dictionary <string, IList <string> >(); if (cartItemModel.Attributes != null) { foreach (var cpa in cartItemModel.Attributes) { productAttributes.TryAdd(cpa.Name, cpa.SelectedValues.Select(x => x.Name).ToList()); } attributeJson = _dataSerializer.Serialize(productAttributes, false); } } //guest signin if user is not signed in ApplicationEngine.GuestSignIn(); currentUser = ApplicationEngine.CurrentUser; //find if there is already an existing product added var cart = cartItemModel.IsWishlist ? _cartService.GetWishlist(currentUser.Id) : _cartService.GetCart(currentUser.Id); var cartItem = cart.CartItems.FirstOrDefault(x => x.ProductId == product.Id && x.AttributeJson == attributeJson); if (cartItem == null) { //no issue adding this cartItem = new CartItem() { ProductId = cartItemModel.ProductId, Quantity = cartItemModel.Quantity, AttributeJson = attributeJson, ComparePrice = product.ComparePrice, Price = variant != null ? variant.Price ?? product.Price : product.Price, ProductVariantId = variant?.Id ?? 0, IsDownloadable = product.IsDownloadable }; if (cartItemModel.IsWishlist) { _cartService.AddToWishlist(ApplicationEngine.CurrentUser.Id, cartItem); } else { _cartService.AddToCart(ApplicationEngine.CurrentUser.Id, cartItem); } } else { var productVariant = product.HasVariants ? _productVariantService.Get(cartItem.ProductVariantId) : null; //can we add this item to cart? ValidateQuantityRange(cartItem.Quantity + cartItemModel.Quantity, product, productVariant, out validationResult); if (validationResult != null) { return(validationResult); } //we can, increment and save cartItem.Quantity = cartItem.Quantity + cartItemModel.Quantity; _cartService.UpdateCart(ApplicationEngine.CurrentUser.Id, cartItem); } //reset shipping details if (cart.ShippingMethodName.IsNullEmptyOrWhiteSpace()) { //clear the shipping methods cart.ShippingMethodName = string.Empty; cart.ShippingMethodDisplayName = string.Empty; cart.ShippingOptionsSerialized = string.Empty; cart.SelectedShippingOption = string.Empty; cart.ShippingOptionsSerialized = string.Empty; _cartService.Update(cart); } return(R.Success.Result); }
public List <ProductCardModel> Get(List <Product> products) { var galleryIds = products.Select(product => product.Gallery.Id).ToList(); var productIds = products.Select(product => product.Id).ToList(); List <MediaFile> mediaFiles = _session.QueryOver <MediaFile>() .Where(file => file.MediaCategory.Id.IsIn(galleryIds)) .OrderBy(file => file.DisplayOrder) .Asc.Cacheable() .List().ToList(); List <ProductVariant> variants = _session.QueryOver <ProductVariant>() .Where(productVariant => productVariant.Product.Id.IsIn(productIds)) .Cacheable() .List().ToList(); var productCardModels = new List <ProductCardModel>(); foreach (var product in products) { MediaFile image = mediaFiles.FirstOrDefault(file => file.IsImage() && file.MediaCategory.Id == product.Gallery.Id); var productVariants = variants.FindAll(productVariant => productVariant.Product.Id == product.Id); if (!productVariants.Any()) { continue; } var productCardModel = new ProductCardModel { Name = product.Name, Url = product.LiveUrlSegment, Abstract = product.ProductAbstract, SearchResultAbstract = product.SearchResultAbstract, Image = image?.FileUrl, BrandImage = product.BrandPage?.FeatureImage, PreviousPriceText = _ecommerceSettings.PreviousPriceText, ProductReviewsEnabled = _productReviewSettings.EnableProductReviews, IsMultiVariant = productVariants.Count > 1 }; if (productVariants.Count == 1) { var variant = productVariants.FirstOrDefault(); productCardModel.PreviousPrice = _productPricingMethod.GetDisplayPreviousPrice(variant); productCardModel.Price = _productPricingMethod.GetUnitPrice(variant); productCardModel.PricePreTax = _productPricingMethod.GetUnitPricePreTax(variant); productCardModel.Tax = _productPricingMethod.GetUnitTax(variant); productCardModel.VariantId = variant.Id; CanBuyStatus canBuyStatus = _productVariantAvailabilityService.CanBuy(variant, 1); productCardModel.CanBuyStatus = canBuyStatus; productCardModel.StockMessage = canBuyStatus.OK ? (!string.IsNullOrEmpty(variant.CustomStockInStockMessage) ? variant.CustomStockInStockMessage : _stringResourceProvider.GetValue("In Stock")) : (!string.IsNullOrEmpty(variant.CustomStockOutOfStockMessage) ? variant.CustomStockOutOfStockMessage : _stringResourceProvider.GetValue("Out of Stock")); productCardModel.Rating = variant.Rating; productCardModel.NumberOfReviews = variant.NumberOfReviews; if (variant.ETag != null) { productCardModel.ETag = variant.ETag; } } else { ProductVariant variant = productVariants.OrderBy(x => _productPricingMethod.GetUnitPrice(x, 0m, 0m)).FirstOrDefault(); productCardModel.Price = variant != null ? _productPricingMethod.GetUnitPrice(variant, 0m, 0m) : (decimal?)null; productCardModel.Rating = variant.Rating; productCardModel.NumberOfReviews = variant.NumberOfReviews; if (variant.ETag != null) { productCardModel.ETag = variant.ETag; } } productCardModels.Add(productCardModel); } return(productCardModels); }
public CanBuyStatus CanBuyAny(ProductVariant productVariant) { return(_productVariantAvailabilityService.CanBuy(productVariant, 1)); }
/// <summary> /// Validates shopping cart item attributes /// </summary> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <returns>Warnings</returns> public virtual IList <string> GetShoppingCartItemAttributeWarnings(ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes) { if (productVariant == null) { throw new ArgumentNullException("productVariant"); } var warnings = new List <string>(); //selected attributes var pva1Collection = _productAttributeParser.ParseProductVariantAttributes(selectedAttributes); foreach (var pva1 in pva1Collection) { var pv1 = pva1.ProductVariant; if (pv1 != null) { if (pv1.Id != productVariant.Id) { warnings.Add("Attribute error"); } } else { warnings.Add("Attribute error"); return(warnings); } } //existing product attributes var pva2Collection = productVariant.ProductVariantAttributes; foreach (var pva2 in pva2Collection) { if (pva2.IsRequired) { bool found = false; //selected product attributes foreach (var pva1 in pva1Collection) { if (pva1.Id == pva2.Id) { var pvaValuesStr = _productAttributeParser.ParseValues(selectedAttributes, pva1.Id); foreach (string str1 in pvaValuesStr) { if (!String.IsNullOrEmpty(str1.Trim())) { found = true; break; } } } } //if not found if (!found) { if (!string.IsNullOrEmpty(pva2.TextPrompt)) { warnings.Add(pva2.TextPrompt); } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.SelectAttribute"), pva2.ProductAttribute.GetLocalized(a => a.Name))); } } } } return(warnings); }
public void Can_get_final_product_price_with_tier_prices_by_customerRole() { var productVariant = new ProductVariant { Id = 1, Name = "Product variant name 1", Price = 12.34M, CustomerEntersPrice = false, Published = true, Product = new Product() { Id = 1, Name = "Product name 1", Published = true } }; //customer roles var customerRole1 = new CustomerRole() { Id = 1, Name = "Some role 1", Active = true, }; var customerRole2 = new CustomerRole() { Id = 2, Name = "Some role 2", Active = true, }; //add tier prices productVariant.TierPrices.Add(new TierPrice() { Price = 10, Quantity = 2, ProductVariant = productVariant, CustomerRole = customerRole1 }); productVariant.TierPrices.Add(new TierPrice() { Price = 9, Quantity = 2, ProductVariant = productVariant, CustomerRole = customerRole2 }); productVariant.TierPrices.Add(new TierPrice() { Price = 8, Quantity = 5, ProductVariant = productVariant, CustomerRole = customerRole1 }); productVariant.TierPrices.Add(new TierPrice() { Price = 5, Quantity = 10, ProductVariant = productVariant, CustomerRole = customerRole2 }); //customer Customer customer = new Customer(); customer.CustomerRoles.Add(customerRole1); _priceCalcService.GetFinalPrice(productVariant, customer, 0, false, 1).ShouldEqual(12.34M); _priceCalcService.GetFinalPrice(productVariant, customer, 0, false, 2).ShouldEqual(10); _priceCalcService.GetFinalPrice(productVariant, customer, 0, false, 3).ShouldEqual(10); _priceCalcService.GetFinalPrice(productVariant, customer, 0, false, 5).ShouldEqual(8); _priceCalcService.GetFinalPrice(productVariant, customer, 0, false, 10).ShouldEqual(8); }
/// <summary> /// Finds a shopping cart item in the cart /// </summary> /// <param name="shoppingCart">Shopping cart</param> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <param name="customerEnteredPrice">Price entered by a customer</param> /// <returns>Found shopping cart item</returns> public virtual ShoppingCartItem FindShoppingCartItemInTheCart(IList <ShoppingCartItem> shoppingCart, ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes = "", decimal customerEnteredPrice = decimal.Zero) { if (shoppingCart == null) { throw new ArgumentNullException("shoppingCart"); } if (productVariant == null) { throw new ArgumentNullException("productVariant"); } foreach (var sci in shoppingCart.Where(a => a.ShoppingCartType == shoppingCartType)) { if (sci.ProductVariantId == productVariant.Id) { //attributes bool attributesEqual = _productAttributeParser.AreProductAttributesEqual(sci.AttributesXml, selectedAttributes); //gift cards bool giftCardInfoSame = true; if (sci.ProductVariant.IsGiftCard) { string giftCardRecipientName1 = string.Empty; string giftCardRecipientEmail1 = string.Empty; string giftCardSenderName1 = string.Empty; string giftCardSenderEmail1 = string.Empty; string giftCardMessage1 = string.Empty; _productAttributeParser.GetGiftCardAttribute(selectedAttributes, out giftCardRecipientName1, out giftCardRecipientEmail1, out giftCardSenderName1, out giftCardSenderEmail1, out giftCardMessage1); string giftCardRecipientName2 = string.Empty; string giftCardRecipientEmail2 = string.Empty; string giftCardSenderName2 = string.Empty; string giftCardSenderEmail2 = string.Empty; string giftCardMessage2 = string.Empty; _productAttributeParser.GetGiftCardAttribute(sci.AttributesXml, out giftCardRecipientName2, out giftCardRecipientEmail2, out giftCardSenderName2, out giftCardSenderEmail2, out giftCardMessage2); if (giftCardRecipientEmail1.ToLowerInvariant() != giftCardRecipientEmail2.ToLowerInvariant() || giftCardSenderName1.ToLowerInvariant() != giftCardSenderName2.ToLowerInvariant()) { giftCardInfoSame = false; } } //price is the same (for products which require customers to enter a price) bool customerEnteredPricesEqual = true; if (sci.ProductVariant.CustomerEntersPrice) { customerEnteredPricesEqual = Math.Round(sci.CustomerEnteredPrice, 2) == Math.Round(customerEnteredPrice, 2); } //found? if (attributesEqual && giftCardInfoSame && customerEnteredPricesEqual) { return(sci); } } } return(null); }
public void Can_get_product_discount() { var productVariant = new ProductVariant { Id = 1, Name = "Product variant name 1", Price = 12.34M, CustomerEntersPrice = false, Published = true, Product = new Product() { Id = 1, Name = "Product name 1", Published = true } }; //customer Customer customer = null; //discounts var discount1 = new Discount() { Id = 1, Name = "Discount 1", DiscountType = DiscountType.AssignedToSkus, DiscountAmount = 3, DiscountLimitation = DiscountLimitationType.Unlimited }; discount1.AppliedToProductVariants.Add(productVariant); productVariant.AppliedDiscounts.Add(discount1); _discountService.Expect(ds => ds.IsDiscountValid(discount1, customer)).Return(true); var discount2 = new Discount() { Id = 2, Name = "Discount 2", DiscountType = DiscountType.AssignedToSkus, DiscountAmount = 4, DiscountLimitation = DiscountLimitationType.Unlimited }; discount2.AppliedToProductVariants.Add(productVariant); productVariant.AppliedDiscounts.Add(discount2); _discountService.Expect(ds => ds.IsDiscountValid(discount2, customer)).Return(true); var discount3 = new Discount() { Id = 3, Name = "Discount 3", DiscountType = DiscountType.AssignedToOrderSubTotal, DiscountAmount = 5, DiscountLimitation = DiscountLimitationType.Unlimited, RequiresCouponCode = true, CouponCode = "SECRET CODE" }; discount3.AppliedToProductVariants.Add(productVariant); productVariant.AppliedDiscounts.Add(discount3); //discount is not valid _discountService.Expect(ds => ds.IsDiscountValid(discount3, customer)).Return(false); Discount appliedDiscount; _priceCalcService.GetDiscountAmount(productVariant, customer, 0, 1, out appliedDiscount).ShouldEqual(4); appliedDiscount.ShouldNotBeNull(); appliedDiscount.ShouldEqual(discount2); }
/// <summary> /// Gets the final price /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="includeDiscounts">A value indicating whether include discounts or not for final price computation</param> /// <returns>Final price</returns> public virtual decimal GetFinalPrice(ProductVariant productVariant, bool includeDiscounts, Customer customer, out IList <Discount> appliedDiscounts, bool showHiddenDiscounts = true) { return(GetFinalPrice(productVariant, customer, includeDiscounts, out appliedDiscounts, showHiddenDiscounts)); }
public string FormatAttributes(ProductVariant productVariant, string attributes, string wrapperHtml, Customer customer, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool renderProductAttributes = true, bool renderGiftCardAttributes = true) { var result = new StringBuilder(); //attributes if (renderProductAttributes) { var pvaCollection = _productAttributeParser.ParseProductVariantAttributes(attributes); for (int i = 0; i < pvaCollection.Count; i++) { var pva = pvaCollection[i]; var valuesStr = _productAttributeParser.ParseValues(attributes, pva.Id); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string pvaAttribute = string.Empty; if (!pva.ShouldHaveValues()) { if (pva.AttributeControlType == AttributeControlType.MultilineTextbox) { pvaAttribute = string.Format(wrapperHtml, pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), HtmlHelper.FormatText(valueStr, false, true, true, false, false, false)); } else { pvaAttribute = string.Format(wrapperHtml, pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), valueStr); } } else { int pvaId = 0; if (int.TryParse(valueStr, out pvaId)) { var pvaValue = _productAttributeService.GetProductVariantAttributeValueById(pvaId); if (pvaValue != null) { pvaAttribute = string.Format(wrapperHtml, pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), pvaValue.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id)); if (renderPrices) { decimal taxRate = decimal.Zero; decimal priceAdjustmentBase = _taxService.GetProductPrice(productVariant, pvaValue.PriceAdjustment, customer, out taxRate); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment, false, false); pvaAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } else if (priceAdjustmentBase < decimal.Zero) { string priceAdjustmentStr = _priceFormatter.FormatPrice(-priceAdjustment, false, false); pvaAttribute += string.Format(" [-{0}]", priceAdjustmentStr); } } } } } if (!String.IsNullOrEmpty(pvaAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } //we don't encode multiline textbox input if (htmlEncode && pva.AttributeControlType != AttributeControlType.MultilineTextbox) { result.Append(HttpUtility.HtmlEncode(pvaAttribute)); } else { result.Append(pvaAttribute); } } } } } //gift cards if (renderGiftCardAttributes) { if (productVariant.IsGiftCard) { string giftCardRecipientName = string.Empty; string giftCardRecipientEmail = string.Empty; string giftCardSenderName = string.Empty; string giftCardSenderEmail = string.Empty; string giftCardMessage = string.Empty; _productAttributeParser.GetGiftCardAttribute(attributes, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); if (!String.IsNullOrEmpty(result.ToString())) { result.Append(serapator); } if (htmlEncode) { result.Append(HttpUtility.HtmlEncode(string.Format(_localizationService.GetResource("GiftCardAttribute.For"), giftCardRecipientName))); result.Append(serapator); result.Append(HttpUtility.HtmlEncode(string.Format(_localizationService.GetResource("GiftCardAttribute.From"), giftCardSenderName))); } else { result.Append(string.Format(_localizationService.GetResource("GiftCardAttribute.For"), giftCardRecipientName)); //result.Append(string.Format(_localizationService.GetResource("GiftCardAttribute.ForEmail"), giftCardRecipientEmail)); result.Append(serapator); result.Append(string.Format(_localizationService.GetResource("GiftCardAttribute.From"), giftCardSenderName)); } } } return(result.ToString()); }
/// <summary> /// Gets discount amount /// </summary> /// <param name="productVariant">Product variant</param> /// <returns>Discount amount</returns> public virtual decimal GetDiscountAmount(ProductVariant productVariant, bool showHiddenDiscounts = true) { var customer = _workContext.CurrentCustomer; return(GetDiscountAmount(productVariant, customer, decimal.Zero, showHiddenDiscounts)); }
/// <summary> /// Converts kit product assoications into order line items for a basket that is /// being finalized. /// </summary> /// <param name="basket">The basket checking out</param> /// <param name="order">The order being created</param> /// <param name="idLookup">A translation table to map basket ids to order ids</param> internal static void GenerateKitProducts(Basket basket, Order order, Dictionary <string, int> idLookup) { foreach (BasketItem basketItem in basket.Items) { if (basketItem.OrderItemType == OrderItemType.Product) { int[] kitProductIds = AlwaysConvert.ToIntArray(basketItem.KitList); if (kitProductIds != null && kitProductIds.Length > 0) { //keep track of the price/weight of the master line item //decrement these values for each line item registered LSDecimal masterPrice = basketItem.Price; LSDecimal masterWeight = basketItem.Weight; foreach (int kitProductId in kitProductIds) { // WE ONLY NEED TO GENERATE RECORDS FOR THE HIDDEN ITEMS // VISIBLE KIT MBMER PRODUCTS ARE GENERATED DURING THE BASKET RECALCULATION KitProduct kp = KitProductDataSource.Load(kitProductId); if (kp.KitComponent.InputType == KitInputType.IncludedHidden) { Product p = kp.Product; ProductVariant pv = kp.ProductVariant; OrderItem item = new OrderItem(); item.OrderId = order.OrderId; // SET THE PARENT ITEM ID FOR THIS ITEM if (idLookup.ContainsKey("I" + basketItem.BasketItemId)) { item.ParentItemId = idLookup["I" + basketItem.BasketItemId]; } item.OrderItemType = OrderItemType.Product; if (idLookup.ContainsKey("S" + basketItem.BasketShipmentId)) { item.OrderShipmentId = idLookup["S" + basketItem.BasketShipmentId]; } if (idLookup.ContainsKey("I" + basketItem.BasketItemId)) { item.ParentItemId = idLookup["I" + basketItem.BasketItemId]; } item.ProductId = kp.ProductId; item.Name = kp.DisplayName; item.OptionList = kp.OptionList; if (pv != null) { item.VariantName = pv.VariantName; item.Sku = pv.Sku; } else { item.Sku = p.Sku; } item.Quantity = (short)(kp.Quantity * basketItem.Quantity); item.TaxCodeId = p.TaxCodeId; //THE CALCULATED PRICE IS FOR ALL ITEMS (EXT PRICE) //TO GET A LINE ITEM PRICE WE MUST DIVIDE BY QUANTITY item.Price = kp.CalculatedPrice / kp.Quantity; item.Weight = kp.CalculatedWeight / kp.Quantity; item.CostOfGoods = p.CostOfGoods; item.WishlistItemId = basketItem.WishlistItemId; item.WrapStyleId = basketItem.WrapStyleId; item.IsHidden = (kp.KitComponent.InputType == KitInputType.IncludedHidden); //USE PARENT SHIPPABLE STATUS FOR HIDDEN KITTED PRODUCTS item.Shippable = basketItem.Shippable; item.Save(); order.Items.Add(item); masterPrice -= kp.CalculatedPrice; masterWeight -= kp.CalculatedWeight; } } //UPDATE THE PRICE OF THE KIT LINE ITEM (BASE PRICE OF PRODUCT LESS KIT PARTS) if (idLookup.ContainsKey("I" + basketItem.BasketItemId)) { int index = order.Items.IndexOf(idLookup["I" + basketItem.BasketItemId]); if (index > -1) { order.Items[index].Price = masterPrice; order.Items[index].Weight = masterWeight; order.Items[index].Save(); } } } } } }
/// <summary> /// Creates a Product without saving it to the database /// </summary> /// <param name="name"> /// The name. /// </param> /// <param name="sku"> /// The SKU. /// </param> /// <param name="price"> /// The price. /// </param> /// <returns> /// The <see cref="IProduct"/>. /// </returns> public IProduct CreateProduct(string name, string sku, decimal price) { var templateVariant = new ProductVariant(name, sku, price); var product = new Product(templateVariant); if (Creating.IsRaisedEventCancelled(new Events.NewEventArgs<IProduct>(product), this)) { product.WasCancelled = true; return product; } Created.RaiseEvent(new Events.NewEventArgs<IProduct>(product), this); return product; }
public RegistrationsVariantVm(ProductVariant variant) { this.ProductVariantId = variant.ProductVariantId; this.Name = variant.Name; }
/// <summary> /// Generates variants asynchronous. /// </summary> /// <param name="parameter">AsyncControl parameters</param> private void GenerateAndSave(object parameter) { try { // Regenerate already existing variants if (mRegenerateVariants) { ProductAttributeSet productAttributeSet = new ProductAttributeSet(CategorySelector.SelectedCategories.Values.Where(x => x > VariantOptionInfo.NewOption)); List<ProductVariant> existingVariants = VariantHelper.AddNewCategoriesToVariantsOfProduct(ProductID, productAttributeSet); // Use special action contexts to turn off unnecessary actions using (ECommerceActionContext eCommerceContext = new ECommerceActionContext()) { eCommerceContext.TouchParent = false; eCommerceContext.SetLowestPriceToParent = false; eCommerceContext.AssignDefaultTaxesToProducts = false; existingVariants.ForEach(pVariant => { AddLog(HTMLHelper.HTMLEncode(ResHelper.LocalizeString(pVariant.Variant.SKUName)) + GetString("com.variants.isredefined")); VariantHelper.SetProductVariant(pVariant); }); } // Save variant to update parent SKULastModified a SKUPrice properties var lastVariant = existingVariants.LastOrDefault(); if (lastVariant != null) { lastVariant.Variant.Generalized.SetObject(); } } // Generate non-existing variants ProductVariant productVariant = null; // Use special action contexts to turn off unnecessary actions using (ECommerceActionContext eCommerceContext = new ECommerceActionContext()) { eCommerceContext.TouchParent = false; eCommerceContext.SetLowestPriceToParent = false; eCommerceContext.AssignDefaultTaxesToProducts = false; foreach (DataRow row in mVariantsToGenerate) { IEnumerable<int> options = GetAllOptions(row, NewCategories.Union(ExistingCategories)); productVariant = new ProductVariant(ProductID, new ProductAttributeSet(options)); AddLog(HTMLHelper.HTMLEncode(ResHelper.LocalizeString(productVariant.Variant.SKUName)) + GetString("com.variants.isdefined")); productVariant.Set(); } } // Save variant to update parent SKULastModified a SKUPrice properties if (productVariant != null) { productVariant.Variant.Generalized.SetObject(); } } catch (Exception ex) { CurrentError = GetString("com.variant.definerror"); EventLogProvider.LogException("Variant definition", "DEFINEVARIANT", ex); } }
public static RegistrationsVariantVm Create(ProductVariant variant) => variant == null ? null : new RegistrationsVariantVm(variant);
/// <summary> /// Formats attributes /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="attributes">Attributes</param> /// <returns>Attributes</returns> public static string FormatAttributes(ProductVariant productVariant, string attributes) { var customer = NopContext.Current.User; return FormatAttributes(productVariant, attributes, customer, "<br />"); }
public void Unpublish(ProductVariant variant) { }
/// <summary> /// Formats attributes /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="attributes">Attributes</param> /// <param name="customer">Customer</param> /// <param name="serapator">Serapator</param> /// <param name="htmlEncode">A value indicating whether to encode (HTML) values</param> /// <param name="renderPrices">A value indicating whether to render prices</param> /// <returns>Attributes</returns> public static string FormatAttributes(ProductVariant productVariant, string attributes, Customer customer, string serapator, bool htmlEncode, bool renderPrices) { return FormatAttributes(productVariant, attributes, customer, serapator, htmlEncode, renderPrices, true, true); }
public static ProductVariantModel ToModel(this ProductVariant entity) { return(Mapper.Map <ProductVariant, ProductVariantModel>(entity)); }
public CannotOrderQuantity(ProductVariant variant, int stockRemaining) { _variant = variant; _stockRemaining = stockRemaining; }
public static ProductVariant ToEntity(this ProductVariantModel model, ProductVariant destination) { return(Mapper.Map(model, destination)); }
public List <SelectListItem> Get(ProductVariant productVariant) { return(_shippingMethodAdminService.GetAll() .BuildSelectItemList(info => info.Name, info => info.Type, info => productVariant.RestrictedTo.Contains(info.Type), emptyItem: null)); }
/// <summary> /// Generates variants asynchronous. /// </summary> /// <param name="parameter">AsyncControl parameters</param> private void GenerateAndSave(object parameter) { try { // Regenerate already existing variants if (mRegenerateVariants) { ProductAttributeSet productAttributeSet = new ProductAttributeSet(CategorySelector.SelectedCategories.Values.Where(x => x > VariantOptionInfo.NewOption)); List <ProductVariant> existingVariants = VariantHelper.AddNewCategoriesToVariantsOfProduct(ProductID, productAttributeSet); // Use special action contexts to turn off unnecessary actions using (ECommerceActionContext eCommerceContext = new ECommerceActionContext()) { eCommerceContext.TouchParent = false; eCommerceContext.SetLowestPriceToParent = false; existingVariants.ForEach(pVariant => { AddLog(HTMLHelper.HTMLEncode(ResHelper.LocalizeString(pVariant.Variant.SKUName)) + GetString("com.variants.isredefined")); VariantHelper.SetProductVariant(pVariant); }); } // Save variant to update parent SKULastModified a SKUPrice properties var lastVariant = existingVariants.LastOrDefault(); if (lastVariant != null) { lastVariant.Variant.Generalized.SetObject(); } } // Generate non-existing variants ProductVariant productVariant = null; // Use special action contexts to turn off unnecessary actions using (ECommerceActionContext eCommerceContext = new ECommerceActionContext()) { eCommerceContext.TouchParent = false; eCommerceContext.SetLowestPriceToParent = false; foreach (DataRow row in mVariantsToGenerate) { IEnumerable <int> options = GetAllOptions(row, NewCategories.Union(ExistingCategories)); productVariant = new ProductVariant(ProductID, new ProductAttributeSet(options)); AddLog(HTMLHelper.HTMLEncode(ResHelper.LocalizeString(productVariant.Variant.SKUName)) + GetString("com.variants.isdefined")); productVariant.Set(); } } // Save variant to update parent SKULastModified a SKUPrice properties if (productVariant != null) { productVariant.Variant.Generalized.SetObject(); } } catch (Exception ex) { CurrentError = GetString("com.variant.definerror"); Service.Resolve <IEventLogService>().LogException("Variant definition", "DEFINEVARIANT", ex); } }