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

Fix: Error selecting applicable discounts #1434

Merged
merged 2 commits into from
Jan 11, 2024

Conversation

se09deluca
Copy link
Contributor

@se09deluca se09deluca commented Dec 31, 2023

The discount selection currently takes all the discounts with and without coupon code because of this conditional query

->when($cart?->coupon_code,
                fn ($query, $value) => $query->where('coupon', '=', $value)->orWhere(fn ($query) => $query->whereNull('coupon')->orWhere('coupon', '')),
                fn ($query, $value) => $query->whereNull('coupon')->orWhere('coupon', '')
            )

when the $cart?->coupon_code is true, it executes the first closure in which it selects the discounts having the correct coupon but also the discounts with null coupon code or empty strings. Only the second clousure (executed when $cart?->coupon_code is false) should selects the discount with null coupons or empty.

This issue currently make the query selects all the discounts that has no coupon_code (even the expired ones, because of the OR clause)
Below a simplified result of the ->toSql() of the query.

select *
from `lunar_discounts`
where `starts_at` is not null and `starts_at` <= now() and (`ends_at` is null or `ends_at` > now())
          and (uses < max_uses or `max_uses` is null)
          and `coupon` = 'EXAMPLE_CODE' or (`coupon` is null or `coupon` = '')
order by `priority` desc, `id` asc

The PR essentially changes the positive closure. By making use of a where condition with a closure, the query builder creates a logical group around the WHERE conditions and the resulting SQL query will have the affected conditions placed in parentheses, as the simplified example below:

select *
from `lunar_discounts`
where `starts_at` is not null and `starts_at` <= now() and (`ends_at` is null or `ends_at` > now())
          and (uses < max_uses or `max_uses` is null)
          and (`coupon` = 'EXAMPLE_CODE' or `coupon` is null or `coupon` = '')
order by `priority` desc, `id` asc

PS: the provided example are simplified because for readability purpose i removed the subqueries relative to channels, customer groups and discount's purchasables.

Copy link

vercel bot commented Dec 31, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
lunar-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 11, 2024 9:47am

@se09deluca se09deluca force-pushed the fix/discount-selection branch from 3c31a38 to 2131c6d Compare December 31, 2023 15:18
@se09deluca se09deluca changed the title fix: conditional query on cart's coupon_code Fix: Error selecting applicable discounts Dec 31, 2023
@se09deluca se09deluca marked this pull request as ready for review December 31, 2023 15:40
@glennjacobs glennjacobs added the bug Something isn't working label Jan 3, 2024
@glennjacobs glennjacobs added this to the v0.7 milestone Jan 3, 2024
@alecritson alecritson merged commit ff999fe into lunarphp:0.7 Jan 11, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants