Programmatically Create configurable product in Magento 2.1 Issue

2k views Asked by At

I facing issue while creating configurable product in Magento 2.1 programmatically. I'm reading products from xml and save. The issue is when i associate simple product with configurable product. Products are created successfully. But configurable product associated products are not shown on backend. Here is my code:

<?php
/**
 * Created by PhpStorm.
 * User: Muhammad Noman Rauf
 * Date: 15/12/2016
 * Time: 1:15 AM
 */

use Magento\Framework\App\Bootstrap;

error_reporting(E_ALL);
ini_set("display_errors", 1);
if (file_exists('Export_Products_20170104_152014.xml')) {
    $content = simplexml_load_file('Export_Products_20170104_152014.xml', 'SimpleXMLElement', LIBXML_NOCDATA);

    include('app/bootstrap.php');
    $bootstrap = Bootstrap::create(BP, $_SERVER);

    $objectManager = $bootstrap->getObjectManager();

    $state = $objectManager->get('Magento\Framework\App\State');
    $state->setAreaCode('frontend');

    $_categoryFactory = $objectManager->get('Magento\Catalog\Model\CategoryFactory');

    $url = \Magento\Framework\App\ObjectManager::getInstance();

    $storeManager = $url->get('\Magento\Store\Model\StoreManagerInterface');
    $mediaurl = $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
/// Get Website ID
    $websiteId = $storeManager->getWebsite()->getWebsiteId();

/// Get Store ID
    $store = $storeManager->getStore();
    $storeId = $store->getStoreId();

/// Get Root Category ID
    $rootNodeId = $store->getRootCategoryId();

/// Get Root Category
    $rootCat = $objectManager->get('Magento\Catalog\Model\Category');
    $cat_info = $rootCat->load($rootNodeId);
    $product = $objectManager->get('Magento\Catalog\Model\Product');

    foreach ($content as $key => $value) {
        echo "<pre>";
        $_product = $objectManager->create('Magento\Catalog\Model\Product');

        //print_r($value->images);
        $sku = $value->ID;
        $name = $value->name;
        $description = $value->commercial_desc;
        $catgory = $value->category;
        $color = array();
        if (isset($value->prices) && !empty($value->prices)) {
            foreach ($value->prices->pricelist as $k => $v):
                $vn = (array)$v;
                ksort($vn);
                if ($vn['currency'] == 'EUR') {
                    $price = $vn['price'];
                }
            endforeach;
        }

        if (isset($value->images) && !empty($value->images)) {

            foreach ($value->images->img_url as $k => $v):
                $v;
            endforeach;
        }

        if (isset($value->colors) && !empty($value->colors)) {

            foreach ($value->colors->color as $k => $v):
                $color[] = $v->Description;

                foreach ($v->sizes->size as $sizes => $size) {
                    $s = $size->ID;
                }
                if (isset($v->images) && !empty($v->images->img_url)) {
                    foreach ($v->images->img_url as $imgs => $img) {
                        $color_img = $img;
                    }
                }

            endforeach;
        }
        $collection = $_categoryFactory->create()->getCollection()->addFieldToFilter('name', $catgory);

        if ($collection->getSize()) {
            $categoryId = $collection->getFirstItem()->getId();
            $categoryId;
        } else {
            $name = ucfirst($catgory);
            $url = strtolower($catgory);
            $cleanurl = trim(preg_replace('/ +/', '', preg_replace('/[^A-Za-z0-9 ]/', '', urldecode(html_entity_decode(strip_tags($url))))));
            /// Add a new sub category under root category
            $categoryTmp = $_categoryFactory->create();
            $categoryTmp->setName($name);
            $categoryTmp->setIsActive(true);
            $categoryTmp->setUrlKey($cleanurl);
            $categoryTmp->setData('description', $catgory);
            $categoryTmp->setParentId(2);
            $categoryTmp->setStoreId($storeId);
            $categoryTmp->setPath($rootCat->getPath());
            $categoryTmp->save();

            $categoryId = $categoryTmp->getId();
        }

        if ($product->getIdBySku($sku)) {
            echo "already in database " . $sku . " Please change name and sku in xml file.";
            continue;
        } else {

            /** @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepo */
            $attributeRepo = $objectManager->get(\Magento\Catalog\Api\ProductAttributeRepositoryInterface::class);
            $attribute = $attributeRepo->get('color');  // color should be in default attribute set

            $ids = [];
            $values = [];
            $_product->setName($name);
            $_product->setTypeId('configurable');
            $_product->setAttributeSetId(4);
            $_product->setSku($sku);
            $_product->setDescription($description);
            $_product->setShortDescription($description);
            $_product->setWebsiteIds(array($websiteId));
            $_product->setVisibility(4);
            $_product->setPrice($price);
            $_product->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
            $_product->setCategoryIds(array($categoryId));
            $_product->setImage('img1.jpg');
            $_product->setSmallImage('img1.jpg');
            $_product->setThumbnail('img1.jpg');
            $_product->setStockData(
                array(
                    'use_config_manage_stock' => 0, //'Use config settings' checkbox
                    'manage_stock' => 1, //manage stock
                    'min_sale_qty' => 1, //Minimum Qty Allowed in Shopping Cart
                    'max_sale_qty' => 2, //Maximum Qty Allowed in Shopping Cart
                    'is_in_stock' => 1, //Stock Availability
                    'qty' => 100 //qty
                )
            );

            $_product->save();
            foreach ($attribute->getOptions() as $option) {
                $label = $option->getLabel();

                if (in_array($label, $color)) {
                    $id = $option->getValue();
                    /** @var \Magento\Catalog\Api\Data\ProductInterface $p */
                    $p = $objectManager->create('Magento\Catalog\Model\Product');
                    $p->setSku($sku . '-' . $option->getLabel());
                    $p->setName($sku . '-' . $option->getLabel());
                    $p->setPrice($price);
                    $p->setTypeId('virtual');
                    $p->setColor($option->getValue());
                    $p->setWebsiteIds(array($websiteId));
                    $p->setCategoryIds(array($categoryId));
                    $p->setAttributeSetID($id);
                    $p->setVisibility(Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE);
                    $p->setAttributeSetId(4);
                    $p->save();
                    $ids[] = $p->getId();
                    /** @var \Magento\ConfigurableProduct\Api\Data\OptionValueInterface $opVal */
                    $opVal = $objectManager->create(\Magento\ConfigurableProduct\Api\Data\OptionValueInterface::class);
                    $opVal->setValueIndex($id);
                    $values[] = $opVal;
                }
            }

            /* IF CODE NOT WORKED PLEASE REMOVE THIS CODE : START REMOVE*/

            $pro = $objectManager->create('Magento\Catalog\Model\Product')->load($_product->getId()); // Load Configurable Product
            $attributeModel = $objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute');
            $position = 0;
            $attributes = array($attribute->getAttributeId()); // Super Attribute Ids Used To Create Configurable Product
            foreach ($attributes as $attributeId) {
                $data = array('attribute_id' => $attributeId, 'product_id' => $_product->getId(), 'position' => $position);
                $position++;
                $attributeModel->setData($data)->save();
            }
            $pro->setTypeId("configurable"); // Setting Product Type As Configurable
            $pro->setAffectConfigurableProductAttributes(4);
            $objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable')->setUsedProductAttributeIds($attributes, $pro);
            $pro->setNewVariationsAttributeSetId(4); // Setting Attribute Set Id
            $pro->setAssociatedProductIds($ids);// Setting Associated Products
            $pro->setCanSaveConfigurableAttributes(true);
            $pro->save();

            /* IF CODE NOT WORKED PLEASE REMOVE THIS CODE : END REMOVE*/

            echo "New Product id:" . $_product->getId() . '<br>';

        }

        //print_r($_product->getData());
    }

} else {
    exit('Failed to open xml.');
}

I also followed other solution but can't find any solution.

link 1

link2

link3

1

There are 1 answers

0
Andrew On

Do not forget to use store id in your import. Set store ID "0".

public function setConfigurable_oldfunc($config_id,$simple_prod_id){

    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();

    $storeManager = $objectManager->get('Magento\Store\Model\StoreManagerInterface');
    $store = $storeManager->getStore(0);
    $storeManager->setCurrentStore($store->getCode());

    $productId = $config_id; // Configurable Product Id
    $product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId); // Load Configurable Product
    $attributeModel = $objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute');
    $position = 0;
    $attributes = array(160); // Super Attribute Ids Used To Create Configurable Product

    $associatedProductIds = array($simple_prod_id);

    $optionsData = $product->getTypeInstance(true)->getUsedProducts($product);
    $array_ids = array();

    if(is_array($array_ids) && !empty($array_ids)){

    }else{
        foreach ($attributes as $attributeId) {
            $data = array('attribute_id' => $attributeId, 'product_id' => $productId, 'position' => $position);
            $position++;
            $attributeModel->setData($data)->save();
        }

    }
    $objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable')->setUsedProductAttributeIds($attributes, $product);
    $product->setTypeId("configurable"); // Setting Product Type As Configurable
    $product->setAffectConfigurableProductAttributes(4);
    $product->setNewVariationsAttributeSetId(4); // Setting Attribute Set Id
    $product->setAssociatedProductIds($associatedProductIds);// Setting Associated Products
    $product->setCanSaveConfigurableAttributes(true);
    $product->setStoreId(0);
    $product->save();


}