6

I'm creating products programatically on Magento CE 1.8.1. The form works fine except every once in a while we get a nasty error that comes and goes away, and does not affect all users.

:"SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '970-1' 
for key 'UNQ_CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID'"

Like I said, it doesn't always show up. I found many questions about this problem and saw as many suggestions to use

$product->getResource()->save($product);
// instead of 
// $product->save();

I tried that and I think the error does stop showing up, but a new problem arises; stock isn't saved properly. The code that I was using was:

// this works with $newProduct->save()
// but it doesn't work with $product->getResource()->save($newProduct)

$newProduct->setStockData(array(
              'qty'=>$params["qty"],
              'is_in_stock'=>1, 'notify_stock_qty'=>$params["stockqty"]));

I then tried using this:

$newProduct = Mage::getModel('catalog/product')->load($product_id);
$stockItem = Mage::getModel('cataloginventory/stock_item');
$stockItem->assignProduct($newProduct);
$stockItem->setData('manage_stock', 1);
$stockItem->setData('is_in_stock', 1);
$stockItem->setData('use_config_notify_stock_qty', 0);
$stockItem->setData('qty', 40);
$newProduct->setStockItem($stockItem);
//save product..

But nothing. Stock is always 0, and manage_stock is always set to No. So I tried loading and saving the stock item after saving the product but I got a new error: "SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`bitnami_magento`.`cataloginventory_stock_item`, CONSTRAINT `FK_CATINV_STOCK_ITEM_PRD_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`product_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON D)" which sounds like the product hasn't been created yet! I checked the backend and the product was created, but with no stock. It seems like the resource save method ignores the stockData and also the stockItem.

I'm running out of ideas here. I've read a bunch of questions here where these worked but they're not working for me. Has anyone run into this before?

  • Have you checked this link? This might help. – Adarsh Khatri May 10 '15 at 5:46
  • Not a direct solution but I've had success with: github.com/avstudnitz/AvS_FastSimpleImport – B00MER May 10 '15 at 23:54
  • @AdarshKhatri I have. Like I said, that code works but allows for the error to show up everyonce in a while. It is what I have though. – Vic May 11 '15 at 1:04
  • @B00MER Thanks, but this code is not for importing products. This is to allow certain users to create products from the frontend. – Vic May 11 '15 at 1:06
1
+50

In your example where you load the Mage_CatalogInventory_Model_Stock_Item instance, you should save the instance itself instead of the product.

Saving the product doesn't work, because it ignores the assigned stock item. You can see why this is by looking at the the method

Mage_CatalogInventory_Model_Observer::saveInventoryData

This method is triggered by the catalog_product_save_after event, which is called after a product is saved. The method first checks whether stock_data is set; if it is not set, the stock item is not updated.

  • I've tried this but I get an failed constraint exception. Apparently the product isn't already saved in the database when I try saving the stock item so the product Id constraint fails. I checked that I wasn't trying to save the stock item before the product existed and the code is in the right order so I can only assume the data base transaction hasnt been commited yet. I must be missing something – Vic May 7 '15 at 18:58
  • I'll give this another go. Maybe i find something I hadn't tried yet. This looks the most promissing – Vic May 7 '15 at 19:00
  • Good luck. I encountered this constraint violation a while ago when I was extending an import module with stock data. Unfortunately I cannot recall the exact cause anymore, but it turned out to be a bug in my code. – Aad Mathijssen May 7 '15 at 19:15
  • I'm accepting this answer because it seems like the best fit for my problem, but I did not implement this. I changed something in my code which appears to make this not necessary anymore but it's not an answer to this question; it's a different method. If no other answer arises before the bounty expires this one should receive the bounty points. – Vic May 11 '15 at 1:11
  • Is it that you don't need any stock updates at all anymore, or are you using the setStockData approach (which is my preferred choice when updating stock as part of updating a product)? – Aad Mathijssen May 11 '15 at 10:24
4

This is a working example wich i use:

$product = Mage::getModel('catalog/product');
                $product->setWebsiteIds(array(1));
                $product->setTypeId('simple');
                $product->setName('name');
                $product->setDescription('xyz');
                $product->setShortDescription(' ');
                $product->setStatus(1);
                $product->setTaxClassId(1);
                $product->setWeight(0);
                $product->setCreatedAt(strtotime('now'));
                $product->setManufacturer(1);
                $product->setAttributeSetId(1);
                $product->setSku('sku');
                $product->setPrice(5);
                $product->setVisibility(1);
                $product->save();

After saving the product create stock item:

$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', 1);
            $stockItem->setData('use_config_manage_stock', 0);
            $stockItem->setData('min_sale_qty', 1);
            $stockItem->setData('use_config_min_sale_qty', 0);
            $stockItem->setData('max_sale_qty', 1000);
            $stockItem->setData('use_config_max_sale_qty', 0);
            $stockItem->setData('qty', 10);
            $stockItem->save();
  • Well, like I said in the question, the line $product-> save() makes that first error happen sometimes so I have to save via de resource class. I've already tried your code. – Vic May 1 '15 at 15:19
0

Before saving the new stock data, try loading the stock item from the product, and deleting it.

$stockItem = Mage::getModel('cataloginventory/stock_item')
    ->loadByProduct($product)
    ->delete();
  • The thing is the stock item doesn't even exist at this point. It is not saved when I call $product->getResource()->save($product). I checked the database for it and it's not there. That is the problem :/ – Vic May 6 '15 at 16:14

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.