วิธีการรับสินค้าหมดรายการ - ตรงข้าม addInStockFilterToCollection ()


9

ฉันมีความต้องการที่จะแสดงผลิตภัณฑ์ของหมวดหมู่ในสองรายการ - หนึ่งสำหรับในรายการสต็อก, อื่น ๆ สำหรับรายการหมด

ฉันกำลังใช้

Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection()

เพื่อกรองคอลเลกชันผลิตภัณฑ์ของฉันสำหรับรายการในสต็อก แต่ดูเหมือนจะไม่มีวิธีที่เทียบเท่าในการกรองสำหรับรายการที่หมด - ฉันได้ดูMage_CatalogInventory_Model_Stockแบบจำลองซึ่งเป็นที่ที่กำหนดวิธีการดังกล่าวข้างต้น

ฉันได้เห็นตัวอย่างต่อไปนี้สำหรับการดึงสินค้าออกจากสต็อก:

$collection->joinField(
                    'is_in_stock',
                    'cataloginventory/stock_item',
                    'is_in_stock',
                    'product_id=entity_id',
                    '{{table}}.stock_id=1',
                    'left'
            )
            ->addAttributeToFilter('is_in_stock', array('eq' => 0));

... แต่แน่นอนว่านี่ไม่ใช่เพียงหรือวิธีที่ดีที่สุดในการบรรลุเป้าหมายนี้?

คำตอบ:


3

สมมติว่า$collectionเป็นชุดผลิตภัณฑ์ของคุณที่คุณสร้างเช่นนี้:

$collection = Mage::getModel('catalog/product')->getCollection()
    ->...additional filters here...;

ตอนนี้ทำสิ่งนี้เพื่อคอลเลกชันของคุณ สิ่งนี้จะรวมคอลเลกชันเข้ากับตารางสถานะหุ้น

$website = Mage::app()->getWebsite();
Mage::getModel('cataloginventory/stock_status')->addStockStatusToSelect($collection, $website);

ตอนนี้คุณสามารถกรองสินค้าหมด:

$collection->getSelect()->where('stock_status.stock_status = ?', 0);

สิ่งนี้จะใช้ได้ไม่ว่าตัวเลือกการกำหนดค่าใดจะถูกตั้งค่าสำหรับสินค้าคงคลังของแต่ละผลิตภัณฑ์หรือไม่ (เช่นเป็นผลิตภัณฑ์ที่ไม่มีสต็อกที่มีการจัดการในสต็อกหรือหมด?)
BrynJ

มันควรจะทำงานได้เพราะตารางดัชนีมีการจัดทำดัชนีและจะคำนึงถึงการตั้งค่าที่เป็นไปได้ทั้งหมด คุณเพียงแค่ต้องทำให้แน่ใจว่าดัชนีหุ้นของคุณเป็นปัจจุบัน
Marius

ขอบคุณสำหรับการยืนยัน ดูเหมือนว่าวิธี "เบา" ที่ดีในการรับข้อมูลนี้
BrynJ

การใช้ตารางดัชนีสถานะหุ้นแทนตารางรายการหุ้นเป็นทางออกที่ดีที่สุด
เฟเบียน Schmengler

ฉันต้องส่งตัวเลือกผลิตภัณฑ์เป็นอาร์กิวเมนต์แรกไปยังฟังก์ชัน Mage :: getModel ('cataloginventory / stock_status') -> addStockStatusToSelect ($ collection-> getSelect (), $ website);
minlare

2

ตัวอย่างของคุณไม่นำค่าสำหรับ "use config" มาพิจารณา

เรามาดูวิธีการaddInStockFilterToCollectionทำงาน:

public function addInStockFilterToCollection($collection)
{
    $this->getResource()->setInStockFilterToCollection($collection);
    return $this;
}

ตกลงเป็นการมอบหมายให้วิธีอื่น:

public function setInStockFilterToCollection($collection)
{
    $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
    $cond = array(
        '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=1',
        '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=0',
    );

    if ($manageStock) {
        $cond[] = '{{table}}.use_config_manage_stock = 1 AND {{table}}.is_in_stock=1';
    } else {
        $cond[] = '{{table}}.use_config_manage_stock = 1';
    }

    $collection->joinField(
        'inventory_in_stock',
        'cataloginventory/stock_item',
        'is_in_stock',
        'product_id=entity_id',
        '(' . join(') OR (', $cond) . ')'
    );
    return $this;
}

สิ่งนี้จะรวมตารางสินค้าคงคลังด้วยเงื่อนไขต่อไปนี้:

  1. ผลิตภัณฑ์ไม่ได้ใช้การกำหนดค่าส่วนกลางและตั้ง"จัดการสต็อค" เป็น "ใช่" และมีในสต็อก

    หรือ

  2. ผลิตภัณฑ์ไม่ได้ใช้การกำหนดค่าระดับโลกและตั้งค่า"จัดการสต็อค" เป็น "ไม่"

    หรือ

  3. ผลิตภัณฑ์ใช้การกำหนดค่าส่วนกลางและหากการกำหนดค่าส่วนกลางคือ "จัดการสต็อค = ใช่" อยู่ในสต็อก

คุณต้องคว่ำเงื่อนไขดังต่อไปนี้:

  1. ผลิตภัณฑ์ไม่ได้ใช้การกำหนดค่าส่วนกลางและตั้งค่า"จัดการสต็อค" เป็น "ใช่" และไม่ได้อยู่ในสต็อก

    หรือ

  2. ผลิตภัณฑ์ใช้การกำหนดค่าระดับโลกและการกำหนดค่าระดับโลกคือ "จัดการสต็อก = ใช่" และไม่ได้อยู่ในสต็อก

คำอธิบาย: คุณจะใช้เงื่อนไขที่มีการตรวจสอบ in_stock เท่านั้นและเปลี่ยนการเปรียบเทียบเป็น 0 เงื่อนไขที่ไม่ได้ตรวจสอบ in_stock ("จัดการสต็อค" = "ไม่") หมายความว่าผลิตภัณฑ์อยู่ในสต็อกเสมอโดยไม่คำนึงถึงสถานะสต็อค ดังนั้นเราจึงไม่รวมรายการเหล่านี้ในแบบสอบถาม "หมด"

นี่คือรหัสของคุณ:

public function setOutOfStockFilterToCollection($collection)
{
    $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
    $cond = array(
        '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=0'
    );

    if ($manageStock) {
        $cond[] = '{{table}}.use_config_manage_stock = 1 AND {{table}}.is_in_stock=0';
    }

    $collection->joinField(
        'inventory_in_stock',
        'cataloginventory/stock_item',
        'is_in_stock',
        'product_id=entity_id',
        '(' . join(') OR (', $cond) . ')'
    );
    return $this;
}

คำตอบที่ยอดเยี่ยมโดยละเอียด ดังนั้นคุณควรแนะนำให้สร้างโมดูลสำหรับสิ่งนี้เพื่อขยายMage_CatalogInventory_Model_Stockโมเดล?
BrynJ

1
ไม่มีการเขียนซ้ำหรือขยาย $thisคุณสามารถใส่ได้ทุกที่วิธีการนี้มันไม่ได้ใช้ มันอาจจะเป็นฟังก์ชั่นธรรมดา ฉันจะสร้างโมดูลแยกต่างหากและทำให้มันเป็นวิธีการช่วยเหลือ (หรือถ้าคุณต้องนี้สำหรับโมดูลอื่นเพิ่มเข้าไปในผู้ช่วยของโมดูลนั้น)
เฟเบียน Schmengler

1

ข้อมูลโค้ดต่อไปนี้จะคืนสินค้าให้คุณในหมวดหมู่ที่มีสถานะ 'เปิดใช้งาน' การมองเห็น 'แคตตาล็อกการค้นหา' และความพร้อมของหุ้น 'สินค้าหมด'

$productDetails = Mage::getModel('catalog/category')->load($cat_id)
                  ->getProductCollection()
                  ->addAttributeToSelect('*');

$productDetails->addAttributeToFilter('visibility', 4); 
$productDetails->addAttributeToFilter('status', 1); 
$productDetails->joinField('is_in_stock',
                            'cataloginventory/stock_item',
                            'is_in_stock',
                            'product_id=entity_id',
                            'is_in_stock=0',
                            '{{table}}.stock_id=1',
                            'left');

0

คุณสามารถลองสิ่งนี้

 $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
        $cond = array(
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=0',
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=0',
        );

        if ($manageStock) {
            $cond[] = '{{table}}.use_config_manage_stock = 1 AND {{table}}.is_in_stock=0';
        } else {
            $cond[] = '{{table}}.use_config_manage_stock = 1';
        }

        $collection->joinField(
            'inventory_in_stock',
            'cataloginventory/stock_item',
            'is_in_stock',
            'product_id=entity_id',
            '(' . join(') OR (', $cond) . ')'
        );

หรือคุณสามารถลองสิ่งนี้

  $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
        $cond = array(
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=1 AND {{table}}.is_in_stock=0',
            '{{table}}.use_config_manage_stock = 0 AND {{table}}.manage_stock=0',
        );

        if ($manageStock) {
            $cond[] = '{{table}}.is_in_stock=0';


        $collection->joinField(
            'inventory_in_stock',
            'cataloginventory/stock_item',
            'is_in_stock',
            'product_id=entity_id',
            '(' . join(') OR (', $cond) . ')'
        );

ไม่แน่ใจ 100%


ขอบคุณ @AmitBera คุณช่วยอธิบายบริบทสำหรับคำตอบของคุณและอธิบายความแตกต่างได้ไหม?
BrynJ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.