Failed Conditions
Pull Request — experimental/sf (#3416)
by
unknown
329:25 queued 320:39
created

StockDiffProcessor::prepare()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.7629

Importance

Changes 0
Metric Value
cc 5
nc 5
nop 2
dl 0
loc 26
ccs 11
cts 16
cp 0.6875
crap 5.7629
rs 9.1928
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Service\PurchaseFlow\Processor;
15
16
use Eccube\Entity\ItemHolderInterface;
17
use Eccube\Entity\Master\OrderStatus;
18
use Eccube\Entity\ProductClass;
19
use Eccube\Entity\ProductStock;
20
use Eccube\Repository\ProductClassRepository;
21
use Eccube\Service\PurchaseFlow\ItemHolderValidator;
22
use Eccube\Service\PurchaseFlow\PurchaseContext;
23
use Eccube\Service\PurchaseFlow\PurchaseException;
24
use Eccube\Service\PurchaseFlow\PurchaseProcessor;
25
26
/**
27
 * 編集前/編集後の個数の差分にもとづいて在庫を更新します.
28
 */
29
class StockDiffProcessor extends ItemHolderValidator implements PurchaseProcessor
30
{
31
    /**
32
     * @var ProductClassRepository
33
     */
34
    protected $productClassRepository;
35
36
    /**
37
     * StockProcessor constructor.
38
     *
39
     * @param ProductClassRepository $productClassRepository
40
     */
41 712
    public function __construct(ProductClassRepository $productClassRepository)
42
    {
43 712
        $this->productClassRepository = $productClassRepository;
44
    }
45
46
    /**
47
     * @param ItemHolderInterface $itemHolder
48
     * @param PurchaseContext $context
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
49
     *
50
     * @throws \Eccube\Service\PurchaseFlow\InvalidItemException
51
     */
52 155
    public function validate(ItemHolderInterface $itemHolder, PurchaseContext $context)
53
    {
54 155
        if (is_null($context->getOriginHolder())) {
55
            return;
56
        }
57
58 155
        $From = $context->getOriginHolder();
59 155
        $To = $itemHolder;
60 155
        $diff = $this->getDiffOfQuantities($From, $To);
61
62 155
        foreach ($diff as $id => $quantity) {
63
            /** @var ProductClass $ProductClass */
64 155
            $ProductClass = $this->productClassRepository->find($id);
65 155
            if ($ProductClass->isStockUnlimited()) {
66
                continue;
67
            }
68 155
            $stock = $ProductClass->getStock();
69
            // 更新後ステータスがキャンセルの場合は, 差分ではなく更新後の個数で確認.
70 155
            if ($To->getOrderStatus() && $To->getOrderStatus()->getId() == OrderStatus::CANCEL) {
71
                $Items = $To->getProductOrderItems();
72
                $Items = array_filter($Items, function ($Item) use ($id) {
73
                    return $Item->getProductClass()->getId() == $id;
74
                });
75
                $toQuantity = array_reduce($Items, function ($quantity, $Item) {
76
                    return $quantity += $Item->getQuantity();
77
                }, 0);
78
                if ($stock - $toQuantity < 0) {
79
                    $this->throwInvalidItemException(sprintf('%s: 在庫がたりません', $ProductClass->formatedProductName()));
80
                }
81
            } else {
82 155
                if ($stock - $quantity < 0) {
83 155
                    $this->throwInvalidItemException(sprintf('%s: 在庫がたりません', $ProductClass->formatedProductName()));
84
                }
85
            }
86
        }
87
    }
88
89 155
    protected function getDiffOfQuantities(ItemHolderInterface $From, ItemHolderInterface $To)
90
    {
91 155
        $FromItems = $this->getQuantityByProductClass($From);
92 155
        $ToItems = $this->getQuantityByProductClass($To);
93 155
        $ids = array_unique(array_merge(array_keys($FromItems), array_keys($ToItems)));
94
95 155
        $diff = [];
96 155
        foreach ($ids as $id) {
97
            // 更新された明細
98 155
            if (isset($FromItems[$id]) && isset($ToItems[$id])) {
99
                // 2 -> 3 = +1
100
                // 2 -> 1 = -1
101 153
                $diff[$id] = $ToItems[$id] - $FromItems[$id];
102
            } // 削除された明細
103 5 View Code Duplication
            elseif (isset($FromItems[$id]) && empty($ToItems[$id])) {
104
                // 2 -> 0 = -2
105 3
                $diff[$id] = $FromItems[$id] * -1;
106
            } // 追加された明細
107 5 View Code Duplication
            elseif (!isset($FromItems[$id]) && isset($ToItems[$id])) {
108
                // 0 -> 2 = +2
109 155
                $diff[$id] = $ToItems[$id];
110
            }
111
        }
112
113 155
        return $diff;
114
    }
115
116 155
    protected function getQuantityByProductClass(ItemHolderInterface $ItemHolder)
117
    {
118 155
        $ItemsByProductClass = [];
119 155
        foreach ($ItemHolder->getItems() as $Item) {
120 155
            if ($Item->isProduct()) {
121 155
                $id = $Item->getProductClass()->getId();
122 155
                if (isset($ItemsByProductClass[$id])) {
123
                    $ItemsByProductClass[$id] += $Item->getQuantity();
124
                } else {
125 155
                    $ItemsByProductClass[$id] = $Item->getQuantity();
126
                }
127
            }
128
        }
129
130 155
        return $ItemsByProductClass;
131
    }
132
133
    /**
134
     * 受注の仮確定処理を行います。
135
     *
136
     * @param ItemHolderInterface $target
137
     * @param PurchaseContext $context
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
138
     *
139
     * @throws PurchaseException
140
     */
141 5
    public function prepare(ItemHolderInterface $target, PurchaseContext $context)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
142
    {
143 5
        if (is_null($context->getOriginHolder())) {
144
            return;
145
        }
146
147 5
        $diff = $this->getDiffOfQuantities($context->getOriginHolder(), $target);
148
149 5
        foreach ($diff as $id => $quantity) {
150
            /** @var ProductClass $ProductClass */
151 5
            $ProductClass = $this->productClassRepository->find($id);
152 5
            if ($ProductClass->isStockUnlimited()) {
153
                continue;
154
            }
155
156 5
            $stock = $ProductClass->getStock() - $quantity;
157 5
            $ProductStock = $ProductClass->getProductStock();
158 5
            if (!$ProductStock) {
159
                $ProductStock = new ProductStock();
160
                $ProductStock->setProductClass($ProductClass);
161
                $ProductClass->setProductStock($ProductStock);
162
            }
163 5
            $ProductClass->setStock($stock);
164 5
            $ProductStock->setStock($stock);
165
        }
166
    }
167
168
    /**
169
     * 受注の確定処理を行います。
170
     *
171
     * @param ItemHolderInterface $target
172
     * @param PurchaseContext $context
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
173
     *
174
     * @throws PurchaseException
175
     */
176 5
    public function commit(ItemHolderInterface $target, PurchaseContext $context)
177
    {
178
        // 何もしない.
179 5
        return;
0 ignored issues
show
Coding Style introduced by
Empty return statement not required here
Loading history...
180
    }
181
182
    /**
183
     * 仮確定した受注データの取り消し処理を行います。
184
     *
185
     * @param ItemHolderInterface $itemHolder
186
     * @param PurchaseContext $context
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
187
     */
188
    public function rollback(ItemHolderInterface $itemHolder, PurchaseContext $context)
189
    {
190
        // 何もしない.
191
        return;
0 ignored issues
show
Coding Style introduced by
Empty return statement not required here
Loading history...
192
    }
193
}
194