diff --git a/vendor/magento/module-inventory-indexer/etc/di.xml b/vendor/magento/module-inventory-indexer/etc/di.xml
index 9b74e7c7dad..f5e9f061b97 100644
--- a/vendor/magento/module-inventory-indexer/etc/di.xml
+++ b/vendor/magento/module-inventory-indexer/etc/di.xml
@@ -95,4 +95,14 @@
catalog_product_entity
+
+
+ Magento\InventoryIndexer\Model\IsProductSalable
+
+
+
+
+ Magento\InventoryIndexer\Model\AreProductsSalable
+
+
diff --git a/vendor/magento/module-inventory-sales/Model/GetProductAvailableQty.php b/vendor/magento/module-inventory-sales/Model/GetProductAvailableQty.php
new file mode 100644
index 00000000000..5f47aa552e4
--- /dev/null
+++ b/vendor/magento/module-inventory-sales/Model/GetProductAvailableQty.php
@@ -0,0 +1,76 @@
+resourceConnection = $resourceConnection;
+ }
+
+ /**
+ * Get available quantity for given SKU and Stock
+ *
+ * @param string $sku
+ * @param int $stockId
+ * @return float
+ */
+ public function execute(string $sku, int $stockId): float
+ {
+ $connection = $this->resourceConnection->getConnection();
+ $select = $connection->select()->from(
+ ['issl' => $this->resourceConnection->getTableName(StockSourceLink::TABLE_NAME_STOCK_SOURCE_LINK)],
+ []
+ )->joinInner(
+ ['is' => $this->resourceConnection->getTableName(Source::TABLE_NAME_SOURCE)],
+ sprintf('issl.%s = is.%s', StockSourceLinkInterface::SOURCE_CODE, SourceInterface::SOURCE_CODE),
+ []
+ )->joinInner(
+ ['isi' => $this->resourceConnection->getTableName(SourceItem::TABLE_NAME_SOURCE_ITEM)],
+ sprintf('issl.%s = isi.%s', StockSourceLinkInterface::SOURCE_CODE, SourceItemInterface::SOURCE_CODE),
+ []
+ )->where(
+ sprintf('issl.%s = ?', StockSourceLinkInterface::STOCK_ID),
+ $stockId
+ )->where(
+ sprintf('is.%s = ?', SourceInterface::ENABLED),
+ 1
+ )->where(
+ sprintf('isi.%s = ?', SourceItemInterface::SKU),
+ $sku
+ )->where(
+ sprintf('isi.%s = ?', SourceItemInterface::STATUS),
+ SourceItemInterface::STATUS_IN_STOCK
+ )->columns(
+ ['quantity' => new Zend_Db_Expr(sprintf('SUM(isi.%s)', SourceItemInterface::QUANTITY))]
+ );
+
+ return (float) $connection->fetchOne($select);
+ }
+}
diff --git a/vendor/magento/module-inventory-sales/Model/IsProductSalableCondition/IsSalableWithReservationsCondition.php b/vendor/magento/module-inventory-sales/Model/IsProductSalableCondition/IsSalableWithReservationsCondition.php
index cc8dee8b5ba..e26925e6727 100644
--- a/vendor/magento/module-inventory-sales/Model/IsProductSalableCondition/IsSalableWithReservationsCondition.php
+++ b/vendor/magento/module-inventory-sales/Model/IsProductSalableCondition/IsSalableWithReservationsCondition.php
@@ -11,6 +11,7 @@ use Magento\InventoryCatalogApi\Model\GetProductTypesBySkusInterface;
use Magento\InventoryConfigurationApi\Model\IsSourceItemManagementAllowedForProductTypeInterface;
use Magento\InventoryConfigurationApi\Api\Data\StockItemConfigurationInterface;
use Magento\InventoryReservationsApi\Model\GetReservationsQuantityInterface;
+use Magento\InventorySales\Model\GetProductAvailableQty;
use Magento\InventorySalesApi\Api\IsProductSalableInterface;
use Magento\InventorySalesApi\Model\GetStockItemDataInterface;
use Magento\InventoryConfigurationApi\Api\GetStockItemConfigurationInterface;
@@ -45,25 +46,33 @@ class IsSalableWithReservationsCondition implements IsProductSalableInterface
*/
private $getProductTypesBySkus;
+ /**
+ * @var GetProductAvailableQty
+ */
+ private $getProductAvailableQty;
+
/**
* @param GetStockItemDataInterface $getStockItemData
* @param GetReservationsQuantityInterface $getReservationsQuantity
* @param GetStockItemConfigurationInterface $getStockItemConfiguration
* @param IsSourceItemManagementAllowedForProductTypeInterface $isSourceItemManagementAllowedForProductType
* @param GetProductTypesBySkusInterface $getProductTypesBySkus
+ * @param GetProductAvailableQty $getProductAvailableQty
*/
public function __construct(
GetStockItemDataInterface $getStockItemData,
GetReservationsQuantityInterface $getReservationsQuantity,
GetStockItemConfigurationInterface $getStockItemConfiguration,
IsSourceItemManagementAllowedForProductTypeInterface $isSourceItemManagementAllowedForProductType,
- GetProductTypesBySkusInterface $getProductTypesBySkus
+ GetProductTypesBySkusInterface $getProductTypesBySkus,
+ GetProductAvailableQty $getProductAvailableQty
) {
$this->getStockItemData = $getStockItemData;
$this->getReservationsQuantity = $getReservationsQuantity;
$this->getStockItemConfiguration = $getStockItemConfiguration;
$this->isSourceItemManagementAllowedForProductType = $isSourceItemManagementAllowedForProductType;
$this->getProductTypesBySkus = $getProductTypesBySkus;
+ $this->getProductAvailableQty = $getProductAvailableQty;
}
/**
@@ -84,7 +93,7 @@ class IsSalableWithReservationsCondition implements IsProductSalableInterface
/** @var StockItemConfigurationInterface $stockItemConfiguration */
$stockItemConfiguration = $this->getStockItemConfiguration->execute($sku, $stockId);
- $qtyWithReservation = $stockItemData[GetStockItemDataInterface::QUANTITY] +
+ $qtyWithReservation = $this->getProductAvailableQty->execute($sku, $stockId) +
$this->getReservationsQuantity->execute($sku, $stockId);
return $qtyWithReservation > $stockItemConfiguration->getMinQty();
diff --git a/vendor/magento/module-inventory-sales/Model/ResourceModel/IsStockItemSalableCondition/BackordersCondition.php b/vendor/magento/module-inventory-sales/Model/ResourceModel/IsStockItemSalableCondition/BackordersCondition.php
index 60dedd6612e..74594829ef7 100644
--- a/vendor/magento/module-inventory-sales/Model/ResourceModel/IsStockItemSalableCondition/BackordersCondition.php
+++ b/vendor/magento/module-inventory-sales/Model/ResourceModel/IsStockItemSalableCondition/BackordersCondition.php
@@ -40,7 +40,12 @@ class BackordersCondition implements GetIsStockItemSalableConditionInterface
$itemBackordersCondition = 'legacy_stock_item.backorders <> ' . StockItemConfigurationInterface::BACKORDERS_NO;
$useDefaultBackorders = 'legacy_stock_item.use_config_backorders';
$itemMinQty = 'legacy_stock_item.min_qty';
- $itemQty = 'legacy_stock_item.qty';
+ $globalMinQty = (float) $this->configuration->getMinQty();
+ $minQty = (string) $select->getConnection()->getCheckSql(
+ 'legacy_stock_item.use_config_min_qty = 1',
+ $globalMinQty,
+ $itemMinQty
+ );
$isBackorderEnabled = $globalBackorders === StockItemConfigurationInterface::BACKORDERS_NO
? $useDefaultBackorders . ' = ' . StockItemConfigurationInterface::BACKORDERS_NO . ' AND ' .
@@ -55,6 +60,6 @@ class BackordersCondition implements GetIsStockItemSalableConditionInterface
1
);
- return "($isBackorderEnabled) AND ($itemMinQty >= 0 OR $itemQty > $itemMinQty) AND SUM($isAnyStockItemInStock)";
+ return "($isBackorderEnabled) AND ($minQty >= 0) AND SUM($isAnyStockItemInStock)";
}
}
diff --git a/vendor/magento/module-inventory-sales/Model/ResourceModel/IsStockItemSalableCondition/MinQtyStockWithReservationsCondition.php b/vendor/magento/module-inventory-sales/Model/ResourceModel/IsStockItemSalableCondition/MinQtyStockWithReservationsCondition.php
new file mode 100644
index 00000000000..2844815bb79
--- /dev/null
+++ b/vendor/magento/module-inventory-sales/Model/ResourceModel/IsStockItemSalableCondition/MinQtyStockWithReservationsCondition.php
@@ -0,0 +1,59 @@
+configuration = $configuration;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function execute(Select $select): string
+ {
+ $globalMinQty = (float) $this->configuration->getMinQty();
+ $itemMinQty = 'legacy_stock_item.min_qty';
+ $inStockQty = (string) $select->getConnection()->getCheckSql(
+ 'source_item.' . SourceItemInterface::STATUS . ' = ' . SourceItemInterface::STATUS_OUT_OF_STOCK,
+ 0,
+ 'source_item.' . SourceItemInterface::QUANTITY
+ );
+ $inStockQty = 'SUM(' . $inStockQty . ')';
+ $minQty = (string) $select->getConnection()->getCheckSql(
+ 'legacy_stock_item.use_config_min_qty = 1',
+ $globalMinQty,
+ $itemMinQty
+ );
+ $reservationQty = (string) $select->getConnection()->getCheckSql(
+ 'reservations.reservation_qty IS NULL',
+ 0,
+ 'reservations.reservation_qty'
+ );
+
+ return "$inStockQty + $reservationQty - $minQty > 0";
+ }
+}
diff --git a/vendor/magento/module-inventory-sales/etc/di.xml b/vendor/magento/module-inventory-sales/etc/di.xml
index 12b95a87743..70329af3ef8 100644
--- a/vendor/magento/module-inventory-sales/etc/di.xml
+++ b/vendor/magento/module-inventory-sales/etc/di.xml
@@ -45,12 +45,9 @@
- Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\BackordersCondition
- Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\ManageStockCondition
- - Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\MinQtyStockCondition
+ - Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\MinQtyStockWithReservationsCondition
- Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\SkuIsAbsentInCatalogCondition
-
- - Magento\InventorySales\Model\ResourceModel\IsStockItemSalableCondition\ReservationsCondition
-