Skip to content

Commit 08c6d8d

Browse files
committed
ACP2E-1384: Issue with edit product price in website level
1 parent ffeb0a0 commit 08c6d8d

File tree

3 files changed

+159
-4
lines changed

3 files changed

+159
-4
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,10 +1927,7 @@ protected function _saveProducts()
19271927
}
19281928
if (self::SCOPE_STORE == $rowScope) {
19291929
if (self::SCOPE_WEBSITE == $attribute->getIsGlobal()) {
1930-
// check website defaults already set
1931-
if (!isset($attributes[$attrTable][$rowSku][$attrId][$rowStore])) {
1932-
$storeIds = $this->storeResolver->getStoreIdToWebsiteStoreIds($rowStore);
1933-
}
1930+
$storeIds = $this->storeResolver->getStoreIdToWebsiteStoreIds($rowStore);
19341931
} elseif (self::SCOPE_STORE == $attribute->getIsGlobal()) {
19351932
$storeIds = [$rowStore];
19361933
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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\ImportExport\Test\Fixture;
9+
10+
use Magento\Framework\App\Filesystem\DirectoryList;
11+
use Magento\Framework\DataObject;
12+
use Magento\Framework\DataObjectFactory;
13+
use Magento\Framework\Filesystem;
14+
use Magento\TestFramework\Fixture\Data\ProcessorInterface;
15+
use Magento\TestFramework\Fixture\RevertibleDataFixtureInterface;
16+
17+
class CsvFile implements RevertibleDataFixtureInterface
18+
{
19+
private const DEFAULT_DATA = [
20+
'directory' => DirectoryList::TMP,
21+
'path' => 'import/%uniqid%.csv',
22+
'rows' => [],
23+
];
24+
25+
/**
26+
* @var Filesystem
27+
*/
28+
private Filesystem $filesystem;
29+
30+
/**
31+
* @var ProcessorInterface
32+
*/
33+
private ProcessorInterface $dataProcessor;
34+
35+
/**
36+
* @var DataObjectFactory
37+
*/
38+
private DataObjectFactory $dataObjectFactory;
39+
40+
/**
41+
* @param Filesystem $filesystem
42+
* @param ProcessorInterface $dataProcessor
43+
* @param DataObjectFactory $dataObjectFactory
44+
*/
45+
public function __construct(
46+
Filesystem $filesystem,
47+
ProcessorInterface $dataProcessor,
48+
DataObjectFactory $dataObjectFactory
49+
) {
50+
$this->filesystem = $filesystem;
51+
$this->dataProcessor = $dataProcessor;
52+
$this->dataObjectFactory = $dataObjectFactory;
53+
}
54+
55+
/**
56+
* {@inheritdoc}
57+
* @param array $data Parameters. Same format as CsvFile::DEFAULT_DATA.
58+
* Additional fields:
59+
* - $data['rows']: CSV data to be written into the file in the following format:
60+
* - headers are listed in the first array and the following array
61+
* [
62+
* ['col1', 'col2'],
63+
* ['row1col1', 'row1col2'],
64+
* ]
65+
* - headers are listed as array keys
66+
* [
67+
* ['col1' => 'row1col1', 'col2' => 'row1col2'],
68+
* ['col1' => 'row2col1', 'col2' => 'row2col2'],
69+
* [
70+
*
71+
* @see CsvFile::DEFAULT_DATA
72+
*/
73+
public function apply(array $data = []): ?DataObject
74+
{
75+
$data = $this->dataProcessor->process($this, array_merge(self::DEFAULT_DATA, $data));
76+
$rows = $data['rows'];
77+
$row = reset($rows);
78+
79+
if (array_is_list($row)) {
80+
$cols = $row;
81+
$colsCount = count($cols);
82+
foreach ($rows as $row) {
83+
if ($colsCount !== count($row)) {
84+
throw new \InvalidArgumentException('Arrays in "rows" must be the same size');
85+
}
86+
}
87+
} else {
88+
$cols = array_keys($row);
89+
$lines[] = $cols;
90+
foreach ($rows as $row) {
91+
$line = [];
92+
if (array_diff($cols, array_keys($row))) {
93+
throw new \InvalidArgumentException('Arrays in "rows" must have same keys');
94+
}
95+
foreach ($cols as $field) {
96+
$line[] = $row[$field];
97+
}
98+
$lines[] = $line;
99+
}
100+
$rows = $lines;
101+
}
102+
$directory = $this->filesystem->getDirectoryWrite($data['directory']);
103+
$file = $directory->openFile($data['path'], 'w+');
104+
foreach ($rows as $row) {
105+
$file->writeCsv($row);
106+
}
107+
$file->close();
108+
$data['absolute_path'] = $directory->getAbsolutePath($data['path']);
109+
110+
return $this->dataObjectFactory->create(['data' => $data]);
111+
}
112+
113+
/**
114+
* @inheritDoc
115+
*/
116+
public function revert(DataObject $data): void
117+
{
118+
$directory = $this->filesystem->getDirectoryWrite($data['directory']);
119+
$directory->delete($data['path']);
120+
}
121+
}

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77

88
namespace Magento\CatalogImportExport\Model\Import\ProductTest;
99

10+
use Magento\Catalog\Helper\Data as CatalogConfig;
1011
use Magento\Catalog\Model\Product;
1112
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
13+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
1214
use Magento\CatalogImportExport\Model\Import\ProductTestBase;
1315
use Magento\CatalogInventory\Model\StockRegistry;
1416
use Magento\Framework\Api\SearchCriteria;
@@ -17,6 +19,12 @@
1719
use Magento\ImportExport\Helper\Data;
1820
use Magento\ImportExport\Model\Import;
1921
use Magento\ImportExport\Model\Import\Source\Csv;
22+
use Magento\ImportExport\Test\Fixture\CsvFile as CsvFileFixture;
23+
use Magento\Store\Model\ScopeInterface;
24+
use Magento\Store\Model\Store;
25+
use Magento\TestFramework\Fixture\Config;
26+
use Magento\TestFramework\Fixture\DataFixture;
27+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
2028
use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection;
2129

2230
/**
@@ -770,4 +778,33 @@ public function testImportProductWithTaxClassNone(): void
770778
$simpleProduct = $this->getProductBySku('simple2');
771779
$this->assertSame('0', (string) $simpleProduct->getTaxClassId());
772780
}
781+
782+
#[
783+
Config(CatalogConfig::XML_PATH_PRICE_SCOPE, CatalogConfig::PRICE_SCOPE_WEBSITE, ScopeInterface::SCOPE_STORE),
784+
DataFixture(ProductFixture::class, ['price' => 10], 'product'),
785+
DataFixture(
786+
CsvFileFixture::class,
787+
[
788+
'rows' => [
789+
['sku', 'store_view_code', 'price'],
790+
['$product.sku$', 'default', '9'],
791+
['$product.sku$', 'default', '8'],
792+
]
793+
],
794+
'file'
795+
),
796+
]
797+
public function testImportPriceInStoreViewShouldNotOverrideDefaultScopePrice(): void
798+
{
799+
$fixtures = DataFixtureStorageManager::getStorage();
800+
$sku = $fixtures->get('product')->getSku();
801+
$pathToFile = $fixtures->get('file')->getAbsolutePath();
802+
$importModel = $this->createImportModel($pathToFile);
803+
$this->assertErrorsCount(0, $importModel->validateData());
804+
$importModel->importData();
805+
$product = $this->productRepository->get($sku, storeId: Store::DEFAULT_STORE_ID, forceReload: true);
806+
$this->assertEquals(10, $product->getPrice());
807+
$product = $this->productRepository->get($sku, storeId: Store::DISTRO_STORE_ID, forceReload: true);
808+
$this->assertEquals(9, $product->getPrice());
809+
}
773810
}

0 commit comments

Comments
 (0)