Importação de CSV: Como posso importar produtos relacionados no Magento 2?

9

Como posso importar produtos relacionados via csv no Magento 2?

No meu arquivo csv, tenho uma linha com o atributo related_skus com dados de exemplo "11-111,22-222" para um produto. Mas em admin Produtos-> Catálogo deste produto importado, a guia da barra lateral Produtos Relacionados não mostra produtos, embora esses produtos com skus existam no catálogo.

Onde pode estar o erro?

Hóspede
fonte
Magento mostrou algum erro? Qual é o seu comportamento de importação: adicionar / atualizar, substituir ou excluir?
Khoa TruongDinh
Sem erros, a importação foi concluída com êxito. O comportamento de importação era "Adicionar / Atualizar".
Guest
Você tenta reindexar seu banco de dados?
Khoa TruongDinh
Sim, usei o comando php bin / magento indexer: reindex e limpei o cache. Eu usei cachimbo "|" como separador de valores múltiplos e os dados de exemplo foram "11-111 | 22-222". Talvez o Magento não suporte outro separador de múltiplos valores para o atributo related_skus ?
Guest
Você já conseguiu importar seus produtos agora?
Nolwennig

Respostas:

5

Tivemos o mesmo problema, parece que o módulo de importação tem algum tipo de erro com produtos relacionados

Resolvemos isso escrevendo um novo comando do console que espera um arquivo related.csv de duas colunas (sku pai e filhos skus) na pasta var , com vírgula como separador csv e canal como separador children_skus

Estes são os arquivos, se você quiser tentar. Você substituiria o Sinapsis pelo nome de fornecedor desejado e sincronizaria com o nome de módulo desejado

Depois de instalar o módulo, execute bin/magento setup:upgradee você verá o novo comando se verificar bin/magento list, o que pode ser executado executandobin/magento sync:related

atualizar

Desde a versão 2.2. *, São necessárias 2 alterações: uma linha extra antes de salvar $product, para evitar problemas reportados aqui https://github.com/magento/magento2/issues/10687

$product->unsetData('media_gallery');

E alterando admin para adminhtml em

$this->_appState->setAreaCode('adminhtml');

Eu acho que a primeira mudança é inócua para versões mais antigas, não é a mesma para a segunda. Então eu adicionei apenas o primeiro no código abaixo

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>');
    }
}
Raul Sanchez
fonte
Esse código funcionará durante a criação de novos produtos, mas, na medida em que verifiquei seu código aqui, você está adicionando produtos relacionados ao sku pai existente.
Hitesh Balpande
Se você tiver alguma idéia ao criar o sku principal, podemos adicionar alguns skus relacionados / de vendas adicionais / crossel a esse produto. Por favor, sugira-me obrigado antecipadamente.
Hitesh Balpande
Este código funcionou para mim, obrigado @Raul Sanchez
Hitesh Balpande