Attribute Out of stock Notification

6 months ago
I’ve been using NopCommerce now for around 2 years and I’m really happy with the way it works, how stable it is and the amount of functionality it offers to us and our clients.

We love it!!!

I’ve started to dive into the source and try and solve some of the wishes of our clients and 1 of the wishes is/was to have product attributes (size for example) to display an ‘Out of stock’ notification (and disable the item) in the dropdown, for example:

Small
Medium (out of stock)
Large
Extra large

After many hours/days of searching I think I’ve found the solutions and would like to share this with you all so that you to can use (and improve on it) for your site.
This solution was done using the NopCommerce 4.2 source code.

Please, if there is a better solution or improvements please contribute to this solution to help others!
There are only 2 files in the source that need to be changed and only 1 view file:

The first file you need to change is the ‘ProductDetailsModel.cs’, found here: ‘\Nop.Web\Models\Catalog\’

Add the following line to the code:

public string Name { get; set; }
public int StockQuantity { get; set; }
public string ColorSquaresRgb { get; set; }


This variable (‘StockQuantity’) will be used in the view file so that you can disable and/or display an ‘Out of stock’ notification message next to the attribute.

The next thing is to edit the ‘ProductModelFactory.cs’ file found here: ‘\Nop.Web\Factories\’
Add the following line of code, you should find the code around line 765

var valueModel = new ProductDetailsModel.ProductAttributeValueModel
{
    Id = attributeValue.Id,
    Name = _localizationService.GetLocalized(attributeValue, x => x.Name),
    StockQuantity = GetAttributeStock(product, attributeValue.Id),//Added
    ColorSquaresRgb = attributeValue.ColorSquaresRgb,
    IsPreSelected = attributeValue.IsPreSelected,
    CustomerEntersQty = attributeValue.CustomerEntersQty,
    Quantity = attributeValue.Quantity
};


Now add the following function to retrieve the StockQuantity of the attribute:

/// <summary>
        /// Get the product attribute stock value
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="attributeId">Attribute Id</param>
        /// <returns>STock Quantity value</returns>
        private int GetAttributeStock(Product product, int attributeId) {
            var allAttributesXml = _productAttributeParser.GenerateAllCombinations(product, true);
            var stockVal = -1;

            foreach (var attributesXml in allAttributesXml)
            {
                var combination = _productAttributeParser.FindProductAttributeCombination(product, attributesXml);
                if (combination != null)
                {
                    try {
                        var xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(attributesXml);
                       var attrIdNode =  (XmlElement)xmlDoc.SelectSingleNode(@"//Attributes/ProductAttribute/ProductAttributeValue/Value");
                       var attrId = int.Parse(attrIdNode.InnerText);

                        if (attrId == attributeId)
                            stockVal = combination.StockQuantity;
                      
                    } catch { }                
                    
                }
            }
            return stockVal;
        }

Now that you have the attribute stock quantity you can now use this in the ‘_ProductAttributes.chtml’, found here: ‘/Nop.Web/Views/Product/’

For an example I added some extra functionality for the dropdown:

case AttributeControlType.DropdownList:
                            {
                    <select name="@(controlId)" id="@(controlId)" @(attribute.Values.Any(value => value.CustomerEntersQty) ? Html.Raw($"onchange=\"showHideDropdownQuantity('{controlId}')\"") : null)>
                        @if (!attribute.IsRequired)
                        {
                            <option value="0">--- </option>
                        }
                        @foreach (var attributeValue in attribute.Values)
                        {
                            //Changed attribute stock notification
                            var isDisabled = false;
                            var isInStockNotification = string.Empty;

                            if (@attributeValue.StockQuantity == 0)
                            {
                                isDisabled = true;
                                isInStockNotification = “(Out of Stock)”;
                            }
                            //Changed attribute stock notification
                            var attributeName = string.IsNullOrEmpty(attributeValue.PriceAdjustment) ?
                                attributeValue.Name :
                                T("Products.ProductAttributes.PriceAdjustment", attributeValue.Name, attributeValue.PriceAdjustment,
                                    attributeValue.CustomerEntersQty ? T("Products.ProductAttributes.PriceAdjustment.PerItem").Text : string.Empty).Text;
                            <!-- Changed attribute stock notification -->
                            <option disabled="@isDisabled" selected="@attributeValue.IsPreSelected" value="@attributeValue.Id">@attributeName @isInStockNotification</option>
                            <!-- Changed attribute stock notification -->
                        }
                    </select>


Enjoy and hope this helps others!
Geoff
1 week ago
We need to apply the same update with our Online store. we are using the nopcommerce 4.3  and Visual studio 2017 and applied the same changes in the mentioned files as explained in your post. there were build errors. it prompts for the StockQuantity Variable as undefined . i need to add reference or directive .  i have  added the variables , functions and changes as mentioned in the POST  but unfortunately could not get the result .

Your support would be appreciated .

Kind Regards

Saqiba Sulman
Project Manager
Media Phone Plus