Domanda

Sto cercando di aggiungere alcune colonne extra nella griglia del cliente di Magento. Ho un numero di ordine che funziona con successo (quantità totale di ordini che un cliente ha inserito)

Sto cercando di ottenere l'ultima data di ordinazione, ma non riesco a farlo funzionare. Qualcuno ha fatto questo prima o qualcuno può indicarmi nella giusta direzione su come fare questo?

Questo è il mio codice corrente, ma gli errori e visualizza solo una query SQL.

    $orderTableName = Mage::getSingleton('core/resource')
        ->getTableName('sales/order');
    $collection->getSelect()
        ->joinLeft(
            array('orders' => $orderTableName),
            'orders.customer_id=e.entity_id',
            array(
                'order_count' => 'COUNT(customer_id)',
                'last_order' => 'MAX(created_at)'
            )
        );
    $collection->groupByAttribute('entity_id');
.

È stato utile?

Soluzione

Ecco il funzionamento Esempio per CE 1.8.1:

protected function _prepareCollection()
{
    $collection = Mage::getResourceModel('customer/customer_collection')
        ->addNameToSelect()
        ->addAttributeToSelect('email')
        ->addAttributeToSelect('created_at')
        ->addAttributeToSelect('group_id')
        ->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
        ->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
        ->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
        ->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
        ->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left');



    // add 2 new fields as sub queries      
    $sql ='SELECT MAX(o.created_at)'
        . ' FROM ' . Mage::getSingleton('core/resource')->getTableName('sales/order') . ' AS o'
        . ' WHERE o.customer_id = e.entity_id ';
    $expr = new Zend_Db_Expr('(' . $sql . ')'); 

    $collection->getSelect()->from(null, array('last_order_date'=>$expr));

    $sql ='SELECT COUNT(*)'
        . ' FROM ' . Mage::getSingleton('core/resource')->getTableName('sales/order') . ' AS o'
        . ' WHERE o.customer_id = e.entity_id ';
    $expr = new Zend_Db_Expr('(' . $sql . ')'); 

    $collection->getSelect()->from(null, array('orders_count'=>$expr));

    //echo $collection->getSelect(); exit;      

    $this->setCollection($collection);

    return parent::_prepareCollection();
}
.

e

protected function _prepareColumns()
{
    $this->addColumn('entity_id', array(
        'header'    => Mage::helper('customer')->__('ID'),
        'width'     => '50px',
        'index'     => 'entity_id',
        'type'  => 'number',
    ));

    $this->addColumn('last_order_date', array(
        'header'    => Mage::helper('customer')->__('Last Order Date'),
        'type'      => 'datetime',
        'align'     => 'center',
        'index'     => 'last_order_date',
        'gmtoffset' => true,        
    ));

    $this->addColumn('orders_count', array(
        'header'    => Mage::helper('customer')->__('Orders Count'),
        'index'     => 'orders_count',
    ));

    ........
    ........
.

L'uscita è

ordini

Altri suggerimenti

Ecco come farei questo.
Creerei 2 attributi chiamati last_order_date e orders_count sull'entità del cliente che sono visibili solo nel backend. O non visibile affatto. qui è un modo possibile per aggiungerli .

La creazione di un osservatore sull'evento checkout_submit_all_after che cambierebbe i valori di questi attributi.
Qualcosa del genere:

public function checkoutSubmitAllAfter($observer) {
    $order = $observer->getEvent()->getOrder();
    if ($order) { //if on onepage checkout;
        $customer = $order->getCustomer();
        $lastOrderDate = $order->getCreatedAt();
        $increment = 1;
    }
    else { //if on multishipping checkout
       $orders = $observer->getEvent()->getOrders();
       //get last order that's the important one;
       $order = $orders[count($orders) - 1];
       $customer = $order->getCustomer();
       $lastOrderDate = $order->getCreatedAt();
       $increment = count($orders);
    }
    if ($customer && $customer->getId()) { //check if the customer is logged in
       //make sure you have a clean instance of the customer
       //this line may not be needed. Test with it and without it.
       $customer = Mage::getModel('customer/customer')->load($customer->getId());
       //set the new values on the customer entity
       $customer->setLastOrderDate($lastOrderDate);
       $customer->setOrdersCount((int)$customer->getOrdersCount() + $increment);
       $customer->save();
    }
}
.

Non ho testato il codice, quindi potrei aver perso qualcosa.

Ora hai i valori di cui hai bisogno sull'oggetto cliente e non hai bisogno di alcuna pazzo join o ordinamento di ordinamento e specialmente nessun group by.
Puoi Aggiungi le tue 2 nuove colonne nella griglia del cliente e puoi persino renderli in ordine e filtrabili facilmente.

Se hai già clienti nel tuo DB, allora avrai bisogno di uno script di una volta solo che imposta i valori per i clienti esistenti.
Ma puoi identificare facilmente questi valori.

Se hai bisogno solo di uno stato "completo" come me, quindi aggiungi solo . ' AND o.status LIKE "complete" ' dopo . ' WHERE o.customer_id = e.entity_id ';

Ho anche aggiunto il denaro totale speso dal cliente (quindi il totale di tutti gli ordini completi)

    $total_pricesql ='SELECT sum(o.base_grand_total)'
        . ' FROM ' . Mage::getSingleton('core/resource')->getTableName('sales/order') . ' AS o'
        . ' WHERE o.customer_id = e.entity_id ' . ' AND o.status LIKE  "complete" ';
    $expr = new Zend_Db_Expr('(' . $total_pricesql . ')'); 

    $collection->getSelect()->from(null, array('total_price'=>$expr));
.

e successivamente nello stesso file

    $this->addColumn('total_price', array(
        'header' => Mage::helper('sales')->__('Total'),
        'index' => 'total_price',
        'type'  => 'number',
        'filter'    => false,
    ));
.

Quindi cambia i primi codici di Amasty:

protected function _prepareCollection() {
$collection = Mage::getResourceModel('customer/customer_collection')
    ->addNameToSelect()
    ->addAttributeToSelect('email')
    ->addAttributeToSelect('created_at')
    ->addAttributeToSelect('group_id')
    ->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
    ->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
    ->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
    ->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
    ->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left');



// add 3 new fields as sub queries      
$sql ='SELECT MAX(o.created_at)'
    . ' FROM ' . Mage::getSingleton('core/resource')->getTableName('sales/order') . ' AS o'
    . ' WHERE o.customer_id = e.entity_id ' . ' AND o.status LIKE  "complete" ';
$expr = new Zend_Db_Expr('(' . $sql . ')'); 

$collection->getSelect()->from(null, array('last_order_date'=>$expr));

$sql ='SELECT COUNT(*)'
    . ' FROM ' . Mage::getSingleton('core/resource')->getTableName('sales/order') . ' AS o'
    . ' WHERE o.customer_id = e.entity_id ' . ' AND o.status LIKE  "complete" ';
$expr = new Zend_Db_Expr('(' . $sql . ')'); 

$collection->getSelect()->from(null, array('orders_count'=>$expr));

$total_pricesql ='SELECT sum(o.base_grand_total)'
    . ' FROM ' . Mage::getSingleton('core/resource')->getTableName('sales/order') . ' AS o'
    . ' WHERE o.customer_id = e.entity_id ' . ' AND o.status LIKE  "complete" ';
$expr = new Zend_Db_Expr('(' . $total_pricesql . ')'); 

$collection->getSelect()->from(null, array('total_price'=>$expr));

//echo $collection->getSelect(); exit;      

$this->setCollection($collection); return parent::_prepareCollection();}
.

e il secondo codice:

protected function _prepareColumns() {
$this->addColumn('entity_id', array(
    'header'    => Mage::helper('customer')->__('ID'),
    'width'     => '50px',
    'index'     => 'entity_id',
    'type'  => 'number',
));

$this->addColumn('last_order_date', array(
    'header'    => Mage::helper('customer')->__('Last Order Date'),
    'type'      => 'datetime',
    'align'     => 'center',
    'index'     => 'last_order_date',
    'gmtoffset' => true,        
));

$this->addColumn('orders_count', array(
    'header'    => Mage::helper('customer')->__('Orders Count'),
    'index'     => 'orders_count',
));

$this->addColumn('total_price', array(
    'header' => Mage::helper('sales')->__('Total'),
    'index' => 'total_price',
    'type'  => 'number',
    'filter'    => false,
));

........
........
.

Ecco come ho risolto il problema con il filtro e il funzionamento dell'ordine, _prepareCollection:

$collection = Mage::getResourceModel('customer/customer_collection')
    ->addNameToSelect()
    ->joinAttribute('billing_street', 'customer_address/street', 'default_billing', null, 'left')
    ->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
    ->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
    ->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
;

$sql = sprintf('SELECT MAX(o.created_at) AS created_at FROM %s AS o GROUP BY o.customer_id', Mage::getSingleton('core/resource')->getTableName('sales/order_grid'));
$expr = new Zend_Db_Expr('(' . $sql . ')');

$collection->joinTable(array('order' => 'sales/order_grid'), 'customer_id=entity_id', array('order_created_at' => 'created_at'), "order.created_at IN ($expr)", 'left');
.

Poi su _prepareColumns:

$this->addColumn('order_created_at', array(
    'header'    => Mage::helper('sales')->__('Purchased On'),
    'type'      => 'datetime',
    'index'     => 'order_created_at',
    'gmtoffset' => true,
));
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top