1 | <?php |
||
2 | |||
3 | namespace CfdiUtils\Utils; |
||
4 | |||
5 | class CurrencyDecimals |
||
6 | { |
||
7 | /** @var string */ |
||
8 | private $currency; |
||
9 | |||
10 | /** @var int */ |
||
11 | private $decimals; |
||
12 | |||
13 | 62 | public function __construct(string $currency, int $decimals) |
|
14 | { |
||
15 | 62 | if (! preg_match('/^[A-Z]{3}$/', $currency)) { |
|
16 | 3 | throw new \UnexpectedValueException('Property currency is not valid'); |
|
17 | } |
||
18 | 59 | if ($decimals < 0) { |
|
19 | 1 | throw new \UnexpectedValueException('Property decimals cannot be less than zero'); |
|
20 | } |
||
21 | 58 | $this->currency = $currency; |
|
22 | 58 | $this->decimals = $decimals; |
|
23 | } |
||
24 | |||
25 | 20 | public function currency(): string |
|
26 | { |
||
27 | 20 | return $this->currency; |
|
28 | } |
||
29 | |||
30 | 58 | public function decimals(): int |
|
31 | { |
||
32 | 58 | return $this->decimals; |
|
33 | } |
||
34 | |||
35 | 37 | public function round(float $value): float |
|
36 | { |
||
37 | 37 | return round($value, $this->decimals()); |
|
38 | } |
||
39 | |||
40 | 28 | public function doesNotExceedDecimals(string $value): bool |
|
41 | { |
||
42 | // use pathinfo trick to retrieve the right part after the dot |
||
43 | 28 | return ($this->decimalsCount($value) <= $this->decimals()); |
|
44 | } |
||
45 | |||
46 | 34 | public static function decimalsCount(string $value): int |
|
47 | { |
||
48 | 34 | return strlen(pathinfo($value, PATHINFO_EXTENSION)); |
|
49 | } |
||
50 | |||
51 | 60 | public static function newFromKnownCurrencies(string $currency, int $default = null): self |
|
52 | { |
||
53 | 60 | $decimals = static::knownCurrencyDecimals($currency); |
|
54 | 60 | if ($decimals < 0) { |
|
55 | 5 | if (null === $default) { |
|
56 | 4 | throw new \OutOfBoundsException('The currency %s is not known'); |
|
57 | } |
||
58 | 1 | $decimals = $default; |
|
59 | } |
||
60 | 56 | return new self($currency, $decimals); |
|
61 | } |
||
62 | |||
63 | 61 | public static function knownCurrencyDecimals(string $currency): int |
|
64 | { |
||
65 | 61 | $map = [ |
|
66 | 61 | 'MXN' => 2, |
|
67 | 61 | 'EUR' => 2, |
|
68 | 61 | 'USD' => 2, |
|
69 | 61 | 'XXX' => 0, |
|
70 | 61 | ]; |
|
71 | 61 | return array_key_exists($currency, $map) ? $map[$currency] : -1; |
|
72 | } |
||
73 | } |
||
74 |