Skip to content
This repository was archived by the owner on Dec 19, 2019. It is now read-only.

Return product stock data #125

Merged
merged 15 commits into from
Sep 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogInventoryGraphQl\Model\Resolver;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\CatalogInventory\Model\Configuration;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Store\Model\ScopeInterface;

/**
* {@inheritdoc}
*/
class OnlyXLeftInStockResolver implements ResolverInterface
{
/**
* @var ValueFactory
*/
private $valueFactory;

/**
* @var ScopeConfigInterface
*/
private $scopeConfig;

/**
* @var StockRegistryInterface
*/
private $stockRegistry;

/**
* @param ValueFactory $valueFactory
* @param ScopeConfigInterface $scopeConfig
* @param StockRegistryInterface $stockRegistry
*/
public function __construct(
ValueFactory $valueFactory,
ScopeConfigInterface $scopeConfig,
StockRegistryInterface $stockRegistry
) {
$this->valueFactory = $valueFactory;
$this->scopeConfig = $scopeConfig;
$this->stockRegistry = $stockRegistry;
}

/**
* {@inheritdoc}
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null): Value
{
if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) {
$result = function () {
return null;
};

return $this->valueFactory->create($result);
}

/* @var $product ProductInterface */
$product = $value['model'];
$onlyXLeftQty = $this->getOnlyXLeftQty($product);

$result = function () use ($onlyXLeftQty) {
return $onlyXLeftQty;
};

return $this->valueFactory->create($result);
}

/**
* Get product qty left when "Catalog > Inventory > Stock Options > Only X left Threshold" is greater than 0
*
* @param ProductInterface $product
*
* @return null|float
*/
private function getOnlyXLeftQty(ProductInterface $product): ?float
{
$thresholdQty = (float)$this->scopeConfig->getValue(
Configuration::XML_PATH_STOCK_THRESHOLD_QTY,
ScopeInterface::SCOPE_STORE
);
if ($thresholdQty === 0) {
return null;
}

$stockItem = $this->stockRegistry->getStockItem($product->getId());

$stockCurrentQty = $this->stockRegistry->getStockStatus(
$product->getId(),
$product->getStore()->getWebsiteId()
)->getQty();

$stockLeft = $stockCurrentQty - $stockItem->getMinQty();

$thresholdQty = (float)$this->scopeConfig->getValue(
Configuration::XML_PATH_STOCK_THRESHOLD_QTY,
ScopeInterface::SCOPE_STORE
);

if ($stockCurrentQty > 0 && $stockLeft <= $thresholdQty) {
return $stockLeft;
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogInventoryGraphQl\Model\Resolver;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\CatalogInventory\Api\Data\StockStatusInterface;
use Magento\CatalogInventory\Api\StockStatusRepositoryInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;

/**
* {@inheritdoc}
*/
class StockStatusProvider implements ResolverInterface
{
/**
* @var ValueFactory
*/
private $valueFactory;

/**
* @var StockStatusRepositoryInterface
*/
private $stockStatusRepository;

/**
* @param ValueFactory $valueFactory
* @param StockStatusRepositoryInterface $stockStatusRepository
*/
public function __construct(ValueFactory $valueFactory, StockStatusRepositoryInterface $stockStatusRepository)
{
$this->valueFactory = $valueFactory;
$this->stockStatusRepository = $stockStatusRepository;
}

/**
* {@inheritdoc}
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null): Value
{
if (!array_key_exists('model', $value) || !$value['model'] instanceof ProductInterface) {
$result = function () {
return null;
};

return $this->valueFactory->create($result);
}

/* @var $product ProductInterface */
$product = $value['model'];

$stockStatus = $this->stockStatusRepository->get($product->getId());
$productStockStatus = (int)$stockStatus->getStockStatus();

$result = function () use ($productStockStatus) {
return $productStockStatus === StockStatusInterface::STATUS_IN_STOCK ? 'IN_STOCK' : 'OUT_OF_STOCK';
};

return $this->valueFactory->create($result);
}
}
4 changes: 4 additions & 0 deletions app/code/Magento/CatalogInventoryGraphQl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# CatalogInventoryGraphQl

**CatalogInventoryGraphQl** provides type information for the GraphQl module
to generate inventory stock fields for product information endpoints.
24 changes: 24 additions & 0 deletions app/code/Magento/CatalogInventoryGraphQl/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "magento/module-catalog-inventory-graph-ql",
"description": "N/A",
"type": "magento2-module",
"require": {
"php": "~7.1.3||~7.2.0",
"magento/framework": "*",
"magento/module-store": "*",
"magento/module-catalog": "*",
"magento/module-catalog-inventory": "*"
},
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Magento\\CatalogInventoryGraphQl\\": ""
}
}
}
16 changes: 16 additions & 0 deletions app/code/Magento/CatalogInventoryGraphQl/etc/module.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magento_CatalogInventoryGraphQl">
<sequence>
<module name="Magento_Store"/>
<module name="Magento_Catalog"/>
<module name="Magento_CatalogInventory"/>
</sequence>
</module>
</config>
12 changes: 12 additions & 0 deletions app/code/Magento/CatalogInventoryGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright © Magento, Inc. All rights reserved.
# See COPYING.txt for license details.

interface ProductInterface {
only_x_left_in_stock: Float @doc(description: "Product stock only x left count") @resolver(class: "Magento\\CatalogInventoryGraphQl\\Model\\Resolver\\OnlyXLeftInStockResolver")
stock_status: ProductStockStatus @doc(description: "Stock status of the product") @resolver(class: "Magento\\CatalogInventoryGraphQl\\Model\\Resolver\\StockStatusProvider")
}

enum ProductStockStatus @doc(description: "This enumeration states whether a product stock status is in stock or out of stock") {
IN_STOCK
OUT_OF_STOCK
}
10 changes: 10 additions & 0 deletions app/code/Magento/CatalogInventoryGraphQl/registration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_CatalogInventoryGraphQl', __DIR__);
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"magento/module-catalog-analytics": "*",
"magento/module-catalog-import-export": "*",
"magento/module-catalog-inventory": "*",
"magento/module-catalog-inventory-graph-ql": "*",
"magento/module-catalog-rule": "*",
"magento/module-catalog-rule-configurable": "*",
"magento/module-catalog-search": "*",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\GraphQl\CatalogInventory;

use Magento\TestFramework\TestCase\GraphQlAbstract;

class ProductOnlyXLeftInStockTest extends GraphQlAbstract
{
/**
* @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_all_fields.php
*/
public function testQueryProductOnlyXLeftInStockDisabled()
{
$this->cleanCache();
$productSku = 'simple';

$query = <<<QUERY
{
products(filter: {sku: {eq: "{$productSku}"}})
{
items {
only_x_left_in_stock
}
}
}
QUERY;

$response = $this->graphQlQuery($query);

$this->assertArrayHasKey(0, $response['products']['items']);
$this->assertArrayHasKey('only_x_left_in_stock', $response['products']['items'][0]);
$this->assertNull($response['products']['items'][0]['only_x_left_in_stock']);
}

/**
* @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_all_fields.php
* @magentoConfigFixture default_store cataloginventory/options/stock_threshold_qty 120
*/
public function testQueryProductOnlyXLeftInStockEnabled()
{
$productSku = 'simple';

$query = <<<QUERY
{
products(filter: {sku: {eq: "{$productSku}"}})
{
items {
only_x_left_in_stock
}
}
}
QUERY;
$response = $this->graphQlQuery($query);

$this->assertArrayHasKey(0, $response['products']['items']);
$this->assertArrayHasKey('only_x_left_in_stock', $response['products']['items'][0]);
$this->assertEquals(100, $response['products']['items'][0]['only_x_left_in_stock']);
}
}
Loading