mirror of
https://github.com/chenasraf/nextcloud-autocurrency.git
synced 2026-05-17 17:28:06 +00:00
feat: improve currency matching
This commit is contained in:
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: lint-php-cs-${{ github.head_ref || github.run_id }}
|
||||
group: release-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
21
README.md
21
README.md
@@ -13,25 +13,18 @@ rate.
|
||||
|
||||
Interval for fetch may be adjusted in the admin settings "Auto Currency" section.
|
||||
|
||||
**Note**: This is a companion app to Cospend. Without Cospend, this app will not work.
|
||||
|
||||
## Preparing currency data
|
||||
|
||||
To make this work, a 3-letter currency code must be in the name of the currency.
|
||||
For both main and additional currencies, you must include in the currency name, one of the following:
|
||||
|
||||
Currencies of different code lengths are not currently supported (but are planned).
|
||||
- Currency symbol (`$`, `€`, `£`, etc.)
|
||||
- Currency code (USD, EUR, GBP, etc.) - case insensitive
|
||||
|
||||
The currency code will be fetched using the first 3-uppercase-letter occurrence in the name defined
|
||||
on Cospend.
|
||||
Using one of these will be enough to fetch the correct rate.
|
||||
|
||||
For example, to properly set USD as currency, set the name to one of (but not limited to):
|
||||
|
||||
- USD
|
||||
- $ USD
|
||||
- USD $
|
||||
- United States Dollars (USD)
|
||||
|
||||
Will all be considered "USD" for conversion purposes.
|
||||
|
||||
This rule applies to **main** and **additional currencies**.
|
||||
For a list of available currencies, see [currencies.json](lib/Service/symbols.json).
|
||||
|
||||
To see the full list of available currencies, visit
|
||||
[this page](https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies.json) and
|
||||
|
||||
@@ -10,33 +10,12 @@
|
||||
<description><![CDATA[This NextCloud app automatically fetches currency information for your Cospend projects, and fills
|
||||
them up using the main currency as base. No more manually updating exchange rates!
|
||||
|
||||
It will automatically run once a day and use your currency names to fetch the correct rate.
|
||||
It will automatically run once a day by default and use your currency names to fetch the correct
|
||||
rate.
|
||||
|
||||
The name will be fetched using the first 3-uppercase-letter appearance in the name.
|
||||
Interval for fetch may be adjusted in the admin settings "Auto Currency" section.
|
||||
|
||||
For example:
|
||||
|
||||
- USD
|
||||
- $ USD
|
||||
- USD $
|
||||
- United States Dollars (USD)
|
||||
|
||||
Will all be considered "USD" for conversion purposes.
|
||||
|
||||
This rule applies to main and additional currencies.
|
||||
|
||||
## Contributing
|
||||
|
||||
I am developing this package on my free time, so any support, whether code, issues, or just stars is
|
||||
very helpful to sustaining its life. If you are feeling incredibly generous and would like to donate
|
||||
just a small amount to help sustain this project, I would be very very thankful!
|
||||
|
||||
<a href='https://ko-fi.com/casraf' target='_blank'>
|
||||
<img height='36' style='border:0px;height:36px;' src='https://cdn.ko-fi.com/cdn/kofi1.png?v=3' alt='Buy Me a Coffee at ko-fi.com' />
|
||||
</a>
|
||||
|
||||
I welcome any issues or pull requests on GitHub. If you find a bug, or would like a new feature,
|
||||
don't hesitate to open an appropriate issue and I will do my best to reply promptly.]]></description>
|
||||
**Note**: This is a companion app to Cospend. Without Cospend, this app will not work.]]></description>
|
||||
<version>0.2.1</version>
|
||||
<licence>agpl</licence>
|
||||
<author mail="contact@casraf.dev" homepage="https://casraf.dev">Chen Asraf</author>
|
||||
|
||||
@@ -19,11 +19,19 @@ use Psr\Log\LoggerInterface;
|
||||
|
||||
class FetchCurrenciesService {
|
||||
private static $EXCHANGE_URL = 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/{base}.json';
|
||||
private static $SYMBOLS_FILE = __DIR__ . '/symbols.json';
|
||||
|
||||
private IAppConfig $config;
|
||||
|
||||
private CurrencyMapper $currencyMapper;
|
||||
|
||||
private CospendProjectMapper $projectMapper;
|
||||
|
||||
private LoggerInterface $logger;
|
||||
|
||||
/* @var array<string, array<symbol: string, name: string, symbol_native: string, decimal_digits: int, rounding: int, code: string, name_plural: string>> */
|
||||
private array $symbols;
|
||||
|
||||
public function __construct(
|
||||
IAppConfig $config,
|
||||
CurrencyMapper $currencyMapper,
|
||||
@@ -34,6 +42,7 @@ class FetchCurrenciesService {
|
||||
$this->currencyMapper = $currencyMapper;
|
||||
$this->projectMapper = $projectMapper;
|
||||
$this->logger = $logger;
|
||||
$this->loadSymbols();
|
||||
}
|
||||
|
||||
public function fetchCurrencyRates(): void {
|
||||
@@ -68,8 +77,13 @@ class FetchCurrenciesService {
|
||||
|
||||
foreach ($currencies as $currency) {
|
||||
$cur = $this->getCurrencyName($currency->getName());
|
||||
if ($cur === null) {
|
||||
$this->logger->error('Currency not found: ' . $currency->getName());
|
||||
continue;
|
||||
}
|
||||
$lcur = strtolower($cur);
|
||||
$newRate = floatval(number_format(1 / $json[$lbase][$lcur], 2));
|
||||
$baseRate = $json[$lbase][$lcur];
|
||||
$newRate = floatval(number_format(1 / $baseRate, 2));
|
||||
$currency->setExchangeRate($newRate);
|
||||
$this->logger->info('Setting exchange rate for currency ' . $cur . ' to ' . $newRate);
|
||||
$this->currencyMapper->update($currency);
|
||||
@@ -80,17 +94,35 @@ class FetchCurrenciesService {
|
||||
$this->config->setValueString('autocurrency', 'last_update', $lastUpdate);
|
||||
}
|
||||
|
||||
private function getCurrencyName(string $name): string {
|
||||
// find 3-letter currency code for the base currency
|
||||
preg_match('/([A-Z]{3})/', $name, $matches);
|
||||
/** Match the currency name from the known currencies. **/
|
||||
private function getCurrencyName(string $name): ?string {
|
||||
foreach ($this->symbols as $cur => $currency) {
|
||||
// e.g. usd
|
||||
$id = strtolower($cur);
|
||||
if (strtolower($name) === $id) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
$this->logger->info('Matches: ' . json_encode($matches));
|
||||
// e.g. $
|
||||
$symbol = $currency['symbol'];
|
||||
if (str_contains($name, $symbol)) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
if (count($matches) === 2) {
|
||||
$name = $matches[1];
|
||||
// e.g. $ USD
|
||||
preg_match('/\b' . $id . '\b/', strtolower($name), $matches);
|
||||
if (count($matches) > 0) {
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Load symbols from the symbols.json file */
|
||||
private function loadSymbols(): void {
|
||||
$this->symbols = json_decode(file_get_contents(FetchCurrenciesService::$SYMBOLS_FILE), true);
|
||||
$this->logger->info('Loaded symbols: ' . json_encode($this->symbols));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
1001
lib/Service/symbols.json
Normal file
1001
lib/Service/symbols.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user