Skip to content

Commit 6391fc1

Browse files
authored
Merge branch '2.4-develop' into purchase-order-graphql
2 parents a3489b7 + 72a4d4a commit 6391fc1

File tree

21 files changed

+654
-170
lines changed

21 files changed

+654
-170
lines changed

app/code/Magento/BundleGraphQl/Model/Resolver/Links/Collection.php

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use Magento\Framework\Exception\RuntimeException;
1616
use Magento\Framework\GraphQl\Query\EnumLookup;
1717
use Magento\Framework\GraphQl\Query\Uid;
18-
use Magento\Catalog\Api\ProductRepositoryInterface;
1918
use Zend_Db_Select_Exception;
2019

2120
/**
@@ -51,29 +50,20 @@ class Collection
5150
/** @var Uid */
5251
private $uidEncoder;
5352

54-
/**
55-
* @var ProductRepositoryInterface
56-
*/
57-
private $productRepository;
58-
5953
/**
6054
* @param CollectionFactory $linkCollectionFactory
6155
* @param EnumLookup $enumLookup
6256
* @param Uid|null $uidEncoder
63-
* @param ProductRepositoryInterface|null $productRepository
6457
*/
6558
public function __construct(
6659
CollectionFactory $linkCollectionFactory,
6760
EnumLookup $enumLookup,
68-
Uid $uidEncoder = null,
69-
?ProductRepositoryInterface $productRepository = null
61+
Uid $uidEncoder = null
7062
) {
7163
$this->linkCollectionFactory = $linkCollectionFactory;
7264
$this->enumLookup = $enumLookup;
7365
$this->uidEncoder = $uidEncoder ?: ObjectManager::getInstance()
7466
->get(Uid::class);
75-
$this->productRepository = $productRepository ?: ObjectManager::getInstance()
76-
->get(ProductRepositoryInterface::class);
7767
}
7868

7969
/**
@@ -117,7 +107,6 @@ public function getLinksForOptionId(int $optionId) : array
117107
* Fetch link data and return in array format. Keys for links will be their option Ids.
118108
*
119109
* @return array
120-
* @throws NoSuchEntityException
121110
* @throws RuntimeException
122111
* @throws Zend_Db_Select_Exception
123112
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
@@ -143,33 +132,26 @@ private function fetch() : array
143132

144133
/** @var Selection $link */
145134
foreach ($linkCollection as $link) {
146-
$productDetails = [];
147135
$data = $link->getData();
148-
if (isset($data['product_id'])) {
149-
$productDetails = $this->productRepository->getById($data['product_id']);
150-
}
151-
152-
if ($productDetails && $productDetails->getIsSalable()) {
153-
$formattedLink = [
154-
'price' => $link->getSelectionPriceValue(),
155-
'position' => $link->getPosition(),
156-
'id' => $link->getSelectionId(),
157-
'uid' => $this->uidEncoder->encode((string)$link->getSelectionId()),
158-
'qty' => (float)$link->getSelectionQty(),
159-
'quantity' => (float)$link->getSelectionQty(),
160-
'is_default' => (bool)$link->getIsDefault(),
161-
'price_type' => $this->enumLookup->getEnumValueFromField(
162-
'PriceTypeEnum',
163-
(string)$link->getSelectionPriceType()
164-
) ?: 'DYNAMIC',
165-
'can_change_quantity' => $link->getSelectionCanChangeQty(),
166-
];
167-
$data = array_replace($data, $formattedLink);
168-
if (!isset($this->links[$link->getOptionId()])) {
169-
$this->links[$link->getOptionId()] = [];
170-
}
171-
$this->links[$link->getOptionId()][] = $data;
136+
$formattedLink = [
137+
'price' => $link->getSelectionPriceValue(),
138+
'position' => $link->getPosition(),
139+
'id' => $link->getSelectionId(),
140+
'uid' => $this->uidEncoder->encode((string)$link->getSelectionId()),
141+
'qty' => (float)$link->getSelectionQty(),
142+
'quantity' => (float)$link->getSelectionQty(),
143+
'is_default' => (bool)$link->getIsDefault(),
144+
'price_type' => $this->enumLookup->getEnumValueFromField(
145+
'PriceTypeEnum',
146+
(string)$link->getSelectionPriceType()
147+
) ?: 'DYNAMIC',
148+
'can_change_quantity' => $link->getSelectionCanChangeQty(),
149+
];
150+
$data = array_replace($data, $formattedLink);
151+
if (!isset($this->links[$link->getOptionId()])) {
152+
$this->links[$link->getOptionId()] = [];
172153
}
154+
$this->links[$link->getOptionId()][] = $data;
173155
}
174156

175157
return $this->links;

app/code/Magento/Catalog/Model/Indexer/Product/Price/AbstractAction.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ protected function _syncData(array $processIds = [])
179179
// for backward compatibility split data from old idx table on dimension tables
180180
foreach ($this->dimensionCollectionFactory->create() as $dimensions) {
181181
$insertSelect = $this->getConnection()->select()->from(
182-
['ip_tmp' => $this->_defaultIndexerResource->getIdxTable()]
182+
['ip_tmp' => $this->_defaultIndexerResource->getIdxTable()],
183+
array_keys($this->getConnection()->describeTable($this->tableMaintainer->getMainTableByDimensions($dimensions)))
183184
);
184185

185186
foreach ($dimensions as $dimension) {

app/code/Magento/Catalog/Setup/Patch/Data/UpdateMultiselectAttributesBackendTypes.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,18 @@ public function apply()
8181
->select()
8282
->from($varcharTable)
8383
->where('attribute_id in (?)', $attributesToMigrate);
84-
$dataToMigrate = array_map(static function ($row) {
85-
$row['value_id'] = null;
86-
return $row;
87-
}, $connection->fetchAll($varcharTableDataSql));
88-
89-
foreach (array_chunk($dataToMigrate, 2000) as $dataChunk) {
90-
$connection->insertMultiple($textTable, $dataChunk);
91-
}
9284

85+
$columns = $connection->describeTable($varcharTable);
86+
unset($columns['value_id']);
87+
$connection->query(
88+
$connection->insertFromSelect(
89+
$connection->select()
90+
->from($varcharTable, array_keys($columns))
91+
->where('attribute_id in (?)', $attributesToMigrate),
92+
$textTable,
93+
array_keys($columns)
94+
)
95+
);
9396
$connection->query($connection->deleteFromSelect($varcharTableDataSql, $varcharTable));
9497

9598
foreach ($attributesToMigrate as $attributeId) {
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Catalog\Test\Unit\Model\Indexer\Product\Price\Action;
9+
10+
use Magento\Framework\Exception\InputException;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Framework\Search\Request\Dimension;
13+
use Magento\Store\Model\StoreManagerInterface;
14+
use Magento\Directory\Model\CurrencyFactory;
15+
use Magento\Catalog\Model\Product\Type;
16+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\Factory;
17+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice;
18+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\TierPrice;
19+
use Magento\Catalog\Model\Indexer\Product\Price\DimensionCollectionFactory;
20+
use Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer;
21+
use Magento\Catalog\Model\Indexer\Product\Price\Action\Row;
22+
use Magento\Framework\App\Config\ScopeConfigInterface;
23+
use Magento\Framework\Stdlib\DateTime;
24+
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
25+
use Magento\Framework\DB\Adapter\AdapterInterface;
26+
use Magento\Framework\DB\Select;
27+
use Magento\Framework\Indexer\MultiDimensionProvider;
28+
use PHPUnit\Framework\TestCase;
29+
use PHPUnit\Framework\MockObject\MockObject;
30+
31+
/**
32+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
33+
*/
34+
class RowDefaultPriceIndexerTest extends TestCase
35+
{
36+
/**
37+
* @var Row
38+
*/
39+
private $actionRow;
40+
41+
/**
42+
* @var ScopeConfigInterface|MockObject
43+
*/
44+
private $config;
45+
46+
/**
47+
* @var StoreManagerInterface|MockObject
48+
*/
49+
private $storeManager;
50+
51+
/**
52+
* @var CurrencyFactory|MockObject
53+
*/
54+
private $currencyFactory;
55+
56+
/**
57+
* @var TimezoneInterface|MockObject
58+
*/
59+
private $localeDate;
60+
61+
/**
62+
* @var DateTime|MockObject
63+
*/
64+
private $dateTime;
65+
66+
/**
67+
* @var Type|MockObject
68+
*/
69+
private $catalogProductType;
70+
71+
/**
72+
* @var Factory|MockObject
73+
*/
74+
private $indexerPriceFactory;
75+
76+
/**
77+
* @var DefaultPrice|MockObject
78+
*/
79+
private $defaultIndexerResource;
80+
81+
/**
82+
* @var TierPrice|MockObject
83+
*/
84+
private $tierPriceIndexResource;
85+
86+
/**
87+
* @var DimensionCollectionFactory|MockObject
88+
*/
89+
private $dimensionCollectionFactory;
90+
91+
/**
92+
* @var TableMaintainer|MockObject
93+
*/
94+
private $tableMaintainer;
95+
96+
protected function setUp(): void
97+
{
98+
$this->config = $this->createMock(ScopeConfigInterface::class);
99+
$this->storeManager = $this->createMock(StoreManagerInterface::class);
100+
$this->currencyFactory = $this->createMock(CurrencyFactory::class);
101+
$this->localeDate = $this->createMock(TimezoneInterface::class);
102+
$this->dateTime = $this->createMock(DateTime::class);
103+
$this->catalogProductType = $this->createMock(Type::class);
104+
$this->indexerPriceFactory = $this->createMock(Factory::class);
105+
$this->defaultIndexerResource = $this->createMock(DefaultPrice::class);
106+
$this->tierPriceIndexResource = $this->createMock(TierPrice::class);
107+
$this->dimensionCollectionFactory = $this->createMock(DimensionCollectionFactory::class);
108+
$this->tableMaintainer = $this->createMock(TableMaintainer::class);
109+
110+
$this->actionRow = new Row(
111+
$this->config,
112+
$this->storeManager,
113+
$this->currencyFactory,
114+
$this->localeDate,
115+
$this->dateTime,
116+
$this->catalogProductType,
117+
$this->indexerPriceFactory,
118+
$this->defaultIndexerResource,
119+
$this->tierPriceIndexResource,
120+
$this->dimensionCollectionFactory,
121+
$this->tableMaintainer
122+
);
123+
}
124+
125+
/**
126+
* Test that the price indexer will be able to perform the indexation with DefaultPrice indexer
127+
*
128+
* @return void
129+
* @throws InputException
130+
* @throws LocalizedException
131+
*/
132+
public function testRowDefaultPriceIndexer()
133+
{
134+
$select = $this->createMock(Select::class);
135+
$select->method('from')->willReturnSelf();
136+
$select->method('joinLeft')->willReturnSelf();
137+
$select->method('where')->willReturnSelf();
138+
$select->method('join')->willReturnSelf();
139+
140+
$adapter = $this->createMock(AdapterInterface::class);
141+
$adapter->method('select')->willReturn($select);
142+
$adapter->method('describeTable')->willReturn([]);
143+
144+
$adapter->expects($this->exactly(1))
145+
->method('describeTable');
146+
147+
$this->tableMaintainer->expects($this->exactly(3))->method('getMainTableByDimensions');
148+
149+
$this->defaultIndexerResource->method('getConnection')->willReturn($adapter);
150+
$adapter->method('fetchAll')->with($select)->willReturn([]);
151+
152+
$adapter->expects($this->any())
153+
->method('fetchPairs')
154+
->with($select)
155+
->willReturn(
156+
[1 => 'simple'],
157+
[]
158+
);
159+
160+
$multiDimensionProvider = $this->createMock(MultiDimensionProvider::class);
161+
$this->dimensionCollectionFactory->expects($this->exactly(2))
162+
->method('create')
163+
->willReturn($multiDimensionProvider);
164+
$dimension = $this->createMock(Dimension::class);
165+
$dimension->method('getName')->willReturn('default');
166+
$dimension->method('getValue')->willReturn('0');
167+
$iterator = new \ArrayIterator([[$dimension]]);
168+
$multiDimensionProvider->expects($this->exactly(2))
169+
->method('getIterator')
170+
->willReturn($iterator);
171+
$this->catalogProductType->expects($this->once())
172+
->method('getTypesByPriority')
173+
->willReturn(
174+
[
175+
'simple' => ['price_indexer' => '\Price\Indexer']
176+
]
177+
);
178+
$this->indexerPriceFactory->expects($this->exactly(1))
179+
->method('create')
180+
->with('\Price\Indexer', ['fullReindexAction' => false])
181+
->willReturn($this->defaultIndexerResource);
182+
$this->defaultIndexerResource->expects($this->exactly(1))
183+
->method('reindexEntity');
184+
$this->defaultIndexerResource->expects($this->any())->method('setTypeId')->willReturnSelf();
185+
$this->defaultIndexerResource->expects($this->any())->method('setIsComposite');
186+
$select->expects($this->exactly(1))
187+
->method('deleteFromSelect')
188+
->with('index_price')
189+
->willReturn('');
190+
$adapter->expects($this->exactly(2))
191+
->method('getIndexList')
192+
->willReturn(['entity_id'=>['COLUMNS_LIST'=>['test']]]);
193+
$adapter->expects($this->exactly(2))
194+
->method('getPrimaryKeyName')
195+
->willReturn('entity_id');
196+
197+
$this->actionRow->execute(1);
198+
}
199+
}

0 commit comments

Comments
 (0)