Completed
Push — experimental/sf ( e6c9ad...549caa )
by chihiro
51:25 queued 45:10
created

ShippingController   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 255
Duplicated Lines 2.35 %

Coupling/Cohesion

Components 1
Dependencies 15

Test Coverage

Coverage 94.19%

Importance

Changes 0
Metric Value
dl 6
loc 255
ccs 81
cts 86
cp 0.9419
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 6
    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 6
        $this->mailService = $mailService;
107 6
        $this->orderItemRepository = $orderItemRepository;
108 6
        $this->categoryRepository = $categoryRepository;
109 6
        $this->deliveryRepository = $deliveryRepository;
110 6
        $this->taxRuleService = $taxRuleService;
111 6
        $this->shippingRepository = $shippingRepository;
112 6
        $this->serializer = $serializer;
113 6
        $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 3
    public function index(Request $request, Order $Order)
123
    {
124 3
        $TargetShippings = $Order->getShippings();
125
126
        // 編集前の受注情報を保持
127 3
        $OriginShippings = new ArrayCollection();
128 3
        $OriginOrderItems = [];
129
130 3
        foreach ($TargetShippings as $key => $TargetShipping) {
131 3
            $OriginShippings->add($TargetShipping);
132
133
            // 編集前のお届け先のアイテム情報を保持
134 3
            $OriginOrderItems[$key] = new ArrayCollection();
135
136 3
            foreach ($TargetShipping->getOrderItems() as $OrderItem) {
137 3
                $OriginOrderItems[$key]->add($OrderItem);
138
            }
139
        }
140
141 3
        $builder = $this->formFactory->createBuilder();
142
        $builder
143 3
            ->add('shippings', CollectionType::class, [
144 3
                'entry_type' => ShippingType::class,
145 3
                'data' => $TargetShippings,
146
                'allow_add' => true,
147
                'allow_delete' => true,
148
                'prototype' => true,
149
            ]);
150
151
        // 配送先の追加フラグ
152
        $builder
153 3
            ->add('add_shipping', HiddenType::class, [
154 3
                'mapped' => false,
155
            ]);
156
157
        // 配送先の追加フラグが立っている場合は新しいお届け先を追加
158 3
        $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
159 3
            $data = $event->getData();
160 3
            if ($data['add_shipping']) {
161 1
                $Shippings = $data['shippings'];
162 1
                $newShipping = ['Delivery' => ''];
163 1
                $Shippings[] = $newShipping;
164 1
                $data['shippings'] = $Shippings;
165 1
                $data['add_shipping'] = '';
166 1
                $event->setData($data);
167
            }
168 3
        });
169
170 3
        $form = $builder->getForm();
171
172 3
        $form->handleRequest($request);
173
174 3
        if ($form->isSubmitted() && $form->isValid() && $request->get('mode') == 'register') {
175 3
            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 3
            foreach ($OriginShippings as $key => $OriginShipping) {
180 3
                if (false === $TargetShippings->contains($OriginShipping)) {
181
                    // お届け先自体が削除された場合
182
                    // 削除されたお届け先に紐づく明細の削除
183
                    /** @var OrderItem $OriginOrderItem */
184 1
                    foreach ($OriginOrderItems[$key] as $OriginOrderItem) {
185 1
                        $this->entityManager->remove($OriginOrderItem);
186
                    }
187
188
                    // 削除されたお届け先の削除
189 1
                    $this->entityManager->remove($OriginShipping);
190
                } else {
191
                    // お届け先は削除されていない場合
192
                    // 削除された明細の削除
193
                    /** @var OrderItem $OriginOrderItem */
194 3
                    foreach ($OriginOrderItems[$key] as $OriginOrderItem) {
195 3
                        if (false === $TargetShippings[$key]->getOrderItems()->contains($OriginOrderItem)) {
196 3
                            $this->entityManager->remove($OriginOrderItem);
197
                        }
198
                    }
199
                }
200
            }
201
202
            // 追加された項目の追加
203 3
            foreach ($TargetShippings as $TargetShipping) {
204
                // 追加された明細の追加
205 3
                foreach ($TargetShipping->getOrderItems() as $OrderItem) {
206 3
                    $OrderItem->setShipping($TargetShipping);
207 3
                    $OrderItem->setOrder($Order);
208
                }
209
210
                // 追加されたお届け先の追加
211 3
                $TargetShipping->setOrder($Order);
212
            }
213
214
            try {
215 3
                foreach ($TargetShippings as $TargetShipping) {
216 3
                    $this->entityManager->persist($TargetShipping);
217
                }
218 3
                $this->entityManager->flush();
219
220 3
                $this->addSuccess('admin.shipping.edit.save.complete', 'admin');
221 3
                $this->addInfo('admin.shipping.edit.save.info', 'admin');
222 3
                log_info('出荷登録完了', [$Order->getId()]);
223
224 3
                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 3
        } elseif ($form->isSubmitted() && $request->get('mode') == 'register' && $form->getErrors(true)) {
230 1
            $this->addError('admin.flash.register_failed', 'admin');
231
        }
232
233
        // 商品検索フォーム
234 3
        $builder = $this->formFactory
235 3
            ->createBuilder(SearchProductType::class);
236
237 3
        $searchProductModalForm = $builder->getForm();
238
239
        // 配送業者のお届け時間
240 3
        $times = [];
241 3
        $deliveries = $this->deliveryRepository->findAll();
242 3 View Code Duplication
        foreach ($deliveries as $Delivery) {
243 3
            $deliveryTiems = $Delivery->getDeliveryTimes();
244 3
            foreach ($deliveryTiems as $DeliveryTime) {
245 3
                $times[$Delivery->getId()][$DeliveryTime->getId()] = $DeliveryTime->getDeliveryTime();
246
            }
247
        }
248
249
        return [
250 3
            'form' => $form->createView(),
251 3
            'searchProductModalForm' => $searchProductModalForm->createView(),
252 3
            'Order' => $Order,
253 3
            '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 2
    public function notifyMail(Shipping $Shipping)
282
    {
283 2
        $this->isTokenValid();
284
285 2
        $this->mailService->sendShippingNotifyMail($Shipping);
286
287 2
        $Shipping->setMailSendDate(new \DateTime());
288 2
        $this->shippingRepository->save($Shipping);
289 2
        $this->entityManager->flush();
290
291 2
        return $this->json([
292 2
            'mail' => true,
293
            'shipped' => false,
294
        ]);
295
    }
296
}
297