เพิ่มคอลัมน์ในกริด (ผู้สังเกตการณ์) - คอลัมน์ 'store_id' ในกรณีที่คำสั่งย่อยเป็นปัญหาที่ไม่ชัดเจน


16

ฉันกำลังเพิ่มคอลัมน์ในตารางคำสั่งซื้อโดยใช้วิธีผู้สังเกตการณ์:

  1. ในกิจกรรม -> sales_order_grid_collection_load_beforeฉันกำลังเพิ่มการเข้าร่วมในคอลเล็กชัน
  2. ในกิจกรรม -> core_block_abstract_prepare_layout_beforeฉันกำลังเพิ่มคอลัมน์ลงในตาราง

แก้ไขข้อมูลเพิ่มเติม:

ในกิจกรรม (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'));

}

ในเหตุการณ์ (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');
}

ทุกอย่างทำงานได้ดีจนกระทั่งฉันกรองกริดด้วยตัวกรองมุมมองสโตร์: คอลัมน์ 'store_id' ในกรณีที่ส่วนคำสั่งเป็นปัญหาที่ไม่ชัดเจน

ฉันพิมพ์แบบสอบถาม:

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

ในกรณีที่คุณเห็นนามแฝงstore_idพลาดmain_table

เพื่อให้บรรลุสิ่งนี้ฉันต้องตั้งค่าfilter_indexคอลัมน์ for store แต่ผ่านผู้สังเกตการณ์ ดังนั้นคำถามคือฉันจะทำมันได้อย่างไร?
โดยไม่ต้องเอาชนะคลาสบล็อก ? (ไม่เช่นนั้นผู้สังเกตการณ์ก็ไม่มีประโยชน์อะไร)

คำตอบ:


32

ลองอีกครั้งด้วยวิธีแก้ปัญหาอื่น ๆ ที่ฉันพูดถึงคุณก่อน :-) ฉันได้สร้างส่วนขยายที่สมบูรณ์เพื่อแสดงวิธีเพิ่มเขตข้อมูลลงในตารางกริด หลังจากนั้นคุณต้องใช้ไฟล์การอัพเดตเลย์เอาต์เพื่อเพิ่มคอลัมน์ลงในหน้าสั่งซื้อกริดเท่านั้น

ฉันเรียกว่าส่วนขยาย Example_SalesGrid แต่คุณสามารถเปลี่ยนได้ตามความต้องการของคุณ

เริ่มต้นด้วยการสร้างโมดูล init xml ใน/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>

ต่อไปเราจะสร้างมอดูล config xml ของเรา /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>

ตอนนี้เราสร้างสคริปต์อัพเกรด sql ค่ะ /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();

ต่อไปเราจะสร้างไฟล์อัพเดตเลย์เอาต์ /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>

ตอนนี้เราต้องการไฟล์บล็อกสองไฟล์หนึ่งไฟล์เพื่อสร้างตัวเลือกตัวกรอง /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;
    }
}

และวินาทีที่จะแปลค่าแถวเป็นข้อความที่ถูกต้องที่จะแสดง /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;
    }
}

ไฟล์สุดท้ายที่จำเป็นต้องใช้ก็ต่อเมื่อคุณสร้างคอลัมน์เพิ่มเติมจากตารางอื่นนอกเหนือจากการขาย / การสั่งซื้อ (sales_flat_order) ฟิลด์ทั้งหมดใน sales / order_grid ที่ตรงกับชื่อคอลัมน์จาก sales / order จะได้รับการอัปเดตโดยอัตโนมัติในตาราง sales / order_grid หากคุณต้องการเพิ่มตัวเลือกการชำระเงินตัวอย่างเช่นคุณจะต้องใช้ผู้สังเกตการณ์นี้เพื่อเพิ่มเขตข้อมูลลงในแบบสอบถามเพื่อให้สามารถคัดลอกข้อมูลไปยังตารางที่ถูกต้องได้ ผู้สังเกตการณ์ที่ใช้สำหรับสิ่งนี้อยู่ใน/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'
        //);
    }
}

รหัสนี้เป็นไปตามตัวอย่างจาก http://www.ecomdev.org/2010/07/27/adding-order-attribute-to-orders-grid-in-magento-1-4-1.html

หวังว่าตัวอย่างข้างต้นจะช่วยแก้ปัญหาของคุณ


ขออภัยผมไม่สามารถที่จะทดสอบขณะที่ผมกำลังเดินทาง ... เสียงมันซับซ้อนมากขึ้นอีกนิดว่าวิธีการของฉัน (มันทำงานยังสำหรับคำสั่งซื้อใหม่?)
รา

ผู้สังเกตการณ์กริดจะจัดการกับการเปลี่ยนแปลงข้อมูลทุกครั้งที่มีการเปลี่ยนแปลงเนื่องจากนี่เป็นการใช้ Magento แบบดั้งเดิมคุณไม่จำเป็นต้องสร้างการรวมใด ๆ กับตารางอื่น ๆ ซึ่งจะเป็นการเพิ่มความเร็วในการสืบค้นสำหรับคำสั่งซื้อจำนวนมาก (ข้อมูลทั้งหมดจะถูกเก็บไว้ใน
Vladimir Kerkhoff

เมื่อฉันลองและใช้สิ่งนี้ฉันได้รับข้อผิดพลาดคำเตือน: ไม่มีอาร์กิวเมนต์ที่ 2 สำหรับ Varien_Db_Adapter_Pdo_Mysql :: quoteInto ()
Vaishal Patel

4

ลองใช้สิ่งเหล่านี้:

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
สิ่งนี้ควรได้รับการยอมรับว่าเป็นคำตอบสำหรับวิธีการสังเกตการณ์ของ OP
musicliftsme

2

คุณต้องการsalesOrderGridCollectionLoadBeforeรหัสต่อไปนี้ในวิธีการของคุณ$collection->addFilterToMap('store_id', 'main_table.store_id');หรือไม่ หากไม่ลบออกและลองทำตามขั้นตอนต่อไปนี้:

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

แล้วลองทั้ง :( Column('store_id');ไม่สามารถใช้ได้ในcore_block_abstract_prepare_layout_before (_prepareColumn () จะเรียกว่าหลังจากดังนั้นคอลัมน์ไม่ได้อยู่ในเวลานั้น) addFilterToMapไม่ได้ทำคืองาน
Fra

ความคิดใด ๆ ที่ว่า addFilterToMap ไม่ทำงาน?
Fra

Soory ฉันไม่มีเวลามากเกินไปที่จะดูวันสุดท้ายนี้ อาจจะเป็นพรุ่งนี้. แค่ความคิดเพราะฉันจำได้เล็กน้อยว่าทำไมฉันบอกว่าไม่ใช้ addFilterToMap เป็นวิธีที่คุณใช้อาจไม่ถูกต้องพารามิเตอร์ผิดหรือไม่ได้ใช้ในช่วงเวลาที่ดี เป็นเพียงแนวคิดจากผู้ที่จดจำ
Sylvain Rayé

2

แทนที่จะใช้ชื่อคอลัมน์แบบคงที่คุณสามารถใช้วิธีการด้านล่างสำหรับคอลัมน์ทั้งหมด ฉันสามารถเข้าใจได้ถ้าใช้คำตอบของ mageUz ที่ใช้ได้กับหนึ่งคอลัมน์และถ้าคุณไปหาคอลัมน์อื่นคุณอาจได้รับข้อผิดพลาดเดียวกัน ดังนั้นโค้ดด้านล่างจะให้คำตอบสำหรับคอลัมน์ทั้งหมดพร้อมกัน

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);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.