Passed
Pull Request — master (#67)
by
unknown
12:07
created

ProgressivePrice::getCondition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace hiqdev\php\billing\price;
6
7
use hiqdev\php\billing\plan\PlanInterface;
8
use hiqdev\php\billing\target\TargetInterface;
9
use hiqdev\php\billing\type\TypeInterface;
10
use hiqdev\php\units\Quantity;
11
use hiqdev\php\units\QuantityInterface;
12
use Money\Currency;
13
use Money\Money;
14
15
class ProgressivePrice extends AbstractPrice
16
{
17
    /* @psalm-var array{array{
18
     * "price": numeric,
19
     * "currency": string,
20
     * "value": numeric,
21
     * }} $condition
22
     */
23
    protected array $condition;
24
    /**
25
     * @var QuantityInterface prepaid quantity also implies Unit
26
     * XXX cannot be null cause Unit is required
27
     */
28
    protected $prepaid;
29
30
    public function __construct(
31
        $id,
32
        TypeInterface $type,
33
        TargetInterface $target,
34
        QuantityInterface $prepaid,
35
        array $condition,
36
        PlanInterface $plan = null,
37
    ) {
38
        parent::__construct($id, $type, $target, $plan);
39
        $this->prepaid = $prepaid;
40
        $this->condition = $condition;
41
    }
42
43
    public function getPrepaid()
44
    {
45
        return $this->prepaid;
46
    }
47
48
    public function getCondition(): array
49
    {
50
        return $this->condition;
51
    }
52
53
    public function setCondition(string $key, array $condition): self
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

53
    public function setCondition(/** @scrutinizer ignore-unused */ string $key, array $condition): self

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
54
    {
55
        $this->condition[] = $condition;
56
        return $this;
57
    }
58
59
    private function prepareCondition(): void
60
    {
61
        usort($this->condition, function($a, $b)
62
            {
63
                return $b['value'] <=> $a['value'];
64
            }
65
        );
66
    }
67
68
    /**
69
     * @inheritDoc
70
     */
71
    public function calculateUsage(QuantityInterface $quantity): ?QuantityInterface
72
    {
73
        $usage = $quantity->convert($this->prepaid->getUnit())->subtract($this->prepaid);
74
75
        if ($usage->isPositive()) {
76
            return $usage;
77
        }
78
79
        return Quantity::create($this->prepaid->getUnit()->getName(), 0);
80
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85
    public function calculatePrice(QuantityInterface $quantity): ?Money
86
    {
87
        $result = null;
88
        $this->prepareCondition();
89
        $usage = $this->calculateUsage($quantity);
90
        $quantity = $usage->getQuantity();
91
        foreach ($this->condition as $key => $condition) {
92
            if  ($condition['value'] < $quantity) {
93
                if ($key !== count($this->condition) - 1) {
94
                    $boundary = $quantity - $condition['value'];
95
                    $result += $boundary * $condition['price'];
96
                    $quantity = $quantity - $boundary;
97
                } else {
98
                    $result += $quantity * $condition['price'];
99
                }
100
            }
101
        }
102
        return new Money((int)($result * 100), new Currency($condition['currency']));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $condition seems to be defined by a foreach iteration on line 91. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
103
    }
104
105
    public function calculateSum(QuantityInterface $quantity): ?Money
106
    {
107
        return $this->calculatePrice($quantity);
108
    }
109
}
110