Skip to content

Commit

Permalink
PES-410: slow order grid fix (#47)
Browse files Browse the repository at this point in the history
* v2.2.1 init

* PES-429: order grid update (#44)

* PES-429: order grid update

* PES-429: order grid update - CR

* PES-410: slow order grid fix

* PES-410: slow order grid fix - hybrid carrier caching

* PES-410: slow order grid fix - change log update

Co-authored-by: packeta <[email protected]>
  • Loading branch information
IlIIlIlIl1 and packeta-user authored Dec 7, 2021
1 parent ee52f27 commit 639a2e3
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 42 deletions.
3 changes: 2 additions & 1 deletion CHANGE_LOG.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
2.2.1 - Fixed: order grid did not display paging controls on top of the grid and did not display row count
2.2.1 - Fixed: slow order grid loading
- Fixed: order grid did not display paging controls on top of the grid and did not display row count
- Fixed: order grid export did not set flags correctly

2.2.0 - Added: inline order grid editation
Expand Down
66 changes: 59 additions & 7 deletions Packetery/Checkout/Model/Carrier/Facade.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,32 @@ public function updateCarrierName(string $carrierName, string $carrierCode, ?int
* @return \Packetery\Checkout\Model\HybridCarrier
*/
public function createHybridCarrier(string $carrierCode, ?int $carrierId, string $method, string $country): HybridCarrier {
$carrier = $this->getMagentoCarrier($carrierCode);
$dynamicCarrier = $this->getDynamicCarrier($carrier, $carrierId);
$cache = [];
return $this->createHybridCarrierCached($cache, $carrierCode, $carrierId, $method, $country);
}

/**
* @param array $cache
* @param string $carrierCode
* @param int|null $carrierId
* @param string $method
* @param string $country
* @return \Packetery\Checkout\Model\HybridCarrier
*/
public function createHybridCarrierCached(array &$cache, string $carrierCode, ?int $carrierId, string $method, string $country): HybridCarrier {
$cache['carriers'] = $cache['carriers'] ?? [];
$cache['dynamicCarriers'] = $cache['dynamicCarriers'] ?? [];

if (!array_key_exists($carrierCode, $cache['carriers'])) {
$cache['carriers'][$carrierCode] = $this->getMagentoCarrier($carrierCode);
}
$carrier = $cache['carriers'][$carrierCode];

$dynamicCarrierCode = $carrierCode . '_' . ( $carrierId ?? '' );
if (!array_key_exists($dynamicCarrierCode, $cache['dynamicCarriers'])) {
$cache['dynamicCarriers'][$dynamicCarrierCode] = $this->getDynamicCarrier($carrier, $carrierId);
}
$dynamicCarrier = $cache['dynamicCarriers'][$dynamicCarrierCode];

if ($dynamicCarrier !== null) {
return HybridCarrier::fromAbstractDynamic($carrier, $dynamicCarrier, $method, $country);
Expand Down Expand Up @@ -128,19 +152,47 @@ private function getMagentoCarrier(string $carrierCode): AbstractCarrier {
*/
public static function getAllImplementedBranchIds(): array {
$branchIds = [];
$dirs = glob(__DIR__ . '/Imp/*', GLOB_ONLYDIR);
$classNames = self::getAllBrainClasses();

foreach ($classNames as $className) {
$branchIds[] = $className::getImplementedBranchIds();
}

return array_merge([], ...$branchIds);
}

/**
* @return array<class-string<\Packetery\Checkout\Model\Carrier\AbstractBrain>>
*/
public static function getAllBrainClasses(): array {
$classNames = [];
$dirs = glob(__DIR__ . '/Imp/*', GLOB_ONLYDIR|GLOB_NOSORT);

foreach ($dirs as $dir) {
if ($dir === '.' || $dir === '..') {
continue;
}

$name = basename($dir);
/** @var \Packetery\Checkout\Model\Carrier\AbstractBrain $className */
$className = '\\Packetery\\Checkout\\Model\\Carrier\\Imp\\' . $name . '\\Brain';
$branchIds = array_merge($branchIds, $className::getImplementedBranchIds());
$classNames[] = '\\Packetery\\Checkout\\Model\\Carrier\\Imp\\' . $name . '\\Brain';
}

return $classNames;
}

/**
* @return string[]
*/
public static function getAllCarrierCodes(): array {
$carrierCodes = [];
/** @var \Packetery\Checkout\Model\Carrier\AbstractBrain[] $classNames */
$classNames = self::getAllBrainClasses();

foreach ($classNames as $className) {
$carrierCodes[] = $className::getCarrierCodeStatic();
}

return $branchIds;
return $carrierCodes;
}

/**
Expand Down
26 changes: 26 additions & 0 deletions Packetery/Checkout/Model/ResourceModel/Order/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,30 @@ protected function _construct()
{
$this->_init('Packetery\Checkout\Model\Order', 'Packetery\Checkout\Model\ResourceModel\Order');
}

/**
* @return string
*/
private function createSalesOrderCarrierCodeCondition(): string {
$carrierCodes = \Packetery\Checkout\Model\Carrier\Facade::getAllCarrierCodes();

$carrierCodesConditions = [];
foreach ($carrierCodes as $carrierCode) {
$carrierCodesConditions[] = "`sales_order`.`shipping_method` LIKE " . $this->getConnection()->quote($carrierCode . '\_%', 'STRING');
}
$carrierCodesImploded = implode(' OR ', $carrierCodesConditions);
if (empty($carrierCodesImploded)) {
$carrierCodesImploded = '1';
}

return $carrierCodesImploded;
}

/**
* Joins Magento sale orders in a way that omits redirected orders from Packeta to foreign carrier.
*/
public function joinSalesOrder(): void {
$carrierCodesImploded = $this->createSalesOrderCarrierCodeCondition();
$this->join(['sales_order' => 'sales_order'], "`main_table`.`order_number` = `sales_order`.`increment_id` AND ($carrierCodesImploded)", '');
}
}
48 changes: 48 additions & 0 deletions Packetery/Checkout/Model/ResourceModel/Order/CollectionFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Packetery\Checkout\Model\ResourceModel\Order;

class CollectionFactory
{
/**
* Object Manager instance
*
* @var \Magento\Framework\ObjectManagerInterface
*/
protected $objectManager;

/**
* Instance name to create
*
* @var string
*/
protected $instanceName;

/**
* Factory constructor
*
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param string $instanceName
*/
public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = Collection::class)
{
$this->objectManager = $objectManager;
$this->instanceName = $instanceName;
}

/**
* Create class instance with specified parameters
*
* @param array $data Class constructor arguments to override auto-wiring or specify non-service arguments.
* @return \Packetery\Checkout\Model\ResourceModel\Order\Collection
*/
public function create(array $data = [])
{
/** @var \Packetery\Checkout\Model\ResourceModel\Order\Collection $collection */
$collection = $this->objectManager->create($this->instanceName, $data);
$collection->joinSalesOrder();
return $collection;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,29 @@ class DeliveryDestination extends Column
/** @var \Packetery\Checkout\Model\Config\Source\MethodSelect */
private $methodSelect;

/** @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory */
private $orderCollectionFactory;

/** @var \Packetery\Checkout\Model\Carrier\Facade */
private $carrierFacade;

/**
* Country constructor.
* DeliveryDestination constructor.
*
* @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
* @param \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory
* @param \Packetery\Checkout\Model\Config\Source\MethodSelect $methodSelect
* @param \Packetery\Checkout\Model\Carrier\Facade $carrierFacade
* @param array $components
* @param array $data
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
\Packetery\Checkout\Model\Config\Source\MethodSelect $methodSelect,
\Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
\Packetery\Checkout\Model\Carrier\Facade $carrierFacade,
array $components = [],
array $data = []
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->methodSelect = $methodSelect;
$this->orderCollectionFactory = $orderCollectionFactory;
$this->carrierFacade = $carrierFacade;
}

Expand All @@ -50,17 +47,15 @@ public function __construct(
* @return array
*/
public function prepareDataSource(array $dataSource): array {
$cache = [];

if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as &$item) {
$orderNumber = $item['order_number'];
$collection = $this->orderCollectionFactory->create();
/** @var \Magento\Sales\Model\Order $item */
$order = $collection->getItemByColumnValue('increment_id', $orderNumber);
$shippingMethod = $order->getShippingMethod(true);
$shippingAddress = $order->getShippingAddress();
$carrierCode = $shippingMethod->getData('carrier_code');
$methodCode = MethodCode::fromString($shippingMethod->getData('method'));
$carrier = $this->carrierFacade->createHybridCarrier($carrierCode, $methodCode->getDynamicCarrierId(), $methodCode->getMethod(), $shippingAddress->getCountryId());
$shippingRateCode = $item['shipping_rate_code'];
[$carrierCode, $methodCodeString] = explode('_', $shippingRateCode, 2);
$methodCode = MethodCode::fromString($methodCodeString);
// make sure you do not use any method requiring country
$carrier = $this->carrierFacade->createHybridCarrierCached($cache, $carrierCode, $methodCode->getDynamicCarrierId(), $methodCode->getMethod(), '');

$branchName = (string)$item['point_name'];
$branchId = $item['point_id'];
Expand Down
83 changes: 64 additions & 19 deletions Packetery/Checkout/Ui/Component/Order/Listing/SearchResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,79 @@

namespace Packetery\Checkout\Ui\Component\Order\Listing;

use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
use Magento\Framework\DB\Sql\Expression;
use Magento\Framework\Event\ManagerInterface as EventManager;
use Psr\Log\LoggerInterface as Logger;

class SearchResult extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
{
/**
* @var \Packetery\Checkout\Model\ResourceModel\Order\CollectionFactory
*/
private $orderCollectionFactory;

/**
* SearchResult constructor.
* @param EntityFactory $entityFactory
* @param Logger $logger
* @param FetchStrategy $fetchStrategy
* @param EventManager $eventManager
* @param \Packetery\Checkout\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory
* @param string $mainTable
* @param null|string $resourceModel
* @param null|string $identifierName
* @param null|string $connectionName
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function __construct(
EntityFactory $entityFactory,
Logger $logger,
FetchStrategy $fetchStrategy,
EventManager $eventManager,
\Packetery\Checkout\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
$mainTable,
$resourceModel = null,
$identifierName = null,
$connectionName = null
) {
$this->orderCollectionFactory = $orderCollectionFactory;
parent::__construct(
$entityFactory,
$logger,
$fetchStrategy,
$eventManager,
$mainTable,
$resourceModel,
$identifierName,
$connectionName
);
}

protected function _initSelect() {
$packeteryOrderTable = $this->getTable('packetery_order');
$orderTable = $this->getTable('sales_order');
$subQuery = $this->orderCollectionFactory->create()->getSelect();
$subQuery->reset('columns');
$subQuery->columns(
[
'order_number_reference' => 'main_table.order_number',
'recipient_fullname' => "CONCAT_WS('', main_table.recipient_firstname, ' ',main_table.recipient_lastname)",
'recipient_address' => "CONCAT_WS('', main_table.recipient_street, ' ', main_table.recipient_house_number, ' ', main_table.recipient_city, ' ', main_table.recipient_zip)",
'delivery_destination' => "CONCAT_WS('', main_table.point_name, ' ', main_table.point_id)",
'value_transformed' => "main_table.value",
'cod_transformed' => "IF(main_table.cod > 0, 1, 0)",
'exported_transformed' => "main_table.exported",
'exported_at_transformed' => "main_table.exported_at",
'order_status' => "sales_order.status",
'shipping_rate_code' => "sales_order.shipping_method",
'main_table.*'
]
);

$this->getSelect()
->from(
[
'main_table' => new Expression(
"(
SELECT
main_table.order_number AS order_number_reference,
CONCAT_WS('', main_table.recipient_firstname, ' ',main_table.recipient_lastname) AS recipient_fullname,
CONCAT_WS('', main_table.recipient_street, ' ', main_table.recipient_house_number, ' ', main_table.recipient_city, ' ', main_table.recipient_zip) AS recipient_address,
CONCAT_WS('', main_table.point_name, ' ', main_table.point_id) AS delivery_destination,
main_table.value AS value_transformed,
IF(main_table.cod > 0, 1, 0) AS cod_transformed,
main_table.exported AS exported_transformed,
main_table.exported_at AS exported_at_transformed,
sales_order.status AS order_status,
main_table.*
FROM {$packeteryOrderTable} AS main_table
LEFT JOIN {$orderTable} AS sales_order ON sales_order.increment_id = main_table.order_number
)"
),
'main_table' => new Expression('(' . $subQuery->assemble() . ')'),
]
);

Expand Down

0 comments on commit 639a2e3

Please sign in to comment.