Passed
Pull Request — master (#67)
by
unknown
13:58
created

ProgressivePriceThresholds::getPriceRate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace hiqdev\php\billing\price;
6
7
use hiqdev\php\units\Quantity;
8
use InvalidArgumentException;
9
use Money\Money;
10
11
final class ProgressivePriceThresholds
12
{
13
    /** @var ProgressivePriceThreshold[] */
14
    public array $thresholds;
15
16
    private int $priceRate = 0;
17
18
    /**
19
     * @param ProgressivePriceThreshold[] $thresholds
20
     */
21
   public function __construct(
22
       array $thresholds
23
   )
24
   {
25
       foreach ($thresholds as $threshold) {
26
           $this->add(ProgressivePriceThreshold::createFromScalar(
27
                    (string) $threshold['price'],
28
                    (string) $threshold['currency'],
29
                    (string) $threshold['quantity'],
30
                    (string) $threshold['unit'],
31
               )
32
           );
33
       }
34
       $this->priceRate = MoneyBuilder::calculatePriceMultiplier((string)$threshold['price']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $threshold seems to be defined by a foreach iteration on line 25. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
35
   }
36
37
   public function add(ProgressivePriceThreshold $threshold): void
38
   {
39
      $this->checkCurrency($threshold->price());
40
      $this->checkUnit($threshold->quantity());
41
      $this->appendThresholds($threshold);
42
   }
43
44
    public function get(): array
45
    {
46
        $this->prepareThresholds();
47
        return $this->thresholds;
48
    }
49
50
    public function getPriceRate(): int
51
    {
52
        return $this->priceRate;
53
    }
54
55
    private function prepareThresholds(): void
56
    {
57
        usort($this->thresholds, function (ProgressivePriceThreshold $a, ProgressivePriceThreshold $b) {
58
            if ($b->quantity()->equals($a->quantity())) {
59
                return $b->price()->getAmount() <=> $a->price()->getAmount();
60
            }
61
            return $b->quantity()->getQuantity() <=> $a->quantity()->getQuantity();
62
        });
63
    }
64
65
    private function checkCurrency(Money $price): void
66
    {
67
        if (empty($this->thresholds)) {
68
            return;
69
        }
70
71
        $last = $this->thresholds[array_key_last($this->thresholds)];
72
73
        if (!$last->price()->getCurrency()->equals($price->getCurrency())
74
        ) {
75
            throw new InvalidArgumentException(sprintf(
76
                "Progressive price with threshold currency %s is not valid to other threshold currency %s",
77
                $last->price()->getCurrency()->getCode(),
78
                $price->getCurrency()->getCode()
79
            ));
80
        }
81
    }
82
83
    private function checkUnit(Quantity $prepaid): void
84
    {
85
        if (empty($this->thresholds)) {
86
            return;
87
        }
88
89
        $last = $this->thresholds[array_key_last($this->thresholds)];
90
91
        if (!$last->quantity()->getUnit()->isConvertible($prepaid->getUnit())) {
92
            throw new InvalidArgumentException(sprintf(
93
                "Progressive price with threshold unit %s is not convertible to other threshold unit %s",
94
                $last->quantity()->getUnit()->getName(),
95
                $prepaid->getUnit()->getName()
96
            ));
97
        }
98
    }
99
100
    private function appendThresholds(ProgressivePriceThreshold $threshold): void
101
    {
102
        $this->thresholds[] = $threshold;
103
    }
104
105
    public function __toArray(): array
106
    {
107
        $result = [];
108
        foreach ($this->thresholds as $threshold) {
109
            $result[] = $threshold->__toArray();
110
        }
111
        return $result;
112
    }
113
}
114