Extension Point of Product Import Export - magento/inventory GitHub Wiki
MSI Product Import/Export
One story to consider with MSI is how an admin user imports source item data via the Product Import/Export. To achieve this, we have added an extension point to the Magento Catalog Import Export.
\Magento\CatalogImportExport\Model\Import\Product::_saveStockItem()
/**
* Stock item saving.
*
* @return $this
*/
protected function _saveStockItem()
{
/** @var $stockResource \Magento\CatalogInventory\Model\ResourceModel\Stock\Item */
$stockResource = $this->_stockResItemFac->create();
$entityTable = $stockResource->getMainTable();
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
$stockData = [];
$productIdsToReindex = [];
// Format bunch to stock data rows
foreach ($bunch as $rowNum => $rowData) {
if (!$this->isRowAllowedToImport($rowData, $rowNum)) {
continue;
}
$row = [];
$sku = $rowData[self::COL_SKU];
if ($this->skuProcessor->getNewSku($sku) !== null) {
$row['product_id'] = $this->skuProcessor->getNewSku($sku)['entity_id'];
$productIdsToReindex[] = $row['product_id'];
$row['website_id'] = $this->stockConfiguration->getDefaultScopeId();
$row['stock_id'] = $this->stockRegistry->getStock($row['website_id'])->getStockId();
$stockItemDo = $this->stockRegistry->getStockItem($row['product_id'], $row['website_id']);
$existStockData = $stockItemDo->getData();
$row = array_merge(
$this->defaultStockData,
array_intersect_key($existStockData, $this->defaultStockData),
array_intersect_key($rowData, $this->defaultStockData),
$row
);
if ($this->stockConfiguration->isQty(
$this->skuProcessor->getNewSku($sku)['type_id']
)
) {
$stockItemDo->setData($row);
$row['is_in_stock'] = $this->stockStateProvider->verifyStock($stockItemDo);
if ($this->stockStateProvider->verifyNotification($stockItemDo)) {
$row['low_stock_date'] = $this->dateTime->gmDate(
'Y-m-d H:i:s',
(new \DateTime())->getTimestamp()
);
}
$row['stock_status_changed_auto'] =
(int)!$this->stockStateProvider->verifyStock($stockItemDo);
} else {
$row['qty'] = 0;
}
}
if (!isset($stockData[$sku])) {
$stockData[$sku] = $row;
}
}
// Insert rows
if (!empty($stockData)) {
$this->_connection->insertOnDuplicate($entityTable, array_values($stockData));
$this->stockItemImporter->import($bunch); // Extension Point for MSI Source Item Importing
}
$this->reindexProducts($productIdsToReindex);
}
return $this;
}
Our extension point is:
$this->stockItemImporter->import($bunch); // Extension Point for MSI Source Item Importing
Where stockItemImporter is an instance of \Magento\CatalogImportExport\Model\StockItemImporterInterface
We than have a preference inside Mageno_InventoryImportExport:
<preference for="\Magento\CatalogImportExport\Model\StockItemImporterInterface"
type="\Magento\InventoryImportExport\Model\StockItemImporter" />
So we inject the new MSI class, \Magento\InventoryImportExport\Model\StockItemImporter
and move the operations to the MSI APIs. For example, we use the following to process the qty for source item now:
/**
* Handle Import of Stock Item Data
*
* @param array $stockData
* @return void
*/
public function import(array $stockData)
{
$sourceItems = [];
foreach ($stockData as $stockDatum) {
if (isset($stockDatum[Product::COL_SKU])) {
$inStock = (isset($stockDatum['is_in_stock'])) ? $stockDatum['is_in_stock'] : 0;
$qty = (isset($stockDatum['qty'])) ? $stockDatum['qty'] : 0;
$sourceItem = $this->sourceItemFactory->create();
$sourceItem->setSku($stockDatum[Product::COL_SKU]);
$sourceItem->setSourceId($this->defaultSource->getId());
$sourceItem->setQuantity($qty);
$sourceItem->setStatus($inStock);
$sourceItems[] = $sourceItem;
}
}
if (count($sourceItems) > 0) {
/** Magento\Inventory\Model\SourceItem[] $sourceItems */
$this->sourceItemsSave->execute($sourceItems);
}
}
Where $this->sourceItemsSave
is an instance of MSI's \Magento\InventoryApi\Api\SourceItemsSaveInterface
.
Future Changes
The idea is that eventually we can use this extension point to convert the whole _saveStockItem()
function to here for the new MSI functionality.
At the time of writing this, we have only just started the story, the importing of MSI Source items has now been implemented as part of the Product Import/Export, but only for the Default Source. Next steps are to handle the different potential formatting of the qty
column to be able to import multiple source's items at one. See the relevant story for more information on the different proposed quantity column formats - Update Product import export to include inventory source