Thêm Cột vào lưới (người quan sát) - Cột 'store_id' trong đó mệnh đề là vấn đề mơ hồ


16

Tôi đang thêm một cột vào lưới đặt hàng bằng cách sử dụng phương pháp quan sát viên:

  1. Trong sự kiện -> sales_order_grid_collection_load_beforeTôi đang thêm một tham gia vào bộ sưu tập
  2. Trong sự kiện -> core_block_abstract_prepare_layout_beforeTôi đang thêm một cột vào lưới

EDIT Thông tin thêm:

Trên sự kiện (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'));

}

Trên sự kiện (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');
}

Mọi thứ đều hoạt động tốt cho đến khi tôi lọc lưới với bộ lọc chế độ xem cửa hàng: Cột 'store_id' trong đó mệnh đề là vấn đề mơ hồ

Tôi đã in truy vấn:

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')

Như bạn thấy store_idbỏ lỡ main_tablebí danh.

Để thực hiện điều này tôi chỉ cần đặt filter_indexcột Id cho cửa hàng nhưng thông qua người quan sát Vì vậy, câu hỏi là làm thế nào tôi có thể làm điều đó một cách nhanh chóng ?
Nếu không ghi đè lớp khối ? (nếu không thì cách tiếp cận của người quan sát là vô ích)

Câu trả lời:


32

Chúng ta hãy thử lại với giải pháp khác mà tôi đã đề cập trước đây cho bạn :-), tôi đã xây dựng tiện ích mở rộng hoàn chỉnh để chỉ cho bạn cách thêm trường vào bảng lưới. Sau đó, bạn chỉ cần một tệp cập nhật bố cục để thêm cột để bạn đặt hàng trang lưới.

Tôi đã gọi phần mở rộng example_SalesGrid, nhưng bạn có thể thay đổi nó theo nhu cầu của riêng bạn.

Hãy bắt đầu bằng cách tạo mô-đun init xml trong /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>

Tiếp theo, chúng tôi tạo mô-đun cấu hình xml của chúng tôi trong /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>

Bây giờ chúng tôi tạo tập lệnh nâng cấp sql trong /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();

Tiếp theo, chúng tôi tạo tệp cập nhật bố cục trong /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>

Bây giờ chúng tôi cần hai tệp Chặn, một để tạo các tùy chọn bộ lọc, /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;
    }
}

Và thứ hai để dịch các giá trị hàng thành văn bản chính xác sẽ được hiển thị, /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;
    }
}

Tệp cuối cùng cần thiết chỉ cần thiết nếu bạn tạo thêm một cột từ một bảng khác ngoài doanh số / đơn hàng (sales_flat_order). Tất cả các trường trong sales / order_grid khớp với tên cột từ doanh số / đơn hàng được tự động cập nhật trong bảng sales / order_grid. Nếu bạn cần thêm tùy chọn thanh toán chẳng hạn, bạn sẽ cần người quan sát này thêm trường vào truy vấn để dữ liệu có thể được sao chép vào đúng bảng. Trình quan sát được sử dụng cho điều này là trong /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'
        //);
    }
}

Mã này được dựa trên ví dụ từ http://www.ecomdev.org/2010/07/27/adding-order-attribution-to-nings-grid-in-magento-1-4-1.html

Hy vọng ví dụ trên giải quyết vấn đề của bạn.


Xin lỗi tôi đã không thể kiểm tra nó khi tôi đang đi du lịch ... Nghe có vẻ phức tạp hơn một chút là cách tiếp cận của tôi (nó cũng hoạt động cho đơn hàng mới phải không?)
Fra

Trình quan sát lưới xử lý các thay đổi dữ liệu mỗi khi thay đổi, vì đây là cách sử dụng Magento riêng mà bạn không cần tạo bất kỳ phép nối nào với các bảng khác, điều này tăng tốc truy vấn trên số lượng lớn đơn hàng (tất cả dữ liệu được lưu trữ trong sales_flat_order_grid).
Vladimir Kerkhoff

Khi tôi thử và sử dụng, tôi nhận được lỗi Cảnh báo: Thiếu đối số 2 cho Varien_Db_Ad CHƯƠNG_Pdo_Mysql :: quoteInto ()
Vaishal Patel

4

Hãy thử sử dụng những thứ này:

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);
    }
}

1
Điều này đáng lẽ phải được chấp nhận như là câu trả lời cho phương pháp quan sát của OP.
nhạcliftsme

2

Bạn có thực sự cần trong phương pháp của bạn salesOrderGridCollectionLoadBeforemã sau đây $collection->addFilterToMap('store_id', 'main_table.store_id');? Nếu không loại bỏ nó và thử như sau:

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'));
    }
}

Đã thử cả hai :( Column('store_id');không khả dụng trên core_block_abstract_prepare_layout_before (_prepareColumn () được gọi sau nên cột không tồn tại vào thời điểm đó) addFilterToMapkhông hoạt động là công việc
Fra

Bất cứ ý tưởng tại sao addFilterToMap không hoạt động?
Fra

Soory tôi đã không có quá nhiều thời gian để xem xét những ngày cuối cùng này. Có lẽ ngày mai. Chỉ là một ý tưởng, vì tôi nhớ một chút lý do tại sao tôi nói không sử dụng addFilterToMap, là cách bạn sử dụng có thể không chính xác, các tham số bị sai hoặc không được sử dụng trong thời điểm tốt. Đó chỉ là ý tưởng từ những người nhớ.
Sylvain Rayé

2

Thay vì sử dụng tên cột tĩnh, bạn có thể sử dụng phương thức bên dưới cho tất cả các cột. Tôi có thể hiểu nếu sử dụng câu trả lời của mageUz sẽ hoạt động cho một cột và nếu bạn đi cho một cột khác thì bạn có thể gặp lỗi tương tự. Vì vậy, mã dưới đây cung cấp cho bạn giải pháp cho tất cả các cột đồng thời.

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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.