magento2 – Configurable Product Programmatically Configurations is Empty

configurable-productmagento2programmatically

I am trying to import products from a .csv file and am almost there but I have an issue with the catalog_product_super_link

  • Simple Products Created correctly with correct attribute values
  • Configurable Product created WITHOUT associated products (configurations tab is empty)

Debugging: If I manually edit the table catalog_product_super_link, and add the relation product_id, parent_id, the configurationstab is filled

Sample data:

        //sample test run data
        $param_product['Code'] = 'testCode2';
        $param_product['Name'] = 'Test-name2';
        $param_product['Weight'] = '0.2000';
        $param_product['Price'] = '220';
        $param_product['Brand'] = 'DSQUARED2';
        $param_product['Color'] = 'BLACK~51/RED~49/ROYAL~546/WHITE~54';
        $param_product['Size'] = 'S/M/L/XL/2XL';
        $param_product['ColorArray'] = explode('/', $param_product['Color']);
        $param_product['SizeArray'] = explode('/', $param_product['Size']);

Create Simple product:

protected function createSimpleProduct($param_product) {
        $simple_product = $this->_objectManager->create('Magento\Catalog\Model\Product');
        //init values
        $attribute_set_id = 16;
        //set product settings
        $sku = $param_product['Code'];
        $name = $param_product['Name'];
        //$weight = $param_product['Weight'];
        //$price = $param_product['Price'];
        $weight = ($param_product['Weight'] == 0) ? '0.0000' : $param_product['Weight'];
        $price = ($param_product['Price'] == 0) ? '0' : $param_product['Price'];

        //skip if name or sku is empty -> probs a false line
        if($sku == '' || $name =='') {
            return false;
        }
        //add simple product postfixes for url rewrite and duplicates issues
        $sku_postfix = $this->getPostfix($param_product['Color'], $param_product['Size']);
        $sku .= $sku_postfix;
        $name .= $sku_postfix;
        if($simple_product->getIdBySku($sku)) {
            echo 'Product already exists! Skipping...' . "$sku \n";
            return false;
        }

        // $simple_product = $this->_objectManager->create('\Magento\Catalog\Model\Product');
        $simple_product->setSku($sku);
        $simple_product->setName($name);
        $simple_product->setAttributeSetId($attribute_set_id);
        $simple_product->setStatus(0);
        $simple_product->setTypeId('simple');
        $simple_product->setWebsiteIds(array(1));
        $simple_product->setCategoryIds($param_product['categoriesArray']);
        $simple_product->setWeight($weight);
        $simple_product->setPrice($price);
        $simple_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
                        )
                    );

        //set attributes
        //designer, color, size
        $designer = ($param_product['Brand'] == '') ? 'n/a' : $param_product['Brand'];
        $designers_attribute = $this->_c2gmoduleHelper->createOrGetId('designers', $designer);
        $simple_product->setDesigners($designers_attribute); // value id of S size
        //color
        $_pro_color = ($param_product['Color'] == '') ? 'n/a' : $param_product['Color'];
        $_pro_color = explode('~', $_pro_color);
        $_pro_color = $_pro_color[0];
        $color_attribute = $this->_c2gmoduleHelper->createOrGetId('color', $_pro_color);
        $simple_product->setColor($color_attribute); // value id of Beige Color
        //size
        $_pro_size = ($param_product['Size'] == '') ? 'n/a' : $param_product['Size'];
        $size_attribute = $this->_c2gmoduleHelper->createOrGetId('size', $_pro_size);
        $simple_product->setSize($size_attribute); // value id of S size


        $simple_product->save();

        $simple_product_id = $simple_product->getId();

        //create configurations for configurable product
        $configurableProductsData = array();
        $configurableProductsData[$simple_product_id] = array( //[$simple_product_id] = id of a simple product associated with this configurable
            '0' => array(
                'label' => 'Beige', //attribute label
                'attribute_id' => '93', //attribute ID of attribute 'color' in my store
                'value_index' => $color_attribute, //value of 'Beige' index of the attribute 'color'
                'is_percent'    => 0,
                'pricing_value' => '10',
            ),
            '1' => array(
                'label' => $param_product['Size'], //attribute label
                'attribute_id' => '141', //attribute ID of attribute 'size' in my store
                'value_index' => $size_attribute, //value of 'S' index of the attribute 'size'
                'is_percent'    => 0,
                'pricing_value' => '10',
            ),
        );

        $allInOne['associated_pro_id'] = $simple_product_id;
        $allInOne['configurableProductsData'] = $configurableProductsData;

        echo 'simple product id: ' . "$simple_product_id sku: $sku\n";
        return $allInOne;
    }

and create configurable product:

protected function createConfigurableProduct($param_product, $associatedProductsAttributesArray) {
        //init values
        $attribute_set_id = 16;
        //set product settings
        $sku = $param_product['Code'];
        $name = $param_product['Name'];
        //$weight = $param_product['Weight'];
        //$price = $param_product['Price'];
        $weight = ($param_product['Weight'] == 0) ? '0.0000' : $param_product['Weight'];
        $price = ($param_product['Price'] == 0) ? '0' : $param_product['Price'];

        //configurable product
        $configurable_product = $this->_objectManager->create('\Magento\Catalog\Model\Product');
        //skip if name or sku is empty -> probs a false line
        if($sku == '' || $name =='') {
            return false;
        }
        if($configurable_product->getIdBySku($sku)) {
            echo 'Product already exists! Skipping...' . "$sku \n";
            return false;
        }
        $configurable_product->setSku($sku);
        $configurable_product->setName($name);
        $configurable_product->setAttributeSetId($attribute_set_id);
        $configurable_product->setStatus(1);
        $configurable_product->setTypeId('configurable');
        $configurable_product->setWebsiteIds(array(1));
        $configurable_product->setCategoryIds($param_product['categoriesArray']);
        $configurable_product->setWeight($weight);
        $configurable_product->setPrice($price);
        $configurable_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
                        )
                    );
        //set attributes
        //designer only, color and size should come from associated products
        $designer = ($param_product['Brand'] == '') ? 'n/a' : $param_product['Brand'];
        $designers_attribute = $this->_c2gmoduleHelper->createOrGetId('designers', $designer);
        $configurable_product->setDesigners($designers_attribute);

        $configurable_product->getTypeInstance()->setUsedProductAttributeIds(array(93,141),$configurable_product); //attribute ID of attribute 'size_general' in my store
        $configurableAttributesData = $configurable_product->getTypeInstance()->getConfigurableAttributesAsArray($configurable_product);

        $configurable_product->setCanSaveConfigurableAttributes(true);
        $configurable_product->setConfigurableAttributesData($configurableAttributesData);

        //create actual all in one array for configurable product, and assign* (hopefully) simple products to configurable
        $simpleProductsData = array();
        $associatedProductIds = array();
        foreach ($associatedProductsAttributesArray as $_current_pro_key => $tempAllInOne) {
            $newlyCreatedSimpleProductId = $tempAllInOne['associated_pro_id'];
            $associatedProductIds[] = $newlyCreatedSimpleProductId;
            $simpleProductsData[$newlyCreatedSimpleProductId] = $tempAllInOne['configurableProductsData'][$newlyCreatedSimpleProductId];
        }
        $configurable_product->setAssociatedProductIds($associatedProductIds);// Setting Associated Products
        $configurable_product->setConfigurableProductsData($simpleProductsData);
        // print_r($simpleProductsData);

        $configurable_product->save();
        echo 'configurable product id: ' . $configurable_product->getId() . " sku: $sku\n";
    }

What am I missing? Doing wrong?

I went to google's second page before asking!

Best Answer

I found the answer in a different post, i dont know if this is good practice or a "bad thing to do", but it works!

For anyone else having this issue

replace

$configurable_product->setAssociatedProductIds($associatedProductIds);// Setting Associated Products

with

    $extensionConfigurableAttributes = $configurable_product->getExtensionAttributes();
    $extensionConfigurableAttributes->setConfigurableProductLinks($associatedProductIds);
    $configurable_product->setExtensionAttributes($extensionConfigurableAttributes);