Skip to content

Commit db490b5

Browse files
[EngCom] Public Pull Requests - 2.2-develop
- merged latest code from mainline branch
2 parents 703cc9b + 897deca commit db490b5

File tree

11 files changed

+203
-46
lines changed

11 files changed

+203
-46
lines changed

app/code/Magento/CatalogImportExport/Model/Import/Product.php

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,39 +2116,8 @@ protected function _saveStockItem()
21162116
$row = [];
21172117
$sku = $rowData[self::COL_SKU];
21182118
if ($this->skuProcessor->getNewSku($sku) !== null) {
2119-
$row['product_id'] = $this->skuProcessor->getNewSku($sku)['entity_id'];
2119+
$row = $this->formatStockDataForRow($rowData);
21202120
$productIdsToReindex[] = $row['product_id'];
2121-
2122-
$row['website_id'] = $this->stockConfiguration->getDefaultScopeId();
2123-
$row['stock_id'] = $this->stockRegistry->getStock($row['website_id'])->getStockId();
2124-
2125-
$stockItemDo = $this->stockRegistry->getStockItem($row['product_id'], $row['website_id']);
2126-
$existStockData = $stockItemDo->getData();
2127-
2128-
$row = array_merge(
2129-
$this->defaultStockData,
2130-
array_intersect_key($existStockData, $this->defaultStockData),
2131-
array_intersect_key($rowData, $this->defaultStockData),
2132-
$row
2133-
);
2134-
2135-
if ($this->stockConfiguration->isQty(
2136-
$this->skuProcessor->getNewSku($sku)['type_id']
2137-
)
2138-
) {
2139-
$stockItemDo->setData($row);
2140-
$row['is_in_stock'] = $this->stockStateProvider->verifyStock($stockItemDo);
2141-
if ($this->stockStateProvider->verifyNotification($stockItemDo)) {
2142-
$row['low_stock_date'] = $this->dateTime->gmDate(
2143-
'Y-m-d H:i:s',
2144-
(new \DateTime())->getTimestamp()
2145-
);
2146-
}
2147-
$row['stock_status_changed_auto'] =
2148-
(int)!$this->stockStateProvider->verifyStock($stockItemDo);
2149-
} else {
2150-
$row['qty'] = 0;
2151-
}
21522121
}
21532122

21542123
if (!isset($stockData[$sku])) {
@@ -2840,4 +2809,50 @@ private function getExistingSku($sku)
28402809
{
28412810
return $this->_oldSku[strtolower($sku)];
28422811
}
2812+
2813+
/**
2814+
* Format row data to DB compatible values
2815+
*
2816+
* @param array $rowData
2817+
* @return array
2818+
*/
2819+
private function formatStockDataForRow(array $rowData)
2820+
{
2821+
$sku = $rowData[self::COL_SKU];
2822+
$row['product_id'] = $this->skuProcessor->getNewSku($sku)['entity_id'];
2823+
$row['website_id'] = $this->stockConfiguration->getDefaultScopeId();
2824+
$row['stock_id'] = $this->stockRegistry->getStock($row['website_id'])->getStockId();
2825+
2826+
$stockItemDo = $this->stockRegistry->getStockItem($row['product_id'], $row['website_id']);
2827+
$existStockData = $stockItemDo->getData();
2828+
2829+
$row = array_merge(
2830+
$this->defaultStockData,
2831+
array_intersect_key($existStockData, $this->defaultStockData),
2832+
array_intersect_key($rowData, $this->defaultStockData),
2833+
$row
2834+
);
2835+
2836+
if ($this->stockConfiguration->isQty(
2837+
$this->skuProcessor->getNewSku($sku)['type_id']
2838+
)
2839+
) {
2840+
$stockItemDo->setData($row);
2841+
$row['is_in_stock'] = $stockItemDo->getBackorders() && isset($row['is_in_stock'])
2842+
? $row['is_in_stock']
2843+
: $this->stockStateProvider->verifyStock($stockItemDo);
2844+
if ($this->stockStateProvider->verifyNotification($stockItemDo)) {
2845+
$row['low_stock_date'] = $this->dateTime->gmDate(
2846+
'Y-m-d H:i:s',
2847+
(new \DateTime())->getTimestamp()
2848+
);
2849+
}
2850+
$row['stock_status_changed_auto'] =
2851+
(int)!$this->stockStateProvider->verifyStock($stockItemDo);
2852+
} else {
2853+
$row['qty'] = 0;
2854+
}
2855+
2856+
return $row;
2857+
}
28432858
}

app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ private function changeIsInStockIfNecessary(StockItemInterface $stockItem)
275275
if ($stockItem->getManageStock()
276276
&& $isInStock
277277
&& !$stockItem->getIsInStock()
278-
&& $stockItem->getOrigData(\Magento\CatalogInventory\Api\Data\StockItemInterface::QTY) == 0
278+
&& $stockItem->getQty() > 0
279+
&& $stockItem->getOrigData(\Magento\CatalogInventory\Api\Data\StockItemInterface::QTY) <= 0
279280
&& $stockItem->getOrigData(\Magento\CatalogInventory\Api\Data\StockItemInterface::QTY) !== null
280281
) {
281282
$stockItem->setIsInStock(true)->setStockStatusChangedAutomaticallyFlag(true);

app/code/Magento/Tax/Model/ResourceModel/Calculation/Rule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Magento\Tax\Model\ResourceModel\Calculation;
77

88
/**
9-
* Tax rate resource model
9+
* Tax rule resource model
1010
*
1111
* @author Magento Core Team <core@magentocommerce.com>
1212
*/

dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ protected function _getFixtures($scope, \PHPUnit\Framework\TestCase $test)
102102
* Execute single fixture script
103103
*
104104
* @param string|array $fixture
105+
* @throws \Exception
105106
*/
106107
protected function _applyOneFixture($fixture)
107108
{
@@ -112,9 +113,13 @@ protected function _applyOneFixture($fixture)
112113
require $fixture;
113114
}
114115
} catch (\Exception $e) {
115-
echo 'Exception occurred when running the '
116-
. (is_array($fixture) || is_scalar($fixture) ? json_encode($fixture) : 'callback')
117-
. ' fixture: ', PHP_EOL, $e;
116+
throw new \Exception(
117+
sprintf(
118+
"Exception occurred when running the %s fixture: \n%s",
119+
(\is_array($fixture) || is_scalar($fixture) ? json_encode($fixture) : 'callback'),
120+
$e->getMessage()
121+
)
122+
);
118123
}
119124
$this->_appliedFixtures[] = $fixture;
120125
}

dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/TrackingShipmentForPlacedOrderTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<item name="number" xsi:type="string">0123456789</item>
2727
</data>
2828
<data name="tag" xsi:type="string">severity:S1</data>
29+
<data name="tag" xsi:type="string">stable:no</data><!-- MAGETWO-89369 -->
2930
<constraint name="Magento\Shipping\Test\Constraint\AssertTrackingDetailsIsPresent" />
3031
</variation>
3132
</testCase>

dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/JsTest.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,18 @@ public function testGetAllRatesByProductClassJson()
2929
/** @var \Magento\Catalog\Block\Adminhtml\Product\Edit\Js $block */
3030
$block = $objectManager->create(\Magento\Catalog\Block\Adminhtml\Product\Edit\Js::class);
3131
$jsonResult = $block->getAllRatesByProductClassJson();
32-
$decodedResult = json_decode($jsonResult);
33-
$this->assertNotEmpty($decodedResult, 'Resulting JSON is invalid.');
34-
$taxClassesArray = (array)$decodedResult;
32+
$this->assertJson($jsonResult, 'Resulting JSON is invalid.');
33+
$decodedResult = json_decode($jsonResult, true);
34+
$this->assertNotNull($decodedResult, 'Cannot decode resulting JSON.');
3535
$noneTaxClass = 0;
3636
$defaultProductTaxClass = 2;
3737
$expectedProductTaxClasses = array_unique(
3838
array_merge($fixtureTaxRule->getProductTaxClasses(), [$defaultProductTaxClass, $noneTaxClass])
3939
);
40-
$this->assertCount(
41-
count($expectedProductTaxClasses),
42-
$taxClassesArray,
43-
'Invalid quantity of rates for tax classes.'
44-
);
4540
foreach ($expectedProductTaxClasses as $taxClassId) {
4641
$this->assertArrayHasKey(
4742
"value_{$taxClassId}",
48-
$taxClassesArray,
43+
$decodedResult,
4944
"Rates for tax class with ID '{$taxClassId}' is missing."
5045
);
5146
}

dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Catalog\Model;
79

810
use Magento\Framework\App\Filesystem\DirectoryList;
@@ -586,4 +588,45 @@ public function testSaveWithDifferentQty()
586588
$stockItem = $product->getExtensionAttributes()->getStockItem();
587589
$this->assertEquals(false, $stockItem->getIsInStock());
588590
}
591+
592+
/**
593+
* Check stock status changing if backorders functionality enabled
594+
*
595+
* @magentoDataFixture Magento/Catalog/_files/product_simple_out_of_stock.php
596+
* @dataProvider productWithBackordersDataProvider
597+
* @param int $qty
598+
* @param int $stockStatus
599+
* @param bool $expectedStockStatus
600+
*/
601+
public function testSaveWithBackordersEnabled(int $qty, int $stockStatus, bool $expectedStockStatus)
602+
{
603+
$product = $this->productRepository->get('simple-out-of-stock', true, null, true);
604+
$stockItem = $product->getExtensionAttributes()->getStockItem();
605+
$this->assertEquals(false, $stockItem->getIsInStock());
606+
$stockData = [
607+
'backorders' => 1,
608+
'qty' => $qty,
609+
'is_in_stock' => $stockStatus
610+
];
611+
$product->setStockData($stockData);
612+
$product->save();
613+
$stockItem = $product->getExtensionAttributes()->getStockItem();
614+
615+
$this->assertEquals($expectedStockStatus, $stockItem->getIsInStock());
616+
}
617+
618+
/**
619+
* DataProvider for the testSaveWithBackordersEnabled()
620+
* @return array
621+
*/
622+
public function productWithBackordersDataProvider(): array
623+
{
624+
return [
625+
[0, 0, false],
626+
[0, 1, true],
627+
[-1, 0, false],
628+
[-1, 1, true],
629+
[1, 1, true],
630+
];
631+
}
589632
}

dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,4 +2143,48 @@ public function testProductsWithMultipleStoresWhenMediaIsDisabled()
21432143
$this->assertTrue($errors->getErrorsCount() === 0);
21442144
$this->assertTrue($this->_model->importData());
21452145
}
2146+
2147+
/**
2148+
* Test that imported product stock status with backorders functionality enabled can be set to 'out of stock'.
2149+
*
2150+
* @magentoDataIsolation enabled
2151+
* @magentoAppIsolation enabled
2152+
*/
2153+
public function testImportWithBackordersEnabled()
2154+
{
2155+
$this->importFile('products_to_import_with_backorders_enabled_and_0_qty.csv');
2156+
$product = $this->getProductBySku('simple_new');
2157+
$this->assertFalse($product->getDataByKey('quantity_and_stock_status')['is_in_stock']);
2158+
}
2159+
2160+
/**
2161+
* Import file by providing import filename in parameters
2162+
*
2163+
* @param string $fileName
2164+
*/
2165+
private function importFile(string $fileName)
2166+
{
2167+
$filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
2168+
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
2169+
$source = $this->objectManager->create(
2170+
\Magento\ImportExport\Model\Import\Source\Csv::class,
2171+
[
2172+
'file' => __DIR__ . '/_files/' . $fileName,
2173+
'directory' => $directory
2174+
]
2175+
);
2176+
$errors = $this->_model->setParameters(
2177+
[
2178+
'behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND,
2179+
'entity' => 'catalog_product',
2180+
\Magento\ImportExport\Model\Import::FIELDS_ENCLOSURE => 1
2181+
]
2182+
)->setSource(
2183+
$source
2184+
)->validateData();
2185+
2186+
$this->assertTrue($errors->getErrorsCount() == 0);
2187+
2188+
$this->_model->importData();
2189+
}
21462190
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,crosssell_skus,upsell_skus,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,associated_skus
2+
simple_new,,Default,simple,,base,New Product,,,,1,Taxable Goods,"Catalog, Search",10,,,,new-product,New Product,New Product,New Product ,,,,,,,10/20/2015 7:05,10/20/2015 7:05,,,Block after Info Column,,,,,,,,,,,,,"has_options=1,quantity_and_stock_status=In Stock,required_options=1",0,0,1,0,1,0,1,1,10000,1,0,1,1,1,0,1,1,0,0,0,1,,,,,,,,,,,,,

dev/tests/integration/testsuite/Magento/Tax/_files/tax_classes.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@
3838
\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT
3939
)->save();
4040

41+
// Tax class created but not used in the rule to ensure that unused tax classes are handled properly
42+
$productTaxClass3 = $objectManager->create(
43+
\Magento\Tax\Model\ClassModel::class
44+
)->setClassName(
45+
'ProductTaxClass3'
46+
)->setClassType(
47+
\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT
48+
)->save();
49+
4150
$taxRate = [
4251
'tax_country_id' => 'US',
4352
'tax_region_id' => '12',

0 commit comments

Comments
 (0)