3

我正在用代码创建一个可配置的产品(正在做一个导入模块),一切看起来都很好。添加了属性,简单的库存项目被添加到可配置产品中没有问题但是,当我在字体端查看项目时,它显示为简单产品(没有选项)但是当我保存打开并将产品保存在然后管理面板正确显示前端的选项。

我在重新保存项目之前和之后使用以下代码来检查是否有任何属性不匹配(假设我错过了一些东西)

foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $code=>$attribute)    
{
    $val = Mage::getResourceModel('catalog/product')->getAttributeRawValue($product->getId(), $code, $storeId);
    Mage::log($code . '=>' . $val);
}

新导入的产品(不显示选项)和手动保存的产品(显示)之间的所有值都匹配。

这是我用来创建产品的代码(我省略了将属性/简单项目添加到可配置产品的位,但如果需要,请告诉我):

$productData = array(
    'name'              => $name,
    'websites'          => array(1, 2), 
    'short_description' => $shortDescription,
    'description'       => $longDesc,
    'status'            => 1,
    'weight'            => $weight,
    'tax_class_id'      => 2, //0:None;2:Taxable Goods;4:Shipping
    'categories'        => $categoryIds,
    'price'             => $sellPrice,
);

if ($parentStockItem == null) // != null is child item, == false is simple item,  == null is config item
{
    $productData['has_options'] = 1;
    $productData['required_options'] = 1;
    $productData['msrp_enabled'] = 2; //added to test as this was missing in my comparison check
    $productData['msrp_display_actual_price_type'] = 4;  //added to test as this was missing in my comparison check
}

return $mc->create($type, $setId, $stockCode, $productData);

我需要做些什么来设置一个项目以在前端显示选项吗?

4

2 回答 2

3

好的,我通过比较保存项目之前和之后的数据库快照之间的数据,设法找到了问题。

发生这种情况的原因stock_statuscataloginventory_stock_status. 此值默认为0,但当您保存产品时,它会将其设置为1。您还需要确保您正在设置其他库存选项,因此将以下内容添加到我的例程中可以解决问题:

$stockItem = Mage::getModel('cataloginventory/stock_item');
$stockItem->assignProduct($product);
$stockItem->setData('stock_id', 1);
$stockItem->setData('qty', 0);
$stockItem->setData('use_config_min_qty', 1);
$stockItem->setData('use_config_backorders', 1);
$stockItem->setData('min_sale_qty', 1);
$stockItem->setData('use_config_min_sale_qty', 1);
$stockItem->setData('use_config_max_sale_qty', 1);
$stockItem->setData('is_in_stock', 1);
$stockItem->setData('use_config_notify_stock_qty', 1);
$stockItem->setData('manage_stock', 1);
$stockItem->save();

//This section is what was required.
$stockStatus = Mage::getModel('cataloginventory/stock_status');
$stockStatus->assignProduct($product);
$stockStatus->saveProductStatus($product->getId(), 1);

现在,该项目会在导入后立即正确显示选项。

于 2013-02-28T18:09:50.327 回答
2

I ran into this same problem. Its a tough nut to crack. My solution may not be elegant, but it has worked for a year now without problems. Its a little ugly, but it works.

Yes, you need to do many specific things. Instead of explaining each thing, I'll just post the source code I wrote that accepts a master product and its associated products. It boils down to the fact that you have to create a simple product first, use it as a 'template' for your configurable product.

You have to create the master and associated products first, then use the code below to create the configurable product. If you don't want the master product to exist after creating the configurable, simply add code to delete it then change the sku on the new configurable product's entity_id to the sku of the master product.

Make sure you change YOUR_MAGENTO_DBNAME to your database's name

public function createConfigurableProduct($master_sku, $sku_list) {
    // Recreate the array from the serialized string

    try {
        $sku = array();
        $sku = explode(",", $sku_list);

        if (empty($sku)) {
            die ("You have to pass a valid SKU list");
        }

        // Set an object up for the master sku passed by soap
        $masterProduct = Mage::getModel('catalog/product')->loadByAttribute('sku', $master_sku);
        $attrib = $this->getAttribFromProdId($masterProduct->entity_id);

        if ($attrib->attribute_set_id == "") {
            die ("Could not get master product attribute set id from master product");
        }

        $categories = $masterProduct->getResource()->getCategoryIds($masterProduct); 

        if (empty($categories)) {
            die ("could not get the categories that the master product is in. This code requires it is in at least one category");
        }

        // Create the configurable product based on the master product sku passed through SOAP
        $newProductObj = Mage::getResourceModel('catalog/product_collection')->getData();

        $attributes = $masterProduct->getAttributes();

        // Set attributes
        $product = Mage::getModel('catalog/product');

        // Create master copy
        foreach ($attributes as $attr) {
            $attrCode = $attr['attribute_code'];
            // Don't duplicate these values
            if (
                $attrCode != "type_id" 
                && $attrCode != "sku" 
                && $attrCode != "entity_id"
                && $attrCode != "visibility"
                && $attrCode != "url_key"
                && $attrCode != "url_path")
            {
                $product[$attrCode] = $masterProduct[$attrCode];
            }
        }

        // Add all of the stuff 
        $product->setTypeId('configurable');

        // It will create a configurable product with the master product's sku and append -C to the end. cannot duplicate skus
        $product->setSku(str_replace("-C", "", $masterProduct->sku));
        $product->setPrice($masterProduct->price);
        $product->setVisibilty(4); //catalog and search
        $product->setWebsiteIds(array(1));
        $product->setAttributeSetId($attrib->attribute_set_id); 
        $product->setCategoryIds($categories);
        $product->setName($masterProduct->name);
        $product->setDescription($masterProduct->description);
        $product->setShortDescription($masterProduct->short_description);
        $product->setStatus(1); 
        $product->setTaxClassId('2');
        $product->setFeaturedProduct('0');
        $product->setIsImported(0);
        $product->setWeight($masterProduct->weight);                
        $product->setCreatedAt(strtotime('now'));
        $product->product_type=$masterProduct->product_type;
        $product->vendor_code=$masterProduct->vendor_code;

        /* This is the configurable product attribute array
        We do a foreach loop and gather data from each sku's attrib array
        and create a new array for the new product based on what is to be 
        */

        // First, get the information about the master product from the database
        $db = Mage::getSingleton('core/resource')->getConnection('core_read');
        $sql="select * from 
                `nki_magentoV1.11.1.0`.catalog_eav_attribute AS A 
                INNER JOIN `YOUR_MAGENTO_DBNAME`.eav_attribute AS B ON A.attribute_id = B.attribute_id AND B.is_user_defined = 1 
                INNER JOIN `YOUR_MAGENTO_DBNAME`.eav_entity_attribute as EEA ON B.attribute_id = EEA.attribute_id
                WHERE EEA.attribute_set_id = " . $attrib->attribute_set_id . " AND A.is_configurable = 1 AND attribute_code != 'cost' AND B.source_model IS NOT null";
            //echo $sql;

        // Result Set

        $masterResult = $db->fetchAll($sql);
        $data = array();
        $retSku = array();

        foreach ($masterResult as $master) {
            $dataInner = array();

            // This section handles configurable product parameters based on the simple product's attributes
            $values = array();
            foreach ($sku as $prodsku) {

                $innerVals = array();
                // This gets the attribute of the current product
                try {
                    $productBySku = Mage::getModel('catalog/product')->loadByAttribute('sku',$prodsku);
                } catch (Exception $e)
                {
                    // Product cannot be loaded, so continue to next iteration of the loop
                    continue;
                }

                $attribVal = $productBySku[$master['attribute_code']];

                // Load up the attribute set and compare
                $attribute = $productBySku->getResource()->getAttribute($master['attribute_code']);

                $attributeInfo = Mage::getResourceModel('eav/entity_attribute_collection')
                    ->setCodeFilter($master['attribute_code'])
                    ->getFirstItem();

                // There is a possible chance that there is a null error occur here, however it is VERY
                // unlikely that attributeInfo will not be having a valid attribute loaded
                $attributeOptions = $attributeInfo->getSource()->getAllOptions(false);

                foreach ($attributeOptions as $option) {
                    if ($attribVal == $option['value']) {
                        $innerVals['value_index']=$option['value'];
                        $innerVals['label']=$option['label'];
                        $retSku[] = $prodsku;
                    } 
                }

                $innerVals['attribute_id']=$master['attribute_id'];

                if ($masterProduct['price'] != $productBySku['price']) {

                    $calcPrice = $masterProduct['price'] - $productBySku['price'];
                    $innerVals['pricing_value']=$calcPrice * -1;
                }
                else 
                {
                    $innerVals['pricing_value']= 0;
                }


                //$innerVals['pricing_value'] = '100';
                $innerVals['is_percent'] = '0';

                // Only add to the array if there was a value
                // return only the sku's added to the configurable product

                if ($innerVals['value_index'] <> NULL) {
                    $values[] = $innerVals;
                }


            }

            // Set the sata array for the configurable item
            $dataInner['id'] = NULL;
            $dataInner['label'] = $master['attribute_code'];
            $dataInner['position'] = NULL;
            $dataInner['attribute_id'] = $master['attribute_id'];
            $dataInner['frontend_label'] = $master['frontend_label'];
            $dataInner['html_id'] = 'config_super_product__attribute_0';
            $dataInner['values'] = $values;


            $data[] = $dataInner;   
        }

        $product->setConfigurableAttributesData($data);
        $product->setCanSaveConfigurableAttributes(1);

        // Set the stock data so it will appear on the site
        $stockData = $product->getStockData();
        $stockData['is_in_stock'] = 1;
        $stockData['use_config_manage_stockSpecified'] = true;
        $stockData['use_config_manage_stock'] = 0;
        $stockData['manage_stock'] = 1;
        $product->setStockData($stockData);

        // Finally save the product
        try{
            $product->save();
            $productId = $product->getId();

            //echo $product->getId() . ", $price, $itemNum added\n";
        }
        catch (Exception $e){ 
            // Saving the product failed
            $result = array (
                array(
                    'master_sku' => $master_sku,
                    'sku_list' => $sku_list,
                    'retval' => $e
                    )
            );

            error_log($e);
            return $result;
        } 

        // Add the associated products
        if ($productId > 0) {

            foreach($sku as $productSku) { 
                $productIdBySku = Mage::getModel('catalog/product')->loadByAttribute('sku',$productSku)->getId();

                // Add handler to not die on adding products that don't exist
                if ($producIdBySku > 0)
                {
                    $res = $this->addToConfigurable($productId, $productIdBySku);

                    /*                                              
                    if ($res == -5) 
                    {
                        $result = array (
                            array(
                                'master_sku' => $master_sku,
                                'sku_list' => $sku_list,
                                'retval' => ERR_ADD_ASSOCIATED_PROD_FAIL
                                )
                        );
                        return $result;
                    }
                    */

                }
            }

            $product->save();

            $stockItem = Mage::getModel('cataloginventory/stock_item');
            $stockItem->assignProduct($product);
            $stockItem->setData('is_in_stock', 1);
            $stockItem->setData('stock_id', 1);
            $stockItem->setData('store_id', 1);
            $stockItem->setData('manage_stock', 0);
            $stockItem->setData('use_config_manage_stock', 0);
            $stockItem->setData('min_sale_qty', 0);
            $stockItem->setData('use_config_min_sale_qty', 0);
            $stockItem->setData('max_sale_qty', 1000);
            $stockItem->setData('use_config_max_sale_qty', 0);

            $stockItem->save();


            //echo $productArray['product_id'];
        } else {
            // Something baaaaad happened
        }

    } catch (Exception $e) {
        // FATAL ERROR
        // Return php's fatal error that cannot be handled above (which should not happen, but might)
        die ( $e->getMessage() );
    }   

    echo "Configurable Product Created Successfully";
}
于 2013-02-28T14:18:46.780 回答