Appearance
<div style="display: none;" hidden="true" aria-hidden="true">Are you an LLM? You can read better optimized documentation at /guides/GiftsModule.md for this page in Markdown format</div>
Gifts Module
The gifts module (ecommercen/eshop/) allows store administrators to configure promotional gift rules that automatically assign free products to a customer's order when certain conditions are met.
Architecture
The module is composed of four models and supporting controllers:
| File | Purpose |
|---|---|
ecommercen/eshop/models/Adv_gift_rules_model.php | Static registry of all available rule types |
ecommercen/eshop/models/Adv_gifts_model.php | Core validation engine — evaluates rules against the live cart |
ecommercen/eshop/models/Adv_gift_choices_model.php | Reads eligible gift products from the gift_choices table |
ecommercen/eshop/models/Adv_gift_requirements_model.php | Reads requirement products from the gift_requirements table |
ecommercen/eshop/controllers/Adv_gifts_admin.php | Admin CRUD for gift configurations |
ecommercen/libraries/AdvCartResource.php | Adjusts cart contents for display (rule 13 deduction) |
Gift Rules
Each rule is identified by an integer ID and registered in Adv_gift_rules_model::$data. Every rule entry defines:
id— numeric rule identifiername/help— translation keys resolved viat()at runtimevalidator— method name onAdv_gifts_modelcalled to check cart eligibilityremoveFields— POST fields to strip when saving a gift of this type (fields not applicable to the rule)setDefaults— field defaults forced on save (e.g.,gift_user_choice_count = 0)
Rule Reference
| ID | Name | Trigger | Notes |
|---|---|---|---|
| 1 | Products required | Specific products in cart | User selects gift |
| 2 | Vendors required | Products from specific vendors in cart | User selects gift |
| 3 | Cart total | Cart total within amount range | User selects gift |
| 4 | Products + cart total | Specific products AND total threshold | User selects gift |
| 5 | Products + min amount | Specific products AND minimum total | One gift per rule; gift_per_count forced to 1 |
| 6 | Vendors + cart total | Vendor products AND total threshold | User selects gift |
| 7 | Vendors + min amount | Vendor products AND minimum total | One gift per rule; gift_per_count forced to 1 |
| 8 | Vendors + min price | Vendor products AND minimum item price | User selects gift |
| 9 | Products + min price | Specific products AND minimum item price | User selects gift |
| 10 | Products (combination) | All specified products must be in cart simultaneously | User selects gift |
| 11 | Products required (one gift) | Specific products in cart; returns at most gift_per_count gifts | User selects gift |
| 12 | Vendors required (one gift) | Vendor products in cart; returns at most gift_per_count gifts | User selects gift |
| 13 | Products required — get cheapest free | Specific products in cart | Auto-assign — no user choice |
Rule 13: Products Required — Get Cheapest Free
Added in v4.98.X. This rule automatically assigns the cheapest qualifying product currently in the customer's cart as a free gift — no manual gift selection is required or presented to the customer.
How it works
- The administrator configures a gift with rule 13 and specifies one or more required products.
gift_user_choice_countis forced to0on save (setDefaults) — the gift pool is always computed dynamically, not read from thegift_choicestable.- When the cart is evaluated,
ruleProductsCheapestFreeValidatorcounts the total quantity of matching required products present in the cart (same logic as rule 1). - If the count is ≥
gift_per_count, the rule qualifies.getCheapestRequirementProductInCartthen allocates which products to give for free using a greedy, stock-aware algorithm:- Filters the required products to those actually in the cart.
- Looks up the live price of each via
$this->liveData(populated byAdvCartResource). - Sorts candidates cheapest-first; ties break by lowest product ID (deterministic).
- Iterates the sorted list and takes
min(remaining_gifts, product_stock)units from each candidate until all owed gifts are assigned. - Returns
[1 => [pid, pid, ...]]— a flat per-slot list where each entry represents one gift unit (the same pid may appear multiple times if more than one unit of that product is taken).
- The free product(s) are added to the cart as gifts. Their quantities are subtracted from the paid cart rows in
baseParseCartContentsso the customer is not charged for them. Gift slots with duplicate pids are grouped per-pid at display and adjustment time (viaarray_count_values) so each cart row is deducted by the correct per-product count. - When the order is placed,
adjustCartForRule13Giftsremoves the free items from the stored basket rows.
Key methods
| Method | Location | Purpose |
|---|---|---|
ruleProductsCheapestFreeValidator(int $masterId, array $reqs, array $productsInCart): int | Adv_gifts_model | Returns total qty of required products in cart (eligibility check) |
getCheapestRequirementProductInCart(int $giftId, array $allRequirements, array $productsInCart, int $giftsToGive): array | Adv_gifts_model | Returns [1 => [pid, pid, ...]] — flat per-slot list of auto-assigned gift units, allocated greedily cheapest-first with stock awareness |
getRule13GiftAdjustments() | Adv_order_model | Resolves the cheapest free product and deduction count for the current cart |
adjustCartForRule13Gifts() | Adv_order_model | Removes the free item from basket rows when the order is placed |
adjustCartContentsForRule13() | AdvCartResource | Subtracts the free gift qty from the matching cart row before sending cartContents to the frontend |
Admin order page behaviour
Rule 13 gifts are handled differently on the admin order add/edit page:
- The
gifts_for_productsAJAX endpoint overrideschoices[1]with the cheapest product (mirrorsAdvCartResource). validateProductGiftSelectionsskips rule 13 (auto-assigned — no user selection to validate).- The Vue Vuex getter forces
ruleSatisfiesChoiceSelection = truefor rule 13. getRule13GiftAdjustmentsForProducts()is extracted for reuse between the session cart and the admin fake cart so totals are correctly deducted when payment method, transporter, or address changes are made.
Admin UI fields hidden for rule 13
The following fields are not shown when creating or editing a gift with rule 13 (removeFields):
amount_fromamount_toreq_vendor_ids
isLive behaviour
Rule 13 gifts have no rows in the gift_choices table (the pool is computed dynamically). The getActiveGiftRules query was updated to:
- Select
rule_idin the query so it is available in the filter callback. - Skip the early-exit on empty choices to prevent rule 13 gifts from being excluded.
- Bypass the
gift_choicesexistence check inarray_filterfor rule 13.
Translations
Translation keys eshop.admin.gifts.rule13.name and eshop.admin.gifts.rule13.help are defined in all 8 supported languages:
English: Products required - get cheapest free
Help: Required products in cart trigger the rule. The cheapest required
product currently in cart is automatically assigned as a free gift.
On a price tie the product with the lowest ID is selected.Language files updated: english, greek, german, french, spanish, italian, russian, chinese.
Files to Check for Overrides
If you have customized any of the following files in a client repo, review the changes introduced for rule 13:
ecommercen/eshop/models/Adv_gifts_model.phpecommercen/eshop/models/Adv_gift_rules_model.phpecommercen/eshop/models/Adv_order_model.phpecommercen/eshop/controllers/Adv_orders_admin.phpecommercen/libraries/AdvCartResource.phpassets/admin/js/order-gifts-block.jsapplication/views/admin/footer_js.php