Passed
Push — main ( 986354...d60ffb )
by Thierry
15:08
created

LocaleService::setCurrency()   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
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Siak\Tontine\Service;
4
5
use Akaunting\Money\Currency;
6
use Akaunting\Money\Money;
7
use Illuminate\Support\Collection;
8
use Mcamara\LaravelLocalization\LaravelLocalization;
9
use Rinvex\Country\CountryLoader;
10
use Siak\Tontine\Model\Tontine;
11
use NumberFormatter;
12
13
use function route;
14
use function strtoupper;
15
16
class LocaleService
17
{
18
    /**
19
     * @var Currency
20
     */
21
    private $currency;
22
23
    /**
24
     * @var string
25
     */
26
    private $locale;
0 ignored issues
show
introduced by
The private property $locale is not used, and could be removed.
Loading history...
27
28
    /**
29
     * @var NumberFormatter
30
     */
31
    private $formatter = null;
32
33
    public function __construct(private LaravelLocalization $localization,
34
        private string $countriesDataDir, private string $currenciesDataDir)
35
    {}
36
37
    /**
38
     * Set the currency to be used for money
39
     *
40
     * @param string $currency
41
     *
42
     * @return void
43
     */
44
    public function setCurrency(string $currency)
45
    {
46
        $this->currency = new Currency(strtoupper($currency));
47
    }
48
49
    /**
50
     * Get the currency name
51
     *
52
     * @return string
53
     */
54
    public function getCurrencyName(): string
55
    {
56
        return $this->currency->getName();
57
    }
58
59
    /**
60
     * @return array
61
     */
62
    public function getCountries(): array
63
    {
64
        $locale = $this->localization->getCurrentLocale();
65
        return include($this->countriesDataDir . "/{$locale}/country.php");
66
    }
67
68
    /**
69
     * @param string $code
70
     *
71
     * @return array
72
     */
73
    public function getCountryCurrencies(string $code): array
74
    {
75
        $country = CountryLoader::country($code, false);
76
        $locale = $this->localization->getCurrentLocale();
77
        $localizedCurrencies = include($this->currenciesDataDir . "/{$locale}/currency.php");
78
79
        $currencies = [];
80
        foreach($country['currency'] as $currency)
81
        {
82
            $currencyCode = $currency['iso_4217_code'];
83
            $currencies[$currencyCode] = $localizedCurrencies[$currencyCode];
84
        }
85
        return $currencies;
86
    }
87
88
    /**
89
     * Get the names of countries and currencies
90
     *
91
     * @param array $countries
92
     * @param array $currencies
93
     *
94
     * @return array
95
     */
96
    public function getNames(array $countries, array $currencies): array
97
    {
98
        $locale = $this->localization->getCurrentLocale();
99
        $localizedCountries = include($this->countriesDataDir . "/{$locale}/country.php");
100
        $localizedCurrencies = include($this->currenciesDataDir . "/{$locale}/currency.php");
101
102
        $countryNames = [];
103
        foreach($countries as $code)
104
        {
105
            if(isset($localizedCountries[$code]))
106
            {
107
                $countryNames[$code] = $localizedCountries[$code];
108
            }
109
        }
110
        $currencyNames = [];
111
        foreach($currencies as $code)
112
        {
113
            if(isset($localizedCurrencies[$code]))
114
            {
115
                $currencyNames[$code] = $localizedCurrencies[$code];
116
            }
117
        }
118
        return [$countryNames, $currencyNames];
119
    }
120
121
    /**
122
     * Get the names of countries and currencies from a tontine model
123
     *
124
     * @param Tontine $tontine
125
     *
126
     * @return array
127
     */
128
    public function getNameFromTontine(Tontine $tontine): array
129
    {
130
        [$countries, $currencies] = $this->getNames([$tontine->country_code], [$tontine->currency_code]);
131
        return [$countries[$tontine->country_code] ?? '', $currencies[$tontine->currency_code] ?? ''];
132
    }
133
134
    /**
135
     * Get the names of countries and currencies from a collection of tontines
136
     *
137
     * @param Collection $tontines
138
     *
139
     * @return array
140
     */
141
    public function getNamesFromTontines(Collection $tontines): array
142
    {
143
        $countryCodes = $tontines->pluck('country_code')->toArray();
144
        $currencyCodes = $tontines->pluck('currency_code')->toArray();
145
        return $this->getNames($countryCodes, $currencyCodes);
146
    }
147
148
    /**
149
     * @return string
150
     */
151
    private function _locale(): string
152
    {
153
        $locales = ['en' => 'en_GB', 'fr' => 'fr_FR'];
154
        return $locales[$this->localization->getCurrentLocale()] ?? 'en_GB';
155
    }
156
157
    /**
158
     * @return NumberFormatter
159
     */
160
    private function makeDecimalFormatter(): NumberFormatter
161
    {
162
        $formatter = new NumberFormatter($this->_locale(), NumberFormatter::DECIMAL);
163
        $precision = $this->currency->getPrecision();
164
        $formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $precision);
165
        $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $precision);
166
        return $formatter;
167
    }
168
169
    /**
170
     * @return NumberFormatter
171
     */
172
    private function decimalFormatter(): NumberFormatter
173
    {
174
        return $this->formatter ??= $this->makeDecimalFormatter();
175
    }
176
177
    /**
178
     * Get a formatted amount.
179
     *
180
     * @param int $amount
181
     * @param bool $showSymbol
182
     *
183
     * @return string
184
     */
185
    public function formatMoney(int $amount, bool $showSymbol = true): string
186
    {
187
        $money = new Money($amount, $this->currency);
188
        return $showSymbol ? $money->formatLocale($this->_locale()) :
189
            $this->decimalFormatter()->format($money->getValue());
190
    }
191
192
    /**
193
     * @param float $amount
194
     *
195
     * @return int
196
     */
197
    public function convertMoneyToInt(float $amount): int
198
    {
199
        return (int)(new Money($amount, $this->currency, true))->getAmount();
200
    }
201
202
    /**
203
     * @param int $amount
204
     *
205
     * @return float
206
     */
207
    public function getMoneyValue(int $amount): float
208
    {
209
        return (new Money($amount, $this->currency, false))->getValue();
210
    }
211
212
    /**
213
     * Get the translated URL for a route
214
     *
215
     * @param string $name
216
     * @param array $attributes
217
     *
218
     * @return string
219
     */
220
    public function route(string $name, array $attributes = []): string
221
    {
222
        $locale = $this->localization->getCurrentLocale();
223
        return $this->localization->getLocalizedUrl($locale, route($name, $attributes));
224
    }
225
}
226