Skip to content

Unable to get product collection scoped decimal attribute if price is globally scoped #40218

@gimanik

Description

@gimanik

Preconditions and environment

  • Magento version 2.4.8-p2

Steps to reproduce

Problem is pretty straightforward.

  1. Set price as global (it's by default)
  2. Add decimal scoped attribute example_decimal_attr
  3. Set decimal attribute value on some products on store scope (not global - store_id > 0)
  4. Create product collection for scope where created attribute have value (i.e. store_id = 1)
  5. Add attributes to select:
$collection->setStoreId(1);
$collection->addAttributeToSelect('example_decimal_attr');
$collection->addAttributeToSelect('price');
$collection->load();

Expected result

Loaded products in collection have example_decimal_attr values.

Actual result

Loaded products in collection does not have example_decimal_attr values. If we remove price from collection attributes select, then it works as expected.
This works:

$collection->setStoreId(1);
$collection->addAttributeToSelect('example_decimal_attr');
$collection->load();

Adding $collection->addAttributeToSelect('price'); before loading collection, causes bug, that example_decimal_attr values are not present.

Additional information

The issue is here:
Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection::_getLoadAttributesSelect
lines 177-179:

                if ($attribute->getAttributeCode() === 'price' && (int)$attribute->getIsGlobal() === 1) {
                    $storeId = $this->getDefaultStoreId();
                }

it replaces $storeId with DefaultStoreId (0 - global) for attribute value select that's for all decimal attributes (not only price).

Without ->addAttributeToSelect('price') returned select looks like this:

SELECT `t_d`.`attribute_id`, `e`.`entity_id` FROM `catalog_product_entity_decimal` AS `t_d`
 INNER JOIN `catalog_product_entity` AS `e` ON e.entity_id = t_d.entity_id
 LEFT JOIN `catalog_product_entity_decimal` AS `t_s` ON t_s.attribute_id = t_d.attribute_id AND t_s.entity_id = t_d.entity_id AND t_s.store_id = 1 WHERE (e.entity_id IN (2, 3)) AND (t_d.attribute_id IN (146)) AND (t_d.store_id = IFNULL(t_s.store_id, 0))

and has correct t_s.store_id = 1 and works as expected.

And if we add ->addAttributeToSelect('price') to collection, returned select looks like this:

SELECT `t_d`.`attribute_id`, `e`.`entity_id` FROM `catalog_product_entity_decimal` AS `t_d`
 INNER JOIN `catalog_product_entity` AS `e` ON e.entity_id = t_d.entity_id
 LEFT JOIN `catalog_product_entity_decimal` AS `t_s` ON t_s.attribute_id = t_d.attribute_id AND t_s.entity_id = t_d.entity_id AND t_s.store_id = 0 WHERE (e.entity_id IN (2, 3)) AND (t_d.attribute_id IN (146, 77)) AND (t_d.store_id = IFNULL(t_s.store_id, 0))

with t_s.store_id = 0 which is wrong, because it wont load any other decimal attribute values that are scoped, or loaded values will be from global scope, even though $collection is for specific store_id.

Correct way to fix it is just to remove
Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection::_getLoadAttributesSelect
lines 171-180:

foreach ($attributeIds as $id) {
    $attribute = $this->_eavConfig->getAttribute(
        $this->getEntity()->getType(),
        $id
    );

    if ($attribute->getAttributeCode() === 'price' && (int)$attribute->getIsGlobal() === 1) {
        $storeId = $this->getDefaultStoreId();
    }
}

Because it's not neccessary
Then it works as expected.
Or check there if all attributes are global: $attribute->getIsGlobal() === 1 not only price.

Release note

No response

Triage and priority

  • Severity: S0 - Affects critical data or functionality and leaves users without workaround.
  • Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
  • Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
  • Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
  • Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.

Metadata

Metadata

Assignees

Labels

Issue: ready for confirmationReported on 2.4.8-p2Indicates original Magento version for the Issue report.Triage: Dev.ExperienceIssue related to Developer Experience and needs help with Triage to Confirm or Reject it

Type

No type

Projects

Status

Ready for Confirmation

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions