Failed Conditions
Pull Request — experimental/3.1 (#2624)
by Kentaro
71:04 queued 63:33
created

UsePointProcessor::process()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Eccube\Service\PurchaseFlow\Processor;
4
5
use Doctrine\ORM\EntityManager;
6
use Eccube\Annotation\Inject;
7
use Eccube\Entity\ItemHolderInterface;
8
use Eccube\Entity\Master\OrderItemType;
9
use Eccube\Entity\Master\TaxDisplayType;
10
use Eccube\Entity\Master\TaxType;
11
use Eccube\Entity\BaseInfo;
12
use Eccube\Entity\Order;
13
use Eccube\Entity\OrderItem;
14
use Eccube\Entity\Shipping;
15
use Eccube\Service\PurchaseFlow\ItemHolderProcessor;
16
use Eccube\Service\PurchaseFlow\ProcessResult;
17
use Eccube\Service\PurchaseFlow\PurchaseContext;
18
19
/**
20
 * 使用ポイント値引明細追加.
21
 */
22
class UsePointProcessor implements ItemHolderProcessor
23
{
24
    /**
25
     * @Inject("orm.em")
26
     * @var EntityManager
27
     */
28
    protected $entityManager;
29
30
    /**
31
     * @var BaseInfo
32
     */
33
    protected $BaseInfo;
34
35
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$entityManager" missing
Loading history...
introduced by
Doc comment for parameter "$BaseInfo" missing
Loading history...
36
     * DeliveryFeeProcessor constructor.
37
     *
38
     * @param $app
0 ignored issues
show
introduced by
Missing parameter name
Loading history...
39
     */
40
    public function __construct(EntityManager $entityManager, BaseInfo $BaseInfo)
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $entityManager. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
41
    {
42
        $this->entityManager = $entityManager;
43
        $this->BaseInfo = $BaseInfo;
44
    }
45
46
    /**
47
     * @param ItemHolderInterface $itemHolder
48
     * @param PurchaseContext     $context
49
     *
50
     * @return ProcessResult
51
     */
52
    public function process(ItemHolderInterface $itemHolder, PurchaseContext $context)
53
    {
54
        if ($itemHolder->getUsePoint() > 0) {
55
            if ($itemHolder->getUsePoint() > $context->getUser()->getPoint()) {
56
                // TODO カートに戻さないように修正する
57
                return ProcessResult::error('利用ポイントが所有ポイントを上回っています.');
58
            }
59
60
            $this->removePointDiscountItem($itemHolder);
61
            return $this->addPointDiscountItem($itemHolder);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
62
        }
63
64
        return ProcessResult::success();
65
    }
66
67
    /**
68
     * 明細追加処理
69
     *
70
     * @param ItemHolderInterface $itemHolder
71
     */
72
    protected function addPointDiscountItem(ItemHolderInterface $itemHolder)
73
    {
74
        $DiscountType = $this->entityManager
75
            ->find(OrderItemType::class, OrderItemType::DISCOUNT);
76
        // TODO
77
        $TaxInclude = $this->entityManager
78
            ->find(TaxDisplayType::class, TaxDisplayType::INCLUDED);
79
        $Taxion = $this->entityManager
80
            ->find(TaxType::class, TaxType::TAXATION);
81
82
        /** @var Order $Order */
83
        $Order = $itemHolder;
84
85
        $priceOfUsePoint = $this->usePointToPrice($Order->getUsePoint());
86
        if (($itemHolder->getTotal() + $priceOfUsePoint) < 0) {
87
            // TODO カートに戻さないように修正する
88
            // TODO 送料・手数料も考慮する
89
            return ProcessResult::error('利用ポイントがお支払い金額を上回っています.');
90
        }
91
        $OrderItem = new OrderItem();
92
        $OrderItem->setProductName('ポイント値引')
93
            ->setPrice($priceOfUsePoint)
94
            ->setPriceIncTax($priceOfUsePoint)
95
            ->setTaxRate(8)
96
            ->setQuantity(1)
97
            ->setOrderItemType($DiscountType)
98
            ->setTaxDisplayType($TaxInclude)
99
            ->setTaxType($Taxion)
100
            ->setOrder($itemHolder);
101
        $itemHolder->addItem($OrderItem);
102
        return ProcessResult::success();
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
103
    }
104
105
    /**
106
     * 既存のポイント明細を削除する.
107
     *
108
     * @param ItemHolderInterface $itemHolder
109
     */
110
    protected function removePointDiscountItem(ItemHolderInterface $itemHolder)
111
    {
112
        foreach ($itemHolder->getItems() as $item) {
113
            if ($item->isDiscount() && $item->getProductName() == 'ポイント値引') {
114
                $this->entityManager->remove($item);
115
            }
116
        }
117
    }
118
119
    /**
120
     * 利用ポイントを単価に換算する.
121
     *
122
     * @param integer $usePoint 利用ポイント
123
     * @return integer
124
     */
125
    protected function usePointToPrice($usePoint)
126
    {
127
        return ($usePoint * $this->BaseInfo->getPointConversionRate()) * -1;
128
    }
129
}
130