Failed Conditions
Pull Request — experimental/sf (#3385)
by chihiro
57:31 queued 48:54
created

OrderStateMachine   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 213
Duplicated Lines 8.45 %

Coupling/Cohesion

Components 4
Dependencies 7

Test Coverage

Coverage 98.15%

Importance

Changes 0
Metric Value
dl 18
loc 213
rs 10
c 0
b 0
f 0
ccs 53
cts 54
cp 0.9815
wmc 20
lcom 4
cbo 7

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A apply() 0 9 2
A can() 0 4 1
A getTransition() 0 11 3
A getSubscribedEvents() 0 12 1
A updatePaymentDate() 0 6 1
A updateShippingDate() 0 8 2
A commitUsePoint() 0 6 1
A rollbackUsePoint() 0 6 1
A commitStock() 0 6 1
A rollbackStock() 0 6 1
A commitAddPoint() 9 9 2
A rollbackAddPoint() 9 9 2
A onCompleted() 0 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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;
15
16
use Eccube\Entity\Master\OrderStatus;
17
use Eccube\Entity\Order;
18
use Eccube\Repository\Master\OrderStatusRepository;
19
use Eccube\Service\PurchaseFlow\Processor\PointProcessor;
20
use Eccube\Service\PurchaseFlow\Processor\StockReduceProcessor;
21
use Eccube\Service\PurchaseFlow\PurchaseContext;
22
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
23
use Symfony\Component\Workflow\Event\Event;
24
use Symfony\Component\Workflow\StateMachine;
25
26
class OrderStateMachine implements EventSubscriberInterface
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
27
{
28
    /**
29
     * @var StateMachine
30
     */
31
    private $machine;
32
33
    /**
34
     * @var OrderStatusRepository
35
     */
36
    private $orderStatusRepository;
37
38
    /**
39
     * @var PointProcessor
40
     */
41
    private $pointProcessor;
42
    /**
43
     * @var StockReduceProcessor
44
     */
45
    private $stockReduceProcessor;
46
47 116
    public function __construct(StateMachine $_orderStateMachine, OrderStatusRepository $orderStatusRepository, PointProcessor $pointProcessor, StockReduceProcessor $stockReduceProcessor)
48
    {
49 116
        $this->machine = $_orderStateMachine;
50 116
        $this->orderStatusRepository = $orderStatusRepository;
51 116
        $this->pointProcessor = $pointProcessor;
52 116
        $this->stockReduceProcessor = $stockReduceProcessor;
53
    }
54
55
    /**
56
     * 指定ステータスに遷移.
57
     *
58
     * @param Order $Order 受注
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
introduced by
Expected 7 spaces after parameter name; 1 found
Loading history...
59
     * @param OrderStatus $OrderStatus 遷移先ステータス
60
     */
61 9
    public function apply(Order $Order, OrderStatus $OrderStatus)
62
    {
63 9
        $transition = $this->getTransition($Order, $OrderStatus);
64 9
        if ($transition) {
65 9
            $this->machine->apply($Order, $transition->getName());
66
        } else {
67
            throw new \InvalidArgumentException();
68
        }
69
    }
70
71
    /**
72
     * 指定ステータスに遷移できるかどうかを判定.
73
     *
74
     * @param Order $Order 受注
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
introduced by
Expected 7 spaces after parameter name; 1 found
Loading history...
75
     * @param OrderStatus $OrderStatus 遷移先ステータス
76
     *
77
     * @return boolean 指定ステータスに遷移できる場合はtrue
78
     */
79 40
    public function can(Order $Order, OrderStatus $OrderStatus)
80
    {
81 40
        return !is_null($this->getTransition($Order, $OrderStatus));
82
    }
83
84 46
    private function getTransition(Order $Order, OrderStatus $OrderStatus)
85
    {
86 46
        $transitions = $this->machine->getEnabledTransitions($Order);
87 46
        foreach ($transitions as $t) {
88 45
            if (in_array($OrderStatus->getId(), $t->getTos())) {
89 45
                return $t;
90
            }
91
        }
92
93 28
        return null;
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 1
    public static function getSubscribedEvents()
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
100
    {
101
        return [
102 1
            'workflow.order.completed' => ['onCompleted'],
103
            'workflow.order.transition.pay' => ['updatePaymentDate'],
104
            'workflow.order.transition.cancel' => [['rollbackStock'], ['rollbackUsePoint']],
105
            'workflow.order.transition.back_to_in_progress' => [['commitStock'], ['commitUsePoint']],
106
            'workflow.order.transition.ship' => [['commitAddPoint'], ['updateShippingDate']],
107
            'workflow.order.transition.return' => [['rollbackUsePoint'], ['rollbackAddPoint']],
108
            'workflow.order.transition.cancel_return' => [['commitUsePoint'], ['commitAddPoint']],
109
        ];
110
    }
111
112
    /*
113
     * Event handlers.
114
     */
115
116
    /**
117
     * 入金日を更新する.
118
     *
119
     * @param Event $event
120
     */
121 1
    public function updatePaymentDate(Event $event)
122
    {
123
        /* @var Order $Order */
124 1
        $Order = $event->getSubject();
125 1
        $Order->setPaymentDate(new \DateTime());
126
    }
127
128
    /**
129
     * 発送日を更新する.
130
     *
131
     * @param Event $event
132
     */
133 1
    public function updateShippingDate(Event $event)
134
    {
135
        /* @var Order $Order */
136 1
        $Order = $event->getSubject();
137 1
        foreach ($Order->getShippings() as $Shipping) {
138 1
            $Shipping->setShippingDate(new \DateTime());
139
        }
140
    }
141
142
    /**
143
     * 会員の保有ポイントを減らす.
144
     *
145
     * @param Event $event
146
     *
147
     * @throws PurchaseFlow\PurchaseException
148
     */
149 2
    public function commitUsePoint(Event $event)
150
    {
151
        /* @var Order $Order */
152 2
        $Order = $event->getSubject();
153 2
        $this->pointProcessor->prepare($Order, new PurchaseContext());
154
    }
155
156
    /**
157
     * 利用ポイントを会員に戻す.
158
     *
159
     * @param Event $event
160
     */
161 2
    public function rollbackUsePoint(Event $event)
162
    {
163
        /* @var Order $Order */
164 2
        $Order = $event->getSubject();
165 2
        $this->pointProcessor->rollback($Order, new PurchaseContext());
166
    }
167
168
    /**
169
     * 在庫を減らす.
170
     *
171
     * @param Event $event
172
     *
173
     * @throws PurchaseFlow\PurchaseException
174
     */
175 1
    public function commitStock(Event $event)
176
    {
177
        /* @var Order $Order */
178 1
        $Order = $event->getSubject();
179 1
        $this->stockReduceProcessor->prepare($Order, new PurchaseContext());
180
    }
181
182
    /**
183
     * 在庫を戻す.
184
     *
185
     * @param Event $event
186
     */
187 1
    public function rollbackStock(Event $event)
188
    {
189
        /* @var Order $Order */
190 1
        $Order = $event->getSubject();
191 1
        $this->stockReduceProcessor->rollback($Order, new PurchaseContext());
192
    }
193
194
    /**
195
     * 会員に加算ポイントを付与する.
196
     *
197
     * @param Event $event
198
     */
199 2 View Code Duplication
    public function commitAddPoint(Event $event)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
200
    {
201
        /* @var Order $Order */
202 2
        $Order = $event->getSubject();
203 2
        $Customer = $Order->getCustomer();
204 2
        if ($Customer) {
205 2
            $Customer->setPoint(intval($Customer->getPoint()) + intval($Order->getAddPoint()));
206
        }
207
    }
208
209
    /**
210
     * 会員に付与した加算ポイントを取り消す.
211
     *
212
     * @param Event $event
213
     */
214 1 View Code Duplication
    public function rollbackAddPoint(Event $event)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
215
    {
216
        /* @var Order $Order */
217 1
        $Order = $event->getSubject();
218 1
        $Customer = $Order->getCustomer();
219 1
        if ($Customer) {
220 1
            $Customer->setPoint(intval($Customer->getPoint()) - intval($Order->getAddPoint()));
221
        }
222
    }
223
224
    /**
225
     * 受注ステータスを再設定.
226
     * {@link StateMachine}によって遷移が終了したときには{@link Order#OrderStatus}のidが変更されるだけなのでOrderStatusを設定し直す.
227
     *
228
     * @param Event $event
229
     */
230 9
    public function onCompleted(Event $event)
231
    {
232
        /** @var Order $Order */
233 9
        $Order = $event->getSubject();
234 9
        $OrderStatusId = $Order->getOrderStatus()->getId();
235 9
        $CompletedOrderStatus = $this->orderStatusRepository->find($OrderStatusId);
236 9
        $Order->setOrderStatus($CompletedOrderStatus);
237
    }
238
}
239