在我手动将其保存在管理面板中之前,以编程方式创建的可配置项目不显示选项

时间:2013-02-28 14:01:45

标签: php magento magento-1.7

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

我在重新保存项目之前和之后使用以下代码来检查是否有任何属性不匹配(假设我遗漏了某些内容)

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);

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

2 个答案:

答案 0 :(得分:3)

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

发生这种情况的原因是stock_status中的cataloginventory_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);

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

答案 1 :(得分:2)

我遇到了同样的问题。它是一个难以破解的坚果。我的解决方案可能并不优雅,但它现在已经工作了一年没有问题。它有点难看,但它有效。

是的,你需要做很多具体的事情。我只会发布我编写的接受主产品及其相关产品的源代码,而不是解释每件事。归结为您必须首先创建一个简单的产品,将其用作可配置产品的“模板”。

您必须先创建主产品和相关产品,然后使用下面的代码创建可配置产品。如果您在创建可配置后不希望主产品存在,只需添加代码以将其删除,然后将新可配置产品的entity_id上的sku更改为主产品的sku。

确保将YOUR_MAGENTO_DBNAME更改为数据库名称

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";
}