> ## 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.

# الإجراءات

> كل إجراءات Aftersell Cart SDK لقراءة السلة وتغييرها: الفتح والإغلاق والإضافة والإزالة وتحديث الكمية وتبديل متغير وقراءة الحالة وتنسيق المبالغ.

الإجراءات **تقرأ السلة وتغيّرها**. توجد تحت `window.aftersell.cart.actions`.

<Note>
  تُنفَّذ الإجراءات **بعد جاهزية السلة**، داخل `ready()` أو داخل معالج [حدث](/ar/aftersell/cart/sdk-events).
</Note>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  console.log(state.itemCount, 'items');
});
```

<Note>
  **قبل تحميل السلة، تكون الإجراءات مجرد بدائل صورية (stubs).** يسجّل كل منها تحذيرًا في وحدة التحكم يذكر اسم الإجراء، مثل `cart.actions.addItem() called before the cart loaded`، ولا يفعل شيئًا. الإجراءات غير المتزامنة تظل تُرجع Promise يُحل، لذا تعمل سلسلة `.then()` بشكل طبيعي بدلًا من رمي خطأ؛ وتُرجع `getCart()` القيمة `null` وتُرجع `formatMoney()` سلسلة فارغة.

  لا يتعطل شيء إذا استدعيت إجراءً مبكرًا جدًا، لكن لا يحدث شيء أيضًا. راقب وحدة التحكم بحثًا عن ذلك التحذير عندما يبدو أن إجراءً لا يفعل شيئًا.
</Note>

<div id="every-action">
  ## كل الإجراءات
</div>

| الإجراء                                                  | التوقيع                              | يُرجع                   | ما الذي يفعله              |
| -------------------------------------------------------- | ------------------------------------ | ----------------------- | -------------------------- |
| [`open`](#open-and-close)                                | `open()`                             | لا شيء                  | يفتح الدرج.                |
| [`close`](#open-and-close)                               | `close()`                            | لا شيء                  | يغلق الدرج.                |
| [`getCart`](#getcart)                                    | `getCart()`                          | `AftersellCart \| null` | يقرأ السلة الحالية.        |
| [`formatMoney`](#formatmoneycents)                       | `formatMoney(cents)`                 | `string`                | ينسّق مبلغًا للعرض.        |
| [`addItem`](#additemvariantid-quantity)                  | `addItem(variantId, quantity?)`      | `Promise`               | يضيف متغيرًا.              |
| [`removeItem`](#removeitemkey)                           | `removeItem(key)`                    | `Promise`               | يزيل بندًا.                |
| [`updateItemQuantity`](#updateitemquantitykey-quantity)  | `updateItemQuantity(key, quantity)`  | `Promise`               | يحدد كمية بند.             |
| [`replaceLineVariant`](#replacelinevariantkey-variantid) | `replaceLineVariant(key, variantId)` | `Promise`               | يبدّل متغير بند.           |
| [`refresh`](#refresh)                                    | `refresh()`                          | `Promise`               | يعيد جلب السلة من Shopify. |
| [`visualRefresh`](#visualrefresh)                        | `visualRefresh()`                    | لا شيء                  | يعيد الرسم دون إعادة جلب.  |

<Warning>
  استدعاء إجراء من داخل معالج `cart_updated` قد يسبب حلقة لا نهائية. اقرأ [القاعدتين](/ar/aftersell/cart/sdk-events#the-two-rules) أولًا.
</Warning>

***

<div id="drawer">
  ## الدرج
</div>

<div id="open-and-close">
  ### open وclose
</div>

يفتحان أو يغلقان درج السلة. كلاهما متزامن ولا يأخذ أي وسيطات.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Open the drawer from your own cart link.
document.querySelector('#my-cart-link').addEventListener('click', (event) => {
  event.preventDefault();
  window.aftersell.cart.actions.open();
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Close it after the shopper does something in a custom block.
window.aftersell.cart.actions.close();
```

***

<div id="reading">
  ## القراءة
</div>

<div id="getcart">
  ### getCart()
</div>

يُرجع [كائن السلة](/ar/aftersell/cart/sdk-cart-object) الحالي، أو `null` قبل تحميلها. النتيجة **نسخة**، لذا فإن تعديلها لن يغيّر السلة الحقيقية.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  if (!state) return; // the initial load failed

  console.log(state.itemCount, 'items,', state.items.length, 'lines');
  console.log('Total:', window.aftersell.cart.actions.formatMoney(state.totalPrice));
});
```

لأنها لقطة لحظية، لا تحتفظ بالنتيجة؛ بل اقرأها من جديد في كل مرة تحتاج فيها إلى بيانات حديثة. داخل معالج حدث تكون السلة الحديثة موجودة لديك بالفعل كحمولة، لذا يكون `getCart()` زائدًا هناك.

<div id="formatmoneycents">
  ### formatMoney(cents)
</div>

ينسّق مبلغًا بالوحدات الصغرى باستخدام تنسيق العملة الخاص بمتجرك. كل سعر في SDK يكون بالسنتات، لذا فهذه هي طريقة تحويله إلى شيء يمكنك عرضه.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.actions.formatMoney(5779);  // "$57.79"
window.aftersell.cart.actions.formatMoney(0);     // "$0.00"
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Show the cart total in your own header element.
window.aftersell.cart.events.on('cart_updated', (state) => {
  document.querySelector('#header-total').textContent =
    window.aftersell.cart.actions.formatMoney(state.totalPrice);
});
```

تجاوز التنسيق باستخدام [`configure({ money_format })`](/ar/aftersell/cart/sdk-configure#money_format).

***

<div id="changing-the-cart">
  ## تغيير السلة
</div>

<Note>
  تحدد إجراءات البنود البند عبر **`key`** الخاص بـ Shopify، وليس عبر معرّف المتغير، لأن السلة يمكن أن تحتوي على المتغير نفسه في عدة بنود بخصائص مختلفة. اقرأه من `getCart().items[n].key`.
</Note>

<div id="additemvariantid-quantity">
  ### addItem(variantId, quantity?)
</div>

يضيف متغيرًا إلى السلة. القيمة الافتراضية لـ `quantity` هي `1`. يُحل بعد استقرار السلة.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Add one, then show the shopper.
window.aftersell.cart.actions.addItem(41720671830082).then(() => {
  window.aftersell.cart.actions.open();
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Add a specific quantity.
window.aftersell.cart.actions.addItem(41720671830082, 3);
```

إضافة متغير موجود بالفعل في السلة تزيد كمية ذلك البند بدلًا من إنشاء بند ثانٍ، طالما أن البند الموجود لا يحمل خصائص بند (line item properties). البند الذي يحمل خصائص هو بند مستقل، لذا تحصل على بند جديد.

<div id="removeitemkey">
  ### removeItem(key)
</div>

يزيل بندًا بالكامل.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Remove any free line from the cart.
const gift = window.aftersell.cart.actions
  .getCart()
  .items.find((line) => line.finalLinePrice === 0);
if (gift) window.aftersell.cart.actions.removeItem(gift.key);
```

<div id="updateitemquantitykey-quantity">
  ### updateItemQuantity(key, quantity)
</div>

يحدد كمية بند. تمرير `0` يزيل البند.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const line = window.aftersell.cart.actions.getCart().items[0];
if (line) window.aftersell.cart.actions.updateItemQuantity(line.key, 3);
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Cap a line at one unit.
window.aftersell.cart.events.on('cart_updated', (state) => {
  state.items.forEach((line) => {
    if (line.variantId === LIMITED_VARIANT_ID && line.quantity > 1) {
      window.aftersell.cart.actions.updateItemQuantity(line.key, 1);
    }
  });
});
```

المثال الثاني آمن للتشغيل من `cart_updated` لأن فحص `> 1` يكون خاطئًا في التمريرة الثانية. راجع [القاعدتين](/ar/aftersell/cart/sdk-events#the-two-rules).

<div id="replacelinevariantkey-variantid">
  ### replaceLineVariant(key, variantId)
</div>

يبدّل متغير بند مع الاحتفاظ بكميته وخصائصه. مفيد لمبدّل مقاس أو نكهة داخل السلة.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
const line = window.aftersell.cart.actions.getCart().items[0];
window.aftersell.cart.actions.replaceLineVariant(line.key, 41720671862850);
```

<Warning>
  **تُعاد ضبط خطة البيع** الخاصة بالبند عند التبديل. يتحول بند الاشتراك إلى شراء لمرة واحدة ما لم تُعِد تطبيق خطة.
</Warning>

التبديل هو إضافة يتبعها إزالة، وليس تعديلًا في المكان، لذا فالنتيجة **بند جديد**: يحصل على `key` جديد ويستقر في نهاية السلة. أعد قراءة `getCart()` بعد ذلك بدلًا من إعادة استخدام المفتاح الذي مررته.

***

<div id="refreshing">
  ## إعادة التحميل
</div>

<div id="refresh">
  ### refresh()
</div>

يعيد جلب السلة من Shopify. استخدمه بعد أن يغيّر شيءٌ خارج SDK السلةَ ولم يلحظ الدرج ذلك.

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// After a raw Ajax API call of your own.
fetch('/cart/add.js', { method: 'POST', /* … */ })
  .then(() => window.aftersell.cart.actions.refresh())
  .then(() => { window.aftersell.cart.actions.open(); });
```

في معظم الأحيان لا تحتاج إلى هذا، إذ يستمع Aftersell بالفعل إلى أحداث السلة القياسية في Shopify ويعيد الجلب من تلقاء نفسه. الجأ إليه عندما يتجاوز تكامل مخصص تلك الأحداث.

<div id="visualrefresh">
  ### visualRefresh()
</div>

يعيد تشغيل تحويلات العرض دون إعادة جلب السلة من Shopify. نادرًا ما تحتاج إليه: تسجيل (أو إلغاء تسجيل) [تحويل بند](/ar/aftersell/cart/sdk-hooks#registerlinetransform) أو [مقارِن](/ar/aftersell/cart/sdk-hooks#registerlinecomparator) أو [مُثري](/ar/aftersell/cart/sdk-hooks#registercartenricher) أو أيٍّ من [خطافي الاشتراك](/ar/aftersell/cart/sdk-hooks#registersubscriptionoptionstransform) يشغّل واحدًا نيابةً عنك. فقط خطافا الإضافة إلى السلة لا يفعلان ذلك، لأنهما لا يغيّران أي شيء معروض بالفعل على الشاشة.

الجأ إليه عندما يتغير شيء *يعتمد عليه* تحويل ما دون أن تتغير السلة نفسها:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// A currency switcher changed the format: repaint prices already on screen.
window.myTheme.onCurrencyChange((currency) => {
  window.aftersell.cart.configure({ money_format: FORMATS[currency] });
  window.aftersell.cart.actions.visualRefresh();
});
```

***

<div id="notes-and-edge-cases">
  ## ملاحظات وحالات حدّية
</div>

* **تُحل الإجراءات غير المتزامنة عند استقرار التغيير.** انتظار أحدها يتيح لك ترتيب العمل بعد أن تكون السلة قد تحدّثت فعلًا.
* **يُرجع `getCart()` نسخة.** تعديلها لا يؤثر على السلة الحقيقية.
* **لا يوجد إجراء لأكواد الخصم.** الأكواد المطبَّقة قابلة للقراءة على السلة (`discountCodes` و`totalDiscount`) وعلى مستوى البند (`discountAllocations`)؛ ويطبّقها المتسوقون عبر بلوك [Discount code](/ar/aftersell/cart/discount-code-block).
* **لا يوجد إجراء لسمات السلة أو الملاحظات.** السمات قابلة للقراءة على كائن السلة؛ ويكتب المتسوقون الملاحظات عبر بلوك [Notes](/ar/aftersell/cart/notes-block).
* **لإخفاء بند بدلًا من إزالته**، استخدم [`registerLineTransform`](/ar/aftersell/cart/sdk-hooks#registerlinetransform). الإزالة تغيّر إجمالي المتسوق؛ أما الإخفاء فلا.

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

* **[كائن السلة](/ar/aftersell/cart/sdk-cart-object)**: ما الذي يعيده `getCart()`.
* **[الأحداث](/ar/aftersell/cart/sdk-events)**: متى تنفّذ هذه الإجراءات.
* **[الخطافات](/ar/aftersell/cart/sdk-hooks)**: غيّر كيفية عرض البند بدلًا من تغيير السلة.
* **[حالات الاستخدام](/ar/aftersell/cart/sdk-use-cases)**: حلول كاملة للطلبات الشائعة.
