Failed Conditions
Pull Request — experimental/sf (#3247)
by Kiyotaka
114:07 queued 103:28
created

StockReduceProcessor   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 94.44%

Importance

Changes 0
Metric Value
dl 0
loc 63
rs 10
c 0
b 0
f 0
ccs 17
cts 18
cp 0.9444
wmc 7
lcom 1
cbo 2

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A prepare() 0 7 1
A rollback() 0 7 1
A eachProductOrderItems() 0 23 4
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Service\PurchaseFlow\Processor;
15
16
use Doctrine\DBAL\LockMode;
17
use Eccube\Entity\ItemHolderInterface;
18
use Eccube\Entity\Order;
19
use Eccube\Entity\ProductStock;
20
use Eccube\Repository\ProductStockRepository;
21
use Eccube\Service\PurchaseFlow\PurchaseContext;
22
23
/**
24
 * 在庫制御.
25
 */
26
class StockReduceProcessor extends AbstractPurchaseProcessor
27
{
28
    /**
29
     * @var ProductStockRepository
30
     */
31
    protected $productStockRepository;
32
33
    /**
34
     * StockReduceProcessor constructor.
35
     *
36
     * @param ProductStockRepository $productStockRepository
37
     */
38 61
    public function __construct(ProductStockRepository $productStockRepository)
39
    {
40 61
        $this->productStockRepository = $productStockRepository;
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function prepare(ItemHolderInterface $itemHolder, PurchaseContext $context)
47
    {
48
        // 在庫を減らす
49 7
        $this->eachProductOrderItems($itemHolder, function ($currentStock, $itemQuantity) {
50 3
            return $currentStock - $itemQuantity;
51 7
        });
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function rollback(ItemHolderInterface $itemHolder, PurchaseContext $context)
58
    {
59
        // 在庫を戻す
60 1
        $this->eachProductOrderItems($itemHolder, function ($currentStock, $itemQuantity) {
61 1
            return $currentStock + $itemQuantity;
62 1
        });
63
    }
64
65 8
    private function eachProductOrderItems(ItemHolderInterface $itemHolder, callable $callback)
66
    {
67
        // Order以外の場合は何もしない
68 8
        if (!$itemHolder instanceof Order) {
69
            return;
70
        }
71
72 8
        foreach ($itemHolder->getProductOrderItems() as $item) {
73
            // 在庫が無制限かチェックし、制限ありなら在庫数をチェック
74 8
            if (!$item->getProductClass()->isStockUnlimited()) {
75
                // 在庫チェックあり
76
                // 在庫に対してロック(select ... for update)を実行
77
                /* @var ProductStock $productStock */
78 4
                $productStock = $this->productStockRepository->find(
79 4
                    $item->getProductClass()->getProductStock()->getId(), LockMode::PESSIMISTIC_WRITE
80
                );
81
82 4
                $stock = $callback($productStock->getStock(), $item->getQuantity());
83 4
                $productStock->setStock($stock);
84 8
                $item->getProductClass()->setStock($stock);
85
            }
86
        }
87
    }
88
}
89