Failed Conditions
Pull Request — experimental/sf (#31)
by Kentaro
06:59
created

ShippingController   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 255
Duplicated Lines 2.35 %

Coupling/Cohesion

Components 1
Dependencies 15

Importance

Changes 0
Metric Value
dl 6
loc 255
rs 10
c 0
b 0
f 0
wmc 24
lcom 1
cbo 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 1
F index() 6 134 21
A previewShippingNotifyMail() 0 4 1
A notifyMail() 0 15 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\Controller\Admin\Order;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Eccube\Controller\AbstractController;
18
use Eccube\Entity\Order;
19
use Eccube\Entity\OrderItem;
20
use Eccube\Entity\Shipping;
21
use Eccube\Form\Type\Admin\SearchProductType;
22
use Eccube\Form\Type\Admin\ShippingType;
23
use Eccube\Repository\CategoryRepository;
24
use Eccube\Repository\DeliveryRepository;
25
use Eccube\Repository\OrderItemRepository;
26
use Eccube\Repository\ShippingRepository;
27
use Eccube\Service\MailService;
28
use Eccube\Service\OrderStateMachine;
29
use Eccube\Service\TaxRuleService;
30
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
31
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
32
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
33
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
34
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
35
use Symfony\Component\Form\FormEvent;
36
use Symfony\Component\Form\FormEvents;
37
use Symfony\Component\HttpFoundation\JsonResponse;
38
use Symfony\Component\HttpFoundation\Request;
39
use Symfony\Component\HttpFoundation\Response;
40
use Symfony\Component\Serializer\SerializerInterface;
41
42
class ShippingController extends AbstractController
43
{
44
    /**
45
     * @var OrderItemRepository
46
     */
47
    protected $orderItemRepository;
48
49
    /**
50
     * @var CategoryRepository
51
     */
52
    protected $categoryRepository;
53
54
    /**
55
     * @var DeliveryRepository
56
     */
57
    protected $deliveryRepository;
58
59
    /**
60
     * @var TaxRuleService
61
     */
62
    protected $taxRuleService;
63
64
    /**
65
     * @var ShippingRepository
66
     */
67
    protected $shippingRepository;
68
69
    /**
70
     * @var SerializerInterface
71
     */
72
    protected $serializer;
73
74
    /**
75
     * @var \Eccube\Service\MailService
76
     */
77
    protected $mailService;
78
79
    /**
80
     * @var OrderStateMachine
81
     */
82
    private $orderStateMachine;
83
84
    /**
85
     * EditController constructor.
86
     *
87
     * @param MailService $mailService
88
     * @param OrderItemRepository $orderItemRepository
89
     * @param CategoryRepository $categoryRepository
90
     * @param DeliveryRepository $deliveryRepository
91
     * @param TaxRuleService $taxRuleService
92
     * @param ShippingRepository $shippingRepository
93
     * @param SerializerInterface $serializer
94
     * @param OrderStateMachine $orderStateMachine
95
     */
96
    public function __construct(
97
        MailService $mailService,
98
        OrderItemRepository $orderItemRepository,
99
        CategoryRepository $categoryRepository,
100
        DeliveryRepository $deliveryRepository,
101
        TaxRuleService $taxRuleService,
102
        ShippingRepository $shippingRepository,
103
        SerializerInterface $serializer,
104
        OrderStateMachine $orderStateMachine
105
    ) {
106
        $this->mailService = $mailService;
107
        $this->orderItemRepository = $orderItemRepository;
108
        $this->categoryRepository = $categoryRepository;
109
        $this->deliveryRepository = $deliveryRepository;
110
        $this->taxRuleService = $taxRuleService;
111
        $this->shippingRepository = $shippingRepository;
112
        $this->serializer = $serializer;
113
        $this->orderStateMachine = $orderStateMachine;
114
    }
115
116
    /**
117
     * 出荷登録/編集画面.
118
     *
119
     * @Route("/%eccube_admin_route%/shipping/{id}/edit", requirements={"id" = "\d+"}, name="admin_shipping_edit")
120
     * @Template("@admin/Order/shipping.twig")
121
     */
122
    public function index(Request $request, Order $Order)
123
    {
124
        $TargetShippings = $Order->getShippings();
125
126
        // 編集前の受注情報を保持
127
        $OriginShippings = new ArrayCollection();
128
        $OriginOrderItems = [];
129
130
        foreach ($TargetShippings as $key => $TargetShipping) {
131
            $OriginShippings->add($TargetShipping);
132
133
            // 編集前のお届け先のアイテム情報を保持
134
            $OriginOrderItems[$key] = new ArrayCollection();
135
136
            foreach ($TargetShipping->getOrderItems() as $OrderItem) {
137
                $OriginOrderItems[$key]->add($OrderItem);
138
            }
139
        }
140
141
        $builder = $this->formFactory->createBuilder();
142
        $builder
143
            ->add('shippings', CollectionType::class, [
144
                'entry_type' => ShippingType::class,
145
                'data' => $TargetShippings,
146
                'allow_add' => true,
147
                'allow_delete' => true,
148
                'prototype' => true,
149
            ]);
150
151
        // 配送先の追加フラグ
152
        $builder
153
            ->add('add_shipping', HiddenType::class, [
154
                'mapped' => false,
155
            ]);
156
157
        // 配送先の追加フラグが立っている場合は新しいお届け先を追加
158
        $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
159
            $data = $event->getData();
160
            if ($data['add_shipping']) {
161
                $Shippings = $data['shippings'];
162
                $newShipping = ['Delivery' => ''];
163
                $Shippings[] = $newShipping;
164
                $data['shippings'] = $Shippings;
165
                $data['add_shipping'] = '';
166
                $event->setData($data);
167
            }
168
        });
169
170
        $form = $builder->getForm();
171
172
        $form->handleRequest($request);
173
174
        if ($form->isSubmitted() && $form->isValid() && $request->get('mode') == 'register') {
175
            log_info('出荷登録開始', [$TargetShipping->getId()]);
0 ignored issues
show
Bug introduced by
The variable $TargetShipping seems to be defined by a foreach iteration on line 130. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
176
177
            // 削除された項目の削除
178
            /** @var Shipping $OriginShipping */
179
            foreach ($OriginShippings as $key => $OriginShipping) {
180
                if (false === $TargetShippings->contains($OriginShipping)) {
181
                    // お届け先自体が削除された場合
182
                    // 削除されたお届け先に紐づく明細の削除
183
                    /** @var OrderItem $OriginOrderItem */
184
                    foreach ($OriginOrderItems[$key] as $OriginOrderItem) {
185
                        $this->entityManager->remove($OriginOrderItem);
186
                    }
187
188
                    // 削除されたお届け先の削除
189
                    $this->entityManager->remove($OriginShipping);
190
                } else {
191
                    // お届け先は削除されていない場合
192
                    // 削除された明細の削除
193
                    /** @var OrderItem $OriginOrderItem */
194
                    foreach ($OriginOrderItems[$key] as $OriginOrderItem) {
195
                        if (false === $TargetShippings[$key]->getOrderItems()->contains($OriginOrderItem)) {
196
                            $this->entityManager->remove($OriginOrderItem);
197
                        }
198
                    }
199
                }
200
            }
201
202
            // 追加された項目の追加
203
            foreach ($TargetShippings as $TargetShipping) {
204
                // 追加された明細の追加
205
                foreach ($TargetShipping->getOrderItems() as $OrderItem) {
206
                    $OrderItem->setShipping($TargetShipping);
207
                    $OrderItem->setOrder($Order);
208
                }
209
210
                // 追加されたお届け先の追加
211
                $TargetShipping->setOrder($Order);
212
            }
213
214
            try {
215
                foreach ($TargetShippings as $TargetShipping) {
216
                    $this->entityManager->persist($TargetShipping);
217
                }
218
                $this->entityManager->flush();
219
220
                $this->addSuccess('admin.shipping.edit.save.complete', 'admin');
221
                $this->addInfo('admin.shipping.edit.save.info', 'admin');
222
                log_info('出荷登録完了', [$Order->getId()]);
223
224
                return $this->redirectToRoute('admin_shipping_edit', ['id' => $Order->getId()]);
225
            } catch (\Exception $e) {
226
                log_error('出荷登録エラー', [$Order->getId(), $e]);
227
                $this->addError('admin.flash.register_failed', 'admin');
228
            }
229
        } elseif ($form->isSubmitted() && $request->get('mode') == 'register' && $form->getErrors(true)) {
230
            $this->addError('admin.flash.register_failed', 'admin');
231
        }
232
233
        // 商品検索フォーム
234
        $builder = $this->formFactory
235
            ->createBuilder(SearchProductType::class);
236
237
        $searchProductModalForm = $builder->getForm();
238
239
        // 配送業者のお届け時間
240
        $times = [];
241
        $deliveries = $this->deliveryRepository->findAll();
242 View Code Duplication
        foreach ($deliveries as $Delivery) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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
            $deliveryTiems = $Delivery->getDeliveryTimes();
244
            foreach ($deliveryTiems as $DeliveryTime) {
245
                $times[$Delivery->getId()][$DeliveryTime->getId()] = $DeliveryTime->getDeliveryTime();
246
            }
247
        }
248
249
        return [
250
            'form' => $form->createView(),
251
            'searchProductModalForm' => $searchProductModalForm->createView(),
252
            'Order' => $Order,
253
            'shippingDeliveryTimes' => $this->serializer->serialize($times, 'json'),
254
        ];
255
    }
256
257
    /**
258
     * @Route("/%eccube_admin_route%/shipping/preview_notify_mail/{id}", requirements={"id" = "\d+"}, name="admin_shipping_preview_notify_mail")
259
     *
260
     * @param Shipping $Shipping
261
     *
262
     * @return Response
263
     *
264
     * @throws \Twig_Error
265
     */
266
    public function previewShippingNotifyMail(Shipping $Shipping)
267
    {
268
        return new Response($this->mailService->getShippingNotifyMailBody($Shipping, $Shipping->getOrder()));
269
    }
270
271
    /**
272
     * @Method("PUT")
273
     * @Route("/%eccube_admin_route%/shipping/notify_mail/{id}", requirements={"id" = "\d+"}, name="admin_shipping_notify_mail")
274
     *
275
     * @param Shipping $Shipping
276
     *
277
     * @return JsonResponse
278
     *
279
     * @throws \Twig_Error
280
     */
281
    public function notifyMail(Shipping $Shipping)
282
    {
283
        $this->isTokenValid();
284
285
        $this->mailService->sendShippingNotifyMail($Shipping);
286
287
        $Shipping->setMailSendDate(new \DateTime());
288
        $this->shippingRepository->save($Shipping);
289
        $this->entityManager->flush();
290
291
        return $this->json([
292
            'mail' => true,
293
            'shipped' => false,
294
        ]);
295
    }
296
}
297