Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.

Commit cc4fb4c

Browse files
Merge branch '2.3-develop' into 2.3-qwerty
2 parents 65fd603 + b2f1417 commit cc4fb4c

File tree

132 files changed

+2416
-1205
lines changed

Some content is hidden

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

132 files changed

+2416
-1205
lines changed

app/code/Magento/Backend/Controller/Adminhtml/Dashboard/RefreshStatistics.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66

77
namespace Magento\Backend\Controller\Adminhtml\Dashboard;
88

9-
class RefreshStatistics extends \Magento\Reports\Controller\Adminhtml\Report\Statistics
9+
use Magento\Framework\App\Action\HttpPostActionInterface;
10+
use Magento\Reports\Controller\Adminhtml\Report\Statistics;
11+
12+
/**
13+
* Refresh Dashboard statistics action.
14+
*/
15+
class RefreshStatistics extends Statistics implements HttpPostActionInterface
1016
{
1117
/**
1218
* @param \Magento\Backend\App\Action\Context $context
@@ -25,6 +31,8 @@ public function __construct(
2531
}
2632

2733
/**
34+
* Refresh statistics.
35+
*
2836
* @return \Magento\Backend\Model\View\Result\Redirect
2937
*/
3038
public function execute()

app/code/Magento/Catalog/Block/Adminhtml/Form/Renderer/Fieldset/Element.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
* See COPYING.txt for license details.
55
*/
66

7+
namespace Magento\Catalog\Block\Adminhtml\Form\Renderer\Fieldset;
8+
79
/**
810
* Catalog fieldset element renderer
911
*
1012
* @author Magento Core Team <[email protected]>
1113
*/
12-
namespace Magento\Catalog\Block\Adminhtml\Form\Renderer\Fieldset;
13-
1414
class Element extends \Magento\Backend\Block\Widget\Form\Renderer\Fieldset\Element
1515
{
1616
/**
@@ -29,7 +29,7 @@ public function getDataObject()
2929
}
3030

3131
/**
32-
* Retireve associated with element attribute object
32+
* Retrieve associated with element attribute object
3333
*
3434
* @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute
3535
*/

app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Action/Attribute/Tab/Inventory.php

+2-31
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
*/
66
namespace Magento\Catalog\Block\Adminhtml\Product\Edit\Action\Attribute\Tab;
77

8-
use Magento\Customer\Api\Data\GroupInterface;
9-
108
/**
119
* Products mass update inventory tab
1210
*
@@ -31,29 +29,20 @@ class Inventory extends \Magento\Backend\Block\Widget implements \Magento\Backen
3129
*/
3230
protected $disabledFields = [];
3331

34-
/**
35-
* @var \Magento\Framework\Serialize\SerializerInterface
36-
*/
37-
private $serializer;
38-
3932
/**
4033
* @param \Magento\Backend\Block\Template\Context $context
4134
* @param \Magento\CatalogInventory\Model\Source\Backorders $backorders
4235
* @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
4336
* @param array $data
44-
* @param \Magento\Framework\Serialize\SerializerInterface|null $serializer
4537
*/
4638
public function __construct(
4739
\Magento\Backend\Block\Template\Context $context,
4840
\Magento\CatalogInventory\Model\Source\Backorders $backorders,
4941
\Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
50-
array $data = [],
51-
\Magento\Framework\Serialize\SerializerInterface $serializer = null
42+
array $data = []
5243
) {
5344
$this->_backorders = $backorders;
5445
$this->stockConfiguration = $stockConfiguration;
55-
$this->serializer = $serializer ?? \Magento\Framework\App\ObjectManager::getInstance()
56-
->get(\Magento\Framework\Serialize\SerializerInterface::class);
5746
parent::__construct($context, $data);
5847
}
5948

@@ -85,9 +74,7 @@ public function getFieldSuffix()
8574
*/
8675
public function getStoreId()
8776
{
88-
$storeId = (int)$this->getRequest()->getParam('store');
89-
90-
return $storeId;
77+
return (int)$this->getRequest()->getParam('store');
9178
}
9279

9380
/**
@@ -101,22 +88,6 @@ public function getDefaultConfigValue($field)
10188
return $this->stockConfiguration->getDefaultConfigValue($field);
10289
}
10390

104-
/**
105-
* Returns min_sale_qty configuration for the ALL Customer Group
106-
*
107-
* @return float
108-
*/
109-
public function getDefaultMinSaleQty()
110-
{
111-
$default = $this->stockConfiguration->getDefaultConfigValue('min_sale_qty');
112-
if (!is_numeric($default)) {
113-
$default = $this->serializer->unserialize($default);
114-
$default = $default[GroupInterface::CUST_GROUP_ALL] ?? 1;
115-
}
116-
117-
return (float) $default;
118-
}
119-
12091
/**
12192
* Tab settings
12293
*

app/code/Magento/Catalog/Model/Category.php

+20-12
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,6 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
7272

7373
const CACHE_TAG = 'cat_c';
7474

75-
/**
76-
* Category Store Id
77-
*/
78-
const STORE_ID = 'store_id';
79-
8075
/**#@-*/
8176
protected $_eventPrefix = 'catalog_category';
8277

@@ -573,8 +568,8 @@ public function getStoreIds()
573568
*/
574569
public function getStoreId()
575570
{
576-
if ($this->hasData(self::STORE_ID)) {
577-
return (int)$this->_getData(self::STORE_ID);
571+
if ($this->hasData('store_id')) {
572+
return (int)$this->_getData('store_id');
578573
}
579574
return (int)$this->_storeManager->getStore()->getId();
580575
}
@@ -590,7 +585,7 @@ public function setStoreId($storeId)
590585
if (!is_numeric($storeId)) {
591586
$storeId = $this->_storeManager->getStore($storeId)->getId();
592587
}
593-
$this->setData(self::STORE_ID, $storeId);
588+
$this->setData('store_id', $storeId);
594589
$this->getResource()->setStoreId($storeId);
595590
return $this;
596591
}
@@ -1124,10 +1119,15 @@ public function reindex()
11241119
}
11251120
}
11261121
$productIndexer = $this->indexerRegistry->get(Indexer\Category\Product::INDEXER_ID);
1127-
if (!$productIndexer->isScheduled()
1128-
&& (!empty($this->getAffectedProductIds()) || $this->dataHasChangedFor('is_anchor'))
1129-
) {
1130-
$productIndexer->reindexList($this->getPathIds());
1122+
1123+
if (!empty($this->getAffectedProductIds())
1124+
|| $this->dataHasChangedFor('is_anchor')
1125+
|| $this->dataHasChangedFor('is_active')) {
1126+
if (!$productIndexer->isScheduled()) {
1127+
$productIndexer->reindexList($this->getPathIds());
1128+
} else {
1129+
$productIndexer->invalidate();
1130+
}
11311131
}
11321132
}
11331133

@@ -1152,9 +1152,17 @@ public function getIdentities()
11521152
$identities = [
11531153
self::CACHE_TAG . '_' . $this->getId(),
11541154
];
1155+
11551156
if ($this->hasDataChanges()) {
11561157
$identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $this->getId();
11571158
}
1159+
1160+
if ($this->dataHasChangedFor('is_anchor') || $this->dataHasChangedFor('is_active')) {
1161+
foreach ($this->getPathIds() as $id) {
1162+
$identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $id;
1163+
}
1164+
}
1165+
11581166
if (!$this->getId() || $this->isDeleted() || $this->dataHasChangedFor(self::KEY_INCLUDE_IN_MENU)) {
11591167
$identities[] = self::CACHE_TAG;
11601168
$identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $this->getId();

app/code/Magento/Catalog/Model/Product.php

-5
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
7171
*/
7272
const STORE_ID = 'store_id';
7373

74-
/**
75-
* Product Url path.
76-
*/
77-
const URL_PATH = 'url_path';
78-
7974
/**
8075
* @var string
8176
*/

app/code/Magento/Catalog/Model/Product/Copier.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function copy(Product $product)
8383
? $matches[1] . '-' . ($matches[2] + 1)
8484
: $urlKey . '-1';
8585
$duplicate->setUrlKey($urlKey);
86-
$duplicate->setData(Product::URL_PATH, null);
86+
$duplicate->setData('url_path', null);
8787
try {
8888
$duplicate->save();
8989
$isDuplicateSaved = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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\Product\Type;
9+
10+
use Magento\Store\Model\Store;
11+
use Magento\Catalog\Model\ResourceModel\Product\Price\SpecialPrice;
12+
use Magento\Catalog\Api\Data\SpecialPriceInterface;
13+
use Magento\Store\Api\Data\WebsiteInterface;
14+
15+
/**
16+
* Product special price model.
17+
*
18+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
19+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
20+
*/
21+
class FrontSpecialPrice extends Price
22+
{
23+
/**
24+
* @var SpecialPrice
25+
*/
26+
private $specialPrice;
27+
28+
/**
29+
* @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $ruleFactory
30+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
31+
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
32+
* @param \Magento\Customer\Model\Session $customerSession
33+
* @param \Magento\Framework\Event\ManagerInterface $eventManager
34+
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
35+
* @param \Magento\Customer\Api\GroupManagementInterface $groupManagement
36+
* @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory
37+
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
38+
* @param SpecialPrice $specialPrice
39+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
40+
*/
41+
public function __construct(
42+
\Magento\CatalogRule\Model\ResourceModel\RuleFactory $ruleFactory,
43+
\Magento\Store\Model\StoreManagerInterface $storeManager,
44+
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
45+
\Magento\Customer\Model\Session $customerSession,
46+
\Magento\Framework\Event\ManagerInterface $eventManager,
47+
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
48+
\Magento\Customer\Api\GroupManagementInterface $groupManagement,
49+
\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory,
50+
\Magento\Framework\App\Config\ScopeConfigInterface $config,
51+
SpecialPrice $specialPrice
52+
) {
53+
$this->specialPrice = $specialPrice;
54+
parent::__construct(
55+
$ruleFactory,
56+
$storeManager,
57+
$localeDate,
58+
$customerSession,
59+
$eventManager,
60+
$priceCurrency,
61+
$groupManagement,
62+
$tierPriceFactory,
63+
$config
64+
);
65+
}
66+
67+
/**
68+
* @inheritdoc
69+
*/
70+
protected function _applySpecialPrice($product, $finalPrice)
71+
{
72+
if (!$product->getSpecialPrice()) {
73+
return $finalPrice;
74+
}
75+
76+
$specialPrices = $this->getSpecialPrices($product);
77+
$specialPrice = !(empty($specialPrices)) ? min($specialPrices) : $product->getSpecialPrice();
78+
79+
$specialPrice = $this->calculateSpecialPrice(
80+
$finalPrice,
81+
$specialPrice,
82+
$product->getSpecialFromDate(),
83+
$product->getSpecialToDate(),
84+
WebsiteInterface::ADMIN_CODE
85+
);
86+
$product->setData('special_price', $specialPrice);
87+
88+
return $specialPrice;
89+
}
90+
91+
/**
92+
* Get special prices.
93+
*
94+
* @param mixed $product
95+
* @return array
96+
*/
97+
private function getSpecialPrices($product): array
98+
{
99+
$allSpecialPrices = $this->specialPrice->get([$product->getSku()]);
100+
$specialPrices = [];
101+
foreach ($allSpecialPrices as $price) {
102+
if ($this->isSuitableSpecialPrice($product, $price)) {
103+
$specialPrices[] = $price['value'];
104+
}
105+
}
106+
107+
return $specialPrices;
108+
}
109+
110+
/**
111+
* Price is suitable from default and current store + start and end date are equal.
112+
*
113+
* @param mixed $product
114+
* @param array $price
115+
* @return bool
116+
*/
117+
private function isSuitableSpecialPrice($product, array $price): bool
118+
{
119+
$priceStoreId = $price[Store::STORE_ID];
120+
if (($priceStoreId == Store::DEFAULT_STORE_ID || $product->getStoreId() == $priceStoreId)
121+
&& $price[SpecialPriceInterface::PRICE_FROM] == $product->getSpecialFromDate()
122+
&& $price[SpecialPriceInterface::PRICE_TO] == $product->getSpecialToDate()) {
123+
return true;
124+
}
125+
126+
return false;
127+
}
128+
}

app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml

+15-3
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,20 @@
265265
<checkOption selector="{{ProductInWebsitesSection.website(website)}}" stepKey="selectWebsite"/>
266266
</actionGroup>
267267

268+
<actionGroup name="AdminProductAddSpecialPrice">
269+
<arguments>
270+
<argument name="specialPrice" type="string"/>
271+
</arguments>
272+
<click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickAdvancedPricingLink1"/>
273+
<waitForElementVisible selector="{{AdminProductFormAdvancedPricingSection.specialPrice}}" stepKey="waitSpecialPrice1"/>
274+
<click selector="{{AdminProductFormAdvancedPricingSection.useDefaultPrice}}" stepKey="checkUseDefault"/>
275+
<fillField userInput="{{specialPrice}}" selector="{{AdminProductFormAdvancedPricingSection.specialPrice}}" stepKey="fillSpecialPrice"/>
276+
<click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickDone"/>
277+
<waitForElementNotVisible selector="{{AdminProductFormAdvancedPricingSection.specialPrice}}" stepKey="waitForCloseModalWindow"/>
278+
<click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton"/>
279+
<seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="seeSaveProductMessage"/>
280+
</actionGroup>
281+
268282
<!--Switch to New Store view-->
269283
<actionGroup name="SwitchToTheNewStoreView">
270284
<arguments>
@@ -304,9 +318,7 @@
304318
<argument name="website"/>
305319
<argument name="product"/>
306320
</arguments>
307-
<amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="navigateToProductPage"/>
308-
<waitForPageLoad stepKey="waitForProductsList"/>
309-
<click stepKey="openProduct" selector="{{AdminProductGridActionSection.productName(product.name)}}"/>
321+
<click stepKey="openProduct" selector="{{AdminProductGridActionSection.productName(product.sku)}}"/>
310322
<waitForPageLoad stepKey="waitForProductPage"/>
311323
<scrollTo selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="ScrollToWebsites"/>
312324
<click selector="{{ProductInWebsitesSection.sectionHeader}}" stepKey="openWebsitesList"/>

0 commit comments

Comments
 (0)