1

我希望在产品网格中添加一列(在管理区域中要清楚)以显示该产品已售出多少次。以下是我从其他几篇文章拼凑而成的内容:

在 app/code/local/Namespace/Qtysold/Block/Adminhtml/Catalog/Product/Grid.php

<?php

class Namespace_Qtysold_Block_Adminhtml_Catalog_Product_Grid extends Mage_Adminhtml_Block_Catalog_Product_Grid
{
/* Overwritten to be able to add custom columns to the product grid. Normally
 * one would overwrite the function _prepareCollection, but it won't work because
 * you have to call parent::_prepareCollection() first to get the collection.
 *
 * But since parent::_prepareCollection() also finishes the collection, the
 * joins and attributes to select added in the overwritten _prepareCollection()
 * are 'forgotten'.
 *
 * By overwriting setCollection (which is called in parent::_prepareCollection()),
 * we are able to add the join and/or attribute select in a proper way.
 *
 */
public function setCollection($collection)
{
    /* @var $collection Mage_Catalog_Model_Resource_Product_Collection */

    $store = $this->_getStore();

    if ($store->getId() && !isset($this->_joinAttributes['qty_sold'])) {
        $collection->joinAttribute(
            'qty_sold',
            'reports/product_collection',
            'entity_id',
            null,
            'left',
            $store->getId()
        );
    }
    else {
        $collection->addAttributeToSelect('qty_sold');
    }

    echo "<pre>";
    var_dump((string) $collection->getSelect());
    echo "</pre>";

    parent::setCollection($collection);
}

protected function _prepareColumns()
{
    $store = $this->_getStore();
    $this->addColumnAfter('qty_sold',
        array(
            'header'=> Mage::helper('catalog')->__('Qty Sold'),
            'type'  => 'number',
            'index' => 'qty_sold',
        ),
        'price'
     );

    return parent::_prepareColumns();
}
}

这里有几件事。1) $store->getId() 返回 0,因此它永远不会进入 setCollection 中的第一个块,这是正确的行为,因为它是管理区域吗?2)如果我强制 joinAttribute 运行,它会导致异常(无效实体...),这是意料之中的,因为报告似乎并不是一个实体,但我不太清楚整个实体业务. 3)在其他示例中(例如:http ://www.creativemediagroup.net/creative-media-web-services/magento-blog/30-show-quantity-sold-on-product-page-magento )他们使用像这样的东西:

$_productCollection = Mage::getResourceModel('reports/product_collection')
->addOrderedQty($from, $to, true)
->addAttributeToFilter('sku', $sku)
->setOrder('ordered_qty', 'desc')
->getFirstItem();

而且我不确定是否有任何方法可以“加入”此报告/product_collection,或者是否有任何方法可以重新创建其“addOrderedQty”数据?

这是在 Magento 1.7 上。我可以根据需要提供更多详细信息。我是 Magento 开发的初学者,因此将不胜感激任何帮助(包括学习资源)。谢谢!

4

3 回答 3

1

1) 管理区确实有商店 ID = 0,所以是的,这将始终返回。

这也意味着您的条件总是失败并且永远不会进行任何加入,它只会尝试将 qty_sold 添加到集合中,这当然不会起作用,因为它不是该实体数据的一部分。

问题是 joinAttribute 方法仅适用于“实体”(它取决于您尝试加入的模型使用的类),并且由于报告/产品集合不是其中之一,您将不得不以另一种方式加入使用这样的方法:

join() or joinLeft()

用这种东西:

$collection->getSelect()
    ->join(
    'customer_entity',
    'main_table.customer_id = customer_entity.entity_id',
     array('customer_name' => 'email')
 );
于 2013-02-13T17:24:32.077 回答
1

也在处理这个问题并解决如下:

protected function _prepareCollection() {
    // [...]
    $collection = Mage::getModel('catalog/product')->getCollection();

    // Add subquery join to sales_flat_order_item to get a SUM of how many times this product has been ordered
    $totalOrderedQuery = Mage::getSingleton('core/resource')->getConnection('core_read')
        ->select()
        ->from('sales_flat_order_item', array('product_id', 'qty_ordered' => 'SUM(`qty_ordered`)'))
        ->group('product_id');

    $collection->joinField('qty_ordered', $totalOrderedQuery, 'qty_ordered', 'product_id=entity_id', null, 'left');
    // [...]
    return parent::_prepareCollection();
}

请注意 的用法$collection->joinField(),尝试使用提到的$collection->getSelect()->join(),但由于内部 Magento 数据收集未将列识别​​为数据集的一部分,它给出了排序顺序和过滤的各种问题。

然后_prepareColumns你可以简单地添加列:

$this->addColumn('qty_ordered', array(
    'header' => Mage::helper('xyz')->__('Total quantity ordered'),
    'sortable' => true,
    'width' => '10%',
    'index' => 'qty_ordered',
));

您可能想要添加一个渲染器来检查NULL值并将其转换为'0',否则如果尚未订购产品,您最终将得到空列(您也可以在 SELECT 查询中使用IFNULL for修复此问题qty_ordered)。

于 2015-08-27T13:25:55.320 回答
0

多亏了 Andrew 的提示,我能够实现我所需要的(尽管它并不完美)。这是我更新的 setCollection 代码:

public function setCollection($collection)
{
    /* @var $collection Mage_Catalog_Model_Resource_Product_Collection */

    $store = $this->_getStore();

    $collection->getSelect()->joinLeft(
        array('oi' => 'sales_flat_order_item'),
        'e.entity_id = oi.product_id',
        array("qty_sold" => 'SUM(oi.qty_ordered)')
    )->group('e.entity_id');

    parent::setCollection($collection);
}

我很好奇是否有任何 Magento 开发人员发现这种方法存在严重缺陷(我知道一些业务逻辑,例如不计算被取消的产品等)或提出更好方法的建议。无论哪种方式,这现在都“足够好”并且满足我的需求,所以我会发布以防其他人需要它。

于 2013-02-13T19:31:38.713 回答