2010-10-16 13 views
8

Desidero pre-filtrare * i dati nella griglia delle fatture visibili nel pannello di amministrazione di Magento.Come selezionare campi specifici con alias usando joinTable o joinField in Magento

Here è una domanda che ho chiesto in precedenza, e questa è correlata alla soluzione presentata per questo, quindi potrebbe fungere da buona spiegazione.

Quindi, sto modificando il metodo Mage_Adminhtml_Block_Sales_Invoice_Grid :: _ prepareCollection in modo tale che prima recuperi il cliente indicato dall'amministratore connesso. Quindi recupererà gli ordini da questi clienti - idealmente solo gli ID ordine - Quindi unisci questa raccolta a vendite/order_invoice_grid, per ottenere le fatture da elencare per questo amministratore.

Sulla base dell'ultima risposta e l'utilizzo di these documenti, in seguito sono 3 modi che ho provato unendo queste informazioni: (Codice di esempio 1)

$collection = Mage::getResourceModel('customer/customer_collection');   
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('*')); 
$collection->joinTable('sales/invoice_grid', 'order_id=main_table.entity_id', array('*')); 

Quando faccio quanto sopra, vedo il seguente errore:

A joint field with this alias (0) is already declared. 

#0 /var/www/magento/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(706): Mage::exception('Mage_Eav', 'A joint field w...') 
#1 /var/www/magento/app/code/local/Myproject/Adminhtml/Block/Sales/Invoice/Grid.php(41): Mage_Eav_Model_Entity_Collection_Abstract->joinTable('sales/invoice_g...', 'order_id=main_t...', Array) 
#2 /var/www/magento/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(576): Myproject_Adminhtml_Block_Sales_Invoice_Grid->_prepareCollection() 
#3 /var/www/magento/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(582): Mage_Adminhtml_Block_Widget_Grid->_prepareGrid() 

Se rimuovo la seconda chiamata a joinTable, il codice riportato sopra funziona, ma non è quello che voglio.

L'altro metodo ho provato è con questo codice:

$collection = Mage::getResourceModel('customer/customer_collection');   
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('entity_id as order_entity_id')); 
$collection->joinTable('sales/invoice_grid', 'order_id=main_table.entity_id', array('*')); 

Qui l'errore si verifica nella seconda riga, dove sto effettivamente cercando di alias l'order.entity_id campo in modo che non sia in conflitto con la fattura tabelle entity_id. Tuttavia, che produce un errore come:

Item (Mage_Customer_Model_Customer) with the same id "1" already exist

Ho solo bisogno dell'ordine id in modo che possa ottenere fatture relative, il che suggerisce che posso anche usare funzione joinField, che ho provato come segue:

$collection = Mage::getResourceModel('customer/customer_collection'); 
$collection->joinField('order_entity_id', 'sales/order_grid', 'entity_id', 'customer_id=entity_id' , null, 'left'); 

ma mi dà il seguente errore:

Prodotto (Mage_Customer_Model_Customer) con lo stesso ID "1" esiste già

sto cercando una soluzione che unisce personalizzato ER-> fatture.


By pre-filtro voglio dire che i dati riportati nella griglia è filtrata anche prima di qualsiasi cosa è presentato nella griglia.


Ok, ora il mio codice è simile:

$collection = 
Mage::getResourceModel('customer/customer_collection'); 
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('entity_id' => 'order_entity_id')); 

E l'errore che ottengo è:

SELECT `e`.*, `sales_flat_order_grid`.`order_entity_id` AS `entity_id` FROM `customer_entity` AS `e` 
INNER JOIN `sales_flat_order_grid` ON (sales_flat_order_grid.customer_id=e.entity_id) WHERE (e.entity_type_id = '1') ORDER BY `e`.`created_at` desc, `e`.`created_at` desc LIMIT 20 

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sales_flat_order_grid.order_entity_id' in 'field list' 

risposta

8

Ecco il totale del mio script di test. Per utilizzarlo mettilo in un file nella radice di Magento e digita il suo URL direttamente nel tuo browser, non è gestito dai controller di Magento. Questo è un buon modo di sperimentare quanto non è come influenzato da altri moduli, layout di pagina, ecc

<pre><?php 

require 'app/Mage.php'; 
Mage::app(); 

$collection = Mage::getResourceModel('customer/customer_collection'); 
$collection->getSelect()->reset('columns');   
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('order_entity_id' => 'entity_id')); 
$collection->joinTable('sales/invoice_grid', 'order_id=order_entity_id', array('*')); 

foreach ($collection as $invoice) 
    print_r($invoice->debug()); 

?></pre> 

Come con la tua domanda precedente ho scelto di ripristinare le colonne iniziali perché non credo nel dare il database più lavoro del necessario. Tuttavia non è essenziale, il test riesce ancora senza di esso.

Se ciò non funziona nell'installazione, è necessario considerare quale potrebbe essere l'influenza esterna.

1

Ti dà questo errore "Item (Mage_Customer_Model_Customer) con lo stesso id "1" esiste già "perché un cliente può avere più ordini e quindi potrebbe averne due o più Le voci con lo stesso ID cliente: stai creando una raccolta di clienti e devi avere voci uniche nella raccolta. Devi iniziare dalle fatture e unirti a loro con i clienti.

+0

ho provato con il suo suggerimento, come segue: "$ raccolta = Mage :: getResourceModel ($ this -> _ getCollectionClass()); $ Collezione> joinTable ('vendite/ordine', 'ENTITY_ID = order_id', array ('*'));" E questa volta l'errore è: Fatal error: Call to metodo non definito Mage_Sales_Model_Mysql4_Order_Invoice_Grid_Collection :: joinTable () in /var/www/magento/app/code/local/Myproject/Adminhtml/Block/Sales/Invoice/Grid.php alla riga 41 –

+0

È perché Mage_Sales_Model_Mysql4_Order_Grid_Collection eredita da Mage_Core_Model_Mysql4_Collection_Abstract, non usa il modello eav; per usare join ($ table, $ cond, $ cols = '*'). La collezione cliente eredita da Mage_Eav_Model_Entity_Collection_Abstract e tu usi joinTable –

2

L'errore "Un campo comune con questo alias (0) è già dichiarato." si verifica perché utilizza chiavi di array come alias. Poiché hai due chiamate joinTable(), ognuna con un array, sta tentando di utilizzare l'indice a base zero di entrambi e ovviamente di avere un conflitto.
Così, invece di

array('entity_id as order_entity_id') 

provare

array('entity_id' => 'order_entity_id') 

per evitare il conflitto.

+0

Ho aggiunto una sezione nella mia domanda sotto la seconda partizione orizzontale. sfortunatamente non conosco bene l'ORM di Magento e non riesco a trovare una soluzione. –

+0

Whoops, ho preso la chiave e valore nel modo sbagliato.Avrei dovuto dire 'array ('order_entity_id' => 'ENTITY_ID')' – clockworkgeek

+0

ho già provato in quel modo, e l'errore è: "Prodotto (Mage_Customer_Model_Customer) con lo stesso ID "1" esiste già # 0/var/www/magento/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php (236): Varien_Data_Collection-> addItem (Object (Mage_Customer_Model_Customer)) # 1/var/www/magento/app /code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(963): Mage_Eav_Model_Entity_Collection_Abstract-> addItem (Object (Mage_Customer_Model_Customer)) " –

2

Alla fine ho raggiunto questo risultato passando da fattura-> ordine-> cliente come suggerito da "Anda B". Sto semplicemente incollando la mia soluzione qui come riferimento, ma userò la soluzione this da clockworkgeek, poiché sembra molto più pulita. E la mia soluzione deve ancora essere fatta più pulito ottenendo il 'id' di eav_attribute (agent_id) dal database in fase di esecuzione, invece di difficile codificazione, come incollato qui:

class Myproject_Adminhtml_Block_Sales_Invoice_Grid extends Mage_Adminhtml_Block_Sales_Invoice_Grid 
{ 
    const AGENT_ID_ATTRIBUTE_ID = 118; 

    protected function _prepareCollection() 
    { 

$collection = Mage::getResourceModel($this->_getCollectionClass()); 

     $collection->join('order_grid', 'order_id = order_grid.entity_id', array ('order_entity_id' => 'order_grid.entity_id')); 
     $collection->getSelect()->join('customer_entity', 'customer_id = customer_entity.entity_id', array('customer_entity_id' => 'entity_id', 'email')); 
     $collection->getSelect()->joinLeft('customer_entity_int', 'customer_entity_int.entity_id = customer_entity.entity_id AND attribute_id = ' . Myproject_Adminhtml_Block_Sales_Invoice_Grid::AGENT_ID_ATTRIBUTE_ID, 
             array('attribute_entity_id' => 'customer_entity_int.entity_id', 'attribute_id' , 'value')); 

//Apply Desired Data Filters here 

$this->setCollection($collection); 

return $collection; 
1

Il modo più semplice che ho trovato fuori dalla il forum di Magento,

Nel

protected function _prepareCollection() 
{ 
    $collection = Mage::getResourceModel('customer/customer_collection') 

possiamo utilizzare le query personalizzate come

$collection->getSelect()->columns(array('filename' => new Zend_Db_Expr ("(SELECT filename FROM cat WHERE customer_id =e.entity_id)"))); 

e funziona

$this->setCollection($collection); 
var_dump($collection); 
Problemi correlati