How to show OUT OF STOCK in dropdown (Product Attribute Value Combinations) 3.2

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
10 years ago
Hi everyone,

After two years using Nop, Im finally able to give something back to the community. This should definitely be on the next version. Also, I would like to point that I was able to this in the previous 2.5 version, but back then, I had no experience with MVC Razor or the application itself. I ended up making it work but I changed a TON of files and it was going to be a pain in the ass for others trying to implement it. Also, I could't upgrade because It will break my current customizations, so I finally decided to give it another try with 3.2 version. Well, this time, now with more experience I was able to do it with minor changes, only 4 files and much less code, and I accomplished the same result in a more elegant way. Without further a due, lets begin.

THE PROBLEM

Well, we all love the Attribute Values/Combinations in the system to keep track of Stock for each Product Variant Combination. This works great but the problem is that when the customer selects an item from the dropdown list that is out of stock, he gets the "out of stock" message after clicking on BUY NOW button. Not very elegant right? Imagine having 20 combinations and you only have 5 combinations in stock. The customer could get pissed off and think that you have NOTHING in your store at all.

Let's take the classic T-Shirt example for instance. We have in stock as follows (Color : Size : StockQuantity)
Black : S : 10
Black : M : 0
Black : L  : 15
White : S : 3
White : M : 10
White : L : 12

In the product page, we are going to see TWO dropdownlist's. One for Color and other for Size. Correct?
Wouldn't be nice that if the current selection is 'Black', on the Size dropdown, the options will be as follows:

S
M (out of stock)  <--- This option gets DISABLED
L

Then, if the customer selects 'White', the size dropdown will auto-populate with:

S (only 3 left)   <--- Amazon style
M
L

Well, this is exactly what I did. Wanna know how? Don't worry, it's easy. Let me show you how.

STEP 1. Database changes

We have to Add a boolean column to ProductVariantAttributeValue table. Execute this code:

ALTER TABLE ProductVariantAttributeValue
ADD IsMasterAttribute bit
GO

UPDATE ProductVariantAttributeValue --Set all records to 0
SET IsMasterAttribute=0
GO


This is the flag to tell us that the current Attribute is a Master (I couldn't think of a better name, sorry).
In our example, T-Shirt COLOR will be our master attributes. So, you will have to manually set as 1 the values Attributes of Black and White like this:

UPDATE ProductVariantAttributeValue
SET IsMasterAttribute=1
where id in (829,835)
GO



Ok great, this is all thats needed for db changes.



STEP 2.
Add

public bool IsMasterAttribute { get; set; } //VAS

to ProductVariantAttributevalue.cs in Core\Domain\Catalog

STEP 3.
Modify Nop.Web\Models\Catalog\ProductDetailsModel.cs and add this to the ProductVariantAttributeValueModel class
            public bool IsMasterAttribute { get; set; } //VAS
            public string AffectsObjectId { get; set; } //VAS
            public string CurrentObjectId { get; set; } //VAS
            public List<RenderCombinationModel> RenderCombinations { get; set; } //VAS
            public int GetStockQuantityById(int CombinationValue, List<RenderCombinationModel> Combinations)//VAS
            {
                foreach (RenderCombinationModel combination in Combinations)
                    if (combination.Value == CombinationValue)
                        return combination.Quantity;
                return 0; //this will happen when the are no combinations added to the variant
            }


Also, add a new class below to the same file.

        public partial class RenderCombinationModel : BaseNopEntityModel //VAS
        {
            public string Name { get; set; }
            public int Value { get; set; }
            public int Quantity { get; set; }
            public RenderCombinationModel(string Name, int Value, int Quantity)
            {
                this.Name = Name;
                this.Value = Value;
                this.Quantity = Quantity;
            }
        }




STEP 4.
Modify Nop.Web\Controllers\CatalogController.cs
In the PrepareProductDetailsPageModel method, add this code: (Line 871)

var pvaValueModel = new ProductDetailsModel.ProductVariantAttributeValueModel()
                        {
                            Id = pvaValue.Id,
                            Name = pvaValue.GetLocalized(x => x.Name),
                            ColorSquaresRgb = pvaValue.ColorSquaresRgb, //used with "Color squares" attribute type
                            IsPreSelected = pvaValue.IsPreSelected,
                            IsMasterAttribute = pvaValue.IsMasterAttribute
                        };
                        if (pvaValueModel.IsMasterAttribute)
                        {
                            pvaValueModel.RenderCombinations = new List<ProductDetailsModel.RenderCombinationModel>();
                            IList<ProductVariantAttributeCombination> combinations = _productAttributeService.GetAllProductVariantAttributeCombinations(pvaModel.ProductId);
                            foreach(ProductVariantAttributeCombination comb in combinations)
                            {
                                IList<ProductVariantAttributeValue> values = _productAttributeParser.ParseProductVariantAttributeValues(comb.AttributesXml);
                                    if (values[0].Id == pvaValueModel.Id)
                                    {
                                        pvaValueModel.RenderCombinations.Add(new ProductDetailsModel.RenderCombinationModel(values[1].Name, values[1].Id, comb.StockQuantity));
                                        if(pvaValueModel.AffectsObjectId == null)
                                        {
                                            pvaValueModel.CurrentObjectId = "product_attribute_" + pvaModel.ProductId.ToString() + "_" +
                                                                            values[0].ProductVariantAttribute.ProductAttributeId.ToString() + "_" +
                                                                            values[0].ProductVariantAttributeId.ToString();
                                            pvaValueModel.AffectsObjectId = "product_attribute_" + pvaModel.ProductId.ToString() + "_" +
                                                                            values[1].ProductVariantAttribute.ProductAttributeId.ToString() +  "_" +
                                                                            values[1].ProductVariantAttributeId.ToString();
                                        }
                                    }
                            }
                            
                        }

                        pvaModel.Values.Add(pvaValueModel);



STEP 5.
Update your View. in Nop.Web\Views\Catalog.

Well, i didn't include the code here because it has several modifications along the file, and Its better to just replace with my updated file. Please download all files from here:

https://www.mediafire.com/folder/36lk4dz9fcufm/PVAChanges


All comments are in english. There are only two hardcoded words in spanish:  'Agotado' which means Out of Stock and 'Queda n piezas' means n items in stock left.

I've done basic testing and it works great. I haven't tested with multiple variants, but it should work.
Let me know if it works for you. I'll be check this post for questions.

Regards

Victor


[[[UPDATE 1.0]]]
I added a couple of validations in two files. For non-mastered items.
Also, In the shared webfolder, you will find ADMIN folder, which contains all the files necessary to set the Master Flag to true from the admin UI. I'm extending this, so I will keep posting stuff.
10 years ago
Is there any way to add the boolean code to the database on a mac? Whenever I try to edit the database it says i need a program that is only available on a windows.
10 years ago
Im using sql server 2008, you will probably need a db manager for mac. Which db are u using?
But before you do anything else. Wait for an update on the files, cause im almost done with some changes.
I will update in a few hours.
I will explain my changes later then.
10 years ago
the web hosting I have offers SQL hosting 2012. I might just have to work on a desktop which is possible, but downloading things on it could pose a problem. Okay. I will wait for the update. Thank you.
10 years ago
I work on a mac also, but I have windows 7 on bootcamp. I recommend that you install SQL Server 2008 Manager Studio tool or look for a manager compatible with osx.

Ill post in about two hours.
Regards
10 years ago
UPDATE 2.0

Ok Guys,

I made the mistake of adding the flag to the ProductVariantAttributeValue table instead of just ProductVariantAttribute. (Actually it goes in Product_ProductAttribute_Mapping)
They both work but in my first version you have to turn on the IsMasterAttribute flag for every AttributeValue in the table, instead now I turn the isMasterAttribute flag only once, in the Attribute itself.

I updated my code, report any bugs if bump into one.

Next, I'll be posting on a way to make nopcommerce to work as a simple BOM (Bill of Materials).
10 years ago
Vics - Great addition to NopCommerce! Do you have any recommendations or code available to handle color squares as the master attribute? We have several products that use color squares to represent product options and would love if your addition would work with these type of attributes. Thanks for the code!
10 years ago
joekrauss,

Sure, I can do that. Actually I was planning to do it for a particular product that I have, but I wasn't sure how to handle OUT OF STOCK... My first idea is to set the box to gray or just dissable the selection. What do you think?

These changes go in Line 471 of _ProductAttributes.cshtml file... we already have the stock quantity value we just need to know how to handle it.

How do you need it?
10 years ago
Hello - I recommend using the AllowOutOfStockOrders value that is already available in the ProductVariantAttributeCombination table. If you enable this value the button is available for out of stock items, otherwise it should be greyed out. Thanks again for the code!
10 years ago
Great job Vics... Thanks for your code.... I agree with you that this should definitely be on the next version of nopcommerce....
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.