Skip to content
Open
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
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());
}
}
}