Magento Reports - Products - Products Ordered issu

2020-05-28 11:19发布

The issue: In Magento admin panel, when generating report via Reports - Products - Products Ordered, an error occurs:


    Item (Mage_Catalog_Model_Product) with the same id "45" already exist
    #0 /home/glassesm/public_html/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(236): Varien_Data_Collection->addItem(Object(Mage_Catalog_Model_Product))
    #1 /home/glassesm/public_html/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(964): Mage_Eav_Model_Entity_Collection_Abstract->addItem(Object(Mage_Catalog_Model_Product))
    #2 /home/glassesm/public_html/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(794): Mage_Eav_Model_Entity_Collection_Abstract->_loadEntities(false, false)
    #3 /home/glassesm/public_html/lib/Varien/Data/Collection.php(729): Mage_Eav_Model_Entity_Collection_Abstract->load()
    #4 /home/glassesm/public_html/app/code/core/Mage/Reports/Model/Totals.php(53): Varien_Data_Collection->getIterator()
    #5 /home/glassesm/public_html/app/code/core/Mage/Adminhtml/Block/Report/Grid.php(368): Mage_Reports_Model_Totals->countTotals(Object(Mage_Adminhtml_Block_Report_Product_Sold_Grid), '2011-12-10 00:0...', '2011-12-10 23:5...')
    #6 /home/glassesm/public_html/app/design/adminhtml/default/default/template/report/grid.phtml(138): Mage_Adminhtml_Block_Report_Grid->getReport('2011-12-10 00:0...', '2011-12-10 23:5...')
    #7 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(216): include('/home/glassesm/...')
    #8 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(247): Mage_Core_Block_Template->fetchView('adminhtml/defau...')
    #9 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(261): Mage_Core_Block_Template->renderView()
    #10 /home/glassesm/public_html/app/code/core/Mage/Adminhtml/Block/Template.php(81): Mage_Core_Block_Template->_toHtml()
    #11 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(758): Mage_Adminhtml_Block_Template->_toHtml()
    #12 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(525): Mage_Core_Block_Abstract->toHtml()
    #13 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(476): Mage_Core_Block_Abstract->_getChildHtml('grid', true)
    #14 /home/glassesm/public_html/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Container.php(70): Mage_Core_Block_Abstract->getChildHtml('grid')
    #15 /home/glassesm/public_html/app/design/adminhtml/default/default/template/widget/grid/container.phtml(36): Mage_Adminhtml_Block_Widget_Grid_Container->getGridHtml()
    #16 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(216): include('/home/glassesm/...')
    #17 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(247): Mage_Core_Block_Template->fetchView('adminhtml/defau...')
    #18 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(261): Mage_Core_Block_Template->renderView()
    #19 /home/glassesm/public_html/app/code/core/Mage/Adminhtml/Block/Template.php(81): Mage_Core_Block_Template->_toHtml()
    #20 /home/glassesm/public_html/app/code/core/Mage/Adminhtml/Block/Widget/Container.php(295): Mage_Adminhtml_Block_Template->_toHtml()
    #21 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(758): Mage_Adminhtml_Block_Widget_Container->_toHtml()
    #22 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Text/List.php(43): Mage_Core_Block_Abstract->toHtml()
    #23 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(758): Mage_Core_Block_Text_List->_toHtml()
    #24 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(525): Mage_Core_Block_Abstract->toHtml()
    #25 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(476): Mage_Core_Block_Abstract->_getChildHtml('content', true)
    #26 /home/glassesm/public_html/app/design/adminhtml/default/default/template/page.phtml(74): Mage_Core_Block_Abstract->getChildHtml('content')
    #27 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(216): include('/home/glassesm/...')
    #28 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(247): Mage_Core_Block_Template->fetchView('adminhtml/defau...')
    #29 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Template.php(261): Mage_Core_Block_Template->renderView()
    #30 /home/glassesm/public_html/app/code/core/Mage/Adminhtml/Block/Template.php(81): Mage_Core_Block_Template->_toHtml()
    #31 /home/glassesm/public_html/app/code/core/Mage/Core/Block/Abstract.php(758): Mage_Adminhtml_Block_Template->_toHtml()
    #32 /home/glassesm/public_html/app/code/core/Mage/Core/Model/Layout.php(529): Mage_Core_Block_Abstract->toHtml()
    #33 /home/glassesm/public_html/app/code/core/Mage/Core/Controller/Varien/Action.php(389): Mage_Core_Model_Layout->getOutput()
    #34 /home/glassesm/public_html/app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php(97): Mage_Core_Controller_Varien_Action->renderLayout()
    #35 /home/glassesm/public_html/app/code/core/Mage/Core/Controller/Varien/Action.php(418): Mage_Adminhtml_Report_ProductController->soldAction()
    #36 /home/glassesm/public_html/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(253): Mage_Core_Controller_Varien_Action->dispatch('sold')
    #37 /home/glassesm/public_html/app/code/core/Mage/Core/Controller/Varien/Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
    #38 /home/glassesm/public_html/app/code/core/Mage/Core/Model/App.php(340): Mage_Core_Controller_Varien_Front->dispatch()
    #39 /home/glassesm/public_html/app/Mage.php(627): Mage_Core_Model_App->run(Array)
    #40 /home/glassesm/public_html/index.php(80): Mage::run('', 'store')
    #41 {main}

Could you help me with this issue ?

6条回答
淡お忘
2楼-- · 2020-05-28 11:25

you can also override your collection calss Mage_Sales_Model_Resource_Order_Grid_Collection::addItem which throws this exeption :

<?php
class Fixed_Order_Grid_Collection extends Mage_Sales_Model_Resource_Order_Grid_Collection{

    public function addItem(Varien_Object $item)
    {
        $itemId = $this->_getItemId($item);

        if (!is_null($itemId)) {
            if (isset($this->_items[$itemId])) {
                //throw new Exception('Item ('.get_class($item).') with the same id "'.$item->getId().'" already exist');
            }
            $this->_items[$itemId] = $item;
        } else {
            $this->_addItem($item);
        }
        return $this;
    }
}
class MyCompony_MyExtention_Block_Adminhtml_OrderGrid extends Mage_Adminhtml_Block_Widget_Grid
{
     public function __construct()
    {
        parent::__construct();
        $this->setId('sales_order_grid');
        $this->setUseAjax(true);
        $this->setDefaultSort('created_at');
        $this->setDefaultDir('DESC');
        $this->setSaveParametersInSession(true);
    }
    protected function _getCollectionClass()
    {
        return 'sales/order_grid_collection';
    }

    protected function _prepareCollection()
    {
        $collection = new Fixed_Order_Grid_Collection();
        $select = $collection->getSelect();
        $select->join('sales_flat_order_item AS order_item', 'order_item.order_id=main_table.entity_id','quote_item_id',NULL);
        $select->distinct();
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }
...
查看更多
干净又极端
3楼-- · 2020-05-28 11:26

Got the same error at the same spot, here is why and how I fixed.

Magento ordered products reports builds the "list" from "sales_flat_order_item" then join "catalog/product" for further information about the product (sku, type, options, attribute_set, etc..).

In my case, 3 products was deleted from store, when Magento build the list and join in catalog/product, all the information that I listed above was NULL. When Report module build the collection, at the method addItem, it tries to set an ID as key in the collection array, in those deleted product there is no ID, so NULL is set.

Imagine this set of items to build an report.

ID - Name: 1, 2, 3, DELETED ITEM, 4

When the "DELETE ITEM" is added to the collection, will look like this:

Array(
    1 => Object,
    2 => Object,
    3 => Object,
    4 => Object (DELETED ITEM)
)

This is because in addItem, when there is no ID Magento add an new position in array with auto incremenet:

if (!is_null($itemId)) {
    .
    .
    .
} else {
    $this->_items[] = $item;
}

Then, when the collection add the next item (ID: 4) will throw the exception you are looking at:

if (isset($this->_items[$itemId])) {
    throw new Exception('Item ('.get_class($item).') with the same id "'.$item->getId().'" already exist');
}

Changing the way addItem works is very dangerous!! Collections are used everywhere in Magento, adding an trycatch block will definitly affect how your store work in other places/modules. Here is how I fixed:

You can either copy to local or ovewrite with an custom module, its up to you:

Add an new method in "Reports_Product/Collection" to filter only "existing products"

app/code/local/Mage/Reports/Model/Mysql4/Product/Collection.php

public function addNotDeletedProductRestrition(){
    $this->getSelect()->where('order_items.product_id is NOT NULL');

    return $this;
}

Call this method in the ORDERED Collection.

app/code/local/Mage/Reports/Model/Mysql4/Product/Ordered/Collection.php

protected function _joinFields($from = '', $to = '')
{
    $this->addAttributeToSelect('*')
        ->addOrderedQty($from, $to)
        ->setOrder('ordered_qty', 'desc')
        ->addNotDeletedProductRestrition();

    return $this;
}

I've placed inside _joinFields, but you can call wherever you want.

Sorry about my rusty english, i dont have much time to review, this bug already took me a lot of it.

查看更多
Evening l夕情丶
4楼-- · 2020-05-28 11:33

Just go to your Adminpanel, open the product (first row shows ID) and save it. Do this in all store views. Now the problem should be gone.

查看更多
淡お忘
5楼-- · 2020-05-28 11:34

Actually I have 2 different shops on 2 different servers, and both with magento 1.6. I have this issue on both shops. Checked database, and no double entries there.

My solution was:

Edit : /www/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php
Line: 256

Replace: return parent::addItem($object);

With: try { return parent::addItem($object); } catch (Exception $ex) { }

It works perfect, but any other solution is welcome.

查看更多
ゆ 、 Hurt°
6楼-- · 2020-05-28 11:40

It's saying that you have two products with the same ID. This probably happened when you were working with imports or mass updating your products.

The simple solution would be to find the product with the ID of 35 and either delete it because it's a duplicate, or change the ID because this must be unique. Note that you should be looking in all related tables, not just the product table. The problem could be with your EAV attribute table or any number of others.

查看更多
We Are One
7楼-- · 2020-05-28 11:42

this is because your product collection returns duplicate product ids you can grouped your product collection by grouping 'e.entity_id'

try this

$collection = Mage::getModel('catalog/product')
->getCollection()
->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id = entity_id', null, 'left')
->addAttributeToSelect('*')
->addAttributeToFilter('category_id', array('in' => $uniqueIds));

<?php $collection->getSelect()->group('e.entity_id');?>
查看更多
登录 后发表回答