ProductClassController::edit()   F
last analyzed

Complexity

Conditions 30
Paths 13

Size

Total Lines 258

Duplication

Lines 57
Ratio 22.09 %

Importance

Changes 0
Metric Value
cc 30
nc 13
nop 3
dl 57
loc 258
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
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.ec-cube.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
45
{
46
    /**
47
     * 商品規格が登録されていなければ新規登録、登録されていれば更新画面を表示する
48
     */
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()) {
97
98
                $form->handleRequest($request);
99
100
                if ($form->isValid()) {
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
156
                    }
157
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) {
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...
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
230
            $builder = $app['form.factory']->createBuilder();
231
232
            $builder
233
                ->add('product_classes', 'collection', array(
234
                    'type' => 'admin_product_class',
235
                    'allow_add' => true,
236
                    'allow_delete' => true,
237
                    'data' => $sortProductClasses,
238
                ));
239
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
                'classForm' => $productClassForm,
254
                '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
            ),
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) {
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...
317
                        // 既に登録されていれば最初の画面に戻す
318
                        log_info('商品規格登録済', array($id));
319
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
320
                    }
321
322
                    $addProductClasses = array();
323
324
                    $tmpProductClass = null;
325 View Code Duplication
                    foreach ($form->get('product_classes') as $formData) {
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...
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) {
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...
341
                        // 対象がなければエラー
342
                        log_info('商品規格が未選択', array($id));
343
                        $error = array('message' => '商品規格が選択されていません。');
344
                        return $this->render($app, $Product, $tmpProductClass, true, $form, $error);
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) {
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...
378
                        // 商品規格が0件であれば最初の画面に戻す
379
                        log_info('商品規格が存在しません', array($id));
380
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
381
                    }
382
383
                    $checkProductClasses = array();
384
                    $removeProductClasses = array();
385
386
                    $tempProductClass = null;
387 View Code Duplication
                    foreach ($form->get('product_classes') as $formData) {
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...
388
                        // 追加対象の行をvalidate
389
                        $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) {
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...
405
                        // 対象がなければエラー
406
                        log_info('商品規格が存在しません', array($id));
407
                        $error = array('message' => '商品規格が選択されていません。');
408
                        return $this->render($app, $Product, $tempProductClass, false, $form, $error);
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
                            if ($productClass->getProduct()->getId() == $id &&
421
                                $productClass->getClassCategory1() == $cp->getClassCategory1() &&
422
                                $productClass->getClassCategory2() == $cp->getClassCategory2()) {
423
                                $updateProductClasses[] = $cp;
424
425
                                // 商品情報
426
                                $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()) {
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) {
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...
484
                        // 既に商品が削除されていれば元の画面に戻す
485
                        log_info('商品規格が存在しません', array($id));
486
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
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(
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
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
                '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
                '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
620
        }
621
        return $ProductClasses;
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;
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...
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) {
661
            $ClassCategory1 = $ProductClass->getClassCategory1();
662
            $ClassCategory2 = $ProductClass->getClassCategory2();
663
            return ($ClassCategory1 || $ClassCategory2);
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()) {
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...
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) {
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
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;
780
    }
781
}