Magento – Export CSV error “You cannot define a correlation name more than once” cause by SQL JOIN

csvcustomer-gridexportmagento-1.9

So I have narrowed it down to the fact that Magento does not like the JOIN when I am adding it to the collection. Is there anyway to make it so it doesnt duplicate the correlation name or whatever it is that is causing the error?


I've added an extra column to my customer order grid that will display the customer's street address, but when I try and export the CSV, I am getting the error "cannot define correlation name more than once". I've extended the Webtex extension "Customer Lifetime Sales" by adding a new function.

Here is my function in the Model:

public function addColumnCustomerStreetAddress($block,$after = null)
    {
        if(is_a($block, 'Mage_Adminhtml_Block_Customer_Grid')){
            $block->addColumn('street_address', array(
                'header'    => Mage::helper('customer')->__('Street Address'),
                'type'      => 'text',
                'align'     => 'center',
                'index'     => 'billing_street_first_line',
                'renderer'  => 'Webtex_CustomerLifetimeSales_Block_Catalog_Product_Renderer_Street'
            ));
            if($after)$block->addColumnOrder($this->getName(), $after);
        }
        return $block;
    }

Here is my join in the Observer that grabs the customers street address:

public function addAttributesToCollection($observer)
    {
        /** @var $collection  Mage_Customer_Model_Resource_Customer_Collection */
        $collection = $observer->getCollection();
        if(is_a($collection,'Mage_Customer_Model_Resource_Customer_Collection'))
            $collection->addAttributeToSelect('total_spent')
                ->addAttributeToSelect('total_in_cart')
                ->addAttributeToSelect('orders_count')
                ->joinAttribute('billing_street_first_line', 'customer_address/street', 'default_billing', null)
                ->addAttributeToSelect('last_order_date');
    }

And finally, here is my renderer:

class Webtex_CustomerLifetimeSales_Block_Catalog_Product_Renderer_Street extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
    public function render(Varien_Object $row)
    {
        $value = $row->getData($this->getColumn()->getIndex());
        return $value;
    }
} 

Now this works fine when displaying the street address in the actual grid, but when I try and export to CSV I get this error:

    a:5:{i:0;s:75:"You cannot define a correlation name 'at_my_shipping_street' more than once";i:1;s:2870:"#0 /opt2/sites/mySite/lib/Varien/Db/Select.php(281): Zend_Db_Select->_join('left join', Array, '(`at_my_shippin...', Array, NULL)
#1 /opt2/sites/mySite/lib/Zend/Db/Select.php(357): Varien_Db_Select->_join('left join', Array, '(`at_my_shippin...', Array, NULL)
#2 /opt2/sites/mySite/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(1348): Zend_Db_Select->joinLeft(Array, '(`at_my_shippin...', Array)
#3 /opt2/sites/mySite/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(1315): Mage_Eav_Model_Entity_Collection_Abstract->_joinAttributeToSelect('joinLeft', Object(Mage_Customer_Model_Attribute), 'at_my_shipping_...', Array, 'my_shipping_str...', 'at_my_shipping_...')
#4 /opt2/sites/mySite/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(668): Mage_Eav_Model_Entity_Collection_Abstract->_addAttributeJoin('my_shipping_str...', 'left')
#5 /opt2/sites/mySite/app/code/local/Webtex/CustomerLifetimeSales/Model/Observer.php(153): Mage_Eav_Model_Entity_Collection_Abstract->joinAttribute('my_shipping_str...', 'customer_addres...', 'default_billing', NULL, 'left')
#6 /opt2/sites/mySite/app/code/core/Mage/Core/Model/App.php(1338): Webtex_CustomerLifetimeSales_Model_Observer->addAttributesToCollection(Object(Varien_Event_Observer))
#7 /opt2/sites/mySite/app/code/core/Mage/Core/Model/App.php(1317): Mage_Core_Model_App->_callObserverMethod(Object(Webtex_CustomerLifetimeSales_Model_Observer), 'addAttributesTo...', Object(Varien_Event_Observer))
#8 /opt2/sites/mySite/app/Mage.php(448): Mage_Core_Model_App->dispatchEvent('eav_collection_...', Array)
#9 /opt2/sites/mySite/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(863): Mage::dispatchEvent('eav_collection_...', Array)
#10 /opt2/sites/mySite/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(951): Mage_Eav_Model_Entity_Collection_Abstract->load()
#11 /opt2/sites/mySite/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(1008): Mage_Adminhtml_Block_Widget_Grid->_exportIterateCollection('_exportCsvItem', Array)
#12 /opt2/sites/mySite/app/code/core/Mage/Adminhtml/controllers/CustomerController.php(380): Mage_Adminhtml_Block_Widget_Grid->getCsvFile()
#13 /opt2/sites/mySite/app/code/core/Mage/Core/Controller/Varien/Action.php(418): Mage_Adminhtml_CustomerController->exportCsvAction()
#14 /opt2/sites/mySite/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(254): Mage_Core_Controller_Varien_Action->dispatch('exportCsv')
#15 /opt2/sites/mySite/app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#16 /opt2/sites/mySite/app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#17 /opt2/sites/mySite/app/Mage.php(684): Mage_Core_Model_App->run(Array)
#18 /opt2/sites/mySite/index.php(91): Mage::run('', 'store')
#19 {main}";s:3:"url";s:83:"/mySite/index.php/myAdminArea/customer/exportCsv/key/be8bdec3e90d2a19c7d05bd23470542b/";s:11:"script_name";s:17:"/mySite/index.php";s:4:"skin";s:5:"admin";}

EDIT2:

Here is the entire model Field class, with my modification at the bottom:

class Webtex_CustomerLifetimeSales_Model_Field extends Webtex_Core_Model_Core
{
    protected function _construct()
    {
        $this->_init('clSales/field');
    }

    public function __call($method, $arguments)
    {
        if (substr($method, 0, 9) == 'addColumn') return $this->addCustomColumn($arguments[0],$arguments[1]);
        else return parent::__call($method, $arguments);
    }

    protected function addCustomColumn($block,$after = null)
    {
        if(is_a($block,'Mage_Adminhtml_Block_Customer_Grid'))
        {
            $columnArray = array();
            $columnArray['header'] = Mage::helper('customer')->__($this->getHelper());
            $columnArray['index'] = $this->getIndex();
            $this->getWidth() != 0 ? $columnArray['width'] = $this->getWidth() : '';
            $this->getType() != '' ? $columnArray['type'] = $this->getType() : '';
            if($this->getType() == "price")
                $columnArray['currency_code'] = Mage::app()->getStore()->getBaseCurrency()->getCode();
            $block->addColumn($this->getName(), $columnArray);
            if($after)$block->addColumnsOrder($this->getName(),$after);

        }
        return $block;

    }

    public function addColumnLastOrderDate($block,$after = null)
    {
        if(is_a($block,'Mage_Adminhtml_Block_Customer_Grid')){
            $block->addColumn('last_order_date', array(
                'header'    => Mage::helper('customer')->__('Last Order Date'),
                'type'      => 'datetime',
                'align'     => 'center',
                'index'     => 'last_order_date',
                'gmtoffset' => true
            ));

            if($after)$block->addColumnsOrder($this->getName(),$after);

        }
        return $block;
    }

    public function addColumnStreetAddress($block,$after = null)
    {
        if(is_a($block, 'Mage_Adminhtml_Block_Customer_Grid')){
            $block->addColumn('street_address', array(
                'header'    => Mage::helper('customer')->__('Street Address'),
                'type'      => 'text',
                'align'     => 'center',
                'index'     => 'customer_address',
                'renderer'  => 'Webtex_CustomerLifetimeSales_Block_Catalog_Product_Renderer_Street'
            ));
        }
        return $block;
    }

}

And here is the Observer with my JOIN in the function addAttributesToCollection:

class Webtex_CustomerLifetimeSales_Model_Observer
{

    public function cartSaveAfterHandler($event)
    {
        try {
            $customer = $event->getCart()->getQuote()->getCustomer();
            if ($customer->getId()) {
                $customer->setTotalInCart($event->getCart()->getQuote()->getGrandTotal());
                $customer->save();
            }
        } catch (Exception $e) {
            if (Mage::getIsDeveloperMode()) {
                echo $e->getMessage();
            }
            Mage::logException($e);
        }
    }

    public function orderSaveAfterHandler($event)
    {
        try {
            $customer = $event->getQuote()->getCustomer();
            if ($customer->getId()) {
                $customer->setTotalInCart(0);
                $customer->save();
            }
        } catch (Exception $e) {
            if (Mage::getIsDeveloperMode()) {
                echo $e->getMessage();
            }
            Mage::logException($e);
        }
    }

    public function invoicePayHandler($event)
    {
        try {
            if ($event->getInvoice()->getCustomerId()) {
                $customer = Mage::getModel('customer/customer')->load($event->getInvoice()->getCustomerId());
                $customer->getAttribute('total_spent');
                $customer->setTotalSpent($customer->getTotalSpent() + $event->getInvoice()->getGrandTotal());
                $customer->save();
            }
        } catch (Exception $e) {
            if (Mage::getIsDeveloperMode()) {
                echo $e->getMessage();
            }
            Mage::logException($e);
        }
    }

    public function invoiceRefundHandler($event)
    {
        try {
            if ($event->getCreditmemo()->getCustomerId()) {
                $customer = Mage::getModel('customer/customer')->load($event->getCreditmemo()->getCustomerId());
                $customer->getAttribute('total_spent');
                $customer->setTotalSpent($customer->getTotalSpent() - $event->getCreditmemo()->getGrandTotal());
                $customer->save();
            }
        } catch (Exception $e) {
            if (Mage::getIsDeveloperMode()) {
                echo $e->getMessage();
            }
            Mage::logException($e);
        }
    }

    public function ordersChangeHandler($event)
    {
        try {
            if ($event->getOrder()->getCustomerId()){
                $data = $event->getDataObject()->getData();
                $originData = $event->getDataObject()->getOrigData();
                switch($data['state']){
                    case 'closed':
                        if(isset($originData) && 'complete'==$originData['state']){
                            $customer = Mage::getModel('customer/customer')->load($event->getOrder()->getCustomerId());
                            $customer->getAttribute('total_spent');
                            $customer->getAttribute('orders_count');
                            $customer->setTotalSpent($customer->getTotalSpent() - $data['base_total_refunded']);
                            $customer->setOrdersCount($customer->getOrdersCount() - 1);
                            $customer->save();
                        }
                        break;
                    case 'complete':
                        if(!isset($originData) || 'complete'!=$originData['state']){
                            $customer = Mage::getModel('customer/customer')->load($event->getOrder()->getCustomerId());
                            $customer->getAttribute('total_spent');
                            $customer->getAttribute('orders_count');
                            $customer->setTotalSpent($customer->getTotalSpent() + $data['base_total_paid']);
                            $customer->setOrdersCount($customer->getOrdersCount() + 1);
                            $customer->setLastOrderDate($data['updated_at']);
                            $customer->save();
                        }
                        break;

                }
            }
        } catch (Exception $e) {
            if (Mage::getIsDeveloperMode()) {
                echo $e->getMessage();
            }
            Mage::logException($e);
        }
    }


    public function addAttributesToCollection($observer)
    {
        /** @var $collection  Mage_Customer_Model_Resource_Customer_Collection */
        $customerStreetCollection = $observer->getCollection();
        if(is_a($customerStreetCollection, 'Mage_Customer_Model_Resource_Customer_Collection'))
        {
            $customerStreetCollection->joinAttribute('customer_address', 'customer_address/street', 'default_billing', null, 'left');
        }
        $collection = $observer->getCollection();
        if(is_a($collection,'Mage_Customer_Model_Resource_Customer_Collection'))
            $collection->addAttributeToSelect('total_spent')
                ->addAttributeToSelect('total_in_cart')
                ->addAttributeToSelect('orders_count')
                ->addAttributeToSelect('last_order_date')
                ->addAttributeToSelect('street_address');
    }

    public function addColumnsInGrid($observer)
    {
        $block = $observer->getEvent()->getBlock();
        if(is_a($block,'Mage_Adminhtml_Block_Customer_Grid')
            && $block->getRequest()->getControllerName() == 'customer')
        {
            /** @var $block Mage_Adminhtml_Block_Customer_Grid */
            /** @var $addFieldsCollection Webtex_CustomerLifetimeSales_Model_Resource_Field_Collection */
            $addFieldsCollection = Mage::getModel('clSales/field')->getCollection();
            $addFieldsCollection->addFieldToFilter('native',0)
                ->addFieldToFilter('is_show',1)
                ->addFieldToFilter('editable',1);

            $lastNative = Mage::getModel('clSales/field')->getCollection()
            ->addFieldToFilter('is_show',1)
            ->addFieldToFilter('native',1)
            ->addFieldToFilter('editable',1)
            ->setOrder('entity_id',Varien_Data_Collection::SORT_ORDER_DESC);
            if(Mage::app()->isSingleStoreMode())$lastNative->addFieldToFilter('name',array('neq'=>'website_id'));
            $lastNative = $lastNative->getFirstItem();

            $filter = new Zend_Filter_Word_UnderscoreToCamelCase();

            foreach($addFieldsCollection as $field)
                $block = call_user_func(array($field, 'addColumn' . $filter->filter($field->getName())), $block, $lastNative->getName());




        }
    }

    public function removeColumnsFromGrid($observer)
    {
        $block = $observer->getEvent()->getBlock();
        if(is_a($block,'Mage_Adminhtml_Block_Customer_Grid')
            && $block->getRequest()->getControllerName() == 'customer')
        {
            /** @var $block Mage_Adminhtml_Block_Customer_Grid */
            /** @var $removeFieldsCollection Webtex_CustomerLifetimeSales_Model_Resource_Field_Collection */
            $removeFieldsCollection = Mage::getModel('clSales/field')->getCollection();
            $removeFieldsCollection->addFieldToFilter('native',1)
                                    ->addFieldToFilter('is_show',0)
                                    ->addFieldToFilter('editable',1);

            foreach($removeFieldsCollection as $field)
                $block->removeColumn($field->getName());


        }
    }
}
?>

Best Answer

This error occurs when that column is set more than once. Probably when you export the data, it already calls this column for the second time. In grid class of your model, try using the following function:

protected function _afterLoadCollection() {
    if(!$this->_isExport) {
        $this->removeColumn('at_my_shipping_street');
    }
}

Note: _afterLoadCollection is used in _prepareCollection() function, so if you override this function in your grid class, eventually you may have to change it as well.

Related Topic