I am creating a custom module.
I am testing the ability to update a products quantity.
I have created a bare bones magento module and began testing with code inside indexController.php here is my code:
public function indexAction() {
//Just grabbing sku# 62701 for testing...
$tempProduct = Mage::getModel('catalog/product')->loadByAttribute('sku', 62701 );
$stockData['qty'] = 300;
$tempProduct->setStockData($stockData);
$tempProduct->save();
}
By having the last line in there i get the error.
From the error log:
a:5:{i:0;s:46:"Invalid method Varien_Object::save(Array ( )
Followed by the stack trace...
Any help is appreciated, thank you.
I had to look into this issue and found the problem. The whole stock data/item interface is a bit tricky.
Mage_Catalog_Model_Abstract->loadByAttribute
uses collection-loading on collection catalog/product_collection
with a limit of 1.
Stock items of products in that collection are loaded via the event observer Mage_CatalogInventory_Model_Observer->addStockStatusToCollection
which listens to event catalog_product_collection_load_after
. addStockStatusToCollection
loads stock items of products only if flag require_stock_items
is set true
.
In case of Mage_Catalog_Model_Abstract->loadByAttribute
this flag isn't set so we end up with $product->_data['stock_item']
being of type Varien_Object
(see Mage_CatalogInventory_Model_Stock_Status
lines 488-491).
This causes error
Invalid method Varien_Object::save...
on $product->save
.
I recommend solution 1 if you save the product anyway and want the stock update to happen in the same transaction. Solution 2 only sets stock data so it avoids calling expensive $product->save
.
Use an additional load on the product: this loads $product->_data['stock_item']
properly.
Mage::getModel('catalog/product')->loadByAttribute('sku', 62701 );
$tempProduct->load($tempProduct->getId());
This is an additonal read transaction on the database which slows things down.
As in other answers suggested use the class Mage_CatalogInventory_Model_Stock_Item
directly. But you have reference the product correctly via call to setProduct
to have working code both for new and existing stock items.
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product->getId());
$stockItem->setProduct($product)
->setData('stock_id', Mage_CatalogInventory_Model_Stock::DEFAULT_STOCK_ID)
->setData('qty', 1)
->setData('is_in_stock', 1)
->setData('manage_stock', 1)
->setData('use_config_manage_stock', 0)
->setData('use_config_backorders', 0)
->setData('backorders', 0)
->setData('use_config_max_sale_qty', 0)
->setData('max_sale_qty', 1)
->save();
I found a way to save data that seemed to work in my scenario (not sure why it worked) here: https://stackoverflow.com/a/7608195/1110880
The code that made it work was the following:
$productId = $tempProduct->getId();
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
$stockItem->setData('qty', $qty);
$stockItem->save();
I hope this helps someone.
I can see two potential problems.
loadByAttribute('sku', 62701 )
can only return one item? (That error has shown up when people have tried to update more than one thing at once.)$stockData
is not defined. At a minimum it would be safer to define it.It looks like you're missing something like this:
$stockData = $tempProduct->getStockData();
I'm probably doing something wrong, but I had the same problem and this helped:
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product->getId());
$stockItem->setProductId($product->getId());
$stockItem->setStockId(Mage_CatalogInventory_Model_Stock::DEFAULT_STOCK_ID);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With