Skip to content

Commit 09976e8

Browse files
committed
Merge remote-tracking branch 'l3/MC-40943' into L3-PR-20210310
2 parents 7c7159e + 40c6f04 commit 09976e8

File tree

5 files changed

+100
-13
lines changed

5 files changed

+100
-13
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,7 +1855,7 @@ protected function _saveProducts()
18551855
}
18561856

18571857
$productTypeModel = $this->_productTypeModels[$productType];
1858-
if (!empty($rowData['tax_class_name'])) {
1858+
if (isset($rowData['tax_class_name']) && strlen($rowData['tax_class_name'])) {
18591859
$rowData['tax_class_id'] =
18601860
$this->taxClassProcessor->upsertTaxClass($rowData['tax_class_name'], $productTypeModel);
18611861
}

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

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,25 @@
77

88
use Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType;
99
use Magento\Tax\Model\ClassModel;
10+
use Magento\Tax\Model\ClassModelFactory;
11+
use Magento\Tax\Model\ResourceModel\TaxClass\Collection;
12+
use Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory;
1013

14+
/**
15+
* Imported products tax class processor
16+
*/
1117
class TaxClassProcessor
1218
{
19+
/**
20+
* Empty tax class name
21+
*/
22+
private const CLASS_NONE_NAME = 'none';
23+
24+
/**
25+
* Empty tax class ID
26+
*/
27+
private const CLASS_NONE_ID = 0;
28+
1329
/**
1430
* Tax attribute code.
1531
*/
@@ -25,24 +41,24 @@ class TaxClassProcessor
2541
/**
2642
* Instance of tax class collection factory.
2743
*
28-
* @var \Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory
44+
* @var CollectionFactory
2945
*/
3046
protected $collectionFactory;
3147

3248
/**
3349
* Instance of tax model factory.
3450
*
35-
* @var \Magento\Tax\Model\ClassModelFactory
51+
* @var ClassModelFactory
3652
*/
3753
protected $classModelFactory;
3854

3955
/**
40-
* @param \Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory $collectionFactory
41-
* @param \Magento\Tax\Model\ClassModelFactory $classModelFactory
56+
* @param CollectionFactory $collectionFactory
57+
* @param ClassModelFactory $classModelFactory
4258
*/
4359
public function __construct(
44-
\Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory $collectionFactory,
45-
\Magento\Tax\Model\ClassModelFactory $classModelFactory
60+
CollectionFactory $collectionFactory,
61+
ClassModelFactory $classModelFactory
4662
) {
4763
$this->collectionFactory = $collectionFactory;
4864
$this->classModelFactory = $classModelFactory;
@@ -59,9 +75,9 @@ protected function initTaxClasses()
5975
if (empty($this->taxClasses)) {
6076
$collection = $this->collectionFactory->create();
6177
$collection->addFieldToFilter('class_type', ClassModel::TAX_CLASS_TYPE_PRODUCT);
62-
/* @var $collection \Magento\Tax\Model\ResourceModel\TaxClass\Collection */
78+
/* @var $collection Collection */
6379
foreach ($collection as $taxClass) {
64-
$this->taxClasses[$taxClass->getClassName()] = $taxClass->getId();
80+
$this->taxClasses[mb_strtolower($taxClass->getClassName())] = $taxClass->getId();
6581
}
6682
}
6783
return $this;
@@ -76,7 +92,7 @@ protected function initTaxClasses()
7692
*/
7793
protected function createTaxClass($taxClassName, AbstractType $productTypeModel)
7894
{
79-
/** @var \Magento\Tax\Model\ClassModelFactory $taxClass */
95+
/** @var ClassModelFactory $taxClass */
8096
$taxClass = $this->classModelFactory->create();
8197
$taxClass->setClassType(ClassModel::TAX_CLASS_TYPE_PRODUCT);
8298
$taxClass->setClassName($taxClassName);
@@ -98,10 +114,22 @@ protected function createTaxClass($taxClassName, AbstractType $productTypeModel)
98114
*/
99115
public function upsertTaxClass($taxClassName, AbstractType $productTypeModel)
100116
{
101-
if (!isset($this->taxClasses[$taxClassName])) {
102-
$this->taxClasses[$taxClassName] = $this->createTaxClass($taxClassName, $productTypeModel);
117+
$normalizedTaxClassName = mb_strtolower($taxClassName);
118+
119+
if ($normalizedTaxClassName === (string) self::CLASS_NONE_ID) {
120+
$normalizedTaxClassName = self::CLASS_NONE_NAME;
121+
}
122+
123+
if (!isset($this->taxClasses[$normalizedTaxClassName])) {
124+
$this->taxClasses[$normalizedTaxClassName] = $normalizedTaxClassName === self::CLASS_NONE_NAME
125+
? self::CLASS_NONE_ID
126+
: $this->createTaxClass($taxClassName, $productTypeModel);
127+
}
128+
if ($normalizedTaxClassName === self::CLASS_NONE_NAME) {
129+
// Add None option to tax_class_id options.
130+
$productTypeModel->addAttributeOption(self::ATRR_CODE, self::CLASS_NONE_ID, self::CLASS_NONE_ID);
103131
}
104132

105-
return $this->taxClasses[$taxClassName];
133+
return $this->taxClasses[$normalizedTaxClassName];
106134
}
107135
}

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/TaxClassProcessorTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,22 @@ public function testUpsertTaxClassNotExist()
101101
$taxClassId = $this->taxClassProcessor->upsertTaxClass('noExistClassName', $this->product);
102102
$this->assertEquals(self::TEST_JUST_CREATED_TAX_CLASS_ID, $taxClassId);
103103
}
104+
105+
public function testUpsertTaxClassExistCaseInsensitive()
106+
{
107+
$taxClassId = $this->taxClassProcessor->upsertTaxClass(strtoupper(self::TEST_TAX_CLASS_NAME), $this->product);
108+
$this->assertEquals(self::TEST_TAX_CLASS_ID, $taxClassId);
109+
}
110+
111+
public function testUpsertTaxClassNone()
112+
{
113+
$taxClassId = $this->taxClassProcessor->upsertTaxClass('none', $this->product);
114+
$this->assertEquals(0, $taxClassId);
115+
}
116+
117+
public function testUpsertTaxClassZero()
118+
{
119+
$taxClassId = $this->taxClassProcessor->upsertTaxClass(0, $this->product);
120+
$this->assertEquals(0, $taxClassId);
121+
}
104122
}

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3526,4 +3526,42 @@ public function testImportInvalidAdditionalImages(): void
35263526
$errors->getErrorByRowNumber(0)[0]->getErrorMessage()
35273527
);
35283528
}
3529+
3530+
/**
3531+
* Test that product tax classes "none", "0" are imported correctly
3532+
*
3533+
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
3534+
* @magentoDataFixture Magento/Catalog/_files/second_product_simple.php
3535+
* @magentoAppIsolation enabled
3536+
*/
3537+
public function testImportProductWithTaxClassNone(): void
3538+
{
3539+
$pathToFile = __DIR__ . '/_files/product_tax_class_none_import.csv';
3540+
$importModel = $this->createImportModel($pathToFile);
3541+
$this->assertErrorsCount(0, $importModel->validateData());
3542+
$importModel->importData();
3543+
$simpleProduct = $this->getProductBySku('simple');
3544+
$this->assertSame('0', (string) $simpleProduct->getTaxClassId());
3545+
$simpleProduct = $this->getProductBySku('simple2');
3546+
$this->assertSame('0', (string) $simpleProduct->getTaxClassId());
3547+
}
3548+
3549+
/**
3550+
* @param int $count
3551+
* @param ProcessingErrorAggregatorInterface $errors
3552+
*/
3553+
private function assertErrorsCount(int $count, ProcessingErrorAggregatorInterface $errors): void
3554+
{
3555+
$this->assertEquals(
3556+
$count,
3557+
$errors->getErrorsCount(),
3558+
array_reduce(
3559+
$errors->getAllErrors(),
3560+
function ($output, $error) {
3561+
return "$output\n{$error->getErrorMessage()}";
3562+
},
3563+
''
3564+
)
3565+
);
3566+
}
35293567
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"sku","tax_class_name"
2+
"simple","none"
3+
"simple2","0"

0 commit comments

Comments
 (0)