How can I import related products via csv in Magento 2?
In my csv file I have a row with attribute related_skus with example data "11-111,22-222" for a product. But in admin Products->Catalog in this imported product the sidebar tab Related Products show no products although those products with skus exist in catalog.
Where can be the mistake?
-
Magento showed any errors? What's is your Import Behavior: Add/Update, Replace or Delete?Khoa Truong– Khoa Truong2016年05月18日 03:22:53 +00:00Commented May 18, 2016 at 3:22
-
No errors, import was successfully completed. Import Behavior was "Add/Update".Guest– Guest2016年05月18日 07:16:02 +00:00Commented May 18, 2016 at 7:16
-
You try to re-index your database?Khoa Truong– Khoa Truong2016年05月18日 07:24:27 +00:00Commented May 18, 2016 at 7:24
-
Yes, I used the command php bin/magento indexer:reindex and flushed the cache. I used pipe "|" as Multiple value separator and the example data was "11-111|22-222". Perhaps Magento doesn't support another multiple value separator for related_skus attribute?Guest– Guest2016年05月18日 07:31:10 +00:00Commented May 18, 2016 at 7:31
-
Have you been achieve to import your products now ?Nolwennig– Nolwennig2017年02月14日 15:36:08 +00:00Commented Feb 14, 2017 at 15:36
1 Answer 1
We've experienced the same issue, it seems import module has some kind of bug with related products
We've solved it by writing a new console command which expects a 2 columns (parent sku & children skus) related.csv file in var folder, with comma as csv separator, and pipe as children_skus separator
This are the files, if you want to try. You'd replace Sinapsis with your desired vendor name, and Sync with your desired module name
After installing the module, run bin/magento setup:upgrade & you'll see the new command if you check bin/magento list, which could be executed by running bin/magento sync:related
update
Since 2.2.* version, there are 2 changes required: an extra line before saving $product, to prevent issue reported here https://github.com/magento/magento2/issues/10687
$product->unsetData('media_gallery');
And changing admin to adminhtml in
$this->_appState->setAreaCode('adminhtml');
I think first change is innocuous for older versions, not the same for the second. So I have added only the first in below code
app / code / Sinapsis / Sync / etc / di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\Console\CommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="sync_related" xsi:type="object">Sinapsis\Sync\Console\Command\RelatedCommand</item>
</argument>
</arguments>
</type>
app / code / Sinapsis / Sync / etc / module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="module.xsd">
<module name="Sinapsis_Sync" setup_version="1.0.0">
</module>
app / code / Sinapsis / Sync / registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Sinapsis_Sync',
__DIR__
);
app / code / Sinapsis / Sync / Console / Command / RelatedCommand.php
<?php
namespace Sinapsis\Sync\Console\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\App\State as AppState;
use Magento\Framework\App\Filesystem\DirectoryList;
class RelatedCommand extends Command
{
const CSV_SEPARATOR = ',';
const CHILDREN_SEPARATOR = '|';
protected $_appState;
protected $_objectManager;
protected $_directorylist;
public function __construct(
DirectoryList $_directorylist,
AppState $appState,
ObjectManagerInterface $objectManager
) {
$this->_appState = $appState;
$this->_objectManager = $objectManager;
$this->_directorylist = $_directorylist;
parent::__construct();
}
protected function configure()
{
$this->setName('sync:related')
->setDescription('Synchronize catalog related products');
parent::configure();
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('<info>Starting process...<info>');
$output->writeln('');
$this->_appState->setAreaCode('admin');
$productRepository = $this->_objectManager->create('Magento\Catalog\Model\ProductRepository');
$output->writeln('<info>Loading csv content...<info>');
$output->writeln('');
$filePath = $this->_directorylist->getPath('var') . DIRECTORY_SEPARATOR . 'related.csv';
//@todo control Exception if file does not exist
$parseData = array();
if (($handle = fopen($filePath, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 0, self::CSV_SEPARATOR)) !== FALSE) {
$parseData[] = $data;
}
fclose($handle);
} else {
$output->writeln('<info>Could not read .csv file<info>');
return;
}
$headers = array_shift($parseData); // remove headers
foreach ($parseData as $row){
$skuParent = trim($row[0]);
$skuChildren = trim($row[1]);
$output->writeln('<info>Loading parent product ' . $skuParent . ' ... <info>');
try {
$product = $productRepository->get($skuParent);
} catch (\Magento\Framework\Exception\NoSuchEntityException $e){
$output->writeln('<info>Could not load!<info>');
continue;
}
$links = $product->getProductLinks();
$children = explode(self::CHILDREN_SEPARATOR, $skuChildren);
$i = 1;
foreach ($children as $skuChild){
$output->writeln('<info>Loading related product ' . $skuChild . ' ... <info>');
try {
$child = $productRepository->get($skuChild);
} catch (\Magento\Framework\Exception\NoSuchEntityException $e){
$output->writeln('<info>Could not load!<info>');
continue;
}
$productLink = $this->_objectManager->create('Magento\Catalog\Api\Data\ProductLinkInterface')
->setSku($skuParent)
->setLinkedProductSku($skuChild)
->setPosition($i)
->setLinkType('related');
$links[] = $productLink;
$i++;
}
$product->setProductLinks($links);
$product->unsetData('media_gallery');
$productRepository->save($product);
$output->writeln('<info>Relations saved for ' . $skuParent . '<info>');
}
$output->writeln('');
$output->writeln('<info>Done<info>');
}
}
-
is this code will work while creating new products but as far as i checked your code here you are adding related products to the existing parent sku.Hitesh Balpande– Hitesh Balpande2019年09月25日 14:17:33 +00:00Commented Sep 25, 2019 at 14:17
-
If you have any idea while creating parent sku only can we add some related/upsell/crossel skus to that product. Please suggest me thanks in Advance.Hitesh Balpande– Hitesh Balpande2019年09月25日 14:18:42 +00:00Commented Sep 25, 2019 at 14:18
Explore related questions
See similar questions with these tags.