Completed
Push — 4.0 ( 268f2c...88f012 )
by Hideki
05:48 queued 10s
created

src/Eccube/Repository/TaxRuleRepository.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Repository;
15
16
use Doctrine\ORM\NoResultException;
17
use Eccube\Common\EccubeConfig;
18
use Eccube\Entity\BaseInfo;
19
use Eccube\Entity\Customer;
20
use Eccube\Entity\Master\RoundingType;
21
use Eccube\Entity\TaxRule;
22
use Symfony\Bridge\Doctrine\RegistryInterface;
23
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
24
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
25
26
/**
27
 * TaxRuleRepository
28
 *
29
 * This class was generated by the Doctrine ORM. Add your own custom
30
 * repository methods below.
31
 */
32
class TaxRuleRepository extends AbstractRepository
33
{
34
    private $rules = [];
35
36
    /**
37
     * @var BaseInfo
38
     */
39
    protected $baseInfo;
40
41
    /**
42
     * @var AuthorizationCheckerInterface
43
     */
44
    protected $authorizationChecker;
45
46
    /**
47
     * @var TokenStorageInterface
48
     */
49
    protected $tokenStorage;
50
51
    /**
52
     * TaxRuleRepository constructor.
53
     *
54
     * @param RegistryInterface $registry
55
     * @param TokenStorageInterface $tokenStorage
56
     * @param AuthorizationCheckerInterface $authorizationChecker
57
     * @param BaseInfoRepository $baseInfoRepository
58
     * @param EccubeConfig $eccubeConfig
59 800
     */
60
    public function __construct(
61
        RegistryInterface $registry,
62
        TokenStorageInterface $tokenStorage,
63
        AuthorizationCheckerInterface $authorizationChecker,
64
        BaseInfoRepository $baseInfoRepository,
65
        EccubeConfig $eccubeConfig
66 800
    ) {
67 800
        parent::__construct($registry, TaxRule::class);
68 800
        $this->tokenStorage = $tokenStorage;
69 800
        $this->authorizationChecker = $authorizationChecker;
70 800
        $this->baseInfo = $baseInfoRepository->get();
71
        $this->eccubeConfig = $eccubeConfig;
72
    }
73 7
74
    /**
75 7
     * 新たな TaxRule インスタンスを生成して返す.
76 7
     *
77 7
     * 現在適用されている丸め規則を設定する.
78 7
     * 現在適用されている丸め規則が取得できない場合は四捨五入を設定する.
79 7
     *
80 7
     * @return TaxRule
81
     */
82 7
    public function newTaxRule()
83
    {
84
        /** @var RoundingType $RoundingType */
85
        $RoundingType = $this->getEntityManager()->getRepository(RoundingType::class)->find(RoundingType::ROUND);
86
        try {
87
            $CurrentRule = $this->getByRule();
88
            $RoundingType = $CurrentRule->getRoundingType();
89
        } catch (NoResultException $e) {
90
            // quiet
91
        }
92
        $TaxRule = new TaxRule();
93
        $TaxRule->setRoundingType($RoundingType);
94
        $TaxRule->setTaxAdjust('0');
95
96
        return $TaxRule;
97 465
    }
98
99
    /**
100 465
     * 現在有効な税率設定情報を返す
101
     *
102 52
     * @param  int|null|\Eccube\Entity\Product        $Product      商品
103
     * @param  int|null|\Eccube\Entity\ProductClass   $ProductClass 商品規格
104 52
     * @param  int|null|\Eccube\Entity\Master\Pref    $Pref         都道府県
105 52
     * @param  int|null|\Eccube\Entity\Master\Country $Country      国
106 52
     *
107
     * @return \Eccube\Entity\TaxRule                 税設定情報
108
     *
109
     * @throws NoResultException
110
     */
111 465
    public function getByRule($Product = null, $ProductClass = null, $Pref = null, $Country = null)
112 457
    {
113 457
        // Pref Country 設定
114
        if (!$Pref && !$Country && $this->tokenStorage->getToken() && $this->authorizationChecker->isGranted('ROLE_USER')) {
115
            /* @var $Customer \Eccube\Entity\Customer */
116
            $Customer = $this->tokenStorage->getToken()->getUser();
117 465
            // FIXME なぜか管理画面でも実行されている.
118 24
            if ($Customer instanceof Customer) {
119 457
                $Pref = $Customer->getPref();
120
                $Country = $Customer->getCountry();
121
            }
122 457
        }
123
124 465
        // 商品単位税率設定がOFFの場合
125 23
        if (!$this->baseInfo->isOptionProductTaxRule()) {
126 457
            $Product = null;
127
            $ProductClass = null;
128
        }
129 457
130
        // Cache Key 設定
131 465
        if ($Product instanceof \Eccube\Entity\Product) {
132 53
            $productId = $Product->getId();
133 453
        } elseif ($Product) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $Product of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
134
            $productId = $Product;
135
        } else {
136 453
            $productId = '0';
137
        }
138 465
        if ($ProductClass instanceof \Eccube\Entity\ProductClass) {
139 2
            $productClassId = $ProductClass->getId();
140 465
        } elseif ($ProductClass) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ProductClass of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
141
            $productClassId = $ProductClass;
142
        } else {
143 465
            $productClassId = '0';
144
        }
145 465
        if ($Pref instanceof \Eccube\Entity\Master\Pref) {
146
            $prefId = $Pref->getId();
147
        } elseif ($Pref) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $Pref of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
148 465
            $prefId = $Pref;
149 463
        } else {
150
            $prefId = '0';
151
        }
152 465
        if ($Country instanceof \Eccube\Entity\Master\Country) {
153 465
            $countryId = $Country->getId();
154 465
        } elseif ($Country) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $Country of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
155 465
            $countryId = $Country;
156
        } else {
157
            $countryId = '0';
158 465
        }
159 53
        $cacheKey = $productId.':'.$productClassId.':'.$prefId.':'.$countryId;
160 53
161
        // すでに取得している場合はキャッシュから
162 453
        if (isset($this->rules[$cacheKey])) {
163
            return $this->rules[$cacheKey];
164
        }
165
166 465
        $parameters = [];
167 2
        $qb = $this->createQueryBuilder('t')
168 2
            ->where('t.apply_date < :apply_date');
169
        $parameters[':apply_date'] = new \DateTime();
170 465
171
        // Pref
172
        if ($Pref) {
173
            $qb->andWhere('t.Pref IS NULL OR t.Pref = :Pref');
174
            $parameters['Pref'] = $Pref;
175
        } else {
176
            $qb->andWhere('t.Pref IS NULL');
177
        }
178
179
        // Country
180 465
        if ($Country) {
181 24
            $qb->andWhere('t.Country IS NULL OR t.Country = :Country');
182 24
            $parameters['Country'] = $Country;
183
        } else {
184 457
            $qb->andWhere('t.Country IS NULL');
185
        }
186
187
        /*
188 465
         * Product, ProductClass が persist される前に TaxRuleEventSubscriber によってアクセスされる
189 23
         * 場合があるため、ID の存在もチェックする.
190 23
         * https://github.com/EC-CUBE/ec-cube/issues/677
191
         */
192 464
193
        // Product
194
        if ($Product && $productId > 0) {
195
            $qb->andWhere('t.Product IS NULL OR t.Product = :Product');
196 465
            $parameters['Product'] = $Product;
197 465
        } else {
198 465
            $qb->andWhere('t.Product IS NULL');
199 465
        }
200
201
        // ProductClass
202
        if ($ProductClass && '0' !== $productClassId) {
203 465
            $qb->andWhere('t.ProductClass IS NULL OR t.ProductClass = :ProductClass');
204 465
            $parameters['ProductClass'] = $ProductClass;
205 465
        } else {
206
            $qb->andWhere('t.ProductClass IS NULL');
207
        }
208 465
209 465
        $TaxRules = $qb
210 465
            ->setParameters($parameters)
211 465
            ->orderBy('t.apply_date', 'DESC') // 実際は usort() でソートする
212 465
            ->getQuery()
213
            ->getResult();
214 465
215
        // 地域設定を優先するが、システムパラメーターなどに設定を持っていくか
216
        // 後に書いてあるほど優先される
217 465
        $priorityKeys = [];
218
        foreach ($this->eccubeConfig['eccube_tax_rule_priority'] as $priorityKey) {
219
            $priorityKeys[] = str_replace('_', '', preg_replace('/_id\z/', '', $priorityKey));
220
        }
221 465
222 7
        foreach ($TaxRules as $TaxRule) {
223 465
            $sortNo = 0;
224
            foreach ($priorityKeys as $index => $key) {
225 465
                $arrayProperties = array_change_key_case($TaxRule->toArray());
226 465
                if ($arrayProperties[$key]) {
227
                    // 配列の数値添字を重みとして利用する
228 465
                    $sortNo += 1 << ($index + 1);
229
                }
230
            }
231
            $TaxRule->setSortNo($sortNo);
232
        }
233
234
        // 適用日降順, sortNo 降順にソートする
235
        usort($TaxRules, function ($a, $b) {
236
            return $a->compareTo($b);
237
        });
238
239 3
        if (!empty($TaxRules)) {
240
            $this->rules[$cacheKey] = $TaxRules[0];
241 3
242 3
            return $TaxRules[0];
243 3
        } else {
244
            throw new NoResultException();
245 3
        }
246 3
    }
247
248 3
    /**
249
     * getList
250
     *
251
     * @return array|null
252
     */
253
    public function getList()
254
    {
255
        $qb = $this->createQueryBuilder('t')
256
            ->orderBy('t.apply_date', 'DESC')
257
            ->where('t.Product IS NULL AND t.ProductClass IS NULL');
258
        $TaxRules = $qb
259
            ->getQuery()
260 1
            ->getResult();
261
262
        return $TaxRules;
263 1
    }
264
265
    /**
266 1
     * 税規約の削除.
267
     *
268
     * @param  int|\Eccube\Entity\TaxRule $TaxRule 税規約
269
     *
270
     * @throws NoResultException
271
     */
272
    public function delete($TaxRule)
273
    {
274
        if (!$TaxRule instanceof \Eccube\Entity\TaxRule) {
275
            $TaxRule = $this->find($TaxRule);
276
        }
277
        if (!$TaxRule) {
278
            throw new NoResultException();
279
        }
280
        $em = $this->getEntityManager();
281
        $em->remove($TaxRule);
282
        $em->flush();
283
    }
284
285
    /**
286
     * TaxRule のキャッシュをクリアする.
287
     *
288
     * getByRule() をコールすると、結果をキャッシュし、2回目以降はデータベースへアクセスしない.
289
     * このメソッドをコールすると、キャッシュをクリアし、再度データベースを参照して結果を取得する.
290
     */
291
    public function clearCache()
292
    {
293
        $this->rules = [];
294 5
    }
295
}
296