Failed Conditions
Pull Request — experimental/3.1 (#2532)
by Kentaro
34:08 queued 17:05
created

OrderHelper::createOrderItemsFromOrderDetails()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 38
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 28
c 0
b 0
f 0
nc 9
nop 2
dl 0
loc 38
ccs 0
cts 26
cp 0
crap 30
rs 8.439
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\OrderItem;
19
use Eccube\Entity\Shipping;
20
use Eccube\Repository\DeliveryFeeRepository;
21
use Eccube\Repository\DeliveryRepository;
22
use Eccube\Repository\Master\OrderItemTypeRepository;
23
use Eccube\Repository\Master\OrderStatusRepository;
24
use Eccube\Repository\Master\ShippingStatusRepository;
25
use Eccube\Repository\TaxRuleRepository;
26
use Eccube\Repository\OrderRepository;
27
use Eccube\Repository\PaymentRepository;
28
use Eccube\Util\Str;
29
30
/**
31
 * OrderやOrderに関連するエンティティを構築するクラス
32
 * namespaceやクラス名は要検討
33
 *
34
 * @package Eccube\Service
35
 * @Service
36
 */
37
class OrderHelper
38
{
39
    /**
40
     * @Inject(OrderItemTypeRepository::class)
41
     * @var OrderItemTypeRepository
42
     */
43
    protected $orderItemTypeRepository;
44
45
    /**
46
     * @Inject(OrderStatusRepository::class)
47
     * @var OrderStatusRepository
48
     */
49
    protected $orderStatusRepository;
50
51
    /**
52
     * @Inject(TaxRuleRepository::class)
53
     * @var TaxRuleRepository
54
     */
55
    protected $taxRuleRepository;
56
57
    /**
58
     * @Inject(DeliveryFeeRepository::class)
59
     * @var DeliveryFeeRepository
60
     */
61
    protected $deliveryFeeRepository;
62
63
    /**
64
     * @Inject(DeliveryRepository::class)
65
     * @var DeliveryRepository
66
     */
67
    protected $deliveryRepository;
68
69
    /**
70
     * @Inject(PaymentRepository::class)
71
     * @var PaymentRepository
72
     */
73
    protected $paymentRepository;
74
75
    /**
76
     * @Inject(OrderRepository::class)
77
     * @var OrderRepository
78
     */
79
    protected $orderRepository;
80
81
    /**
82
     * @Inject(ShippingStatusRepository::class)
83
     * @var ShippingStatusRepository
84
     */
85
    protected $shippingStatusRepository;
86
87
    /**
88
     * @Inject("orm.em")
89
     * @var EntityManager
90
     */
91
    protected $entityManager;
92
93
    /**
94
     * @Inject("config")
95
     * @var array
96
     */
97
    protected $appConfig;
98
99
    /**
100
     * 購入処理中の受注データを生成する.
101
     *
102
     * @param Customer $Customer
0 ignored issues
show
introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
103
     * @param CustomerAddress $CustomerAddress
104
     * @param array $CartItems
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
105
     * @return Order
106
     */
107 11
    public function createProcessingOrder(Customer $Customer, CustomerAddress $CustomerAddress, $CartItems)
108
    {
109 11
        $OrderStatus = $this->orderStatusRepository->find($this->appConfig['order_processing']);
110 11
        $Order = new Order($OrderStatus);
111
112
        // pre_order_idを生成
113 11
        $Order->setPreOrderId($this->createPreOrderId());
114
115
        // 顧客情報の設定
116 11
        $this->setCustomer($Order, $Customer);
117
118
        // 明細情報の設定
119 11
        $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...
120
        $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...
121
            /* @var OrderItem $item */
122 11
            $productTypeId = $item->getProductClass()->getProductType()->getId();
123 11
            $result[$productTypeId][] = $item;
124 11
            return $result;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
125 11
        }, []);
126
127 11
        foreach ($OrderItemsGroupByProductType as $OrderItems) {
128 11
            $Shipping = $this->createShippingFromCustomerAddress($CustomerAddress);
129 11
            $this->addOrderItems($Order, $Shipping, $OrderItems);
130 11
            $this->setDefaultDelivery($Shipping);
131 11
            $this->entityManager->persist($Shipping);
132
        }
133
134 11
        $this->setDefaultPayment($Order);
135
136 11
        $this->entityManager->persist($Order);
137 11
        $this->entityManager->flush();
138
139 11
        return $Order;
140
    }
141
142 11
    public function createPreOrderId()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
143
    {
144
        // ランダムなpre_order_idを作成
145 View Code Duplication
        do {
146 11
            $preOrderId = sha1(Str::random(32));
147
148 11
            $Order = $this->orderRepository->findOneBy(
149
                [
150 11
                    'pre_order_id' => $preOrderId,
151 11
                    'OrderStatus' => $this->appConfig['order_processing'],
152
                ]
153
            );
154 11
        } while ($Order);
155
156 11
        return $preOrderId;
157
    }
158
159 11
    public function setCustomer(Order $Order, Customer $Customer)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
160
    {
161 11
        if ($Customer->getId()) {
162 8
            $Order->setCustomer($Customer);
163
        }
164
165 11
        $Order->copyProperties(
166 11
            $Customer,
167
            [
168 11
                'id',
169
                'create_date',
170
                'update_date',
171
                'del_flg',
172
            ]
173
        );
174
    }
175
176
    /**
177
     * @param ArrayCollection $CartItems
178
     * @return OrderItem[]
179
     */
180 11
    private function createOrderItemsFromCartItems($CartItems)
181
    {
182 11
        $ProductItemType = $this->orderItemTypeRepository->find(OrderItemType::PRODUCT);
183
        // TODO
184 11
        $TaxExclude = $this->entityManager->getRepository(TaxDisplayType::class)->find(TaxDisplayType::EXCLUDED);
185 11
        $Taxion = $this->entityManager->getRepository(TaxType::class)->find(TaxType::TAXATION);
186
187 11
        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...
188
            /* @var $item CartItem */
189
            /* @var $ProductClass \Eccube\Entity\ProductClass */
190 11
            $ProductClass = $item->getObject();
191
            /* @var $Product \Eccube\Entity\Product */
192 11
            $Product = $ProductClass->getProduct();
193 11
            $TaxRule = $this->taxRuleRepository->getByRule($Product, $ProductClass);
194
195 11
            $OrderItem = new OrderItem();
196
            $OrderItem
197 11
                ->setProduct($Product)
198 11
                ->setProductClass($ProductClass)
199 11
                ->setProductName($Product->getName())
200 11
                ->setProductCode($ProductClass->getCode())
201 11
                ->setPrice($ProductClass->getPrice02())
202 11
                ->setQuantity($item->getQuantity())
203 11
                ->setTaxRule($TaxRule->getId())
204 11
                ->setTaxRate($TaxRule->getTaxRate())
205 11
                ->setOrderItemType($ProductItemType)
206 11
                ->setTaxDisplayType($TaxExclude)
207 11
                ->setTaxType($Taxion);
208
209 11
            $ClassCategory1 = $ProductClass->getClassCategory1();
210 11
            if (!is_null($ClassCategory1)) {
211 11
                $OrderItem->setClasscategoryName1($ClassCategory1->getName());
212 11
                $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
213
            }
214 11
            $ClassCategory2 = $ProductClass->getClassCategory2();
215 11
            if (!is_null($ClassCategory2)) {
216 11
                $OrderItem->setClasscategoryName2($ClassCategory2->getName());
217 11
                $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
218
            }
219
220 11
            return $OrderItem;
221 11
        }, $CartItems->toArray());
222
    }
223
224 11
    public function createShippingFromCustomerAddress(CustomerAddress $CustomerAddress)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
introduced by
Missing function doc comment
Loading history...
225
    {
226 11
        $Shipping = new Shipping();
227
        $Shipping
228 11
            ->setName01($CustomerAddress->getName01())
229 11
            ->setName02($CustomerAddress->getName02())
230 11
            ->setKana01($CustomerAddress->getKana01())
231 11
            ->setKana02($CustomerAddress->getKana02())
232 11
            ->setCompanyName($CustomerAddress->getCompanyName())
233 11
            ->setTel01($CustomerAddress->getTel01())
234 11
            ->setTel02($CustomerAddress->getTel02())
235 11
            ->setTel03($CustomerAddress->getTel03())
236 11
            ->setFax01($CustomerAddress->getFax01())
237 11
            ->setFax02($CustomerAddress->getFax02())
238 11
            ->setFax03($CustomerAddress->getFax03())
239 11
            ->setZip01($CustomerAddress->getZip01())
240 11
            ->setZip02($CustomerAddress->getZip02())
241 11
            ->setZipCode($CustomerAddress->getZip01().$CustomerAddress->getZip02())
242 11
            ->setPref($CustomerAddress->getPref())
243 11
            ->setAddr01($CustomerAddress->getAddr01())
244 11
            ->setAddr02($CustomerAddress->getAddr02());
245
246 11
        $ShippingStatus = $this->shippingStatusRepository->find(ShippingStatus::PREPARED);
247 11
        $Shipping->setShippingStatus($ShippingStatus);
248
249 11
        return $Shipping;
250
    }
251
252
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$Order" missing
Loading history...
introduced by
Doc comment for parameter "$Shipping" missing
Loading history...
253
     * @deprecated
254
     */
255
    public function addShipping(Order $Order, Shipping $Shipping)
256
    {
257
        @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...
258
        $Order->addShipping($Shipping);
259
        $Shipping->setOrder($Order);
260
    }
261
262 11
    public function setDefaultDelivery(Shipping $Shipping)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
263
    {
264
        // 配送商品に含まれる商品種別を抽出.
265 11
        $OrderItems = $Shipping->getOrderItems();
266 11
        $ProductTypes = [];
267 11 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
268 11
            $ProductClass = $OrderItem->getProductClass();
269 11
            $ProductType = $ProductClass->getProductType();
270 11
            $ProductTypes[$ProductType->getId()] = $ProductType;
271
        }
272
273
        // 商品種別に紐づく配送業者を取得.
274 11
        $Deliveries = $this->deliveryRepository->getDeliveries($ProductTypes);
275
276
        // 初期の配送業者を設定
277 11
        $Delivery = current($Deliveries);
278 11
        $Shipping->setDelivery($Delivery);
279 11
        $Shipping->setShippingDeliveryName($Delivery->getName());
280
281
        // TODO 配送料の取得方法はこれで良いか要検討
282 11
        $deliveryFee = $this->deliveryFeeRepository->findOneBy(array('Delivery' => $Delivery, 'Pref' => $Shipping->getPref()));
283 11
        if ($deliveryFee) {
284 11
            $Shipping->setShippingDeliveryFee($deliveryFee->getFee());
285 11
            $Shipping->setFeeId($deliveryFee->getId());
286
        }
287
    }
288
289 11
    public function setDefaultPayment(Order $Order)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
290
    {
291 11
        $OrderItems = $Order->getOrderItems();
292
293
        // 受注明細に含まれる商品種別を抽出.
294 11
        $ProductTypes = [];
295
        /** @var OrderItem $OrderItem */
296 11 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
297 11
            $ProductClass = $OrderItem->getProductClass();
298 11
            if (is_null($ProductClass)) {
299
                // 商品明細のみ対象とする. 送料明細等はスキップする.
300
                continue;
301
            }
302 11
            $ProductType = $ProductClass->getProductType();
303 11
            $ProductTypes[$ProductType->getId()] = $ProductType;
304
        }
305
306
        // 商品種別に紐づく配送業者を抽出
307 11
        $Deliveries = $this->deliveryRepository->getDeliveries($ProductTypes);
308
309
        // 利用可能な支払い方法を抽出.
310 11
        $Payments = $this->paymentRepository->findAllowedPayments($Deliveries, true);
311
312
        // 初期の支払い方法を設定.
313 11
        $Payment = current($Payments);
314 11
        $Order->setPayment($Payment);
315 11
        $Order->setPaymentMethod($Payment->getMethod());
316
        // TODO CalculateChargeStrategy でセットする
317
        // $Order->setCharge($Payment->getCharge());
318
    }
319
320 11
    public function addOrderItems(Order $Order, Shipping $Shipping, array $OrderItems)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
321
    {
322 11
        foreach ($OrderItems as $OrderItem) {
323 11
            $Shipping->addOrderItem($OrderItem);
324 11
            $Order->addOrderItem($OrderItem);
325 11
            $OrderItem->setOrder($Order);
326 11
            $OrderItem->setShipping($Shipping);
327
        }
328
    }
329
330
}
331