Failed Conditions
Push — experimental/sf ( fbc478...690bfa )
by Kiyotaka
339:17 queued 330:43
created

OrderStateMachine::updateShippingDate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
ccs 5
cts 5
cp 1
crap 3

1 Method

Rating   Name   Duplication   Size   Complexity  
A OrderStateMachine::commitUsePoint() 0 6 1
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 140
    public function __construct(StateMachine $_orderStateMachine, OrderStatusRepository $orderStatusRepository, PointProcessor $pointProcessor, StockReduceProcessor $stockReduceProcessor)
48
    {
49 140
        $this->machine = $_orderStateMachine;
50 140
        $this->orderStatusRepository = $orderStatusRepository;
51 140
        $this->pointProcessor = $pointProcessor;
52 140
        $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 11
    public function apply(Order $Order, OrderStatus $OrderStatus)
62
    {
63 11
        $context = $this->newContext($Order);
64 11
        $transition = $this->getTransition($context, $OrderStatus);
65 11
        if ($transition) {
66 11
            $this->machine->apply($context, $transition->getName());
67
        } else {
68
            throw new \InvalidArgumentException();
69
        }
70
    }
71
72
    /**
73
     * 指定ステータスに遷移できるかどうかを判定.
74
     *
75
     * @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...
76
     * @param OrderStatus $OrderStatus 遷移先ステータス
77
     *
78
     * @return boolean 指定ステータスに遷移できる場合はtrue
79
     */
80 44
    public function can(Order $Order, OrderStatus $OrderStatus)
81
    {
82 44
        return !is_null($this->getTransition($this->newContext($Order), $OrderStatus));
83
    }
84
85 50
    private function getTransition(OrderStateMachineContext $context, OrderStatus $OrderStatus)
86
    {
87 50
        $transitions = $this->machine->getEnabledTransitions($context);
88 50
        foreach ($transitions as $t) {
89 47
            if (in_array($OrderStatus->getId(), $t->getTos())) {
90 47
                return $t;
91
            }
92
        }
93
94 30
        return null;
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100 1
    public static function getSubscribedEvents()
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
101
    {
102
        return [
103 1
            'workflow.order.completed' => ['onCompleted'],
104
            'workflow.order.transition.pay' => ['updatePaymentDate'],
105
            'workflow.order.transition.cancel' => [['rollbackStock'], ['rollbackUsePoint']],
106
            'workflow.order.transition.back_to_in_progress' => [['commitStock'], ['commitUsePoint']],
107
            'workflow.order.transition.ship' => [['commitAddPoint']],
108
            'workflow.order.transition.return' => [['rollbackUsePoint'], ['rollbackAddPoint']],
109
            'workflow.order.transition.cancel_return' => [['commitUsePoint'], ['commitAddPoint']],
110
        ];
111
    }
112
113
    /*
114
     * Event handlers.
115
     */
116
117
    /**
118
     * 入金日を更新する.
119
     *
120
     * @param Event $event
121
     */
122 1
    public function updatePaymentDate(Event $event)
123
    {
124
        /* @var Order $Order */
125 1
        $Order = $event->getSubject()->getOrder();
126 1
        $Order->setPaymentDate(new \DateTime());
127
    }
128
129
    /**
130
     * 会員の保有ポイントを減らす.
131
     *
132
     * @param Event $event
133
     *
134
     * @throws PurchaseFlow\PurchaseException
135
     */
136 2
    public function commitUsePoint(Event $event)
137
    {
138
        /* @var Order $Order */
139 2
        $Order = $event->getSubject()->getOrder();
140 2
        $this->pointProcessor->prepare($Order, new PurchaseContext());
141
    }
142
143
    /**
144
     * 利用ポイントを会員に戻す.
145
     *
146
     * @param Event $event
147
     */
148 2
    public function rollbackUsePoint(Event $event)
149
    {
150
        /* @var Order $Order */
151 2
        $Order = $event->getSubject()->getOrder();
152 2
        $this->pointProcessor->rollback($Order, new PurchaseContext());
153
    }
154
155
    /**
156
     * 在庫を減らす.
157
     *
158
     * @param Event $event
159
     *
160
     * @throws PurchaseFlow\PurchaseException
161
     */
162 1
    public function commitStock(Event $event)
163
    {
164
        /* @var Order $Order */
165 1
        $Order = $event->getSubject()->getOrder();
166 1
        $this->stockReduceProcessor->prepare($Order, new PurchaseContext());
167
    }
168
169
    /**
170
     * 在庫を戻す.
171
     *
172
     * @param Event $event
173
     */
174 1
    public function rollbackStock(Event $event)
175
    {
176
        /* @var Order $Order */
177 1
        $Order = $event->getSubject()->getOrder();
178 1
        $this->stockReduceProcessor->rollback($Order, new PurchaseContext());
179
    }
180
181
    /**
182
     * 会員に加算ポイントを付与する.
183
     *
184
     * @param Event $event
185
     */
186 4 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...
187
    {
188
        /* @var Order $Order */
189 4
        $Order = $event->getSubject()->getOrder();
190 4
        $Customer = $Order->getCustomer();
191 4
        if ($Customer) {
192 4
            $Customer->setPoint(intval($Customer->getPoint()) + intval($Order->getAddPoint()));
193
        }
194
    }
195
196
    /**
197
     * 会員に付与した加算ポイントを取り消す.
198
     *
199
     * @param Event $event
200
     */
201 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...
202
    {
203
        /* @var Order $Order */
204 1
        $Order = $event->getSubject()->getOrder();
205 1
        $Customer = $Order->getCustomer();
206 1
        if ($Customer) {
207 1
            $Customer->setPoint(intval($Customer->getPoint()) - intval($Order->getAddPoint()));
208
        }
209
    }
210
211
    /**
212
     * 受注ステータスを再設定.
213
     * {@link StateMachine}によって遷移が終了したときには{@link Order#OrderStatus}のidが変更されるだけなのでOrderStatusを設定し直す.
214
     *
215
     * @param Event $event
216
     */
217 11
    public function onCompleted(Event $event)
218
    {
219
        /** @var $context OrderStateMachineContext */
220 11
        $context = $event->getSubject();
221 11
        $Order = $context->getOrder();
222 11
        $CompletedOrderStatus = $this->orderStatusRepository->find($context->getStatus());
223 11
        $Order->setOrderStatus($CompletedOrderStatus);
224
    }
225
226 50
    private function newContext(Order $Order)
227
    {
228 50
        return new OrderStateMachineContext((string) $Order->getOrderStatus()->getId(), $Order);
229
    }
230
}
231
232
class OrderStateMachineContext
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
introduced by
Missing class doc comment
Loading history...
introduced by
Multiple classes defined in a single file
Loading history...
233
{
234
    /** @var string */
235
    private $status;
236
237
    /** @var Order */
238
    private $Order;
239
240
    /**
241
     * OrderStateMachineContext constructor.
242
     *
243
     * @param string $status
244
     * @param Order $Order
0 ignored issues
show
introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
245
     */
246 50
    public function __construct($status, Order $Order)
247
    {
248 50
        $this->status = $status;
249 50
        $this->Order = $Order;
250
    }
251
252
    /**
253
     * @return string
254
     */
255 50
    public function getStatus()
256
    {
257 50
        return $this->status;
258
    }
259
260
    /**
261
     * @param string $status
262
     */
263 11
    public function setStatus($status)
264
    {
265 11
        $this->status = $status;
266
    }
267
268
    /**
269
     * @return Order
270
     */
271 11
    public function getOrder()
272
    {
273 11
        return $this->Order;
274
    }
275
}
276