Skip to content

Commit ead79ad

Browse files
author
Anna Bukatar
committed
Merge branch '2.4-develop' of https://github.com/magento-l3/magento2ce into ACP2E-1311
2 parents 44f0de3 + 6de2066 commit ead79ad

File tree

52 files changed

+2139
-482
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2139
-482
lines changed

app/code/Magento/Bundle/Pricing/Adjustment/DefaultSelectionPriceListProvider.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ public function getPriceList(Product $bundleProduct, $searchMin, $useRegularPric
8484
[(int)$option->getOptionId()],
8585
$bundleProduct
8686
);
87+
$selectionsCollection->setFlag('has_stock_status_filter', true);
8788
$selectionsCollection->removeAttributeToSelect();
88-
$selectionsCollection->addQuantityFilter();
8989

9090
if (!$useRegularPrice) {
9191
$selectionsCollection->addAttributeToSelect('special_price');
@@ -140,6 +140,9 @@ private function isShouldFindMinOption(Product $bundleProduct, $searchMin)
140140
private function addMiniMaxPriceList(Product $bundleProduct, $selectionsCollection, $searchMin, $useRegularPrice)
141141
{
142142
$selectionsCollection->addPriceFilter($bundleProduct, $searchMin, $useRegularPrice);
143+
if ($bundleProduct->isSalable()) {
144+
$selectionsCollection->addQuantityFilter();
145+
}
143146
$selectionsCollection->setPage(0, 1);
144147

145148
$selection = $selectionsCollection->getFirstItem();

app/code/Magento/Bundle/Test/Unit/Pricing/Adjustment/DefaultSelectionPriceListProviderTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,47 @@ public function testGetPriceList(): void
177177
$this->selectionCollection->expects($this->once())
178178
->method('getIterator')
179179
->willReturn(new \ArrayIterator([]));
180+
$this->selectionCollection->expects($this->once())
181+
->method('setFlag')
182+
->with('has_stock_status_filter', true);
180183

181184
$this->model->getPriceList($this->product, false, false);
182185
}
186+
187+
public function testGetPriceListWithSearchMin(): void
188+
{
189+
$option = $this->createMock(Option::class);
190+
$option->expects($this->once())->method('getRequired')
191+
->willReturn(true);
192+
$this->optionsCollection->expects($this->any())
193+
->method('getIterator')
194+
->willReturn(new \ArrayIterator([$option]));
195+
$this->typeInstance->expects($this->any())
196+
->method('getOptionsCollection')
197+
->with($this->product)
198+
->willReturn($this->optionsCollection);
199+
$this->product->expects($this->any())
200+
->method('getTypeInstance')
201+
->willReturn($this->typeInstance);
202+
$this->selectionCollection->expects($this->once())
203+
->method('getFirstItem')
204+
->willReturn($this->createMock(Product::class));
205+
$this->typeInstance->expects($this->once())
206+
->method('getSelectionsCollection')
207+
->willReturn($this->selectionCollection);
208+
$this->selectionCollection->expects($this->once())
209+
->method('setFlag')
210+
->with('has_stock_status_filter', true);
211+
$this->selectionCollection->expects($this->once())
212+
->method('addQuantityFilter');
213+
$this->product->expects($this->once())->method('isSalable')->willReturn(true);
214+
$this->optionsCollection->expects($this->once())
215+
->method('getSize')
216+
->willReturn(1);
217+
$this->optionsCollection->expects($this->once())
218+
->method('addFilter')
219+
->willReturn($this->optionsCollection);
220+
221+
$this->model->getPriceList($this->product, true, false);
222+
}
183223
}

app/code/Magento/Catalog/Model/ResourceModel/Attribute/ConditionBuilder.php

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,17 @@
88

99
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
1010
use Magento\Framework\EntityManager\EntityMetadataInterface;
11+
use Magento\Framework\Exception\NoSuchEntityException;
1112
use Magento\Store\Api\Data\StoreInterface;
1213
use Magento\Store\Model\Store;
1314
use Magento\Store\Model\StoreManagerInterface;
14-
use Magento\Catalog\Model\ResourceModel\Eav\Attribute as CatalogEavAttribute;
1515
use Magento\Store\Model\Website;
1616
use Magento\Framework\Model\Entity\ScopeInterface;
1717

1818
/**
1919
* Builds scope-related conditions for catalog attributes
2020
*
2121
* Class ConditionBuilder
22-
* @package Magento\Catalog\Model\ResourceModel\Attribute
2322
*/
2423
class ConditionBuilder
2524
{
@@ -45,6 +44,7 @@ public function __construct(StoreManagerInterface $storeManager)
4544
* @param ScopeInterface[] $scopes
4645
* @param string $linkFieldValue
4746
* @return array
47+
* @throws NoSuchEntityException
4848
*/
4949
public function buildExistingAttributeWebsiteScope(
5050
AbstractAttribute $attribute,
@@ -56,7 +56,7 @@ public function buildExistingAttributeWebsiteScope(
5656
if (!$website) {
5757
return [];
5858
}
59-
$storeIds = $website->getStoreIds();
59+
$storeIds = $this->getStoreIds($website);
6060

6161
$condition = [
6262
$metadata->getLinkField() . ' = ?' => $linkFieldValue,
@@ -81,6 +81,7 @@ public function buildExistingAttributeWebsiteScope(
8181
* @param ScopeInterface[] $scopes
8282
* @param string $linkFieldValue
8383
* @return array
84+
* @throws NoSuchEntityException
8485
*/
8586
public function buildNewAttributesWebsiteScope(
8687
AbstractAttribute $attribute,
@@ -92,7 +93,7 @@ public function buildNewAttributesWebsiteScope(
9293
if (!$website) {
9394
return [];
9495
}
95-
$storeIds = $website->getStoreIds();
96+
$storeIds = $this->getStoreIds($website);
9697

9798
$condition = [
9899
$metadata->getLinkField() => $linkFieldValue,
@@ -109,8 +110,11 @@ public function buildNewAttributesWebsiteScope(
109110
}
110111

111112
/**
113+
* Get website for website scope
114+
*
112115
* @param array $scopes
113116
* @return null|Website
117+
* @throws NoSuchEntityException
114118
*/
115119
private function getWebsiteForWebsiteScope(array $scopes)
116120
{
@@ -119,8 +123,11 @@ private function getWebsiteForWebsiteScope(array $scopes)
119123
}
120124

121125
/**
126+
* Get store from scopes
127+
*
122128
* @param ScopeInterface[] $scopes
123129
* @return StoreInterface|null
130+
* @throws NoSuchEntityException
124131
*/
125132
private function getStoreFromScopes(array $scopes)
126133
{
@@ -132,4 +139,20 @@ private function getStoreFromScopes(array $scopes)
132139

133140
return null;
134141
}
142+
143+
/**
144+
* Get storeIds from the website
145+
*
146+
* @param Website $website
147+
* @return array
148+
*/
149+
private function getStoreIds(Website $website): array
150+
{
151+
$storeIds = $website->getStoreIds();
152+
153+
if (empty($storeIds) && $website->getCode() === Website::ADMIN_CODE) {
154+
$storeIds[] = Store::DEFAULT_STORE_ID;
155+
}
156+
return $storeIds;
157+
}
135158
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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\Model\System\Config\Backend\Rss;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
12+
use Magento\Framework\App\Cache\TypeListInterface;
13+
use Magento\Framework\App\Config\ScopeConfigInterface;
14+
use Magento\Framework\App\Config\Value as ConfigValue;
15+
use Magento\Framework\App\ObjectManager;
16+
use Magento\Framework\Data\Collection\AbstractDb;
17+
use Magento\Framework\Model\Context;
18+
use Magento\Framework\Model\ResourceModel\AbstractResource;
19+
use Magento\Framework\Registry;
20+
21+
class Category extends ConfigValue
22+
{
23+
/**
24+
* @var ProductAttributeRepositoryInterface
25+
*/
26+
private $productAttributeRepository;
27+
28+
/**
29+
* @param Context $context
30+
* @param Registry $registry
31+
* @param ScopeConfigInterface $config
32+
* @param TypeListInterface $cacheTypeList
33+
* @param AbstractResource|null $resource
34+
* @param AbstractDb|null $resourceCollection
35+
* @param array $data
36+
* @param ProductAttributeRepositoryInterface|null $productAttributeRepository
37+
*/
38+
public function __construct(
39+
Context $context,
40+
Registry $registry,
41+
ScopeConfigInterface $config,
42+
TypeListInterface $cacheTypeList,
43+
AbstractResource $resource = null,
44+
AbstractDb $resourceCollection = null,
45+
array $data = [],
46+
ProductAttributeRepositoryInterface $productAttributeRepository = null
47+
) {
48+
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
49+
50+
$this->productAttributeRepository = $productAttributeRepository ??
51+
ObjectManager::getInstance()->get(ProductAttributeRepositoryInterface::class);
52+
}
53+
54+
/**
55+
* @inheritdoc
56+
*/
57+
public function afterSave()
58+
{
59+
if ($this->isValueChanged() && $this->getValue()) {
60+
$updatedAtAttr = $this->productAttributeRepository->get(ProductInterface::UPDATED_AT);
61+
if (!$updatedAtAttr->getUsedForSortBy()) {
62+
$updatedAtAttr->setUsedForSortBy(true);
63+
$this->productAttributeRepository->save($updatedAtAttr);
64+
}
65+
}
66+
67+
return parent::afterSave();
68+
}
69+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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\Fixture;
9+
10+
use Magento\Catalog\Api\CategoryLinkManagementInterface;
11+
use Magento\Framework\Exception\InvalidArgumentException;
12+
use Magento\Framework\DataObject;
13+
use Magento\TestFramework\Fixture\DataFixtureInterface;
14+
15+
/**
16+
* Assigning products to catalog
17+
*/
18+
class AssignProducts implements DataFixtureInterface
19+
{
20+
private const PRODUCTS = 'products';
21+
private const CATEGORY = 'category';
22+
23+
/**
24+
* @var CategoryLinkManagementInterface
25+
*/
26+
private categoryLinkManagementInterface $categoryLinkManagement;
27+
28+
/**
29+
* @param CategoryLinkManagementInterface $categoryLinkManagement
30+
*/
31+
public function __construct(CategoryLinkManagementInterface $categoryLinkManagement)
32+
{
33+
$this->categoryLinkManagement = $categoryLinkManagement;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
* @throws InvalidArgumentException
39+
*/
40+
public function apply(array $data = []): ?DataObject
41+
{
42+
if (empty($data[self::CATEGORY])) {
43+
throw new InvalidArgumentException(__('"%field" is required', ['field' => self::CATEGORY]));
44+
}
45+
46+
if (empty($data[self::PRODUCTS])) {
47+
throw new InvalidArgumentException(__('"%field" is required', ['field' => self::PRODUCTS]));
48+
}
49+
50+
if (!is_array($data[self::PRODUCTS])) {
51+
throw new InvalidArgumentException(__('"%field" must be an array', ['field' => self::PRODUCTS]));
52+
}
53+
54+
foreach ($data[self::PRODUCTS] as $product) {
55+
$this->categoryLinkManagement->assignProductToCategories(
56+
$product->getSku(),
57+
[$data[self::CATEGORY]->getId()]
58+
);
59+
}
60+
61+
return null;
62+
}
63+
}

0 commit comments

Comments
 (0)