Failed Conditions
Push — sf/last-boss ( 53d963...58156b )
by Kiyotaka
09:54 queued 04:25
created

PointHelper::priceToPoint()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 6
rs 10
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;
15
16
use Doctrine\ORM\EntityManagerInterface;
17
use Eccube\Entity\ItemHolderInterface;
18
use Eccube\Entity\Master\OrderItemType;
19
use Eccube\Entity\Master\TaxDisplayType;
20
use Eccube\Entity\Master\TaxType;
21
use Eccube\Entity\OrderItem;
22
use Eccube\Repository\BaseInfoRepository;
23
use Eccube\Service\PurchaseFlow\Processor\PointProcessor;
24
25
class PointHelper
26
{
27
    /**
28
     * @var BaseInfoRepository
29
     */
30
    protected $baseInfoReppsitory;
31
32
    /**
33
     * @var EntityManagerInterface
34
     */
35
    protected $entityManager;
36
37
    /**
38
     * PointHelper constructor.
39
     *
40
     * @param BaseInfoRepository $baseInfoReppsitory
41
     * @param EntityManagerInterface $entityManager
42
     */
43
    public function __construct(BaseInfoRepository $baseInfoReppsitory, EntityManagerInterface $entityManager)
44
    {
45
        $this->baseInfoReppsitory = $baseInfoReppsitory;
46
        $this->entityManager = $entityManager;
47
    }
48
49
    /**
50
     * ポイント設定が有効かどうか.
51
     *
52
     * @return bool
53
     *
54
     * @throws \Doctrine\ORM\NoResultException
55
     * @throws \Doctrine\ORM\NonUniqueResultException
56
     */
57
    public function isPointEnabled()
58
    {
59
        $BaseInfo = $this->baseInfoReppsitory->get();
60
61
        return $BaseInfo->isOptionPoint();
62
    }
63
64
    /**
65
     * ポイントを金額に変換する.
66
     *
67
     * @param $point ポイント
68
     *
69
     * @return float|int 金額
70
     *
71
     * @throws \Doctrine\ORM\NoResultException
72
     * @throws \Doctrine\ORM\NonUniqueResultException
73
     */
74
    public function pointToPrice($point)
75
    {
76
        $BaseInfo = $this->baseInfoReppsitory->get();
77
78
        return intval($point * $BaseInfo->getPointConversionRate());
79
    }
80
81
    /**
82
     * ポイントを値引き額に変換する. マイナス値を返す.
83
     *
84
     * @param $point ポイント
85
     *
86
     * @return float|int 金額
87
     *
88
     * @throws \Doctrine\ORM\NoResultException
89
     * @throws \Doctrine\ORM\NonUniqueResultException
90
     */
91
    public function pointToDiscount($point)
92
    {
93
        return $this->pointToPrice($point) * -1;
94
    }
95
96
    /**
97
     * 金額をポイントに変換する.
98
     *
99
     * @param $price
100
     *
101
     * @return float ポイント
102
     *
103
     * @throws \Doctrine\ORM\NoResultException
104
     * @throws \Doctrine\ORM\NonUniqueResultException
105
     */
106
    public function priceToPoint($price)
107
    {
108
        $BaseInfo = $this->baseInfoReppsitory->get();
109
110
        return floor($price / $BaseInfo->getPointConversionRate());
111
    }
112
113
    /**
114
     * 明細追加処理.
115
     *
116
     * @param ItemHolderInterface $itemHolder
117
     * @param integer $discount
118
     */
119
    public function addPointDiscountItem(ItemHolderInterface $itemHolder, $discount)
120
    {
121
        $DiscountType = $this->entityManager->find(OrderItemType::class, OrderItemType::POINT);
122
        $TaxInclude = $this->entityManager->find(TaxDisplayType::class, TaxDisplayType::INCLUDED);
123
        $Taxation = $this->entityManager->find(TaxType::class, TaxType::NON_TAXABLE);
124
125
        $OrderItem = new OrderItem();
126
        $OrderItem->setProductName($DiscountType->getName())
127
            ->setPrice($discount)
128
            ->setQuantity(1)
129
            ->setTax(0)
130
            ->setTaxRate(0)
131
            ->setTaxRuleId(null)
132
            ->setRoundingType(null)
133
            ->setOrderItemType($DiscountType)
134
            ->setTaxDisplayType($TaxInclude)
135
            ->setTaxType($Taxation)
136
            ->setOrder($itemHolder)
0 ignored issues
show
Documentation introduced by
$itemHolder is of type object<Eccube\Entity\ItemHolderInterface>, but the function expects a null|object<Eccube\Entity\Order>.

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...
137
            ->setProcessorName(PointProcessor::class);
138
        $itemHolder->addItem($OrderItem);
139
    }
140
141
    /**
142
     * 既存のポイント明細を削除する.
143
     *
144
     * @param ItemHolderInterface $itemHolder
145
     */
146
    public function removePointDiscountItem(ItemHolderInterface $itemHolder)
147
    {
148
        foreach ($itemHolder->getItems() as $item) {
149
            if ($item->getProcessorName() == PointProcessor::class) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Eccube\Entity\ItemInterface as the method getProcessorName() does only exist in the following implementations of said interface: Eccube\Entity\OrderItem.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
150
                $itemHolder->removeOrderItem($item);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Eccube\Entity\ItemHolderInterface as the method removeOrderItem() does only exist in the following implementations of said interface: Eccube\Entity\Order.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
151
                $this->entityManager->remove($item);
152
            }
153
        }
154
    }
155
156
    public function prepare(ItemHolderInterface $itemHolder, $point)
157
    {
158
        // ユーザの保有ポイントを減算
159
        $Customer = $itemHolder->getCustomer();
160
        $Customer->setPoint($Customer->getPoint() - $point);
161
    }
162
163
    public function rollback(ItemHolderInterface $itemHolder, $point)
164
    {
165
        // 利用したポイントをユーザに戻す.
166
        $Customer = $itemHolder->getCustomer();
167
        $Customer->setPoint($Customer->getPoint() + $point);
168
    }
169
}
170