/// <summary>
        /// Gets SKU, Manufacturer part number and GTIN
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="attributesXml">Attributes in XML format</param>
        /// <param name="productAttributeParser">Product attribute service (used when attributes are specified)</param>
        /// <param name="sku">SKU</param>
        /// <param name="manufacturerPartNumber">Manufacturer part number</param>
        /// <param name="gtin">GTIN</param>
        private static void GetSkuMpnGtin(this Product product, string attributesXml, IProductAttributeParser productAttributeParser,
                                          out string sku, out string manufacturerPartNumber, out string gtin)
        {
            if (product == null)
            {
                throw new ArgumentNullException("product");
            }

            sku = null;
            manufacturerPartNumber = null;
            gtin = null;

            if (!String.IsNullOrEmpty(attributesXml) &&
                product.ManageInventoryMethod == ManageInventoryMethod.ManageStockByAttributes)
            {
                //manage stock by attribute combinations
                if (productAttributeParser == null)
                {
                    throw new ArgumentNullException("productAttributeParser");
                }

                //let's find appropriate record
                var combination = product
                                  .ProductAttributeCombinations
                                  .FirstOrDefault(x => productAttributeParser.AreProductAttributesEqual(x.AttributesXml, attributesXml));
                if (combination != null)
                {
                    sku = combination.Sku;
                    manufacturerPartNumber = combination.ManufacturerPartNumber;
                    gtin = combination.Gtin;
                }
            }

            if (String.IsNullOrEmpty(sku))
            {
                sku = product.Sku;
            }
            if (String.IsNullOrEmpty(manufacturerPartNumber))
            {
                manufacturerPartNumber = product.ManufacturerPartNumber;
            }
            if (String.IsNullOrEmpty(gtin))
            {
                gtin = product.Gtin;
            }
        }
		public static ProductVariantAttributeCombination MergeWithCombination(this Product product, string selectedAttributes, IProductAttributeParser productAttributeParser)
        {
            Guard.ArgumentNotNull(productAttributeParser, "productAttributeParser");

			if (selectedAttributes.IsNullOrEmpty())
				return null;

            // let's find appropriate record
			var combination = product
                .ProductVariantAttributeCombinations
                .Where(x => x.IsActive == true)
                .FirstOrDefault(x => productAttributeParser.AreProductAttributesEqual(x.AttributesXml, selectedAttributes));

            if (combination != null)
            {
				product.MergeWithCombination(combination);
            }
			return combination;
        }
示例#3
0
        public static ProductVariantAttributeCombination MergeWithCombination(this Product product, string selectedAttributes, IProductAttributeParser productAttributeParser)
        {
            Guard.ArgumentNotNull(productAttributeParser, "productAttributeParser");

            if (selectedAttributes.IsNullOrEmpty())
            {
                return(null);
            }

            // let's find appropriate record
            var combination = product
                              .ProductVariantAttributeCombinations
                              .Where(x => x.IsActive == true)
                              .FirstOrDefault(x => productAttributeParser.AreProductAttributesEqual(x.AttributesXml, selectedAttributes));

            if (combination != null)
            {
                product.MergeWithCombination(combination);
            }
            return(combination);
        }
        protected virtual decimal GetPreselectedPrice(Product product, PriceCalculationContext context, ProductBundleItemData bundleItem, IEnumerable <ProductBundleItemData> bundleItems)
        {
            var taxRate = decimal.Zero;
            var attributesTotalPriceBase       = decimal.Zero;
            var preSelectedPriceAdjustmentBase = decimal.Zero;
            var isBundle            = (product.ProductType == ProductType.BundledProduct);
            var isBundleItemPricing = (bundleItem != null && bundleItem.Item.BundleProduct.BundlePerItemPricing);
            var isBundlePricing     = (bundleItem != null && !bundleItem.Item.BundleProduct.BundlePerItemPricing);
            var bundleItemId        = (bundleItem == null ? 0 : bundleItem.Item.Id);

            var selectedAttributes      = new NameValueCollection();
            var selectedAttributeValues = new List <ProductVariantAttributeValue>();
            var attributes = context.Attributes.Load(product.Id);

            // 1. fill selectedAttributes with initially selected attributes
            foreach (var attribute in attributes.Where(x => x.ProductVariantAttributeValues.Count > 0 && x.ShouldHaveValues()))
            {
                int preSelectedValueId = 0;
                ProductVariantAttributeValue defaultValue = null;
                var selectedValueIds = new List <int>();
                var pvaValues        = attribute.ProductVariantAttributeValues;

                foreach (var pvaValue in pvaValues)
                {
                    ProductBundleItemAttributeFilter attributeFilter = null;

                    if (bundleItem.FilterOut(pvaValue, out attributeFilter))
                    {
                        continue;
                    }

                    if (preSelectedValueId == 0 && attributeFilter != null && attributeFilter.IsPreSelected)
                    {
                        preSelectedValueId = attributeFilter.AttributeValueId;
                    }

                    if (!isBundlePricing && pvaValue.IsPreSelected)
                    {
                        decimal attributeValuePriceAdjustment = GetProductVariantAttributeValuePriceAdjustment(pvaValue);
                        decimal priceAdjustmentBase           = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, out taxRate);

                        preSelectedPriceAdjustmentBase = decimal.Add(preSelectedPriceAdjustmentBase, priceAdjustmentBase);
                    }
                }

                // value pre-selected by a bundle item filter discards the default pre-selection
                if (preSelectedValueId != 0 && (defaultValue = pvaValues.FirstOrDefault(x => x.Id == preSelectedValueId)) != null)
                {
                    //defaultValue.IsPreSelected = true;
                    selectedAttributeValues.Add(defaultValue);
                    selectedAttributes.AddProductAttribute(attribute.ProductAttributeId, attribute.Id, defaultValue.Id, product.Id, bundleItemId);
                }
                else
                {
                    foreach (var value in pvaValues.Where(x => x.IsPreSelected))
                    {
                        selectedAttributeValues.Add(value);
                        selectedAttributes.AddProductAttribute(attribute.ProductAttributeId, attribute.Id, value.Id, product.Id, bundleItemId);
                    }
                }
            }

            // 2. find attribute combination for selected attributes and merge it
            if (!isBundle && selectedAttributes.Count > 0)
            {
                var attributeXml = selectedAttributes.CreateSelectedAttributesXml(product.Id, attributes, _productAttributeParser, _services.Localization,
                                                                                  _downloadService, _catalogSettings, _httpRequestBase, new List <string>(), true, bundleItemId);

                var combinations = context.AttributeCombinations.Load(product.Id);

                var selectedCombination = combinations.FirstOrDefault(x => _productAttributeParser.AreProductAttributesEqual(x.AttributesXml, attributeXml));

                if (selectedCombination != null && selectedCombination.IsActive && selectedCombination.Price.HasValue)
                {
                    product.MergedDataValues = new Dictionary <string, object> {
                        { "Price", selectedCombination.Price.Value }
                    };
                }
            }

            if (_catalogSettings.EnableDynamicPriceUpdate && !isBundlePricing)
            {
                if (selectedAttributeValues.Count > 0)
                {
                    selectedAttributeValues.Each(x => attributesTotalPriceBase += GetProductVariantAttributeValuePriceAdjustment(x));
                }
                else
                {
                    attributesTotalPriceBase = preSelectedPriceAdjustmentBase;
                }
            }

            if (bundleItem != null)
            {
                bundleItem.AdditionalCharge = attributesTotalPriceBase;
            }

            var result = GetFinalPrice(product, bundleItems, _services.WorkContext.CurrentCustomer, attributesTotalPriceBase, true, 1, bundleItem, context);

            return(result);
        }
        protected virtual decimal GetPreselectedPrice(Product product, ProductBundleItemData bundleItem, IList <ProductBundleItemData> bundleItems)
        {
            var taxRate = decimal.Zero;
            var attributesTotalPriceBase       = decimal.Zero;
            var preSelectedPriceAdjustmentBase = decimal.Zero;
            var isBundle            = (product.ProductType == ProductType.BundledProduct);
            var isBundleItemPricing = (bundleItem != null && bundleItem.Item.BundleProduct.BundlePerItemPricing);
            var isBundlePricing     = (bundleItem != null && !bundleItem.Item.BundleProduct.BundlePerItemPricing);
            var bundleItemId        = (bundleItem == null ? 0 : bundleItem.Item.Id);
            var attributes          = (isBundle ? new List <ProductVariantAttribute>() : _productAttributeService.GetProductVariantAttributesByProductId(product.Id));
            var selectedAttributes  = new NameValueCollection();
            List <ProductVariantAttributeValue> selectedAttributeValues = null;

            foreach (var attribute in attributes)
            {
                int preSelectedValueId = 0;
                ProductVariantAttributeValue defaultValue = null;

                if (attribute.ShouldHaveValues())
                {
                    var pvaValues = _productAttributeService.GetProductVariantAttributeValues(attribute.Id);
                    if (pvaValues.Count == 0)
                    {
                        continue;
                    }

                    foreach (var pvaValue in pvaValues)
                    {
                        ProductBundleItemAttributeFilter attributeFilter = null;

                        if (bundleItem.FilterOut(pvaValue, out attributeFilter))
                        {
                            continue;
                        }

                        if (preSelectedValueId == 0 && attributeFilter != null && attributeFilter.IsPreSelected)
                        {
                            preSelectedValueId = attributeFilter.AttributeValueId;
                        }

                        if (!isBundlePricing && pvaValue.IsPreSelected)
                        {
                            decimal attributeValuePriceAdjustment = GetProductVariantAttributeValuePriceAdjustment(pvaValue);
                            decimal priceAdjustmentBase           = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, out taxRate);

                            preSelectedPriceAdjustmentBase = decimal.Add(preSelectedPriceAdjustmentBase, priceAdjustmentBase);
                        }
                    }

                    // value pre-selected by a bundle item filter discards the default pre-selection
                    if (preSelectedValueId != 0 && (defaultValue = pvaValues.FirstOrDefault(x => x.Id == preSelectedValueId)) != null)
                    {
                        defaultValue.IsPreSelected = true;
                    }

                    if (defaultValue == null)
                    {
                        defaultValue = pvaValues.FirstOrDefault(x => x.IsPreSelected);
                    }

                    if (defaultValue == null && attribute.IsRequired)
                    {
                        defaultValue = pvaValues.First();
                    }

                    if (defaultValue != null)
                    {
                        selectedAttributes.AddProductAttribute(attribute.ProductAttributeId, attribute.Id, defaultValue.Id, product.Id, bundleItemId);
                    }
                }
            }

            if (!isBundle && selectedAttributes.Count > 0)
            {
                string attributeXml = selectedAttributes.CreateSelectedAttributesXml(product.Id, attributes, _productAttributeParser, _commonServices.Localization,
                                                                                     _downloadService, _catalogSettings, _httpRequestBase, new List <string>(), true, bundleItemId);

                selectedAttributeValues = _productAttributeParser.ParseProductVariantAttributeValues(attributeXml).ToList();

                var combinations = _productAttributeService.GetAllProductVariantAttributeCombinations(product.Id);

                var selectedCombination = combinations.FirstOrDefault(x => _productAttributeParser.AreProductAttributesEqual(x.AttributesXml, attributeXml));

                if (selectedCombination != null && selectedCombination.IsActive)
                {
                    product.MergeWithCombination(selectedCombination);
                }
            }

            if (_catalogSettings.EnableDynamicPriceUpdate && !isBundlePricing)
            {
                if (selectedAttributeValues != null)
                {
                    selectedAttributeValues.Each(x => attributesTotalPriceBase += GetProductVariantAttributeValuePriceAdjustment(x));
                }
                else
                {
                    attributesTotalPriceBase = preSelectedPriceAdjustmentBase;
                }
            }

            if (bundleItem != null)
            {
                bundleItem.AdditionalCharge = attributesTotalPriceBase;
            }

            var result = GetFinalPrice(product, bundleItems, _commonServices.WorkContext.CurrentUser, attributesTotalPriceBase, true, 1, bundleItem);

            return(result);
        }
        /// <summary>
        /// Gets SKU, Manufacturer part number and GTIN
        /// </summary>
        /// <param name="productVariant">Product variant</param>
        /// <param name="selectedAttributes">Selected attributes (XML format)</param>
        /// <param name="productAttributeParser">Product attribute service (used when attributes are specified)</param>
        /// <param name="sku">SKU</param>
        /// <param name="manufacturerPartNumber">Manufacturer part number</param>
        /// <param name="gtin">GTIN</param>
        private static void GetSkuMpnGtin(this ProductVariant productVariant, string selectedAttributes, IProductAttributeParser productAttributeParser,
            out string sku, out string manufacturerPartNumber, out string gtin)
        {
            if (productVariant == null)
                throw new ArgumentNullException("productVariant");

            sku = null;
            manufacturerPartNumber = null;
            gtin = null;

            if (productVariant.ManageInventoryMethod == ManageInventoryMethod.ManageStockByAttributes)
            {
                //manage stock by attribute combinations
                if (productAttributeParser == null)
                    throw new ArgumentNullException("productAttributeParser");

                //let's find appropriate record
                var combination = productVariant
                    .ProductVariantAttributeCombinations
                    .FirstOrDefault(x => productAttributeParser.AreProductAttributesEqual(x.AttributesXml, selectedAttributes));
                if (combination != null)
                {
                    sku = combination.Sku;
                    manufacturerPartNumber = combination.ManufacturerPartNumber;
                    gtin = combination.Gtin;
                }
            }

            if (String.IsNullOrEmpty(sku))
                sku = productVariant.Sku;
            if (String.IsNullOrEmpty(manufacturerPartNumber))
                manufacturerPartNumber = productVariant.ManufacturerPartNumber;
            if (String.IsNullOrEmpty(gtin))
                gtin = productVariant.Gtin;
        }
示例#7
0
        protected virtual decimal GetPreselectedPrice(
            Product product,
            Customer customer,
            Currency currency,
            PriceCalculationContext context,
            ProductBundleItemData bundleItem,
            IEnumerable <ProductBundleItemData> bundleItems)
        {
            var taxRate = decimal.Zero;
            var attributesTotalPriceBase       = decimal.Zero;
            var preSelectedPriceAdjustmentBase = decimal.Zero;
            var isBundle            = product.ProductType == ProductType.BundledProduct;
            var isBundleItemPricing = bundleItem != null && bundleItem.Item.BundleProduct.BundlePerItemPricing;
            var isBundlePricing     = bundleItem != null && !bundleItem.Item.BundleProduct.BundlePerItemPricing;
            var bundleItemId        = bundleItem == null ? 0 : bundleItem.Item.Id;

            var query = new ProductVariantQuery();
            var selectedAttributeValues = new List <ProductVariantAttributeValue>();
            var attributes = context.Attributes.GetOrLoad(product.Id);

            // 1. Fill query with initially selected attributes.
            foreach (var attribute in attributes.Where(x => x.ProductVariantAttributeValues.Any() && x.ShouldHaveValues()))
            {
                int preSelectedValueId = 0;
                ProductVariantAttributeValue defaultValue = null;
                var selectedValueIds = new List <int>();
                var pvaValues        = attribute.ProductVariantAttributeValues;

                foreach (var pvaValue in pvaValues)
                {
                    ProductBundleItemAttributeFilter attributeFilter = null;

                    if (bundleItem?.Item?.FilterOut(pvaValue, out attributeFilter) ?? false)
                    {
                        continue;
                    }

                    if (preSelectedValueId == 0 && attributeFilter != null && attributeFilter.IsPreSelected)
                    {
                        preSelectedValueId = attributeFilter.AttributeValueId;
                    }

                    if (!isBundlePricing && pvaValue.IsPreSelected)
                    {
                        var includingTax = _services.WorkContext.TaxDisplayType == TaxDisplayType.IncludingTax;
                        var attributeValuePriceAdjustment = GetProductVariantAttributeValuePriceAdjustment(pvaValue, product, customer, context, 1);
                        var priceAdjustmentBase           = _taxService.GetProductPrice(product, product.TaxCategoryId, attributeValuePriceAdjustment,
                                                                                        includingTax, customer, currency, _taxSettings.PricesIncludeTax, out taxRate);

                        preSelectedPriceAdjustmentBase = decimal.Add(preSelectedPriceAdjustmentBase, priceAdjustmentBase);
                    }
                }

                // Value pre-selected by a bundle item filter discards the default pre-selection.
                if (preSelectedValueId != 0 && (defaultValue = pvaValues.FirstOrDefault(x => x.Id == preSelectedValueId)) != null)
                {
                    //defaultValue.IsPreSelected = true;
                    selectedAttributeValues.Add(defaultValue);
                    query.AddVariant(new ProductVariantQueryItem(defaultValue.Id.ToString())
                    {
                        ProductId          = product.Id,
                        BundleItemId       = bundleItemId,
                        AttributeId        = attribute.ProductAttributeId,
                        VariantAttributeId = attribute.Id,
                        Alias      = attribute.ProductAttribute.Alias,
                        ValueAlias = defaultValue.Alias
                    });
                }
                else
                {
                    foreach (var value in pvaValues.Where(x => x.IsPreSelected))
                    {
                        selectedAttributeValues.Add(value);
                        query.AddVariant(new ProductVariantQueryItem(value.Id.ToString())
                        {
                            ProductId          = product.Id,
                            BundleItemId       = bundleItemId,
                            AttributeId        = attribute.ProductAttributeId,
                            VariantAttributeId = attribute.Id,
                            Alias      = attribute.ProductAttribute.Alias,
                            ValueAlias = value.Alias
                        });
                    }
                }
            }

            // 2. Find attribute combination for selected attributes and merge it.
            if (!isBundle && query.Variants.Any())
            {
                var attributeXml = query.CreateSelectedAttributesXml(product.Id, bundleItemId, attributes, _productAttributeParser, _services.Localization,
                                                                     _downloadService, _catalogSettings, _httpRequestBase, new List <string>());

                var combinations = context.AttributeCombinations.GetOrLoad(product.Id);

                var selectedCombination = combinations.FirstOrDefault(x => _productAttributeParser.AreProductAttributesEqual(x.AttributesXml, attributeXml));

                if (selectedCombination != null && selectedCombination.IsActive && selectedCombination.Price.HasValue)
                {
                    product.MergedDataValues = new Dictionary <string, object> {
                        { "Price", selectedCombination.Price.Value }
                    };

                    if (selectedCombination.BasePriceAmount.HasValue)
                    {
                        product.MergedDataValues.Add("BasePriceAmount", selectedCombination.BasePriceAmount.Value);
                    }

                    if (selectedCombination.BasePriceBaseAmount.HasValue)
                    {
                        product.MergedDataValues.Add("BasePriceBaseAmount", selectedCombination.BasePriceBaseAmount.Value);
                    }
                }
            }

            if (_catalogSettings.EnableDynamicPriceUpdate && !isBundlePricing)
            {
                if (selectedAttributeValues.Count > 0)
                {
                    selectedAttributeValues.Each(x => attributesTotalPriceBase += GetProductVariantAttributeValuePriceAdjustment(x, product, customer, context, 1));
                }
                else
                {
                    attributesTotalPriceBase = preSelectedPriceAdjustmentBase;
                }
            }

            if (bundleItem != null)
            {
                bundleItem.AdditionalCharge = attributesTotalPriceBase;
            }

            var result = GetFinalPrice(product, bundleItems, customer, attributesTotalPriceBase, true, 1, bundleItem, context);

            return(result);
        }
示例#8
0
        /// <summary>
        /// Validates a product variant for standard properties
        /// </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>
        /// <returns>Warnings</returns>
        public virtual IList <string> GetStandardWarnings(Customer customer, ShoppingCartType shoppingCartType,
                                                          ProductVariant productVariant, string selectedAttributes, decimal customerEnteredPrice,
                                                          int quantity)
        {
            if (customer == null)
            {
                throw new ArgumentNullException("customer");
            }

            if (productVariant == null)
            {
                throw new ArgumentNullException("productVariant");
            }

            var warnings = new List <string>();

            var product = productVariant.Product;

            if (product == null)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CannotLoadProduct"), productVariant.ProductId));
                return(warnings);
            }

            //deleted?
            if (product.Deleted || productVariant.Deleted)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.ProductDeleted"));
                return(warnings);
            }

            //published?
            if (!product.Published || !productVariant.Published)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished"));
            }

            //ACL
            if (!_aclService.Authorize(product, customer))
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished"));
            }

            //disabled "add to cart" button
            if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.DisableBuyButton)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.BuyingDisabled"));
            }

            //disabled "add to wishlist" button
            if (shoppingCartType == ShoppingCartType.Wishlist && productVariant.DisableWishlistButton)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.WishlistDisabled"));
            }

            //call for price
            if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.CallForPrice)
            {
                warnings.Add(_localizationService.GetResource("Products.CallForPrice"));
            }

            //customer entered price
            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)));
                }
            }

            //quantity validation
            var hasQtyWarnings = false;

            if (quantity < productVariant.OrderMinimumQuantity)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MinimumQuantity"), productVariant.OrderMinimumQuantity));
                hasQtyWarnings = true;
            }
            if (quantity > productVariant.OrderMaximumQuantity)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumQuantity"), productVariant.OrderMaximumQuantity));
                hasQtyWarnings = true;
            }
            var allowedQuantities = productVariant.ParseAllowedQuatities();

            if (allowedQuantities.Length > 0 && !allowedQuantities.Contains(quantity))
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.AllowedQuantities"), string.Join(", ", allowedQuantities)));
            }

            var validateOutOfStock = shoppingCartType == ShoppingCartType.ShoppingCart || !_shoppingCartSettings.AllowOutOfStockItemsToBeAddedToWishlist;

            if (validateOutOfStock && !hasQtyWarnings)
            {
                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 combination = productVariant
                                      .ProductVariantAttributeCombinations
                                      .FirstOrDefault(x => _productAttributeParser.AreProductAttributesEqual(x.AttributesXml, selectedAttributes));
                    if (combination != null &&
                        !combination.AllowOutOfStockOrders &&
                        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"));
                }
            }
            return(warnings);
        }
示例#9
0
        /// <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>();

            var product = productVariant.Product;

            if (product == null)
            {
                warnings.Add(string.Format("Product (Id={0}) can not be loaded", productVariant.ProductId));
                return(warnings);
            }

            if (product.Deleted || productVariant.Deleted)
            {
                warnings.Add("Product is deleted");
                return(warnings);
            }

            if (!product.Published || !productVariant.Published)
            {
                warnings.Add("Product is not published");
            }

            if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.DisableBuyButton)
            {
                warnings.Add("Buying is disabled for this product");
            }

            if (shoppingCartType == ShoppingCartType.Wishlist && productVariant.DisableWishlistButton)
            {
                warnings.Add("Wishlist is disabled for this product");
            }

            if (shoppingCartType == ShoppingCartType.ShoppingCart &&
                productVariant.CallForPrice)
            {
                warnings.Add(_localizationService.GetResource("Products.CallForPrice"));
            }

            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("Product is not available");
                    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("Product is not available");
                }
            }

            //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);
        }
示例#10
0
        /// <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="product">Product</param>
        /// <param name="attributes">Attributes</param>
        /// <param name="customerEnteredPrice">Price entered by a customer</param>
        /// <param name="rentalStartDate">Rental start date</param>
        /// <param name="rentalEndDate">Rental end date</param>
        /// <returns>Found shopping cart item</returns>
        public virtual async Task <ShoppingCartItem> FindShoppingCartItem(IList <ShoppingCartItem> shoppingCart,
                                                                          ShoppingCartType shoppingCartType,
                                                                          string productId,
                                                                          string warehouseId = null,
                                                                          IList <CustomAttribute> attributes = null,
                                                                          decimal?customerEnteredPrice       = null,
                                                                          DateTime?rentalStartDate           = null,
                                                                          DateTime?rentalEndDate             = null)
        {
            if (shoppingCart == null)
            {
                throw new ArgumentNullException(nameof(shoppingCart));
            }

            foreach (var sci in shoppingCart.Where(a => a.ShoppingCartTypeId == shoppingCartType))
            {
                if (sci.ProductId == productId && sci.WarehouseId == warehouseId)
                {
                    //attributes
                    var _product = await _productService.GetProductById(sci.ProductId);

                    bool attributesEqual = _productAttributeParser.AreProductAttributesEqual(_product, sci.Attributes, attributes, false);
                    if (_product.ProductTypeId == ProductType.BundledProduct)
                    {
                        foreach (var bundle in _product.BundleProducts)
                        {
                            var p1 = await _productService.GetProductById(bundle.ProductId);

                            if (p1 != null)
                            {
                                if (!_productAttributeParser.AreProductAttributesEqual(p1, sci.Attributes, attributes, false))
                                {
                                    attributesEqual = false;
                                }
                            }
                        }
                    }
                    //gift vouchers
                    bool giftVoucherInfoSame = true;
                    if (_product.IsGiftVoucher)
                    {
                        _productAttributeParser.GetGiftVoucherAttribute(attributes,
                                                                        out var giftVoucherRecipientName1, out var giftVoucherRecipientEmail1,
                                                                        out var giftVoucherSenderName1, out var giftVoucherSenderEmail1, out var giftVoucherMessage1);

                        _productAttributeParser.GetGiftVoucherAttribute(sci.Attributes,
                                                                        out var giftVoucherRecipientName2, out var giftVoucherRecipientEmail2,
                                                                        out var giftVoucherSenderName2, out var giftVoucherSenderEmail2, out var giftVoucherMessage2);

                        if (giftVoucherRecipientName1.ToLowerInvariant() != giftVoucherRecipientName2.ToLowerInvariant() ||
                            giftVoucherSenderName1.ToLowerInvariant() != giftVoucherSenderName2.ToLowerInvariant())
                        {
                            giftVoucherInfoSame = false;
                        }
                    }

                    //price is the same (for products which require customers to enter a price)
                    bool customerEnteredPricesEqual = true;
                    if (sci.EnteredPrice.HasValue)
                    {
                        if (customerEnteredPrice.HasValue)
                        {
                            customerEnteredPricesEqual = Math.Round(sci.EnteredPrice.Value, 2) == Math.Round(customerEnteredPrice.Value, 2);
                        }
                        else
                        {
                            customerEnteredPricesEqual = false;
                        }
                    }
                    else
                    {
                        if (customerEnteredPrice.HasValue)
                        {
                            customerEnteredPricesEqual = false;
                        }
                    }

                    //found?
                    if (attributesEqual && giftVoucherInfoSame && customerEnteredPricesEqual)
                    {
                        return(sci);
                    }
                }
            }

            return(null);
        }