-
Notifications
You must be signed in to change notification settings - Fork 9.4k
A fix for issue #9265 #9266
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
A fix for issue #9265 #9266
Conversation
This line: $quantity = $quantity ?: 1; in ./vendor/magento/module-catalog/Pricing/Price/TierPrice.php, line 75, uses the ternary shorthand operator to set the quantity to 1 when the quantity that is passed can be converted to false. At this point, the quantity comes from the SaleableInterface item - the simple product model itself. Note that the type signature for the getQty method in SaleableInterface indicates that it should always return a float: /** * Returns quantity of saleable item * * @return float */ public function getQty(); However, on the grouped-product page this item comes from this collection: ./vendor/magento/module-catalog/Model/ResourceModel/Product/Link/Product/Collection.php (a collection of linked products). So the quantity that is set in the product model comes from the "Default quantity" field which is stored as an attribute of the link(catalog_product_link_attribute_decimal) - however, since neither Magento nor the underlying Zend libraries have any conversion from the MySQL to PHP types when loading the collections, and MySQL client/server communication is done via a text-based protocol, this "qty" field ends up being a string in PHP. Thus, the getQty function will return a string representation of a decimal value("0.0000000") in a clear violation of the SaleableInterface, and it leads to this issue with the tier price above(since the ternary shorthand operator will treat "0.000000" string as true, not setting the quantity to 1 as a result). Suggested fix does a forceful conversion of the link-attributes with type=decimal to a PHP float-value on the link-product-collection afterLoad event. It is possible to do the same for the integer type as well, but doing it just for the type=decimal seems least intrusive, and it would solve this interface-mismatch and tier-price issue.
codacy fix
Hi, |
Hi, root@manage /var/www/magento2/last_dev/magento2 # git log -n 1
This is a screenshot of an incorrect product-page without the suggested fix: This is a screenshot of a correct product page with the suggested fix applied: Those are the settings for the grouped product: Those are the settings for the test2 product: Tier price for the test2 product: Do you have the same settings when testing and do you see the same in frontend? |
The "Default Quantity" field in the "Grouped Products" section on the grouped product should be 0 Please note that this is essential to reproduce the bug. |
- reverted original fix due to broken logic in other parts or the system - added local fix for Tier Price
- reverted original fix due to broken logic in other parts or the system - added local fix for Tier Price
- cover changes with test
Fixes issue #9265
Description
This line: $quantity = $quantity ?: 1;
in ./vendor/magento/module-catalog/Pricing/Price/TierPrice.php, line 75,
uses the ternary shorthand operator to set the quantity to 1 when
the quantity that is passed can be converted to false.
At this point, the quantity comes from the SaleableInterface item - the simple product model itself.
Note that the type signature for the getQty method in SaleableInterface indicates that it should always
return a float:
/**
*/
public function getQty();
However, on the grouped-product page this item comes from this collection:
./vendor/magento/module-catalog/Model/ResourceModel/Product/Link/Product/Collection.php
(a collection of linked products). So the quantity that is set in the product model comes from the
"Default quantity" field which is stored as an attribute of the link(catalog_product_link_attribute_decimal) -
however, since neither Magento nor the underlying Zend libraries have any conversion from the MySQL to PHP types when loading the collections,
and MySQL client/server communication is done via a text-based protocol, this "qty" field ends up being a string in PHP.
Thus, the getQty function will return a string representation of a decimal value("0.0000000") in a clear violation of the SaleableInterface, and it leads to this issue with the tier price above(since the ternary shorthand operator will treat "0.000000" string as true, not setting the quantity to 1 as a result).
Suggested fix does a forceful conversion of the link-attributes with type=decimal to a PHP float-value on the link-product-collection afterLoad event.
It is possible to do the same for the integer type as well, but doing it just for the type=decimal seems least intrusive, and it would solve this interface-mismatch and tier-price issue.
Fixed Issues (if relevant)
Manual testing scenarios
Contribution checklist