Last active
August 21, 2024 01:30
-
-
Save artttj/adc9d16e1c45437fdbfff6e873648ecd to your computer and use it in GitHub Desktop.
Magento 2 Update Stock Qty from CSV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Script to import/update stocks/inventory/qty in bulk via CSV | |
* | |
* @author Artyom Yagovdik <artyom.yagovdik(at)gmail.com> | |
* @website https://artttj.github.io/ | |
*/ | |
ini_set('display_errors', 1); | |
ini_set('display_startup_errors', 1); | |
error_reporting(E_ALL); | |
// Capture warning / notice as exception | |
set_error_handler('mp_exceptions_error_handler'); | |
function mp_exceptions_error_handler($severity, $message, $filename, $lineno) | |
{ | |
if (error_reporting() == 0) { | |
return; | |
} | |
if (error_reporting() & $severity) { | |
throw new ErrorException($message, 0, $severity, $filename, $lineno); | |
} | |
} | |
require __DIR__ . '/../app/bootstrap.php'; | |
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER); | |
$obj = $bootstrap->getObjectManager(); | |
$state = $obj->get('Magento\Framework\App\State'); | |
$state->setAreaCode('adminhtml'); | |
/**************************************************************************************************/ | |
// UTILITY FUNCTIONS - START | |
/**************************************************************************************************/ | |
function _mpLog($data, $includeSep = false) | |
{ | |
$fileName = BP . '/var/log/m2-magepsycho-import-stocks.log'; | |
if ($includeSep) { | |
$separator = str_repeat('=', 70); | |
file_put_contents($fileName, $separator . '<br />' . PHP_EOL, FILE_APPEND | LOCK_EX); | |
} | |
file_put_contents($fileName, $data . '<br />' . PHP_EOL, FILE_APPEND | LOCK_EX); | |
} | |
function mpLogAndPrint($message, $separator = false) | |
{ | |
_mpLog($message, $separator); | |
if (is_array($message) || is_object($message)) { | |
print_r($message); | |
} else { | |
echo $message . '<br />' . PHP_EOL; | |
} | |
if ($separator) { | |
echo str_repeat('=', 70) . '<br />' . PHP_EOL; | |
} | |
} | |
function getIndex($field) | |
{ | |
global $headers; | |
$index = array_search($field, $headers); | |
if (!strlen($index)) { | |
$index = -1; | |
} | |
return $index; | |
} | |
function readCsvRows($csvFile) | |
{ | |
$rows = []; | |
$fileHandle = fopen($csvFile, 'r'); | |
while (($row = fgetcsv($fileHandle, 0, ',', '"', '"')) !== false) { | |
$rows[] = $row; | |
} | |
fclose($fileHandle); | |
return $rows; | |
} | |
function _getResource() | |
{ | |
global $obj; | |
return $obj->get('Magento\Framework\App\ResourceConnection'); | |
} | |
function _getConnection() | |
{ | |
return _getResource()->getConnection(); | |
} | |
function _getTableName($tableName) | |
{ | |
return _getResource()->getTableName($tableName); | |
} | |
function _getIdFromSku($sku) | |
{ | |
$connection = _getConnection(); | |
$sql = "SELECT entity_id FROM " . _getTableName('catalog_product_entity') . " WHERE sku = ?"; | |
return $connection->fetchOne( | |
$sql, | |
[ | |
$sku | |
] | |
); | |
} | |
function checkIfSkuExists($sku) | |
{ | |
$connection = _getConnection(); | |
$sql = "SELECT COUNT(entity_id) AS count_no FROM " . _getTableName('catalog_product_entity') . " WHERE sku = ?"; | |
return $connection->fetchOne($sql, [$sku]); | |
} | |
/** | |
* Updates the stock/qty | |
* Note: It doesn't take care for multi-source/website based inventory | |
* For proper results, stock indexing is required | |
* | |
* @param $entityId | |
* @param $qty | |
* | |
* @return int | |
*/ | |
function updateStocks($sku, $qty) | |
{ | |
global $obj; | |
// Existing Stock Items | |
// $sourceItemsSaveInterface = $obj->get('Magento\InventoryApi\Api\SourceItemsSaveInterface'); | |
// $sourceItemFactory = $obj->get('Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory'); | |
// $sourceItem = $sourceItemFactory->create(); | |
// $sourceItem->setSourceCode('default'); | |
// $sourceItem->setSku($sku); | |
// $sourceItem->setQuantity($qty); | |
// $sourceItem->setStatus(1); | |
// $sourceItemsSaveInterface->execute([$sourceItem]); | |
$productFactory = $obj->get('Magento\Catalog\Api\Data\ProductInterfaceFactory'); | |
$product = $productFactory->create(); | |
$productId = _getIdFromSku($sku); | |
$product->load($productId); | |
$product->setStockData( | |
[ | |
'use_config_manage_stock' => 0, | |
'manage_stock' => 1, | |
'is_in_stock' => 1, | |
'qty' => $qty | |
] | |
); | |
$product->save(); | |
return 1; | |
} | |
/**************************************************************************************************/ | |
// UTILITY FUNCTIONS - END | |
/**************************************************************************************************/ | |
try { | |
#EDIT - The path to import CSV file (Relative to Magento2 Root) | |
$csvFile = 'var/import/stock_sample.csv'; | |
$csvData = readCsvRows(BP . '/' . $csvFile); | |
$headers = array_shift($csvData); | |
$count = 0; | |
foreach ($csvData as $_data) { | |
$count++; | |
$sku = $_data[getIndex('sku')]; | |
$qty = $_data[getIndex('qty')]; | |
if (!($entityId = _getIdFromSku($sku))) { | |
$message = $count . '. FAILURE:: Product with SKU (' . $sku . ') doesn\'t exist.'; | |
mpLogAndPrint($message); | |
continue; | |
} | |
try { | |
$updatedCount = updateStocks($sku, $qty); | |
$message = $count . '. SUCCESS:: Updated SKU (' . $sku . ') with qty (' . $qty . '), UpdatedCount::' . (int)$updatedCount; | |
mpLogAndPrint($message); | |
} catch (Exception $e) { | |
$message = $count . '. ERROR:: While updating SKU (' . $sku . ') with qty (' . $qty . ') => ' . $e->getMessage(); | |
mpLogAndPrint($message); | |
} | |
} | |
} catch (Exception $e) { | |
mpLogAndPrint('EXCEPTION::' . $e->getTraceAsString()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment