diff --git a/InventoryDataExporter/Model/Provider/StockStatus.php b/InventoryDataExporter/Model/Provider/StockStatus.php
index c8f698f0..75304444 100644
--- a/InventoryDataExporter/Model/Provider/StockStatus.php
+++ b/InventoryDataExporter/Model/Provider/StockStatus.php
@@ -9,6 +9,7 @@
namespace Magento\InventoryDataExporter\Model\Provider;
use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Stdlib\DateTime;
use Magento\InventoryDataExporter\Model\Query\InventoryStockQuery;
use Psr\Log\LoggerInterface;
@@ -35,6 +36,11 @@ class StockStatus
*/
private $query;
+ /**
+ * @var DateTime
+ */
+ private $dateTime;
+
/**
* @var LoggerInterface
*/
@@ -43,16 +49,19 @@ class StockStatus
/**
* @param ResourceConnection $resourceConnection
* @param InventoryStockQuery $query
+ * @param DateTime $dateTime
* @param LoggerInterface $logger
*/
public function __construct(
ResourceConnection $resourceConnection,
InventoryStockQuery $query,
+ DateTime $dateTime,
LoggerInterface $logger
) {
$this->resourceConnection = $resourceConnection;
$this->query = $query;
$this->logger = $logger;
+ $this->dateTime = $dateTime;
}
/**
@@ -103,6 +112,9 @@ private function fillWithDefaultValues(array $row): array
throw new \RuntimeException("missed required field: " . \var_export($row, true));
}
$row['id'] = StockStatusIdBuilder::build($row);
+
+ // set updated at
+ $row['updatedAt'] = $this->dateTime->formatDate(time());
// set default values
$row['infiniteStock'] = false;
$row['qtyForSale'] = $row['qty'];
diff --git a/InventoryDataExporter/Model/Query/StockStatusDeleteQuery.php b/InventoryDataExporter/Model/Query/StockStatusDeleteQuery.php
new file mode 100644
index 00000000..1a505cdc
--- /dev/null
+++ b/InventoryDataExporter/Model/Query/StockStatusDeleteQuery.php
@@ -0,0 +1,86 @@
+resourceConnection = $resourceConnection;
+ $this->metadata = $metadata;
+ }
+
+ /**
+ * Get stocks which are assigned to the list of provided SKUs
+ *
+ * @param array $skus
+ * @return array
+ */
+ public function getStocksAssignedToSkus(array $skus): array
+ {
+ $connection = $this->resourceConnection->getConnection();
+ $select = $connection->select()
+ ->from(
+ ['source_item' => $this->resourceConnection->getTableName('inventory_source_item')],
+ ['source_item.sku', 'source_stock_link.stock_id']
+ )->joinLeft(
+ ['source_stock_link' => $this->resourceConnection->getTableName('inventory_source_stock_link')],
+ 'source_item.source_code = source_stock_link.source_code'
+ )->where('source_item.sku IN (?)', $skus);
+
+ $fetchedSourceItems = [];
+ foreach ($connection->fetchAll($select) as $sourceItem) {
+ $fetchedSourceItems[$sourceItem['sku']][$sourceItem['stock_id']][] = $sourceItem['source_code'];
+ }
+
+ return $fetchedSourceItems;
+ }
+
+ /**
+ * Mark stock statuses as deleted
+ *
+ * @param array $stocksToDelete
+ */
+ public function markStockStatusesAsDeleted(array $stocksToDelete): void
+ {
+ $connection = $this->resourceConnection->getConnection();
+ $feedTableName = $this->resourceConnection->getTableName($this->metadata->getFeedTableName());
+ foreach ($stocksToDelete as $stockId => $skus) {
+ $connection->update(
+ $feedTableName,
+ ['is_deleted' => new \Zend_Db_Expr('1')],
+ [
+ 'sku IN (?)' => $skus,
+ 'stock_id = ?' => $stockId
+ ]
+ );
+ }
+ }
+}
diff --git a/InventoryDataExporter/Plugin/BulkSourceUnassign.php b/InventoryDataExporter/Plugin/BulkSourceUnassign.php
new file mode 100644
index 00000000..bb6fbd22
--- /dev/null
+++ b/InventoryDataExporter/Plugin/BulkSourceUnassign.php
@@ -0,0 +1,80 @@
+stockStatusDeleteQuery = $stockStatusDeleteQuery;
+ }
+
+ /**
+ * Check which stocks will be unassigned from products and mark them as deleted in feed table
+ *
+ * @param \Magento\InventoryCatalog\Model\ResourceModel\BulkSourceUnassign $subject
+ * @param array $skus
+ * @param array $sourceCodes
+ * @return void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function beforeExecute(
+ \Magento\InventoryCatalog\Model\ResourceModel\BulkSourceUnassign $subject,
+ array $skus,
+ array $sourceCodes
+ ): void {
+ $fetchedSourceItems = $this->stockStatusDeleteQuery->getStocksAssignedToSkus($skus);
+ $stocksToDelete = $this->getStocksToDelete($skus, $sourceCodes, $fetchedSourceItems);
+
+ if (!empty($stocksToDelete)) {
+ $this->stockStatusDeleteQuery->markStockStatusesAsDeleted($stocksToDelete);
+ }
+ }
+
+ /**
+ * @param array $affectedSkus
+ * @param array $deletedSources
+ * @return array
+ */
+ private function getStocksToDelete(array $affectedSkus, array $deletedSources, $fetchedSourceItems): array
+ {
+ $stocksToDelete = [];
+ foreach ($affectedSkus as $deletedItemSku) {
+ foreach ($fetchedSourceItems[$deletedItemSku] as $fetchedItemStockId => $fetchedItemSources) {
+ if ($this->getContainsAllKeys($fetchedItemSources, $deletedSources)) {
+ $stocksToDelete[(string)$fetchedItemStockId][] = $deletedItemSku;
+ }
+ }
+ }
+
+ return $stocksToDelete;
+ }
+
+ /**
+ * @param array $fetchedSources
+ * @param array $deletedSources
+ * @return bool
+ */
+ private function getContainsAllKeys(array $fetchedSources, array $deletedSources): bool
+ {
+ return empty(\array_diff($fetchedSources, $deletedSources));
+ }
+}
diff --git a/InventoryDataExporter/Plugin/MarkItemsAsDeleted.php b/InventoryDataExporter/Plugin/MarkItemsAsDeleted.php
new file mode 100644
index 00000000..493793a1
--- /dev/null
+++ b/InventoryDataExporter/Plugin/MarkItemsAsDeleted.php
@@ -0,0 +1,85 @@
+stockStatusDeleteQuery = $stockStatusDeleteQuery;
+ }
+
+ /**
+ * Set is_deleted value to 1 for deleted stock statuses
+ *
+ * @param DeleteMultiple $subject
+ * @param SourceItemInterface[] $sourceItems
+ * @return void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function beforeExecute(
+ DeleteMultiple $subject,
+ array $sourceItems
+ ): void {
+ $deletedSourceItems = [];
+ foreach ($sourceItems as $sourceItem) {
+ $deletedSourceItems[$sourceItem->getSku()][] = $sourceItem->getSourceCode();
+ }
+
+ $fetchedSourceItems = $this->stockStatusDeleteQuery->getStocksAssignedToSkus(array_keys($deletedSourceItems));
+
+ $stocksToDelete = $this->getStocksToDelete($deletedSourceItems, $fetchedSourceItems);
+ if (!empty($stocksToDelete)) {
+ $this->stockStatusDeleteQuery->markStockStatusesAsDeleted($stocksToDelete);
+ }
+ }
+
+ /**
+ * @param array $deletedSourceItems
+ * @param $fetchedSourceItems
+ * @return array
+ */
+ private function getStocksToDelete(array $deletedSourceItems, $fetchedSourceItems): array
+ {
+ $stocksToDelete = [];
+ foreach ($deletedSourceItems as $deletedItemSku => $deletedItemSources) {
+ foreach ($fetchedSourceItems[$deletedItemSku] as $fetchedItemStockId => $fetchedItemSources) {
+ if ($this->getContainsAllKeys($fetchedItemSources, $deletedItemSources)) {
+ $stocksToDelete[(string)$fetchedItemStockId][] = $deletedItemSku;
+ }
+ }
+ }
+
+ return $stocksToDelete;
+ }
+
+ /**
+ * @param array $fetchedSources
+ * @param array $deletedSources
+ * @return bool
+ */
+ private function getContainsAllKeys(array $fetchedSources, array $deletedSources): bool
+ {
+ return empty(\array_diff($fetchedSources, $deletedSources));
+ }
+}
diff --git a/InventoryDataExporter/etc/db_schema.xml b/InventoryDataExporter/etc/db_schema.xml
index 417618f3..118ecc1b 100644
--- a/InventoryDataExporter/etc/db_schema.xml
+++ b/InventoryDataExporter/etc/db_schema.xml
@@ -51,7 +51,6 @@
/>
-
diff --git a/InventoryDataExporter/etc/di.xml b/InventoryDataExporter/etc/di.xml
index 2414ae1d..36db5e76 100644
--- a/InventoryDataExporter/etc/di.xml
+++ b/InventoryDataExporter/etc/di.xml
@@ -6,11 +6,6 @@
*/
-->
-
-
- catalog_product_entity
-
-
stockStatus
@@ -26,10 +21,10 @@
stock_statuses
sku
- catalog_product_entity
+ inventory_source_item
sku
inventory_data_exporter_stock_status
- id
+ sku
- feed_data
- is_deleted
@@ -45,21 +40,10 @@
-
-
- Magento\InventoryDataExporter\Model\Indexer\StockStatusMarkRemovedEntities
-
-
-
-
- Magento\InventoryDataExporter\Model\Query\MarkRemovedEntitiesQuery
-
-
Magento\InventoryDataExporter\Model\Indexer\StockStatusFeedIndexMetadata
Magento\InventoryDataExporter\Model\Indexer\StockStatusDataSerializer
-
@@ -72,4 +56,19 @@
+
+
+
+
+
+
+
+
+
+ Magento\InventoryDataExporter\Model\Indexer\StockStatusFeedIndexMetadata
+
+
+