Passed
Pull Request — master (#75)
by
unknown
13:54
created

AbstractPrice::jsonSerialize()   B

Complexity

Conditions 7
Paths 64

Size

Total Lines 20
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
c 1
b 0
f 0
dl 0
loc 20
ccs 4
cts 4
cp 1
rs 8.8333
cc 7
nc 64
nop 0
crap 7
1
<?php
2
/**
3
 * PHP Billing Library
4
 *
5
 * @link      https://github.com/hiqdev/php-billing
6
 * @package   php-billing
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2020, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\billing\price;
12
13
use hiqdev\php\billing\action\ActionInterface;
14
use hiqdev\php\billing\charge\ChargeModifier;
15
use hiqdev\php\billing\charge\SettableChargeModifierTrait;
16
use hiqdev\php\billing\Exception\CannotReassignException;
17
use hiqdev\php\billing\plan\PlanInterface;
18
use hiqdev\php\billing\target\TargetInterface;
19
use hiqdev\php\billing\type\TypeInterface;
20
use hiqdev\php\units\QuantityInterface;
21
use Money\Money;
22
23
/**
24
 * Price.
25
 * @see PriceInterface
26
 * By default Price is applicable when same target and same type as Action.
27
 * But it can be different e.g. same price for all targets when certain type.
28
 *
29
 * @author Andrii Vasyliev <[email protected]>
30
 */
31
abstract class AbstractPrice implements PriceInterface, ChargeModifier
32
{
33
    use SettableChargeModifierTrait;
34
35
    /**
36
     * @var integer
37
     */
38
    protected $id;
39
40
    /**
41
     * @var TypeInterface
42
     */
43
    protected $type;
44
45
    /**
46
     * @var TargetInterface
47
     */
48
    protected $target;
49
50
    /**
51
     * @var PlanInterface|null
52
     */
53
    protected $plan;
54
55 41
    public function __construct(
56
        $id,
57
        TypeInterface $type,
58
        TargetInterface $target,
59
        PlanInterface $plan = null
60
    ) {
61 41
        $this->id = $id;
62 41
        $this->type = $type;
63 41
        $this->target = $target;
64 41
        $this->plan = $plan;
65 41
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70 4
    public function getId()
71
    {
72 4
        return $this->id;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 25
    public function getType()
79
    {
80 25
        return $this->type;
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86 25
    public function getTarget()
87
    {
88 25
        return $this->target;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94 1
    public function getPlan(): ?PlanInterface
95
    {
96 1
        return $this->plan;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function hasPlan()
103
    {
104
        return $this->plan !== null;
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110
    public function setPlan(PlanInterface $plan)
111
    {
112
        if ($this->hasPlan()) {
113
            throw new CannotReassignException('price plan');
114
        }
115
        $this->plan = $plan;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     * Default sum calculation method: sum = price * usage.
121
     */
122 13
    public function calculateSum(QuantityInterface $quantity): ?Money
123
    {
124 13
        $usage = $this->calculateUsage($quantity);
125 13
        if ($usage === null) {
126
            return null;
127
        }
128
129 13
        $price = $this->calculatePrice($quantity);
130 13
        if ($price === null) {
131
            return null;
132
        }
133
134
        /// TODO add configurable rounding mode later
135 13
        return $price->multiply(sprintf('%.14F', $usage->getQuantity()), Money::ROUND_UP);
136
    }
137
138 1
    public function jsonSerialize(): array
139
    {
140 1
        return [
141
            'id' => $this->id,
142
            'class' => (new \ReflectionClass($this))->getShortName(),
143
            'type' => $this->getType()->getName(),
144
            'type_id' => $this->getType()->getId(),
145
            'object_id' => $this->getTarget()->getId(),
146 21
            'object' => [
147
                'id' => $this->getTarget()->getId(),
148
                'name' => $this->getTarget()->getName(),
149
                'type' => $this->getTarget()->getType(),
150
            ],
151
            'plan_id' => $this->getPlan()?->getId(),
152
            'subprices' => $this instanceof PriceWithSubpriceInterface ? $this->getSubprices()->values() : null,
153
            'rate' => $this instanceof PriceWithRateInterface ? $this->getRate() : null,
154
            'unit' => $this instanceof PriceWithUnitInterface ? $this->getUnit()->getName() : null,
155
            'currency' => $this instanceof PriceWithCurrencyInterface ? $this->getCurrency()->getCode() : null,
156
            'sums' => $this instanceof PriceWithSumsInterface ? $this->getSums()->values() : null,
157 21
            'quantity' => $this instanceof PriceWithQuantityInterface ? $this->getPrepaid()->getQuantity() : 0,
158 21
        ];
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164
    public function isApplicable(ActionInterface $action): bool
165
    {
166
        /* sorry, debugging facility
167
        var_dump([
168
            'action.target'     => $action->getTarget(),
169
            'price.target'      => $this->getTarget(),
170
            'action.type'       => $action->getType(),
171
            'price.type'        => $this->getType(),
172
            'target matches'    => $action->getTarget()->matches($this->getTarget()),
173
            'type matches'      => $action->getType()->matches($this->getType()),
174
        ]); */
175
        return $action->getTarget()->matches($this->getTarget()) &&
176
               $action->getType()->matches($this->getType());
177
    }
178
}
179