Passed
Pull Request — master (#67)
by
unknown
14:21
created

ProgressivePrice   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 28
c 1
b 0
f 0
dl 0
loc 81
rs 10
wmc 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getThresholds() 0 3 1
A getPrice() 0 3 1
A calculatePrice() 0 3 1
A __construct() 0 13 1
A getPrepaid() 0 3 1
A calculateUsage() 0 9 2
A calculateSum() 0 18 3
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\Currencies\ISOCurrencies;
13
use Money\Currency;
14
use Money\Money;
15
use Money\Parser\DecimalMoneyParser;
16
17
class ProgressivePrice extends AbstractPrice
18
{
19
    protected ProgressivePriceThresholds $thresholds;
20
21
    protected Money $price;
22
23
    protected QuantityInterface $prepaid;
24
25
    public function __construct(
26
        $id,
27
        TypeInterface $type,
28
        TargetInterface $target,
29
        QuantityInterface $prepaid,
30
        Money $price,
31
        array $thresholds,
32
        ?PlanInterface $plan = null
33
    ) {
34
        parent::__construct($id, $type, $target, $plan);
35
        $this->thresholds = new ProgressivePriceThresholds($thresholds);
36
        $this->price = $price;
37
        $this->prepaid = $prepaid;
38
    }
39
40
    /**
41
     * @return ProgressivePriceThresholds
42
     */
43
    public function getThresholds(): ProgressivePriceThresholds
44
    {
45
        return $this->thresholds;
46
    }
47
48
    public function getPrepaid(): QuantityInterface
49
    {
50
        return $this->prepaid;
51
    }
52
53
    public function getPrice(): Money
54
    {
55
        return $this->price;
56
    }
57
58
    /**
59
     * @inheritDoc
60
     */
61
    public function calculateUsage(QuantityInterface $quantity): ?QuantityInterface
62
    {
63
        $usage = $quantity->convert($this->prepaid->getUnit());
64
65
        if ($usage->isPositive()) {
66
            return $usage;
67
        }
68
69
        return Quantity::create($this->prepaid->getUnit()->getName(), $quantity->getQuantity());
70
    }
71
72
    /**
73
     * @inheritDoc
74
     */
75
    public function calculatePrice(QuantityInterface $quantity): ?Money
76
    {
77
        return $this->price;
78
    }
79
80
    public function calculateSum(QuantityInterface $quantity): ?Money
81
    {
82
        $result = new Money(0, $this->price->getCurrency());
83
        $usage = $this->calculateUsage($quantity);
84
        $thresholds = $this->thresholds->get();
85
        foreach ($thresholds as $key => $threshold) {
86
            if  ($threshold->quantity()->compare($usage) < 0) {
87
                    $boundary = $usage->subtract($threshold->quantity());
88
                    $result = $result->add(new Money(
89
                            (int) $boundary->multiply($threshold->price()->getAmount())->getQuantity(),
90
                            $threshold->price()->getCurrency()
91
                        )
92
                    );
93
                    $usage = $usage->subtract($boundary);
94
            }
95
        }
96
        $result = (new DecimalMoneyParser(new ISOCurrencies()))->parse($result->getAmount(), $result->getCurrency());
97
        return $result->divide($this->thresholds->getPriceRate());
98
    }
99
}
100