Failed Conditions
Pull Request — experimental/sf (#3241)
by k-yamamura
43:19 queued 23:09
created

EditController   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 260
Duplicated Lines 9.62 %

Coupling/Cohesion

Components 2
Dependencies 17

Test Coverage

Coverage 68.04%

Importance

Changes 0
Metric Value
dl 25
loc 260
rs 10
c 0
b 0
f 0
ccs 66
cts 97
cp 0.6804
wmc 27
lcom 2
cbo 17

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 19 19 1
F edit() 6 123 21
A searchProduct() 0 27 2
A searchItem() 0 18 3

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\Shipping;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Eccube\Controller\AbstractController;
18
use Eccube\Entity\Master\ShippingStatus;
19
use Eccube\Entity\OrderItem;
20
use Eccube\Entity\Shipping;
21
use Eccube\Form\Type\Admin\ShippingType;
22
use Eccube\Repository\CategoryRepository;
23
use Eccube\Repository\DeliveryRepository;
24
use Eccube\Repository\Master\ShippingStatusRepository;
25
use Eccube\Repository\OrderItemRepository;
26
use Eccube\Repository\ShippingRepository;
27
use Eccube\Service\TaxRuleService;
28
use Knp\Component\Pager\PaginatorInterface;
29
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
30
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
31
use Symfony\Component\HttpFoundation\Request;
32
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
33
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
34
use Symfony\Component\Serializer\SerializerInterface;
35
use Eccube\Service\MailService;
36
37
class EditController extends AbstractController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
38
{
39
    /**
40
     * @var OrderItemRepository
41
     */
42
    protected $orderItemRepository;
43
44
    /**
45
     * @var CategoryRepository
46
     */
47
    protected $categoryRepository;
48
49
    /**
50
     * @var DeliveryRepository
51
     */
52
    protected $deliveryRepository;
53
54
    /**
55
     * @var TaxRuleService
56
     */
57
    protected $taxRuleService;
58
59
    /**
60
     * @var ShippingRepository
61
     */
62
    protected $shippingRepository;
63
64
    /**
65
     * @var SerializerInterface
66
     */
67
    protected $serializer;
68
69
    /**
70
     * @var ShippingStatusRepository
71
     */
72
    protected $shippingStatusRepository;
73
74
    /**
75
     * @var \Eccube\Service\MailService
76
     */
77
    protected $mailService;
78
79
    /**
80
     * EditController constructor.
81
     *
82
     * @param MailService $mailService
0 ignored issues
show
introduced by
Expected 14 spaces after parameter type; 1 found
Loading history...
83
     * @param OrderItemRepository $orderItemRepository
0 ignored issues
show
introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
84
     * @param CategoryRepository $categoryRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
85
     * @param DeliveryRepository $deliveryRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
86
     * @param TaxRuleService $taxRuleService
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
87
     * @param ShippingRepository $shippingRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
88
     * @param ShippingStatusRepository $shippingStatusRepository
89
     * @param SerializerInterface $serializer
0 ignored issues
show
introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
90
     */
91 6 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
92
        MailService $mailService,
93
        OrderItemRepository $orderItemRepository,
94
        CategoryRepository $categoryRepository,
95
        DeliveryRepository $deliveryRepository,
96
        TaxRuleService $taxRuleService,
97
        ShippingRepository $shippingRepository,
98
        ShippingStatusRepository $shippingStatusRepository,
99
        SerializerInterface $serializer
100
    ) {
101 6
        $this->mailService = $mailService;
102 6
        $this->orderItemRepository = $orderItemRepository;
103 6
        $this->categoryRepository = $categoryRepository;
104 6
        $this->deliveryRepository = $deliveryRepository;
105 6
        $this->taxRuleService = $taxRuleService;
106 6
        $this->shippingRepository = $shippingRepository;
107 6
        $this->shippingStatusRepository = $shippingStatusRepository;
108 6
        $this->serializer = $serializer;
109
    }
110
111
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
112
     * 出荷登録/編集画面.
113
     *
114
     * @Route("/%eccube_admin_route%/shipping/new", name="admin_shipping_new")
115
     * @Route("/%eccube_admin_route%/shipping/{id}/edit", requirements={"id" = "\d+"}, name="admin_shipping_edit")
116
     * @Template("@admin/Shipping/edit.twig")
117
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
118 6
    public function edit(Request $request, $id = null)
119
    {
120 6
        $TargetShipping = null;
0 ignored issues
show
Unused Code introduced by
$TargetShipping is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
121 6
        $OriginShipping = null;
0 ignored issues
show
Unused Code introduced by
$OriginShipping is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
122
123 6
        if (null === $id) {
124
            // 空のエンティティを作成.
125 2
            $TargetShipping = new Shipping();
126
        } else {
127 5
            $TargetShipping = $this->shippingRepository->find($id);
128 5
            if (null === $TargetShipping) {
129
                throw new NotFoundHttpException();
130
            }
131
        }
132
133
        // 編集前の受注情報を保持
134 6
        $OriginShipping = clone $TargetShipping;
135
        // 編集前のお届け先のアイテム情報を保持
136 6
        $OriginalOrderItems = new ArrayCollection();
137
138 6
        foreach ($TargetShipping->getOrderItems() as $OrderItem) {
139 4
            $OriginalOrderItems->add($OrderItem);
140
        }
141
142 6
        $builder = $this->formFactory
143 6
            ->createBuilder(ShippingType::class, $TargetShipping);
144
145 6
        $form = $builder->getForm();
146 6
        $form->handleRequest($request);
147
148 6
        if ($form->isSubmitted() && $form->isValid()) {
149
            // TODO: Should move logic out of controller such as service, modal
150
151
            // FIXME 税額計算は CalculateService で処理する. ここはテストを通すための暫定処理
152
            // see EditControllerTest::testOrderProcessingWithTax
153 5
            $OrderItems = $TargetShipping->getOrderItems();
154 5
            $taxtotal = 0;
155 5
            foreach ($OrderItems as $OrderItem) {
156 4
                $tax = $this->taxRuleService
157 4
                    ->calcTax($OrderItem->getPrice(), $OrderItem->getTaxRate(), $OrderItem->getTaxRule());
158 4
                $OrderItem->setPriceIncTax($OrderItem->getPrice() + $tax);
159
160 4
                $taxtotal += $tax * $OrderItem->getQuantity();
161
            }
162
163 5
            log_info('出荷登録開始', [$TargetShipping->getId()]);
164
            // TODO 在庫の有無や販売制限数のチェックなども行う必要があるため、完了処理もcaluclatorのように抽象化できないか検討する.
165
            // TODO 後続にある会員情報の更新のように、完了処理もcaluclatorのように抽象化できないか検討する.
166
            // 画面上で削除された明細をremove
167 5
            foreach ($OriginalOrderItems as $OrderItem) {
168 4
                if (false === $TargetShipping->getOrderItems()->contains($OrderItem)) {
169 4
                    $OrderItem->setShipping(null);
170
                }
171
            }
172
173 5
            foreach ($TargetShipping->getOrderItems() as $OrderItem) {
174 4
                $OrderItem->setShipping($TargetShipping);
175
            }
176
177 5
            $OriginShippingStatus = $OriginShipping->getShippingStatus();
178 5
            $TargetShippingStatus = $TargetShipping->getShippingStatus();
179
180
            // 出荷ステータス変更時の処理
181 5
            if ($TargetShippingStatus !== null
182 5
             && $TargetShippingStatus->getId() == ShippingStatus::SHIPPED) {
183
                // 「出荷済み」にステータスが変更された場合
184 2
                if ($OriginShippingStatus === null
185 2
                 || $OriginShippingStatus->getId() != $TargetShippingStatus->getId()) {
186
                    // 出荷日時を更新
187 2
                    $TargetShipping->setShippingDate(new \DateTime());
188
                    // 出荷メールを送信
189 2
                    if ($form->get('notify_email')->getData()) {
190
                        try {
191 1
                            $this->mailService->sendShippingNotifyMail(
192 1
                              $TargetShipping
193
                            );
194
                        } catch (\Exception $e) {
195
                            log_error('メール通知エラー', [$TargetShipping->getId(), $e]);
196
                            $this->addError(
197
                              'admin.shipping.edit.shipped_mail_failed',
198 2
                              'admin'
199
                            );
200
                        }
201
                    }
202
                }
203
            } else {
204
                // 「出荷済み」以外に変更した場合は、出荷日時をクリアする
205 3
                $TargetShipping->setShippingDate(null);
206
            }
207
208
            try {
209 5
                $this->entityManager->persist($TargetShipping);
210 5
                $this->entityManager->flush();
211
212 5
                $this->addSuccess('admin.shipping.edit.save.complete', 'admin');
213 5
                $this->addInfo('admin.shipping.edit.save.info', 'admin');
214 5
                log_info('出荷登録完了', [$TargetShipping->getId()]);
215
216 5
                return $this->redirectToRoute('admin_shipping_edit', ['id' => $TargetShipping->getId()]);
217
            } catch (\Exception $e) {
218
                log_error('出荷登録エラー', [$TargetShipping->getId(), $e]);
219
                $this->addError('admin.flash.register_failed', 'admin');
220
            }
221 6
        } elseif ($form->isSubmitted() && $form->getErrors(true)) {
222
            $this->addError('admin.flash.register_failed', 'admin');
223
        }
224
225
        // 配送業者のお届け時間
226 6
        $times = [];
227 6
        $deliveries = $this->deliveryRepository->findAll();
228 6 View Code Duplication
        foreach ($deliveries as $Delivery) {
229 6
            $deliveryTiems = $Delivery->getDeliveryTimes();
230 6
            foreach ($deliveryTiems as $DeliveryTime) {
231 6
                $times[$Delivery->getId()][$DeliveryTime->getId()] = $DeliveryTime->getDeliveryTime();
232
            }
233
        }
234
235
        return [
236 6
            'form' => $form->createView(),
237 6
            'Shipping' => $TargetShipping,
238 6
            'shippingDeliveryTimes' => $this->serializer->serialize($times, 'json'),
239
        ];
240
    }
241
242
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$paginator" missing
Loading history...
243
     * @Route("/%eccube_admin_route%/shipping/search/product", name="admin_shipping_search_product")
244
     * @Template("@admin/Shipping/search_product.twig")
245
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
246
    public function searchProduct(Request $request, PaginatorInterface $paginator)
247
    {
248
        if (!$request->isXmlHttpRequest()) {
249
            throw new BadRequestHttpException();
250
        }
251
252
        // FIXME: should use consistent param for pageno ? Other controller use page_no, but here use pageno, then I change from pageno to page_no
253
        $page_no = (int) $request->get('page_no', 1);
254
        $page_count = $this->eccubeConfig['eccube_default_page_count'];
255
256
        // TODO OrderItemRepository に移動
257
        $qb = $this->orderItemRepository->createQueryBuilder('s')
258
            ->where('s.Shipping is null AND s.Order is not null')
259
            ->andWhere('s.OrderItemType in (1, 2)');
260
261
        /** @var \Knp\Component\Pager\Pagination\SlidingPagination $pagination */
262
        $pagination = $paginator->paginate(
263
            $qb,
264
            $page_no,
265
            $page_count,
266
            ['wrap-queries' => true]
267
        );
268
269
        return [
270
            'pagination' => $pagination,
271
        ];
272
    }
273
274
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
275
     * @Route("/%eccube_admin_route%/shipping/search/item", name="admin_shipping_search_item")
276
     * @Template("@admin/Shipping/order_item_prototype.twig")
277
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
278
    public function searchItem(Request $request)
279
    {
280
        if (!$request->isXmlHttpRequest()) {
281
            throw new BadRequestHttpException();
282
        }
283
284
        $id = (int) $request->get('order-item-id');
285
        /** @var OrderItem $OrderItem */
286
        $OrderItem = $this->orderItemRepository->find($id);
287
        if (null === $OrderItem) {
288
            // not found.
289
            return $this->json([], 404);
290
        }
291
292
        return [
293
            'OrderItem' => $OrderItem,
294
        ];
295
    }
296
}
297