Completed
Pull Request — experimental/sf (#3412)
by Kentaro
14:51 queued 07:29
created

PurchaseFlow   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 279
Duplicated Lines 17.56 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 95.5%

Importance

Changes 0
Metric Value
dl 49
loc 279
ccs 106
cts 111
cp 0.955
rs 9.68
c 0
b 0
f 0
wmc 34
lcom 2
cbo 2

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A setPurchaseProcessors() 0 4 1
A setItemValidators() 0 4 1
A setItemHolderValidators() 0 4 1
A setItemPreprocessors() 0 4 1
A setItemHolderPreprocessors() 0 4 1
B validate() 0 38 7
A prepare() 0 6 2
A commit() 0 6 2
A rollback() 0 6 2
A addPurchaseProcessor() 0 4 1
A addItemHolderPreprocessor() 0 4 1
A addItemPreprocessor() 0 4 1
A addItemValidator() 0 4 1
A addItemHolderValidator() 0 4 1
A calculateTotal() 0 14 2
A calculateSubTotal() 15 15 2
A calculateDeliveryFeeTotal() 11 11 1
A calculateDiscount() 12 12 1
A calculateCharge() 11 11 1
A calculateTax() 0 14 2
A calculateAll() 0 9 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\PurchaseFlow;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Eccube\Entity\ItemHolderInterface;
18
use Eccube\Entity\ItemInterface;
19
use Eccube\Entity\Order;
20
use Eccube\Entity\OrderItem;
21
22
class PurchaseFlow
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
23
{
24
    /**
25
     * @var ArrayCollection|ItemPreprocessor[]
26
     */
27
    protected $itemPreprocessors;
28
29
    /**
30
     * @var ArrayCollection|ItemHolderPreprocessor[]
31
     */
32
    protected $itemHolderPreprocessors;
33
34
    /**
35
     * @var ArrayCollection|ItemValidator[]
36
     */
37
    protected $itemValidators;
38
39
    /**
40
     * @var ArrayCollection|ItemHolderValidator[]
41
     */
42
    protected $itemHolderValidators;
43
44
    /**
45
     * @var ArrayCollection|PurchaseProcessor[]
46
     */
47
    protected $purchaseProcessors;
48
49 764
    public function __construct()
50
    {
51 764
        $this->purchaseProcessors = new ArrayCollection();
52 764
        $this->itemValidators = new ArrayCollection();
53 764
        $this->itemHolderValidators = new ArrayCollection();
54 764
        $this->itemPreprocessors = new ArrayCollection();
55 764
        $this->itemHolderPreprocessors = new ArrayCollection();
56
    }
57
58 725
    public function setPurchaseProcessors(ArrayCollection $processors)
59
    {
60 725
        $this->purchaseProcessors = $processors;
61
    }
62
63 758
    public function setItemValidators(ArrayCollection $itemValidators)
64
    {
65 758
        $this->itemValidators = $itemValidators;
66
    }
67
68 758
    public function setItemHolderValidators(ArrayCollection $itemHolderValidators)
69
    {
70 758
        $this->itemHolderValidators = $itemHolderValidators;
71
    }
72
73
    public function setItemPreprocessors(ArrayCollection $itemPreprocessors)
74
    {
75
        $this->itemPreprocessors = $itemPreprocessors;
76
    }
77
78 758
    public function setItemHolderPreprocessors(ArrayCollection $itemHolderPreprocessors)
79
    {
80 758
        $this->itemHolderPreprocessors = $itemHolderPreprocessors;
81
    }
82
83 293
    public function validate(ItemHolderInterface $itemHolder, PurchaseContext $context)
84
    {
85 293
        $this->calculateAll($itemHolder);
86
87 293
        $flowResult = new PurchaseFlowResult($itemHolder);
88
89 293
        foreach ($itemHolder->getItems() as $item) {
90 289
            foreach ($this->itemPreprocessors as $itemPreprocessor) {
91 289
                $itemPreprocessor->process($item, $context);
92
            }
93
        }
94
95 293
        $this->calculateAll($itemHolder);
96
97 293
        foreach ($this->itemHolderPreprocessors as $holderPreprocessor) {
98 257
            $holderPreprocessor->process($itemHolder, $context);
99
        }
100
101 293
        $this->calculateAll($itemHolder);
102
103 293
        foreach ($itemHolder->getItems() as $item) {
104 289
            foreach ($this->itemValidators as $itemValidator) {
105 81
                $result = $itemValidator->execute($item, $context);
106 289
                $flowResult->addProcessResult($result);
107
            }
108
        }
109
110 293
        $this->calculateAll($itemHolder);
111
112 293
        foreach ($this->itemHolderValidators as $itemHolderValidator) {
113 264
            $result = $itemHolderValidator->execute($itemHolder, $context);
114 264
            $flowResult->addProcessResult($result);
115
        }
116
117 293
        $this->calculateAll($itemHolder);
118
119 293
        return $flowResult;
120
    }
121
122
    /**
123
     * 購入フロー仮確定処理.
124
     *
125
     * @param ItemHolderInterface $target
126
     * @param PurchaseContext $context
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
127
     *
128
     * @throws PurchaseException
129
     */
130 34
    public function prepare(ItemHolderInterface $target, PurchaseContext $context)
131
    {
132 34
        foreach ($this->purchaseProcessors as $processor) {
133 27
            $processor->prepare($target, $context);
134
        }
135
    }
136
137
    /**
138
     * 購入フロー確定処理.
139
     *
140
     * @param ItemHolderInterface $target
141
     * @param PurchaseContext     $context
142
     *
143
     * @throws PurchaseException
144
     */
145 26
    public function commit(ItemHolderInterface $target, PurchaseContext $context)
146
    {
147 26
        foreach ($this->purchaseProcessors as $processor) {
148 26
            $processor->commit($target, $context);
149
        }
150
    }
151
152
    /**
153
     * 購入フロー仮確定取り消し処理.
154
     *
155
     * @param ItemHolderInterface $target
156
     * @param PurchaseContext $context
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
157
     */
158
    public function rollback(ItemHolderInterface $target, PurchaseContext $context)
159
    {
160
        foreach ($this->purchaseProcessors as $processor) {
161
            $processor->rollback($target, $context);
162
        }
163
    }
164
165 16
    public function addPurchaseProcessor(PurchaseProcessor $processor)
166
    {
167 16
        $this->purchaseProcessors[] = $processor;
168
    }
169
170 26
    public function addItemHolderPreprocessor(ItemHolderPreprocessor $holderPreprocessor)
171
    {
172 26
        $this->itemHolderPreprocessors[] = $holderPreprocessor;
173
    }
174
175 2
    public function addItemPreprocessor(ItemPreprocessor $itemPreprocessor)
176
    {
177 2
        $this->itemPreprocessors[] = $itemPreprocessor;
178
    }
179
180 3
    public function addItemValidator(ItemValidator $itemValidator)
181
    {
182 3
        $this->itemValidators[] = $itemValidator;
183
    }
184
185 36
    public function addItemHolderValidator(ItemHolderValidator $itemHolderValidator)
186
    {
187 36
        $this->itemHolderValidators[] = $itemHolderValidator;
188
    }
189
190
    /**
191
     * @param ItemHolderInterface $itemHolder
192
     */
193
    protected function calculateTotal(ItemHolderInterface $itemHolder)
194
    {
195 293
        $total = $itemHolder->getItems()->reduce(function ($sum, ItemInterface $item) {
196 289
            $sum += $item->getPriceIncTax() * $item->getQuantity();
197
198 289
            return $sum;
199 293
        }, 0);
200 293
        $itemHolder->setTotal($total);
201
        // TODO
202 293
        if ($itemHolder instanceof Order) {
203
            // Order には PaymentTotal もセットする
204 262
            $itemHolder->setPaymentTotal($total);
205
        }
206
    }
207
208 293 View Code Duplication
    protected function calculateSubTotal(ItemHolderInterface $itemHolder)
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...
209
    {
210 293
        $total = $itemHolder->getItems()
211 293
            ->getProductClasses()
212 293
            ->reduce(function ($sum, ItemInterface $item) {
213 232
                $sum += $item->getPriceIncTax() * $item->getQuantity();
214
215 232
                return $sum;
216 293
            }, 0);
217
        // TODO
218 293
        if ($itemHolder instanceof Order) {
219
            // Order の場合は SubTotal をセットする
220 262
            $itemHolder->setSubTotal($total);
221
        }
222
    }
223
224
    /**
225
     * @param ItemHolderInterface $itemHolder
226
     */
227 293 View Code Duplication
    protected function calculateDeliveryFeeTotal(ItemHolderInterface $itemHolder)
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...
228
    {
229 293
        $total = $itemHolder->getItems()
230 293
            ->getDeliveryFees()
231 293
            ->reduce(function ($sum, ItemInterface $item) {
232 203
                $sum += $item->getPriceIncTax() * $item->getQuantity();
233
234 203
                return $sum;
235 293
            }, 0);
236 293
        $itemHolder->setDeliveryFeeTotal($total);
237
    }
238
239
    /**
240
     * @param ItemHolderInterface $itemHolder
241
     */
242 293 View Code Duplication
    protected function calculateDiscount(ItemHolderInterface $itemHolder)
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...
243
    {
244 293
        $total = $itemHolder->getItems()
245 293
            ->getDiscounts()
246 293
            ->reduce(function ($sum, ItemInterface $item) {
247 168
                $sum += $item->getPriceIncTax() * $item->getQuantity();
248
249 168
                return $sum;
250 293
            }, 0);
251
        // TODO 後方互換のため discount には正の整数を代入する
252 293
        $itemHolder->setDiscount($total * -1);
253
    }
254
255
    /**
256
     * @param ItemHolderInterface $itemHolder
257
     */
258 293 View Code Duplication
    protected function calculateCharge(ItemHolderInterface $itemHolder)
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...
259
    {
260 293
        $total = $itemHolder->getItems()
261 293
            ->getCharges()
262 293
            ->reduce(function ($sum, ItemInterface $item) {
263 152
                $sum += $item->getPriceIncTax() * $item->getQuantity();
264
265 152
                return $sum;
266 293
            }, 0);
267 293
        $itemHolder->setCharge($total);
268
    }
269
270
    /**
271
     * @param ItemHolderInterface $itemHolder
272
     */
273 293
    protected function calculateTax(ItemHolderInterface $itemHolder)
274
    {
275 293
        $total = $itemHolder->getItems()
276 293
            ->reduce(function ($sum, ItemInterface $item) {
277 289
                if ($item instanceof OrderItem) {
278 262
                    $sum += $item->getTax() * $item->getQuantity();
279
                } else {
280 79
                    $sum += ($item->getPriceIncTax() - $item->getPrice()) * $item->getQuantity();
281
                }
282
283 289
                return $sum;
284 293
            }, 0);
285 293
        $itemHolder->setTax($total);
286
    }
287
288
    /**
289
     * @param ItemHolderInterface $itemHolder
290
     */
291 293
    protected function calculateAll(ItemHolderInterface $itemHolder)
292
    {
293 293
        $this->calculateDeliveryFeeTotal($itemHolder);
294 293
        $this->calculateCharge($itemHolder);
295 293
        $this->calculateDiscount($itemHolder);
296 293
        $this->calculateSubTotal($itemHolder); // Order の場合のみ
297 293
        $this->calculateTax($itemHolder);
298 293
        $this->calculateTotal($itemHolder);
299
    }
300
}
301