Tambahkan Kolom ke kisi (pengamat) - Kolom 'store_id' di mana klausa merupakan masalah yang mendua

16

Saya menambahkan kolom ke kisi pesanan menggunakan pendekatan pengamat:

  1. Di acara tersebut -> sales_order_grid_collection_load_beforesaya menambahkan bergabung ke koleksi
  2. Pada acara tersebut -> core_block_abstract_prepare_layout_beforesaya menambahkan kolom ke kisi

EDIT Info:

Pada Acara (1):

   public function salesOrderGridCollectionLoadBefore($observer)
{
    $collection = $observer->getOrderGridCollection();
    $collection->addFilterToMap('store_id', 'main_table.store_id');
    $select = $collection->getSelect();
    $select->joinLeft(array('oe' => $collection->getTable('sales/order')), 'oe.entity_id=main_table.entity_id', array('oe.customer_group_id'));

}

Pada Acara (2):

public function appendCustomColumn(Varien_Event_Observer $observer)
{
    $block = $observer->getBlock();
    if (!isset($block)) {
        return $this;
    }

    if ($block->getType() == 'adminhtml/sales_order_grid') {
        /* @var $block Mage_Adminhtml_Block_Customer_Grid */
        $this->_addColumnToGrid($block);
    }
}

protected function _addColumnToGrid($grid)
{

    $groups = Mage::getResourceModel('customer/group_collection')
        ->addFieldToFilter('customer_group_id', array('gt' => 0))
        ->load()
        ->toOptionHash();
    $groups[0] = 'Guest';


    /* @var $block Mage_Adminhtml_Block_Customer_Grid */
    $grid->addColumnAfter('customer_group_id', array(
        'header' => Mage::helper('customer')->__('Customer Group'),
        'index' => 'customer_group_id',
        'filter_index' => 'oe.customer_group_id',
        'type' => 'options',
        'options' => $groups,
    ), 'shipping_name');
}

Semuanya berfungsi dengan baik sampai saya menyaring kotak dengan filter tampilan toko: Kolom 'store_id' di mana klausa adalah masalah ambigu

Saya telah mencetak kueri:

SELECT `main_table`.*, `oe`.`customer_group_id` 
FROM `sales_flat_order_grid` AS `main_table`
LEFT JOIN `sales_flat_order` AS `oe` ON oe.entity_id=main_table.entity_id 
WHERE (store_id = '5') AND (oe.customer_group_id = '6')

Seperti yang Anda lihat store_idmiss main_tablealias.

Untuk mencapai ini saya hanya perlu mengatur filter_indexkolom ID toko tetapi melalui pengamat Jadi pertanyaannya adalah bagaimana saya bisa melakukannya dengan cepat ?
Tanpa mengesampingkan kelas blok ? (Kalau tidak, pendekatan pengamat tidak berguna)

Fra
sumber

Jawaban:

32

Mari kita coba ini lagi dengan solusi lain yang saya sebutkan sebelumnya untuk Anda :-), saya telah membangun ekstensi lengkap untuk menunjukkan kepada Anda bagaimana menambahkan bidang ke tabel kisi. Setelah itu Anda hanya perlu file pembaruan tata letak untuk menambahkan kolom untuk Anda memesan halaman kisi.

Saya menelepon ekstensi Example_SalesGrid, tetapi Anda dapat mengubahnya untuk kebutuhan Anda sendiri.

Mari kita mulai dengan membuat modul init xml di /app/etc/modules/Example_SalesGrid.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!--
 Module bootstrap file
-->
<config>
    <modules>
        <Example_SalesGrid>
            <active>true</active>
            <codePool>community</codePool>
            <depends>
                <Mage_Sales />
            </depends>
        </Example_SalesGrid>
    </modules>
</config>

Selanjutnya kita membuat konfigurasi modul xml di /app/code/community/Example/SalesGrid/etc/config.xml :

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Example_SalesGrid>
            <version>0.1.0</version> <!-- define version for sql upgrade -->
        </Example_SalesGrid>
    </modules>
    <global>
        <models>
            <example_salesgrid>
                <class>Example_SalesGrid_Model</class>
            </example_salesgrid>
        </models>
        <blocks>
            <example_salesgrid>
                <class>Example_SalesGrid_Block</class>
            </example_salesgrid>
        </blocks>
        <events>
            <!-- Add observer configuration -->
            <sales_order_resource_init_virtual_grid_columns>
                <observers>
                    <example_salesgrid>
                        <model>example_salesgrid/observer</model>
                        <method>addColumnToResource</method>
                    </example_salesgrid>
                </observers>
            </sales_order_resource_init_virtual_grid_columns>
        </events>
        <resources>
            <!-- initialize sql upgrade setup -->
            <example_salesgrid_setup>
                <setup>
                    <module>Example_SalesGrid</module>
                    <class>Mage_Sales_Model_Mysql4_Setup</class>
                </setup>
            </example_salesgrid_setup>
        </resources>
    </global>
    <adminhtml>
        <layout>
            <!-- layout upgrade configuration -->
            <updates>
                <example_salesgrid>
                    <file>example/salesgrid.xml</file>
                </example_salesgrid>
            </updates>
        </layout>
    </adminhtml>
</config>

Sekarang kita membuat skrip upgrade sql di /app/code/community/Example/SalesGrid/sql/example_salesgrid_setup/install-0.1.0.php :

<?php
/**
 * Setup scripts, add new column and fulfills
 * its values to existing rows
 *
 */
$this->startSetup();
// Add column to grid table

$this->getConnection()->addColumn(
    $this->getTable('sales/order_grid'),
    'customer_group_id',
    'smallint(6) DEFAULT NULL'
);

// Add key to table for this field,
// it will improve the speed of searching & sorting by the field
$this->getConnection()->addKey(
    $this->getTable('sales/order_grid'),
    'customer_group_id',
    'customer_group_id'
);

// Now you need to fullfill existing rows with data from address table

$select = $this->getConnection()->select();
$select->join(
    array('order'=>$this->getTable('sales/order')),
    $this->getConnection()->quoteInto(
        'order.entity_id = order_grid.entity_id'
    ),
    array('customer_group_id' => 'customer_group_id')
);
$this->getConnection()->query(
    $select->crossUpdateFromSelect(
        array('order_grid' => $this->getTable('sales/order_grid'))
    )
);

$this->endSetup();

Selanjutnya kita membuat file pembaruan tata letak di /app/design/adminhtml/default/default/layout/example/salesgrid.xml:

<?xml version="1.0"?>
<layout>
    <!-- main layout definition that adds the column -->
    <add_order_grid_column_handle>
        <reference name="sales_order.grid">
            <action method="addColumnAfter">
                <columnId>customer_group_id</columnId>
                <arguments module="sales" translate="header">
                    <header>Customer Group</header>
                    <index>customer_group_id</index>
                    <type>options</type>
                    <filter>Example_SalesGrid_Block_Widget_Grid_Column_Customer_Group</filter>
                    <renderer>Example_SalesGrid_Block_Widget_Grid_Column_Renderer_Customer_Group</renderer>
                    <width>200</width>
                </arguments>
                <after>grand_total</after>
            </action>
        </reference>
    </add_order_grid_column_handle>
    <!-- order grid action -->
    <adminhtml_sales_order_grid>
        <!-- apply the layout handle defined above -->
        <update handle="add_order_grid_column_handle" />
    </adminhtml_sales_order_grid>
    <!-- order grid view action -->
    <adminhtml_sales_order_index>
        <!-- apply the layout handle defined above -->
        <update handle="add_order_grid_column_handle" />
    </adminhtml_sales_order_index>
</layout>

Sekarang kita membutuhkan dua file Blokir, satu untuk membuat opsi filter, /app/code/community/Example/SalesGrid/Block/Widget/Grid/Column/Customer/Group.php:

<?php

class Example_SalesGrid_Block_Widget_Grid_Column_Customer_Group extends Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select  {

    protected $_options = false;

    protected function _getOptions(){

        if(!$this->_options) {
            $methods = array();
            $methods[] = array(
                'value' =>  '',
                'label' =>  ''
            );
            $methods[] = array(
                'value' =>  '0',
                'label' =>  'Guest'
            );

            $groups = Mage::getResourceModel('customer/group_collection')
                ->addFieldToFilter('customer_group_id', array('gt' => 0))
                ->load()
                ->toOptionArray();

            $this->_options = array_merge($methods,$groups);
        }
        return $this->_options;
    }
}

Dan yang kedua untuk menerjemahkan nilai baris ke teks yang benar yang akan ditampilkan, /app/code/community/Example/SalesGrid/Block/Widget/Grid/Column/Renderer/Customer/Group.php :

<?php

class Example_SalesGrid_Block_Widget_Grid_Column_Renderer_Customer_Group extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract   {

    protected $_options = false;

    protected function _getOptions(){

        if(!$this->_options) {
            $methods = array();
            $methods[0] = 'Guest';

            $groups = Mage::getResourceModel('customer/group_collection')
                ->addFieldToFilter('customer_group_id', array('gt' => 0))
                ->load()
                ->toOptionHash();
            $this->_options = array_merge($methods,$groups);
        }
        return $this->_options;
    }

    public function render(Varien_Object $row){
        $value = $this->_getValue($row);
        $options = $this->_getOptions();
        return isset($options[$value]) ? $options[$value] : $value;
    }
}

File terakhir yang dibutuhkan hanya diperlukan jika Anda membuat kolom tambahan dari tabel selain dari penjualan / pesanan (sales_flat_order). Semua bidang dalam sales / order_grid yang cocok dengan nama kolom dari sales / order secara otomatis diperbarui dalam tabel sales / order_grid. Jika Anda perlu menambahkan opsi pembayaran misalnya, Anda akan memerlukan pengamat ini untuk menambahkan bidang ke kueri sehingga data dapat disalin ke tabel yang benar. Pengamat yang digunakan untuk ini adalah di /app/code/community/Example/SalesGrid/Model/Observer.php :

<?php
/**
 * Event observer model
 *
 *
 */
class Example_SalesGrid_Model_Observer {

    public function addColumnToResource(Varien_Event_Observer $observer) {
        // Only needed if you use a table other than sales/order (sales_flat_order)

        //$resource = $observer->getEvent()->getResource();
        //$resource->addVirtualGridColumn(
        //  'payment_method',
        //  'sales/order_payment',
        //  array('entity_id' => 'parent_id'),
        //  'method'
        //);
    }
}

Kode ini didasarkan pada contoh dari http://www.ecomdev.org/2010/07/27/adding-order-attribute-to-orders-grid-in-magento-1-4-1.html

Semoga contoh di atas menyelesaikan masalah Anda.

Vladimir Kerkhoff
sumber
Maaf saya tidak bisa mengujinya saat bepergian ... Kedengarannya sedikit lebih rumit bahwa pendekatan saya (apakah itu juga berfungsi untuk pesanan baru?)
Fra
Pengamat kisi menangani perubahan data pada setiap perubahan, karena ini adalah penggunaan Magento asli yang Anda tidak perlu membuat gabungan ke tabel lain, ini mempercepat kueri pada sejumlah besar pesanan (semua data disimpan di sales_flat_order_grid).
Vladimir Kerkhoff
Ketika saya mencoba dan menggunakan ini, saya mendapatkan kesalahan. Peringatan: Hilang argumen 2 untuk Varien_Db_Adapter_Pdo_Mysql :: quoteInto ()
Vaishal Patel
4

Coba gunakan ini:

public function salesOrderGridCollectionLoadBefore($observer)
{
    /**
     * @var $select Varien_DB_Select
     */
    $collection = $observer->getOrderGridCollection();
    $collection->addFilterToMap('store_id', 'main_table.store_id');
    $select     = $collection->getSelect();
    $select->joinLeft(array('oe' => $collection->getTable('sales/order')), 'oe.entity_id=main_table.entity_id', array('oe.customer_group_id'));
    if ($where = $select->getPart('where')) {
        foreach ($where as $key=> $condition) {
            if (strpos($condition, 'store_id')) {
                $value       = explode('=', trim($condition, ')'));
                $value       = trim($value[1], "' ");
                $where[$key] = "(main_table.store_id = '$value')";
            }
        }
        $select->setPart('where', $where);
    }
}
mageUz
sumber
1
Ini seharusnya benar-benar diterima sebagai jawaban untuk pendekatan pengamat OP.
musicliftsme
2

Apakah Anda benar-benar membutuhkan salesOrderGridCollectionLoadBeforekode berikut dalam metode Anda $collection->addFilterToMap('store_id', 'main_table.store_id');? Jika tidak menghapusnya dan coba yang berikut ini:

protected function _addColumnToGrid($grid)
{
....... // here you code from your post above

    $storeIdColumn = $grid->getColumn('store_id');

    if($storeIdColumn) {
        $storeIdColumn->addData(array('filter_index' => 'main_table.store_id'));
    }
}
Sylvain Rayé
sumber
Sudah mencoba kedua :( Column('store_id');tidak tersedia di core_block_abstract_prepare_layout_before (_prepareColumn () dipanggil setelah jadi kolom tidak ada pada waktu itu) addFilterToMaptidak melakukan pekerjaan
Fra
tahu mengapa addFilterToMap tidak berfungsi?
Fra
Soory Saya tidak punya banyak waktu untuk melihatnya hari-hari terakhir ini. Mungkin besok. Hanya sebuah ide, karena saya ingat sedikit alasan mengapa saya bilang tidak menggunakan addFilterToMap, adalah bagaimana Anda menggunakan mungkin salah, parameter salah atau tidak digunakan pada saat yang tepat. Itu hanya ide dari ingatan.
Sylvain Rayé
2

Alih-alih menggunakan nama kolom statis, Anda dapat menggunakan metode di bawah ini untuk semua kolom. Saya bisa mengerti jika menggunakan jawaban mageUz yang akan bekerja untuk satu kolom dan jika Anda pergi untuk beberapa kolom lainnya maka Anda mungkin mendapatkan kesalahan yang sama. Jadi kode di bawah ini memberi Anda solusi untuk semua kolom secara bersamaan.

public function salesOrderGridCollectionLoadBefore(Varien_Event_Observer $observer)
{
    $collection = $observer->getOrderGridCollection();
    $select = $collection->getSelect();
    $select->joinLeft(array('order' => $collection->getTable('sales/order')), 'order.entity_id=main_table.entity_id',array('shipping_arrival_date' => 'shipping_arrival_date'));

    if ($where = $select->getPart('where')) {
        foreach ($where as $key=> $condition) {
            $parsedString = $this->get_string_between($condition, '`', '`');
    $yes = $this->checkFiledExistInTable('order_grid',$parsedString);
    if($yes){
        $condition = str_replace('`','',$condition);
        $where[$key] = str_replace($parsedString,"main_table.".$parsedString,$condition);
    }
        }
        $select->setPart('where', $where);
    }
}

 public function checkFiledExistInTable($entity=null,$parsedString=null){
   $resource = Mage::getSingleton('core/resource');
   $readConnection = $resource->getConnection('core_read');

    if($entity == 'order'){
       $table = 'sales/order';
    }elseif($entity == 'order_grid'){
        $table = 'sales/order_grid';
    }else{
        return false;
    }

     $tableName = $resource->getTableName($table);
    $saleField = $readConnection->describeTable($tableName);

    if (array_key_exists($parsedString,$saleField)){
       return true;
   }else{
      return false;
   }
 }

function get_string_between($string, $start, $end){
    $string = ' ' . $string;
    $ini = strpos($string, $start);
    if ($ini == 0) return '';
    $ini += strlen($start);
    $len = strpos($string, $end, $ini) - $ini;
    return substr($string, $ini, $len);
}
jyotiranjan.in
sumber