Appearance
Gift Rules & Free Products
Flow ID: CF-14 | Module(s): eshop, Promotion domain | Complexity: High | Last Updated: 2026-05-19
Business Overview
Gift rules automatically grant free products when cart meets conditions. 13 rule types cover: specific products, vendor products, cart total, product combinations, and the special "cheapest product free" (Rule 13).
Key business behaviors:
- Evaluated on every cart render via
AdvCartResource::getGifts() - Gift quantity:
floor(validatorResult / gift_per_count), capped byremainingstock - Rule 13 special: cheapest qualifying product becomes free (no gift selection)
- Customer can choose from eligible gifts (
gift_user_choice_countlimit)
API Reference
REST Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /rest/promotion/gift | Backend | List gift rules |
| POST | /rest/promotion/gift | Backend | Create gift rule |
| GET | /rest/promotion/gift-requirement | Backend | List requirements |
| GET | /rest/promotion/gift-choice | Backend | List gift choices |
13 Rule Types
| Rule | Validator | Trigger |
|---|---|---|
| 1 | ruleProductsValidator | Specific products in cart |
| 2 | ruleVendorsValidator | Vendor products in cart |
| 3 | ruleTotalCartValidator | Cart total in amount range |
| 4 | ruleProductsTotalCartValidator | Products + cart total |
| 5 | ruleProductsTotalMinAmountValidator | Products' total value in range |
| 6 | ruleVendorsTotalCartValidator | Vendors + cart total |
| 7 | ruleVendorsTotalMinAmountValidator | Vendors' total value in range |
| 8 | ruleVendorsTotalMinPriceValidator | Individual vendor product prices |
| 9 | ruleProductsTotalMinPriceValidator | Individual product prices |
| 10 | ruleProductsCombinationValidator | ALL required products present (minimum qty) |
| 11 | ruleProductsValidatorOneGift | Products, caps at 1 gift |
| 12 | ruleVendorsValidatorReturnOneGift | Vendors, caps at 1 gift |
| 13 | ruleProductsCheapestFreeValidator | Cheapest requirement product = free |
Rule 13 Special Handling
Doesn't use gift_choices table. Instead finds cheapest requirement product via getCheapestRequirementProductInCart(). In order pricing, paidQty = quantity - rule13GiftCount.
Save-side invariant (4.101.0): dom_gift_ID is stripped on save and historical orphan rows were purged — see AD-09 Gift Rules Admin for the full save-pipeline detail and cleanup migration.
Admin path convergence (4.101.0): Both admin order paths in Adv_orders_admin.php now delegate to filterApplicableGiftRules() — see AD-09 Gift Rules Admin for details.
REST checkout (src/Domains/Checkout/PlaceOrderService.php) does not yet apply gift rules — any order placed via /rest/checkout/place-order skips Rule 13 and all other gift rule evaluations. Tracked as #85.
Known Issues & Security Gaps
Race on
gifts.remainingcounter —Adv_gifts_model::updateCounter()(ecommercen/eshop/models/Adv_gifts_model.php:1192-1199) decrements the remaining counter with a non-transactional read-then-write. Two concurrent checkouts can both observeremaining=1, both pass the eligibility check, and both decrement — driving the counter negative. Self-corrects on the next evaluation (negative remaining fails the>0filter) but the N-th concurrent buyer still receives the gift. Tracked as #203.[RESOLVED 4.101.0, commit bd187f2db] Admin order validation dropped Rule 13 gifts — see AD-09 Known Issues for the full resolution detail.
[SAVE-SIDE RESOLVED 4.101.0, commit 879423e21] Rule 13 admin form persisted
dom_gift_IDtogift_choices(never read at runtime) — see AD-09 Known Issues for the fix and cleanup migration detail.[RENDER-SIDE OPEN] Admin form still renders the gift-products picker when Rule 13 is selected — see AD-09 Known Issues for the open tracking detail.
[OPEN — client override risk] Any client repo that overrides
Adv_orders_admin::validateProductGiftSelections()and retains the old inlinearray_filterclosure will continue to drop Rule 13 gifts from admin order validation. Checkapplication/modules/eshop/controllers/Adv_orders_admin.phpin client repos for this pattern.
Client Extension Points
- Gift model override: Custom validator logic, new rule types
- Gift rules model: Rule definitions, field visibility per type
- Admin:
postDataRuleCleanupHelper()strips inapplicable fields per rule
Data Model
| Table | Purpose |
|---|---|
gifts / gifts_mui | Gift rule master + translations |
gift_requirements | Trigger conditions (option_type 1=product, 2=vendor) |
gift_choices | Products offered as gifts |
For full column-level schema details, see AD-09 Gift Rules Admin.
Related Flows
- CF-02 Product Detail — gift badges shown on product page
- CF-05 Cart Management — gifts evaluated every render
- CF-06 Order Preview — gift selection during checkout
- CF-07 Order Confirmation — gift stock decremented
- AD-09 Gift Rules Admin — admin gift rule CRUD
Wiki Guide: Detailed gift module documentation — see Gifts Module.