-
Notifications
You must be signed in to change notification settings - Fork 247
Extension Point of 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
.
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
Multi-Source Inventory developed by Magento 2 Community
- Technical Vision. Catalog Inventory
- Installation Guide
- List of Inventory APIs and their legacy analogs
- MSI Roadmap
- Known Issues in Order Lifecycle
- MSI User Guide
- 2.3 LIVE User Guide
- MSI Release Notes and Installation
- Overview
- Get Started with MSI
- MSI features and processes
- Global and Product Settings
- Configure Source Selection Algorithm
- Create Sources
- Create Stock
- Assign Inventory and Product Notifications
- Configure MSI backorders
- MSI Import and Export Product Data
- Mass Action Tool
- Shipment and Order Management
- CLI reference
- Reports and MSI
- MSI FAQs
- DevDocs Documentation
- Manage Inventory Management Modules (install/upgrade info)
- Inventory Management
- Reservations
- Inventory CLI reference
- Inventory API reference
- Inventory In-Store Pickup API reference
- Order Processing with Inventory Management
- Managing sources
- Managing stocks
- Link and unlink stocks and sources
- Manage source items
- Perform bulk actions
- Manage Low-Quantity Notifications
- Check salable quantities
- Manage source selection algorithms
- User Stories
- Support of Store Pickup for MSI
- Product list assignment per Source
- Source assignment per Product
- Stocks to Sales Channel Mapping
- Adapt Product Import/Export to support multi Sourcing
- Introduce SourceCode attribute for Source and SourceItem entities
- Assign Source Selector for Processing of Returns Credit Memo
- User Scenarios:
- Technical Designs:
- Module Structure in MSI
- When should an interface go into the Model directory and when should it go in the Api directory?
- Source and Stock Item configuration Design and DB structure
- Stock and Source Configuration design
- Open Technical Questions
- Inconsistent saving of Stock Data
- Source API
- Source WebAPI
- Sources to Sales Channels mapping
- Service Contracts MSI
- Salable Quantity Calculation and Mechanism of Reservations
- StockItem indexation
- Web API and How To cover them with Functional Testing
- Source Selection Algorithms
- Validation of Domain Entities
- PHP 7 Syntax usage for Magento contribution
- The first step towards pre generated IDs. And how this will improve your Integration tests
- The Concept of Default Source and Domain Driven Design
- Extension Point of Product Import/Export
- Source Selection Algorithm
- SourceItem Entity Extension
- Design Document for changing SerializerInterface
- Stock Management for Order Cancelation
- Admin UI
- MFTF Extension Tests
- Weekly MSI Demos
- Tutorials