Skip to content

Fix: Error selecting applicable discounts#1434

Merged
alecritson merged 2 commits intolunarphp:0.7from
se09deluca:fix/discount-selection
Jan 11, 2024
Merged

Fix: Error selecting applicable discounts#1434
alecritson merged 2 commits intolunarphp:0.7from
se09deluca:fix/discount-selection

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.

@vercel
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 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants