我希望在产品网格中添加一列(在管理区域中清除)以显示此产品的销售次数。以下是我从其他几篇文章拼凑到一起后到目前为止的内容:
在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-&gt; getId()返回0,所以它永远不会进入setCollection中的第一个块,这是正确的行为,因为它是Admin区域? 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();
我不确定是否有任何方法可以“加入”此reports / product_collection,或者是否有任何方法可以重新创建其“addOrderedQty”数据?
这是在Magento 1.7上。我可以根据需要提供进一步的细节。我是Magento开发的初学者,所以任何帮助(包括学习资源)都将非常感激。谢谢!
答案 0 :(得分:1)
1)管理区域的商店ID = 0,所以是的,这将始终返回。
这也意味着你的条件总是失败并且永远不会加入,它只会尝试将qty_sold添加到集合中,这当然不会起作用,因为它不是该实体数据的一部分。
问题是joinAttribute方法只适用于“Entites”(它取决于您尝试加入的模型使用的类),并且由于报告/产品集合不是其中之一,您将不得不使用这样的方法加入另一种方式:
join() or joinLeft()
有这样的事情:
$collection->getSelect()
->join(
'customer_entity',
'main_table.customer_id = customer_entity.entity_id',
array('customer_name' => 'email')
);
答案 1 :(得分: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'
,否则如果产品尚未订购,您最终会得到空列(您可以还可以使用qty_ordered
对for(SKSpriteNode *object in self.myArray) {
if([object.name isEqualToString:@"name1"]) {
[object methodName];
}
}
)在SELECT查询中修复此问题。
答案 2 :(得分: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开发人员发现这种方法存在严重缺陷(我知道一些业务逻辑,例如不计算被取消的产品等)或建议采用更好的方法。无论哪种方式,这对于现在来说都“足够好”并满足我的需求,所以我会发布以防其他人需要它。