diff --git a/vendor/magento/module-bundle/Model/Inventory/ChangeParentStockStatus.php b/vendor/magento/module-bundle/Model/Inventory/ChangeParentStockStatus.php
new file mode 100644
index 000000000000..023893d7317e
--- /dev/null
+++ b/vendor/magento/module-bundle/Model/Inventory/ChangeParentStockStatus.php
@@ -0,0 +1,160 @@
+bundleType = $bundleType;
+ $this->criteriaInterfaceFactory = $criteriaInterfaceFactory;
+ $this->stockItemRepository = $stockItemRepository;
+ $this->stockConfiguration = $stockConfiguration;
+ }
+
+ /**
+ * Update stock status of bundle products based on children products stock status
+ *
+ * @param array $childrenIds
+ * @return void
+ */
+ public function execute(array $childrenIds): void
+ {
+ $parentIds = $this->bundleType->getParentIdsByChild($childrenIds);
+ foreach (array_unique($parentIds) as $productId) {
+ $this->processStockForParent((int)$productId);
+ }
+ }
+
+ /**
+ * Update stock status of bundle product based on children products stock status
+ *
+ * @param int $productId
+ * @return void
+ */
+ private function processStockForParent(int $productId): void
+ {
+ $stockItems = $this->getStockItems([$productId]);
+ $parentStockItem = $stockItems[$productId] ?? null;
+ if ($parentStockItem) {
+ $childrenIsInStock = $this->isChildrenInStock($productId);
+ if ($this->isNeedToUpdateParent($parentStockItem, $childrenIsInStock)) {
+ $parentStockItem->setIsInStock($childrenIsInStock);
+ $parentStockItem->setStockStatusChangedAuto(1);
+ $this->stockItemRepository->save($parentStockItem);
+ }
+ }
+ }
+
+ /**
+ * Returns stock status of bundle product based on children stock status
+ *
+ * Returns TRUE if any of the following conditions is true:
+ * - At least one product is in-stock in each required option
+ * - Any product is in-stock (if all options are optional)
+ *
+ * @param int $productId
+ * @return bool
+ */
+ private function isChildrenInStock(int $productId) : bool
+ {
+ $childrenIsInStock = false;
+ $childrenIds = $this->bundleType->getChildrenIds($productId, true);
+ $stockItems = $this->getStockItems(array_merge(...array_values($childrenIds)));
+ foreach ($childrenIds as $childrenIdsPerOption) {
+ $childrenIsInStock = false;
+ foreach ($childrenIdsPerOption as $id) {
+ $stockItem = $stockItems[$id] ?? null;
+ if ($stockItem && $stockItem->getIsInStock()) {
+ $childrenIsInStock = true;
+ break;
+ }
+ }
+ if (!$childrenIsInStock) {
+ break;
+ }
+ }
+
+ return $childrenIsInStock;
+ }
+
+ /**
+ * Check if parent item should be updated
+ *
+ * @param StockItemInterface $parentStockItem
+ * @param bool $childrenIsInStock
+ * @return bool
+ */
+ private function isNeedToUpdateParent(
+ StockItemInterface $parentStockItem,
+ bool $childrenIsInStock
+ ): bool {
+ return $parentStockItem->getIsInStock() !== $childrenIsInStock &&
+ ($childrenIsInStock === false || $parentStockItem->getStockStatusChangedAuto());
+ }
+
+ /**
+ * Get stock items for provided product IDs
+ *
+ * @param array $productIds
+ * @return StockItemInterface[]
+ */
+ private function getStockItems(array $productIds): array
+ {
+ $criteria = $this->criteriaInterfaceFactory->create();
+ $criteria->setScopeFilter($this->stockConfiguration->getDefaultScopeId());
+ $criteria->setProductsFilter(array_unique($productIds));
+ $stockItemCollection = $this->stockItemRepository->getList($criteria);
+
+ $stockItems = [];
+ foreach ($stockItemCollection->getItems() as $stockItem) {
+ $stockItems[$stockItem->getProductId()] = $stockItem;
+ }
+
+ return $stockItems;
+ }
+}
diff --git a/vendor/magento/module-bundle/Model/Inventory/ParentItemProcessor.php b/vendor/magento/module-bundle/Model/Inventory/ParentItemProcessor.php
new file mode 100644
index 000000000000..5e013ced75c3
--- /dev/null
+++ b/vendor/magento/module-bundle/Model/Inventory/ParentItemProcessor.php
@@ -0,0 +1,39 @@
+changeParentStockStatus = $changeParentStockStatus;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function process(Product $product)
+ {
+ $this->changeParentStockStatus->execute([$product->getId()]);
+ }
+}
diff --git a/vendor/magento/module-bundle/etc/di.xml b/vendor/magento/module-bundle/etc/di.xml
index 17b6d228e88e..5224151f306c 100644
--- a/vendor/magento/module-bundle/etc/di.xml
+++ b/vendor/magento/module-bundle/etc/di.xml
@@ -271,4 +271,11 @@
+
+
+
+ - Magento\Bundle\Model\Inventory\ParentItemProcessor
+
+
+
diff --git a/vendor/magento/module-bundle-import-export/Plugin/Import/Product/UpdateBundleProductsStockItemStatusPlugin.php b/vendor/magento/module-bundle-import-export/Plugin/Import/Product/UpdateBundleProductsStockItemStatusPlugin.php
new file mode 100644
index 000000000000..45013372a440
--- /dev/null
+++ b/vendor/magento/module-bundle-import-export/Plugin/Import/Product/UpdateBundleProductsStockItemStatusPlugin.php
@@ -0,0 +1,49 @@
+changeParentStockStatus = $changeParentStockStatus;
+ }
+
+ /**
+ * Update bundle products stock item status based on children products stock status after import
+ *
+ * @param StockItemImporterInterface $subject
+ * @param mixed $result
+ * @param array $stockData
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function afterImport(
+ StockItemImporterInterface $subject,
+ $result,
+ array $stockData
+ ): void {
+ if ($stockData) {
+ $this->changeParentStockStatus->execute(array_column($stockData, 'product_id'));
+ }
+ }
+}
diff --git a/vendor/magento/module-bundle-import-export/etc/di.xml b/vendor/magento/module-bundle-import-export/etc/di.xml
index 2bcbbedcc910..d697b52f628a 100644
--- a/vendor/magento/module-bundle-import-export/etc/di.xml
+++ b/vendor/magento/module-bundle-import-export/etc/di.xml
@@ -13,4 +13,9 @@
+
+
+