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

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

Lesson 13 / 34

Product Typesالستة وأكتر.

كل نوع منتج في Magento — إزاي بيشتغل من جوّه، امتى تستخدمه، وإزاي بيتصرّف في السلة والتسعير والمخزون. وفي الآخر، إزاي تعمل نوع مخصّص بنفسك.

● 6 أنواع امتى تستخدم كل واحد السلة والتسعير نوع مخصّص

Magento 2 فيه ستة أنواع منتجات: Simple منتج واحد بسعر ومخزون، Configurable أب بيبيع أبناءه الـ simple حسب اختيار العميل، Bundle العميل بيركّبه من مجموعات اختيار، Grouped عرض لمنتجات مستقلة مع بعض، Virtual من غير شحن، و Downloadable بملفات بتتحمّل بعد الشراء. النوع بيحدد التسعير والمخزون وشكل السلة، وتغييره بعد البيع صعب.

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

الصورة الكاملة

الستة أنواع في نظرة واحدة.

type
simple
منتج واحد بسعر واحد و SKU واحد.
مثالكتاب، كوباية، منتج مالوش اختيارات.
configurable
منتج أب بيخلّي العميل يختار بين منتجات simple.
مثالتيشيرت بمقاسات وألوان — كل تركيبة منتج simple مستقل.
bundle
مجموعة يركّبها العميل من خيارات تحددها إنت.
مثالكمبيوتر: تختار المعالج والرام والهارد.
grouped
منتجات منفصلة معروضة مع بعض في صفحة واحدة.
مثالطقم أدوات مطبخ — كل قطعة تتشترى لوحدها.
virtual
منتج مالوش شحن — خدمة أو ضمان.
مثالاشتراك، تركيب، ضمان ممتد.
downloadable
ملف بيتحمّل بعد الشراء.
مثالكتاب إلكتروني، برنامج، ملف صوتي.
التقسيمة الذهنية

فكّر فيهم كـ 3 مجموعات: منتج واحد (simple, virtual, downloadable)، ومنتج مركّب من منتجات تانية (configurable, bundle)، ومنتج بيعرض منتجات تانية بس (grouped).

i
الـ simple هو أساس كل حاجة. الـ configurable والـ bundle والـ grouped كلهم في النهاية بيبيعوا منتجات simple — الفرق بس في إزاي العميل بيوصل لها وإزاي بتتعرض.
• • •
◆ Part 2 — الأنواع بالتفصيل
02

Simple

الأساس — وأكتر نوع هتستخدمه.

إيه هو

منتج مادي واحد له SKU واحد وسعر واحد ومخزون واحد. مفيش اختيارات ولا تركيبات.

البنية
Simple Product
سعر · مخزون · SKU
التسعير

سعر مباشر. ممكن يكون عليه special_price (سعر خاص) أو tier prices (أسعار بالكمية).

المخزون

كمية مباشرة. بتتخصم عند الشراء بشكل مباشر.

في السلة

سطر واحد. الكمية × السعر. أبسط حالة ممكنة.

امتى تستخدمه
  • المنتج مالوش أي اختيارات — كتاب، علبة، قطعة.
  • أو كـ ابن داخل configurable (وده الاستخدام الأكتر شيوعاً فعلياً).
i
الـ simple ممكن يكون عليه Custom Options — حقول إضافية زي "اكتب اسمك على المنتج". دي مش نوع منفصل، بس ميزة على أي منتج، وبتأثر على السعر من غير ما تحتاج منتجات منفصلة. مناسبة للتخصيصات البسيطة.
• • •
03

Configurable

أهم نوع بعد الـ simple — وأكتر واحد بيلخبط.

إيه هو

منتج أب بيعرض اختيارات (مقاس، لون)، وكل تركيبة بتشاور على منتج simple حقيقي. العميل بيختار، والـ simple المناسب هو اللي بيتحط في السلة فعلياً.

الأب (اللي العميل بيشوفه)
T-Shirt (configurable)
الأبناء (اللي بيتباع فعلاً)
S / أحمر
M / أحمر
S / أزرق
M / أزرق
تشبيه زي قائمة طعام في مطعم. القائمة بتعرض "بيتزا" باختيارات حجم وإضافات. بس اللي بيتعمل في المطبخ فعلاً هو صنف محدد — بيتزا وسط بالجبنة. القائمة هي الأب، والصنف المحدد هو الابن.
الشرط الأساسي

الخصائص اللي بتفرّق بين الأبناء (المقاس واللون) لازم تكون:

  • نوعها select (قائمة منسدلة).
  • الـ scope بتاعها Global.
  • apply_to شاملة الـ simple والـ configurable.
!
لو الخاصية مش مستوفية التلات شروط دي، مش هتظهر في قائمة الخصائص وإنت بتعمل الـ configurable — ومش هيبقى واضح ليه. دي أشهر حيرة مع النوع ده.
التسعير

السعر المعروض بيجي من الأبناء مش من الأب. Magento بيعرض أقل سعر أو نطاق ("من 100 لـ 150"). لما العميل يختار، السعر بيتحدّث للابن المختار.

المخزون

المخزون على الأبناء. الأب بيبقى متاح طالما ابن واحد على الأقل متاح. لو كل الأبناء خلصوا، الأب بيختفي.

في السلة

بيتحط سطرين جوّه Magento — الأب (المعروض) والابن (الفعلي). العميل بيشوف سطر واحد، بس الكود بيشوف الاتنين.

!
ده سبب الفرق بين getAllItems() وgetAllVisibleItems() اللي اتكلمنا عنه في درس الـ Quote. لو حسبت إجمالي على getAllItems() مع configurable، هتحسب السعر مرتين.
امتى تستخدمه
  • المنتج له تنويعات محددة ولكل تنويعة مخزون منفصل.
  • عايز التنويعات تظهر في الفلاتر (فلتر باللون مثلاً).
  • كل تنويعة ليها SKU خاص للتتبّع في المخزن.
i
لو التنويعات مالهاش مخزون منفصل ومش محتاجة تظهر في الفلاتر، الـ Custom Options على منتج simple أبسط بكتير — بتوفّر عليك عشرات المنتجات وتعقيد الإدارة.
• • •
04

Bundle

العميل بيركّب منتجه بنفسه.

إيه هو

منتج بيتكوّن من مجموعات اختيارات، وكل مجموعة فيها منتجات. العميل بيختار من كل مجموعة، والناتج منتج مركّب واحد.

الحزمة
Gaming PC (bundle)
مجموعات الاختيار
المعالج
الرام
الهارد
كل مجموعة فيها منتجات simple
تشبيه زي وجبة في مطعم بتختار مكوّناتها — تختار نوع الساندويتش، والمشروب، والإضافة. النتيجة وجبة واحدة بسعر مجمّع، بس أنت اللي ركّبتها.
التسعير — نوعان

Dynamic

السعر = مجموع المختارات. بيتغيّر مع كل اختيار.

Fixed

سعر ثابت للحزمة، والاختيارات ممكن تضيف فرق سعر.

المخزون

بيتخصم من كل منتج مكوّن على حدة. والحزمة بتبقى متاحة طالما كل الخيارات الإلزامية متاحة.

في السلة

سطر واحد ظاهر للعميل (الحزمة)، وجوّاه أسطر للمكوّنات. نفس منطق الأب والأبناء.

امتى تستخدمه
  • العميل بيركّب المنتج من خيارات محددة.
  • عايز تبيع مجموعة بسعر مجمّع.
  • المكوّنات ليها مخزون منفصل بتتابعه.
!
الـ bundle أتقل نوع على الأداء. حساب السعر بيحتاج تحميل كل الخيارات وكل منتجاتها. صفحة قسم فيها bundles كتير بتبقى أبطأ بشكل ملحوظ — فمتستخدمهوش إلا لما تحتاجه فعلاً.
• • •
05

Grouped

أبسط الأنواع المركّبة — وأقلها استخداماً.

إيه هو

مجرد عرض لمنتجات منفصلة في صفحة واحدة. كل منتج بيفضل مستقل تماماً — بسعره ومخزونه — والعميل بيحدد كمية لكل واحد.

المجموعة (عرض فقط)
طقم مطبخ (grouped)
منتجات مستقلة تماماً
حلة
مقلاة
غطا
الفرق الجوهري عن الـ bundle

في الـ grouped، لما العميل يشتري، بيتحط في السلة أسطر منفصلة لكل منتج — كأنه اشتراهم واحد واحد. مفيش كيان مركّب.

Grouped

3 منتجات = 3 أسطر منفصلة في السلة. مفيش سعر للمجموعة.

Bundle

3 مكوّنات = سطر واحد بسعر مجمّع.

التسعير والمخزون

مفيش سعر للمجموعة نفسها. كل منتج بسعره ومخزونه المستقل.

امتى تستخدمه
  • منتجات مرتبطة بيشتريها العميل مع بعض عادة.
  • عايز تسهّل شراءهم من صفحة واحدة.
  • مش محتاج سعر مجمّع ولا كيان مركّب.
i
الـ grouped هو أقل نوع استخداماً عملياً. في معظم الحالات اللي بيفكّر الناس فيه، الأنسب يكون related products أو bundle حسب إذا كان محتاج سعر مجمّع ولا لأ.
• • •
06

Virtual و Downloadable

المنتجات غير المادية.

إيه هو

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

الأثر على الـ checkout

لو السلة كلها منتجات virtual، Magento بيتخطى خطوة الشحن تماماً — مفيش عنوان شحن ولا اختيار شركة شحن.

!
ده اللي بيخلّي $quote->isVirtual() مهمة. لو كودك بيفترض إن فيه عنوان شحن دايماً، هيقع مع السلة الافتراضية. شيّك دايماً قبل ما تقرا عنوان الشحن.
امتى تستخدمه
  • خدمات: تركيب، صيانة، استشارة.
  • ضمانات ممتدة.
  • اشتراكات وعضويات.
  • رسوم إضافية بتتباع كمنتج.
إيه هو

زي الـ virtual، بس بيرفق ملفات العميل بيحمّلها بعد الشراء.

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

بيتحدد بإعداد: عند الطلب أو عند الفاتورة (يعني بعد تأكيد الدفع). الافتراضي والأأمن هو بعد الفاتورة.

!
لو خليته يتاح عند الطلب مع طريقة دفع زي الدفع عند الاستلام، العميل ممكن يحمّل الملف ومايدفعش أبداً. خليه عند الفاتورة إلا لو كل طرق الدفع فورية.
• • •
◆ Part 3 — الاختيار والكود
07

المقارنة الشاملة

كل نوع في كل بُعد.

dimension
السعر
simple/virtual/downloadable: مباشر · configurable: من الابن · bundle: مجمّع أو ثابت · grouped: مفيش سعر للمجموعة
ملاحظةالـ configurable والـ bundle بيعرضوا نطاق سعر في القوائم.
المخزون
simple: مباشر · configurable: على الأبناء · bundle: على المكوّنات · grouped: كل منتج مستقل
ملاحظةالأب في الـ configurable مالوش مخزون خاص.
في السلة
simple: سطر · configurable/bundle: أب + أبناء · grouped: أسطر منفصلة
ملاحظةده سبب الفرق بين getAllItems وgetAllVisibleItems.
الشحن
simple/configurable/bundle/grouped: نعم · virtual/downloadable: لأ
ملاحظةسلة كلها virtual بتتخطى خطوة الشحن.
الفلاتر
configurable: بيظهر مع فلاتر أبنائه · الباقي: بخصائصه هو
ملاحظةميزة كبيرة للـ configurable — فلتر باللون بيلاقي الأب.
تكلفة الأداء
simple: الأخف · configurable: متوسط · bundle: الأتقل
تحذيرbundles كتير في صفحة قسم بتبطّئها بشكل ملحوظ.
• • •
08

إزاي أختار

شجرة قرار عملية.

  • المنتج بيتشحن؟ لأ → virtual، أو downloadable لو فيه ملف.
  • له تنويعات (مقاس/لون)؟ لأ → simple وخلاص.
  • كل تنويعة ليها مخزون و SKU منفصل؟ أيوة → configurable.
  • لأ، التنويعات بسيطة؟simple + Custom Options.
  • العميل بيركّب من مجموعات اختيار؟bundle.
  • عايز تعرض منتجات مستقلة مع بعض بس؟grouped (أو related products).
القرار الأصعب: configurable ولا simple بـ custom options

Custom Options

أبسط بكتير. منتج واحد. بس مفيش مخزون منفصل ومش بيظهر في الفلاتر.

Configurable

منتج لكل تركيبة. مخزون منفصل وفلاتر شغّالة — بس إدارة أتقل.

i
القاعدة العملية: لو محتاج تتابع مخزون كل تنويعة أو العميل يفلتر بيها — خد configurable. غير كده، custom options هتوفّر عليك عشرات المنتجات وتعقيد إدارة مالوش لازمة.
!
تغيير نوع المنتج بعد ما يتباع صعب جداً. الأوردرات القديمة بتفضل مربوطة بالبنية القديمة، والتحويل ممكن يكسر تاريخ المبيعات. خد القرار ده بعناية من الأول.
• • •
09

التعامل معهم في الكود

الأنماط اللي هتحتاجها.

معرفة النوعphp
use Magento\Catalog\Model\Product\Type;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;

// الثوابت الجاهزة
Type::TYPE_SIMPLE    // 'simple'
Type::TYPE_VIRTUAL   // 'virtual'
Type::TYPE_BUNDLE    // 'bundle'
Configurable::TYPE_CODE  // 'configurable'

// الفحص
if ($product->getTypeId() === Configurable::TYPE_CODE) {
    // منطق خاص بالـ configurable
}

// فحوصات جاهزة مفيدة
$product->isVirtual();     // مالوش شحن؟
$product->isComposite();   // مركّب من منتجات تانية؟
$product->isSalable();     // متاح للبيع؟
التعامل مع الـ configurablephp
// الوصول لمنطق النوع
$typeInstance = $product->getTypeInstance();

// كل الأبناء (المنتجات الفعلية)
$children = $typeInstance->getUsedProducts($product);

foreach ($children as $child) {
    printf(
        "%s — %s\n",
        $child->getSku(),
        $child->getPrice()
    );
}

// الخصائص اللي بيتكوّن منها (المقاس، اللون)
$attributes = $typeInstance
    ->getConfigurableAttributes($product);

// العكس: من ابن للأب
$parentIds = $typeInstance
    ->getParentIdsByChild($childId);
التعامل مع الأصناف في السلةphp
// للعرض والعد — الآباء بس
foreach ($quote->getAllVisibleItems() as $item) {
    // ده اللي العميل شايفه
    printf("%s x%d\n", $item->getName(), $item->getQty());
}

// للمخزون والشحن — المنتجات الفعلية
foreach ($quote->getAllItems() as $item) {
    // تخطّى الآباء عشان متحسبش مرتين
    if ($item->getHasChildren()) {
        continue;
    }
    // ده المنتج اللي هيتشحن فعلاً
}
!
النمط ده (getAllItems مع تخطّي اللي ليه أبناء) هو الطريقة الصحيحة للحصول على المنتجات الفعلية. من غير الشيك، هتعدّ الأب والابن — وده بيسبب خصم مخزون مضاعف أو وزن شحن غلط.
• • •
10

عمل نوع مخصّص

لما الأنواع الموجودة ماتكفيش.

!
فكّر كويس قبل ما تعمل نوع جديد. النوع المخصّص بيحتاج شغل في التسعير والمخزون والسلة والفهرسة والأوردرات. في 90% من الحالات، نوع موجود + custom options أو خصائص إضافية بيحل المشكلة بجزء بسيط من الجهد.
etc/product_types.xmlxml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <type name="subscription"
    label="Subscription Product"
    modelInstance="Vendor\Module\Model\Product\Type\Subscription"
    indexPriority="40"
    sortOrder="50">

    <!-- نموذج حساب السعر -->
    <priceModel
      instance="Vendor\Module\Model\Product\Price\Subscription"/>

    <!-- منتج مالوش شحن -->
    <customAttributes>
      <attribute name="is_real_product" value="false"/>
    </customAttributes>
  </type>
</config>
شرح الإعدادات
  • name — كود النوع، وده اللي بيتخزّن في type_id.
  • modelInstance — الكلاس اللي فيه منطق النوع.
  • priceModel — كلاس حساب السعر (اختياري).
  • is_real_productfalse يعني مالوش شحن (زي virtual).
  • indexPriority — ترتيب المعالجة في الفهرسة.
Model/Product/Type/Subscription.phpphp
namespace Vendor\Module\Model\Product\Type;

use Magento\Catalog\Model\Product\Type\AbstractType;
use Magento\Catalog\Model\Product;
use Magento\Framework\DataObject;

class Subscription extends AbstractType
{
    public const TYPE_CODE = 'subscription';

    // هل المنتج ده بيتشحن؟
    public function isVirtual($product = null): bool
    {
        return true;
    }

    // هل محتاج وزن؟
    public function hasWeight(): bool
    {
        return false;
    }

    // التحقق قبل الإضافة للسلة
    public function _prepareProduct(
        DataObject $buyRequest,
        $product,
        $processMode
    ) {
        $result = parent::_prepareProduct(
            $buyRequest, $product, $processMode
        );

        // تحقق من مدة الاشتراك
        $months = (int) $buyRequest->getData('months');

        if ($months < 1) {
            // نص الخطأ بيرجع للعميل
            return __('Please choose a subscription period.');
        }

        // خزّن المدة مع الصنف
        $product->addCustomOption('months', $months);

        return $result;
    }
}
الميثودز اللي غالباً هتعدّلها
method
isVirtual()
هل المنتج بيتشحن.
امتىلو نوعك خدمة أو رقمي.
_prepareProduct()
التحقق ومعالجة الإضافة للسلة.
امتىالأهم — هنا بتتحقق من الاختيارات.
isSalable()
هل متاح للبيع.
امتىلو التوفّر بيتحدد بمنطق خاص.
isComposite()
هل مركّب من منتجات تانية.
امتىلو نوعك فيه أبناء.
hasWeight()
هل له وزن للشحن.
امتىمع الأنواع غير المادية.
i
بعد التعريف، شغّل setup:upgrade وcache:clean، والنوع هيظهر في قائمة أنواع المنتجات في الأدمن. وهتحتاج كمان واجهة إدخال في الأدمن لو نوعك ليه بيانات خاصة.
• • •
◆ Part 4 — الخلاصة
11

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

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

  • عد أصناف السلة بـ getAllItems مع configurable — حساب مضاعف. استخدم getAllVisibleItems للعرض.
  • خاصية مش Global في الـ configurable — مش هتظهر في قائمة الاختيارات، والسبب مش واضح.
  • افتراض وجود عنوان شحن دايماً — بيقع مع السلة الافتراضية. شيّك بـ isVirtual().
  • حساب المخزون على الأب في الـ configurable — المخزون على الأبناء، والأب مالوش كمية.
  • bundles كتير في صفحة قسم — بتبطّئها بشكل ملحوظ.
  • تغيير نوع منتج بعد ما اتباع — بيكسر ارتباط الأوردرات القديمة.
  • configurable بدل custom options لتنويعات مالهاش مخزون منفصل — تعقيد بلا فايدة.
  • downloadable متاح "عند الطلب" مع دفع عند الاستلام — تحميل بدون دفع.
  • نوع مخصّص من غير داعي — شغل كتير في التسعير والمخزون والفهرسة كان ممكن يتوفّر.
i
لو منتج بيتصرّف بشكل غريب، ابدأ بالسؤال عن نوعه. كتير من السلوكيات "الغريبة" هي السلوك الصحيح لنوع مختلف عن اللي إنت فاكره.
• • •
12

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

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

Q1إيه الفرق بين configurable و grouped و bundle؟
الإجابة: configurable — العميل بيختار تنويعة واحدة، والـ simple المناسب بيتباع. bundle — بيركّب منتج من مجموعات اختيار بسعر مجمّع. grouped — مجرد عرض لمنتجات مستقلة، وكل واحد بيتحط سطر منفصل في السلة.
Q2فين المخزون في الـ configurable؟
الإجابة: على الأبناء (الـ simple products). الأب مالوش مخزون خاص، وبيبقى متاح طالما ابن واحد على الأقل متاح. لو كل الأبناء خلصوا، الأب بيختفي من الكتالوج.
Q3امتى تستخدم custom options بدل configurable؟
الإجابة: لما التنويعات مالهاش مخزون منفصل ومش محتاجة تظهر في الفلاتر. الـ custom options أبسط بكتير — منتج واحد بدل عشرات. لو محتاج تتابع مخزون كل تنويعة أو العميل يفلتر بيها، خد configurable.
Q4ليه الـ configurable بيحط سطرين في السلة؟
الإجابة: سطر للأب (اللي العميل شايفه) وسطر للابن (المنتج الفعلي اللي هيتشحن ويتخصم من المخزون). عشان كده getAllVisibleItems بترجّع الآباء بس وgetAllItems بترجّع الاتنين.
Q5إزاي تعمل نوع منتج مخصّص؟
الإجابة: تعرّفه في etc/product_types.xml بكلاس بيورّث من AbstractType، وتعدّل الميثودز اللي تحتاجها زي isVirtual() و_prepareProduct(). بس الأهم إنك تتأكد إن محتاجه فعلاً — في معظم الحالات نوع موجود مع custom options بيكفي بجهد أقل بكتير.
Q6إيه اللي بيحصل لو السلة كلها منتجات virtual؟
الإجابة: Magento بيتخطى خطوة الشحن كاملة — مفيش عنوان شحن ولا اختيار شركة. عشان كده $quote->isVirtual() مهمة، وأي كود بيفترض وجود عنوان شحن لازم يشيّك عليها الأول.

Product Types ✓

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

الخلاصة: الـ simple هو أساس كل حاجة، والـ configurable بيبيع أبناءه، والنوع قرار صعب التراجع عنه بعد أول بيعة.

// magento 2 · product types · reference

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

كاتب الدرس

Abdulrahman Masoud

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

أسئلة شائعة

إيه الفرق بين Configurable و Bundle و Grouped في Magento 2؟

الـ Configurable منتج أب بيخلّي العميل يختار تنويعة واحدة زي المقاس واللون، والـ simple المناسب هو اللي بيتباع فعلًا. الـ Bundle بيخلّي العميل يركّب منتج من مجموعات اختيار بسعر مجمّع أو ثابت، وبيتحط سطر واحد في السلة. الـ Grouped مجرد عرض لمنتجات مستقلة في صفحة واحدة، وكل منتج بيتحط سطر منفصل بسعره ومخزونه.

فين المخزون في الـ Configurable Product؟

على الأبناء الـ simple، مش على الأب. الأب بيفضل متاح للبيع طالما ابن واحد على الأقل متاح، ولو كل الأبناء خلصوا الأب بيبقى out of stock. عشان كده لو بتحسب مخزون أو وزن شحن في الكود، لفّ على getAllItems() وتخطّى الأصناف اللي ليها أبناء، لأن الأب نفسه مالوش كمية حقيقية.

امتى أستخدم Custom Options بدل Configurable Product؟

لما التنويعات مالهاش مخزون منفصل ومش محتاجة تظهر في الفلاتر. الـ Custom Options حقول على منتج simple واحد بتأثر على السعر من غير ما تعمل عشرات المنتجات. لو محتاج تتابع مخزون كل تنويعة أو ليها SKU خاص أو العميل هيفلتر بيها في الـ layered navigation، خد Configurable.

ليه الـ Configurable بيحط سطرين في السلة؟

سطر للأب اللي العميل شايفه وسطر للابن اللي هيتشحن ويتخصم من المخزون. العميل بيشوف سطر واحد، بس الكود بيشوف الاتنين. عشان كده getAllVisibleItems() بترجّع الآباء بس للعرض والعدّ، وgetAllItems() بترجّع الاتنين. لو حسبت إجمالي على getAllItems من غير ما تتخطّى الأب هتحسب السعر مرتين.

إيه الخصائص اللي ينفع أعمل بيها Configurable Product؟

الخاصية لازم تكون نوعها Dropdown أو Swatch، والـ scope بتاعها Global، ومنطبقة على أنواع المنتجات المستخدمة من apply_to. لو شرط منهم ناقص مش هتظهر في قائمة الخصائص وإنت بتعمل الـ Configurable من غير أي رسالة توضّح السبب، ودي أشهر حيرة مع النوع ده.

إيه اللي بيحصل لو السلة كلها منتجات Virtual؟

Magento بيتخطى خطوة الشحن كلها في الـ checkout: مفيش عنوان شحن ولا اختيار شركة شحن. عشان كده $quote->isVirtual() مهمة، وأي كود بيقرا عنوان الشحن لازم يشيّك عليها الأول وإلا هيقع مع السلة الافتراضية. الـ Downloadable نفس الفكرة مع ملفات بتتاح للتحميل، والافتراضي إنها تتاح بعد الفاتورة مش بعد الطلب.

إزاي أعمل نوع منتج مخصّص في Magento 2؟

عرّفه في etc/product_types.xml بـ name و label و modelInstance، وكلاس بيورّث من Magento\Catalog\Model\Product\Type\AbstractType وتعدّل فيه isVirtual() و _prepareProduct() وغيرهم. بس النوع الجديد بيحتاج شغل في التسعير والمخزون والسلة والفهرسة، ففي معظم الحالات نوع موجود مع custom options أو خصائص إضافية بيكفي بجهد أقل بكتير.