Failed Conditions
Branch experimental/sf (68db07)
by Kentaro
42:17 queued 33:39
created

OrderHelper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 10
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
ccs 11
cts 11
cp 1
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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 Doctrine\Common\Collections\ArrayCollection;
17
use Doctrine\ORM\EntityManager;
18
use Doctrine\ORM\EntityManagerInterface;
19
use Eccube\Common\EccubeConfig;
20
use Eccube\Entity\Cart;
21
use Eccube\Entity\CartItem;
22
use Eccube\Entity\Customer;
23
use Eccube\Entity\Master\OrderItemType;
24
use Eccube\Entity\Master\OrderStatus;
25
use Eccube\Entity\Master\ShippingStatus;
26
use Eccube\Entity\Master\TaxDisplayType;
27
use Eccube\Entity\Master\TaxType;
28
use Eccube\Entity\Order;
29
use Eccube\Entity\OrderItem;
30
use Eccube\Entity\Shipping;
31
use Eccube\Repository\DeliveryFeeRepository;
32
use Eccube\Repository\DeliveryRepository;
33
use Eccube\Repository\Master\OrderItemTypeRepository;
34
use Eccube\Repository\Master\OrderStatusRepository;
35
use Eccube\Repository\Master\ShippingStatusRepository;
36
use Eccube\Repository\OrderRepository;
37
use Eccube\Repository\PaymentRepository;
38
use Eccube\Repository\TaxRuleRepository;
39
use Eccube\Util\StringUtil;
40
41
/**
42
 * OrderやOrderに関連するエンティティを構築するクラス
43
 * namespaceやクラス名は要検討
44
 */
45
class OrderHelper
46
{
47
    /**
48
     * @var OrderItemTypeRepository
49
     */
50
    protected $orderItemTypeRepository;
51
52
    /**
53
     * @var OrderStatusRepository
54
     */
55
    protected $orderStatusRepository;
56
57
    /**
58
     * @var TaxRuleRepository
59
     */
60
    protected $taxRuleRepository;
61
62
    /**
63
     * @var DeliveryFeeRepository
64
     */
65
    protected $deliveryFeeRepository;
66
67
    /**
68
     * @var DeliveryRepository
69
     */
70
    protected $deliveryRepository;
71
72
    /**
73
     * @var PaymentRepository
74
     */
75
    protected $paymentRepository;
76
77
    /**
78
     * @var OrderRepository
79
     */
80
    protected $orderRepository;
81
82
    /**
83
     * @var ShippingStatusRepository
84
     */
85
    protected $shippingStatusRepository;
86
87
    /**
88
     * @var EntityManager
89
     */
90
    protected $entityManager;
91
92
    /**
93
     * @var EccubeConfig
94
     */
95
    protected $eccubeConfig;
96
97
    /**
98
     * OrderHelper constructor.
99
     *
100
     * @param OrderItemTypeRepository $orderItemTypeRepository
0 ignored issues
show
introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
101
     * @param OrderStatusRepository $orderStatusRepository
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
102
     * @param TaxRuleRepository $taxRuleRepository
0 ignored issues
show
introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
103
     * @param DeliveryFeeRepository $deliveryFeeRepository
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
104
     * @param DeliveryRepository $deliveryRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
105
     * @param PaymentRepository $paymentRepository
0 ignored issues
show
introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
106
     * @param OrderRepository $orderRepository
0 ignored issues
show
introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
107
     * @param ShippingStatusRepository $shippingStatusRepository
108
     * @param EntityManager $entityManager
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
109
     * @param EccubeConfig $eccubeConfig
0 ignored issues
show
introduced by
Expected 13 spaces after parameter type; 1 found
Loading history...
110
     */
111 173
    public function __construct(
112
        OrderItemTypeRepository $orderItemTypeRepository,
113
        OrderStatusRepository $orderStatusRepository,
114
        TaxRuleRepository $taxRuleRepository,
115
        DeliveryFeeRepository $deliveryFeeRepository,
116
        DeliveryRepository $deliveryRepository,
117
        PaymentRepository $paymentRepository,
118
        OrderRepository $orderRepository,
119
        ShippingStatusRepository $shippingStatusRepository,
120
        EntityManagerInterface $entityManager,
121
        EccubeConfig $eccubeConfig
122
    ) {
123 173
        $this->orderItemTypeRepository = $orderItemTypeRepository;
124 173
        $this->orderStatusRepository = $orderStatusRepository;
125 173
        $this->taxRuleRepository = $taxRuleRepository;
126 173
        $this->deliveryFeeRepository = $deliveryFeeRepository;
127 173
        $this->deliveryRepository = $deliveryRepository;
128 173
        $this->paymentRepository = $paymentRepository;
129 173
        $this->orderRepository = $orderRepository;
130 173
        $this->shippingStatusRepository = $shippingStatusRepository;
131 173
        $this->entityManager = $entityManager;
0 ignored issues
show
Documentation Bug introduced by
$entityManager is of type object<Doctrine\ORM\EntityManagerInterface>, but the property $entityManager was declared to be of type object<Doctrine\ORM\EntityManager>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
132 173
        $this->eccubeConfig = $eccubeConfig;
133
    }
134
135
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$preOrderId" missing
Loading history...
136
     * 購入処理中の受注データを生成する.
137
     *
138
     * @param Customer $Customer
139
     * @param array $CartItems
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
140
     *
141
     * @return Order
142
     */
143 51
    public function createProcessingOrder(Customer $Customer, $CartItems, $preOrderId = null)
144
    {
145 51
        $OrderStatus = $this->orderStatusRepository->find(OrderStatus::PROCESSING);
146 51
        $Order = new Order($OrderStatus);
147
148 51
        if (!$preOrderId) {
149
            // pre_order_idを生成
150 51
            $Order->setPreOrderId($this->createPreOrderId());
151
        }
152
153
        // 顧客情報の設定
154 51
        $this->setCustomer($Order, $Customer);
155
156
        // 明細情報の設定
157 51
        $OrderItems = $this->createOrderItemsFromCartItems($CartItems);
0 ignored issues
show
Documentation introduced by
$CartItems is of type array, but the function expects a object<Doctrine\Common\C...ctions\ArrayCollection>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
158 51
        $OrderItemsGroupBySaleType = array_reduce($OrderItems, function ($result, $item) {
159
            /* @var OrderItem $item */
160 51
            $saleTypeId = $item->getProductClass()->getSaleType()->getId();
161 51
            $result[$saleTypeId][] = $item;
162
163 51
            return $result;
164 51
        }, []);
165
166 51
        foreach ($OrderItemsGroupBySaleType as $OrderItems) {
167 51
            $Shipping = $this->createShippingFromCustomer($Customer);
168 51
            $this->addOrderItems($Order, $Shipping, $OrderItems);
169 51
            $this->setDefaultDelivery($Shipping);
170 51
            $this->entityManager->persist($Shipping);
171
        }
172
173 51
        $this->setDefaultPayment($Order);
174
175 51
        $this->entityManager->persist($Order);
176 51
        $this->entityManager->flush();
177
178 51
        return $Order;
179
    }
180
181
    /**
182
     * OrderをCartに変換します.
183
     *
184
     * @param Order $Order
185
     *
186
     * @return Cart
187
     */
188 2
    public function convertToCart(Order $Order)
189
    {
190 2
        $Cart = new Cart();
191 2
        $Cart->setPreOrderId($Order->getPreOrderId());
192
        /** @var OrderItem $OrderItem */
193 2
        foreach ($Order->getProductOrderItems() as $OrderItem) {
194 1
            $CartItem = new CartItem();
195 1
            $ProductClass = $OrderItem->getProductClass();
196 1
            $this->entityManager->refresh($ProductClass);
197 1
            $CartItem->setProductClass($ProductClass);
198 1
            $CartItem->setPrice($OrderItem->getPriceIncTax());
199 1
            $CartItem->setQuantity($OrderItem->getQuantity());
200 1
            $Cart->addCartItem($CartItem);
201
        }
202
203 2
        return $Cart;
204
    }
205
206 51
    private function createPreOrderId()
207
    {
208
        // ランダムなpre_order_idを作成
209 View Code Duplication
        do {
210 51
            $preOrderId = sha1(StringUtil::random(32));
211
212 51
            $Order = $this->orderRepository->findOneBy(
213
                [
214 51
                    'pre_order_id' => $preOrderId,
215
                    'OrderStatus' => OrderStatus::PROCESSING,
216
                ]
217
            );
218 51
        } while ($Order);
219
220 51
        return $preOrderId;
221
    }
222
223 51
    private function setCustomer(Order $Order, Customer $Customer)
224
    {
225 51
        if ($Customer->getId()) {
226 34
            $Order->setCustomer($Customer);
227
        }
228
229 51
        $Order->copyProperties(
230 51
            $Customer,
231
            [
232 51
                'id',
233
                'create_date',
234
                'update_date',
235
                'del_flg',
236
            ]
237
        );
238
    }
239
240
    /**
241
     * @param ArrayCollection $CartItems
242
     *
243
     * @return OrderItem[]
244
     */
245 51
    private function createOrderItemsFromCartItems($CartItems)
246
    {
247 51
        $ProductItemType = $this->orderItemTypeRepository->find(OrderItemType::PRODUCT);
248
        // TODO
249 51
        $TaxExclude = $this->entityManager->getRepository(TaxDisplayType::class)->find(TaxDisplayType::EXCLUDED);
250 51
        $Taxion = $this->entityManager->getRepository(TaxType::class)->find(TaxType::TAXATION);
251
252 51
        return array_map(function ($item) use ($ProductItemType, $TaxExclude, $Taxion) {
253
            /* @var $item CartItem */
254
            /* @var $ProductClass \Eccube\Entity\ProductClass */
255 51
            $ProductClass = $item->getProductClass();
256
            /* @var $Product \Eccube\Entity\Product */
257 51
            $Product = $ProductClass->getProduct();
258 51
            $TaxRule = $this->taxRuleRepository->getByRule($Product, $ProductClass);
259
260 51
            $OrderItem = new OrderItem();
261
            $OrderItem
262 51
                ->setProduct($Product)
263 51
                ->setProductClass($ProductClass)
264 51
                ->setProductName($Product->getName())
265 51
                ->setProductCode($ProductClass->getCode())
266 51
                ->setPrice($ProductClass->getPrice02())
267 51
                ->setQuantity($item->getQuantity())
268 51
                ->setTaxRule($TaxRule->getId())
269 51
                ->setTaxRate($TaxRule->getTaxRate())
270 51
                ->setOrderItemType($ProductItemType)
271 51
                ->setTaxDisplayType($TaxExclude)
272 51
                ->setTaxType($Taxion);
273
274 51
            $ClassCategory1 = $ProductClass->getClassCategory1();
275 51
            if (!is_null($ClassCategory1)) {
276 51
                $OrderItem->setClasscategoryName1($ClassCategory1->getName());
277 51
                $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
278
            }
279 51
            $ClassCategory2 = $ProductClass->getClassCategory2();
280 51
            if (!is_null($ClassCategory2)) {
281 38
                $OrderItem->setClasscategoryName2($ClassCategory2->getName());
282 38
                $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
283
            }
284
285 51
            return $OrderItem;
286 51
        }, $CartItems->toArray());
287
    }
288
289 51
    private function createShippingFromCustomer(Customer $Customer)
290
    {
291 51
        $Shipping = new Shipping();
292
        $Shipping
293 51
            ->setName01($Customer->getName01())
294 51
            ->setName02($Customer->getName02())
295 51
            ->setKana01($Customer->getKana01())
296 51
            ->setKana02($Customer->getKana02())
297 51
            ->setCompanyName($Customer->getCompanyName())
298 51
            ->setTel01($Customer->getTel01())
299 51
            ->setTel02($Customer->getTel02())
300 51
            ->setTel03($Customer->getTel03())
301 51
            ->setFax01($Customer->getFax01())
302 51
            ->setFax02($Customer->getFax02())
303 51
            ->setFax03($Customer->getFax03())
304 51
            ->setZip01($Customer->getZip01())
305 51
            ->setZip02($Customer->getZip02())
306 51
            ->setZipCode($Customer->getZip01().$Customer->getZip02())
307 51
            ->setPref($Customer->getPref())
308 51
            ->setAddr01($Customer->getAddr01())
309 51
            ->setAddr02($Customer->getAddr02());
310
311 51
        $ShippingStatus = $this->shippingStatusRepository->find(ShippingStatus::PREPARED);
312 51
        $Shipping->setShippingStatus($ShippingStatus);
313
314 51
        return $Shipping;
315
    }
316
317 51
    private function setDefaultDelivery(Shipping $Shipping)
318
    {
319
        // 配送商品に含まれる販売種別を抽出.
320 51
        $OrderItems = $Shipping->getOrderItems();
321 51
        $SaleTypes = [];
322
        /** @var OrderItem $OrderItem */
323 51 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
324 51
            $ProductClass = $OrderItem->getProductClass();
325 51
            $SaleType = $ProductClass->getSaleType();
326 51
            $SaleTypes[$SaleType->getId()] = $SaleType;
327
        }
328
329
        // 販売種別に紐づく配送業者を取得.
330 51
        $Deliveries = $this->deliveryRepository->getDeliveries($SaleTypes);
331
332
        // 初期の配送業者を設定
333 51
        $Delivery = current($Deliveries);
334 51
        $Shipping->setDelivery($Delivery);
335 51
        $Shipping->setShippingDeliveryName($Delivery->getName());
336
    }
337
338 51
    private function setDefaultPayment(Order $Order)
339
    {
340 51
        $OrderItems = $Order->getOrderItems();
341
342
        // 受注明細に含まれる販売種別を抽出.
343 51
        $SaleTypes = [];
344
        /** @var OrderItem $OrderItem */
345 51 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
346 51
            $ProductClass = $OrderItem->getProductClass();
347 51
            if (is_null($ProductClass)) {
348
                // 商品明細のみ対象とする. 送料明細等はスキップする.
349
                continue;
350
            }
351 51
            $SaleType = $ProductClass->getSaleType();
352 51
            $SaleTypes[$SaleType->getId()] = $SaleType;
353
        }
354
355
        // 販売種別に紐づく配送業者を抽出
356 51
        $Deliveries = $this->deliveryRepository->getDeliveries($SaleTypes);
357
358
        // 利用可能な支払い方法を抽出.
359 51
        $Payments = $this->paymentRepository->findAllowedPayments($Deliveries, true);
360
361
        // 初期の支払い方法を設定.
362 51
        $Payment = current($Payments);
363 51
        if ($Payment) {
364 51
            $Order->setPayment($Payment);
365 51
            $Order->setPaymentMethod($Payment->getMethod());
366
        }
367
        // TODO CalculateChargeStrategy でセットする
368
        // $Order->setCharge($Payment->getCharge());
369
    }
370
371 51
    private function addOrderItems(Order $Order, Shipping $Shipping, array $OrderItems)
372
    {
373 51
        foreach ($OrderItems as $OrderItem) {
374 51
            $Shipping->addOrderItem($OrderItem);
375 51
            $Order->addOrderItem($OrderItem);
376 51
            $OrderItem->setOrder($Order);
377 51
            $OrderItem->setShipping($Shipping);
378
        }
379
    }
380
}
381