Magento中产品库存不报警解决方案

redmaomail 2024-07-24 18:12 阅读数 77 #Magento

红帽云邮外贸主机

最近我们的一个客户联系我们,告诉我们产品报警功能不再工作。在调查后,我发现最后的一封产品报警邮件是几个月前的。在此期间,我们已经在网站升级到Magento的EE,起初我想,也许在升级过程中出了问题。另一种可能是,客户也许修改了Transactional Email Template。在看完日志文件后,我没发现任何相关的邮件。系统虽然没有发送其它电子邮件。

在调查过程中,我看论坛上的其它开发者有相似的问题也没解决的。在追寻和查找后,我们发现问题所在。

简单说来,这个事件在Magento处理产品报库存警的集合方法里。我们的客户有超过40000封订阅和超过30000个需要将“缺货”状态改为“有货”。所以当Magento尝试从product_alert_stock表读取40000条记录到集合里的时候,由于内存限制而失败了。可能你的product_alert_stock表有超过20000记录时,产品库存报警功能就失效了。

解决方案相对简单。通过以1000为集合创建分页来遍历超过30000条记录。正如Magento在系统中所做的那样。新的功能是通过遍历所有的这些记录,循环出status=0(未处理)的记录,检查产品现在是否有货。当true=> set status=1就发送电子邮件通知客户。

那么,让我们创建我们的模块,Alwayly_ProductAlert,这将提高Magento方法。

1. Create file in app/etc/modules/ Alwayly_ProductAlert.xml with the following content:


<?xml version="1.0"?>
<config>
    <modules>
        <Alwayly_ProductAlert>
            <active>true</active>
            <codePool>local</codePool>
        </Alwayly_ProductAlert>
    </modules>
</config>

2. Create file in app/code/local/Alwayly/ProductAlert/etc/ config.xml with the following content:


<?xml version="1.0"?>
<config>
    <modules>
        <Alwayly_ProductAlert>
            <version>1.0.0.0</version>
        </Alwayly_ProductAlert>
    </modules>
    <global>
        <models>
            <productalert>
                <rewrite>
                    <observer>Alwayly_ProductAlert_Model_Observer</observer>
                </rewrite>
            </productalert>
        </models>
    </global>
</config>

你可以看到我们重写了Mage_ProductAlert_Model_Observer类

Create file in /www/app/code/local/Alwayly/ProductAlert/Model/ Observer.php with the following content:


<?php
 
/*
 * ProductAlert observer
*/
class Alwayly_ProductAlert_Model_Observer extends Mage_ProductAlert_Model_Observer
{
     /**
     * Process stock emails
     *
     * @param Mage_ProductAlert_Model_Email $email
     * @return Mage_ProductAlert_Model_Observer
     */
    protected function _processStock(Mage_ProductAlert_Model_Email $email)
    {
 
        $email->setType('stock');
 
        foreach ($this->_getWebsites() as $website) {
 
            /* @var $website Mage_Core_Model_Website */
 
            if (!$website->getDefaultGroup() || !$website->getDefaultGroup()->getDefaultStore()) {
 
                continue;
            }
            if (!Mage::getStoreConfig(
                self::XML_PATH_STOCK_ALLOW,
                $website->getDefaultGroup()->getDefaultStore()->getId()
            )) {
 
                continue;
            }
            try {
 
                $wholeCollection = Mage::getModel('productalert/stock')
                    ->getCollection()
//                   ->addWebsiteFilter($website->getId())
                    ->addFieldToFilter('website_id', $website->getId())
                    ->addFieldToFilter('status', 0)
                ;
//                $wholeCollection->getSelect()->order('alert_stock_id DESC');
 
                /*       table: !product_alert_stock!
                alert_stock_id: 1
                   customer_id: 1
                    product_id: 1
                    website_id: 1
                      add_date: 2013-04-26 12:08:30
                     send_date: 2013-04-26 12:28:16
                    send_count: 2
                        status: 1
                */
            }
            catch (Exception $e) {
                Mage::log('error-1-collection $e=' . $e->getMessage(), false, 'product_alert_stock_error.log', true);
                $this->_errors[] = $e->getMessage();
                return $this;
            }
 
            $previousCustomer = null;
            $email->setWebsite($website);
 
            try {
 
                $originalCollection = $wholeCollection;
                $count = null;
                $page  = 1;
                $lPage = null;
                $break = false;
 
                while ($break !== true) {
                    $collection = clone $originalCollection;
                    $collection->setPageSize(1000);
                    $collection->setCurPage($page);
                    $collection->load();
                    if (is_null($count)) {
                        $count = $collection->getSize();
                        $lPage = $collection->getLastPageNumber();
                    }
                    if ($lPage == $page) {
                        $break = true;
                    }
 
                    Mage::log('page=' . $page, false, 'check_page_count.log', true);
                    Mage::log('collection=' . (string)$collection->getSelect(), false, 'check_page_count.log', true);
 
                    $page ++;
 
                    foreach ($collection as $alert) {
 
                        try {
 
                            if (!$previousCustomer || $previousCustomer->getId() != $alert->getCustomerId()) {
 
                                $customer = Mage::getModel('customer/customer')->load($alert->getCustomerId());
                                if ($previousCustomer) {
                                    $email->send();
                                }
                                if (!$customer) {
                                    continue;
                                }
                                $previousCustomer = $customer;
                                $email->clean();
                                $email->setCustomer($customer);
 
                            }
                            else {
 
                                $customer = $previousCustomer;
                            }
 
                            $product = Mage::getModel('catalog/product')
                                ->setStoreId($website->getDefaultStore()->getId())
                                ->load($alert->getProductId());
                            /* @var $product Mage_Catalog_Model_Product */
                            if (!$product) {
 
                                continue;
                            }
 
                            $product->setCustomerGroupId($customer->getGroupId());
 
                            if ($product->isSalable()) {
 
                                $email->addStockProduct($product);
 
                                $alert->setSendDate(Mage::getModel('core/date')->gmtDate());
                                $alert->setSendCount($alert->getSendCount() + 1);
                                $alert->setStatus(1);
                                $alert->save();
 
                            }
                        }
                        catch (Exception $e) {
                            Mage::log('error-2-alert $e=' . $e->getMessage(), false, 'product_alert_stock_error.log', true);
                            $this->_errors[] = $e->getMessage();
                        }
                    }
                }
 
                Mage::log("\n\n", false, 'check_page_count.log', true);
 
            } catch (Exception $e) {
                Mage::log('error-3-steps $e=' . $e->getMessage(), false, 'product_alert_stock_error.log', true);
            }
 
            if ($previousCustomer) {
                try {
                    $email->send();
                }
                catch (Exception $e) {
                    $this->_errors[] = $e->getMessage();
                }
            }
        }
 
        return $this;
    }
 
    /**
     * Run process send product alerts
     */
    public function process()
    {
        Mage::log('ProductAlert started @' . now(), false, 'product_alert_workflow.log', true);
 
        $email = Mage::getModel('productalert/email');
        /* @var $email Mage_ProductAlert_Model_Email */
        $this->_processPrice($email);
        $this->_processStock($email);
        $this->_sendErrorEmail();
 
        Mage::log('ProductAlert finished @' . now(), false, 'product_alert_workflow.log', true);
 
        return $this;
    }
}

你可以看到,我们重写了process()和 _processStock()方法。在process()方法中,我们添加了Mage::log()创建起止时间到var/log/product_alert_workflow.log。这样我们就能知道脚本是否执行完成。同样的,我们增强_processStock()方法的功能,我们增加了一些Mage:log()调用来跟踪,看所有的行为是否按期待的方式表现。

最后,如果你不想等待你的Cron被触发,你可以在Magento根目录下创建一个文件,让我们调用它。

Alwayly_cron.php


<?php

require_once 'app/Mage.php';
Mage::app();
 
try {
    Mage::getModel('productalert/observer')-&gtprocess();
} catch (Exception $e) {
    Mage::log('error-0-start $e=' . $e-&gtgetMessage() . ' @' . now(), false, 'product_alert_stock_error.log', true);
}

就是这些了,这个解决思路同样适用于产品价格报警。


红帽云邮外贸主机

分享到:
版权声明:本站内容源自互联网,如有内容侵犯了你的权益,请联系删除相关内容。
    红帽云邮外贸主机
热门
    红帽云邮外贸主机
    红帽云邮外贸主机