اتخطّى للمحتوى

المرحلة 03 · الكتالوج والتجارةدرس 15 من 3415 دقيقة قراءةآخر تحديث:

Lesson 15 / 34

Pricing & Promotionsالتسعير والعروض.

إزاي Magento بيوصل للسعر النهائي. أنواع الأسعار وترتيب أولويتها، الفرق بين عروض الكتالوج وعروض السلة، الـ price indexer، والضرايب.

● حرج تجارياً سلّم الأسعار Catalog vs Cart الفهرسة

التسعير في Magento 2 بيبدأ من الـ price، والـ final_price هو الأقل بينه وبين الـ special_price والـ tier_price وسعر الـ Catalog Price Rule، وده اللي بيظهر في الكتالوج والفلاتر ومحتاج فهرسة. الـ Cart Price Rules والكوبونات بتخصم من الإجمالي في السلة كسطر منفصل من غير ما تغيّر سعر المنتج. في الكود استخدم حقول base_ للمنطق.

// ليه ده موضوع حسّاس الأخطاء في التسعير بتكلّف فلوس فعلية — بيع بأقل من التكلفة، أو خصومات بتتراكم على بعض، أو عميل بيشوف سعر ويدفع تاني. والأسوأ إن الأخطاء دي مابتظهرش في الـ logs — بتظهر في تقرير الأرباح آخر الشهر أو في شكوى عميل. افهم ترتيب الأولوية كويس قبل ما تلمس أي حاجة.
◆ Part 1 — الفهم
01

أنواع الأسعار

فيه أكتر من "سعر" على المنتج الواحد.

price type
price
السعر الأساسي. نقطة البداية لكل حساب.
امتىالسعر العادي للمنتج.
special_price
سعر خاص مؤقت، بتاريخ بداية ونهاية اختياريين.
امتىتخفيض على منتج محدد لفترة. أبسط من قاعدة كاملة.
tier_price
سعر حسب الكمية ومجموعة العميل. "اشتري 10 بسعر أقل".
امتىالبيع بالجملة، أو تسعير مختلف لمجموعات العملاء.
cost
تكلفة المنتج. مابتظهرش للعميل.
امتىتقارير الأرباح. حقل داخلي بحت.
final_price
الناتج المحسوب بعد كل القواعد. مش حقل بتملاه.
امتىده اللي العميل بيشوفه فعلاً.
msrp
السعر الموصى به من المصنّع.
امتىعرض "السعر الأصلي" مشطوب جنب سعرك.
!
الـ cost مابيظهرش للعميل في الواجهة — بس ممكن يتسرّب في الـ API. لو عملت endpoint بيرجّع كل حقول المنتج، التكلفة والهامش هيروحوا للتطبيق. حدّد الحقول الراجعة صراحةً، خصوصاً في GraphQL.
• • •
02

سلّم الأولوية

أهم قسم — إزاي Magento بيقرّر السعر النهائي.

القاعدة

Magento بيبدأ بالسعر الأساسي وبيمرّ على الطبقات. في كل طبقة، بياخد الأقل عادة — بس الترتيب نفسه مهم لأن كل طبقة بتشتغل على ناتج اللي قبلها.

1 price السعر الأساسي — نقطة البداية
2 special_price / tier_price الأقل بينهم بياخد الأولوية
3 Catalog Price Rule بتشتغل على الناتج من فوق
↓ = final_price
4 Cart Price Rule في السلة — بتخصم من الإجمالي مش من سعر المنتج
الفرق الجوهري بين 3 و 4

الطبقات 1–3 بتحدد final_price — السعر اللي بيظهر في صفحة المنتج وفي القوائم. الطبقة 4 مابتغيّرش سعر المنتج، بتضيف خصم على مستوى السلة.

تشبيه زي سوبر ماركت. سعر المنتج على الرف بعد التخفيضات هو الـ final_price — ده اللي شايفه وإنت بتتفرج. لما توصل الكاشير وتقول "عندي كوبون خصم 10%"، ده cart rule — الخصم بيتحسب على إجمالي الفاتورة، والسعر على الرف مااتغيّرش.
مثال محسوب
منتج سعره 1000text
price          = 1000
special_price  =  800   # الأقل، فياخد الأولوية
                        # → 800

catalog rule: خصم 10%   # بتشتغل على الـ 800
                        # → 720  = final_price

# العميل بيشوف 720 في صفحة المنتج

cart rule: خصم 50 ج     # على مستوى السلة
                        # → الإجمالي 670

# بس سعر المنتج في السلة لسه بيتعرض 720
# والخصم بيظهر كسطر منفصل في الإجماليات
!
لاحظ إن الـ catalog rule اشتغلت على الـ 800 مش الـ 1000. ده بيلخبط الناس كتير لما يحسبوا هامش الربح — خصم 10% على منتج عليه خصم خاص أصلاً بيطلع أقل من المتوقع. الخصومات بتتراكم، مش بتتنافس.
• • •
03

الـ Scope والعملات

فين السعر بيختلف، وليه الـ base مهمة.

نطاق السعر

بيتحدد من Stores → Configuration → Catalog → Price → Catalog Price Scope، وله قيمتين.

Global

سعر واحد لكل المتاجر. أبسط في الإدارة.

Website

سعر مختلف لكل website. للأسواق المختلفة.

!
تغيير النطاق ده بعد ما المتجر يشتغل بيأثر على كل الأسعار الموجودة. لو غيّرت من global لـ website، الأسعار الموجودة بتتنسخ — وأي تعديل بعدها بيبقى على مستوى الـ website بس. قرار يتاخد من الأول.
العملة — الـ base مقابل العرض
currency
Base Currency
عملة التخزين والمحاسبة. كل الأرقام الحقيقية بيها.
استخدمهافي كل المنطق الحسابي والمقارنات.
Display Currency
العملة اللي العميل بيشوفها، بتتحوّل بسعر الصرف.
استخدمهافي العرض بس.
غلط — مقارنة بعملة العرضphp
if ($quote->getGrandTotal() > 500) {
    // 500 بأي عملة؟ النتيجة بتختلف
    // حسب العملة اللي العميل مختارها
}
صح — بالعملة الأساسيةphp
if ($quote->getBaseGrandTotal() > 500) {
    // 500 بالعملة الأساسية — ثابت دايماً
}
i
قاعدة بسيطة: أي حقل ليه نسخة بـ base_ — استخدم نسخة الـ base في الكود، والعادية في العرض. لو المتجر بعملة واحدة الفرق مش هيبان، بس أول ما تضيف عملة تانية الكود اللي مش ماشي على القاعدة دي هيبدأ يحسب غلط بصمت.
• • •
◆ Part 2 — العروض
04

Catalog Price Rules

خصومات بتغيّر سعر المنتج نفسه.

إيه هي

قاعدة بتطبّق خصم على منتجات بتنطبق عليها شروط، والخصم بيظهر في سعر المنتج نفسه — في صفحة المنتج وفي القوائم والفلاتر.

مكوّناتها
  • الشروط — على خصائص المنتج (القسم، الماركة، السعر).
  • الإجراء — نسبة مئوية، مبلغ ثابت، أو سعر ثابت.
  • النطاق — websites ومجموعات عملاء محددة.
  • التواريخ — بداية ونهاية.
  • الأولوية — لما أكتر من قاعدة تنطبق.
الميزة الأهم

لأن الخصم بيدخل في الـ final_price، فهو بيظهر في الفلاتر والترتيب بالسعر. لو فلترت "أقل من 500"، المنتج اللي بقى 450 بعد الخصم هيظهر.

!
القواعد دي محتاجة تطبيق وفهرسة. بعد ما تعمل قاعدة، لازم تتطبّق (Apply Rules) والفهرس يتحدّث. لو الخصم مش ظاهر، ده أول سبب تشيّك عليه — مش الكود.
التطبيق من سطر الأوامرbash
# إعادة فهرسة أسعار الكتالوج
bin/magento indexer:reindex catalog_rule

# وفهرس الأسعار العام
bin/magento indexer:reindex catalog_product_price

bin/magento cache:clean
امتى تستخدمها
  • تخفيض على فئة كاملة — "خصم 20% على كل الشتوي".
  • تسعير خاص لمجموعة عملاء — أسعار الجملة.
  • لما تحتاج الخصم يظهر في الفلاتر.
• • •
05

Cart Price Rules

خصومات على مستوى السلة.

إيه هي

قاعدة بتطبّق خصم على السلة لما شروط تتحقق — إجمالي معيّن، عدد أصناف، منتج محدد موجود. الخصم بيظهر كسطر منفصل في الإجماليات.

أنواع الإجراءات
action
نسبة من المنتج
خصم بنسبة على المنتجات المطابقة.
مثال"خصم 15% على الأحذية".
مبلغ ثابت
مبلغ محدد يتخصم من كل منتج مطابق.
مثال"خصم 20 ج على كل قطعة".
مبلغ ثابت من السلة
مبلغ واحد يتخصم من الإجمالي.
مثال"خصم 100 ج على الطلب".
اشترِ X واحصل على Y
منتجات مجانية بناءً على الكمية.
مثال"اشتري 2 خد 1 مجاناً".
الشروط المتاحة

أقوى من الـ catalog rules — تقدر تشترط على الإجمالي، عدد الأصناف، الوزن، بلد الشحن، مجموعة العميل، وجود منتج معيّن.

إعدادان مهمان
setting
Discard subsequent rules
لو مفعّل، القواعد اللي بعده مابتشتغلش.
مهمده اللي بيمنع تراكم الخصومات. استخدمه مع الأولوية.
Priority
ترتيب التطبيق. الرقم الأقل بيتطبّق الأول.
مهمبيحدد أي قاعدة تكسب لما تتعارض.
!
سيناريو بيحصل كتير: عندك 3 قواعد شغّالة، والعميل بيستوفي شروط التلاتة. من غير Discard subsequent rules، الخصومات بتتجمع كلها — وممكن الإجمالي يوصل صفر أو بالسالب. راجع القواعد النشطة مع بعض مش كل واحدة لوحدها.
• • •
06

الفرق والتفاعل بينهم

أهم مقارنة في الموضوع كله.

dimension
إيه اللي بيتغيّر
Catalog: سعر المنتج نفسه · Cart: خصم على الإجمالي
الأثرالأولى بتغيّر final_price، التانية لأ.
فين بيظهر
Catalog: صفحة المنتج والقوائم · Cart: في السلة بس
الأثرالـ catalog بتجذب العميل من الكتالوج.
الفلاتر والترتيب
Catalog: بتدخل فيهم · Cart: لأ
الأثرفرق مهم للـ SEO وتجربة التصفّح.
الشروط
Catalog: على خصائص المنتج · Cart: على السلة كلها
الأثرالـ cart أقوى وأمرن.
الكوبونات
Catalog: مافيش · Cart: نعم
الأثرأي حاجة بكود خصم = cart rule.
الفهرسة
Catalog: محتاجة فهرسة · Cart: فورية
الأثرالـ cart rules بتشتغل لحظياً.
إزاي بيتفاعلوا

الـ cart rule بتشتغل على الـ final_price اللي طلع من الـ catalog rule. يعني بيتراكموا.

مثال التراكمtext
السعر            1000
catalog rule -20%  → 800   (final_price)
cart rule    -10%  → 720   (الإجمالي)

# الخصم الفعلي 28% مش 30%
# لأن التانية اشتغلت على 800 مش 1000
!
الفرق بين 28% و30% صغير في المثال ده، بس على حجم مبيعات كبير أو خصومات أعلى بيبقى فرق ملموس في الهامش. ولو فيه 3 أو 4 قواعد متراكمة، الحسبة بتبقى صعبة التتبّع — اختبر السيناريوهات الحقيقية بسلة فعلية قبل إطلاق أي حملة.
القاعدة العملية للاختيار

Catalog Rule

لما عايز الخصم يبان في الكتالوج ويجذب العميل من الأول.

Cart Rule

لما الخصم مشروط بالسلة — إجمالي معيّن، كوبون، شحن مجاني.

• • •
07

الكوبونات

نوع خاص من الـ cart rules.

coupon type
بدون كوبون
القاعدة بتشتغل تلقائياً لما الشروط تتحقق.
امتى"شحن مجاني فوق 500".
كود ثابت
كود واحد للجميع.
امتىالحملات العامة — SUMMER20.
أكواد مولّدة
أكواد فريدة لكل عميل.
امتىحملات شخصية، أو تعويض عميل.
حدود الاستخدام — مهمة جداً
limit
Uses per Coupon
إجمالي مرات استخدام الكود.
حذرمن غيره، كود واحد ممكن يستخدم آلاف المرات لو اتسرّب.
Uses per Customer
كام مرة العميل الواحد يستخدمه.
حذرمن غيره، عميل واحد يستخدمه كل يوم.
تاريخ الانتهاء
آخر يوم للاستخدام.
امتىدايماً حطّه. كوبون بدون نهاية بيفضل شغّال للأبد.
!
الـ Uses per Customer بيشتغل على العملاء المسجّلين بس. الضيوف مالهمش هوية ثابتة، فالحد مابيتطبّقش عليهم بنفس الفعالية. لو الكوبون قيمته عالية، اشترط تسجيل الدخول — وإلا حد ممكن يستخدمه مرات كتير كضيف بإيميلات مختلفة.
• • •
◆ Part 3 — التقني
08

الـ Price Indexer

ليه الأسعار محتاجة فهرسة أصلاً.

المشكلة

حساب الـ final_price لمنتج واحد بيحتاج: السعر، الـ special، الـ tier، مجموعة العميل، الـ website، والقواعد المنطبقة. عمل ده لكل منتج في صفحة قسم مكلّف جداً.

الحل

Magento بيحسب الأسعار مقدماً ويحطها في جدول مسطّح. صفحة القسم بتقرا من الجدول ده مباشرة.

تغيير سعر
الفهرس يتعلّم invalid
إعادة فهرسة
السعر الجديد ظاهر
indexer
catalog_product_price
الأسعار النهائية لكل منتج ومجموعة عميل و website.
بيتأثر بـأي تغيير سعر أو tier أو special.
catalog_rule_product
أي قاعدة كتالوج بتنطبق على أي منتج.
بيتأثر بـإنشاء أو تعديل catalog price rule.
التشخيصbash
# حالة الفهارس
bin/magento indexer:status

# إعادة فهرسة الأسعار
bin/magento indexer:reindex catalog_product_price
bin/magento indexer:reindex catalog_rule_product

# شوف السعر المفهرس فعلاً
# SELECT * FROM catalog_product_index_price
# WHERE entity_id = 42;
!
السبب الأول لـ "غيّرت السعر ومش ظاهر": الفهرس مش متحدّث. قبل ما تفتح أي كود، شغّل indexer:status وشوف لو فيه فهرس invalid. ولو الفهارس على Update on Schedule، تأكد إن الـ cron شغّال.
i
الاستعلام الأخير مفيد جداً في التشخيص — بيوريك السعر اللي Magento فعلاً بيستخدمه لكل مجموعة عميل و website. لو الرقم هناك غلط، المشكلة في الفهرسة. لو صح والعميل شايف غير كده، المشكلة في الكاش.
• • •
09

التسعير في الكود

قراءة الأسعار والتدخّل فيها.

الطريقة الحديثة — Price Objectsphp
use Magento\Catalog\Pricing\Price\FinalPrice;
use Magento\Catalog\Pricing\Price\RegularPrice;

// السعر النهائي بعد كل القواعد
$final = $product
    ->getPriceInfo()
    ->getPrice(FinalPrice::PRICE_CODE)
    ->getValue();

// السعر الأساسي قبل الخصومات
$regular = $product
    ->getPriceInfo()
    ->getPrice(RegularPrice::PRICE_CODE)
    ->getValue();

// فيه خصم؟
$hasDiscount = $final < $regular;
الطريقة القديمة — لسه شغّالةphp
$product->getPrice();       // الأساسي
$product->getFinalPrice();  // بعد الخصومات
$product->getSpecialPrice();

// ملاحظة: getFinalPrice مابتاخدش في الاعتبار
// الـ cart rules — دي على مستوى السلة
!
لو المنتج اتحمّل من collection، الأسعار ممكن ماتكونش محمّلة. استخدم addPriceData() على الـ collection، وإلا getFinalPrice() هترجّع السعر الأساسي من غير الخصومات — وده خطأ صامت خطير لأن الرقم بيبان معقول.
الخيارات المتاحة
approach
Catalog Price Rule
من الأدمن، من غير كود.
الأفضللو الشروط تقدر تتعبّر عنها بقاعدة. جرّبها الأول دايماً.
Custom Price في السلة
setCustomPrice() على الصنف.
امتىتسعير خاص لحالة معيّنة. لازم setOriginalCustomPrice() كمان.
Total Collector
إضافة رسم أو خصم كسطر في الإجماليات.
امتىرسوم إضافية — تغليف، خدمة.
Plugin على السعر
اعتراض حساب السعر.
أخيرمكلّف على الأداء — بيتنده لكل منتج في كل صفحة.
السعر المخصّص بشكل صحيحphp
$item = $quote->getItemById($itemId);

// الاتنين مع بعض — مهم
$item->setCustomPrice($newPrice);
$item->setOriginalCustomPrice($newPrice);

// عشان السعر ما يترجعش
$item->getProduct()->setIsSuperMode(true);

$quote->collectTotals();
$this->cartRepository->save($quote);
!
التلات سطور دول لازم مع بعض. لو حطّيت setCustomPrice لوحدها، السعر بيترجع لسعر الكتالوج مع أول collectTotals() — وده بيحصل كتير في الـ checkout، فالعميل ممكن يشوف السعر المخصّص وبعدين يدفع السعر العادي.
• • •
10

الضرايب

الجزء اللي بيلخبط في الحسبة.

المكوّنات الثلاثة
  • Tax Class — تصنيف للمنتج وللعميل.
  • Tax Rate — النسبة لمنطقة جغرافية.
  • Tax Rule — بتربط التلاتة: منتج + عميل + منطقة = نسبة.
أهم إعداد — السعر شامل الضريبة ولا لأ

Excluding Tax

السعر المدخل بدون ضريبة، وبتتضاف عند الحساب. شائع في أمريكا.

Including Tax

السعر المدخل شامل الضريبة. شائع في أوروبا والخليج.

!
الإعداد ده بيغيّر معنى كل سعر في المتجر. لو غيّرته بعد ما تدخل الأسعار، كل الأرقام هتبقى غلط — إما بتحصّل ضريبة زيادة أو بتخسر قيمتها. اتفق عليه مع المحاسبة قبل إدخال أي منتج.
ترتيب الضريبة والخصم

الضريبة بتتحسب على المبلغ بعد الخصم. ده الترتيب الصح محاسبياً — العميل مايدفعش ضريبة على فلوس ماخدهاش.

مثالtext
السعر          1000
خصم 10%        -100
                ────
الصافي          900
ضريبة 15%      +135   # على 900 مش 1000
                ────
الإجمالي       1035
i
الترتيب ده بيتحدد في إعدادات الضريبة (Calculation Settings). التغيير فيه ليه أثر قانوني ومحاسبي — ماتغيّرهوش من غير الرجوع للمحاسبة.
• • •
◆ Part 4 — الخلاصة
11

الفخاخ الشائعة

اقرا دي حتى لو مش هتقرا حاجة تانية.

  • نسيان إعادة الفهرسة — السبب الأول لـ "غيّرت السعر ومش ظاهر".
  • خصومات متراكمة بدون Discard subsequent rules — إجمالي أقل من المتوقع أو صفر.
  • استخدام getGrandTotal بدل getBaseGrandTotal في المنطق — بيكسر المتاجر متعددة العملات.
  • setCustomPrice من غير setOriginalCustomPrice — السعر بيترجع، والعميل يدفع غير اللي شافه.
  • قراءة السعر من collection بدون addPriceData — بترجّع السعر الأساسي بدون خصومات، بصمت.
  • كوبون بدون حد استخدام أو تاريخ انتهاء — خسارة كبيرة لو اتسرّب.
  • الاعتماد على Uses per Customer مع الضيوف — الحد مابيتطبّقش بفعالية.
  • plugin على حساب السعر — بيتنده لكل منتج في كل صفحة. جرّب catalog rule الأول.
  • تغيير نطاق السعر أو إعداد الضريبة بعد التشغيل — بيأثر على كل الأسعار الموجودة.
  • كشف cost في الـ API — تسريب بيانات تجارية حسّاسة.
i
لو سعر طالع غلط، اسأل بالترتيب: الفهرس متحدّث؟الكاش اتمسح؟فيه كام قاعدة منطبقة؟بقرا base ولا display؟ الأربعة دول بيحلّوا أغلب الحالات.
• • •
12

أسئلة الإنترفيو

الأسئلة المتكررة.

Q1إيه الفرق بين Catalog و Cart Price Rules؟
الإجابة: الـ catalog بتغيّر سعر المنتج نفسه، فبتظهر في صفحة المنتج والقوائم والفلاتر، ومحتاجة فهرسة. الـ cart بتضيف خصم على مستوى السلة كسطر منفصل، شروطها على السلة كلها، وبتدعم الكوبونات، وبتشتغل لحظياً.
Q2إزاي Magento بيوصل للـ final_price؟
الإجابة: بيبدأ بالـ price، بعدين بياخد الأقل بين الـ special_price والـ tier_price، وبعدين بيطبّق الـ catalog rules على الناتج. المهم إن كل طبقة بتشتغل على ناتج اللي قبلها — الخصومات بتتراكم مش بتتنافس.
Q3غيّرت سعر والعميل لسه شايف القديم — ليه؟
الإجابة: بالترتيب: الفهرس (catalog_product_price) مش متحدّث، أو الـ cron واقف لو الفهارس على Schedule، أو الكاش (FPC) مش متمسوح. بشيّك indexer:status الأول قبل أي حاجة تانية.
Q4ليه تستخدم base_price في الكود؟
الإجابة: لأن الـ base بالعملة الأساسية الثابتة، والعادي بعملة العرض اللي بتتغيّر حسب اختيار العميل. أي مقارنة أو حساب بعملة العرض بيدي نتيجة مختلفة حسب العملة — والخطأ ده صامت ومابيظهرش إلا لما تضيف عملة تانية.
Q5عايز خصم لمجموعة عملاء معيّنة — إزاي؟
الإجابة: تلات خيارات: tier price على المنتج لمجموعة محددة (أبسط، لمنتجات قليلة)، أو catalog price rule بشرط المجموعة (الأنسب لفئات كاملة)، أو cart rule لو الخصم مشروط بالسلة. الأفضل catalog rule لو عايز الخصم يبان في الكتالوج.
Q6الضريبة بتتحسب قبل الخصم ولا بعده؟
الإجابة: بعد الخصم — على الصافي. ده الصح محاسبياً لأن العميل مايدفعش ضريبة على مبلغ ماخدهوش. الترتيب بيتحدد في إعدادات حساب الضريبة، وتغييره ليه أثر قانوني فمايتغيّرش من غير الرجوع للمحاسبة.

Pricing & Promotions ✓

دلوقتي فاهم سلّم الأسعار وترتيب أولويته، الفرق بين عروض الكتالوج والسلة وإزاي بيتراكموا، الـ price indexer، والتسعير في الكود والضرايب.

الخلاصة: الخصومات بتتراكم على ناتج بعض، والـ catalog rule بتغيّر السعر نفسه والـ cart rule بتخصم من الإجمالي، والفهرسة هي أول مكان تشوفه لما سعر مايظهرش.

// magento 2 · pricing · rules · indexer

خلّصت الدرس؟علّمه عشان تتابع تقدّمك في الكورس.

كاتب الدرس

Abdulrahman Masoud

عندك سؤال على الدرس أو محتاج مساعدة في مشروع Magento؟ كلّمني.

أسئلة شائعة

إيه الفرق بين Catalog Price Rule و Cart Price Rule في Magento 2؟

الـ Catalog Rule بتغيّر سعر المنتج نفسه، فالخصم بيظهر في صفحة المنتج والقوائم والفلاتر والترتيب بالسعر، وشروطها على خصائص المنتج ومحتاجة فهرسة. الـ Cart Rule بتضيف خصم على مستوى السلة كسطر منفصل في الإجماليات، شروطها على السلة كلها زي الإجمالي وبلد الشحن، وهي الوحيدة اللي بتدعم الكوبونات وبتشتغل لحظيًا.

إزاي Magento 2 بيحسب الـ final_price؟

بياخد الأقل بين السعر الأساسي والـ special_price لو في فترته والـ tier_price المناسب لمجموعة العميل والكمية، وسعر الـ Catalog Rule المحسوب من السعر الأساسي. يعني منتج بـ 1000 عليه special 800 وقاعدة 10% بيبقى سعره 800 مش 720، لأن القاعدة والسعر الخاص بيتنافسوا مش بيتراكموا. اللي بيتراكم فعلًا هو الـ Cart Rule لأنها بتخصم من الـ final_price في السلة.

غيّرت السعر في Magento والعميل لسه شايف القديم، ليه؟

غالبًا الفهرس. الأسعار بتتحسب مقدمًا في جدول catalog_product_index_price، فلو الفهرس invalid أو على Update on Schedule والـ cron واقف، السعر القديم بيفضل. شغّل indexer:status وبعدين indexer:reindex catalog_product_price، ولو الخصم من Catalog Rule أعد فهرسة catalogrule_rule كمان. لو الفهرس صح والعميل شايف غيره، المشكلة في الـ Full Page Cache.

ليه أستخدم getBaseGrandTotal بدل getGrandTotal في الكود؟

لأن أي حقل ليه نسخة base_ متخزّن بالعملة الأساسية الثابتة، والنسخة العادية بعملة العرض اللي بتتحوّل بسعر الصرف حسب اختيار العميل. مقارنة زي الإجمالي أكبر من 500 بعملة العرض بتدي نتيجة مختلفة لكل عملة. استخدم نسخة الـ base في المنطق والمقارنات والعادية في العرض بس، وإلا الكود هيحسب غلط بصمت أول ما تضيف عملة تانية.

إزاي أحط سعر مخصّص لصنف في السلة برمجيًا؟

على الـ quote item نادي setCustomPrice($price) و setOriginalCustomPrice($price) مع بعض، و$item->getProduct()->setIsSuperMode(true)، وبعدين $quote->collectTotals() واحفظ الـ quote. لو حطّيت setCustomPrice لوحدها السعر بيترجع لسعر الكتالوج مع أول collectTotals، وده بيحصل كتير في الـ checkout فالعميل يشوف سعر ويدفع غيره.

ليه خصومات الـ Cart Rules بتتجمّع على بعض في Magento؟

لأن كل قاعدة شروطها متحقّقة بتتطبّق بالترتيب حسب Priority، والرقم الأقل الأول. عشان تمنع التراكم فعّل Discard subsequent rules في القاعدة اللي المفروض تكسب، فالقواعد اللي بعدها مابتشتغلش. من غيره ممكن تلات قواعد يتجمّعوا والإجمالي يوصل صفر. راجع القواعد النشطة مع بعض بسلة حقيقية قبل أي حملة.

إزاي أحمي الكوبونات من الاستغلال في Magento 2؟

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