diff --git a/app/code/Magento/Sales/Model/Config/Backend/Grid/AsyncIndexing.php b/app/code/Magento/Sales/Model/Config/Backend/Grid/AsyncIndexing.php new file mode 100644 index 0000000000000000000000000000000000000000..b7eb6d8457f8188701f00cc5f9a717c3352fea15 --- /dev/null +++ b/app/code/Magento/Sales/Model/Config/Backend/Grid/AsyncIndexing.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Config\Backend\Grid; + +/** + * Backend model for global configuration value + * 'dev/grid/async_indexing'. + */ +class AsyncIndexing extends \Magento\Framework\App\Config\Value +{ + /** + * Dispatches corresponding event after saving of configuration + * value if it was changed. + * + * Dispatches next events: + * + * - config_data_dev_grid_async_indexing_enabled + * - config_data_dev_grid_async_indexing_disabled + * + * @return $this + */ + public function afterSave() + { + if ($this->isValueChanged()) { + $state = $this->getValue() ? 'enabled' : 'disabled'; + + $this->_eventManager->dispatch( + $this->_eventPrefix . '_dev_grid_async_indexing_' . $state, + $this->_getEventData() + ); + } + + return $this; + } +} diff --git a/app/code/Magento/Sales/Model/Observer/IndexGrid.php b/app/code/Magento/Sales/Model/Observer/IndexGrid.php new file mode 100644 index 0000000000000000000000000000000000000000..fdf54b0f8f48a0aeafe7a4b3ecf172be97b04996 --- /dev/null +++ b/app/code/Magento/Sales/Model/Observer/IndexGrid.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Observer; + +/** + * Sales entity grids indexing observer. + * + * Performs handling of events and cron jobs related to indexing + * of Order, Invoice, Shipment and Creditmemo grids. + */ +class IndexGrid +{ + /** + * Entity grid model. + * + * @var \Magento\Sales\Model\Resource\GridInterface + */ + protected $entityGrid; + + /** + * Global configuration storage. + * + * @var \Magento\Framework\App\Config\ScopeConfigInterface + */ + protected $globalConfig; + + /** + * @param \Magento\Sales\Model\Resource\GridInterface $entityGrid + * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig + */ + public function __construct( + \Magento\Sales\Model\Resource\GridInterface $entityGrid, + \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig + ) { + $this->entityGrid = $entityGrid; + $this->globalConfig = $globalConfig; + } + + /** + * Handles synchronous insertion of the new entity into + * corresponding grid on certain events. + * + * Used in the next events: + * + * - sales_order_save_after + * - sales_order_invoice_save_after + * - sales_order_shipment_save_after + * - sales_order_creditmemo_save_after + * + * Works only if asynchronous grid indexing is disabled + * in global settings. + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + */ + public function syncInsert(\Magento\Framework\Event\Observer $observer) + { + if (!$this->globalConfig->getValue('dev/grid/async_indexing')) { + $this->entityGrid->refresh($observer->getDataObject()->getId()); + } + } + + /** + * Handles synchronous removing of the entity from + * corresponding grid on certain events. + * + * Used in the next events: + * + * - sales_order_delete_after + * - sales_order_invoice_delete_after + * - sales_order_shipment_delete_after + * - sales_order_creditmemo_delete_after + * + * @param \Magento\Framework\Event\Observer $observer + * @return void + */ + public function syncRemove(\Magento\Framework\Event\Observer $observer) + { + $this->entityGrid->purge($observer->getDataObject()->getId()); + } + + /** + * Handles asynchronous insertion of the new entity into + * corresponding grid during cron job. + * + * Also method is used in the next events: + * + * - config_data_dev_grid_async_indexing_disabled + * + * Works only if asynchronous grid indexing is enabled + * in global settings. + * + * @return void + */ + public function asyncInsert() + { + if ($this->globalConfig->getValue('dev/grid/async_indexing')) { + $this->entityGrid->refreshBySchedule(); + } + } +} diff --git a/app/code/Magento/Sales/Model/Resource/AbstractGrid.php b/app/code/Magento/Sales/Model/Resource/AbstractGrid.php index ec8941c2ba11f91649a8abc9d9a6d243da9f552f..862b5079bad3c3a0db285fb9a7588c8493597d12 100644 --- a/app/code/Magento/Sales/Model/Resource/AbstractGrid.php +++ b/app/code/Magento/Sales/Model/Resource/AbstractGrid.php @@ -71,4 +71,24 @@ abstract class AbstractGrid extends AbstractDb implements GridInterface [($field ?: 'entity_id') . ' = ?' => $value] ); } + + /** + * Returns update time of the last row in the grid. + * + * If there are no rows in the grid, default value will be returned. + * + * @param string $default + * @return string + */ + protected function getLastUpdatedAtValue($default = '0000-00-00 00:00:00') + { + $select = $this->getConnection()->select() + ->from($this->getTable($this->gridTableName), ['updated_at']) + ->order('updated_at DESC') + ->limit(1); + + $row = $this->getConnection()->fetchRow($select); + + return isset($row['updated_at']) ? $row['updated_at'] : $default; + } } diff --git a/app/code/Magento/Sales/Model/Resource/Entity.php b/app/code/Magento/Sales/Model/Resource/Entity.php index ada1a586187ca71f5705579f6395d6048ac4a762..9c1f3f65522ad540885b495a9f130661d12181ee 100644 --- a/app/code/Magento/Sales/Model/Resource/Entity.php +++ b/app/code/Magento/Sales/Model/Resource/Entity.php @@ -50,28 +50,20 @@ abstract class Entity extends AbstractDb */ protected $salesIncrement; - /** - * @var \Magento\Sales\Model\Resource\GridInterface - */ - protected $gridAggregator; - /** * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute * @param \Magento\Sales\Model\Increment $salesIncrement * @param string|null $resourcePrefix - * @param GridInterface|null $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, \Magento\Sales\Model\Increment $salesIncrement, - $resourcePrefix = null, - \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null + $resourcePrefix = null ) { $this->attribute = $attribute; $this->salesIncrement = $salesIncrement; - $this->gridAggregator = $gridAggregator; parent::__construct($context, $resourcePrefix); } @@ -89,6 +81,24 @@ abstract class Entity extends AbstractDb return $this; } + /** + * Prepares data for saving and removes update time (if exists). + * This prevents saving same update time on each entity update. + * + * @param \Magento\Framework\Model\AbstractModel $object + * @return array + */ + protected function _prepareDataForSave(\Magento\Framework\Model\AbstractModel $object) + { + $data = parent::_prepareDataForTable($object, $this->getMainTable()); + + if (isset($data['updated_at'])) { + unset($data['updated_at']); + } + + return $data; + } + /** * Perform actions before object save * @@ -127,10 +137,6 @@ abstract class Entity extends AbstractDb */ protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) { - if ($this->gridAggregator) { - $this->gridAggregator->refresh($object->getId()); - } - $adapter = $this->_getReadAdapter(); $columns = $adapter->describeTable($this->getMainTable()); @@ -158,9 +164,6 @@ abstract class Entity extends AbstractDb */ protected function _afterDelete(\Magento\Framework\Model\AbstractModel $object) { - if ($this->gridAggregator) { - $this->gridAggregator->purge($object->getId()); - } parent::_afterDelete($object); return $this; } diff --git a/app/code/Magento/Sales/Model/Resource/GridInterface.php b/app/code/Magento/Sales/Model/Resource/GridInterface.php index b257a569cf0b5a5370e8d7683dfbfe22ee6ad175..138d7726f41a42313a40b40d8f78d64b25099fb4 100644 --- a/app/code/Magento/Sales/Model/Resource/GridInterface.php +++ b/app/code/Magento/Sales/Model/Resource/GridInterface.php @@ -12,12 +12,25 @@ namespace Magento\Sales\Model\Resource; interface GridInterface { /** + * Adds new rows to the grid. + * + * Only rows that correspond to $value and $field parameters should be added. + * * @param int|string $value * @param null|string $field * @return \Zend_Db_Statement_Interface */ public function refresh($value, $field = null); + /** + * Adds new rows to the grid. + * + * Only rows created/updated since the last method call should be added. + * + * @return \Zend_Db_Statement_Interface + */ + public function refreshBySchedule(); + /** * @param int|string $value * @param null|string $field diff --git a/app/code/Magento/Sales/Model/Resource/Order.php b/app/code/Magento/Sales/Model/Resource/Order.php index f25e34923c21c51bc297793e8133fbcc42925a1a..5a2cd7fedbdb9ba58feb7a9d830015b8e0182077 100644 --- a/app/code/Magento/Sales/Model/Resource/Order.php +++ b/app/code/Magento/Sales/Model/Resource/Order.php @@ -9,7 +9,6 @@ use Magento\Framework\App\Resource as AppResource; use Magento\Framework\Math\Random; use Magento\Sales\Model\Increment as SalesIncrement; use Magento\Sales\Model\Resource\Entity as SalesResource; -use Magento\Sales\Model\Resource\Order\Grid as OrderGrid; use Magento\Sales\Model\Resource\Order\Handler\Address as AddressHandler; use Magento\Sales\Model\Resource\Order\Handler\State as StateHandler; use Magento\Sales\Model\Spi\OrderResourceInterface; @@ -61,7 +60,6 @@ class Order extends SalesResource implements OrderResourceInterface * @param SalesIncrement $salesIncrement * @param AddressHandler $addressHandler * @param StateHandler $stateHandler - * @param OrderGrid $gridAggregator * @param string|null $resourcePrefix */ public function __construct( @@ -70,12 +68,11 @@ class Order extends SalesResource implements OrderResourceInterface SalesIncrement $salesIncrement, AddressHandler $addressHandler, StateHandler $stateHandler, - OrderGrid $gridAggregator, $resourcePrefix = null ) { $this->stateHandler = $stateHandler; $this->addressHandler = $addressHandler; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** @@ -199,6 +196,7 @@ class Order extends SalesResource implements OrderResourceInterface $relatedObject->save(); $relatedObject->setOrder($object); } + return parent::_afterSave($object); } } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Address.php b/app/code/Magento/Sales/Model/Resource/Order/Address.php index 0ae0007afce4c6df73de79ae9dfb3a79fd7bee57..bacacbbcd01e37894b0cbbe547f002d8db5d4545 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Address.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Address.php @@ -37,7 +37,6 @@ class Address extends SalesResource implements OrderAddressResourceInterface * @param \Magento\Sales\Model\Order\Address\Validator $validator * @param \Magento\Sales\Model\Resource\GridPool $gridPool * @param string|null $resourcePrefix - * @param \Magento\Sales\Model\Resource\GridInterface $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, @@ -45,12 +44,11 @@ class Address extends SalesResource implements OrderAddressResourceInterface \Magento\Sales\Model\Increment $salesIncrement, \Magento\Sales\Model\Order\Address\Validator $validator, \Magento\Sales\Model\Resource\GridPool $gridPool, - $resourcePrefix = null, - \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null + $resourcePrefix = null ) { $this->_validator = $validator; $this->gridPool = $gridPool; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php index 11123a7771cc03258f42cfb5318f72e6b08b0722..5f2797d8efcef0b57860d26d44f81219d405a679 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo.php @@ -9,7 +9,6 @@ use Magento\Framework\App\Resource as AppResource; use Magento\Sales\Model\Increment as SalesIncrement; use Magento\Sales\Model\Resource\Attribute; use Magento\Sales\Model\Resource\Entity as SalesResource; -use Magento\Sales\Model\Resource\Order\Creditmemo\Grid as CreditmemoGrid; use Magento\Sales\Model\Spi\CreditmemoResourceInterface; /** @@ -42,17 +41,15 @@ class Creditmemo extends SalesResource implements CreditmemoResourceInterface * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute * @param SalesIncrement $salesIncrement - * @param CreditmemoGrid $gridAggregator * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, Attribute $attribute, SalesIncrement $salesIncrement, - CreditmemoGrid $gridAggregator, $resourcePrefix = null ) { - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** @@ -93,6 +90,7 @@ class Creditmemo extends SalesResource implements CreditmemoResourceInterface $comment->save(); } } + return parent::_afterSave($object); } } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php index 4bd2bc8463cfeec1d5a6d18b75f2196f71ae6e31..dce44c4bb8673690183a8013b40a0b19405d1549 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Comment.php @@ -35,18 +35,16 @@ class Comment extends Entity implements CreditmemoCommentResourceInterface * @param \Magento\Sales\Model\Increment $salesIncrement * @param \Magento\Sales\Model\Order\Creditmemo\Comment\Validator $validator * @param string|null $resourcePrefix - * @param \Magento\Sales\Model\Resource\GridInterface $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, \Magento\Sales\Model\Increment $salesIncrement, \Magento\Sales\Model\Order\Creditmemo\Comment\Validator $validator, - $resourcePrefix = null, - \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null + $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Grid.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Grid.php index 512b2b6879ee9d26ef74b873b8d1ee3d5a0cc438..7d769253351d876da7f1ccba803da175bb195a10 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Grid.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Grid.php @@ -24,7 +24,10 @@ class Grid extends AbstractGrid protected $creditmemoTableName = 'sales_creditmemo'; /** - * Refresh grid row + * Adds new order creditmemos to the grid. + * + * Only order creditmemos that correspond to $value and $field + * parameters will be added. * * @param int|string $value * @param null|string $field @@ -34,6 +37,31 @@ class Grid extends AbstractGrid { $select = $this->getGridOriginSelect() ->where(($field ?: 'sfc.entity_id') . ' = ?', $value); + + return $this->getConnection()->query( + $this->getConnection() + ->insertFromSelect( + $select, + $this->getTable($this->gridTableName), + [], + AdapterInterface::INSERT_ON_DUPLICATE + ) + ); + } + + /** + * Adds new order creditmemos to the grid. + * + * Only order creditmemos created/updated since the last method call + * will be added. + * + * @return \Zend_Db_Statement_Interface + */ + public function refreshBySchedule() + { + $select = $this->getGridOriginSelect() + ->where('sfc.updated_at >= ?', $this->getLastUpdatedAtValue()); + return $this->getConnection()->query( $this->getConnection() ->insertFromSelect( @@ -81,6 +109,7 @@ class Grid extends AbstractGrid 'increment_id' => 'sfc.increment_id', 'order_increment_id' => 'sfo.increment_id', 'created_at' => 'sfc.created_at', + 'updated_at' => 'sfc.updated_at', 'order_created_at' => 'sfo.created_at', 'billing_name' => "trim(concat(ifnull(sba.firstname, ''), ' ', ifnull(sba.lastname, '')))", ] diff --git a/app/code/Magento/Sales/Model/Resource/Order/Grid.php b/app/code/Magento/Sales/Model/Resource/Order/Grid.php index 4dbd369c9989f512275335bc848e69628bf8b25c..92bccf926f30a0f069e4def9af00929ab7282975 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Grid.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Grid.php @@ -19,7 +19,9 @@ class Grid extends AbstractGrid protected $gridTableName = 'sales_order_grid'; /** - * Refresh grid row + * Adds new orders to the grid. + * + * Only orders that correspond to $value and $field parameters will be added. * * @param int|string $value * @param null|string $field @@ -29,6 +31,30 @@ class Grid extends AbstractGrid { $select = $this->getGridOriginSelect() ->where(($field ?: 'sfo.entity_id') . ' = ?', $value); + + return $this->getConnection()->query( + $this->getConnection() + ->insertFromSelect( + $select, + $this->getTable($this->gridTableName), + [], + AdapterInterface::INSERT_ON_DUPLICATE + ) + ); + } + + /** + * Adds new orders to the grid. + * + * Only orders created/updated since the last method call will be added. + * + * @return \Zend_Db_Statement_Interface + */ + public function refreshBySchedule() + { + $select = $this->getGridOriginSelect() + ->where('sfo.updated_at >= ?', $this->getLastUpdatedAtValue()); + return $this->getConnection()->query( $this->getConnection() ->insertFromSelect( diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice.php index 79317bda2843a1869942360867eb84c9fd28ad70..406589dafd152ccf2f0f602f01fe74bf38188955 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Invoice.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice.php @@ -9,7 +9,6 @@ use Magento\Framework\App\Resource; use Magento\Sales\Model\Increment as SalesIncrement; use Magento\Sales\Model\Resource\Attribute; use Magento\Sales\Model\Resource\Entity as SalesResource; -use Magento\Sales\Model\Resource\Order\Invoice\Grid as InvoiceGrid; use Magento\Sales\Model\Spi\InvoiceResourceInterface; /** @@ -38,17 +37,15 @@ class Invoice extends SalesResource implements InvoiceResourceInterface * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute * @param SalesIncrement $salesIncrement - * @param InvoiceGrid $gridAggregator * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, Attribute $attribute, SalesIncrement $salesIncrement, - InvoiceGrid $gridAggregator, $resourcePrefix = null ) { - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** @@ -93,6 +90,7 @@ class Invoice extends SalesResource implements InvoiceResourceInterface $comment->save(); } } + return parent::_afterSave($object); } } diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php index 32d95112c41bf7215db251323aa6d313f596b9d1..5d44bd40bd5c0d50c8632f7647c16a089e026a0e 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Comment.php @@ -34,7 +34,6 @@ class Comment extends Entity implements InvoiceCommentResourceInterface * @param \Magento\Sales\Model\Resource\Attribute $attribute * @param \Magento\Sales\Model\Increment $salesIncrement * @param \Magento\Sales\Model\Order\Invoice\Comment\Validator $validator - * @param \Magento\Sales\Model\Resource\GridInterface $gridAggregator * @param string|null $resourcePrefix */ public function __construct( @@ -42,11 +41,10 @@ class Comment extends Entity implements InvoiceCommentResourceInterface \Magento\Sales\Model\Resource\Attribute $attribute, \Magento\Sales\Model\Increment $salesIncrement, \Magento\Sales\Model\Order\Invoice\Comment\Validator $validator, - $resourcePrefix = null, - \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null + $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Grid.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Grid.php index 35bb45b0e153c03c5751ffe91746a91db9c455b0..e203becb74c7e47a3302e6c77bd2900840fb5029 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Grid.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Grid.php @@ -24,7 +24,10 @@ class Grid extends AbstractGrid protected $invoiceTableName = 'sales_invoice'; /** - * Refresh grid row + * Adds new order invoices to the grid. + * + * Only order invoices that correspond to $value and $field + * parameters will be added. * * @param int|string $value * @param null|string $field @@ -34,6 +37,31 @@ class Grid extends AbstractGrid { $select = $this->getGridOriginSelect() ->where(($field ?: 'sfi.entity_id') . ' = ?', $value); + + return $this->getConnection()->query( + $this->getConnection() + ->insertFromSelect( + $select, + $this->getTable($this->gridTableName), + [], + AdapterInterface::INSERT_ON_DUPLICATE + ) + ); + } + + /** + * Adds new order invoices to the grid. + * + * Only order invoices created/updated since the last method call + * will be added. + * + * @return \Zend_Db_Statement_Interface + */ + public function refreshBySchedule() + { + $select = $this->getGridOriginSelect() + ->where('sfi.updated_at >= ?', $this->getLastUpdatedAtValue()); + return $this->getConnection()->query( $this->getConnection() ->insertFromSelect( @@ -75,6 +103,7 @@ class Grid extends AbstractGrid 'increment_id' => 'sfi.increment_id', 'order_increment_id' => 'sfo.increment_id', 'created_at' => 'sfi.created_at', + 'updated_at' => 'sfi.updated_at', 'order_created_at' => 'sfo.created_at', 'billing_name' => "trim(concat(ifnull(sba.firstname, ''), ' ', ifnull(sba.lastname, '')))", ] diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment.php index 0d2ecdf5bfceddee81573e84392543634769ba1b..1d11adfed6748e73b3d0a02cb6faeedc23beaf47 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment.php @@ -9,7 +9,6 @@ use Magento\Framework\App\Resource as AppResource; use Magento\Sales\Model\Increment as SalesIncrement; use Magento\Sales\Model\Resource\Attribute; use Magento\Sales\Model\Resource\Entity as SalesResource; -use Magento\Sales\Model\Resource\Order\Shipment\Grid as ShipmentGrid; use Magento\Sales\Model\Spi\ShipmentResourceInterface; /** @@ -47,17 +46,15 @@ class Shipment extends SalesResource implements ShipmentResourceInterface * @param \Magento\Framework\Model\Resource\Db\Context $context * @param Attribute $attribute * @param SalesIncrement $salesIncrement - * @param ShipmentGrid $gridAggregator * @param string|null $resourcePrefix */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, Attribute $attribute, SalesIncrement $salesIncrement, - ShipmentGrid $gridAggregator, $resourcePrefix = null ) { - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php index e18d89970fb50860305407633261e6e2f5d29479..ab50e07d1afa570c0bada035ae60344a5b9fbbf3 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Comment.php @@ -35,18 +35,16 @@ class Comment extends Entity implements ShipmentCommentResourceInterface * @param \Magento\Sales\Model\Increment $salesIncrement * @param \Magento\Sales\Model\Order\Shipment\Comment\Validator $validator * @param string|null $resourcePrefix - * @param \Magento\Sales\Model\Resource\GridInterface $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, \Magento\Sales\Model\Increment $salesIncrement, \Magento\Sales\Model\Order\Shipment\Comment\Validator $validator, - $resourcePrefix = null, - \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null + $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Grid.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Grid.php index 9dd1c697d4a780cfb53901a0f57b79db0f181e7d..c8c84e615498d0621dcf68acc9fe1d08393e7da7 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Grid.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Grid.php @@ -24,7 +24,10 @@ class Grid extends AbstractGrid protected $shipmentTableName = 'sales_shipment'; /** - * Refresh grid row + * Adds new order shipments to the grid. + * + * Only order shipments that correspond to $value and $field + * parameters will be added. * * @param int|string $value * @param null|string $field @@ -34,6 +37,31 @@ class Grid extends AbstractGrid { $select = $this->getGridOriginSelect() ->where(($field ?: 'sfs.entity_id') . ' = ?', $value); + + return $this->getConnection()->query( + $this->getConnection() + ->insertFromSelect( + $select, + $this->getTable($this->gridTableName), + [], + AdapterInterface::INSERT_ON_DUPLICATE + ) + ); + } + + /** + * Adds new order shipments to the grid. + * + * Only order shipments created/updated since the last method call + * will be added. + * + * @return \Zend_Db_Statement_Interface + */ + public function refreshBySchedule() + { + $select = $this->getGridOriginSelect() + ->where('sfs.updated_at >= ?', $this->getLastUpdatedAtValue()); + return $this->getConnection()->query( $this->getConnection() ->insertFromSelect( @@ -70,6 +98,7 @@ class Grid extends AbstractGrid 'increment_id' => 'sfs.increment_id', 'order_increment_id' => 'sfo.increment_id', 'created_at' => 'sfs.created_at', + 'updated_at' => 'sfs.updated_at', 'order_created_at' => 'sfo.created_at', 'shipping_name' => "trim(concat(ifnull(ssa.firstname, ''), ' ' ,ifnull(ssa.lastname, '')))", ] diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php index 9ff1715b0dc714a8ce93d562ec99f770312541f3..86b27bc301c0e4084b8bcd9f718f4756f2f9b411 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Track.php @@ -35,18 +35,16 @@ class Track extends SalesResource implements ShipmentTrackResourceInterface * @param \Magento\Sales\Model\Increment $salesIncrement * @param \Magento\Sales\Model\Order\Shipment\Track\Validator $validator * @param string|null $resourcePrefix - * @param \Magento\Sales\Model\Resource\GridInterface $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, \Magento\Sales\Model\Increment $salesIncrement, \Magento\Sales\Model\Order\Shipment\Track\Validator $validator, - $resourcePrefix = null, - \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null + $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Model/Resource/Order/Status/History.php b/app/code/Magento/Sales/Model/Resource/Order/Status/History.php index ff92ebe32c2ebc63be6afd3d3cbeba8b8a7dba14..bf50f4b6b004e7f2beb4c2eaeb1838408ea5c343 100644 --- a/app/code/Magento/Sales/Model/Resource/Order/Status/History.php +++ b/app/code/Magento/Sales/Model/Resource/Order/Status/History.php @@ -27,18 +27,16 @@ class History extends Entity implements OrderStatusHistoryResourceInterface * @param \Magento\Sales\Model\Increment $salesIncrement * @param Validator $validator * @param string|null $resourcePrefix - * @param \Magento\Sales\Model\Resource\GridInterface $gridAggregator */ public function __construct( \Magento\Framework\Model\Resource\Db\Context $context, \Magento\Sales\Model\Resource\Attribute $attribute, \Magento\Sales\Model\Increment $salesIncrement, Validator $validator, - $resourcePrefix = null, - \Magento\Sales\Model\Resource\GridInterface $gridAggregator = null + $resourcePrefix = null ) { $this->validator = $validator; - parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix, $gridAggregator); + parent::__construct($context, $attribute, $salesIncrement, $resourcePrefix); } /** diff --git a/app/code/Magento/Sales/Setup/UpgradeSchema.php b/app/code/Magento/Sales/Setup/UpgradeSchema.php index 19c29e24be8cf388eb9dc3669afe5590e6cc87bf..6f3f45fa05e18b0595892a8f0c9201a711388652 100644 --- a/app/code/Magento/Sales/Setup/UpgradeSchema.php +++ b/app/code/Magento/Sales/Setup/UpgradeSchema.php @@ -60,5 +60,52 @@ class UpgradeSchema implements UpgradeSchemaInterface } } } + + if (version_compare($context->getVersion(), '2.0.2') < 0) { + + /** + * Adding 'updated_at' columns. + */ + + $tables = ['sales_shipment_grid', 'sales_invoice_grid', 'sales_creditmemo_grid']; + + foreach ($tables as $table) { + $table = $setup->getTable($table); + + $setup->getConnection() + ->addColumn( + $table, + 'updated_at', + [ + 'type' => Table::TYPE_TIMESTAMP, + 'after' => 'created_at', + 'comment' => 'Updated At' + ] + ); + + $setup->getConnection() + ->addIndex($table, $setup->getIdxName($table, ['updated_at']), 'updated_at'); + } + + /** + * Modifying default value of 'updated_at' columns. + */ + + $tables = ['sales_order', 'sales_shipment', 'sales_invoice', 'sales_creditmemo']; + + foreach ($tables as $table) { + $table = $setup->getTable($table); + + $setup->getConnection() + ->modifyColumn( + $table, + 'updated_at', + [ + 'type' => Table::TYPE_TIMESTAMP, + 'default' => Table::TIMESTAMP_INIT_UPDATE + ] + ); + } + } } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Grid/AsyncIndexingTest.php b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Grid/AsyncIndexingTest.php new file mode 100644 index 0000000000000000000000000000000000000000..972cfae38e2ae4273235a2c7a7d1ac260b4f45a3 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Config/Backend/Grid/AsyncIndexingTest.php @@ -0,0 +1,93 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\Config\Backend\Grid; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Unit test of backend model for global configuration value + * 'dev/grid/async_indexing'. + */ +class AsyncIndexingTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Model\Config\Backend\Grid\AsyncIndexing + */ + protected $object; + + /** + * @var \Magento\Framework\App\Config|\PHPUnit_Framework_MockObject_MockObject + */ + protected $config; + + /** + * @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject + */ + protected $context; + + /** + * @var \Magento\Framework\Event\Manager\Proxy|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eventManager; + + protected function setUp() + { + $objectManager = new ObjectManager($this); + + $this->config = $this->getMock('Magento\Framework\App\Config', [], [], '', false); + + $this->eventManager = $this->getMock('Magento\Framework\Event\Manager\Proxy', [], [], '', false); + + $this->context = $this->getMock('Magento\Framework\Model\Context', ['getEventDispatcher'], [], '', false); + $this->context->expects($this->any())->method('getEventDispatcher')->willReturn($this->eventManager); + + $this->object = $objectManager->getObject( + '\Magento\Sales\Model\Config\Backend\Grid\AsyncIndexing', + [ + 'config' => $this->config, + 'context' => $this->context + ] + ); + } + + /** + * @param int $value + * @param int $oldValue + * @param string $eventName + * @dataProvider testAfterSaveDataProvider + * @return void + */ + public function testAfterSave($value, $oldValue, $eventName) + { + $path = 'dev/grid/async_indexing'; + $scope = \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT; + + $this->object->setData(['value' => $value, 'path' => $path, 'scope' => $scope]); + + $this->config->expects($this->once())->method('getValue')->with($path, $scope)->willReturn($oldValue); + + if ($value == $oldValue) { + $this->eventManager->expects($this->never())->method('dispatch'); + } else { + $this->eventManager->expects($this->once())->method('dispatch')->with($eventName); + } + + $this->object->afterSave(); + } + + /** + * @return array + */ + public function testAfterSaveDataProvider() + { + return [ + [0, 0, null], + [1, 1, null], + [0, 1, 'config_data_dev_grid_async_indexing_disabled'], + [1, 0, 'config_data_dev_grid_async_indexing_enabled'] + ]; + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php index 58b073f18f682315c63f326e7e8b467a6bcb5b8b..6819c63725246e283b3ed876a3695d00384e45d2 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Resource/OrderTest.php @@ -39,10 +39,6 @@ class OrderTest extends \PHPUnit_Framework_TestCase * @var \Magento\Sales\Model\Increment|\PHPUnit_Framework_MockObject_MockObject */ protected $salesIncrementMock; - /** - * @var \Magento\Sales\Model\Resource\Order\Grid|\PHPUnit_Framework_MockObject_MockObject - */ - protected $gridAggregatorMock; /** * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject */ @@ -96,7 +92,6 @@ class OrderTest extends \PHPUnit_Framework_TestCase ); $this->stateHandlerMock = $this->getMock('Magento\Sales\Model\Resource\Order\Handler\State', [], [], '', false); $this->salesIncrementMock = $this->getMock('Magento\Sales\Model\Increment', [], [], '', false); - $this->gridAggregatorMock = $this->getMock('Magento\Sales\Model\Resource\Order\Grid', [], [], '', false); $this->orderMock = $this->getMock( 'Magento\Sales\Model\Order', [], @@ -154,8 +149,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase $this->attributeMock, $this->salesIncrementMock, $this->addressHandlerMock, - $this->stateHandlerMock, - $this->gridAggregatorMock + $this->stateHandlerMock ); } diff --git a/app/code/Magento/Sales/etc/adminhtml/system.xml b/app/code/Magento/Sales/etc/adminhtml/system.xml index d15118237917ade6b7c382a043f2f9941bb02af3..e7482704e39adc243e781283034f20f391152eb0 100644 --- a/app/code/Magento/Sales/etc/adminhtml/system.xml +++ b/app/code/Magento/Sales/etc/adminhtml/system.xml @@ -371,5 +371,15 @@ </field> </group> </section> + <section id="dev"> + <group id="grid" type="text" sortOrder="131" showInDefault="1" showInWebsite="0" showInStore="0"> + <label>Grid Settings</label> + <field id="async_indexing" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0"> + <label>Asynchronous indexing</label> + <source_model>Magento\Config\Model\Config\Source\Enabledisable</source_model> + <backend_model>Magento\Sales\Model\Config\Backend\Grid\AsyncIndexing</backend_model> + </field> + </group> + </section> </system> </config> diff --git a/app/code/Magento/Sales/etc/config.xml b/app/code/Magento/Sales/etc/config.xml index 2d42f963e6965decc5159ed82becc3fec22d25d2..f88cf2955f60ed8f3db411ad7f4f49b37b87dc51 100644 --- a/app/code/Magento/Sales/etc/config.xml +++ b/app/code/Magento/Sales/etc/config.xml @@ -94,5 +94,10 @@ <dashboard> <use_aggregated_data>0</use_aggregated_data> </dashboard> + <dev> + <grid> + <async_indexing>0</async_indexing> + </grid> + </dev> </default> </config> diff --git a/app/code/Magento/Sales/etc/crontab.xml b/app/code/Magento/Sales/etc/crontab.xml index 10e96dec3ab06c5877e9f44c14ed63ee0f17c9ca..1bd5b3e3e2478754784856b302a17ec3c2162470 100644 --- a/app/code/Magento/Sales/etc/crontab.xml +++ b/app/code/Magento/Sales/etc/crontab.xml @@ -25,5 +25,17 @@ <job name="aggregate_sales_report_bestsellers_data" instance="Magento\Sales\Model\Observer\AggregateSalesReportBestsellersData" method="execute"> <schedule>0 0 * * *</schedule> </job> + <job name="sales_grid_order_async_insert" instance="Magento\Sales\Model\Observer\Order\IndexGrid" method="asyncInsert"> + <schedule>*/1 * * * *</schedule> + </job> + <job name="sales_grid_order_invoice_async_insert" instance="Magento\Sales\Model\Observer\Order\Invoice\IndexGrid" method="asyncInsert"> + <schedule>*/1 * * * *</schedule> + </job> + <job name="sales_grid_order_shipment_async_insert" instance="Magento\Sales\Model\Observer\Order\Shipment\IndexGrid" method="asyncInsert"> + <schedule>*/1 * * * *</schedule> + </job> + <job name="sales_grid_order_creditmemo_async_insert" instance="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" method="asyncInsert"> + <schedule>*/1 * * * *</schedule> + </job> </group> </config> diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index ce41a5bd24663c3567f11a32c61f29db2425bfd9..b30edfeb3afc1280ce7cc77f844c982b51110c10 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -137,4 +137,24 @@ </argument> </arguments> </type> + <virtualType name="Magento\Sales\Model\Observer\Order\IndexGrid" type="Magento\Sales\Model\Observer\IndexGrid"> + <arguments> + <argument name="entityGrid" xsi:type="object">Magento\Sales\Model\Resource\Order\Grid</argument> + </arguments> + </virtualType> + <virtualType name="Magento\Sales\Model\Observer\Order\Invoice\IndexGrid" type="Magento\Sales\Model\Observer\IndexGrid"> + <arguments> + <argument name="entityGrid" xsi:type="object">Magento\Sales\Model\Resource\Order\Invoice\Grid</argument> + </arguments> + </virtualType> + <virtualType name="Magento\Sales\Model\Observer\Order\Shipment\IndexGrid" type="Magento\Sales\Model\Observer\IndexGrid"> + <arguments> + <argument name="entityGrid" xsi:type="object">Magento\Sales\Model\Resource\Order\Shipment\Grid</argument> + </arguments> + </virtualType> + <virtualType name="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" type="Magento\Sales\Model\Observer\IndexGrid"> + <arguments> + <argument name="entityGrid" xsi:type="object">Magento\Sales\Model\Resource\Order\Creditmemo\Grid</argument> + </arguments> + </virtualType> </config> diff --git a/app/code/Magento/Sales/etc/events.xml b/app/code/Magento/Sales/etc/events.xml index a4105518a48dedf01bcee2e42ee0be3d54dc7e49..7829d98ef926c6c14de526616d7ca5213d61827a 100644 --- a/app/code/Magento/Sales/etc/events.xml +++ b/app/code/Magento/Sales/etc/events.xml @@ -9,4 +9,34 @@ <event name="sales_order_place_after"> <observer name="sales_vat_request_params_order_comment" instance="Magento\Sales\Model\Observer\Frontend\Quote\AddVatRequestParamsOrderComment" method="execute" /> </event> + <event name="sales_order_save_after"> + <observer name="sales_grid_order_sync_insert" instance="Magento\Sales\Model\Observer\Order\IndexGrid" method="syncInsert" /> + </event> + <event name="sales_order_invoice_save_after"> + <observer name="sales_grid_order_invoice_sync_insert" instance="Magento\Sales\Model\Observer\Order\Invoice\IndexGrid" method="syncInsert" /> + </event> + <event name="sales_order_shipment_save_after"> + <observer name="sales_grid_order_shipment_sync_insert" instance="Magento\Sales\Model\Observer\Order\Shipment\IndexGrid" method="syncInsert" /> + </event> + <event name="sales_order_creditmemo_save_after"> + <observer name="sales_grid_order_creditmemo_sync_insert" instance="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" method="syncInsert" /> + </event> + <event name="sales_order_delete_after"> + <observer name="sales_grid_order_sync_remove" instance="Magento\Sales\Model\Observer\Order\IndexGrid" method="syncRemove" /> + </event> + <event name="sales_order_invoice_delete_after"> + <observer name="sales_grid_order_invoice_sync_remove" instance="Magento\Sales\Model\Observer\Order\Invoice\IndexGrid" method="syncRemove" /> + </event> + <event name="sales_order_shipment_delete_after"> + <observer name="sales_grid_order_shipment_sync_remove" instance="Magento\Sales\Model\Observer\Order\Shipment\IndexGrid" method="syncRemove" /> + </event> + <event name="sales_order_creditmemo_delete_after"> + <observer name="sales_grid_order_creditmemo_sync_remove" instance="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" method="syncRemove" /> + </event> + <event name="config_data_dev_grid_async_indexing_disabled"> + <observer name="sales_grid_order_async_insert" instance="Magento\Sales\Model\Observer\Order\IndexGrid" method="asyncInsert" /> + <observer name="sales_grid_order_invoice_async_insert" instance="Magento\Sales\Model\Observer\Order\Invoice\IndexGrid" method="asyncInsert" /> + <observer name="sales_grid_order_shipment_async_insert" instance="Magento\Sales\Model\Observer\Order\Shipment\IndexGrid" method="asyncInsert" /> + <observer name="sales_grid_order_creditmemo_async_insert" instance="Magento\Sales\Model\Observer\Order\Creditmemo\IndexGrid" method="asyncInsert" /> + </event> </config> diff --git a/app/code/Magento/Sales/etc/module.xml b/app/code/Magento/Sales/etc/module.xml index 54f554e7e038cdd9b8d28c791b8273376e1bbf48..90aa0777f18f1719f61c05970857a20669d7163b 100644 --- a/app/code/Magento/Sales/etc/module.xml +++ b/app/code/Magento/Sales/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> - <module name="Magento_Sales" setup_version="2.0.1"> + <module name="Magento_Sales" setup_version="2.0.2"> <sequence> <module name="Magento_Rule"/> <module name="Magento_Catalog"/>