ProductClassController   D
last analyzed

Complexity

Total Complexity 81

Size/Duplication

Total Lines 738
Duplicated Lines 10.16 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 47.83%

Importance

Changes 0
Metric Value
dl 75
loc 738
rs 4
c 0
b 0
f 0
ccs 11
cts 23
cp 0.4783
wmc 81
lcom 1
cbo 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
D index() 7 214 21
D edit() 57 258 30
B render() 0 46 4
B createProductClasses() 0 37 6
A newProductClass() 0 8 1
A getProductClassesOriginal() 0 7 1
A getProductClassesExcludeNonClass() 0 9 2
B setDefualtProductClass() 11 35 6
C insertProductClass() 0 47 7
A isValiedCategory() 0 10 3

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ProductClassController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProductClassController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Controller\Admin\Product;
26
27
use Doctrine\Common\Collections\ArrayCollection;
28
use Eccube\Application;
29
use Eccube\Common\Constant;
30
use Eccube\Entity\ClassName;
31
use Eccube\Entity\Product;
32
use Eccube\Entity\ProductClass;
33
use Eccube\Entity\ProductStock;
34
use Eccube\Entity\TaxRule;
35
use Eccube\Event\EccubeEvents;
36
use Eccube\Event\EventArgs;
37
use Symfony\Component\Form\FormBuilder;
38
use Symfony\Component\Form\FormError;
39
use Symfony\Component\HttpFoundation\RedirectResponse;
40
use Symfony\Component\HttpFoundation\Request;
41
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
42
use Symfony\Component\Validator\Constraints as Assert;
43
44
class ProductClassController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
45
{
46
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
47
     * 商品規格が登録されていなければ新規登録、登録されていれば更新画面を表示する
48
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
49
    public function index(Application $app, Request $request, $id)
50
    {
51
        /** @var $Product \Eccube\Entity\Product */
52
        $Product = $app['eccube.repository.product']->find($id);
53
        $hasClassCategoryFlg = false;
54
55
        if (!$Product) {
56
            throw new NotFoundHttpException('商品が存在しません');
57
        }
58
59
        // 商品規格情報が存在しなければ新規登録させる
60
        if (!$Product->hasProductClass()) {
61
            // 登録画面を表示
62
63
            log_info('商品規格新規登録表示', array($id));
64
65
            $builder = $app['form.factory']->createBuilder();
66
67
            $builder
68
                ->add('class_name1', 'entity', array(
69
                    'class' => 'Eccube\Entity\ClassName',
70
                    'property' => 'name',
71
                    'empty_value' => '規格1を選択',
72
                    'constraints' => array(
73
                        new Assert\NotBlank(),
74
                    ),
75
                ))
76
                ->add('class_name2', 'entity', array(
77
                    'class' => 'Eccube\Entity\ClassName',
78
                    'property' => 'name',
79
                    'empty_value' => '規格2を選択',
80
                    'required' => false,
81
                ));
82
83
            $event = new EventArgs(
84
                array(
85
                    'builder' => $builder,
86
                    'Product' => $Product,
87
                ),
88
                $request
89
            );
90
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_INDEX_INITIALIZE, $event);
91
92
            $form = $builder->getForm();
93
94
            $productClassForm = null;
95
96
            if ('POST' === $request->getMethod()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
97
98
                $form->handleRequest($request);
99
100
                if ($form->isValid()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
101
102
                    $data = $form->getData();
103
104
                    $ClassName1 = $data['class_name1'];
105
                    $ClassName2 = $data['class_name2'];
106
107
                    log_info('選択された商品規格', array($ClassName1, $ClassName2));
108
109
                    // 各規格が選択されている際に、分類を保有しているか確認
110
                    $class1Valied = $this->isValiedCategory($ClassName1);
111
                    $class2Valied = $this->isValiedCategory($ClassName2);
112
113
                    // 規格が選択されていないか、選択された状態で分類が保有されていれば、画面表示
114
                    if($class1Valied && $class2Valied){
115
                        $hasClassCategoryFlg = true;
116
                    }
117
118
                    if (!is_null($ClassName2) && $ClassName1->getId() == $ClassName2->getId()) {
119
                        // 規格1と規格2が同じ値はエラー
120
                        $form['class_name2']->addError(new FormError('規格1と規格2は、同じ値を使用できません。'));
121
                    } else {
122
                        // 規格分類が設定されていない商品規格を取得
123
                        $orgProductClasses = $Product->getProductClasses();
124
                        $sourceProduct = $orgProductClasses[0];
125
126
                        // 規格分類が組み合わされた商品規格を取得
127
                        $ProductClasses = $this->createProductClasses($app, $Product, $ClassName1, $ClassName2);
128
129
                        // 組み合わされた商品規格にデフォルト値をセット
130
                        foreach ($ProductClasses as $productClass) {
131
                            $this->setDefualtProductClass($app, $productClass, $sourceProduct);
132
                        }
133
134
                        $builder = $app['form.factory']->createBuilder();
135
136
                        $builder
137
                            ->add('product_classes', 'collection', array(
138
                                'type' => 'admin_product_class',
139
                                'allow_add' => true,
140
                                'allow_delete' => true,
141
                                'data' => $ProductClasses,
142
                            ));
143
144
                        $event = new EventArgs(
145
                            array(
146
                                'builder' => $builder,
147
                                'Product' => $Product,
148
                                'ProductClasses' => $ProductClasses,
149
                            ),
150
                            $request
151
                        );
152
                        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_INDEX_CLASSES, $event);
153
154
                        $productClassForm = $builder->getForm()->createView();
155
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
156
                    }
157
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
158
                }
159
            }
160
161
            return $app->render('Product/product_class.twig', array(
162
                'form' => $form->createView(),
163
                'classForm' => $productClassForm,
164
                'Product' => $Product,
165
                'not_product_class' => true,
166
                'error' => null,
167
                'has_class_category_flg' => $hasClassCategoryFlg,
168
            ));
169
        } else {
170
            // 既に商品規格が登録されている場合、商品規格画面を表示する
171
172
            log_info('商品規格登録済表示', array($id));
173
174
            // 既に登録されている商品規格を取得
175
            $ProductClasses = $this->getProductClassesExcludeNonClass($Product);
176
177
            // 設定されている規格分類1、2を取得(商品規格の規格分類には必ず同じ値がセットされている)
178
            $ProductClass = $ProductClasses[0];
179
            $ClassName1 = $ProductClass->getClassCategory1()->getClassName();
180
            $ClassName2 = null;
181
            if (!is_null($ProductClass->getClassCategory2())) {
182
                $ClassName2 = $ProductClass->getClassCategory2()->getClassName();
183
            }
184
185
            // 規格分類が組み合わされた空の商品規格を取得
186
            $createProductClasses = $this->createProductClasses($app, $Product, $ClassName1, $ClassName2);
187
188
            $mergeProductClasses = array();
189
            $sortProductClasses = new ArrayCollection();
190
191
            // 商品税率が設定されている場合、商品税率を項目に設定
192
            $BaseInfo = $app['eccube.repository.base_info']->get();
193 View Code Duplication
            if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
194
                foreach ($ProductClasses as $class) {
195
                    if ($class->getTaxRule() && !$class->getTaxRule()->getDelFlg()) {
196
                        $class->setTaxRate($class->getTaxRule()->getTaxRate());
197
                    }
198
                }
199
            }
200
201
            // 登録済み商品規格と空の商品規格をマージ
202
            $flag = false;
203
            foreach ($createProductClasses as $createProductClass) {
204
                // 既に登録済みの商品規格にチェックボックスを設定
205
                foreach ($ProductClasses as $productClass) {
206
                    if ($productClass->getClassCategory1() == $createProductClass->getClassCategory1() &&
207
                        $productClass->getClassCategory2() == $createProductClass->getClassCategory2()) {
208
                        // チェックボックスを追加
209
                        $productClass->setAdd(true);
210
                        $flag = true;
211
                        $sortProductClasses->add($productClass);
212
                        break;
213
                    }
214
                }
215
216
                if (!$flag) {
217
                    $mergeProductClasses[] = $createProductClass;
218
                }
219
220
                $flag = false;
221
            }
222
223
            // 登録済み商品規格と空の商品規格をマージ
224
            foreach ($mergeProductClasses as $mergeProductClass) {
225
                // 空の商品規格にデフォルト値を設定
226
                $this->setDefualtProductClass($app, $mergeProductClass, $sortProductClasses[0]);
227
                $sortProductClasses->add($mergeProductClass);
228
            }
229 1
230
            $builder = $app['form.factory']->createBuilder();
231
232
            $builder
233
                ->add('product_classes', 'collection', array(
234
                    'type' => 'admin_product_class',
235 1
                    'allow_add' => true,
236
                    'allow_delete' => true,
237
                    'data' => $sortProductClasses,
238
                ));
239 1
240
            $event = new EventArgs(
241
                array(
242
                    'builder' => $builder,
243
                    'Product' => $Product,
244
                    'ProductClasses' => $sortProductClasses,
245
                ),
246
                $request
247
            );
248
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_INDEX_CLASSES, $event);
249
250
            $productClassForm = $builder->getForm()->createView();
251
252
            return $app->render('Product/product_class.twig', array(
253 1
                'classForm' => $productClassForm,
254 1
                'Product' => $Product,
255
                'class_name1' => $ClassName1,
256
                'class_name2' => $ClassName2,
257
                'not_product_class' => false,
258
                'error' => null,
259
                'has_class_category_flg' => true,
260
            ));
261
        }
262
    }
263
264
    /**
265
     * 商品規格の登録、更新、削除を行う
266
     *
267
     * @param Application $app
268
     * @param Request     $request
269
     * @param int         $id
270
     * @return RedirectResponse
271
     */
272
    public function edit(Application $app, Request $request, $id)
273
    {
274
275
        /* @var $softDeleteFilter \Eccube\Doctrine\Filter\SoftDeleteFilter */
276
        $softDeleteFilter = $app['orm.em']->getFilters()->getFilter('soft_delete');
277
        $softDeleteFilter->setExcludes(array(
278
            'Eccube\Entity\TaxRule',
279
        ));
280
281
        /** @var $Product \Eccube\Entity\Product */
282
        $Product = $app['eccube.repository.product']->find($id);
283
284
        if (!$Product) {
285
            throw new NotFoundHttpException('商品が存在しません');
286
        }
287
288
        /* @var FormBuilder $builder */
289
        $builder = $app['form.factory']->createBuilder();
290
        $builder->add('product_classes', 'collection', array(
291
            'type' => 'admin_product_class',
292
            'allow_add' => true,
293
            'allow_delete' => true,
294
        ));
295
296
        $event = new EventArgs(
297
            array(
298
                'builder' => $builder,
299
                'Product' => $Product,
300 1
            ),
301
            $request
302
        );
303
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_INITIALIZE, $event);
304
305
        $form = $builder->getForm();
306
307
        $ProductClasses = $this->getProductClassesExcludeNonClass($Product);
308
309
        $form->handleRequest($request);
310
        if ($form->isSubmitted()) {
311
            switch ($request->get('mode')) {
312
                case 'edit':
313
                    // 新規登録
314
                    log_info('商品規格新規登録開始', array($id));
315
316 View Code Duplication
                    if (count($ProductClasses) > 0) {
317
                        // 既に登録されていれば最初の画面に戻す
318
                        log_info('商品規格登録済', array($id));
319
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
320
                    }
321
322
                    $addProductClasses = array();
323
324
                    $tmpProductClass = null;
325 View Code Duplication
                    foreach ($form->get('product_classes') as $formData) {
326
                        // 追加対象の行をvalidate
327
                        $ProductClass = $formData->getData();
328
329
                        if ($ProductClass->getAdd()) {
330
                            if ($formData->isValid()) {
331
                                $addProductClasses[] = $ProductClass;
332
                            } else {
333
                                // 対象行のエラー
334
                                return $this->render($app, $Product, $ProductClass, true, $form);
335
                            }
336
                        }
337
                        $tmpProductClass = $ProductClass;
338
                    }
339
340 View Code Duplication
                    if (count($addProductClasses) == 0) {
341
                        // 対象がなければエラー
342
                        log_info('商品規格が未選択', array($id));
343
                        $error = array('message' => '商品規格が選択されていません。');
344
                        return $this->render($app, $Product, $tmpProductClass, true, $form, $error);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
345
                    }
346
347
                    // 選択された商品規格を登録
348
                    $this->insertProductClass($app, $Product, $addProductClasses);
0 ignored issues
show
Documentation introduced by
$addProductClasses 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...
349
350
                    // デフォルトの商品規格を更新
351
                    $defaultProductClass = $app['eccube.repository.product_class']
352
                        ->findOneBy(array('Product' => $Product, 'ClassCategory1' => null, 'ClassCategory2' => null));
353
354
                    $defaultProductClass->setDelFlg(Constant::ENABLED);
355
356
                    $app['orm.em']->flush();
357
358
                    log_info('商品規格新規登録完了', array($id));
359
360
                    $event = new EventArgs(
361
                        array(
362
                            'form' => $form,
363
                            'Product' => $Product,
364
                            'defaultProductClass' => $defaultProductClass,
365
                        ),
366
                        $request
367
                    );
368
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_COMPLETE, $event);
369
370
                    $app->addSuccess('admin.product.product_class.save.complete', 'admin');
371
372
                    break;
373
                case 'update':
374
                    // 更新
375
                    log_info('商品規格更新開始', array($id));
376
377 View Code Duplication
                    if (count($ProductClasses) == 0) {
378
                        // 商品規格が0件であれば最初の画面に戻す
379
                        log_info('商品規格が存在しません', array($id));
380
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
381
                    }
382
383
                    $checkProductClasses = array();
384
                    $removeProductClasses = array();
385
386
                    $tempProductClass = null;
387 View Code Duplication
                    foreach ($form->get('product_classes') as $formData) {
388
                        // 追加対象の行をvalidate
389 1
                        $ProductClass = $formData->getData();
390
391
                        if ($ProductClass->getAdd()) {
392
                            if ($formData->isValid()) {
393
                                $checkProductClasses[] = $ProductClass;
394
                            } else {
395
                                return $this->render($app, $Product, $ProductClass, false, $form);
396
                            }
397
                        } else {
398
                            // 削除対象の行
399
                            $removeProductClasses[] = $ProductClass;
400
                        }
401
                        $tempProductClass = $ProductClass;
402
                    }
403
404 View Code Duplication
                    if (count($checkProductClasses) == 0) {
405
                        // 対象がなければエラー
406
                        log_info('商品規格が存在しません', array($id));
407
                        $error = array('message' => '商品規格が選択されていません。');
408
                        return $this->render($app, $Product, $tempProductClass, false, $form, $error);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
409
                    }
410
411
412
                    // 登録対象と更新対象の行か判断する
413
                    $addProductClasses = array();
414
                    $updateProductClasses = array();
415
                    foreach ($checkProductClasses as $cp) {
416
                        $flag = false;
417
418
                        // 既に登録済みの商品規格か確認
419
                        foreach ($ProductClasses as $productClass) {
420 1
                            if ($productClass->getProduct()->getId() == $id &&
421
                                $productClass->getClassCategory1() == $cp->getClassCategory1() &&
422
                                $productClass->getClassCategory2() == $cp->getClassCategory2()) {
423
                                $updateProductClasses[] = $cp;
424
425
                                // 商品情報
426 1
                                $cp->setProduct($Product);
427
                                // 商品在庫
428
                                $productStock = $productClass->getProductStock();
429
                                if (!$cp->getStockUnlimited()) {
430
                                    $productStock->setStock($cp->getStock());
431
                                } else {
432
                                    $productStock->setStock(null);
433
                                }
434
                                $this->setDefualtProductClass($app, $productClass, $cp);
435
                                $flag = true;
436
                                break;
437
                            }
438
                        }
439
                        if (!$flag) {
440
                            $addProductClasses[] = $cp;
441
                        }
442
                    }
443
444
                    foreach ($removeProductClasses as $rc) {
445
                        // 登録されている商品規格に削除フラグをセット
446
                        foreach ($ProductClasses as $productClass) {
447
                            if ($productClass->getProduct()->getId() == $id &&
448
                                $productClass->getClassCategory1() == $rc->getClassCategory1() &&
449
                                $productClass->getClassCategory2() == $rc->getClassCategory2()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
450
451
                                $productClass->setDelFlg(Constant::ENABLED);
452
                                break;
453
                            }
454
                        }
455
                    }
456
457
                    // 選択された商品規格を登録
458
                    $this->insertProductClass($app, $Product, $addProductClasses);
0 ignored issues
show
Documentation introduced by
$addProductClasses 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...
459
460
                    $app['orm.em']->flush();
461
462
                    log_info('商品規格更新完了', array($id));
463
464
                    $event = new EventArgs(
465
                        array(
466
                            'form' => $form,
467
                            'Product' => $Product,
468
                            'updateProductClasses' => $updateProductClasses,
469
                            'addProductClasses' => $addProductClasses,
470
                        ),
471
                        $request
472
                    );
473
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_UPDATE, $event);
474
475
                    $app->addSuccess('admin.product.product_class.update.complete', 'admin');
476
477
                    break;
478
479
                case 'delete':
480
                    // 削除
481
                    log_info('商品規格削除開始', array($id));
482
483 View Code Duplication
                    if (count($ProductClasses) == 0) {
484
                        // 既に商品が削除されていれば元の画面に戻す
485
                        log_info('商品規格が存在しません', array($id));
486
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
487
                    }
488
489
                    foreach ($ProductClasses as $ProductClass) {
490
                        // 登録されている商品規格に削除フラグをセット
491
                        $ProductClass->setDelFlg(Constant::ENABLED);
492
                    }
493
494
                    /* @var $softDeleteFilter \Eccube\Doctrine\Filter\SoftDeleteFilter */
495
                    $softDeleteFilter = $app['orm.em']->getFilters()->getFilter('soft_delete');
496
                    $softDeleteFilter->setExcludes(array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
497
                        'Eccube\Entity\ProductClass'
498
                    ));
499
500
                    // デフォルトの商品規格を更新
501
                    $defaultProductClass = $app['eccube.repository.product_class']
502
                        ->findOneBy(array('Product' => $Product, 'ClassCategory1' => null, 'ClassCategory2' => null, 'del_flg' => Constant::ENABLED));
503
504
                    $defaultProductClass->setDelFlg(Constant::DISABLED);
505
506
                    $app['orm.em']->flush();
507
                    log_info('商品規格削除完了', array($id));
508
509
                    $event = new EventArgs(
510
                        array(
511
                            'form' => $form,
512
                            'Product' => $Product,
513
                            'defaultProductClass' => $defaultProductClass,
514
                        ),
515
                        $request
516
                    );
517
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_DELETE, $event);
518
519
                    $app->addSuccess('admin.product.product_class.delete.complete', 'admin');
520
521
                    break;
522
                default:
523
                    break;
524
            }
525
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
526
        }
527
528
        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
529
    }
530
531
    /**
532
     * 登録、更新時のエラー画面表示
533
     *
534
     */
535
    protected function render($app, $Product, $ProductClass, $not_product_class, $classForm, $error = null)
536
    {
537
538
        $ClassName1 = null;
539
        $ClassName2 = null;
540
        // 規格を取得
541
        if (isset($ProductClass)) {
542
            $ClassCategory1 = $ProductClass->getClassCategory1();
543
            if ($ClassCategory1) {
544
                $ClassName1 = $ClassCategory1->getClassName();
545
            }
546
            $ClassCategory2 = $ProductClass->getClassCategory2();
547
            if ($ClassCategory2) {
548
                $ClassName2 = $ClassCategory2->getClassName();
549
            }
550
        }
551
552
        $form = $app->form()
553
            ->add('class_name1', 'entity', array(
554 1
                'class' => 'Eccube\Entity\ClassName',
555
                'property' => 'name',
556
                'empty_value' => '規格1を選択',
557
                'data' => $ClassName1,
558
            ))
559
            ->add('class_name2', 'entity', array(
560
                'class' => 'Eccube\Entity\ClassName',
561
                'property' => 'name',
562 1
                'empty_value' => '規格2を選択',
563
                'data' => $ClassName2,
564
            ))
565
            ->getForm();
566
567
        log_info('商品規格登録エラー');
568
569
570
        return $app->render('Product/product_class.twig', array(
571
            'form' => $form->createView(),
572
            'classForm' => $classForm->createView(),
573
            'Product' => $Product,
574
            'class_name1' => $ClassName1,
575
            'class_name2' => $ClassName2,
576
            'not_product_class' => $not_product_class,
577
            'error' => $error,
578
            'has_class_category_flg' => true,
579
        ));
580
    }
581
582
583
    /**
584
     * 規格1と規格2を組み合わせた商品規格を作成
585
     */
586
    private function createProductClasses($app, Product $Product, ClassName $ClassName1 = null, ClassName $ClassName2 = null)
587
    {
588
589
        $ClassCategories1 = array();
590
        if ($ClassName1) {
591
            $ClassCategories1 = $app['eccube.repository.class_category']->findBy(array('ClassName' => $ClassName1), array('rank' => 'DESC'));
592
        }
593
594
        $ClassCategories2 = array();
595
        if ($ClassName2) {
596
            $ClassCategories2 = $app['eccube.repository.class_category']->findBy(array('ClassName' => $ClassName2), array('rank' => 'DESC'));
597
        }
598
599
        $ProductClasses = array();
600
        foreach ($ClassCategories1 as $ClassCategory1) {
601
            if ($ClassCategories2) {
602
                foreach ($ClassCategories2 as $ClassCategory2) {
603
                    $ProductClass = $this->newProductClass($app);
604
                    $ProductClass->setProduct($Product);
605
                    $ProductClass->setClassCategory1($ClassCategory1);
606
                    $ProductClass->setClassCategory2($ClassCategory2);
607
                    $ProductClass->setTaxRate(null);
608
                    $ProductClass->setDelFlg(Constant::DISABLED);
609
                    $ProductClasses[] = $ProductClass;
610
                }
611
            } else {
612
                $ProductClass = $this->newProductClass($app);
613
                $ProductClass->setProduct($Product);
614
                $ProductClass->setClassCategory1($ClassCategory1);
615
                $ProductClass->setTaxRate(null);
616
                $ProductClass->setDelFlg(Constant::DISABLED);
617
                $ProductClasses[] = $ProductClass;
618
            }
619
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
620
        }
621
        return $ProductClasses;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
622
    }
623
624
    /**
625
     * 新しい商品規格を作成
626
     */
627
    private function newProductClass(Application $app)
628
    {
629
        $ProductType = $app['eccube.repository.master.product_type']->find($app['config']['product_type_normal']);
630
631
        $ProductClass = new ProductClass();
632
        $ProductClass->setProductType($ProductType);
633
        return $ProductClass;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
634
    }
635
636
    /**
637
     * 商品規格のコピーを取得.
638
     *
639
     * @see http://symfony.com/doc/current/cookbook/form/form_collections.html
640
     * @param Product $Product
641
     * @return \Eccube\Entity\ProductClass[]
642
     */
643
    private function getProductClassesOriginal(Product $Product)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
644
    {
645
        $ProductClasses = $Product->getProductClasses();
646
        return $ProductClasses->filter(function($ProductClass) {
0 ignored issues
show
Unused Code introduced by
The parameter $ProductClass is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
introduced by
Missing blank line before return statement
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
647
            return true;
648
        });
649
    }
650
651
    /**
652
     * 規格なし商品を除いて商品規格を取得.
653
     *
654
     * @param Product $Product
655
     * @return \Eccube\Entity\ProductClass[]
656
     */
657
    private function getProductClassesExcludeNonClass(Product $Product)
658
    {
659
        $ProductClasses = $Product->getProductClasses();
660
        return $ProductClasses->filter(function($ProductClass) {
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
661
            $ClassCategory1 = $ProductClass->getClassCategory1();
662
            $ClassCategory2 = $ProductClass->getClassCategory2();
663
            return ($ClassCategory1 || $ClassCategory2);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
664
        });
665
    }
666
667
    /**
668
     * デフォルトとなる商品規格を設定
669
     *
670
     * @param $productClassDest コピー先となる商品規格
671
     * @param $productClassOrig コピー元となる商品規格
672
     */
673
    private function setDefualtProductClass($app, $productClassDest, $productClassOrig) {
674
        $productClassDest->setDeliveryDate($productClassOrig->getDeliveryDate());
675
        $productClassDest->setProduct($productClassOrig->getProduct());
676
        $productClassDest->setProductType($productClassOrig->getProductType());
677
        $productClassDest->setCode($productClassOrig->getCode());
678
        $productClassDest->setStock($productClassOrig->getStock());
679
        $productClassDest->setStockUnlimited($productClassOrig->getStockUnlimited());
680
        $productClassDest->setSaleLimit($productClassOrig->getSaleLimit());
681
        $productClassDest->setPrice01($productClassOrig->getPrice01());
682
        $productClassDest->setPrice02($productClassOrig->getPrice02());
683
        $productClassDest->setDeliveryFee($productClassOrig->getDeliveryFee());
684
685
        // 個別消費税
686
        $BaseInfo = $app['eccube.repository.base_info']->get();
687
        if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
688
            if ($productClassOrig->getTaxRate() !== false && $productClassOrig->getTaxRate() !== null) {
689
                $productClassDest->setTaxRate($productClassOrig->getTaxRate());
690 View Code Duplication
                if ($productClassDest->getTaxRule()) {
691
                    $productClassDest->getTaxRule()->setTaxRate($productClassOrig->getTaxRate());
692
                    $productClassDest->getTaxRule()->setDelFlg(Constant::DISABLED);
693
                } else {
694
                    $taxrule = $app['eccube.repository.tax_rule']->newTaxRule();
695
                    $taxrule->setTaxRate($productClassOrig->getTaxRate());
696
                    $taxrule->setApplyDate(new \DateTime());
697
                    $taxrule->setProduct($productClassDest->getProduct());
698
                    $taxrule->setProductClass($productClassDest);
699
                    $productClassDest->setTaxRule($taxrule);
700
                }
701
            } else {
702
                if ($productClassDest->getTaxRule()) {
703
                    $productClassDest->getTaxRule()->setDelFlg(Constant::ENABLED);
704
                }
705
            }
706
        }
707
    }
708
709
710
    /**
711
     * 商品規格を登録
712
     *
713
     * @param Application     $app
714
     * @param Product         $Product
715
     * @param ArrayCollection $ProductClasses 登録される商品規格
716
     */
717
    private function insertProductClass($app, $Product, $ProductClasses) {
718
719
        $BaseInfo = $app['eccube.repository.base_info']->get();
720
721
        // 選択された商品を登録
722
        foreach ($ProductClasses as $ProductClass) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
723
724
            $ProductClass->setDelFlg(Constant::DISABLED);
725
            $ProductClass->setProduct($Product);
726
            $app['orm.em']->persist($ProductClass);
727
728
            // 在庫情報を作成
729
            $ProductStock = new ProductStock();
730
            $ProductClass->setProductStock($ProductStock);
731
            $ProductStock->setProductClass($ProductClass);
732
            if (!$ProductClass->getStockUnlimited()) {
733
                $ProductStock->setStock($ProductClass->getStock());
734
            } else {
735
                // 在庫無制限時はnullを設定
736
                $ProductStock->setStock(null);
737
            }
738
            $app['orm.em']->persist($ProductStock);
739
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
740
        }
741
742
        // 商品税率が設定されている場合、商品税率をセット
743
        if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
744
            // 初期設定の税設定.
745
            $TaxRule = $app['eccube.repository.tax_rule']->find(TaxRule::DEFAULT_TAX_RULE_ID);
746
            // 初期税率設定の計算方法を設定する
747
            $CalcRule = $TaxRule->getCalcRule();
748
            foreach ($ProductClasses as $ProductClass) {
749
                if ($ProductClass && is_numeric($taxRate = $ProductClass->getTaxRate())) {
750
                    $TaxRule = new TaxRule();
751
                    $TaxRule->setProduct($Product);
752
                    $TaxRule->setProductClass($ProductClass);
753
                    $TaxRule->setCalcRule($CalcRule);
754
                    $TaxRule->setTaxRate($taxRate);
755
                    $TaxRule->setTaxAdjust(0);
756
                    $TaxRule->setApplyDate(new \DateTime());
757
                    $TaxRule->setDelFlg(Constant::DISABLED);
758
                    $app['orm.em']->persist($TaxRule);
759
                }
760
            }
761
        }
762
763
    }
764
765
    /**
766
     * 規格の分類判定
767
     *
768
     * @param $class_name
769
     * @return boolean
770
     */
771
    private function isValiedCategory($class_name)
772
    {
773
        if (empty($class_name)) {
774
            return true;
775
        }
776
        if (count($class_name->getClassCategories()) < 1) {
777
            return false;
778
        }
779
        return true;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
780
    }
781
}