diff --git a/src/Model/Resolver/EntityUrl.php b/src/Model/Resolver/EntityUrl.php index 132f656..6721218 100644 --- a/src/Model/Resolver/EntityUrl.php +++ b/src/Model/Resolver/EntityUrl.php @@ -10,21 +10,22 @@ namespace ScandiPWA\UrlrewriteGraphQl\Model\Resolver; +use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\CatalogInventory\Api\StockStateInterface; +use Magento\CatalogInventory\Model\Stock\StockItemRepository; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface; -use Magento\Catalog\Api\CategoryRepositoryInterface; -use Magento\CatalogInventory\Model\Stock\StockItemRepository; -use Magento\Store\Model\ScopeInterface; /** * UrlRewrite field resolver, used for GraphQL request processing. @@ -71,6 +72,10 @@ class EntityUrl implements ResolverInterface */ private $scopeConfig; + /** + * @var StockStateInterface + */ + private $stockState; /** * @param UrlFinderInterface $urlFinder @@ -80,6 +85,7 @@ class EntityUrl implements ResolverInterface * @param CategoryRepositoryInterface $categoryRepository * @param StockItemRepository $stockItemRepository * @param ScopeConfigInterface $scopeConfig + * @param StockStateInterface $stockState */ public function __construct( UrlFinderInterface $urlFinder, @@ -88,7 +94,8 @@ public function __construct( CollectionFactory $productCollectionFactory, CategoryRepositoryInterface $categoryRepository, StockItemRepository $stockItemRepository, - ScopeConfigInterface $scopeConfig + ScopeConfigInterface $scopeConfig, + StockStateInterface $stockState ) { $this->urlFinder = $urlFinder; $this->storeManager = $storeManager; @@ -97,6 +104,7 @@ public function __construct( $this->categoryRepository = $categoryRepository; $this->stockItemRepository = $stockItemRepository; $this->scopeConfig = $scopeConfig; + $this->stockState = $stockState; } /** @@ -141,10 +149,20 @@ public function resolve( $product = $collection->addIdFilter($id)->getFirstItem(); $isInStock = false; - try { - $isInStock = $this->stockItemRepository->get($id)->getIsInStock(); - } catch (NoSuchEntityException $e) { - // Ignoring error is safe + switch ($product['type_id']) { + case 'configurable': + $isInStock = $this->getConfigurableProductStockState($product); + break; + case 'bundle': + $isInStock = $this->getBundleProductsStockState($this->getBundleProductChildrenItems($product, $id)); + break; + default: + try { + $isInStock = $this->stockItemRepository->get($id)->getIsInStock(); + } catch (NoSuchEntityException $e) { + // Ignoring error is safe + } + break; } $isOutOfStockDisplay = $this->scopeConfig->getValue( @@ -239,4 +257,36 @@ private function sanitizeType(string $type) : string { return strtoupper(str_replace('-', '_', $type)); } + + private function getBundleProductChildrenItems($product, $id) + { + $typeInstance = $product->getTypeInstance(); + return $typeInstance->getChildrenIds($id, true); + } + + private function getBundleProductsStockState($childrenProductsCollection) : bool + { + $total_stock = 0; + foreach ($childrenProductsCollection as $value) { + foreach ($value as $concreteIndex) { + $total_stock += $this->stockState->getStockQty($concreteIndex); + } + } + + return $total_stock > 0; + } + + private function getConfigurableProductStockState($product) : bool + { + $totalStock = 0; + if ($product->getTypeID() === 'configurable') { + $productTypeInstance = $product->getTypeInstance(); + $usedProducts = $productTypeInstance->getUsedProducts($product); + foreach ($usedProducts as $simple) { + $totalStock += $this->stockState->getStockQty($simple->getId(), $simple->getStore()->getWebsiteId()); + } + } + + return $totalStock > 0; + } }