Skip to content

Commit afdd66f

Browse files
author
Oleksii Korshenko
authored
Merge pull request #788 from magento-okapis/MAGETWO-55237-import_config_product
[Okapis] MAGETWO-55237: import config product
2 parents 5d1e030 + bcd898c commit afdd66f

File tree

6 files changed

+208
-20
lines changed

6 files changed

+208
-20
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ protected function _saveProductAttributes(array $attributesData)
12491249
$linkId = $this->_connection->fetchOne(
12501250
$this->_connection->select()
12511251
->from($this->getResource()->getTable('catalog_product_entity'))
1252-
->where('sku = ?', $sku)
1252+
->where('sku = ?', (string)$sku)
12531253
->columns($this->getProductEntityLinkField())
12541254
);
12551255

dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ public function exportImportDataProvider()
2121
],
2222
['_cache_instance_products', '_cache_instance_configurable_attributes'],
2323
],
24+
'configurable-product-12345' => [
25+
[
26+
'Magento/ConfigurableProduct/_files/product_configurable_12345.php'
27+
],
28+
[
29+
'12345',
30+
],
31+
['_cache_instance_products', '_cache_instance_configurable_attributes'],
32+
],
2433
];
2534
}
2635

dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/Import/Product/Type/ConfigurableTest.php

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515
*/
1616
class ConfigurableTest extends \PHPUnit_Framework_TestCase
1717
{
18-
/**
19-
* Configurable product test Name
20-
*/
21-
const TEST_PRODUCT_NAME = 'Configurable 1';
22-
2318
/**
2419
* Configurable product test Type
2520
*/
@@ -30,13 +25,6 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
3025
*/
3126
protected $model;
3227

33-
/**
34-
* Configurable product options SKU list
35-
*
36-
* @var array
37-
*/
38-
protected $optionSkuList = ['Configurable 1-Option 1', 'Configurable 1-Option 2'];
39-
4028
/**
4129
* @var \Magento\Framework\ObjectManagerInterface
4230
*/
@@ -56,14 +44,32 @@ protected function setUp()
5644
$this->productMetadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
5745
}
5846

47+
public function configurableImportDataProvider()
48+
{
49+
return [
50+
'Configurable 1' => [
51+
__DIR__ . '/../../_files/import_configurable.csv',
52+
'Configurable 1',
53+
['Configurable 1-Option 1', 'Configurable 1-Option 2'],
54+
],
55+
'12345' => [
56+
__DIR__ . '/../../_files/import_configurable_12345.csv',
57+
'12345',
58+
['Configurable 1-Option 1', 'Configurable 1-Option 2'],
59+
],
60+
];
61+
}
62+
5963
/**
64+
* @param $pathToFile Path to import file
65+
* @param $productName Name/sku of configurable product
66+
* @param $optionSkuList Name of variations for configurable product
6067
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
6168
* @magentoAppArea adminhtml
69+
* @dataProvider configurableImportDataProvider
6270
*/
63-
public function testConfigurableImport()
71+
public function testConfigurableImport($pathToFile, $productName, $optionSkuList)
6472
{
65-
// import data from CSV file
66-
$pathToFile = __DIR__ . '/../../_files/import_configurable.csv';
6773
$filesystem = $this->objectManager->create(
6874
\Magento\Framework\Filesystem::class
6975
);
@@ -90,23 +96,23 @@ public function testConfigurableImport()
9096

9197
/** @var \Magento\Catalog\Model\ResourceModel\Product $resource */
9298
$resource = $this->objectManager->get(\Magento\Catalog\Model\ResourceModel\Product::class);
93-
$productId = $resource->getIdBySku(self::TEST_PRODUCT_NAME);
99+
$productId = $resource->getIdBySku($productName);
94100
$this->assertTrue(is_numeric($productId));
95101
/** @var \Magento\Catalog\Model\Product $product */
96102
$product = $this->objectManager->get(ProductRepositoryInterface::class)->getById($productId);
97103

98104
$this->assertFalse($product->isObjectNew());
99-
$this->assertEquals(self::TEST_PRODUCT_NAME, $product->getName());
105+
$this->assertEquals($productName, $product->getName());
100106
$this->assertEquals(self::TEST_PRODUCT_TYPE, $product->getTypeId());
101107

102108
$optionCollection = $product->getTypeInstance()->getConfigurableOptions($product);
103109
foreach ($optionCollection as $option) {
104110
foreach ($option as $optionData) {
105-
$this->assertContains($optionData['sku'], $this->optionSkuList);
111+
$this->assertContains($optionData['sku'], $optionSkuList);
106112
}
107113
}
108114

109-
$optionIdList = $resource->getProductsIdsBySkus($this->optionSkuList);
115+
$optionIdList = $resource->getProductsIdsBySkus($optionSkuList);
110116
foreach ($optionIdList as $optionId) {
111117
$this->assertArrayHasKey($optionId, $product->getExtensionAttributes()->getConfigurableProductLinks());
112118
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
sku,store_view_code,attribute_set_code,product_type,name,description,short_description,weight,product_online,tax_class_name,visibility,price,url_key,display_product_options_in,map_price,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,configurable_variations,configurable_variation_labels,associated_skus
2+
Configurable 1-Option 1,,Default,simple,Configurable 1-Option 1,,,,1,Taxable Goods,Not Visible Individually,10,configurable-1-option-1,Block after Info Column,,"attribute_with_option=Option Label,has_options=0,quantity_and_stock_status=In Stock,required_options=0,test_configurable=Option 1",99999,0,0,0,0,1,1,0,0,0,1,,1,1,0,0,1,0,0,0,1,,,
3+
Configurable 1-Option 2,,Default,simple,Configurable 1-Option 2,,,,1,Taxable Goods,Not Visible Individually,10,configurable-1-option-2,Block after Info Column,,"has_options=0,quantity_and_stock_status=In Stock,required_options=0,test_configurable=Option 2",99999,0,0,0,0,1,1,0,0,0,1,,1,1,0,0,1,0,0,0,1,,,
4+
12345,,Default,configurable,12345,,,,1,Taxable Goods,"Catalog, Search",10,12345,Block after Info Column,,"has_options=1,quantity_and_stock_status=In Stock,required_options=0",0,0,0,0,0,1,1,0,0,0,1,,1,0,0,0,1,0,0,0,1,"sku=Configurable 1-Option 1,test_configurable=Option 1|sku=Configurable 1-Option 2,test_configurable=Option 2",test_configurable=test_configurable,
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\ProductRepositoryInterface;
8+
use Magento\Catalog\Model\Product;
9+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
10+
use Magento\Catalog\Model\Product\Type;
11+
use Magento\Catalog\Model\Product\Visibility;
12+
use Magento\Catalog\Setup\CategorySetup;
13+
use Magento\ConfigurableProduct\Helper\Product\Options\Factory;
14+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
15+
use Magento\Eav\Api\Data\AttributeOptionInterface;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
18+
\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
19+
20+
require __DIR__ . '/configurable_attribute.php';
21+
22+
/** @var ProductRepositoryInterface $productRepository */
23+
$productRepository = Bootstrap::getObjectManager()
24+
->create(ProductRepositoryInterface::class);
25+
26+
/** @var $installer CategorySetup */
27+
$installer = Bootstrap::getObjectManager()->create(CategorySetup::class);
28+
29+
/* Create simple products per each option value*/
30+
/** @var AttributeOptionInterface[] $options */
31+
$options = $attribute->getOptions();
32+
33+
$attributeValues = [];
34+
$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default');
35+
$associatedProductIds = [];
36+
$productIds = [30, 40];
37+
array_shift($options); //remove the first option which is empty
38+
39+
foreach ($options as $option) {
40+
/** @var $product Product */
41+
$product = Bootstrap::getObjectManager()->create(Product::class);
42+
$productId = array_shift($productIds);
43+
$product->setTypeId(Type::TYPE_SIMPLE)
44+
->setId($productId)
45+
->setAttributeSetId($attributeSetId)
46+
->setWebsiteIds([1])
47+
->setName('Configurable Option' . $option->getLabel())
48+
->setSku('simple_' . $productId)
49+
->setPrice($productId)
50+
->setTestConfigurable($option->getValue())
51+
->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE)
52+
->setStatus(Status::STATUS_ENABLED)
53+
->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]);
54+
55+
$product = $productRepository->save($product);
56+
57+
/** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */
58+
$stockItem = Bootstrap::getObjectManager()->create(\Magento\CatalogInventory\Model\Stock\Item::class);
59+
$stockItem->load($productId, 'product_id');
60+
61+
if (!$stockItem->getProductId()) {
62+
$stockItem->setProductId($productId);
63+
}
64+
$stockItem->setUseConfigManageStock(1);
65+
$stockItem->setQty(1000);
66+
$stockItem->setIsQtyDecimal(0);
67+
$stockItem->setIsInStock(1);
68+
$stockItem->save();
69+
70+
$attributeValues[] = [
71+
'label' => 'test',
72+
'attribute_id' => $attribute->getId(),
73+
'value_index' => $option->getValue(),
74+
];
75+
$associatedProductIds[] = $product->getId();
76+
}
77+
78+
/** @var $product Product */
79+
$product = Bootstrap::getObjectManager()->create(Product::class);
80+
81+
/** @var Factory $optionsFactory */
82+
$optionsFactory = Bootstrap::getObjectManager()->create(Factory::class);
83+
84+
$configurableAttributesData = [
85+
[
86+
'attribute_id' => $attribute->getId(),
87+
'code' => $attribute->getAttributeCode(),
88+
'label' => $attribute->getStoreLabel(),
89+
'position' => '0',
90+
'values' => $attributeValues,
91+
],
92+
];
93+
94+
$configurableOptions = $optionsFactory->create($configurableAttributesData);
95+
96+
$extensionConfigurableAttributes = $product->getExtensionAttributes();
97+
$extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions);
98+
$extensionConfigurableAttributes->setConfigurableProductLinks($associatedProductIds);
99+
100+
$product->setExtensionAttributes($extensionConfigurableAttributes);
101+
102+
// Remove any previously created product with the same id.
103+
/** @var \Magento\Framework\Registry $registry */
104+
$registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
105+
$registry->unregister('isSecureArea');
106+
$registry->register('isSecureArea', true);
107+
try {
108+
$productToDelete = $productRepository->getById(11);
109+
$productRepository->delete($productToDelete);
110+
111+
/** @var \Magento\Quote\Model\ResourceModel\Quote\Item $itemResource */
112+
$itemResource = Bootstrap::getObjectManager()->get(\Magento\Quote\Model\ResourceModel\Quote\Item::class);
113+
$itemResource->getConnection()->delete(
114+
$itemResource->getMainTable(),
115+
'product_id = ' . $productToDelete->getId()
116+
);
117+
} catch (\Exception $e) {
118+
// Nothing to remove
119+
}
120+
$registry->unregister('isSecureArea');
121+
$registry->register('isSecureArea', false);
122+
123+
$product->setTypeId(Configurable::TYPE_CODE)
124+
->setId(11)
125+
->setAttributeSetId($attributeSetId)
126+
->setWebsiteIds([1])
127+
->setName('Configurable Product 12345')
128+
->setSku('12345')
129+
->setVisibility(Visibility::VISIBILITY_BOTH)
130+
->setStatus(Status::STATUS_ENABLED)
131+
->setStockData(['use_config_manage_stock' => 1, 'is_in_stock' => 1]);
132+
133+
$productRepository->save($product);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
8+
9+
/** @var \Magento\Framework\Registry $registry */
10+
$registry = $objectManager->get(\Magento\Framework\Registry::class);
11+
12+
$registry->unregister('isSecureArea');
13+
$registry->register('isSecureArea', true);
14+
15+
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
16+
$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
17+
->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
18+
19+
foreach (['simple_30', 'simple_40', '12345'] as $sku) {
20+
try {
21+
$product = $productRepository->get($sku, false, null, true);
22+
23+
$stockStatus = $objectManager->create(\Magento\CatalogInventory\Model\Stock\Status::class);
24+
$stockStatus->load($product->getEntityId(), 'product_id');
25+
$stockStatus->delete();
26+
27+
$productRepository->delete($product);
28+
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
29+
//Product already removed
30+
}
31+
}
32+
33+
require __DIR__ . '/configurable_attribute_rollback.php';
34+
35+
$registry->unregister('isSecureArea');
36+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)