Magento: автоматическое изменение inventory_stock_availability при обновлении количества


person freakimkaefig    schedule 04.12.2014    source источник


Ответы (2)


Я нашел подходящий подход, используя комбинацию ответа @DWils и cronjob.

В моей конфигурации расширения (app/code/local/My/UpdateStockAvailability/etc/config.xml):

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <My_UpdateStockAvailability>
            <version>1.0.0</version>
        </My_UpdateStockAvailability>
    </modules>
    <global>
         <models>
            <my_updatestockavailability>
                <class>My_UpdateStockAvailability_Model</class>
            </my_updatestockavailability>
        </models>
        <events>
            <catalog_product_save_after>
                <observers>
                    <my_updatestockavailability>
                        <class>my_updatestockavailability/observer</class>
                        <method>updateStockAvailability</method>
                        <type>singleton</type>
                    </my_updatestockavailability>
                </observers>
            </catalog_product_save_after>
        </events>
    </global>

    <crontab>
        <jobs>
            <updatestockavailabilitycronjob>
                <schedule>
                    <cron_expr>*/15 7-19 * * *</cron_expr>
                </schedule>
                <run>
                    <model>my_updatestockavailability/observer::updateCronAction</model>
                </run>
            </updatestockavailabilitycronjob>
        </jobs>
    </crontab>
</config>

Мой наблюдатель (app/code/local/My/UpdateStockAvailability/Model/Observer.php):

<?php

class My_UpdateStockAvailability_Model_observer {

    public function updateStockAvailability(Varien_Event_Observer $observer) {
        $product = $observer->getProduct();
        $stockData = $product->getStockData();

        if ( $product && $stockData['qty'] ) {
            $stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product->getEntityId()); // Load the stock for this product
            $stock->setData('is_in_stock', 1); // Set the Product to InStock
            $stock->save(); // Save
        }
    }

    public function updateCronAction() {
        $collection = Mage::getResourceModel('cataloginventory/stock_item_collection');
        $outQty = Mage::getStoreConfig('cataloginventory/item/options_min_qty');
        $collection->addFieldToFilter('qty', array('gt' => $outQty));
        $collection->addFieldToFilter('is_in_stock', 0);

        foreach ($collection as $item) {
            $item->setData('is_in_stock', 1);
        }
        $collection->save();

        $bundleCollection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect('*')
            ->addAttributeToSelect('type')
            ->addAttributeToFilter('type_id', 'bundle')
            ->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));

        foreach ($bundleCollection as $bundle) {
            $selectionCollection = $bundle->getTypeInstance(true)->getSelectionsCollection($bundle->getTypeInstance(true)->getOptionsIds($bundle), $bundle);

            $allInStock = true;
            foreach ($selectionCollection as $option) {
                $stockItem = $option->getStockItem();
                if ($stockItem->getQty() <= 0 || $stockItem->getIsInStock() <= $outQty) {
                    $allInStock = false;
                }
            }

            if ($allInStock) {
                $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($bundle);
                $stockItem->setData('is_in_stock', 1);
                $stockItem->save();
            }
        }
    }
}

Наконец, модуль xml (app/etc/modules/My_UpdateStockAvailability.xml):

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <My_UpdateStockAvailability>
            <active>true</active>
            <codePool>local</codePool>
        </My_UpdateStockAvailability>
    </modules>
</config>
person freakimkaefig    schedule 29.07.2015
comment
как я могу увидеть вывод этого cron - person Bhavin Thummar; 28.03.2018
comment
Я действительно не знаю, что вы пытаетесь сделать. Но если вы хотите выводить отладочные сообщения для своего задания cron, вы можете использовать Mage::Log("Output here"); для входа в system.log. - person freakimkaefig; 29.03.2018

Вы можете справиться с этим, добавив наблюдателя для наблюдения за catalog_product_save_before и сказать ему проверить количество продукта, и если> 0 (или минимальное значение для срабатывания отсутствия на складе)

Затем установите флаг inventory_stock_availability в 1 и вернитесь. Это изменит флаг до того, как произойдет сохранение продукта.

Имейте в виду, что это может иметь другие последствия для функциональности магазина, если флаги количества и наличия на складе управляются отдельно, в зависимости от того, как был настроен ваш магазин. Например, в одном магазине, который у нас есть, мы скрываем покупку сейчас, если для нее установлено значение «Нет в наличии» и какое-либо количество в наличии уже зарезервировано для кого-то, но еще не отправлено.

Вот одна статья, подробно описывающая, как создать такого наблюдателя
http://blog.chapagain.com.np/magento-event-observer-with-save-before-and-save-after/

person DWils    schedule 05.06.2015
comment
Подход работает, если количество обновляется в бэкэнде magento. Мы используем расширение сообщества BarcodeShipping, которое обновляет количество через API. Я нашел подходящее решение, используя cronjob (подробности см. В моем ответе). - person freakimkaefig; 29.07.2015