Search code examples
magento-1.5magento

Magento observer (sales_order_grid_collection_load_before), filter collection by a product attribute


So I'm working with sales_order_grid_collection_load_before observer event at the moment, where I can get the collection being used through $collection = $observer->getEvent()->getOrderGridCollection();, I'm just wondering, if it is possible to filter this collection by a product from the order attribute. What I mean with that is the order grid collection has sub products related to that order, I need to only show orders if at least one of the products match a specific criteria (in my case, I've given the products an admin_id attribute, which is set to the administrator who added the product).

Thanks!


Solution

  • I've done a very similar thing by doing the following:

    1. Override the sales order grid block. To do this you will need to set up your own extension (it looks like you might already be doing this, but just in case, there is some handy doco in the Magento wiki)

      <config>
          <modules>
              <Company_Module>
                  <version>0.1.0</version>
              </Company_Module>
          </modules>
          <global>
              <blocks>
                  <company_module>
                      <class>Company_Module_Block</class>
                  </company_module>
                  <adminhtml>
                      <rewrite>
                          <sales_order_grid>Company_Module_Block_Sales_Order_Grid</sales_order_grid>
                      </rewrite>
                  </adminhtml>
              </blocks>
          </global>
      </config>
      
    2. I then copied the /app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php into my extensions folder at /app/code/local/Company/Module/Block/Sales/Order

    3. In the copied file I changed the class name to class Company_Module_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid

    4. I then changed the _prepareCollection function. In this case I was interested in grabbing the customer_group_id and customer_email from the sales_flat_order table

      protected function _prepareCollection() {
          $collection = Mage::getResourceModel($this->_getCollectionClass());
          // left join onto the sales_flat_order table, retrieving the customer_group_id and customer_email columns -< this can be expanded
          $collection->getSelect()->join('sales_flat_order', 'main_table.entity_id=sales_flat_order.entity_id', array('customer_group_id'=>'customer_group_id', 'customer_email'=>'customer_email'), null, 'left');
      
          // grab the current user and get their associated customer groups (additional coding required to associate the customer groups to an admin user
          $user = Mage::getSingleton('admin/session')->getUser();
          $roleId = implode('', $user->getRoles());
          $customerGroupIds = Mage::getModel('admin/roles')->load($roleId)->getCustomerGroupIds();
          $orders = Mage::getResourceModel('sales/order_collection');
      
          // if the admin user has associated customer group ids then find the orders associated with those
          // this would be where you would do your filtering of the products
          if (count($customerGroupIds)) {
              $orders->addAttributeToFilter('customer_group_id', array('in' => $customerGroupIds));
          }
          $orderIds = $orders->getAllIds();
          $collection->addAttributeToFilter('entity_id', array('in' => $orderIds));
      
          $this->setCollection($collection);
      
          return parent::_prepareCollection();
      }
      

    You may not need the join to the sales_flat_order table...you might be able to do it just by doing the filtering in the second part of the _prepareCollection function shown above. In my case, I was displaying the customer_group_id and the customer_email in the grid so that the user could manually filter, if required.