Question

UPDATE: I figured out that the issue is that while this script updates the item in the cataloginventory_stock_item table, it fails to update it in the cataloginventory_stock_status table. Added an answer for how to fix this.

The following script is being used to update the inventory levels of items in my store:

<?

 define('MAGENTO', realpath(dirname(__FILE__)));
 require_once MAGENTO . '/app/Mage.php';

 umask(0);
 Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
 $count = 0;

 $file = fopen(MAGENTO . '/var/import/updateStockLevels.csv', 'r');
 while (($line = fgetcsv($file)) !== FALSE) { 

 if ($count == 0) {
 foreach ($line as $key=>$value) {
 $cols[$value] = $key;
 } 
 } 

 $count++;

 if ($count == 1) continue;

 #Convert the lines to cols 
 if ($count > 0) { 
 foreach($cols as $col=>$value) {
 unset(${$col});
 ${$col} = $line[$value];
 } 
 }

 // Check if SKU exists
 $product = Mage::getModel('catalog/product')->loadByAttribute('sku',$sku); 

 if ( $product ) {

 $productId = $product->getId();
 $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
 $stockItemId = $stockItem->getId();
 $stock = array();

 if (!$stockItemId) {
 $stockItem->setData('product_id', $product->getId());
 $stockItem->setData('stock_id', 1); 
 } else {
 $stock = $stockItem->getData();
 }

 foreach($cols as $col=>$value) {
 $stock[$col] = $line[$value];
 } 

 foreach($stock as $field => $value) {
 $stockItem->setData($field, $value?$value:0);
 }



 $stockItem->save();

 unset($stockItem);
 unset($product);
 }

 echo "<br />Stock updated $sku";

 }
 fclose($file);

?>

This script works great and all qty levels are updated accurately. The issue is with the in stock check.

If I go to an item page on the frontend that has qty zero after running the script, it shows it as In Stock. However, when I go to check that item in the backend, the Inventory->Stock Availability field correctly shows as Out of Stock, and the database itself has the correct value.

If I go to the product page in the admin, and click to save the product (since it already shows it correctly being out of stock in the availability field), its fixes the problem. The frontend will now show it properly as out of stock.

Since qty set to 0 and is_in_stock set to false (0) is not enough to mark it properly as Out of Stock on the frontend, I assume that there must be some field that I am not properly updating in my script, that is only updated properly when I save the item from the admin backend. However I don't know what field(s) I could be missing.

Was it helpful?

Solution

I confirmed that the issue was in fact that some fields were not being updated that needed to be. These fields ended up being qty and stock_status in the table cataloginventory_stock_status. I found a couple ways to fix this. You can update each item in the script using the assign function that the Mage_CatalogInventory_Model_Stock_Status has. Simply place it in the if ( $product ) loop.

The other way is to use the rebuild function that the Mage_CatalogInventory_Model_Stock_Status has. You call this outside the if loop and it will rebuild all the stock statuses on the site based on their newly updated qty. This is the method I used, and my edit was simply adding this function call after the if loop, right after the fclose line.

fclose($handle);

$stockStatus = Mage::getModel('cataloginventory/stock_status')->rebuild($website_Id);

It increases the script run time by about 30-40%, but the script is still quite quick and now it works fully.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top