10

This is what I've done so far. The simple and configurable products are created. The problem is I cannot assign the simple product to configurable product. Here is the code (ids and attributes works with default sample data).

    //simple product
    $simple_product = $this->_objectManager->create('\Magento\Catalog\Model\Product');
    $simple_product->setSku('test-simple');
    $simple_product->setName('test name simple');
    $simple_product->setAttributeSetId(4);
    $simple_product->setSize_general(193); // value id of S size
    $simple_product->setStatus(1);
    $simple_product->setTypeId('simple');
    $simple_product->setPrice(10);
    $simple_product->setWebsiteIds(array(1));
    $simple_product->setCategoryIds(array(31));
    $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
        )
    );

    $simple_product->save();

    $simple_product_id = $simple_product->getId();
    echo "simple product id: ".$simple_product_id."\n";


    //configurable product
    $configurable_product = $this->_objectManager->create('\Magento\Catalog\Model\Product');
    $configurable_product->setSku('test-configurable');
    $configurable_product->setName('test name configurable');
    $configurable_product->setAttributeSetId(4);
    $configurable_product->setStatus(1);
    $configurable_product->setTypeId('configurable');
    $configurable_product->setPrice(11);
    $configurable_product->setWebsiteIds(array(1));
    $configurable_product->setCategoryIds(array(31));
    $configurable_product->setStockData(array(
        'use_config_manage_stock' => 0, //'Use config settings' checkbox
        'manage_stock' => 1, //manage stock
        'is_in_stock' => 1, //Stock Availability
        )
    );

    $configurable_product->getTypeInstance()->setUsedProductAttributeIds(array(152),$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);

    $configurableProductsData = array();
    $configurableProductsData[$simple_product_id] = array( //[$simple_product_id] = id of a simple product associated with this configurable
        '0' => array(
            'label' => 'S', //attribute label
            'attribute_id' => '152', //attribute ID of attribute 'size_general' in my store
            'value_index' => '193', //value of 'S' index of the attribute 'size_general'
            'is_percent'    => 0,
            'pricing_value' => '10',
        )
    );
    $configurable_product->setConfigurableProductsData($configurableProductsData);

    $configurable_product->save();

    echo "configurable product id: ".$configurable_product->getId()."\n";
  • Have you got final solution for it ? – Praful Rajput Apr 19 '16 at 13:12
  • What should $attributeSetId be? – Abdo Tasks May 10 '18 at 16:34
7

You can review on API functional test for creating configurable product

Code should look like:

$product = $productFactory->create(['name'=> 'configurable product', ... ]);
$configurableOption = $optionFactory->create([]);
$linkedProduct = $linkFactory->create([]);
$product->getExtensionAttributes()->setConfigurableProductOptions($configurableOption);
$product->getExtensionAttributes()->setConfigurableProductLinks($linkedProduct);
$productRepository->save($product)

Please note that the API currently does not generate simple products, they need to be created in advance.

  • 2
    For future audiences: This (and the example, separate answer) is the correct way to do it. But it's very important to note the last line. You must save through the product repository. Calling $product->save() directly will not trigger the configurable data to save (as found in \Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave). – Ryan Hoerr Feb 22 '16 at 18:45
5

I created example script. All direct usages of ObjectManager should be replaced on DI

    $ob = ObjectManager::getInstance();

    /** @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepo */
    $attributeRepo =  $ob->get(\Magento\Catalog\Api\ProductAttributeRepositoryInterface::class);

    $attribute = $attributeRepo->get('color');  // color should be in default attribute set

    /** @var \Magento\Catalog\Api\ProductRepositoryInterface $pr */
    $pr = $ob->get(ProductRepositoryInterface::class);
    $ids = [];
    $values = [];
    foreach($attribute->getOptions() as $option) {
        $id = $option->getValue();
        /** @var \Magento\Catalog\Api\Data\ProductInterface $p */
        $p = $ob->get(\Magento\Catalog\Api\Data\ProductInterface::class);
        $p->setSku('simple-'. $id);
        $p->setName('Configurable Product option #'. $option->getLabel());
        $p->setPrice(10 + $id);
        $p->setTypeId('simple');
        $p->setCustomAttribute($attribute->getAttributeCode(), $id);
        $p = $pr->save($p);
        $ids[] = $p->getId();
        /** @var \Magento\ConfigurableProduct\Api\Data\OptionValueInterface $opVal */
        $opVal =  $ob->create(\Magento\ConfigurableProduct\Api\Data\OptionValueInterface::class);
        $opVal->setValueIndex($id);
        $values[] = $opVal;
    }
    /** @var \Magento\Catalog\Api\Data\ProductInterface $cp */
    $cp = $ob->get(\Magento\Catalog\Api\Data\ProductInterface::class);
    $cp->setSku('configurable');
    $cp->setName('Configurable product');


    /** @var \Magento\ConfigurableProduct\Api\Data\OptionInterface $option */
    $option = $ob->create(\Magento\ConfigurableProduct\Api\Data\OptionInterface::class);
    $option->setLabel('Product Color');
    $option->setAttributeId($attribute->getAttributeId());
    $option->setValues($values);

    $exteAttrs = $cp->getExtensionAttributes();
    $exteAttrs->setConfigurableProductLinks($ids);
    $exteAttrs->setConfigurableProductOptions([
        $option
    ]);

    $pr->save($cp);

see https://github.com/magento/magento2/blob/2.1/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php as other example

  • Hi Andy, thanks for your solution. But $cp->getExtensionAttributes() is null everytime, no matter what I do&change. For example : "PHP Fatal error: Call to a member function setConfigurableProductOptions() on null " – mmmgigi Nov 26 '15 at 10:56
  • use code like $productExtension = $product->getExtensionAttributes(); if ($productExtension === null) { $productExtension = $this->productExtensionFactory->create(); } – KAndy Nov 26 '15 at 13:09
  • @Kandy, please review your answer, it not works because incompleteness. you have to fix $option->setValues($values), but especially you forgot $cp->setExtensionAttributes($exteAttrs). – LucScu Jul 20 '16 at 10:02
  • You right. Maybe better to use code from test github.com/magento/magento2/blob/2.1/dev/tests/integration/… – KAndy Jul 20 '16 at 10:25
  • Just a hint for folks wanting to create simple products... configurable products are aggregations of simple products, so the simple product creation code is in here too! – quickshiftin Jul 30 '16 at 17:22
1

The below code works fine for me.

/* Associate simple product to configurable */
$associatedProductIds = array($simplProductId1,$simplProductId2,$simplProductId3,$simplProductId4);//Simple Product ids array
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($configProductId); // Load Configurable Product
$attributeModel = $objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute');
$position = 0;
$attributes = array($attributeColorId, $attributeSizeId); // Super Attribute Ids Used To Create Configurable Product(list of supper attribute ids what ever belong to that the attribute set under which the configurable product is)
foreach ($attributes as $attributeId) {
    $data = array('attribute_id' => $attributeId, 'product_id' => $configProductId, 'position' => $position);
    $position++;
    $attributeModel->setData($data);//->save();
}
$product->setTypeId("configurable");
$product->setAffectConfigurableProductAttributes($attributeSetId);
$objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable')->setUsedProductAttributeIds($attributes, $product);
$product->setNewVariationsAttributeSetId($attributeSetId);
$product->setAssociatedProductIds($associatedProductIds);// Setting Associated Products
$product->setCanSaveConfigurableAttributes(true);
$product->save();
  • It not work. Giving me error that option are not defined – Asish Hira Aug 23 '17 at 6:28
  • Giving me same error that option are not defined - @Asish have you solved this problem – Nidhi Aug 31 '17 at 7:10
  • @Asish & Nidhi : yes it worked fine for me and ofcz u hv to declare the options – Ipsita Rout Aug 31 '17 at 14:55
  • @Nidhi no I am not able to solve that. – Asish Hira Sep 1 '17 at 5:58
  • @IpsitaRout can you add the code by which we can declare options ? – Asish Hira Sep 1 '17 at 6:00

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.