Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CE 2.1.7 Attributes - Display Out of Stock Products #10454

Closed
stroblee opened this issue Aug 7, 2017 · 52 comments
Closed

CE 2.1.7 Attributes - Display Out of Stock Products #10454

stroblee opened this issue Aug 7, 2017 · 52 comments
Labels
bug report Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release

Comments

@stroblee
Copy link

stroblee commented Aug 7, 2017

Preconditions

  1. Magento CE 2.1.7
  2. Apache 2.4.27
  3. PHP 7..0.22
  4. Varnish 4.1.8

Steps to reproduce

  1. Install Magento 2.1.7 CE Sample Data
  2. Admin > Stores > Configuration > Catalog > Inventory > Stock Options > Display Out of Stock Products = Yes.
  3. CLI php bin/magento indexer:reindex
  4. Admin > Products > Catalog > Breathe-Easy Tank-XS-Puple, Breathe-Easy Tank-XS-White, Breathe-Easy Tank-XS-Orange. Set either Quantity = 0 or Stock Status = Out of Stock.
  5. CLI php bin/magento cache:clean

Expected result

  1. Frontend product - Breathe-Easy Tank. The swatch attribute Size XS' should display with class disabled (red strike through) for all Simple products part of Configurable product.

Actual result

  1. Frontend product - Breathe-Easy Tank. The swatch attribute Size XS not displayed at all.

Other Information

  1. If one Simple product from Configurable options, i.e. Breathe-Easy Tank-XS-Puple, Breathe-Easy Tank-XS-White, Breathe-Easy Tank-XS-Orange has either Quantity => 1 or Stock Status = In Stock then the remaining out of stock products will display the swatch attribute 'Size XS' with class disabled (red strike through) for all Simple products part of Configurable product.
@dankocherga
Copy link

The issue seems to be in a way how Magento retrieves products for showing as a configurable options.

In the Magento\ConfigurableProduct\Block\Product\View\Type\Configurable:: getAllowProducts method it checks for the getSkipSaleableCheck flag which is false and only set to true during admin checkout.

Since the flag is false, it goes down to the Magento\ConfigurableProduct\Model\Product\Type\Configurable::getSalableUsedProducts where stock status is always validated.

In other words, "Display Out of Stock Products" configuration does not make any difference in building configurable product options.

@magento-engcom-team magento-engcom-team added G1 Passed bug report Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed and removed G1 Passed labels Sep 5, 2017
@magento-engcom-team magento-engcom-team added the Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed label Sep 18, 2017
@magento-engcom-team magento-engcom-team added 2.1.x Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release labels Oct 11, 2017
@torlokken
Copy link

Any update on this? Major issue for us.

@thiagolima-bm
Copy link
Member

I'm working on it #SQUASHTOBERFEST

@callumstar
Copy link

Is there any updates on if this has been fixed at all on Magento 2.1.9?

@dawhoo
Copy link

dawhoo commented Nov 28, 2017

@callumstar no, it's not fixed in 2.2.1 either.

@Brendonwbrown
Copy link

Was assigned to Development in Progress. Then was unassigned. Fun stuff.

@wejobes
Copy link

wejobes commented Dec 11, 2017

I have stumbled across this issue. It seems to be caused by this class: \Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Attribute\InStockOptionSelectBuilder.

This plugin ignores the stock-config check completely. I have overridden this plugin to look like this:
`
public function __construct(Status $stockStatusResource, StockConfigurationInterface $stockConfiguration)
{
$this->stockStatusResource = $stockStatusResource;
$this->stockConfiguration = $stockConfiguration;
}

/**
 * Add stock status filter to select.
 *
 * @param OptionSelectBuilderInterface $subject
 * @param Select $select
 * @return Select
 *
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function afterGetSelect(OptionSelectBuilderInterface $subject, Select $select)
{
    if (!$this->stockConfiguration->isShowOutOfStock()) {
        $select->joinInner(
            ['stock' => $this->stockStatusResource->getMainTable()],
            'stock.product_id = entity.entity_id',
            []
        )->where(
            'stock.stock_status = ?',
            \Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK
        );
    }

    return $select;
}

}
`

I am not using the swatches, so it may cause that to break. But with using the selectors, it works correctly.

@VincentMarmiesse
Copy link
Contributor

Hi @wejobes,
I tried your solution with swatches and it's working well but the attribute can be selected and is not disabled or something.

@jeffb1a5
Copy link

how is this on 2.2.6?

@lucasvrooij
Copy link

@piwni I tried your fork on 2.2.6. but it goes back to hiding the option alltogether. What would be the correct way to implement it?

@congson95dev
Copy link

congson95dev commented Jan 2, 2019

@josh-carter i've use your extension, but it doesn't work on magento 2.2.5
I've try @piwni commit as well

@piwni
Copy link

piwni commented Jan 2, 2019

It seems to me that there may be more things that need to be taken into consideration. I'll take a look at it in a free while.

@congson95dev
Copy link

@piwni thanks you, i've searching for this issue all day long and find a lot of code and suggestion, but none of them work so far.

@PathToLife
Copy link
Member

PathToLife commented Jan 16, 2019

I'm also having this problem in magento2.3

// I have found that the configurable $options data is initially set here
// I have made it so that this returns the entire array of attribute codes and product numbers -
//  - for the configurable regardless of stock status 
/* @var \Magento\ConfigurableProduct\Helper\Data $this->$helper */
$options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());

Note that the $options[array] correctly contains all out of stock attribute ids => product ids

$options array

This $options array is passed to a function that attempts to serialize/add extra data that is required buy the js renderer such as labels.

$attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);

/**
     * Get product attributes
     *
     * @param Product $product
     * @param array $options
     * @return array
     */
    public function getAttributesData(Product $product, array $options = [])
    {
        $defaultValues = [];
        $attributes = [];
        $productInstance = $product->getTypeInstance();
        $productEnabledAttributes = $productInstance ->getConfigurableAttributes($product);
        foreach ($productEnabledAttributes as $attribute) {
            $attributeOptionsData = $this->getAttributeOptionsData($attribute, $options);
            if ($attributeOptionsData) {
                $productAttribute = $attribute->getProductAttribute();
                $attributeId = $productAttribute->getId();
                $attributes[$attributeId] = [
                    'id' => $attributeId,
                    'code' => $productAttribute->getAttributeCode(),
                    'label' => $productAttribute->getStoreLabel($product->getStoreId()),
                    'options' => $attributeOptionsData,
                    'position' => $attribute->getPosition(),
                ];
                $defaultValues[$attributeId] = $this->getAttributeConfigValue($attributeId, $product);
            }
        }
        return [
            'attributes' => $attributes,
            'defaultValues' => $defaultValues,
        ];
    }

However getAttributesData does not obey the $options param. A sub call function must unwittingly run a filter operation. Observe below how the return $attributesData has filtered attribute "138"

data filtered

From the getAttributesData() function, I'm suspecting getConfigurableAttributes() to be the cause of out of stock options not displaying in magento 2.3, this function retrieves data from a cache that was generated a few clock cycles ago.

/**
     * Retrieve configurable attributes data
     *
     * @param  \Magento\Catalog\Model\Product $product
     * @return \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute[]
     */
    public function getConfigurableAttributes($product)
    {
        \Magento\Framework\Profiler::start(
            'CONFIGURABLE:' . __METHOD__,
            ['group' => 'CONFIGURABLE', 'method' => __METHOD__]
        );
        if (!$product->hasData($this->_configurableAttributes)) {
            $configurableAttributes = $this->getConfigurableAttributeCollection($product);
            $this->extensionAttributesJoinProcessor->process($configurableAttributes);
            $configurableAttributes->orderByPosition()->load();
            $product->setData($this->_configurableAttributes, $configurableAttributes);
        }
        \Magento\Framework\Profiler::stop('CONFIGURABLE:' . __METHOD__);
        return $product->getData($this->_configurableAttributes);
    }

Really confused atm. That stack trace is insane.

image

@PathToLife
Copy link
Member

PathToLife commented Jan 22, 2019

There's a configuration available in admin that says "Show out of stock product"

I'm under the impression that this should also apply to configurable products, however the js render code doesn't seem to disable options that are out of stock in selection. This is perhaps why there's two plugins dedicated to making sure out of stock options don't show.

Culprit plugin locations:

  • MODULE Magento_ConfigurableProduct -> AttributeValidation.php
  • MODULE Magento_InventoryConfigurableProduct -> IsSalableOptionSelectBuilder.php

Since those plugins weren't following the "Show out of stock product" configuration, I added an afterGetSelect plugin checks for the "Show out of stock product" config.

I changed the Json builder to send preorder data and in stock information to my override of the configurable product render code.

Result: This is what I was trying to do: https://i.imgur.com/mk1lNve.png

this explains what the culprit plugins do:

https://i.imgur.com/J7vsY2G.png

'stock check added here' https://i.imgur.com/vnJ4oqA.png

'aaaannnndddd here again for good measure'https://i.imgur.com/Jr6TSBb.png

TLDR: Some one at magento doubly doesn't want people getting out of stock options. Configurable SQL table layout is really complex.

@seyuf
Copy link

seyuf commented Jan 22, 2019

Hi @PathToLife,
you're saying that this issue still exist in 2.3 despite MSI? (I was under the impression that this was fixed there). Or are you not using MSI?

@PathToLife
Copy link
Member

PathToLife commented Jan 23, 2019

Yep MSI is enabled, but we're not using it.

Regardless the culprit plugins should have a check for the "Show out of stock product" (Store ID basis) configuration anyhow.

And the configurable js code might need updating so dropdown options are greyed out / show out of stock message

@seyuf
Copy link

seyuf commented Jan 23, 2019

Ha alright, thanks for the info.
I will check with MSI to see if these issues still exists as MSI is the recommended option on m 2.3.

Otherwise i m not sure, but i believe some of your work was already done in the plugin mentioned above(https://github.com/interjar/configurable-child-visibility).
As for the customization of the out stock options display, im not sure that is necessarily a core functionality/feature, for in any case if the user try to order and out of stock option he will be prompted with the according error msg.

Anyway good job 👍

@visahardik
Copy link

I'm also having this problem in magento2.3

// I have found that the configurable $options data is initially set here
// I have made it so that this returns the entire array of attribute codes and product numbers -
//  - for the configurable regardless of stock status 
/* @var \Magento\ConfigurableProduct\Helper\Data $this->$helper */
$options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());

Note that the $options[array] correctly contains all out of stock attribute ids => product ids

$options array

This $options array is passed to a function that attempts to serialize/add extra data that is required buy the js renderer such as labels.

$attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);

/**
     * Get product attributes
     *
     * @param Product $product
     * @param array $options
     * @return array
     */
    public function getAttributesData(Product $product, array $options = [])
    {
        $defaultValues = [];
        $attributes = [];
        $productInstance = $product->getTypeInstance();
        $productEnabledAttributes = $productInstance ->getConfigurableAttributes($product);
        foreach ($productEnabledAttributes as $attribute) {
            $attributeOptionsData = $this->getAttributeOptionsData($attribute, $options);
            if ($attributeOptionsData) {
                $productAttribute = $attribute->getProductAttribute();
                $attributeId = $productAttribute->getId();
                $attributes[$attributeId] = [
                    'id' => $attributeId,
                    'code' => $productAttribute->getAttributeCode(),
                    'label' => $productAttribute->getStoreLabel($product->getStoreId()),
                    'options' => $attributeOptionsData,
                    'position' => $attribute->getPosition(),
                ];
                $defaultValues[$attributeId] = $this->getAttributeConfigValue($attributeId, $product);
            }
        }
        return [
            'attributes' => $attributes,
            'defaultValues' => $defaultValues,
        ];
    }

However getAttributesData does not obey the $options param. A sub call function must unwittingly run a filter operation. Observe below how the return $attributesData has filtered attribute "138"

data filtered

From the getAttributesData() function, I'm suspecting getConfigurableAttributes() to be the cause of out of stock options not displaying in magento 2.3, this function retrieves data from a cache that was generated a few clock cycles ago.

/**
     * Retrieve configurable attributes data
     *
     * @param  \Magento\Catalog\Model\Product $product
     * @return \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute[]
     */
    public function getConfigurableAttributes($product)
    {
        \Magento\Framework\Profiler::start(
            'CONFIGURABLE:' . __METHOD__,
            ['group' => 'CONFIGURABLE', 'method' => __METHOD__]
        );
        if (!$product->hasData($this->_configurableAttributes)) {
            $configurableAttributes = $this->getConfigurableAttributeCollection($product);
            $this->extensionAttributesJoinProcessor->process($configurableAttributes);
            $configurableAttributes->orderByPosition()->load();
            $product->setData($this->_configurableAttributes, $configurableAttributes);
        }
        \Magento\Framework\Profiler::stop('CONFIGURABLE:' . __METHOD__);
        return $product->getData($this->_configurableAttributes);
    }

Really confused atm. That stack trace is insane.

image

I am also facing this problem here, Did you get any solution ?

@ibecmattb
Copy link

Still occurs in Magento 2.3

The above module fix does not work for 2.3

Any movement on this or suggestions?

@RonakParmar
Copy link
Member

Still exist in Magneto 2.3, I have tested in 2.3-develop branch. Is there any fix for this issue?

@Berman59
Copy link

Berman59 commented Sep 2, 2019

Have there been any updates on this bug?

@budoland-ab
Copy link

@josh-carter :

What about you? Your repository was installed more than 6000 times. Are you planning an update for https://github.com/interjar/configurable-child-visibility to be compatible with magento 2.3?

@magento:
This should be fixed. It's important to show the users which products are generally available even if they are out of stock for the moment.

@diamondavocado
Copy link

@magento This is an extremely basic requirement for any e-commerce platform. How has this bug been allowed to remain unresolved for over two years? This is seriously worrying; if something this fundamental isn't fixed, what other problems might be lurking within the platform?

@engcom-Charlie
Copy link
Contributor

engcom-Charlie commented Nov 11, 2019

Hello everyone!
We are not able to reproduce this issue on the latest 2.3-develop(with Varnish 4) branch by provided steps.

Manual testing scenario:

  1. Install Magento Sample Data
  2. Admin > Stores > Configuration > Catalog > Inventory > Stock Options > Display Out of Stock Products = Yes.
  3. CLI php bin/magento indexer:reindex
  4. Admin > Products > Catalog > Breathe-Easy Tank-XS-Puple, Breathe-Easy Tank-XS-White, Breathe-Easy Tank-XS-Orange. Set either Quantity = 0 or Stock Status = Out of Stock.
  5. CLI php bin/magento cache:clean

Result:
Frontend product - Breathe-Easy Tank. The swatch attribute Size XS' should display with class disabled (red strike through) for all Simple products part of Configurable product.
image

So i have to close this issue.

@philkun
Copy link
Contributor

philkun commented Dec 2, 2019

Have you tested this with configurable products only having one attribute varient?
For example, a product with a variant of size

Related
#15047

@palomamtnez
Copy link

Is there a solution for 2.3?

@toby-pondr
Copy link

toby-pondr commented Feb 20, 2020

It seems like the confusion stems from if there's one colour or multiple colour choices. If there is only one colour choice available, the sold out size will be hidden. Whereas if there are multiple colour choices available, the sold out size will be striked when the sold out colour is selected.

Personally, I would like the option to always show the sold out size, regardless of the number of colours available.

@diamondavocado
Copy link

diamondavocado commented Mar 20, 2020

@engcom-Charlie Why close this issue instead of seeking clarification? This is still a problem in 2.4! This is the kind of thing making me really frustrated with Magento.

@danbtl
Copy link
Contributor

danbtl commented May 13, 2020

@diamondavocado @palomamtnez Did you find a solution for this?

@MichaelThessel
Copy link

This has been closed incorrectly. See @toby-pondr's comment. This is only an issue if the product only has one color.

@MichaelThessel
Copy link

@stroblee looks like only the original author can re-open this. Mind re-opening?

@joshdavenport
Copy link

@engcom-Charlie @magento-engcom-team this closure is based on a misunderstanding of the issue at hand here, see response from @MichaelThessel and the recently opened issue by them also #30046.

The intention is clearly to show out stock swatch options, the screenshot demonstrates this:

But this doesn't happen when there is only one attribute, so it is only partially working.

@Quentin-Sch
Copy link

Helloooooo,
2.4.3 and still wait for this. Why is it closed ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release
Projects
None yet
Development

No branches or pull requests