Skip to content

Commit

Permalink
refs EC-CUBE#109 商品価格変更の Mutation を実装
Browse files Browse the repository at this point in the history
  • Loading branch information
okazy committed Feb 18, 2021
1 parent de7758c commit 4ab2111
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 0 deletions.
116 changes: 116 additions & 0 deletions GraphQL/Mutation/UpdateProductPriceMutation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Plugin\Api\GraphQL\Mutation;

use Doctrine\ORM\EntityManager;
use Eccube\Entity\ProductClass;
use Eccube\Repository\ProductClassRepository;
use GraphQL\Type\Definition\Type;
use Plugin\Api\GraphQL\Error\InvalidArgumentException;
use Plugin\Api\GraphQL\Mutation;
use Plugin\Api\GraphQL\Types;

class UpdateProductPriceMutation implements Mutation
{
/**
* @var Types
*/
private $types;

/**
* @var ProductClassRepository
*/
private $productClassRepository;

/**
* @var EntityManager
*/
private $entityManager;

public function __construct(
Types $types,
ProductClassRepository $productClassRepository,
EntityManager $entityManager
) {
$this->types = $types;
$this->productClassRepository = $productClassRepository;
$this->entityManager = $entityManager;
}

public function getName()
{
return 'updateProductPrice';
}

public function getMutation()
{
return [
'type' => $this->types->get(ProductClass::class),
'args' => [
'code' => [
'type' => Type::nonNull(Type::string()),
'description' => trans('api.update_product_price.args.description.product_code'),
],
'price01' => [
'type' => Type::int(),
'description' => trans('api.update_product_price.args.description.price01'),
],
'price02' => [
'type' => Type::nonNull(Type::int()),
'description' => trans('api.update_product_price.args.description.price02'),
],
],
'resolve' => [$this, 'updateProductPrice'],
];
}

public function updateProductPrice($root, $args)
{
$ProductClasses = $this->productClassRepository->findBy(['code' => $args['code']]);

// 更新対象の商品規格をチェック
if (count($ProductClasses) < 1) {
throw new InvalidArgumentException('code: No ProductClass found;');
}
if (count($ProductClasses) > 1) {
throw new InvalidArgumentException('code: Multiple ProductClass found;');
}

/** @var ProductClass $ProductClass */
$ProductClass = current($ProductClasses);

// price01 が指定されている場合は通常価格を更新
if (array_key_exists('price01', $args)) {
if ($args['price01'] < 0) {
throw new InvalidArgumentException('price01: price01 should be 0 or more.;');
}

$ProductClass->setPrice01($args['price01']);
}

// price02 が指定されている場合は販売価格を更新
if (array_key_exists('price02', $args)) {
if ($args['price02'] < 0) {
throw new InvalidArgumentException('price02: price02 should be 0 or more.;');
}

$ProductClass->setPrice02($args['price02']);
}

$this->productClassRepository->save($ProductClass);
$this->entityManager->flush();

return $ProductClass;
}
}
6 changes: 6 additions & 0 deletions Resource/locale/messages.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ api:
product_code: SKU
stock: Stock (If the stock_unlimited is set to false, please set the value more than 0.)
stock_unlimited: 'Stock unlimited (Specify false: Limited or true: Unlimited)'
update_product_price:
args:
description:
product_code: SKU
price01: Regular Price
price02: Selling Price
update_shipped:
args:
description:
Expand Down
6 changes: 6 additions & 0 deletions Resource/locale/messages.ja.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ api:
product_code: 商品コード
stock: 在庫数(在庫無制限の場合、0以上の数値を指定)
stock_unlimited: 在庫無制限(無制限は true 、制限は false を指定)
update_product_price:
args:
description:
product_code: 商品コード
price01: 通常価格
price02: 販売価格
update_shipped:
args:
description:
Expand Down
131 changes: 131 additions & 0 deletions Tests/GraphQL/Mutation/UpdateProductPriceMutationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Plugin\Api\Tests\GraphQL\Mutation;

use Eccube\Entity\ProductClass;
use Eccube\Repository\ProductClassRepository;
use Eccube\Tests\EccubeTestCase;
use Plugin\Api\GraphQL\Error\InvalidArgumentException;
use Plugin\Api\GraphQL\Mutation\UpdateProductPriceMutation;
use Plugin\Api\GraphQL\Types;

class UpdateProductPriceMutationTest extends EccubeTestCase
{
/** @var ProductClassRepository */
private $productClassRepository;

/** @var UpdateProductPriceMutation */
private $updateProductPriceMutation;

public function setUp()
{
parent::setUp();
$types = $this->container->get(Types::class);
$this->productClassRepository = $this->container->get(ProductClassRepository::class);
$this->updateProductPriceMutation = new UpdateProductPriceMutation($types, $this->productClassRepository, $this->entityManager);

// テスト用の商品を作成
$Product = $this->createProduct();
/** @var ProductClass[] $ProductClasses */
$ProductClasses = $Product->getProductClasses();

$ProductClasses[0]->setCode('produce-code');
$ProductClasses[0]->setPrice01(2000);
$ProductClasses[0]->setPrice02(1000);

$ProductClasses[1]->setCode('produce-code2');
$ProductClasses[1]->setPrice01(2000);
$ProductClasses[1]->setPrice02(1000);

$this->entityManager->persist($Product);
$this->entityManager->flush();
}

/**
* @dataProvider updateProductPriceProvider
*
* @param $args
* @param $expectPrice01
* @param $expectPrice02
* @param $expectExeption
*/
public function testUpdateProductPrice($args, $expectPrice01, $expectPrice02, $expectExeption)
{
try {
$ProductClass = $this->updateProductPriceMutation->updateProductPrice(null, $args);

// レスポンスの確認
self::assertEquals($expectPrice01, $ProductClass->getPrice01());
self::assertEquals($expectPrice02, $ProductClass->getPrice02());
} catch (InvalidArgumentException $e) {
// エラーの確認
self::assertRegExp($expectExeption, $e->getMessage());
}

// DBの確認
/** @var ProductClass[] $ProductClasses */
$ProductClasses = $this->productClassRepository->findBy(['code' => $args['code']]);
$this->entityManager->refresh($ProductClasses[0]);
self::assertEquals($expectPrice01, $ProductClasses[0]->getPrice01());
self::assertEquals($expectPrice02, $ProductClasses[0]->getPrice02());
}

public function updateProductPriceProvider()
{
return [
[['code' => 'produce-code', 'price01' => 200, 'price02' => 100], 200, 100, false],
[['code' => 'produce-code', 'price01' => 200, 'price02' => 0], 200, 0, false],
[['code' => 'produce-code', 'price01' => 200, 'price02' => -1], 2000, 1000, '/price02 should be 0 or more./'],
[['code' => 'produce-code', 'price01' => 0, 'price02' => 100], 0, 100, false],
[['code' => 'produce-code', 'price01' => -1, 'price02' => 100], 2000, 1000, '/price01 should be 0 or more./'],
[['code' => 'produce-code', 'price01' => null, 'price02' => 100], null, 100, false],
[['code' => 'produce-code', 'price02' => 100], 2000, 100, false],
];
}

/**
* 重複するcodeを指定して更新
*/
public function testUpdateProductPriceMultiple()
{
// プロダクトコードを重複させる
$ProductClasses = $this->productClassRepository->findBy(['code' => 'produce-code']);
$ProductClasses[0]->setCode('code-multiple');
$ProductClasses = $this->productClassRepository->findBy(['code' => 'produce-code2']);
$ProductClasses[0]->setCode('code-multiple');
$this->entityManager->flush();

try {
$this->updateProductPriceMutation->updateProductPrice(null, ['code' => 'code-multiple']);
// 通らない
self::assertTrue(false);
} catch (InvalidArgumentException $e) {
self::assertRegExp('/Multiple ProductClass found/', $e->getMessage());
}
}

/**
* 存在しないcodeを指定して更新
*/
public function testUpdateProductPriceNoData()
{
try {
$this->updateProductPriceMutation->updateProductPrice(null, ['code' => 'code-multiple', 'price01' => 200, 'price02' => 100]);
// 通らない
self::assertTrue(false);
} catch (InvalidArgumentException $e) {
self::assertRegExp('/No ProductClass found/', $e->getMessage());
}
}
}

0 comments on commit 4ab2111

Please sign in to comment.