Failed Conditions
Push — 4.0 ( f3e983...d5d6e1 )
by Ryo
22s queued 10s
created

OrderItemType::buildForm()   F

Complexity

Conditions 22
Paths 1

Size

Total Lines 165

Duplication

Lines 24
Ratio 14.55 %

Code Coverage

Tests 67
CRAP Score 22.5879

Importance

Changes 0
Metric Value
cc 22
nc 1
nop 2
dl 24
loc 165
ccs 67
cts 75
cp 0.8933
crap 22.5879
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.ec-cube.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\Form\Type\Admin;
15
16
use Doctrine\ORM\EntityManagerInterface;
17
use Eccube\Common\EccubeConfig;
18
use Eccube\Entity\BaseInfo;
19
use Eccube\Entity\Master\OrderItemType as OrderItemTypeMaster;
20
use Eccube\Entity\Master\TaxType;
21
use Eccube\Entity\OrderItem;
22
use Eccube\Entity\ProductClass;
23
use Eccube\Form\DataTransformer;
24
use Eccube\Form\Type\PriceType;
25
use Eccube\Repository\BaseInfoRepository;
26
use Eccube\Repository\Master\OrderItemTypeRepository;
27
use Eccube\Repository\OrderItemRepository;
28
use Eccube\Repository\ProductClassRepository;
29
use Eccube\Repository\TaxRuleRepository;
30
use Eccube\Util\StringUtil;
31
use Symfony\Component\Form\AbstractType;
32
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
33
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
34
use Symfony\Component\Form\Extension\Core\Type\TextType;
35
use Symfony\Component\Form\FormBuilderInterface;
36
use Symfony\Component\Form\FormError;
37
use Symfony\Component\Form\FormEvent;
38
use Symfony\Component\Form\FormEvents;
39
use Symfony\Component\Form\FormInterface;
40
use Symfony\Component\OptionsResolver\OptionsResolver;
41
use Symfony\Component\Validator\Constraints as Assert;
42
use Symfony\Component\Validator\ConstraintViolationListInterface;
43
use Symfony\Component\Validator\Validator\ValidatorInterface;
44
45
class OrderItemType extends AbstractType
46
{
47
    /**
48
     * @var EntityManagerInterface
49
     */
50
    protected $entityManager;
51
52
    /**
53
     * @var EccubeConfig
54
     */
55
    protected $eccubeConfig;
56
57
    /**
58
     * @var BaseInfo
59
     */
60
    protected $BaseInfo;
61
62
    /**
63
     * @var ProductClassRepository
64
     */
65
    protected $productClassRepository;
66
67
    /**
68
     * @var OrderItemRepository
69
     */
70
    protected $orderItemRepository;
71
72
    /**
73
     * @var OrderItemTypeRepository
74
     */
75
    protected $orderItemTypeRepository;
76
77
    /**
78
     * @var TaxRuleRepository
79
     */
80
    protected $taxRuleRepository;
81
82
    /**
83
     * @var ValidatorInterface
84
     */
85
    protected $validator;
86
87
    /**
88
     * OrderItemType constructor.
89
     *
90
     * @param EntityManagerInterface $entityManager
91
     * @param EccubeConfig $eccubeConfig
92
     * @param BaseInfoRepository $baseInfoRepository
93 32
     * @param ProductClassRepository $productClassRepository
94
     * @param OrderItemRepository $orderItemRepository
95
     * @param OrderItemTypeRepository $orderItemTypeRepository
96
     * @param TaxRuleRepository $taxRuleRepository
97
     * @param ValidatorInterface $validator
98
     *
99
     * @throws \Exception
100
     */
101
    public function __construct(
102
        EntityManagerInterface $entityManager,
103 32
        EccubeConfig $eccubeConfig,
104 32
        BaseInfoRepository $baseInfoRepository,
105 32
        ProductClassRepository $productClassRepository,
106 32
        OrderItemRepository $orderItemRepository,
107 32
        OrderItemTypeRepository $orderItemTypeRepository,
108 32
        TaxRuleRepository $taxRuleRepository,
109 32
        ValidatorInterface $validator
110 32
    ) {
111
        $this->entityManager = $entityManager;
112
        $this->eccubeConfig = $eccubeConfig;
113
        $this->BaseInfo = $baseInfoRepository->get();
114
        $this->productClassRepository = $productClassRepository;
115
        $this->orderItemRepository = $orderItemRepository;
116 32
        $this->orderItemTypeRepository = $orderItemTypeRepository;
117
        $this->taxRuleRepository = $taxRuleRepository;
118
        $this->validator = $validator;
119 32
    }
120
121 32
    /**
122 32
     * {@inheritdoc}
123 32
     */
124
    public function buildForm(FormBuilderInterface $builder, array $options)
125
    {
126
        $builder
127 32
            ->add('product_name', TextType::class, [
128 32
                'constraints' => [
129
                    new Assert\NotBlank(),
130 32
                    new Assert\Length([
131
                        'max' => $this->eccubeConfig['eccube_mtext_len'],
132 32
                    ]),
133 32
                ],
134 32
            ])
135
            ->add('price', PriceType::class, [
136
                'accept_minus' => true,
137
            ])
138
            ->add('quantity', IntegerType::class, [
139
                'constraints' => [
140 32
                    new Assert\NotBlank(),
141 32
                    new Assert\Length([
142 32
                        'max' => $this->eccubeConfig['eccube_int_len'],
143 32
                    ]),
144
                ],
145 32
            ])
146 32
            ->add('tax_rate', IntegerType::class, [
147 32
                'required' => true,
148 32
                'constraints' => [
149
                    new Assert\NotBlank(),
150
                    new Assert\Range(['min' => 0]),
151 32
                    new Assert\Regex([
152
                        'pattern' => "/^\d+(\.\d+)?$/u",
153 19
                        'message' => 'form_error.float_only',
154
                    ]),
155 19
                ],
156 19
            ]);
157 19
158 18
        $builder
159 18
            ->add($builder->create('order_item_type', HiddenType::class)
160 18
                ->addModelTransformer(new DataTransformer\EntityToIdTransformer(
161 18
                    $this->entityManager,
162 1
                    OrderItemTypeMaster::class
163
                )))
164 18
            ->add($builder->create('tax_type', HiddenType::class)
165 13
                ->addModelTransformer(new DataTransformer\EntityToIdTransformer(
166
                    $this->entityManager,
167 18
                    TaxType::class
168 13
                )))
169 13
            ->add($builder->create('ProductClass', HiddenType::class)
170 13
                ->addModelTransformer(new DataTransformer\EntityToIdTransformer(
171
                    $this->entityManager,
172 18
                    ProductClass::class
173 8
                )));
174 8
175 8
        // 受注明細フォームの税率を補完する
176
        $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
177
            $OrderItem = $event->getData();
178 18
179
            if (!isset($OrderItem['tax_rate']) || StringUtil::isBlank($OrderItem['tax_rate'])) {
180
                $orderItemTypeId = $OrderItem['order_item_type'];
181 4
182
                if ($orderItemTypeId == OrderItemTypeMaster::PRODUCT) {
183 32
                    /** @var ProductClass $ProductClass */
184
                    $ProductClass = $this->productClassRepository->find($OrderItem['ProductClass']);
185
                    $Product = $ProductClass->getProduct();
186 32
                    $TaxRule = $this->taxRuleRepository->getByRule($Product, $ProductClass);
187 19
188
                    if (!isset($OrderItem['tax_type']) || StringUtil::isBlank($OrderItem['tax_type'])) {
189 19
                        $OrderItem['tax_type'] = TaxType::TAXATION;
190
                    }
191 19
192 19
                } else {
193
                    if ($orderItemTypeId == OrderItemTypeMaster::DISCOUNT && $OrderItem['tax_type'] == TaxType::NON_TAXABLE) {
194 19
                        $OrderItem['tax_rate'] = '0';
195 18
                        $event->setData($OrderItem);
196 18
197 18
                        return;
198
                    }
199
200 4
                    $TaxRule = $this->taxRuleRepository->getByRule();
201 1
                }
202 1
203 1
                $OrderItem['tax_rate'] = $TaxRule->getTaxRate();
204 1
                $event->setData($OrderItem);
205
            }
206 1
        });
207
208
        $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
209 3
            /** @var OrderItem $OrderItem */
210
            $OrderItem = $event->getData();
211 3
212 3
            $OrderItemType = $OrderItem->getOrderItemType();
213 3
214 3
            switch ($OrderItemType->getId()) {
215
                case OrderItemTypeMaster::PRODUCT:
216 3
                    $ProductClass = $OrderItem->getProductClass();
217
                    $Product = $ProductClass->getProduct();
218
                    $OrderItem->setProduct($Product);
219
                    if (null === $OrderItem->getPrice()) {
220
                        $OrderItem->setPrice($ProductClass->getPrice02());
221 32
                    }
222
                    if (null === $OrderItem->getProductCode()) {
223
                        $OrderItem->setProductCode($ProductClass->getCode());
224
                    }
225
                    if (null === $OrderItem->getClassName1() && $ProductClass->hasClassCategory1()) {
226
                        $ClassCategory1 = $ProductClass->getClassCategory1();
227 32
                        $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
228
                        $OrderItem->setClassCategoryName1($ClassCategory1->getName());
229 32
                    }
230 32
                    if (null === $OrderItem->getClassName2() && $ProductClass->hasClassCategory2()) {
231
                        if ($ClassCategory2 = $ProductClass->getClassCategory2()) {
232
                            $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
233
                            $OrderItem->setClassCategoryName2($ClassCategory2->getName());
234
                        }
235
                    }
236 View Code Duplication
                    if (null === $OrderItem->getRoundingType()) {
237 16
                        $TaxRule = $this->taxRuleRepository->getByRule($Product, $ProductClass);
238
                        $OrderItem->setRoundingType($TaxRule->getRoundingType())
239 16
                            ->setTaxAdjust($TaxRule->getTaxAdjust());
240
                    }
241
                    break;
242
                default:
243 View Code Duplication
                    if (null === $OrderItem->getRoundingType()) {
244
                        $TaxRule = $this->taxRuleRepository->getByRule();
245
                        $OrderItem->setRoundingType($TaxRule->getRoundingType())
246 19
                            ->setTaxAdjust($TaxRule->getTaxAdjust());
247
                    }
248 19
            }
249
        });
250
251
        // price, quantityのバリデーション
252 19
        $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
253
            $form = $event->getForm();
254
            /** @var OrderItem $OrderItem */
255
            $OrderItem = $event->getData();
256
257
            $OrderItemType = $OrderItem->getOrderItemType();
258
            switch ($OrderItemType->getId()) {
259
                // 商品明細: 金額 -> 正, 個数 -> 正負
260
                case OrderItemTypeMaster::PRODUCT:
261
                    $errors = $this->validator->validate($OrderItem->getPrice(), [new Assert\GreaterThanOrEqual(0)]);
262
                    $this->addErrorsIfExists($form['price'], $errors);
263
                    break;
264
265
                // 値引き明細: 金額 -> 負, 個数 -> 正
266 View Code Duplication
                case OrderItemTypeMaster::DISCOUNT:
267
                    $errors = $this->validator->validate($OrderItem->getPrice(), [new Assert\LessThanOrEqual(0)]);
268
                    $this->addErrorsIfExists($form['price'], $errors);
269
                    $errors = $this->validator->validate($OrderItem->getQuantity(), [new Assert\GreaterThanOrEqual(0)]);
270
                    $this->addErrorsIfExists($form['quantity'], $errors);
271
272
                    break;
273
274
                // 送料, 手数料: 金額 -> 正, 個数 -> 正
275
                case OrderItemTypeMaster::DELIVERY_FEE:
276 View Code Duplication
                case OrderItemTypeMaster::CHARGE:
277
                    $errors = $this->validator->validate($OrderItem->getPrice(), [new Assert\GreaterThanOrEqual(0)]);
278
                    $this->addErrorsIfExists($form['price'], $errors);
279
                    $errors = $this->validator->validate($OrderItem->getQuantity(), [new Assert\GreaterThanOrEqual(0)]);
280
                    $this->addErrorsIfExists($form['quantity'], $errors);
281
282
                    break;
283
284
                default:
285
                    break;
286
            }
287
        });
288
    }
289
290
    /**
291
     * {@inheritdoc}
292
     */
293
    public function configureOptions(OptionsResolver $resolver)
294
    {
295
        $resolver->setDefaults([
296
            'data_class' => OrderItem::class,
297
        ]);
298
    }
299
300
    /**
301
     * {@inheritdoc}
302
     */
303
    public function getBlockPrefix()
304
    {
305
        return 'order_item';
306
    }
307
308
    /**
309
     * @param FormInterface $form
310
     * @param ConstraintViolationListInterface $errors
311
     */
312
    protected function addErrorsIfExists(FormInterface $form, ConstraintViolationListInterface $errors)
313
    {
314
        if (empty($errors)) {
315
            return;
316
        }
317
318
        foreach ($errors as $error) {
319
            $form->addError(new FormError(
320
                $error->getMessage(),
321
                $error->getMessageTemplate(),
322
                $error->getParameters(),
323
                $error->getPlural()));
324
        }
325
    }
326
}
327