0
votes

I have a custom xml file and I make a massive import of the products. I have some simples products under configurables ones. All is working well, configurable products are created with the simple products the "associated products" tab but one last thing still doesn't work : the price of each product.

Actually, Each simple product has its own price and the correct value is well saved in its attribute but in the "super product attribute configuration" panel, the values are empty.

Super product attributes configuration

When I fill the price fields manually, it works but it obviously must be done by the script, programmatically.

Here is my function to create the configurable product :

protected function createConfigurableProductFromSimpleProduct($product, $flagshipID)
{
    $configurableProduct = $product->duplicate();
    $configurableProduct->getResource()->save($configurableProduct);
    $configurableProduct= Mage::getModel('catalog/product')->load($configurableProduct->getId());

    $configurableProduct->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE)
                     ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
                     ->setSku($flagshipID)
                     ->setDefRef($product_id)
                     ->getTypeInstance()->setUsedProductAttributeIds(array($this->getAttributeId('root_colors'))); //attribute ID of attribute 'root_colors' in my store

    $configurableProduct->setName($configurableProduct->getName());
    $configurableProduct->setStatus(1);
    $configurableProduct->setStockData(array(
        'is_in_stock' => 1
    ));
    $configurableProduct->setUrlKey($configurableProduct->getName());
    $configurableProduct->save();

    return $configurableProduct;
}

And here is the code for linking simple products to this configurable product :

protected function linkSimpleProductsToConfigurableProduct($simpleProducts, $configurableProduct)
{
    $configurableProductsData = array();
    foreach ($simpleProducts as $_product) {
        $_product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE);
        $_product->getResource()->save($_product);
        $configurableProductsData[$_product->getId()] = array( //[id] = id of a simple product associated with this configurable
            '0' => array(
                'label'         => $this->getAttributeRawValue($this->getAttributeId('root_colors'), $_product->getRoot()), //attribute label
                'attribute_id'  => $this->getAttributeId('root_colors'), //attribute ID of discriminator attribute in my store
                'value_index'   => $_product->getColor(),
                'pricing_value' => $_product->getPrice(),
                'is_percent'    => '0'
            )
        );
    }
    $configurableAttributesData = $configurableProduct->getTypeInstance()->getConfigurableAttributesAsArray();
    $configurableProduct->setCanSaveConfigurableAttributes(true);
    $configurableProduct->setConfigurableAttributesData($configurableAttributesData);
    $configurableProduct->setConfigurableProductsData($configurableProductsData);
    var_dump('saving configurable product after having link some simple products');
    $configurableProduct->save();
}

Any help is welcome, thank you !

3

3 Answers

1
votes

Hy all! After reading thousand of answer i solved it!

    $cProduct->setCanSaveConfigurableAttributes(true); 
    $cProduct->setCanSaveCustomOptions(true);
    $cProductTypeInstance = $cProduct->getTypeInstance();
    $cProductTypeInstance->setUsedProductAttributeIds(array($attribute_id));

    $attributes_array = $cProductTypeInstance->getConfigurableAttributesAsArray();
    foreach($attributes_array as $key => $attribute_array) {
         $attributes_array[$key]['use_default'] = 0; 
         $attributes_array[$key]['position'] = 0;   
         if (isset($attribute_array['frontend_label'])) {
             $attributes_array[$key]['label'] = $attribute_array['frontend_label']; 
         } else {
             $attributes_array[$key]['label'] = $attribute_array['attribute_code']; 
         }

    }   

    $dataArray = array();
    foreach ($simpleProducts as $simpleArray) {
         $dataArray[$simpleArray['id']] = array( 
            "label" => $simpleArray['label'],
            "attribute_id" => $simpleArray['attr_id'], 
            "value_index" => $simpleArray['value'],
            "is_percent" => '0', 
            "pricing_value" => $simpleArray['price'] 
        ); 
    }   


// MAIN MOD! Here i prepare an array for attributesData.
        $valuesArray = array();
        foreach($dataArray as $data){
            $valuesArray[] = $data; 
        }

    // MAIN MOD! 
    // this is not the best, but in my case I've only one attribute.
    $attributes_array[0]['values'] = $valuesArray;
    $cProduct->setConfigurableProductsData($dataArray);
    $cProduct->setConfigurableAttributesData($attributes_array);

I dont post all the codes, but i see that with these little modification it solve the problem!

0
votes

I'm having the exact same issue and suspect this is due to something in Magento 1.9. I've tried a couple of code workarounds, but none of them work yet. Hmm, same bummer as you are suffering from.

Instead of providing further comments, I'll just provide an answer instead ;)

I digged into this a little bit deeper and found that the setConfigurableProductsData() call is designed to set product information, but the flag "pricing_value" simply does not work (at least it doesn't work in Magento 1.9). The call is only used to identify the Simple Products that are part of this Configurable Product. Instead the setConfigurableAttributesData() call needs to be used to define the relationship between Simple Products and pricing.

The following code worked for me: It moves the definition of specific option values (identified with value_index) with specific prices (pricing_value) as part of the attribute-data and not the product-data.

$configurableAttributeSizeValues = array();
foreach($simpleProducts as $simpleProduct) {
    $configurableAttributeSizeValues[] = array(
        'label' => $simpleProduct->getAttributeText('size'),
        'value_index' => $simpleProduct->getSize(),
        'is_percent' => false,
        'pricing_value' => $simpleProduct->getPrice(),
    );
}
$configurableAttributeSize = array(
    'id' => null,
    'label' => 'Size',
    'frontend_label' => 'Size',
    'attribute_id' => $attribute->getId(),
    'attribute_code' => 'size',
    'values' => $configurableAttributeSizeValues,
    'position' => 0,
);
$configurableAttributesData = array($configurableAttributeSize);

$configurableProductsIds = array();
foreach($simpleProducts as $simpleProduct) {
    $configurableProductsIds[$simpleProduct->getId()] = $simpleProduct->getId();
}

$product->setConfigurableProductsData($configurableProductsIds);
$product->setConfigurableAttributesData($configurableAttributesData);
$product->setCanSaveConfigurableAttributes(true);

Before this code is put to use, I've loaded a product-collection called $simpleProducts and a single attribute $attribute. If you want to load multiple attributes to the same product, you can by adding them to the $configurableAttributesData array.

The original $configurableProductsData that you created in your code can still be used, however because most of its purpose is moved to the attributes-array instead, you can also just create a simple array of Simple Product IDs instead. That's what I did with $configurableProductsIds.

Hope this helps you out as well.

0
votes

Here is what worked for me (some code repeated for clarity). Both setConfigurableProductsData and setConfigurableAttributesData need to be used for pricing_value to be saved.

$configurableAttributesData = $product->getTypeInstance()->getConfigurableAttributesAsArray();
$product->getTypeInstance()->setUsedProductAttributeIds(array($attribute->getId()));
$product->setCanSaveConfigurableAttributes(true);
$configurableProductsData[$childId] = array(
    $childProductId => array(
        'label' => $childProduct->getAttributeText($attribute->getAttributeCode()),
        'attribute_id' => $attribute->getId(),
        'value_index' => $optionId, 
        'is_percent' => false, 
        'pricing_value' => $childProduct->getPrice() 
    )
);
$configurableAttributesData[0]['values'][] = array(
    'label' => $childProduct->getAttributeText($attribute->getAttributeCode()),
    'attribute_id' => $attribute->getId(),
    'value_index' => $optionId,
    'is_percent' => false, 
    'pricing_value' => $childProduct->getPrice() 
);
$configurableAttributesData[0]['attribute_id'] = $attribute->getId();
$product->setConfigurableProductsData($configurableProductsData);
$product->setConfigurableAttributesData($configurableAttributesData);
$product->save();