Failed Conditions
Pull Request — experimental/3.1 (#2534)
by chihiro
09:59
created

OrderHelper::createOrderDetailsFromCartItems()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 39
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 27
nc 5
nop 1
dl 0
loc 39
rs 8.5806
c 0
b 0
f 0
ccs 0
cts 26
cp 0
crap 20
1
<?php
2
3
namespace Eccube\Service;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\ORM\EntityManager;
7
use Eccube\Annotation\Inject;
8
use Eccube\Annotation\Service;
9
use Eccube\Common\Constant;
10
use Eccube\Entity\CartItem;
11
use Eccube\Entity\Customer;
12
use Eccube\Entity\CustomerAddress;
13
use Eccube\Entity\Master\OrderItemType;
14
use Eccube\Entity\Master\ShippingStatus;
15
use Eccube\Entity\Master\TaxDisplayType;
16
use Eccube\Entity\Master\TaxType;
17
use Eccube\Entity\Order;
18
use Eccube\Entity\OrderDetail;
19
use Eccube\Entity\OrderItem;
20
use Eccube\Entity\Shipping;
21
use Eccube\Repository\DeliveryFeeRepository;
22
use Eccube\Repository\DeliveryRepository;
23
use Eccube\Repository\Master\OrderItemTypeRepository;
24
use Eccube\Repository\Master\OrderStatusRepository;
25
use Eccube\Repository\Master\ShippingStatusRepository;
26
use Eccube\Repository\TaxRuleRepository;
27
use Eccube\Repository\OrderRepository;
28
use Eccube\Repository\PaymentRepository;
29
use Eccube\Util\Str;
30
31
/**
32
 * OrderやOrderに関連するエンティティを構築するクラス
33
 * namespaceやクラス名は要検討
34
 *
35
 * @package Eccube\Service
36
 * @Service
37
 */
38
class OrderHelper
39
{
40
    /**
41
     * @Inject(OrderItemTypeRepository::class)
42
     * @var OrderItemTypeRepository
43
     */
44
    protected $orderItemTypeRepository;
45
46
    /**
47
     * @Inject(OrderStatusRepository::class)
48
     * @var OrderStatusRepository
49
     */
50
    protected $orderStatusRepository;
51
52
    /**
53
     * @Inject(TaxRuleRepository::class)
54
     * @var TaxRuleRepository
55
     */
56
    protected $taxRuleRepository;
57
58
    /**
59
     * @Inject(DeliveryFeeRepository::class)
60
     * @var DeliveryFeeRepository
61
     */
62
    protected $deliveryFeeRepository;
63
64
    /**
65
     * @Inject(DeliveryRepository::class)
66
     * @var DeliveryRepository
67
     */
68
    protected $deliveryRepository;
69
70
    /**
71
     * @Inject(PaymentRepository::class)
72
     * @var PaymentRepository
73
     */
74
    protected $paymentRepository;
75
76
    /**
77
     * @Inject(OrderRepository::class)
78
     * @var OrderRepository
79
     */
80
    protected $orderRepository;
81
82
    /**
83
     * @Inject(ShippingStatusRepository::class)
84
     * @var ShippingStatusRepository
85
     */
86
    protected $shippingStatusRepository;
87
88
    /**
89
     * @Inject("orm.em")
90
     * @var EntityManager
91
     */
92
    protected $entityManager;
93
94
    /**
95
     * @Inject("config")
96
     * @var array
97
     */
98
    protected $appConfig;
99
100
    /**
101
     * 購入処理中の受注データを生成する.
102
     *
103
     * @param Customer $Customer
0 ignored issues
show
introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
104
     * @param CustomerAddress $CustomerAddress
105
     * @param array $CartItems
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
106
     * @return Order
107
     */
108
    public function createProcessingOrder(Customer $Customer, CustomerAddress $CustomerAddress, $CartItems)
109
    {
110
        $OrderStatus = $this->orderStatusRepository->find($this->appConfig['order_processing']);
111
        $Order = new Order($OrderStatus);
112
113
        // pre_order_idを生成
114
        $Order->setPreOrderId($this->createPreOrderId());
115
116
        // 顧客情報の設定
117
        $this->setCustomer($Order, $Customer);
118
119
        // 明細情報の設定
120
        $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...
121
        $OrderItemsGroupByProductType = array_reduce($OrderItems, function($result, $item) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
122
            /* @var OrderItem $item */
123
            $productTypeId = $item->getProductClass()->getProductType()->getId();
124
            $result[$productTypeId][] = $item;
125
            return $result;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
126
        }, []);
127
128
        foreach ($OrderItemsGroupByProductType as $OrderItems) {
129
            $Shipping = $this->createShippingFromCustomerAddress($CustomerAddress);
130
            $this->addOrderItems($Order, $Shipping, $OrderItems);
131
            $this->setDefaultDelivery($Shipping);
132
            $this->entityManager->persist($Shipping);
133
        }
134
135
        $this->setDefaultPayment($Order);
136
137
        $this->entityManager->persist($Order);
138
        $this->entityManager->flush();
139
140
        return $Order;
141
    }
142
143
    public function createPreOrderId()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
144
    {
145
        // ランダムなpre_order_idを作成
146 View Code Duplication
        do {
147
            $preOrderId = sha1(Str::random(32));
148
149
            $Order = $this->orderRepository->findOneBy(
150
                [
151
                    'pre_order_id' => $preOrderId,
152
                    'OrderStatus' => $this->appConfig['order_processing'],
153
                ]
154
            );
155
        } while ($Order);
156
157
        return $preOrderId;
158
    }
159
160
    public function setCustomer(Order $Order, Customer $Customer)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
161
    {
162
        if ($Customer->getId()) {
163
            $Order->setCustomer($Customer);
164
        }
165
166
        $Order->copyProperties(
167
            $Customer,
168
            [
169
                'id',
170
                'create_date',
171
                'update_date',
172
                'del_flg',
173
            ]
174
        );
175
    }
176
177
    /**
178
     * @param ArrayCollection $CartItems
179
     * @return OrderItem[]
180
     */
181
    private function createOrderItemsFromCartItems($CartItems)
182
    {
183
        $ProductItemType = $this->orderItemTypeRepository->find(OrderItemType::PRODUCT);
184
        // TODO
185
        $TaxExclude = $this->entityManager->getRepository(TaxDisplayType::class)->find(TaxDisplayType::EXCLUDED);
186
        $Taxion = $this->entityManager->getRepository(TaxType::class)->find(TaxType::TAXATION);
187
188
        return array_map(function($item) use ($ProductItemType, $TaxExclude, $Taxion) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
189
            /* @var $item CartItem */
190
            /* @var $ProductClass \Eccube\Entity\ProductClass */
191
            $ProductClass = $item->getObject();
192
            /* @var $Product \Eccube\Entity\Product */
193
            $Product = $ProductClass->getProduct();
194
            $TaxRule = $this->taxRuleRepository->getByRule($Product, $ProductClass);
195
196
            $OrderItem = new OrderItem();
197
            $OrderItem
198
                ->setProduct($Product)
199
                ->setProductClass($ProductClass)
200
                ->setProductName($Product->getName())
201
                ->setProductCode($ProductClass->getCode())
202
                ->setPrice($ProductClass->getPrice02())
203
                ->setQuantity($item->getQuantity())
204
                ->setTaxRule($TaxRule->getId())
205
                ->setTaxRate($TaxRule->getTaxRate())
206
                ->setOrderItemType($ProductItemType)
207
                ->setTaxDisplayType($TaxExclude)
208
                ->setTaxType($Taxion);
209
210
            $ClassCategory1 = $ProductClass->getClassCategory1();
211
            if (!is_null($ClassCategory1)) {
212
                $OrderItem->setClasscategoryName1($ClassCategory1->getName());
213
                $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
214
            }
215
            $ClassCategory2 = $ProductClass->getClassCategory2();
216
            if (!is_null($ClassCategory2)) {
217
                $OrderItem->setClasscategoryName2($ClassCategory2->getName());
218
                $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
219
            }
220
221
            return $OrderItem;
222
        }, $CartItems->toArray());
223
    }
224
225
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$CartItems" missing
Loading history...
226
     * @deprecated
227
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
228
    public function createOrderDetailsFromCartItems($CartItems)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
229
    {
230
        @trigger_error('The '.__METHOD__.' method is deprecated.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
231
        $OrderDetails = [];
232
233
        foreach ($CartItems as $item) {
234
            /* @var $ProductClass \Eccube\Entity\ProductClass */
235
            $ProductClass = $item->getObject();
236
            /* @var $Product \Eccube\Entity\Product */
237
            $Product = $ProductClass->getProduct();
238
239
            $OrderDetail = new OrderDetail();
240
            $TaxRule = $this->taxRuleRepository->getByRule($Product, $ProductClass);
241
            $OrderDetail
242
                ->setProduct($Product)
243
                ->setProductClass($ProductClass)
244
                ->setProductName($Product->getName())
245
                ->setProductCode($ProductClass->getCode())
246
                ->setPrice($ProductClass->getPrice02())
247
                ->setQuantity($item->getQuantity())
248
                ->setTaxRule($TaxRule->getId())
249
                ->setTaxRate($TaxRule->getTaxRate());
250
251
            $ClassCategory1 = $ProductClass->getClassCategory1();
252
            if (!is_null($ClassCategory1)) {
253
                $OrderDetail->setClasscategoryName1($ClassCategory1->getName());
254
                $OrderDetail->setClassName1($ClassCategory1->getClassName()->getName());
255
            }
256
            $ClassCategory2 = $ProductClass->getClassCategory2();
257
            if (!is_null($ClassCategory2)) {
258
                $OrderDetail->setClasscategoryName2($ClassCategory2->getName());
259
                $OrderDetail->setClassName2($ClassCategory2->getClassName()->getName());
260
            }
261
262
            $OrderDetails[] = $OrderDetail;
263
        }
264
265
        return $OrderDetails;
266
    }
267
268
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$Order" missing
Loading history...
introduced by
Doc comment for parameter "$OrderDetails" missing
Loading history...
269
     * @deprecated
270
     */
271
    public function addOrderDetails(Order $Order, array $OrderDetails)
272
    {
273
        @trigger_error('The '.__METHOD__.' method is deprecated.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
274
        foreach ($OrderDetails as $OrderDetail) {
275
            $Order->addOrderDetail($OrderDetail);
276
            $OrderDetail->setOrder($Order);
277
        }
278
    }
279
280
    public function createShippingFromCustomerAddress(CustomerAddress $CustomerAddress)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
281
    {
282
        $Shipping = new Shipping();
283
        $Shipping
284
            ->setName01($CustomerAddress->getName01())
285
            ->setName02($CustomerAddress->getName02())
286
            ->setKana01($CustomerAddress->getKana01())
287
            ->setKana02($CustomerAddress->getKana02())
288
            ->setCompanyName($CustomerAddress->getCompanyName())
289
            ->setTel01($CustomerAddress->getTel01())
290
            ->setTel02($CustomerAddress->getTel02())
291
            ->setTel03($CustomerAddress->getTel03())
292
            ->setFax01($CustomerAddress->getFax01())
293
            ->setFax02($CustomerAddress->getFax02())
294
            ->setFax03($CustomerAddress->getFax03())
295
            ->setZip01($CustomerAddress->getZip01())
296
            ->setZip02($CustomerAddress->getZip02())
297
            ->setZipCode($CustomerAddress->getZip01().$CustomerAddress->getZip02())
298
            ->setPref($CustomerAddress->getPref())
299
            ->setAddr01($CustomerAddress->getAddr01())
300
            ->setAddr02($CustomerAddress->getAddr02());
301
302
        $ShippingStatus = $this->shippingStatusRepository->find(ShippingStatus::PREPARED);
303
        $Shipping->setShippingStatus($ShippingStatus);
304
305
        return $Shipping;
306
    }
307
308
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$Order" missing
Loading history...
introduced by
Doc comment for parameter "$Shipping" missing
Loading history...
309
     * @deprecated
310
     */
311
    public function addShipping(Order $Order, Shipping $Shipping)
312
    {
313
        @trigger_error('The '.__METHOD__.' method is deprecated.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
314
        $Order->addShipping($Shipping);
315
        $Shipping->setOrder($Order);
316
    }
317
318
    public function setDefaultDelivery(Shipping $Shipping)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
319
    {
320
        // 配送商品に含まれる商品種別を抽出.
321
        $OrderItems = $Shipping->getOrderItems();
322
        $ProductTypes = [];
323 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
324
            $ProductClass = $OrderItem->getProductClass();
325
            $ProductType = $ProductClass->getProductType();
326
            $ProductTypes[$ProductType->getId()] = $ProductType;
327
        }
328
329
        // 商品種別に紐づく配送業者を取得.
330
        $Deliveries = $this->deliveryRepository->getDeliveries($ProductTypes);
331
332
        // 初期の配送業者を設定
333
        $Delivery = current($Deliveries);
334
        $Shipping->setDelivery($Delivery);
335
        $Shipping->setShippingDeliveryName($Delivery->getName());
336
337
        // TODO 配送料の取得方法はこれで良いか要検討
338
        $deliveryFee = $this->deliveryFeeRepository->findOneBy(array('Delivery' => $Delivery, 'Pref' => $Shipping->getPref()));
339
        if ($deliveryFee) {
340
            $Shipping->setShippingDeliveryFee($deliveryFee->getFee());
341
            $Shipping->setFeeId($deliveryFee->getId());
342
        }
343
    }
344
345
    public function setDefaultPayment(Order $Order)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
346
    {
347
        $OrderItems = $Order->getOrderItems();
348
349
        // 受注明細に含まれる商品種別を抽出.
350
        $ProductTypes = [];
351
        /** @var OrderItem $OrderItem */
352 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
353
            $ProductClass = $OrderItem->getProductClass();
354
            if (is_null($ProductClass)) {
355
                // 商品明細のみ対象とする. 送料明細等はスキップする.
356
                continue;
357
            }
358
            $ProductType = $ProductClass->getProductType();
359
            $ProductTypes[$ProductType->getId()] = $ProductType;
360
        }
361
362
        // 商品種別に紐づく配送業者を抽出
363
        $Deliveries = $this->deliveryRepository->getDeliveries($ProductTypes);
364
365
        // 利用可能な支払い方法を抽出.
366
        $Payments = $this->paymentRepository->findAllowedPayments($Deliveries, true);
367
368
        // 初期の支払い方法を設定.
369
        $Payment = current($Payments);
370
        $Order->setPayment($Payment);
371
        $Order->setPaymentMethod($Payment->getMethod());
372
        // TODO CalculateChargeStrategy でセットする
373
        // $Order->setCharge($Payment->getCharge());
374
    }
375
376
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$OrderDetails" missing
Loading history...
introduced by
Doc comment for parameter "$groupByProductType" missing
Loading history...
377
     * @deprecated
378
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
379
    public function createOrderItemsFromOrderDetails($OrderDetails, $groupByProductType = true)
380
    {
381
        @trigger_error('The '.__METHOD__.' method is deprecated.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
382
        $OrderItems = [];
383
384
        foreach ($OrderDetails as $OrderDetail) {
385
            $Product = $OrderDetail->getProduct();
386
            $ProductClass = $OrderDetail->getProductClass();
387
            $ProductType = $ProductClass->getProductType();
388
389
            $OrderItem = new OrderItem();
390
            $OrderItem
391
                ->setProductClass($ProductClass)
392
                ->setProduct($Product)
393
                ->setProductName($Product->getName())
394
                ->setProductCode($ProductClass->getCode())
395
                ->setPrice($ProductClass->getPrice02())
396
                ->setQuantity($OrderDetail->getQuantity());
397
398
            $ClassCategory1 = $ProductClass->getClassCategory1();
399
            if (!is_null($ClassCategory1)) {
400
                $OrderItem->setClasscategoryName1($ClassCategory1->getName());
401
                $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
402
            }
403
            $ClassCategory2 = $ProductClass->getClassCategory2();
404
            if (!is_null($ClassCategory2)) {
405
                $OrderItem->setClasscategoryName2($ClassCategory2->getName());
406
                $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
407
            }
408
            if ($groupByProductType) {
409
                $OrderItems[$ProductType->getId()][] = $OrderItem;
410
            } else {
411
                $OrderItems[] = $OrderItem;
412
            }
413
        }
414
415
        return $OrderItems;
416
    }
417
418
    public function addOrderItems(Order $Order, Shipping $Shipping, array $OrderItems)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
419
    {
420
        foreach ($OrderItems as $OrderItem) {
421
            $Shipping->addOrderItem($OrderItem);
422
            $Order->addOrderItem($OrderItem);
423
            $OrderItem->setOrder($Order);
424
            $OrderItem->setShipping($Shipping);
425
        }
426
    }
427
428
}
429