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

No one assigned

    Labels

    Area: CatalogComponent: AttributesIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedPriority: P3May be fixed according to the position in the backlog.Reported on 2.4.8-p2Indicates original Magento version for the Issue report.Reproduced on 2.4.xThe issue has been reproduced on latest 2.4-develop branchTriage: Dev.ExperienceIssue related to Developer Experience and needs help with Triage to Confirm or Reject it

    Type

    No type

    Projects

    Status

    Ready for Development

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions