Skip to content

Commit fbfac3e

Browse files
authored
Merge pull request #6171 from magento-tsg-csl3/2.4-develop-pr41
[TSG-CSL3] For 2.4 (pr41)
2 parents 1064e35 + fd6c705 commit fbfac3e

File tree

23 files changed

+726
-146
lines changed

23 files changed

+726
-146
lines changed

Diff for: app/code/Magento/Catalog/Test/Unit/Model/Product/Filter/DateTimeTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Catalog\Model\Product\Filter\DateTime;
1111
use Magento\Framework\Locale\Resolver;
1212
use Magento\Framework\Locale\ResolverInterface;
13+
use Magento\Framework\Stdlib\DateTime\Intl\DateFormatterFactory;
1314
use Magento\Framework\Stdlib\DateTime\Timezone;
1415
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1516
use PHPUnit\Framework\TestCase;
@@ -43,7 +44,7 @@ function () {
4344
);
4445
$timezone = $objectManager->getObject(
4546
Timezone::class,
46-
['localeResolver' => $localeResolver]
47+
['localeResolver' => $localeResolver, 'dateFormatterFactory' => new DateFormatterFactory()]
4748
);
4849
$stdlibDateTimeFilter = $objectManager->getObject(
4950
\Magento\Framework\Stdlib\DateTime\Filter\DateTime::class,

Diff for: app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<actionGroup ref="AdminCatalogPriceRuleSaveAndApplyActionGroup" stepKey="saveAndApplyFirstPriceRule"/>
3636
<!-- Perform reindex -->
3737
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex">
38-
<argument name="indices" value="catalogrule_rule"/>
38+
<argument name="indices" value=""/>
3939
</actionGroup>
4040
</before>
4141

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="CheckoutDifferentDefaultCountryPerStoreTest">
12+
<annotations>
13+
<features value="One Page Checkout"/>
14+
<stories value="Checkout via the Storefront"/>
15+
<title value="Checkout different default country per store"/>
16+
<description value="Checkout display default country per store view"/>
17+
<severity value="MAJOR"/>
18+
<testCaseId value="MC-37707"/>
19+
<useCaseId value="MC-36884"/>
20+
<group value="checkout"/>
21+
</annotations>
22+
<before>
23+
<!-- Create simple product -->
24+
<createData entity="SimpleProduct2" stepKey="createProduct"/>
25+
<!-- Create store view -->
26+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminArea"/>
27+
<actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView">
28+
<argument name="customStore" value="customStore"/>
29+
</actionGroup>
30+
<!-- Set Germany as default country for created store view -->
31+
<magentoCLI command="config:set --scope=stores --scope-code={{customStore.code}} general/country/default {{DE_Address_Berlin_Not_Default_Address.country_id}}" stepKey="changeDefaultCountry"/>
32+
</before>
33+
<after>
34+
<!--Delete product and store view-->
35+
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
36+
<actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView">
37+
<argument name="customStore" value="customStore"/>
38+
</actionGroup>
39+
</after>
40+
<!-- Open product and add product to cart-->
41+
<actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="openProductPage">
42+
<argument name="productUrlKey" value="$$createProduct.custom_attributes[url_key]$$"/>
43+
</actionGroup>
44+
<actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="addProductToCart">
45+
<argument name="product" value="$$createProduct$$"/>
46+
<argument name="productCount" value="1"/>
47+
</actionGroup>
48+
<!-- Go to cart -->
49+
<actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/>
50+
<!-- Switch store view -->
51+
<actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="switchStoreViewActionGroup">
52+
<argument name="storeView" value="customStore"/>
53+
</actionGroup>
54+
<!-- Go to checkout page -->
55+
<actionGroup ref="OpenStoreFrontCheckoutShippingPageActionGroup" stepKey="openCheckoutShippingPage"/>
56+
<!-- Grab country code from checkout page and assert value with default country for created store view -->
57+
<grabValueFrom selector="{{CheckoutShippingSection.country}}" stepKey="grabCountry"/>
58+
<assertEquals stepKey="assertCountryValue">
59+
<actualResult type="const">$grabCountry</actualResult>
60+
<expectedResult type="string">{{DE_Address_Berlin_Not_Default_Address.country_id}}</expectedResult>
61+
</assertEquals>
62+
</test>
63+
</tests>

Diff for: app/code/Magento/Checkout/view/frontend/web/js/view/cart/shipping-estimation.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,13 @@ define(
7979

8080
if (!quote.isVirtual()) {
8181
checkoutProvider.on('shippingAddress', function (shippingAddressData) {
82-
checkoutData.setShippingAddressFromData(shippingAddressData);
82+
//jscs:disable requireCamelCaseOrUpperCaseIdentifiers
83+
if (quote.shippingAddress().countryId !== shippingAddressData.country_id ||
84+
(shippingAddressData.postcode || shippingAddressData.region_id)
85+
) {
86+
checkoutData.setShippingAddressFromData(shippingAddressData);
87+
}
88+
//jscs:enable requireCamelCaseOrUpperCaseIdentifiers
8389
});
8490
} else {
8591
checkoutProvider.on('shippingAddress', function (shippingAddressData) {

Diff for: app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Magento\Framework\Exception\NoSuchEntityException;
2020
use Magento\Framework\Locale\Resolver;
2121
use Magento\Framework\Locale\ResolverInterface;
22+
use Magento\Framework\Stdlib\DateTime\Intl\DateFormatterFactory;
2223
use Magento\Framework\Stdlib\DateTime\Timezone;
2324
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
2425
use Magento\Framework\View\Element\Html\Date;
@@ -50,7 +51,7 @@ class DobTest extends TestCase
5051
const YEAR = '2014';
5152

5253
// Value of date('Y', strtotime(self::DATE))
53-
const DATE_FORMAT = 'M/d/Y';
54+
const DATE_FORMAT = 'M/d/y';
5455

5556
/** Constants used by Dob::setDateInput($code, $html) */
5657
const DAY_HTML =
@@ -119,7 +120,7 @@ function () {
119120
);
120121
$timezone = $objectManager->getObject(
121122
Timezone::class,
122-
['localeResolver' => $localeResolver]
123+
['localeResolver' => $localeResolver, 'dateFormatterFactory' => new DateFormatterFactory()]
123124
);
124125

125126
$this->_locale = Resolver::DEFAULT_LOCALE;
@@ -357,7 +358,8 @@ public function getDateFormatDataProvider(): array
357358
preg_replace(
358359
'/[^MmDdYy\/\.\-]/',
359360
'',
360-
(new \IntlDateFormatter('ar_SA', \IntlDateFormatter::SHORT, \IntlDateFormatter::NONE))
361+
(new DateFormatterFactory())
362+
->create('ar_SA', \IntlDateFormatter::SHORT, \IntlDateFormatter::NONE)
361363
->getPattern()
362364
)
363365
],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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\GroupedProduct\Model\Inventory;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Framework\EntityManager\MetadataPool;
12+
use Magento\GroupedProduct\Model\Product\Type\Grouped;
13+
use Magento\Catalog\Api\Data\ProductInterface as Product;
14+
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
15+
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
16+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
17+
use Magento\CatalogInventory\Observer\ParentItemProcessorInterface;
18+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
19+
use Magento\GroupedProduct\Model\ResourceModel\Product\Link;
20+
use Magento\Framework\App\ResourceConnection;
21+
22+
/**
23+
* Process parent stock item for grouped product
24+
*/
25+
class ParentItemProcessor implements ParentItemProcessorInterface
26+
{
27+
/**
28+
* @var Grouped
29+
*/
30+
private $groupedType;
31+
32+
/**
33+
* @var StockItemRepositoryInterface
34+
*/
35+
private $stockItemRepository;
36+
37+
/**
38+
* @var StockConfigurationInterface
39+
*/
40+
private $stockConfiguration;
41+
42+
/**
43+
* @var StockItemCriteriaInterfaceFactory
44+
*/
45+
private $criteriaInterfaceFactory;
46+
47+
/**
48+
* Product metadata pool
49+
*
50+
* @var MetadataPool
51+
*/
52+
private $metadataPool;
53+
54+
/**
55+
* @var ResourceConnection
56+
*/
57+
private $resource;
58+
59+
/**
60+
* @param Grouped $groupedType
61+
* @param StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory
62+
* @param StockItemRepositoryInterface $stockItemRepository
63+
* @param StockConfigurationInterface $stockConfiguration
64+
* @param ResourceConnection $resource
65+
* @param MetadataPool $metadataPool
66+
*/
67+
public function __construct(
68+
Grouped $groupedType,
69+
StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory,
70+
StockItemRepositoryInterface $stockItemRepository,
71+
StockConfigurationInterface $stockConfiguration,
72+
ResourceConnection $resource,
73+
MetadataPool $metadataPool
74+
) {
75+
$this->groupedType = $groupedType;
76+
$this->criteriaInterfaceFactory = $criteriaInterfaceFactory;
77+
$this->stockConfiguration = $stockConfiguration;
78+
$this->stockItemRepository = $stockItemRepository;
79+
$this->resource = $resource;
80+
$this->metadataPool = $metadataPool;
81+
}
82+
83+
/**
84+
* Process parent products
85+
*
86+
* @param Product $product
87+
* @return void
88+
*/
89+
public function process(Product $product)
90+
{
91+
$parentIds = $this->getParentEntityIdsByChild($product->getId());
92+
foreach ($parentIds as $productId) {
93+
$this->processStockForParent((int)$productId);
94+
}
95+
}
96+
97+
/**
98+
* Change stock item for parent product depending on children stock items
99+
*
100+
* @param int $productId
101+
* @return void
102+
*/
103+
private function processStockForParent(int $productId)
104+
{
105+
$criteria = $this->criteriaInterfaceFactory->create();
106+
$criteria->setScopeFilter($this->stockConfiguration->getDefaultScopeId());
107+
$criteria->setProductsFilter($productId);
108+
$stockItemCollection = $this->stockItemRepository->getList($criteria);
109+
$allItems = $stockItemCollection->getItems();
110+
if (empty($allItems)) {
111+
return;
112+
}
113+
$parentStockItem = array_shift($allItems);
114+
$groupedChildrenIds = $this->groupedType->getChildrenIds($productId);
115+
$criteria->setProductsFilter($groupedChildrenIds);
116+
$stockItemCollection = $this->stockItemRepository->getList($criteria);
117+
$allItems = $stockItemCollection->getItems();
118+
119+
$groupedChildrenIsInStock = false;
120+
121+
foreach ($allItems as $childItem) {
122+
if ($childItem->getIsInStock() === true) {
123+
$groupedChildrenIsInStock = true;
124+
break;
125+
}
126+
}
127+
128+
if ($this->isNeedToUpdateParent($parentStockItem, $groupedChildrenIsInStock)) {
129+
$parentStockItem->setIsInStock($groupedChildrenIsInStock);
130+
$parentStockItem->setStockStatusChangedAuto(1);
131+
$this->stockItemRepository->save($parentStockItem);
132+
}
133+
}
134+
135+
/**
136+
* Check is parent item should be updated
137+
*
138+
* @param StockItemInterface $parentStockItem
139+
* @param bool $childrenIsInStock
140+
* @return bool
141+
*/
142+
private function isNeedToUpdateParent(StockItemInterface $parentStockItem, bool $childrenIsInStock): bool
143+
{
144+
return $parentStockItem->getIsInStock() !== $childrenIsInStock &&
145+
($childrenIsInStock === false || $parentStockItem->getStockStatusChangedAuto());
146+
}
147+
148+
/**
149+
* Retrieve parent ids array by child id
150+
*
151+
* @param int $childId
152+
* @return string[]
153+
*/
154+
private function getParentEntityIdsByChild($childId)
155+
{
156+
$select = $this->resource->getConnection()
157+
->select()
158+
->from(['l' => $this->resource->getTableName('catalog_product_link')], [])
159+
->join(
160+
['e' => $this->resource->getTableName('catalog_product_entity')],
161+
'e.' .
162+
$this->metadataPool->getMetadata(ProductInterface::class)->getLinkField() . ' = l.product_id',
163+
['e.entity_id']
164+
)
165+
->where('l.linked_product_id = ?', $childId)
166+
->where(
167+
'link_type_id = ?',
168+
Link::LINK_TYPE_GROUPED
169+
);
170+
171+
return $this->resource->getConnection()->fetchCol($select);
172+
}
173+
}

Diff for: app/code/Magento/GroupedProduct/etc/di.xml

+7
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,11 @@
105105
</argument>
106106
</arguments>
107107
</type>
108+
<type name="Magento\CatalogInventory\Observer\SaveInventoryDataObserver">
109+
<arguments>
110+
<argument name="parentItemProcessorPool" xsi:type="array">
111+
<item name="grouped" xsi:type="object"> Magento\GroupedProduct\Model\Inventory\ParentItemProcessor</item>
112+
</argument>
113+
</arguments>
114+
</type>
108115
</config>

Diff for: app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ protected function _prepareForm()
226226
'title' => __('Select File to Import'),
227227
'required' => true,
228228
'class' => 'input-file',
229+
'onchange' => 'varienImport.refreshLoadedFileLastModified(this);',
229230
'note' => __(
230231
'File must be saved in UTF-8 encoding for proper import'
231232
),
@@ -282,7 +283,7 @@ protected function getDownloadSampleFileHtml()
282283
private function getImportBehaviorTooltip()
283284
{
284285
$html = '<div class="admin__field-tooltip tooltip">
285-
<a class="admin__field-tooltip-action action-help" target="_blank" title="What is this?"
286+
<a class="admin__field-tooltip-action action-help" target="_blank" title="What is this?"
286287
href="https://docs.magento.com/m2/ce/user_guide/system/data-import.html"><span>'
287288
. __('What is this?')
288289
. '</span></a></div>';

Diff for: app/code/Magento/ImportExport/i18n/en_US.csv

+1
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,4 @@ Summary,Summary
127127
"File %1 deleted","File %1 deleted"
128128
"Please provide valid export file name","Please provide valid export file name"
129129
"%1 is not a valid file","%1 is not a valid file"
130+
"Content of uploaded file was changed, please re-upload the file","Content of uploaded file was changed, please re-upload the file"

0 commit comments

Comments
 (0)