8

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 TruongDinh May 18 '16 at 3:22
  • No errors, import was successfully completed. Import Behavior was "Add/Update". – Guest May 18 '16 at 7:16
  • You try to re-index your database? – Khoa TruongDinh May 18 '16 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 May 18 '16 at 7:31
  • Have you been achieve to import your products now ? – Nolwennig Feb 14 '17 at 15:36
4

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>');
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.