Skip to content

Commit

Permalink
Merge pull request #8685 from magento-l3/Tier4-Kings-PR-12-18-2023
Browse files Browse the repository at this point in the history
Tier4 Kings PR Delivery 12.18.2023
  • Loading branch information
2 parents 59b2921 + ee2cf8c commit e53e613
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 25 deletions.
38 changes: 26 additions & 12 deletions app/code/Magento/CatalogImportExport/Model/Import/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
class Product extends AbstractEntity
{
private const COL_NAME_FORMAT = '/[\x00-\x1F\x7F]/';
private const DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR = ',';
public const CONFIG_KEY_PRODUCT_TYPES = 'global/importexport/import_product_types';

/**
Expand Down Expand Up @@ -939,7 +938,7 @@ public function __construct(
$this->_optionEntity = $data['option_entity'] ??
$optionFactory->create(['data' => ['product_entity' => $this]]);
$this->skuStorage = $skuStorage ?? ObjectManager::getInstance()
->get(SkuStorage::class);
->get(SkuStorage::class);
$this->_initAttributeSets()
->_initTypeModels()
->_initSkus()
Expand All @@ -949,7 +948,7 @@ public function __construct(
$this->productRepository = $productRepository ?? ObjectManager::getInstance()
->get(ProductRepositoryInterface::class);
$this->stockItemProcessor = $stockItemProcessor ?? ObjectManager::getInstance()
->get(StockItemProcessorInterface::class);
->get(StockItemProcessorInterface::class);
}

/**
Expand Down Expand Up @@ -2837,7 +2836,7 @@ private function prepareNewSkuData($sku)
*
* @return array
*/
private function _parseAdditionalAttributes($rowData)
private function _parseAdditionalAttributes(array $rowData): array
{
if (empty($rowData['additional_attributes'])) {
return $rowData;
Expand All @@ -2847,7 +2846,7 @@ private function _parseAdditionalAttributes($rowData)
$rowData[mb_strtolower($key)] = $value;
}
} else {
$rowData = array_merge($rowData, $this->getAdditionalAttributes($rowData['additional_attributes']));
$rowData = array_merge($rowData, $this->getAdditionalAttributes($rowData));
}
return $rowData;
}
Expand All @@ -2861,14 +2860,14 @@ private function _parseAdditionalAttributes($rowData)
* codeN => valueN
* ]
*
* @param string $additionalAttributes Attributes data that will be parsed
* @param array $rowData
* @return array
*/
private function getAdditionalAttributes($additionalAttributes)
private function getAdditionalAttributes(array $rowData): array
{
return empty($this->_parameters[Import::FIELDS_ENCLOSURE])
? $this->parseAttributesWithoutWrappedValues($additionalAttributes)
: $this->parseAttributesWithWrappedValues($additionalAttributes);
? $this->parseAttributesWithoutWrappedValues($rowData['additional_attributes'], $rowData['product_type'])
: $this->parseAttributesWithWrappedValues($rowData['additional_attributes']);
}

/**
Expand All @@ -2882,9 +2881,10 @@ private function getAdditionalAttributes($additionalAttributes)
*
* @param string $attributesData Attributes data that will be parsed. It keeps data in format:
* code=value,code2=value2...,codeN=valueN
* @param string $productType
* @return array
*/
private function parseAttributesWithoutWrappedValues($attributesData)
private function parseAttributesWithoutWrappedValues(string $attributesData, string $productType): array
{
$attributeNameValuePairs = explode($this->getMultipleValueSeparator(), $attributesData);
$preparedAttributes = [];
Expand All @@ -2900,6 +2900,17 @@ private function parseAttributesWithoutWrappedValues($attributesData)
}
list($code, $value) = explode(self::PAIR_NAME_VALUE_SEPARATOR, $attributeData, 2);
$code = mb_strtolower($code);

$entityTypeModel = $this->retrieveProductTypeByName($productType);
if ($entityTypeModel) {
$attrParams = $entityTypeModel->retrieveAttributeFromCache($code);
if (!empty($attrParams) && $attrParams['type'] == 'multiselect') {
$parsedValue = $this->parseMultiselectValues($value, self::PSEUDO_MULTI_LINE_SEPARATOR);
if (count($parsedValue) > 1) {
$value = $parsedValue;
}
}
}
$preparedAttributes[$code] = $value;
}
return $preparedAttributes;
Expand Down Expand Up @@ -2949,10 +2960,13 @@ private function parseAttributesWithWrappedValues($attributesData)
* @return array
* @since 100.1.2
*/
public function parseMultiselectValues($values, $delimiter = self::PSEUDO_MULTI_LINE_SEPARATOR)
public function parseMultiselectValues($values, $delimiter = '')
{
if (empty($this->_parameters[Import::FIELDS_ENCLOSURE])) {
if ($this->getMultipleValueSeparator() !== self::DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR) {
if (is_array($values)) {
return $values;
}
if (!$delimiter) {
$delimiter = $this->getMultipleValueSeparator();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected function setUp(): void
$entityTypeModel->expects($this->any())->method('retrieveAttributeFromCache')->willReturn([]);
$this->context = $this->createPartialMock(
Product::class,
['retrieveProductTypeByName', 'retrieveMessageTemplate', 'getBehavior']
['retrieveProductTypeByName', 'retrieveMessageTemplate', 'getBehavior', 'getMultipleValueSeparator']
);
$this->context->expects($this->any())->method('retrieveProductTypeByName')->willReturn($entityTypeModel);
$this->context->expects($this->any())->method('retrieveMessageTemplate')->willReturn('error message');
Expand Down Expand Up @@ -83,6 +83,7 @@ protected function setUp(): void
*/
public function testAttributeValidation($behavior, $attrParams, $rowData, $isValid, $attrCode = 'attribute_code')
{
$this->context->method('getMultipleValueSeparator')->willReturn(Product::PSEUDO_MULTI_LINE_SEPARATOR);
$this->context->expects($this->any())->method('getBehavior')->willReturn($behavior);
$result = $this->validator->isAttributeValid(
$attrCode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\CatalogInventory\Model\Spi\StockStateProviderInterface;
use Magento\ConfigurableImportExport\Model\Import\Product\Type\Configurable;
use Magento\Eav\Model\Config;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
use Magento\Eav\Model\Entity\Attribute\Set;
Expand Down Expand Up @@ -1471,18 +1472,32 @@ public function testGetImagesFromRow($rowData, $expectedResult): void
*/
public function testParseAttributesWithoutWrappedValuesWillReturnsLowercasedAttributeCodes(): void
{
$attributesData = 'PARAM1=value1,param2=value2';
$entityTypeModel = $this->createPartialMock(
Configurable::class,
['retrieveAttributeFromCache']
);
$entityTypeModel->expects($this->exactly(2))->method('retrieveAttributeFromCache')->willReturn([
'type' => 'multiselect'
]);
$importProduct = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['retrieveProductTypeByName'])
->getMock();
$importProduct->expects($this->exactly(2))->method('retrieveProductTypeByName')->willReturn($entityTypeModel);

$attributesData = 'PARAM1=value1,param2=value2|value3';
$preparedAttributes = $this->invokeMethod(
$this->importProduct,
$importProduct,
'parseAttributesWithoutWrappedValues',
[$attributesData]
[$attributesData, 'configurable']
);

$this->assertArrayHasKey('param1', $preparedAttributes);
$this->assertEquals('value1', $preparedAttributes['param1']);

$this->assertArrayHasKey('param2', $preparedAttributes);
$this->assertEquals('value2', $preparedAttributes['param2']);
$this->assertEquals('value2', $preparedAttributes['param2'][0]);
$this->assertEquals('value3', $preparedAttributes['param2'][1]);

$this->assertArrayNotHasKey('PARAM1', $preparedAttributes);
}
Expand Down Expand Up @@ -1684,7 +1699,7 @@ public function productCategoriesDataProvider()
],
'catalog_category_product',
[
[2, 5],
[2, 5],
[
[
'product_id' => 2,
Expand Down Expand Up @@ -2191,4 +2206,57 @@ protected function createModelMockWithErrorAggregator(

return $importProduct;
}

/**
* @dataProvider valuesDataProvider
*/
public function testParseMultiselectValues($value, $fieldSeparator, $valueSeparator)
{
$this->importProduct->setParameters(
[
Import::FIELD_FIELD_SEPARATOR => $fieldSeparator,
Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR => $valueSeparator
]
);
$this->assertEquals(explode($valueSeparator, $value), $this->importProduct->parseMultiselectValues($value));
}

/**
* @return array
*/
public function valuesDataProvider(): array
{
return [
'pipeWithCustomFieldSeparator' => [
'value' => 'L|C|D|T|H',
'fieldSeparator' => ';',
'valueSeparator' => '|'
],
'commaWithCustomFieldSeparator' => [
'value' => 'L,C,D,T,H',
'fieldSeparator' => ';',
'valueSeparator' => ','
],
'pipeWithDefaultFieldSeparator' => [
'value' => 'L|C|D|T|H',
'fieldSeparator' => ',',
'valueSeparator' => '|'
],
'commaWithDefaultFieldSeparator' => [
'value' => 'L,C,D,T,H',
'fieldSeparator' => ',',
'valueSeparator' => ','
],
'anonymousValueSeparatorWithDefaultFieldSeparator' => [
'value' => 'L+C+D+T+H',
'fieldSeparator' => ',',
'valueSeparator' => '+'
],
'anonymousValueSeparatorWithDefaultFieldSeparatorAndSingleValue' => [
'value' => 'L',
'fieldSeparator' => ',',
'valueSeparator' => '*'
]
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public function collectRates(RateRequest $request)
if ($item->getHasChildren() && $item->isShipSeparately()) {
foreach ($item->getChildren() as $child) {
if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
$freeShipping = is_numeric($child->getFreeShipping()) ? $child->getFreeShipping() : 0;
$freeShipping = (int)$child->getFreeShipping();
$freeQty += $item->getQty() * ($child->getQty() - $freeShipping);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,11 @@ protected function setUp(): void

/**
* @param bool $freeshipping
* @param bool $isShipSeparately
* @dataProvider collectRatesWithGlobalFreeShippingDataProvider
* @return void
*/
public function testCollectRatesWithGlobalFreeShipping($freeshipping)
public function testCollectRatesWithGlobalFreeShipping($freeshipping, $isShipSeparately)
{
$rate = [
'price' => 15,
Expand Down Expand Up @@ -177,11 +178,17 @@ public function testCollectRatesWithGlobalFreeShipping($freeshipping)
$this->resultFactoryMock->expects($this->once())->method('create')->willReturn($result);

$product->expects($this->any())->method('isVirtual')->willReturn(false);

$item->expects($this->any())->method('getProduct')->willReturn($product);
$item->expects($this->any())->method('getFreeShipping')->willReturn(1);
$item->expects($this->any())->method('getQty')->willReturn(1);

if ($isShipSeparately) {
$freeShippingReturnValue = true;
$item->expects($this->any())->method('getHasChildren')->willReturn(1);
$item->expects($this->any())->method('isShipSeparately')->willReturn(1);
$item->expects($this->any())->method('getChildren')->willReturn([$item]);
} else {
$freeShippingReturnValue = "1";
}
$item->expects($this->any())->method('getFreeShipping')->willReturn($freeShippingReturnValue);
$request->expects($this->any())->method('getAllItems')->willReturn([$item]);
$request->expects($this->any())->method('getPackageQty')->willReturn(1);

Expand Down Expand Up @@ -225,8 +232,9 @@ private function captureArg(&$captureVar)
public function collectRatesWithGlobalFreeShippingDataProvider()
{
return [
['freeshipping' => true],
['freeshipping' => false]
['freeshipping' => true, 'isShipSeparately' => false],
['freeshipping' => false, 'isShipSeparately' => false],
['freeshipping' => true, 'isShipSeparately' => true]
];
}
}

0 comments on commit e53e613

Please sign in to comment.