> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# إضافة هدية مجانية تلقائيًا عند حد معين

> حالة استخدام لـ Cart SDK تضيف هدية مجانية عندما يتجاوز إجمالي السلة حدًا معينًا، وتزيلها إذا انخفض الإجمالي دونه.

راقب إجمالي السلة وأبقِ هدية مجانية متزامنة معه: أضف الهدية بمجرد أن يتجاوز المتسوق حد الإنفاق، وأزلها إذا انخفض دونه مرة أخرى.

<Note>
  للحصول على نسخة يهيئها التاجر مع مستويات وقواعد لكل سوق وشريط تقدم، استخدم كتلة [Rewards](/ar/aftersell/cart/rewards-block)، بدون تعليمات برمجية. هذا الحل مخصص للحالات التي لا تستطيع الكتلة التعبير عن قاعدتك فيها.
</Note>

<div id="the-snippet">
  ## المقتطف
</div>

الصقه في **Cart settings → Custom script → Initialization**، وحدّد الثابتَين:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const FREE_GIFT_VARIANT_ID = 1234567890; // the gift product's variant id
const THRESHOLD_CENTS = 5000;            // $50.00, since totals are in cents

function reconcileGift(state) {
  const gift = state.items.find((line) => line.variantId === FREE_GIFT_VARIANT_ID);
  const qualifies = state.totalPrice >= THRESHOLD_CENTS;

  if (qualifies && !gift) {
    window.aftersell.cart.actions.addItem(FREE_GIFT_VARIANT_ID, 1);
  } else if (!qualifies && gift) {
    window.aftersell.cart.actions.removeItem(gift.key);
  }
}

window.aftersell.cart.events.on('cart_loaded', reconcileGift);
window.aftersell.cart.events.on('cart_updated', reconcileGift);
```

<div id="how-it-works">
  ## كيف يعمل
</div>

تصف **`reconcileGift`** الحالة التي *ينبغي* أن تكون عليها السلة، ثم تُجري تغييرًا واحدًا على الأكثر للوصول إليها:

* مؤهلة والهدية غير موجودة → [`addItem`](/ar/aftersell/cart/sdk-actions#additemvariantid-quantity) يضيفها.
* غير مؤهلة والهدية موجودة → [`removeItem`](/ar/aftersell/cart/sdk-actions#removeitemkey) يزيلها، بواسطة `key` الخاص بالسطر.
* خلاف ذلك → لا تفعل شيئًا.

تعمل عند كل من [`cart_loaded`](/ar/aftersell/cart/sdk-events#cart_loaded) (بحيث تحصل السلة المؤهلة أصلًا عند تحميل الصفحة على الهدية) و [`cart_updated`](/ar/aftersell/cart/sdk-events#cart_updated) (بحيث تتفاعل مع كل تغيير بعد ذلك). ولأن `cart_loaded` يُعاد بثه للمشتركين المتأخرين، يعمل هذا بغض النظر عن وقت تشغيل نصك البرمجي.

<Warning>
  **حارسا `!gift` / `gift` هما ما يمنع هذا من الدوران في حلقة.** إضافة الهدية تطلق `cart_updated`، الذي يشغّل `reconcileGift` مرة أخرى، والمرور الثاني يجد الهدية موجودة بالفعل فلا يفعل شيئًا. احذف الحارسين وستحصل على حلقة لا نهائية. راجع [القاعدتين](/ar/aftersell/cart/sdk-events#the-two-rules).
</Warning>

لاحظ أن إضافة الهدية **ترفع إجمالي السلة**، لذا فإن الحد القريب من سعر منتج ما قد يتذبذب: إضافة هدية بقيمة 0\$ آمنة، أما هدية بسعر فقد تدفع السلة بنفسها فوق الحد. أبقِ الهدية مجانية، أو قارن مع إجمالي يستثنيها.

<div id="adapting-it">
  ## تكييفه
</div>

**اجعل الشرط عدد العناصر بدلًا من الإنفاق:**

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const qualifies = state.itemCount >= 3;
```

**اجعل الشرط وجود منتج معين في السلة:**

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const qualifies = state.items.some((line) => line.productId === TRIGGER_PRODUCT_ID);
```

**في دول معينة فقط.** اقرأ [`context`](/ar/aftersell/cart/sdk-overview#context)، المتاح قبل تحميل السلة:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const ELIGIBLE = ['US', 'CA'];

// Only register the handlers for eligible countries.
if (ELIGIBLE.includes(window.aftersell.cart.context.customer_country)) {
  window.aftersell.cart.events.on('cart_loaded', reconcileGift);
  window.aftersell.cart.events.on('cart_updated', reconcileGift);
}
```

**استثنِ الهدية من الحد** حتى لا تُبقي نفسها في السلة:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const subtotalWithoutGift = state.items.reduce(
  (sum, line) => (line.variantId === FREE_GIFT_VARIANT_ID ? sum : sum + line.finalLinePrice),
  0
);
const qualifies = subtotalWithoutGift >= THRESHOLD_CENTS;
```

**ضع علامة على الهدية بحيث تُقرأ كهدية.** يمكن لـ[محوّل السطر](/ar/aftersell/cart/sdk-hooks#registerlinetransform) تغيير عنوان السطر وعنوان المتغير وحالة الإخفاء والخصائص الداخلية — لذا أعد تسميتها:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerLineTransform((line) => {
  if (line.variantId === FREE_GIFT_VARIANT_ID) {
    line.setTitle('Free gift 🎁');
  }
});
```

<Note>
  محوّل السطر **لا يستطيع إخفاء عناصر التحكم في كمية السطر** — فمُعدِّلاته الوحيدة هي `setTitle` و `setVariantTitle` و `setHidden` و `setInternalProperties`. إذا غيّر متسوق كمية الهدية، فصحّحها من داخل معالج `cart_updated` بدلًا من ذلك.
</Note>

<div id="where-to-go-next">
  ## إلى أين تذهب بعد ذلك
</div>

* **[كتلة Rewards](/ar/aftersell/cart/rewards-block)**: النسخة بدون تعليمات برمجية، مع مستويات.
* **[الإجراءات](/ar/aftersell/cart/sdk-actions)**: `addItem` و `removeItem` والبقية.
* **[الأحداث](/ar/aftersell/cart/sdk-events)**: لماذا الحارسان مهمان.
