Importar CSV: ¿Cómo puedo importar productos relacionados en Magento 2?

9

¿Cómo puedo importar productos relacionados a través de csv en Magento 2?

En mi archivo csv tengo una fila con el atributo related_skus con datos de ejemplo "11-111,22-222" para un producto. Pero en admin Productos-> Catálogo en este producto importado, la pestaña de la barra lateral Productos relacionados no muestra productos, aunque existen productos con skus en el catálogo.

¿Dónde puede estar el error?

Invitado
fuente
Magento mostró algún error? ¿Cuál es su comportamiento de importación: Agregar / Actualizar, Reemplazar o Eliminar?
Khoa TruongDinh
Sin errores, la importación se completó con éxito. El comportamiento de importación fue "Agregar / Actualizar".
Invitado
¿Intentas volver a indexar tu base de datos?
Khoa TruongDinh
Sí, utilicé el comando php bin / magento indexer: reindex y enjuagué el caché. Usé la pipa "|" como separador de valores múltiples y los datos de ejemplo fueron "11-111 | 22-222". ¿Quizás Magento no admite otro separador de valores múltiples para el atributo related_skus ?
Invitado
¿Ha logrado importar sus productos ahora?
Nolwennig

Respuestas:

5

Hemos experimentado el mismo problema, parece que el módulo de importación tiene algún tipo de error con productos relacionados

Lo hemos resuelto escribiendo un nuevo comando de consola que espera un archivo relacionado.csv de 2 columnas (sku primario y skus secundario) en la carpeta var , con una coma como separador csv y una tubería como separador children_skus

Estos son los archivos, si quieres probar. Reemplazaría Sinapsis con el nombre del proveedor deseado y Sync con el nombre del módulo deseado

Después de instalar el módulo, ejecute bin/magento setup:upgradey verá el nuevo comando si marca bin/magento list, que podría ejecutarse ejecutandobin/magento sync:related

actualizar

Desde la versión 2.2. *, Se requieren 2 cambios: una línea adicional antes de guardar $product, para evitar problemas reportados aquí https://github.com/magento/magento2/issues/10687

$product->unsetData('media_gallery');

Y cambiando admin a adminhtml en

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

Creo que el primer cambio es inocuo para versiones anteriores, no es lo mismo para el segundo. Así que he agregado solo el primero en el siguiente código

aplicación / código / 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>

aplicación / código / 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>');
    }
}
Raúl Sánchez
fuente
es que este código funcionará al crear nuevos productos, pero en la medida en que verifiqué su código aquí, está agregando productos relacionados al sku principal existente.
Hitesh Balpande
Si tiene alguna idea al crear sku padre solo podemos agregar algunos skus relacionados / upsell / crossel a ese producto. Por favor sugiérame gracias de antemano.
Hitesh Balpande
Este código funcionó para mí, gracias @Raul Sanchez
Hitesh Balpande