Skip to content

Commit

Permalink
Merge pull request #7781 from magento-l3/PR_22_JUL_2022_odubovyk
Browse files Browse the repository at this point in the history
L3 Bugfix Delivery
  • Loading branch information
vzabaznov authored Aug 4, 2022
2 parents 2e45de7 + 98068a6 commit 8427030
Show file tree
Hide file tree
Showing 43 changed files with 1,504 additions and 413 deletions.
102 changes: 102 additions & 0 deletions app/code/Magento/Bundle/Test/Fixture/AddProductToCart.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Bundle\Test\Fixture;

use Magento\Bundle\Model\Product\Type;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;
use Magento\Quote\Api\CartRepositoryInterface;

class AddProductToCart extends \Magento\Quote\Test\Fixture\AddProductToCart
{
/**
* @var ProductRepositoryInterface
*/
private ProductRepositoryInterface $productRepository;

/**
* @var Type
*/
private Type $productType;

/**
* @param CartRepositoryInterface $cartRepository
* @param ProductRepositoryInterface $productRepository
* @param DataObjectFactory $dataObjectFactory
* @param Type $productType
*/
public function __construct(
CartRepositoryInterface $cartRepository,
ProductRepositoryInterface $productRepository,
DataObjectFactory $dataObjectFactory,
Type $productType
) {
parent::__construct($cartRepository, $productRepository, $dataObjectFactory);
$this->productRepository = $productRepository;
$this->productType = $productType;
}

/**
* {@inheritdoc}
* @param array $data Parameters
* $data['selections'] can be supplied in following formats:
* - [["$product1.id$"], ["$product2.id$"]]
* - [[{"product_id":"$product1.id$","qty":1}], [{"product_id":"$product2.id$","qty":1}]]
* - To skip an option, pass empty array [["$product1.id$"], [], ["$product2.id$"]]
* <pre>
* $data = [
* 'cart_id' => (int) Cart ID. Required.
* 'product_id' => (int) Product ID. Required.
* 'selections' => (array) array of options selections. Required.
* 'qty' => (int) Quantity. Optional. Default: 1.
* ]
* </pre>
*/
public function apply(array $data = []): ?DataObject
{
$bundleProduct = $this->productRepository->getById($data['product_id']);
$buyRequest = [
'bundle_option' => [],
'bundle_option_qty' => [],
'qty' => $data['qty'] ?? 1,
];
$options = $this->productType->getOptionsCollection($bundleProduct);
$selections = $this->productType->getSelectionsCollection([], $bundleProduct);
$options->appendSelections($selections, true);
$optionsList = array_values($options->getItems());
foreach ($data['selections'] as $index => $selections) {
if (!empty($selections)) {
$option = $optionsList[$index];
foreach ($selections as $item) {
if (is_array($item)) {
$productId = (int)$item['product_id'];
$qty = $item['qty'] ?? 1;
} else {
$productId = (int)$item;
$qty = 1;
}
foreach ($option->getSelections() as $selection) {
if (((int)$selection->getProductId()) === $productId) {
$buyRequest['bundle_option'][$option->getId()][] = $selection->getSelectionId();
$buyRequest['bundle_option_qty'][$option->getId()][$selection->getSelectionId()] = $qty;
break;
}
}
}
}
}
return parent::apply(
[
'cart_id' => $data['cart_id'],
'product_id' => $data['product_id'],
'buy_request' => $buyRequest
]
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ abstract public function execute($ids);
* @param array $processIds
* @return AbstractAction
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
* @deprecated 102.0.6 Used only for backward compatibility for indexer, which not support indexation by dimensions
* @deprecated 102.0.6
* @see Used only for backward compatibility for indexer, which not support indexation by dimensions
*/
protected function _syncData(array $processIds = [])
{
Expand Down Expand Up @@ -386,31 +387,33 @@ protected function _reindexRows($changedIds = [])
$changedIds = array_unique(array_merge($changedIds, ...array_values($parentProductsTypes)));
$productsTypes = array_merge_recursive($productsTypes, $parentProductsTypes);

if ($changedIds) {
$typeIndexers = array_filter(
$this->getTypeIndexers(),
function ($type) use ($productsTypes) {
return isset($productsTypes[$type]) && !empty($productsTypes[$type]);
},
ARRAY_FILTER_USE_KEY
);
if (empty($typeIndexers)) {
$this->deleteIndexData($changedIds);
return $changedIds;
}

$typeIndexers = $this->getTypeIndexers();
foreach ($typeIndexers as $productType => $indexer) {
$entityIds = $productsTypes[$productType] ?? [];
if (empty($entityIds)) {
continue;
}

$entityIds = $productsTypes[$productType];
if ($indexer instanceof DimensionalIndexerInterface) {
foreach ($this->dimensionCollectionFactory->create() as $dimensions) {
$this->tableMaintainer->createMainTmpTable($dimensions);
$temporaryTable = $this->tableMaintainer->getMainTmpTable($dimensions);
$this->_emptyTable($temporaryTable);
$indexer->executeByDimensions($dimensions, \SplFixedArray::fromArray($entityIds, false));
// copy to index
$this->_insertFromTable(
$temporaryTable,
$this->tableMaintainer->getMainTableByDimensions($dimensions)
);
$mainTable = $this->tableMaintainer->getMainTableByDimensions($dimensions);
$this->_insertFromTable($temporaryTable, $mainTable);
$this->deleteOutdatedData($entityIds, $temporaryTable, $mainTable);
}
} else {
// handle 3d-party indexers for backward compatibility
$this->deleteIndexData($changedIds);
$this->_emptyTable($this->_defaultIndexerResource->getIdxTable());
$this->_copyRelationIndexData($entityIds);
$indexer->reindexEntity($entityIds);
Expand All @@ -421,6 +424,30 @@ protected function _reindexRows($changedIds = [])
return $changedIds;
}

/**
* Delete records that do not exist anymore
*
* @param array $entityIds
* @param string $temporaryTable
* @param string $mainTable
* @return void
*/
private function deleteOutdatedData(array $entityIds, string $temporaryTable, string $mainTable): void
{
$joinCondition = [
'tmp_table.entity_id = main_table.entity_id',
'tmp_table.customer_group_id = main_table.customer_group_id',
'tmp_table.website_id = main_table.website_id',
];
$select = $this->getConnection()->select()
->from(['main_table' => $mainTable], null)
->joinLeft(['tmp_table' => $temporaryTable], implode(' AND ', $joinCondition), null)
->where('tmp_table.entity_id IS NULL')
->where('main_table.entity_id IN (?)', $entityIds, \Zend_Db::INT_TYPE);
$query = $select->deleteFromSelect('main_table');
$this->getConnection()->query($query);
}

/**
* Delete Index data index for list of entities
*
Expand All @@ -445,7 +472,8 @@ private function deleteIndexData(array $entityIds)
* @param null|array $parentIds
* @param array $excludeIds
* @return \Magento\Catalog\Model\Indexer\Product\Price\AbstractAction
* @deprecated 102.0.6 Used only for backward compatibility for do not broke custom indexer implementation
* @deprecated 102.0.6
* @see Used only for backward compatibility for do not broke custom indexer implementation
* which do not work by dimensions.
* For indexers, which support dimensions all composite products read data directly from main price indexer table
* or replica table for partial or full reindex correspondingly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ public function create(array $rawPrice, $sku)
$price->setCustomerGroup(
$rawPrice['all_groups'] == $this->allGroupsId
? $this->allGroupsValue
: $this->customerGroupRepository->getById($rawPrice['customer_group_id'])->getCode()
: ($rawPrice['customer_group_code']
?? $this->customerGroupRepository->getById($rawPrice['customer_group_id'])->getCode())
);
$price->setQuantity($rawPrice['qty']);

Expand Down
31 changes: 24 additions & 7 deletions app/code/Magento/Catalog/Model/Product/Price/TierPriceStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Magento\Catalog\Model\Indexer\Product\Price\Processor as PriceIndexerProcessor;
use Magento\Catalog\Model\Product\Price\Validation\TierPriceValidator;
use Magento\Catalog\Model\ProductIdLocatorInterface;
use Magento\Customer\Model\ResourceModel\Group\GetCustomerGroupCodesByIds;

class TierPriceStorage implements TierPriceStorageInterface
{
Expand All @@ -22,8 +23,6 @@ class TierPriceStorage implements TierPriceStorageInterface
private $tierPricePersistence;

/**
* Tier price validator.
*
* @var TierPriceValidator
*/
private $tierPriceValidator;
Expand All @@ -36,38 +35,42 @@ class TierPriceStorage implements TierPriceStorageInterface
private $tierPriceFactory;

/**
* Price index processor.
*
* @var PriceIndexerProcessor
*/
private $priceIndexProcessor;

/**
* Product ID locator.
*
* @var ProductIdLocatorInterface
*/
private $productIdLocator;

/**
* @var GetCustomerGroupCodesByIds
*/
private $getCustomerGroupCodesByIds;

/**
* @param TierPricePersistence $tierPricePersistence
* @param TierPriceValidator $tierPriceValidator
* @param TierPriceFactory $tierPriceFactory
* @param PriceIndexerProcessor $priceIndexProcessor
* @param ProductIdLocatorInterface $productIdLocator
* @param GetCustomerGroupCodesByIds $getCustomerGroupCodesByIds
*/
public function __construct(
TierPricePersistence $tierPricePersistence,
TierPriceValidator $tierPriceValidator,
TierPriceFactory $tierPriceFactory,
PriceIndexerProcessor $priceIndexProcessor,
ProductIdLocatorInterface $productIdLocator
ProductIdLocatorInterface $productIdLocator,
GetCustomerGroupCodesByIds $getCustomerGroupCodesByIds
) {
$this->tierPricePersistence = $tierPricePersistence;
$this->tierPriceValidator = $tierPriceValidator;
$this->tierPriceFactory = $tierPriceFactory;
$this->priceIndexProcessor = $priceIndexProcessor;
$this->productIdLocator = $productIdLocator;
$this->getCustomerGroupCodesByIds = $getCustomerGroupCodesByIds;
}

/**
Expand Down Expand Up @@ -148,8 +151,22 @@ private function getExistingPrices(array $skus, bool $groupBySku = false): array
if ($rawPrices) {
$linkField = $this->tierPricePersistence->getEntityLinkField();
$skuByIdLookup = $this->buildSkuByIdLookup($skus);
$customerGroupCodesByIds = $this->getCustomerGroupCodesByIds->execute(
array_column(
array_filter(
$rawPrices,
static function (array $row) {
return (int) $row['all_groups'] !== 1;
}
),
'customer_group_id'
),
);
foreach ($rawPrices as $rawPrice) {
$sku = $skuByIdLookup[$rawPrice[$linkField]];
if (isset($customerGroupCodesByIds[$rawPrice['customer_group_id']])) {
$rawPrice['customer_group_code'] = $customerGroupCodesByIds[$rawPrice['customer_group_id']];
}
$price = $this->tierPriceFactory->create($rawPrice, $sku);
if ($groupBySku) {
$prices[$sku][] = $price;
Expand Down
Loading

0 comments on commit 8427030

Please sign in to comment.