src/Eccube/Repository/TaxRuleRepository.php line 111

Open in your IDE?
  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.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Repository;
  13. use Doctrine\ORM\NoResultException;
  14. use Doctrine\Persistence\ManagerRegistry as RegistryInterface;
  15. use Eccube\Common\EccubeConfig;
  16. use Eccube\Entity\BaseInfo;
  17. use Eccube\Entity\Customer;
  18. use Eccube\Entity\Master\RoundingType;
  19. use Eccube\Entity\TaxRule;
  20. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  21. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  22. /**
  23.  * TaxRuleRepository
  24.  *
  25.  * This class was generated by the Doctrine ORM. Add your own custom
  26.  * repository methods below.
  27.  */
  28. class TaxRuleRepository extends AbstractRepository
  29. {
  30.     private $rules = [];
  31.     /**
  32.      * @var BaseInfo
  33.      */
  34.     protected $baseInfo;
  35.     /**
  36.      * @var AuthorizationCheckerInterface
  37.      */
  38.     protected $authorizationChecker;
  39.     /**
  40.      * @var TokenStorageInterface
  41.      */
  42.     protected $tokenStorage;
  43.     /**
  44.      * TaxRuleRepository constructor.
  45.      *
  46.      * @param RegistryInterface $registry
  47.      * @param TokenStorageInterface $tokenStorage
  48.      * @param AuthorizationCheckerInterface $authorizationChecker
  49.      * @param BaseInfoRepository $baseInfoRepository
  50.      * @param EccubeConfig $eccubeConfig
  51.      */
  52.     public function __construct(
  53.         RegistryInterface $registry,
  54.         TokenStorageInterface $tokenStorage,
  55.         AuthorizationCheckerInterface $authorizationChecker,
  56.         BaseInfoRepository $baseInfoRepository,
  57.         EccubeConfig $eccubeConfig
  58.     ) {
  59.         parent::__construct($registryTaxRule::class);
  60.         $this->tokenStorage $tokenStorage;
  61.         $this->authorizationChecker $authorizationChecker;
  62.         $this->baseInfo $baseInfoRepository->get();
  63.         $this->eccubeConfig $eccubeConfig;
  64.     }
  65.     /**
  66.      * 新たな TaxRule インスタンスを生成して返す.
  67.      *
  68.      * 現在適用されている丸め規則を設定する.
  69.      * 現在適用されている丸め規則が取得できない場合は四捨五入を設定する.
  70.      *
  71.      * @return TaxRule
  72.      */
  73.     public function newTaxRule()
  74.     {
  75.         /** @var RoundingType $RoundingType */
  76.         $RoundingType $this->getEntityManager()->getRepository(RoundingType::class)->find(RoundingType::ROUND);
  77.         try {
  78.             $CurrentRule $this->getByRule();
  79.             $RoundingType $CurrentRule->getRoundingType();
  80.         } catch (NoResultException $e) {
  81.             // quiet
  82.         }
  83.         $TaxRule = new TaxRule();
  84.         $TaxRule->setRoundingType($RoundingType);
  85.         $TaxRule->setTaxAdjust('0');
  86.         return $TaxRule;
  87.     }
  88.     /**
  89.      * 現在有効な税率設定情報を返す
  90.      *
  91.      * @param  int|\Eccube\Entity\Product|null        $Product      商品
  92.      * @param  int|\Eccube\Entity\ProductClass|null   $ProductClass 商品規格
  93.      * @param  int|\Eccube\Entity\Master\Pref|null    $Pref         都道府県
  94.      * @param  int|\Eccube\Entity\Master\Country|null $Country      国
  95.      *
  96.      * @return \Eccube\Entity\TaxRule                 税設定情報
  97.      *
  98.      * @throws NoResultException
  99.      */
  100.     public function getByRule($Product null$ProductClass null$Pref null$Country null)
  101.     {
  102.         // Pref Country 設定
  103.         if (!$Pref && !$Country && $this->tokenStorage->getToken() && $this->authorizationChecker->isGranted('ROLE_USER')) {
  104.             /* @var $Customer \Eccube\Entity\Customer */
  105.             $Customer $this->tokenStorage->getToken()->getUser();
  106.             // FIXME なぜか管理画面でも実行されている.
  107.             if ($Customer instanceof Customer) {
  108.                 $Pref $Customer->getPref();
  109.                 $Country $Customer->getCountry();
  110.             }
  111.         }
  112.         // 商品単位税率設定がOFFの場合
  113.         if (!$this->baseInfo->isOptionProductTaxRule()) {
  114.             $Product null;
  115.             $ProductClass null;
  116.         }
  117.         // Cache Key 設定
  118.         if ($Product instanceof \Eccube\Entity\Product) {
  119.             $productId $Product->getId();
  120.         } elseif ($Product) {
  121.             $productId $Product;
  122.         } else {
  123.             $productId '0';
  124.         }
  125.         if ($ProductClass instanceof \Eccube\Entity\ProductClass) {
  126.             $productClassId $ProductClass->getId();
  127.         } elseif ($ProductClass) {
  128.             $productClassId $ProductClass;
  129.         } else {
  130.             $productClassId '0';
  131.         }
  132.         if ($Pref instanceof \Eccube\Entity\Master\Pref) {
  133.             $prefId $Pref->getId();
  134.         } elseif ($Pref) {
  135.             $prefId $Pref;
  136.         } else {
  137.             $prefId '0';
  138.         }
  139.         if ($Country instanceof \Eccube\Entity\Master\Country) {
  140.             $countryId $Country->getId();
  141.         } elseif ($Country) {
  142.             $countryId $Country;
  143.         } else {
  144.             $countryId '0';
  145.         }
  146.         $cacheKey $productId.':'.$productClassId.':'.$prefId.':'.$countryId;
  147.         // すでに取得している場合はキャッシュから
  148.         if (isset($this->rules[$cacheKey])) {
  149.             return $this->rules[$cacheKey];
  150.         }
  151.         $parameters = [];
  152.         $qb $this->createQueryBuilder('t')
  153.             ->where('t.apply_date < :apply_date');
  154.         $parameters[':apply_date'] = new \DateTime();
  155.         // Pref
  156.         if ($Pref) {
  157.             $qb->andWhere('t.Pref IS NULL OR t.Pref = :Pref');
  158.             $parameters['Pref'] = $Pref;
  159.         } else {
  160.             $qb->andWhere('t.Pref IS NULL');
  161.         }
  162.         // Country
  163.         if ($Country) {
  164.             $qb->andWhere('t.Country IS NULL OR t.Country = :Country');
  165.             $parameters['Country'] = $Country;
  166.         } else {
  167.             $qb->andWhere('t.Country IS NULL');
  168.         }
  169.         /*
  170.          * Product, ProductClass が persist される前に TaxRuleEventSubscriber によってアクセスされる
  171.          * 場合があるため、ID の存在もチェックする.
  172.          * https://github.com/EC-CUBE/ec-cube/issues/677
  173.          */
  174.         // Product
  175.         if ($Product && $productId 0) {
  176.             $qb->andWhere('t.Product IS NULL OR t.Product = :Product');
  177.             $parameters['Product'] = $Product;
  178.         } else {
  179.             $qb->andWhere('t.Product IS NULL');
  180.         }
  181.         // ProductClass
  182.         if ($ProductClass && '0' !== $productClassId) {
  183.             $qb->andWhere('t.ProductClass IS NULL OR t.ProductClass = :ProductClass');
  184.             $parameters['ProductClass'] = $ProductClass;
  185.         } else {
  186.             $qb->andWhere('t.ProductClass IS NULL');
  187.         }
  188.         $TaxRules $qb
  189.             ->setParameters($parameters)
  190.             ->orderBy('t.apply_date''DESC'// 実際は usort() でソートする
  191.             ->getQuery()
  192.             ->getResult();
  193.         // 地域設定を優先するが、システムパラメーターなどに設定を持っていくか
  194.         // 後に書いてあるほど優先される
  195.         $priorityKeys = [];
  196.         foreach ($this->eccubeConfig['eccube_tax_rule_priority'] as $priorityKey) {
  197.             $priorityKeys[] = str_replace('_'''preg_replace('/_id\z/'''$priorityKey));
  198.         }
  199.         foreach ($TaxRules as $TaxRule) {
  200.             $sortNo 0;
  201.             foreach ($priorityKeys as $index => $key) {
  202.                 $arrayProperties array_change_key_case($TaxRule->toArray());
  203.                 if ($arrayProperties[$key]) {
  204.                     // 配列の数値添字を重みとして利用する
  205.                     $sortNo += << ($index 1);
  206.                 }
  207.             }
  208.             $TaxRule->setSortNo($sortNo);
  209.         }
  210.         // 適用日降順, sortNo 降順にソートする
  211.         usort($TaxRules, function ($a$b) {
  212.             return $a->compareTo($b);
  213.         });
  214.         if (!empty($TaxRules)) {
  215.             $this->rules[$cacheKey] = $TaxRules[0];
  216.             return $TaxRules[0];
  217.         } else {
  218.             throw new NoResultException();
  219.         }
  220.     }
  221.     /**
  222.      * getList
  223.      *
  224.      * @return array|null
  225.      */
  226.     public function getList()
  227.     {
  228.         $qb $this->createQueryBuilder('t')
  229.             ->orderBy('t.apply_date''DESC')
  230.             ->where('t.Product IS NULL AND t.ProductClass IS NULL');
  231.         $TaxRules $qb
  232.             ->getQuery()
  233.             ->getResult();
  234.         return $TaxRules;
  235.     }
  236.     /**
  237.      * 税規約の削除.
  238.      *
  239.      * @param  int|\Eccube\Entity\TaxRule $TaxRule 税規約
  240.      *
  241.      * @throws NoResultException
  242.      */
  243.     public function delete($TaxRule)
  244.     {
  245.         if (!$TaxRule instanceof \Eccube\Entity\TaxRule) {
  246.             $TaxRule $this->find($TaxRule);
  247.         }
  248.         if (!$TaxRule) {
  249.             throw new NoResultException();
  250.         }
  251.         $em $this->getEntityManager();
  252.         $em->remove($TaxRule);
  253.         $em->flush();
  254.     }
  255.     /**
  256.      * TaxRule のキャッシュをクリアする.
  257.      *
  258.      * getByRule() をコールすると、結果をキャッシュし、2回目以降はデータベースへアクセスしない.
  259.      * このメソッドをコールすると、キャッシュをクリアし、再度データベースを参照して結果を取得する.
  260.      */
  261.     public function clearCache()
  262.     {
  263.         $this->rules = [];
  264.     }
  265. }