Skip to content

Match the price filter to the range the slider displays - #1290

Open
boo-code wants to merge 1 commit into
PrestaShop:devfrom
boo-code:fix/price-filter-matches-displayed-bounds
Open

Match the price filter to the range the slider displays#1290
boo-code wants to merge 1 commit into
PrestaShop:devfrom
boo-code:fix/price-filter-matches-displayed-bounds

Conversation

@boo-code

Copy link
Copy Markdown
Contributor
Questions Answers
Description? The price slider is built from floor() of the lowest indexed price and ceil() of the highest, while the filter compares the raw indexed column against the value the shopper picked. A product indexed at 5995.000001 is therefore offered as spanning 5995 to 5996 and then satisfies neither end, so dragging either handle empties the listing. The bounds now cover the range that was displayed for the product.
Type? bug fix
BC breaks? no
Deprecations? no
Fixed ticket? Fixes PrestaShop/PrestaShop#37604.
How to test? See below.
Sponsor company

How to test

Give a product a tax excluded price whose tax included value is not representable exactly, for instance 4995.833334 at 20 percent, and reindex. The shop then holds a single indexed value of 5995.000001.

Measured on a 9.2 shop before the change:

indexed: price_min=5995.000001 price_max=5995.000001
slider shows: 5995 -> 5996

filter 5995..5995 -> product returned: no
filter 5996..5996 -> product returned: no
filter 5995..5996 -> product returned: YES

Both ends of the range the slider itself offered return nothing. That is the two symptoms of the report, the unexpected upper bound and the empty result on an exact price.

The change

$this->getSearchAdapter()->addFilter('price_min', [floor($maxPrice) + 1], '<');
$this->getSearchAdapter()->addFilter('price_max', [ceil($minPrice) - 1], '>');

price_min < floor(max) + 1 is the same condition as floor(price_min) <= max, and the mirror on the other side, so a product matches exactly the range it was shown as occupying. Writing it this way keeps the column alone on its side of the comparison, so the index on layered_price_index is still usable, which FLOOR(price_min) <= :max would have prevented.

The six decimals themselves are not the problem, they come from ps_round($price * (100 + $taxRate) / 100, 6) at index time and are correct. Only the comparison was using a different rounding from the display.

Tests

testInitSearchWidensPriceBoundsToTheDisplayedRange pins the produced bounds for a 5995 to 5995 selection, and the existing expectation in testInitSearchWithAllFilters is updated to the new operators. Reverting the change turns both red.

OK (101 tests, 938 assertions)

Related

#1281 and #1283 also touch price filtering, both in the post filter of Filters/Products.php. This one changes the bounds sent to SQL in Product/Search.php, so they do not overlap, but they are worth sequencing deliberately since all three affect which products a price range returns.

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

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

Basic price filtering of faceted search is broken

2 participants