diff --git a/vendor/magento/module-inventory-import-export/Plugin/Import/SourceItemImporter.php b/vendor/magento/module-inventory-import-export/Plugin/Import/SourceItemImporter.php
index d1c9a3e02c8..02bda87de4d 100644
--- a/vendor/magento/module-inventory-import-export/Plugin/Import/SourceItemImporter.php
+++ b/vendor/magento/module-inventory-import-export/Plugin/Import/SourceItemImporter.php
@@ -7,12 +7,24 @@ declare(strict_types=1);
namespace Magento\InventoryImportExport\Plugin\Import;
-use Magento\CatalogImportExport\Model\StockItemImporterInterface;
-use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory;
+use Magento\CatalogImportExport\Model\Import\Product\SkuProcessor;
+use Magento\CatalogImportExport\Model\StockItemProcessorInterface;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Exception\CouldNotSaveException;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Validation\ValidationException;
+use Magento\Inventory\Model\ResourceModel\SourceItem;
use Magento\InventoryApi\Api\Data\SourceItemInterface;
+use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory;
use Magento\InventoryApi\Api\SourceItemsSaveInterface;
use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface;
+use Magento\InventoryCatalogApi\Model\IsSingleSourceModeInterface;
+/**
+ * Assigning products to default source
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
class SourceItemImporter
{
/**
@@ -36,57 +48,116 @@ class SourceItemImporter
*/
private $defaultSource;
+ /**
+ * @var IsSingleSourceModeInterface
+ */
+ private $isSingleSourceMode;
+
+ /**
+ * @var ResourceConnection
+ */
+ private $resourceConnection;
+
+ /**
+ * @var SkuProcessor
+ */
+ private $skuProcessor;
+
/**
* StockItemImporter constructor
*
* @param SourceItemsSaveInterface $sourceItemsSave
* @param SourceItemInterfaceFactory $sourceItemFactory
* @param DefaultSourceProviderInterface $defaultSourceProvider
+ * @param IsSingleSourceModeInterface $isSingleSourceMode
+ * @param ResourceConnection $resourceConnection
+ * @param SkuProcessor $skuProcessor
*/
public function __construct(
SourceItemsSaveInterface $sourceItemsSave,
SourceItemInterfaceFactory $sourceItemFactory,
- DefaultSourceProviderInterface $defaultSourceProvider
+ DefaultSourceProviderInterface $defaultSourceProvider,
+ IsSingleSourceModeInterface $isSingleSourceMode,
+ ResourceConnection $resourceConnection,
+ SkuProcessor $skuProcessor
) {
$this->sourceItemsSave = $sourceItemsSave;
$this->sourceItemFactory = $sourceItemFactory;
$this->defaultSource = $defaultSourceProvider;
+ $this->isSingleSourceMode = $isSingleSourceMode;
+ $this->resourceConnection = $resourceConnection;
+ $this->skuProcessor = $skuProcessor;
}
/**
* After plugin Import to import Stock Data to Source Items
*
- * @param StockItemImporterInterface $subject
- * @param null $result
+ * @param StockItemProcessorInterface $subject
+ * @param mixed $result
* @param array $stockData
- * @throws \Magento\Framework\Exception\CouldNotSaveException
- * @throws \Magento\Framework\Exception\InputException
- * @throws \Magento\Framework\Validation\ValidationException
+ * @param array $importedData
* @return void
- * @see StockItemImporterInterface::import()
+ * @throws CouldNotSaveException
+ * @throws InputException
+ * @throws ValidationException
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function afterImport(
- StockItemImporterInterface $subject,
+ public function afterProcess(
+ StockItemProcessorInterface $subject,
$result,
- array $stockData
- ) {
+ array $stockData,
+ array $importedData
+ ): void {
$sourceItems = [];
+ $skusHavingDefaultSource = $this->getSkusHavingDefaultSource(array_keys($stockData));
+
foreach ($stockData as $sku => $stockDatum) {
- $inStock = (isset($stockDatum['is_in_stock'])) ? intval($stockDatum['is_in_stock']) : 0;
- $qty = (isset($stockDatum['qty'])) ? $stockDatum['qty'] : 0;
- /** @var SourceItemInterface $sourceItem */
+ $isNewSku = !array_key_exists(strtolower((string)$sku), $this->skuProcessor->getOldSkus());
+ $isQtyExplicitlySet = $importedData[$sku]['qty'] ?? false;
+
+ $inStock = $stockDatum['is_in_stock'] ?? 0;
+ $qty = $stockDatum['qty'] ?? 0;
$sourceItem = $this->sourceItemFactory->create();
$sourceItem->setSku((string)$sku);
$sourceItem->setSourceCode($this->defaultSource->getCode());
$sourceItem->setQuantity((float)$qty);
- $sourceItem->setStatus($inStock);
- $sourceItems[] = $sourceItem;
+ $sourceItem->setStatus((int)$inStock);
+
+ //Prevent existing products to be assigned to `default` source, when `qty` is not explicitly set.
+ if ($isNewSku
+ || $isQtyExplicitlySet
+ || $this->isSingleSourceMode->execute()
+ || in_array($sourceItem->getSku(), $skusHavingDefaultSource, true)) {
+ $sourceItems[] = $sourceItem;
+ }
}
if (count($sourceItems) > 0) {
/** SourceItemInterface[] $sourceItems */
$this->sourceItemsSave->execute($sourceItems);
}
}
+
+ /**
+ * Fetch product's skus having assigned to `default` source.
+ *
+ * @param array $listSku
+ * @return array
+ */
+ private function getSkusHavingDefaultSource(array $listSku): array
+ {
+ $connection = $this->resourceConnection->getConnection();
+ $select = $connection->select()->from(
+ $this->resourceConnection->getTableName(SourceItem::TABLE_NAME_SOURCE_ITEM),
+ [SourceItemInterface::SKU]
+ )->where(
+ SourceItemInterface::SKU . ' IN (?)',
+ $listSku
+ )->where(
+ SourceItemInterface::SOURCE_CODE . ' = ?',
+ $this->defaultSource->getCode()
+ );
+
+ return $connection->fetchCol($select);
+ }
}
diff --git a/vendor/magento/module-inventory-import-export/etc/di.xml b/vendor/magento/module-inventory-import-export/etc/di.xml
index 5d0db315768..c6a09491c92 100644
--- a/vendor/magento/module-inventory-import-export/etc/di.xml
+++ b/vendor/magento/module-inventory-import-export/etc/di.xml
@@ -28,9 +28,11 @@
-
+
+
+