├── .gitattributes ├── .github └── FUNDING.yml ├── CHANGELOG.md ├── LICENSE.md ├── Model └── ResourceModel │ └── Order │ └── Grid │ └── Collection.php ├── Plugin └── FormatOrderItemsExport.php ├── README.md ├── composer.json ├── etc ├── adminhtml │ └── di.xml ├── di.xml └── module.xml ├── registration.php └── view └── adminhtml └── ui_component └── sales_order_grid.xml /.gitattributes: -------------------------------------------------------------------------------- 1 | /docs export-ignore 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: markshust 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 6 | 7 | ## [2.0.0] - 2025-05-13 8 | 9 | ### Fixed 10 | - Order grid page errors when pipe symbol (and possibly other special characters) appear in SKU [#15](https://github.com/markshust/magento2-module-ordergrid/issues/15) 11 | 12 | ## [1.1.1] - 2022-02-10 13 | 14 | ### Fixed 15 | - Bug when filtering by order date [#13](https://github.com/markshust/magento2-module-ordergrid/issues/13) 16 | 17 | ## [1.1.0] - 2022-08-01 18 | 19 | ### Updated 20 | - Update order_items field into export-friendly format. [#12](https://github.com/markshust/magento2-module-ordergrid/issues/12) 21 | 22 | ## [1.0.9] - 2021-11-02 23 | 24 | ### Fixed 25 | - Order grid filter does not work anymore. [#8](https://github.com/markshust/magento2-module-ordergrid/issues/8) 26 | 27 | ## [1.0.8] - 2021-04-16 28 | 29 | ### Fixed 30 | - Added strict types and few other minor updates to pass static analysis checks. [ecd1da99](https://github.com/markshust/magento2-module-ordergrid/commit/ecd1da99c9019c95f957166fb312368497271b9a) 31 | 32 | ## [1.0.7] - 2021-02-26 33 | 34 | ### Fixed 35 | - Count always displays “”1 records found”. [#5](https://github.com/markshust/magento2-module-ordergrid/pull/5) 36 | - Cannot select all items. [#5](https://github.com/markshust/magento2-module-ordergrid/pull/5) 37 | 38 | ## [1.0.6] - 2021-02-04 39 | 40 | ### Fixed 41 | - Version bump for Composer package resolution. 42 | 43 | ## [1.0.5] - 2021-02-04 44 | 45 | ### Fixed 46 | - Fixed filters and order grid styles [#4](https://github.com/markshust/magento2-module-ordergrid/pull/4). 47 | 48 | ## [1.0.4] - 2020-04-22 49 | 50 | ### Fixed 51 | - Updated php and magento framework version constraints to >=7.1 and >=101 respectively, for more seamless compatibility with new Magento releases. 52 | 53 | ## [1.0.3] - 2020-04-22 54 | 55 | ### Fixed 56 | - Updated php version constraint to ~7.1 (any version 7.1 or higher). 57 | 58 | ## [1.0.2] - 2019-10-18 59 | 60 | ### Fixed 61 | - Updated composer version constraints to support newer versions of Magento. 62 | 63 | ## [1.0.1] - 2019-05-10 64 | 65 | ### Fixed 66 | - Fixes suggested by Magento Coding Standard. 67 | 68 | ## [1.0.0] - 2019-01-11 69 | 70 | ### Added 71 | - Initial release. 72 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Model/ResourceModel/Order/Grid/Collection.php: -------------------------------------------------------------------------------- 1 | getFlag(self::PRODUCT_FILTER_FLAG)) { 27 | return $this->addProductFilter($condition); 28 | } 29 | 30 | return parent::addFieldToFilter($field, $condition); 31 | } 32 | 33 | /** 34 | * Add product-specific filtering to collection. 35 | * 36 | * @param array|int|string|null $condition 37 | * @return Collection 38 | */ 39 | private function addProductFilter( 40 | array|int|string|null $condition 41 | ): Collection { 42 | $orderItemTable = $this->getTable(self::SALES_ORDER_ITEM_TABLE); 43 | $orderItemAlias = 'soi'; 44 | 45 | // Join the order item table 46 | $this->getSelect()->join( 47 | [$orderItemAlias => $orderItemTable], 48 | "main_table.entity_id = {$orderItemAlias}.order_id", 49 | [] 50 | ); 51 | 52 | // Group by order ID to avoid duplicates 53 | $this->getSelect()->group('main_table.entity_id'); 54 | 55 | // Filter by product SKU and name 56 | $this->addFieldToFilter( 57 | [ 58 | "{$orderItemAlias}.sku", 59 | "{$orderItemAlias}.name", 60 | ], 61 | [ 62 | $condition, 63 | $condition, 64 | ] 65 | ); 66 | 67 | $this->setFlag(self::PRODUCT_FILTER_FLAG, 1); 68 | 69 | return $this; 70 | } 71 | 72 | /** 73 | * Add order items data to collection after load. 74 | * 75 | * @return SearchResult 76 | */ 77 | protected function _afterLoad(): SearchResult 78 | { 79 | $orderIds = $this->getColumnValues('entity_id'); 80 | 81 | if (!empty($orderIds)) { 82 | $this->addOrderItemsToCollection($orderIds); 83 | } 84 | 85 | return parent::_afterLoad(); 86 | } 87 | 88 | /** 89 | * Add order items HTML to each order in the collection. 90 | * 91 | * @param array $orderIds 92 | * @return void 93 | */ 94 | private function addOrderItemsToCollection( 95 | array $orderIds 96 | ): void { 97 | // Get all relevant order items 98 | $orderItems = $this->getOrderItems($orderIds); 99 | 100 | // Group order items by order ID for efficient lookup 101 | $productsByOrderId = $this->groupOrderItemsByOrderId($orderItems); 102 | 103 | // Add HTML representation to each order 104 | foreach ($orderIds as $orderId) { 105 | if (!isset($productsByOrderId[$orderId])) { 106 | continue; 107 | } 108 | 109 | $order = $this->getItemById($orderId); 110 | if (!$order) { 111 | continue; 112 | } 113 | 114 | $order->setData(self::ORDER_ITEMS_FIELD, $this->formatOrderItemsHtml($productsByOrderId[$orderId])); 115 | } 116 | } 117 | 118 | /** 119 | * Group order items by their parent order ID. 120 | * 121 | * @param array $orderItems 122 | * @return array 123 | */ 124 | private function groupOrderItemsByOrderId( 125 | array $orderItems 126 | ): array { 127 | $result = []; 128 | 129 | foreach ($orderItems as $item) { 130 | $result[$item['order_id']][] = $item; 131 | } 132 | 133 | return $result; 134 | } 135 | 136 | /** 137 | * Format order items as HTML. 138 | * 139 | * @param array $orderItems 140 | * @return string 141 | */ 142 | private function formatOrderItemsHtml( 143 | array $orderItems 144 | ): string { 145 | $html = ''; 146 | 147 | foreach ($orderItems as $item) { 148 | $html .= sprintf( 149 | '
%d x [%s] %s
', 150 | (int)$item['qty_ordered'], 151 | $item['sku'], 152 | $item['name'] 153 | ); 154 | } 155 | 156 | return $html; 157 | } 158 | 159 | /** 160 | * Get order items for the specified order IDs. 161 | * 162 | * @param array $orderIds 163 | * @return array 164 | */ 165 | private function getOrderItems( 166 | array $orderIds 167 | ): array { 168 | $connection = $this->getConnection(); 169 | 170 | $select = $connection->select() 171 | ->from( 172 | $this->getTable(self::SALES_ORDER_ITEM_TABLE), 173 | [ 174 | 'order_id', 175 | 'sku', 176 | 'name', 177 | 'qty_ordered', 178 | ] 179 | ) 180 | ->where('order_id IN (?)', $orderIds) 181 | ->where('parent_item_id IS NULL'); // Exclude child products (e.g., in configurable products) 182 | 183 | return $connection->fetchAll($select); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Plugin/FormatOrderItemsExport.php: -------------------------------------------------------------------------------- 1 | getData('order_items')) { 26 | $decodedItems = html_entity_decode($orderItems); 27 | $explodedItems = explode('
', $decodedItems); 28 | 29 | foreach ($explodedItems as $itemId => $explodedItem) { 30 | $explodedItems[$itemId] = trim(strip_tags($explodedItem)); 31 | } 32 | 33 | $implodedItems = implode(';', $explodedItems); 34 | $document->setData('order_items', $implodedItems); 35 | } 36 | 37 | return [ 38 | $document, 39 | $fields, 40 | $options, 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

MarkShust_OrderGrid

2 | 3 |
4 |

Adds more details to the order grid in the admin.

5 | Supported Magento Versions 6 | Latest Stable Version 7 | Composer Downloads 8 | Maintained - Yes 9 | 10 |
11 | 12 | ## Table of contents 13 | 14 | - [Summary](#summary) 15 | - [Installation](#installation) 16 | - [Usage](#usage) 17 | - [License](#license) 18 | 19 | ## Summary 20 | 21 | Out of the box, the Magento admin displays high-level information within the sales order grid. It does not provide more detailed information would could be useful to specific businesses. 22 | 23 | This module adds more detailed information to the admin order grid. Initially, a new column is added to the order grid which contains order line items, which includes specific quantity and product names of items ordered. 24 | 25 | ## Installation 26 | 27 | ``` 28 | composer require markshust/magento2-module-ordergrid 29 | bin/magento module:enable MarkShust_OrderGrid 30 | bin/magento setup:upgrade 31 | ``` 32 | 33 | ## Usage 34 | 35 | This module has no configuration. Just install, and you'll see a new column in the order grid called Order Items. 36 | 37 | ![Screenshot](https://raw.githubusercontent.com/markshust/magento2-module-ordergrid/master/docs/demo.png) 38 | 39 | ## License 40 | 41 | [MIT](https://opensource.org/licenses/MIT) 42 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "markshust/magento2-module-ordergrid", 3 | "description": "The Order Grid module adds more details to the order grid in the admin.", 4 | "require": { 5 | "php": "^7|^8", 6 | "magento/framework": "^101|^102|^103" 7 | }, 8 | "type": "magento2-module", 9 | "version": "2.0.0", 10 | "license": [ 11 | "MIT" 12 | ], 13 | "autoload": { 14 | "files": [ 15 | "registration.php" 16 | ], 17 | "psr-4": { 18 | "MarkShust\\OrderGrid\\": "" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /etc/adminhtml/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | MarkShust\OrderGrid\Model\ResourceModel\Order\Grid\Collection 7 | 8 | 9 | 10 | 11 | 12 | sales_order_grid 13 | Magento\Sales\Model\ResourceModel\Order 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Magento_Ui/js/grid/columns/column 8 | 9 | 10 | ui/grid/cells/html 11 | text 12 | left 13 | false 14 | Order Items 15 | text 16 | 17 | 18 | 19 | 20 | 21 | --------------------------------------------------------------------------------