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

Out of Stock associated product but its color swatch appears as product image #1694

Open
ADDISON74 opened this issue Jun 20, 2021 · 2 comments

Comments

@ADDISON74
Copy link
Contributor

Here are the steps to reproduce this issue.

  1. Create a Configurable Product based on Color attribute which has in my case 2 defined values Blue and Grey.

  2. In Images section add 3 images. The first image is used as Base/Small/Thumbnail, and the other two for swatches with these Labels: Blue-swatch, Grey-swatch.

  3. Create 2 Associated Products for each color. In Inventory section you should have Qty >0 and Stock Availability "In Stock".

Now load the Frontend. You should see as options both colors as bellow.

1

  1. Let's edit associated product for Grey color. Go to Inventory section and change Stock Availability to "Out of Stock". Reload the Frontend. Now option Grey disappeared which is correct but look at "MORE VIEWS" block bellow the product image. Now there are two thumbnails instead of one. The new addition is Grey-swatch image just see its title attribute bellow.

2

In conclusion, if one option is not available its swatch should be excluded completely from listing in Frontend. Unfortunately Magento treats its image defined with Label format Color-Name-swatch as a product image and this is definitely a bug.

Please note if you set the associated product to Disable its swatch disappears from MORE VIEWS block. See bellow.

3

@ADDISON74 ADDISON74 added the bug label Jun 20, 2021
@elidrissidev
Copy link
Member

I'm taking this issue.

@elidrissidev
Copy link
Member

I have identified the problem and tried multiple fixes that work, but I'm not sure yet which one is appropriate and will not cause side effects.

In Mage_ConfigurableSwatches_Helper_Mediafallback::attachProductChildrenAttributeMapping, there is a loop that goes through all configurable children and checks if they have the color attribute and are in stock before adding them to the $mapping array. This array is then set as data on the product with key child_attribute_label_mapping.

foreach ($parentProduct->getChildrenProducts() as $childProduct) {
// product has no value for attribute or not available, we can't process it
$isInStock = $childProduct->getStockItem()->getIsInStock();
if (!$childProduct->hasData($attribute->getAttributeCode())
|| (!$isInStock && !Mage::helper('cataloginventory')->isShowOutOfStock())) {
continue;
}
$optionId = $childProduct->getData($attribute->getAttributeCode());
// if we don't have a default label, skip it
if (!isset($optionLabels[$optionId][0])) {
continue;
}
// using default value as key unless store-specific label is present
$optionLabel = $optionLabels[$optionId][0];
if (isset($optionLabels[$optionId][$storeId])) {
$optionLabel = $optionLabels[$optionId][$storeId];
}
// initialize arrays if not present
if (!isset($mapping[$optionLabel])) {
$mapping[$optionLabel] = array(
'product_ids' => array(),
);
}
$mapping[$optionLabel]['product_ids'][] = $childProduct->getId();
$mapping[$optionLabel]['label'] = $optionLabel;
$mapping[$optionLabel]['default_label'] = $optionLabels[$optionId][0];
$mapping[$optionLabel]['labels'] = $optionLabels[$optionId];
if ($attribute->getAttributeId() == $listSwatchAttr->getAttributeId()
&& !in_array($mapping[$optionLabel]['label'], $listSwatchValues)
) {
$listSwatchValues[$optionId] = $mapping[$optionLabel]['label'];
$listSwatchStockValues[$optionId] = $isInStock;
}
} // end looping child products

It is then getting used by Mage_ConfigurableSwatches_Helper_Productimg::filterImageInGallery to decide whether the image should be displayed in the gallery. Since the product is out of stock, it is not present in the mapping array and thus the condition at the end is returning true.

/**
* Determine whether to show an image in the product media gallery
*
* @param Mage_Catalog_Model_Product $product
* @param Varien_Object $image
* @return bool
*/
public function filterImageInGallery($product, $image)
{
if (!Mage::helper('configurableswatches')->isEnabled()) {
return true;
}
if (!isset($this->_productImageFilters[$product->getId()])) {
$mapping = call_user_func_array("array_merge_recursive", array_values($product->getChildAttributeLabelMapping()));
$filters = array_unique($mapping['labels']);
$filters = array_merge($filters, array_map(function ($label) {
return $label . Mage_ConfigurableSwatches_Helper_Productimg::SWATCH_LABEL_SUFFIX;
}, $filters));
$this->_productImageFilters[$product->getId()] = $filters;
}
return !in_array(
Mage_ConfigurableSwatches_Helper_Data::normalizeKey($image->getLabel()),
$this->_productImageFilters[$product->getId()]
);
}

The easiest solution that will work is to add a condition to check if the image label resembles a swatch like so:

if (preg_match('/.+'.self::SWATCH_LABEL_SUFFIX.'$/', $image->getLabel())) {
    // This is a swatch image, do not show it
    return false;
}

But then this will not work if the image label is is named after the color name directly without the '-swatch' suffix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants