Magento - 修改产品属性后重新分配目录规则

时间:2011-09-12 12:31:50

标签: php magento

我正在开发Magento 1.5.1.0的扩展程序,这允许我将产品目录价格规则添加到库存数量减少到零的产品中。我在属性集中添加了一个名为auto_discount_active的属性。这个属性是我的开/关开关,它作为我的定价规则的条件。

我写了一个观察者对事件sales_order_place_aftercatalog_product_save_before作出反应。它的任务是检查当前产品的库存数量是否已更改,并将我的自定义属性设置为打开或关闭。

处理catalog_product_save_before事件的方法工作正常。在后端保存文章后,价格规则变为(in)活动状态。代码如下所示:

class Company_AutoDiscount_Model_Observer
{
  public function updateAutoDiscount($observer)
  {
    /**
     * @var Varien_Event
     */
    $event     = $observer->getEvent();

    $product    = $event->getProduct();
    $data       = $product->getStockData(); 

    $discount   = $data['qty'] < 1 ? true : false;
    $attributes = $product->getAttributes();
    $attribute  = $attributes["auto_discount_active"];

    if ($product->getAutoDiscountAllowed())
    {
        $product->setAutoDiscountActive($discount);
    }

    return $this;
  }
}

现在我想做同样的事情,如果有人在我的商店下订单。我使用迄今为止有效的事件sales_order_place_after。但在更改自定义属性值后,价格规则不会更新。我的观察者方法如下:

public function updateAutoDiscountAfterOrder($observer)
{
    /**
     * @var Varien_Event
     */
    $event      = $observer->getEvent();
    $order      = $event->getOrder();

    foreach ($order->getItemsCollection() as $item) 
    {
        $productId  = $item->getProductId();
        $productIds[] = $productId;
        $product    = Mage::getModel('catalog/product')->setStoreId($order->getStoreId())->load($productId);
        $data       = $product->getStockData(); 

        $discount   = $data['qty'] < 1 ? true : false;

        if ($product->getAutoDiscountAllowed())
        { 
            $product->setAutoDiscountActive($discount);
            $product->save();
        }

        Mage::getModel('catalogrule/rule')->applyAllRulesToProduct($productId);
    }
    return $this;
}

下订单并在后端手动保存购买的商品而不进行更改后,价格规则会更新。但我已经用我的观察者方法得到了更新。

更改自定义属性后,我需要做什么才能分配目录价格规则?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

好的,我想就一些相当重要的代码优化建议你。

您可以使用以下方法缩小集合大小并删除循环中的条件逻辑:

$order->getItemsCollection()->addFieldToFilter('is_in_stock', 0);

您还可以使用更多更快的方法更新所有属性而不是save(),方法是使用:

Mage::getSingleton('catalog/product_action')
    ->updateAttributes($order->getItemsCollection()->addFieldToFilter('is_in_stock', 0)->getAllIds(), array('auto_discount_active' => 1), 0);

另外,请记住,您还需要将您的观察者应用于任何产品库存水平修改,即。产品保存,导入,贷项凭证(退款) - 所以它是一个相当广阔的领域。你可能会更好地重写股票类,因为没有太多的事件发送会给你足够的空间来覆盖它。

最后,为了执行规则的分配,我建议扩展规则的资源模型(Mage/CatalogRule/Model/Mysql4/Rule.php),以便您可以传入产品ID数组(以保存它迭代整个目录)。

您可以简单地扩展getRuleProductIds()以使用上面的集合中的产品ID获取Mage ::注册表变量(如果已设置)。然后在运行上面的代码之后,您可以执行

Mage::getModel('catalogrule/rule')->load(myruleid)->save();

如果需要,它将重新索引并将规则应用于新产品 - 仅适用于已更改的产品。

我认为这种方法可以节省大量的开销。