【问题标题】:Are unconverted quote records ever removed in Magento?Magento 中是否曾经删除过未转换的报价记录?
【发布时间】:2012-09-22 15:32:50
【问题描述】:

tl;dr:似乎没有其他现成的机制可以删除从未转换为订单的报价记录。

Mage_Sales 模块有一个计划的作业来清理过期的报价,但这只会删除标记为非活动的sales_flat_quote 记录(即is_active = 0)。据我所知,只有当报价转换为订单时,报价才会被标记为无效。如果是这样的话,那么报价表只会越来越大。

参考Mage_Sales_Model_Observer::cleanExpiredQuotes()

class Mage_Sales_Model_Observer
{
    //...

    public function cleanExpiredQuotes($schedule)
    {
        Mage::dispatchEvent('clear_expired_quotes_before', array('sales_observer' => $this));

        $lifetimes = Mage::getConfig()->getStoresConfigByPath('checkout/cart/delete_quote_after');
        foreach ($lifetimes as $storeId=>$lifetime) {
            $lifetime *= 86400;

            /** @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */
            $quotes = Mage::getModel('sales/quote')->getCollection();

            $quotes->addFieldToFilter('store_id', $storeId);
            $quotes->addFieldToFilter('updated_at', array('to'=>date("Y-m-d", time()-$lifetime)));
            $quotes->addFieldToFilter('is_active', 0);

            foreach ($this->getExpireQuotesAdditionalFilterFields() as $field => $condition) {
                $quotes->addFieldToFilter($field, $condition);
            }

            $quotes->walk('delete');
        }
        return $this;
    }

    //...
}

【问题讨论】:

  • 我向 Magento Suport 开了一张票(作为 Magento 企业客户和银牌合作伙伴)。第一个回应是:给我们你所有的 ssh/db 细节来检查......他们花了一段时间才明白我真正指的是什么(他们的支持人员没有 Magento 编码经验)。他们说 Magento 无法检查报价是否仍然有效,这就是它不会被删除的原因。如果客户返回,他将找不到他的报价。当然,我们的一位客户在数据库中有数百万条报价,添加到购物车受到很大影响。
  • @FlorinelChis,Ben 问题不是那么容易解决,Magento 的人是对的,他们无法确定可以删除哪个引用。首先是支付方式中的问题,即在不改变 is_active 状态的情况下将客户重定向到第三方网站,但另一个问题是,即使是像 Paypal 这样的核心模块也在做同样的事情:)。 is_active 的问题,如果此标志等于 1,您偶尔可以删除登录客户的报价,该客户刚刚为后者保存产品。
  • @IvanChepurnyi - RE 保存的购物车 - 我认为可能有时间限制 - 客户在添加到购物车后 1-2 个月多久转换一次(不确定)?我确实忘记了回调支付方式,但这似乎也很容易处理,例如任何超过 6 个月的有效报价都可能是无效报价。即使对于回调支付方式,订单是否已创建且购物车“已死”?
  • @benmarks 这仍然是一个问题,magento 是否计划在某个时候解决这个问题?
  • @Erfan - 它没有。请参阅 [this answer] (stackoverflow.com/a/12545295/833795) 获取解决方案。

标签: magento


【解决方案1】:

用你自己的清理例程覆盖观察者。我们保留特定时间段的特定报价,因此删除 4 层。来宾购物车会重新邮寄并且可以恢复,空的注册客户报价会在已完成的报价旁边过期,并且根据观察到的客户行为,包含内容的注册购物车会保存很长时间。

<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Mage
 * @package     Mage_Sales
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */


/**
 * Sales observer
 *
 * @category   Chief
 * @package    Chief_Sales
 * @author     Magento Core Team <core@magentocommerce.com>
 */

/* Valid for 1.4.2.0, 1.5.1.0 */

class Chief_Sales_Model_Observer extends Mage_Sales_Model_Observer
{
    /**
     * Clean expired quotes (cron process)
     *
     * @param Mage_Cron_Model_Schedule $schedule
     * @return Mage_Sales_Model_Observer
     */
    public function cleanExpiredQuotes($schedule)
    {
        $lifetimes = Mage::getConfig()->getStoresConfigByPath('checkout/cart/delete_quote_after');

        /* Quotes converted to orders */
        foreach ($lifetimes as $storeId=>$lifetime) {
            $lifetime *= 86400;

            $quotes = Mage::getModel('sales/quote')->getCollection();
            /* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */

            $quotes->addFieldToFilter('store_id', $storeId);
            $quotes->addFieldToFilter('updated_at', array('to'=>date("Y-m-d", time()-$lifetime)));
            $quotes->addFieldToFilter('is_active', 0);            // Filled Quotes
            $quotes->walk('delete');
        }


        /* Quotes abandoned by Guest Carts */
        foreach ($lifetimes as $storeId=>$lifetime) {
            $lifetime *= 86400;

            // triple lifetime for abandoned cart remail
            $lifetime *= 3;

            $quotes = Mage::getModel('sales/quote')->getCollection();
            /* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */

            $quotes->addFieldToFilter('store_id', $storeId);
            $quotes->addFieldToFilter('updated_at', array('to'=>date("Y-m-d", time()-$lifetime)));
            $quotes->addFieldToFilter('is_active', 1);            // Active Quotes
            $quotes->addFieldToFilter('customer_group_id', 0);    // Which are Group NLI (Guest)
            $quotes->walk('delete');
        }


        /* Quotes abandoned by Registered carts no contents */
        foreach ($lifetimes as $storeId=>$lifetime) {
            $lifetime *= 86400;

            $quotes = Mage::getModel('sales/quote')->getCollection();
            /* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */

            $quotes->addFieldToFilter('store_id', $storeId);
            $quotes->addFieldToFilter('updated_at', array('to'=>date("Y-m-d", time()-$lifetime)));
            $quotes->addFieldToFilter('is_active', 1);                      // Active Quotes
            $quotes->addFieldToFilter('customer_group_id', array('gt'=>0)); // For all other groups
            $quotes->addFieldToFilter('items_qty', 0);                      // For empty carts
            $quotes->walk('delete');
        }


        /* Quotes abandoned by Registered carts */
        foreach ($lifetimes as $storeId=>$lifetime) {
            $lifetime *= 86400;

            // Registered cart lifetime for abandoned cart remail 7*25 = 175 days
            $lifetime *= 25;

            $quotes = Mage::getModel('sales/quote')->getCollection();
            /* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */

            $quotes->addFieldToFilter('store_id', $storeId);
            $quotes->addFieldToFilter('updated_at', array('to'=>date("Y-m-d", time()-$lifetime)));
            $quotes->addFieldToFilter('is_active', 1);                      // Active Quotes
            $quotes->addFieldToFilter('customer_group_id', array('gt'=>0)); // For all other groups
            $quotes->addFieldToFilter('items_qty', array('gt'=>0));         // For expired carts
            $quotes->walk('delete');
        }
        return $this;
    }
}

【讨论】:

  • 我可以在 Magento 的 1.9.x 版本中看到,不再需要重写,因为它们实际上在 Observer 的一开始就调度了一个事件,即 clear_expired_quotes_before 所以这个事件的观察者是现在要走的路。
  • 最后一个 foreach 循环(已注册购物车放弃的引号)也应该将 is_active 过滤器设置为 1 对吗? (不是 0,因为它不会清除旧引号,只会清除可能已转换为订单的引号)
  • @Erfan - 是的,你是对的。我只是将它与我​​创建的外部脚本进行了比较,然后再修改观察者使其自动化。我们希望它删除 XXX 天内的有效报价,以便客户可以回来下订单。已填充的引号已处理。
  • 应该是公认的答案,因为另一个是仅链接的答案。
  • 非常感谢您提供此信息。我在我们的数据库中发现一年多前的活跃报价超过 170 万条!这帮不了什么忙! Magento 不应该将此设置命名为“Quote Lifetime”,因为它不是这样的。将其保存在数据库中是转换后的年龄。但任何未转换的报价都会无限期保留。清理这些是很好的做法。
猜你喜欢
  • 2016-11-02
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
  • 2020-12-08
  • 2013-07-13
相关资源
最近更新 更多