Optimize currency search.

This commit is contained in:
James Cole
2025-09-07 14:49:49 +02:00
parent cce5a73dd2
commit 4835b05304
30 changed files with 211 additions and 157 deletions

View File

@@ -28,5 +28,5 @@ parameters:
# The level 8 is the highest level. original was 5 # The level 8 is the highest level. original was 5
# 7 is more than enough, higher just leaves NULL things. # 7 is more than enough, higher just leaves NULL things.
level: 8 level: 7

View File

@@ -35,6 +35,7 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface; use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Http\Api\CleansChartData; use FireflyIII\Support\Http\Api\CleansChartData;
use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
@@ -143,7 +144,7 @@ class BudgetController extends Controller
// convert data if necessary. // convert data if necessary.
if (true === $this->convertToPrimary && $currencyId !== $this->primaryCurrency->id) { if (true === $this->convertToPrimary && $currencyId !== $this->primaryCurrency->id) {
$currencies[$currencyId] ??= TransactionCurrency::find($currencyId); $currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId);
$row['pc_budgeted'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['budgeted']); $row['pc_budgeted'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['budgeted']);
$row['pc_spent'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['spent']); $row['pc_spent'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['spent']);
$row['pc_left'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['left']); $row['pc_left'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['left']);
@@ -231,7 +232,7 @@ class BudgetController extends Controller
* @var array $block * @var array $block
*/ */
foreach ($spent as $currencyId => $block) { foreach ($spent as $currencyId => $block) {
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId); $this->currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId);
$return[$currencyId] ??= [ $return[$currencyId] ??= [
'currency_id' => (string)$currencyId, 'currency_id' => (string)$currencyId,
'currency_code' => $block['currency_code'], 'currency_code' => $block['currency_code'],

View File

@@ -33,6 +33,7 @@ use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\CurrencyExchangeRate; use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface; use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\ExchangeRateTransformer; use FireflyIII\Transformers\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -98,7 +99,7 @@ class StoreController extends Controller
$from = $request->getFromCurrency(); $from = $request->getFromCurrency();
$collection = new Collection(); $collection = new Collection();
foreach ($data['rates'] as $key => $rate) { foreach ($data['rates'] as $key => $rate) {
$to = TransactionCurrency::where('code', $key)->first(); $to = Amount::getTransactionCurrencyByCode($key);
if (null === $to) { if (null === $to) {
continue; // should not happen. continue; // should not happen.
} }

View File

@@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate; namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
@@ -48,7 +49,7 @@ class StoreByDateRequest extends FormRequest
public function getFromCurrency(): TransactionCurrency public function getFromCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('from'))->first(); return Amount::getTransactionCurrencyByCode((string) $this->get('from'));
} }
/** /**
@@ -83,7 +84,7 @@ class StoreByDateRequest extends FormRequest
continue; continue;
} }
$to = TransactionCurrency::where('code', $key)->first(); $to = Amount::getTransactionCurrencyByCode((string) $key);
if (null === $to) { if (null === $to) {
$validator->errors()->add(sprintf('rates.%s', $key), trans('validation.invalid_currency_code', ['code' => $key])); $validator->errors()->add(sprintf('rates.%s', $key), trans('validation.invalid_currency_code', ['code' => $key]));
} }

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
@@ -42,7 +43,7 @@ class StoreRequest extends FormRequest
public function getFromCurrency(): TransactionCurrency public function getFromCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('from'))->first(); return Amount::getTransactionCurrencyByCode((string) $this->get('from'));
} }
public function getRate(): string public function getRate(): string
@@ -52,7 +53,7 @@ class StoreRequest extends FormRequest
public function getToCurrency(): TransactionCurrency public function getToCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('to'))->first(); return Amount::getTransactionCurrencyByCode((string) $this->get('to'));
} }
/** /**

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank; namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use FireflyIII\Support\Facades\Amount;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
@@ -135,13 +136,13 @@ class StoreRequest extends FormRequest
private function getCurrencyFromData(Validator $validator, array $data): ?TransactionCurrency private function getCurrencyFromData(Validator $validator, array $data): ?TransactionCurrency
{ {
if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) { if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) {
$currency = TransactionCurrency::whereCode($data['transaction_currency_code'])->first(); $currency = Amount::getTransactionCurrencyByCode((string) $data['transaction_currency_code']);
if (null !== $currency) { if (null !== $currency) {
return $currency; return $currency;
} }
} }
if (array_key_exists('transaction_currency_id', $data) && '' !== (string) $data['transaction_currency_id']) { if (array_key_exists('transaction_currency_id', $data) && '' !== (string) $data['transaction_currency_id']) {
$currency = TransactionCurrency::find((int) $data['transaction_currency_id']); $currency = Amount::getTransactionCurrencyById((int) $data['transaction_currency_id']);
if (null !== $currency) { if (null !== $currency) {
return $currency; return $currency;
} }

View File

@@ -25,9 +25,11 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade; namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Preference; use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -38,9 +40,9 @@ class UpgradesCurrencyPreferences extends Command
public const string CONFIG_NAME = '610_upgrade_currency_prefs'; public const string CONFIG_NAME = '610_upgrade_currency_prefs';
protected $description = 'Upgrade user currency preferences'; protected $description = 'Upgrade user currency preferences';
protected $signature = 'upgrade:610-currency-preferences {--F|force : Force the execution of this command.}'; protected $signature = 'upgrade:610-currency-preferences {--F|force : Force the execution of this command.}';
/** /**
* Execute the console command. * Execute the console command.
@@ -65,7 +67,7 @@ class UpgradesCurrencyPreferences extends Command
{ {
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) { if (null !== $configVar) {
return (bool) $configVar->data; return (bool)$configVar->data;
} }
return false; return false;
@@ -80,7 +82,7 @@ class UpgradesCurrencyPreferences extends Command
$this->upgradeGroupPreferences($group); $this->upgradeGroupPreferences($group);
} }
$users = User::get(); $users = User::get();
/** @var User $user */ /** @var User $user */
foreach ($users as $user) { foreach ($users as $user) {
@@ -104,8 +106,8 @@ class UpgradesCurrencyPreferences extends Command
private function upgradeUserPreferences(User $user): void private function upgradeUserPreferences(User $user): void
{ {
$currencies = TransactionCurrency::get(); $currencies = TransactionCurrency::get();
$enabled = new Collection(); $enabled = new Collection();
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
foreach ($currencies as $currency) { foreach ($currencies as $currency) {
@@ -116,10 +118,10 @@ class UpgradesCurrencyPreferences extends Command
$user->currencies()->sync($enabled->pluck('id')->toArray()); $user->currencies()->sync($enabled->pluck('id')->toArray());
// set the default currency for the user and for the group: // set the default currency for the user and for the group:
$preference = $this->getPreference($user); $preference = $this->getPreference($user);
$primaryCurrency = TransactionCurrency::where('code', $preference)->first(); try {
if (null === $primaryCurrency) { $primaryCurrency = Amount::getTransactionCurrencyByCode($preference);
// get EUR } catch (FireflyException) {
$primaryCurrency = TransactionCurrency::where('code', 'EUR')->first(); $primaryCurrency = TransactionCurrency::where('code', 'EUR')->first();
} }
$user->currencies()->updateExistingPivot($primaryCurrency->id, ['user_default' => true]); $user->currencies()->updateExistingPivot($primaryCurrency->id, ['user_default' => true]);
@@ -135,7 +137,7 @@ class UpgradesCurrencyPreferences extends Command
} }
if (null !== $preference->data && !is_array($preference->data)) { if (null !== $preference->data && !is_array($preference->data)) {
return (string) $preference->data; return (string)$preference->data;
} }
return 'EUR'; return 'EUR';

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
/** /**
* Class TransactionCurrencyFactory * Class TransactionCurrencyFactory
@@ -48,7 +49,7 @@ class TransactionCurrencyFactory
if (1 === $count) { if (1 === $count) {
$old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first(); $old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first();
$old->forceDelete(); $old->forceDelete();
app('log')->warning(sprintf('Force deleted old currency with ID #%d and code "%s".', $old->id, $data['code'])); Log::warning(sprintf('Force deleted old currency with ID #%d and code "%s".', $old->id, $data['code']));
} }
try { try {
@@ -64,8 +65,8 @@ class TransactionCurrencyFactory
); );
} catch (QueryException $e) { } catch (QueryException $e) {
$result = null; $result = null;
app('log')->error(sprintf('Could not create new currency: %s', $e->getMessage())); Log::error(sprintf('Could not create new currency: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString()); Log::error($e->getTraceAsString());
throw new FireflyException('400004: Could not store new currency.', 0, $e); throw new FireflyException('400004: Could not store new currency.', 0, $e);
} }
@@ -79,7 +80,7 @@ class TransactionCurrencyFactory
$currencyId = (int) $currencyId; $currencyId = (int) $currencyId;
if ('' === $currencyCode && 0 === $currencyId) { if ('' === $currencyCode && 0 === $currencyId) {
app('log')->debug('Cannot find anything on empty currency code and empty currency ID!'); Log::debug('Cannot find anything on empty currency code and empty currency ID!');
return null; return null;
} }
@@ -90,7 +91,7 @@ class TransactionCurrencyFactory
if (null !== $currency) { if (null !== $currency) {
return $currency; return $currency;
} }
app('log')->warning(sprintf('Currency ID is %d but found nothing!', $currencyId)); Log::warning(sprintf('Currency ID is %d but found nothing!', $currencyId));
} }
// then by code: // then by code:
if ('' !== $currencyCode) { if ('' !== $currencyCode) {
@@ -98,9 +99,9 @@ class TransactionCurrencyFactory
if (null !== $currency) { if (null !== $currency) {
return $currency; return $currency;
} }
app('log')->warning(sprintf('Currency code is %d but found nothing!', $currencyCode)); Log::warning(sprintf('Currency code is %d but found nothing!', $currencyCode));
} }
app('log')->warning('Found nothing for currency.'); Log::warning('Found nothing for currency.');
return null; return null;
} }

View File

@@ -25,14 +25,15 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware; namespace FireflyIII\Http\Middleware;
use Closure; use Closure;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\GroupMembership; use FireflyIII\Models\GroupMembership;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Models\Webhook; use FireflyIII\Models\Webhook;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -103,33 +104,33 @@ class InterestingMessage
// send message about newly created transaction group. // send message about newly created transaction group.
/** @var null|TransactionGroup $group */ /** @var null|TransactionGroup $group */
$group = auth()->user()->transactionGroups()->with(['transactionJournals', 'transactionJournals.transactionType'])->find((int) $transactionGroupId); $group = auth()->user()->transactionGroups()->with(['transactionJournals', 'transactionJournals.transactionType'])->find((int)$transactionGroupId);
if (null === $group) { if (null === $group) {
return; return;
} }
$count = $group->transactionJournals->count(); $count = $group->transactionJournals->count();
/** @var null|TransactionJournal $journal */ /** @var null|TransactionJournal $journal */
$journal = $group->transactionJournals->first(); $journal = $group->transactionJournals->first();
if (null === $journal) { if (null === $journal) {
return; return;
} }
$title = $count > 1 ? $group->title : $journal->description; $title = $count > 1 ? $group->title : $journal->description;
if ('created' === $message) { if ('created' === $message) {
session()->flash('success_url', route('transactions.show', [$transactionGroupId])); session()->flash('success_url', route('transactions.show', [$transactionGroupId]));
session()->flash('success', (string) trans('firefly.stored_journal', ['description' => $title])); session()->flash('success', (string)trans('firefly.stored_journal', ['description' => $title]));
} }
if ('updated' === $message) { if ('updated' === $message) {
$type = strtolower((string) $journal->transactionType->type); $type = strtolower((string)$journal->transactionType->type);
session()->flash('success_url', route('transactions.show', [$transactionGroupId])); session()->flash('success_url', route('transactions.show', [$transactionGroupId]));
session()->flash('success', (string) trans(sprintf('firefly.updated_%s', $type), ['description' => $title])); session()->flash('success', (string)trans(sprintf('firefly.updated_%s', $type), ['description' => $title]));
} }
if ('no_change' === $message) { if ('no_change' === $message) {
$type = strtolower((string) $journal->transactionType->type); $type = strtolower((string)$journal->transactionType->type);
session()->flash('warning_url', route('transactions.show', [$transactionGroupId])); session()->flash('warning_url', route('transactions.show', [$transactionGroupId]));
session()->flash('warning', (string) trans(sprintf('firefly.no_changes_%s', $type), ['description' => $title])); session()->flash('warning', (string)trans(sprintf('firefly.no_changes_%s', $type), ['description' => $title]));
} }
} }
@@ -149,7 +150,7 @@ class InterestingMessage
$message = $request->get('message'); $message = $request->get('message');
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
/** @var null|UserGroup $userGroup */ /** @var null|UserGroup $userGroup */
$userGroup = UserGroup::find($userGroupId); $userGroup = UserGroup::find($userGroupId);
@@ -170,13 +171,13 @@ class InterestingMessage
if ('deleted' === $message) { if ('deleted' === $message) {
session()->flash('success', (string) trans('firefly.flash_administration_deleted', ['title' => $userGroup->title])); session()->flash('success', (string)trans('firefly.flash_administration_deleted', ['title' => $userGroup->title]));
} }
if ('created' === $message) { if ('created' === $message) {
session()->flash('success', (string) trans('firefly.flash_administration_created', ['title' => $userGroup->title])); session()->flash('success', (string)trans('firefly.flash_administration_created', ['title' => $userGroup->title]));
} }
if ('updated' === $message) { if ('updated' === $message) {
session()->flash('success', (string) trans('firefly.flash_administration_updated', ['title' => $userGroup->title])); session()->flash('success', (string)trans('firefly.flash_administration_updated', ['title' => $userGroup->title]));
} }
} }
@@ -196,22 +197,22 @@ class InterestingMessage
$message = $request->get('message'); $message = $request->get('message');
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
/** @var null|Account $account */ /** @var null|Account $account */
$account = $user->accounts()->withTrashed()->find($accountId); $account = $user->accounts()->withTrashed()->find($accountId);
if (null === $account) { if (null === $account) {
return; return;
} }
if ('deleted' === $message) { if ('deleted' === $message) {
session()->flash('success', (string) trans('firefly.account_deleted', ['name' => $account->name])); session()->flash('success', (string)trans('firefly.account_deleted', ['name' => $account->name]));
} }
if ('created' === $message) { if ('created' === $message) {
session()->flash('success', (string) trans('firefly.stored_new_account', ['name' => $account->name])); session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name]));
} }
if ('updated' === $message) { if ('updated' === $message) {
session()->flash('success', (string) trans('firefly.updated_account', ['name' => $account->name])); session()->flash('success', (string)trans('firefly.updated_account', ['name' => $account->name]));
} }
} }
@@ -231,16 +232,16 @@ class InterestingMessage
$message = $request->get('message'); $message = $request->get('message');
/** @var null|Bill $bill */ /** @var null|Bill $bill */
$bill = auth()->user()->bills()->withTrashed()->find($billId); $bill = auth()->user()->bills()->withTrashed()->find($billId);
if (null === $bill) { if (null === $bill) {
return; return;
} }
if ('deleted' === $message) { if ('deleted' === $message) {
session()->flash('success', (string) trans('firefly.deleted_bill', ['name' => $bill->name])); session()->flash('success', (string)trans('firefly.deleted_bill', ['name' => $bill->name]));
} }
if ('created' === $message) { if ('created' === $message) {
session()->flash('success', (string) trans('firefly.stored_new_bill', ['name' => $bill->name])); session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name]));
} }
} }
@@ -260,19 +261,19 @@ class InterestingMessage
$message = $request->get('message'); $message = $request->get('message');
/** @var null|Webhook $webhook */ /** @var null|Webhook $webhook */
$webhook = auth()->user()->webhooks()->withTrashed()->find($webhookId); $webhook = auth()->user()->webhooks()->withTrashed()->find($webhookId);
if (null === $webhook) { if (null === $webhook) {
return; return;
} }
if ('deleted' === $message) { if ('deleted' === $message) {
session()->flash('success', (string) trans('firefly.deleted_webhook', ['title' => $webhook->title])); session()->flash('success', (string)trans('firefly.deleted_webhook', ['title' => $webhook->title]));
} }
if ('updated' === $message) { if ('updated' === $message) {
session()->flash('success', (string) trans('firefly.updated_webhook', ['title' => $webhook->title])); session()->flash('success', (string)trans('firefly.updated_webhook', ['title' => $webhook->title]));
} }
if ('created' === $message) { if ('created' === $message) {
session()->flash('success', (string) trans('firefly.stored_new_webhook', ['title' => $webhook->title])); session()->flash('success', (string)trans('firefly.stored_new_webhook', ['title' => $webhook->title]));
} }
} }
@@ -289,32 +290,31 @@ class InterestingMessage
{ {
// params: // params:
// get parameters from request. // get parameters from request.
$code = $request->get('code'); $code = (string) $request->get('code');
$message = $request->get('message'); $message = (string) $request->get('message');
try {
/** @var null|TransactionCurrency $currency */ $currency = Amount::getTransactionCurrencyByCode($code);
$currency = TransactionCurrency::whereCode($code)->first(); } catch (FireflyException) {
if (null === $currency) {
return; return;
} }
if ('enabled' === $message) { if ('enabled' === $message) {
session()->flash('success', (string) trans('firefly.currency_is_now_enabled', ['name' => $currency->name])); session()->flash('success', (string)trans('firefly.currency_is_now_enabled', ['name' => $currency->name]));
} }
if ('enable_failed' === $message) { if ('enable_failed' === $message) {
session()->flash('error', (string) trans('firefly.could_not_enable_currency', ['name' => $currency->name])); session()->flash('error', (string)trans('firefly.could_not_enable_currency', ['name' => $currency->name]));
} }
if ('disabled' === $message) { if ('disabled' === $message) {
session()->flash('success', (string) trans('firefly.currency_is_now_disabled', ['name' => $currency->name])); session()->flash('success', (string)trans('firefly.currency_is_now_disabled', ['name' => $currency->name]));
} }
if ('disable_failed' === $message) { if ('disable_failed' === $message) {
session()->flash('error', (string) trans('firefly.could_not_disable_currency', ['name' => $currency->name])); session()->flash('error', (string)trans('firefly.could_not_disable_currency', ['name' => $currency->name]));
} }
if ('default' === $message) { if ('default' === $message) {
session()->flash('success', (string) trans('firefly.new_default_currency', ['name' => $currency->name])); session()->flash('success', (string)trans('firefly.new_default_currency', ['name' => $currency->name]));
} }
if ('default_failed' === $message) { if ('default_failed' === $message) {
session()->flash('error', (string) trans('firefly.default_currency_failed', ['name' => $currency->name])); session()->flash('error', (string)trans('firefly.default_currency_failed', ['name' => $currency->name]));
} }
} }
} }

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests; namespace FireflyIII\Http\Requests;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
@@ -60,7 +61,7 @@ class PiggyBankStoreRequest extends FormRequest
$accounts = []; $accounts = [];
} }
foreach ($accounts as $item) { foreach ($accounts as $item) {
$data['accounts'][] = ['account_id' => (int) $item]; $data['accounts'][] = ['account_id' => (int)$item];
} }
return $data; return $data;
@@ -97,7 +98,7 @@ class PiggyBankStoreRequest extends FormRequest
$repository = app(AccountRepositoryInterface::class); $repository = app(AccountRepositoryInterface::class);
$types = config('firefly.piggy_bank_account_types'); $types = config('firefly.piggy_bank_account_types');
foreach ($data['accounts'] as $value) { foreach ($data['accounts'] as $value) {
$accountId = (int) $value; $accountId = (int)$value;
$account = $repository->find($accountId); $account = $repository->find($accountId);
if (null !== $account) { if (null !== $account) {
// check currency here. // check currency here.
@@ -106,7 +107,7 @@ class PiggyBankStoreRequest extends FormRequest
if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) { if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) {
$validator->errors()->add('accounts', trans('validation.invalid_account_currency')); $validator->errors()->add('accounts', trans('validation.invalid_account_currency'));
} }
$type = $account->accountType->type; $type = $account->accountType->type;
if (!in_array($type, $types, true)) { if (!in_array($type, $types, true)) {
$validator->errors()->add('accounts', trans('validation.invalid_account_type')); $validator->errors()->add('accounts', trans('validation.invalid_account_type'));
} }
@@ -123,9 +124,10 @@ class PiggyBankStoreRequest extends FormRequest
private function getCurrencyFromData(array $data): TransactionCurrency private function getCurrencyFromData(array $data): TransactionCurrency
{ {
$currencyId = (int) ($data['transaction_currency_id'] ?? 0); $currencyId = (int)($data['transaction_currency_id'] ?? 0);
$currency = TransactionCurrency::find($currencyId); try {
if (null === $currency) { $currency = Amount::getTransactionCurrencyById($currencyId);
} catch (FireflyException) {
return Amount::getPrimaryCurrency(); return Amount::getPrimaryCurrency();
} }

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests; namespace FireflyIII\Http\Requests;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
@@ -129,8 +130,9 @@ class PiggyBankUpdateRequest extends FormRequest
private function getCurrencyFromData(array $data): TransactionCurrency private function getCurrencyFromData(array $data): TransactionCurrency
{ {
$currencyId = (int) ($data['transaction_currency_id'] ?? 0); $currencyId = (int) ($data['transaction_currency_id'] ?? 0);
$currency = TransactionCurrency::find($currencyId); try {
if (null === $currency) { $currency = Amount::getTransactionCurrencyById($currencyId);
} catch (FireflyException) {
return Amount::getPrimaryCurrency(); return Amount::getPrimaryCurrency();
} }

View File

@@ -38,6 +38,7 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Services\Internal\Destroy\AccountDestroyService; use FireflyIII\Services\Internal\Destroy\AccountDestroyService;
use FireflyIII\Services\Internal\Update\AccountUpdateService; use FireflyIII\Services\Internal\Update\AccountUpdateService;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface; use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
@@ -400,7 +401,7 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
} }
$currencyId = (int) $this->getMetaValue($account, 'currency_id'); $currencyId = (int) $this->getMetaValue($account, 'currency_id');
if ($currencyId > 0) { if ($currencyId > 0) {
return TransactionCurrency::find($currencyId); return Amount::getTransactionCurrencyById($currencyId);
} }
return null; return null;

View File

@@ -166,7 +166,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
$currencyDecimalPlaces = $journal['currency_decimal_places']; $currencyDecimalPlaces = $journal['currency_decimal_places'];
} }
if (true === $convertToPrimary && $journalCurrencyId !== $currencyId) { if (true === $convertToPrimary && $journalCurrencyId !== $currencyId) {
$currencies[$journalCurrencyId] ??= TransactionCurrency::find($journalCurrencyId); $currencies[$journalCurrencyId] ??= Amount::getTransactionCurrencyById($journalCurrencyId);
$amount = $converter->convert($currencies[$journalCurrencyId], $primaryCurrency, $journal['date'], $amount); $amount = $converter->convert($currencies[$journalCurrencyId], $primaryCurrency, $journal['date'], $amount);
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\PiggyBank; namespace FireflyIII\Repositories\PiggyBank;
use Exception;
use FireflyIII\Events\Model\PiggyBank\ChangedAmount; use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
use FireflyIII\Events\Model\PiggyBank\ChangedName; use FireflyIII\Events\Model\PiggyBank\ChangedName;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
@@ -32,12 +33,11 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\Note; use FireflyIII\Models\Note;
use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups; use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Exception;
/** /**
* Trait ModifiesPiggyBanks * Trait ModifiesPiggyBanks
@@ -71,9 +71,9 @@ trait ModifiesPiggyBanks
$pivot->native_current_amount = null; $pivot->native_current_amount = null;
// also update native_current_amount. // also update native_current_amount.
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup); $userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
if ($userCurrency->id !== $piggyBank->transaction_currency_id) { if ($userCurrency->id !== $piggyBank->transaction_currency_id) {
$converter = new ExchangeRateConverter(); $converter = new ExchangeRateConverter();
$converter->setIgnoreSettings(true); $converter->setIgnoreSettings(true);
$pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount); $pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount);
} }
@@ -94,9 +94,9 @@ trait ModifiesPiggyBanks
$pivot->native_current_amount = null; $pivot->native_current_amount = null;
// also update native_current_amount. // also update native_current_amount.
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup); $userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
if ($userCurrency->id !== $piggyBank->transaction_currency_id) { if ($userCurrency->id !== $piggyBank->transaction_currency_id) {
$converter = new ExchangeRateConverter(); $converter = new ExchangeRateConverter();
$converter->setIgnoreSettings(true); $converter->setIgnoreSettings(true);
$pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount); $pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount);
} }
@@ -128,8 +128,8 @@ trait ModifiesPiggyBanks
Log::debug(sprintf('Maximum amount: %s', $maxAmount)); Log::debug(sprintf('Maximum amount: %s', $maxAmount));
} }
$compare = bccomp($amount, $maxAmount); $compare = bccomp($amount, $maxAmount);
$result = $compare <= 0; $result = $compare <= 0;
Log::debug(sprintf('Compare <= 0? %d, so canAddAmount is %s', $compare, var_export($result, true))); Log::debug(sprintf('Compare <= 0? %d, so canAddAmount is %s', $compare, var_export($result, true)));
@@ -163,11 +163,11 @@ trait ModifiesPiggyBanks
public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank
{ {
$repetition = $this->getRepetition($piggyBank); $repetition = $this->getRepetition($piggyBank);
if (null === $repetition) { if (null === $repetition) {
return $piggyBank; return $piggyBank;
} }
$max = $piggyBank->target_amount; $max = $piggyBank->target_amount;
if (1 === bccomp($amount, $max) && 0 !== bccomp($piggyBank->target_amount, '0')) { if (1 === bccomp($amount, $max) && 0 !== bccomp($piggyBank->target_amount, '0')) {
$amount = $max; $amount = $max;
} }
@@ -210,14 +210,14 @@ trait ModifiesPiggyBanks
public function update(PiggyBank $piggyBank, array $data): PiggyBank public function update(PiggyBank $piggyBank, array $data): PiggyBank
{ {
$piggyBank = $this->updateProperties($piggyBank, $data); $piggyBank = $this->updateProperties($piggyBank, $data);
if (array_key_exists('notes', $data)) { if (array_key_exists('notes', $data)) {
$this->updateNote($piggyBank, (string)$data['notes']); $this->updateNote($piggyBank, (string)$data['notes']);
} }
// update the order of the piggy bank: // update the order of the piggy bank:
$oldOrder = $piggyBank->order; $oldOrder = $piggyBank->order;
$newOrder = (int)($data['order'] ?? $oldOrder); $newOrder = (int)($data['order'] ?? $oldOrder);
if ($oldOrder !== $newOrder) { if ($oldOrder !== $newOrder) {
$this->setOrder($piggyBank, $newOrder); $this->setOrder($piggyBank, $newOrder);
} }
@@ -287,7 +287,7 @@ trait ModifiesPiggyBanks
$piggyBank->name = $data['name']; $piggyBank->name = $data['name'];
} }
if (array_key_exists('transaction_currency_id', $data) && is_int($data['transaction_currency_id'])) { if (array_key_exists('transaction_currency_id', $data) && is_int($data['transaction_currency_id'])) {
$currency = TransactionCurrency::find($data['transaction_currency_id']); $currency = Amount::getTransactionCurrencyById($data['transaction_currency_id']);
if (null !== $currency) { if (null !== $currency) {
$piggyBank->transaction_currency_id = $currency->id; $piggyBank->transaction_currency_id = $currency->id;
} }
@@ -320,7 +320,7 @@ trait ModifiesPiggyBanks
return; return;
} }
$dbNote = $piggyBank->notes()->first(); $dbNote = $piggyBank->notes()->first();
if (null === $dbNote) { if (null === $dbNote) {
$dbNote = new Note(); $dbNote = new Note();
$dbNote->noteable()->associate($piggyBank); $dbNote->noteable()->associate($piggyBank);
@@ -331,16 +331,15 @@ trait ModifiesPiggyBanks
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool public function setOrder(PiggyBank $piggyBank, int $newOrder): bool
{ {
$oldOrder = $piggyBank->order; $oldOrder = $piggyBank->order;
// Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); // Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
if ($newOrder > $oldOrder) { if ($newOrder > $oldOrder) {
PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
->where('accounts.user_id', $this->user->id) ->where('accounts.user_id', $this->user->id)
->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder) ->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder)
->where('piggy_banks.id', '!=', $piggyBank->id) ->where('piggy_banks.id', '!=', $piggyBank->id)
->distinct()->decrement('piggy_banks.order') ->distinct()->decrement('piggy_banks.order');
;
$piggyBank->order = $newOrder; $piggyBank->order = $newOrder;
Log::debug(sprintf('[1] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); Log::debug(sprintf('[1] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
@@ -349,12 +348,11 @@ trait ModifiesPiggyBanks
return true; return true;
} }
PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
->where('accounts.user_id', $this->user->id) ->where('accounts.user_id', $this->user->id)
->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder) ->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder)
->where('piggy_banks.id', '!=', $piggyBank->id) ->where('piggy_banks.id', '!=', $piggyBank->id)
->distinct()->increment('piggy_banks.order') ->distinct()->increment('piggy_banks.order');
;
$piggyBank->order = $newOrder; $piggyBank->order = $newOrder;
Log::debug(sprintf('[2] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); Log::debug(sprintf('[2] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
@@ -375,7 +373,7 @@ trait ModifiesPiggyBanks
} }
// if this account contains less than the amount, remove the current amount, update the amount and continue. // if this account contains less than the amount, remove the current amount, update the amount and continue.
$this->removeAmount($piggyBank, $account, $current); $this->removeAmount($piggyBank, $account, $current);
$amount = bcsub($amount, (string)$current); $amount = bcsub($amount, (string)$current);
} }
} }
} }

View File

@@ -354,7 +354,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
->first() ->first()
; ;
if (null !== $currencyPreference) { if (null !== $currencyPreference) {
$currency = TransactionCurrency::where('id', $currencyPreference->data)->first(); $currency = Amount::getTransactionCurrencyById((int) $currencyPreference->data);
} }
$journalId = $row->transaction_journal_id; $journalId = $row->transaction_journal_id;
$return[$journalId] ??= []; $return[$journalId] ??= [];

View File

@@ -32,6 +32,7 @@ use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Services\Internal\Update\AccountUpdateService; use FireflyIII\Services\Internal\Update\AccountUpdateService;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
@@ -141,7 +142,7 @@ class AccountRepository implements AccountRepositoryInterface
} }
$currencyId = (int) $this->getMetaValue($account, 'currency_id'); $currencyId = (int) $this->getMetaValue($account, 'currency_id');
if ($currencyId > 0) { if ($currencyId > 0) {
return TransactionCurrency::find($currencyId); return Amount::getTransactionCurrencyById($currencyId);
} }
return null; return null;

View File

@@ -29,11 +29,11 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Support\Facades\Preferences; use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Singleton\PreferencesSingleton; use FireflyIII\Support\Singleton\PreferencesSingleton;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use NumberFormatter; use NumberFormatter;
use FireflyIII\Support\Facades\Steam;
/** /**
* Class Amount. * Class Amount.
@@ -59,15 +59,15 @@ class Amount
*/ */
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string
{ {
$locale = Steam::getLocale(); $locale = Steam::getLocale();
$rounded = Steam::bcround($amount, $decimalPlaces); $rounded = Steam::bcround($amount, $decimalPlaces);
$coloured ??= true; $coloured ??= true;
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY); $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
$fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, $symbol); $fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, $symbol);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces); $fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces);
$fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces); $fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces);
$result = (string)$fmt->format((float)$rounded); // intentional float $result = (string)$fmt->format((float)$rounded); // intentional float
if (true === $coloured) { if (true === $coloured) {
if (1 === bccomp($rounded, '0')) { if (1 === bccomp($rounded, '0')) {
@@ -85,7 +85,7 @@ class Amount
public function formatByCurrencyId(int $currencyId, string $amount, ?bool $coloured = null): string public function formatByCurrencyId(int $currencyId, string $amount, ?bool $coloured = null): string
{ {
$format = TransactionCurrency::find($currencyId); $format = $this->getTransactionCurrencyById($currencyId);
return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured); return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured);
} }
@@ -115,6 +115,40 @@ class Amount
return (string)$amount; return (string)$amount;
} }
public function getTransactionCurrencyById(int $currencyId): TransactionCurrency
{
$instance = PreferencesSingleton::getInstance();
$key = sprintf('transaction_currency_%d', $currencyId);
/** @var TransactionCurrency|null $pref */
$pref = $instance->getPreference($key);
if (null !== $pref) {
return $pref;
}
$currency = TransactionCurrency::find($currencyId);
if (null === $currency) {
throw new FireflyException(sprintf('Could not find a transaction currency with ID #%d', $currencyId));
}
$instance->setPreference($key, $currency);
return $currency;
}
public function getTransactionCurrencyByCode(string $code): TransactionCurrency
{
$instance = PreferencesSingleton::getInstance();
$key = sprintf('transaction_currency_%s', $code);
/** @var TransactionCurrency|null $pref */
$pref = $instance->getPreference($key);
if (null !== $pref) {
return $pref;
}
$currency = TransactionCurrency::whereCode($code)->first();
if (null === $currency) {
throw new FireflyException(sprintf('Could not find a transaction currency with code "%s"', $code));
}
$instance->setPreference($key, $currency);
return $currency;
}
public function convertToPrimary(?User $user = null): bool public function convertToPrimary(?User $user = null): bool
{ {
$instance = PreferencesSingleton::getInstance(); $instance = PreferencesSingleton::getInstance();
@@ -129,8 +163,8 @@ class Amount
return $pref; return $pref;
} }
$key = sprintf('convert_to_primary_%d', $user->id); $key = sprintf('convert_to_primary_%d', $user->id);
$pref = $instance->getPreference($key); $pref = $instance->getPreference($key);
if (null === $pref) { if (null === $pref) {
$res = true === Preferences::getForUser($user, 'convert_to_primary', false)->data && true === config('cer.enabled'); $res = true === Preferences::getForUser($user, 'convert_to_primary', false)->data && true === config('cer.enabled');
$instance->setPreference($key, $res); $instance->setPreference($key, $res);
@@ -156,7 +190,7 @@ class Amount
public function getPrimaryCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency public function getPrimaryCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency
{ {
$cache = new CacheProperties(); $cache = new CacheProperties();
$cache->addProperty('getPrimaryCurrencyByGroup'); $cache->addProperty('getPrimaryCurrencyByGroup');
$cache->addProperty($userGroup->id); $cache->addProperty($userGroup->id);
if ($cache->has()) { if ($cache->has()) {
@@ -186,16 +220,16 @@ class Amount
*/ */
public function getAmountFromJournalObject(TransactionJournal $journal): string public function getAmountFromJournalObject(TransactionJournal $journal): string
{ {
$convertToPrimary = $this->convertToPrimary(); $convertToPrimary = $this->convertToPrimary();
$currency = $this->getPrimaryCurrency(); $currency = $this->getPrimaryCurrency();
$field = $convertToPrimary && $currency->id !== $journal->transaction_currency_id ? 'pc_amount' : 'amount'; $field = $convertToPrimary && $currency->id !== $journal->transaction_currency_id ? 'pc_amount' : 'amount';
/** @var null|Transaction $sourceTransaction */ /** @var null|Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first(); $sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $sourceTransaction) { if (null === $sourceTransaction) {
return '0'; return '0';
} }
$amount = $sourceTransaction->{$field} ?? '0'; $amount = $sourceTransaction->{$field} ?? '0';
if ((int)$sourceTransaction->foreign_currency_id === $currency->id) { if ((int)$sourceTransaction->foreign_currency_id === $currency->id) {
// use foreign amount instead! // use foreign amount instead!
$amount = (string)$sourceTransaction->foreign_amount; // hard coded to be foreign amount. $amount = (string)$sourceTransaction->foreign_amount; // hard coded to be foreign amount.
@@ -243,20 +277,20 @@ class Amount
private function getLocaleInfo(): array private function getLocaleInfo(): array
{ {
// get config from preference, not from translation: // get config from preference, not from translation:
$locale = Steam::getLocale(); $locale = Steam::getLocale();
$array = Steam::getLocaleArray($locale); $array = Steam::getLocaleArray($locale);
setlocale(LC_MONETARY, $array); setlocale(LC_MONETARY, $array);
$info = localeconv(); $info = localeconv();
// correct variables // correct variables
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes'); $info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
$info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes'); $info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
$info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space'); $info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
$info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space'); $info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY); $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
$info['mon_decimal_point'] = $fmt->getSymbol(NumberFormatter::MONETARY_SEPARATOR_SYMBOL); $info['mon_decimal_point'] = $fmt->getSymbol(NumberFormatter::MONETARY_SEPARATOR_SYMBOL);
$info['mon_thousands_sep'] = $fmt->getSymbol(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL); $info['mon_thousands_sep'] = $fmt->getSymbol(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL);
@@ -288,11 +322,11 @@ class Amount
// there are five possible positions for the "+" or "-" sign (if it is even used) // there are five possible positions for the "+" or "-" sign (if it is even used)
// pos_a and pos_e could be the ( and ) symbol. // pos_a and pos_e could be the ( and ) symbol.
$posA = ''; // before everything $posA = ''; // before everything
$posB = ''; // before currency symbol $posB = ''; // before currency symbol
$posC = ''; // after currency symbol $posC = ''; // after currency symbol
$posD = ''; // before amount $posD = ''; // before amount
$posE = ''; // after everything $posE = ''; // after everything
// format would be (currency before amount) // format would be (currency before amount)
// AB%sC_D%vE // AB%sC_D%vE
@@ -334,9 +368,9 @@ class Amount
} }
if ($csPrecedes) { if ($csPrecedes) {
return $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE; return $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE;
} }
return $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE; return $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE;
} }
} }

View File

@@ -26,7 +26,7 @@ namespace FireflyIII\Support;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Support\Facades\Amount;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -61,7 +61,7 @@ class Balance
foreach ($result as $entry) { foreach ($result as $entry) {
$accountId = (int) $entry->account_id; $accountId = (int) $entry->account_id;
$currencyId = (int) $entry->transaction_currency_id; $currencyId = (int) $entry->transaction_currency_id;
$currencies[$currencyId] ??= TransactionCurrency::find($currencyId); $currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId);
$return[$accountId] ??= []; $return[$accountId] ??= [];
if (array_key_exists($currencyId, $return[$accountId])) { if (array_key_exists($currencyId, $return[$accountId])) {
continue; continue;

View File

@@ -23,7 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Support\Binder; namespace FireflyIII\Support\Binder;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use Illuminate\Routing\Route; use Illuminate\Routing\Route;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -38,10 +40,12 @@ class CurrencyCode implements BinderInterface
public static function routeBinder(string $value, Route $route): TransactionCurrency public static function routeBinder(string $value, Route $route): TransactionCurrency
{ {
if (auth()->check()) { if (auth()->check()) {
$currency = TransactionCurrency::where('code', trim($value))->first(); try {
if (null !== $currency) { $currency = Amount::getTransactionCurrencyByCode(trim($value));
return $currency; } catch(FireflyException) {
throw new NotFoundHttpException();
} }
return $currency;
} }
throw new NotFoundHttpException(); throw new NotFoundHttpException();

View File

@@ -28,6 +28,7 @@ use Carbon\Carbon;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Navigation; use FireflyIII\Support\Facades\Navigation;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -184,7 +185,7 @@ class AccountBalanceGrouped
if (array_key_exists($currencyId, $this->currencies)) { if (array_key_exists($currencyId, $this->currencies)) {
return $this->currencies[$currencyId]; return $this->currencies[$currencyId];
} }
$this->currencies[$currencyId] = TransactionCurrency::find($currencyId); $this->currencies[$currencyId] = Amount::getTransactionCurrencyById($currencyId);
return $this->currencies[$currencyId]; return $this->currencies[$currencyId];
} }

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -264,7 +265,7 @@ class ExchangeRateConverter
if ($cache->has()) { if ($cache->has()) {
return (int) $cache->get(); return (int) $cache->get();
} }
$euro = TransactionCurrency::whereCode('EUR')->first(); $euro = Amount::getTransactionCurrencyByCode('EUR');
++$this->queryCount; ++$this->queryCount;
if (null === $euro) { if (null === $euro) {
throw new FireflyException('Cannot find EUR in system, cannot do currency conversion.'); throw new FireflyException('Cannot find EUR in system, cannot do currency conversion.');

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Support\Http\Api;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
class SummaryBalanceGrouped class SummaryBalanceGrouped
@@ -110,7 +111,7 @@ class SummaryBalanceGrouped
// transaction info: // transaction info:
$currencyId = (int) $journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$amount = bcmul((string) $journal['amount'], $multiplier); $amount = bcmul((string) $journal['amount'], $multiplier);
$currency = $this->currencies[$currencyId] ?? TransactionCurrency::find($currencyId); $currency = $this->currencies[$currencyId] ?? Amount::getTransactionCurrencyById($currencyId);
$this->currencies[$currencyId] = $currency; $this->currencies[$currencyId] = $currency;
$pcAmount = $converter->convert($currency, $this->default, $journal['date'], $amount); $pcAmount = $converter->convert($currency, $this->default, $journal['date'], $amount);
if ((int) $journal['foreign_currency_id'] === $this->default->id) { if ((int) $journal['foreign_currency_id'] === $this->default->id) {

View File

@@ -38,8 +38,8 @@ use Illuminate\Support\Facades\Log;
*/ */
trait ValidatesUserGroupTrait trait ValidatesUserGroupTrait
{ {
protected ?UserGroup $userGroup = null; protected UserGroup $userGroup;
protected ?User $user = null; protected User $user;
/** /**
* An "undocumented" filter * An "undocumented" filter

View File

@@ -142,7 +142,7 @@ class PiggyBankEnrichment implements EnrichmentInterface
$accountId = (int)$item->account_id; $accountId = (int)$item->account_id;
$currencyId = (int)$item->data; $currencyId = (int)$item->data;
if (!array_key_exists($currencyId, $this->currencies)) { if (!array_key_exists($currencyId, $this->currencies)) {
$this->currencies[$currencyId] = TransactionCurrency::find($currencyId); $this->currencies[$currencyId] = Amount::getTransactionCurrencyById($currencyId);
} }
// $this->accountCurrencies[$accountId] = $this->currencies[$currencyId]; // $this->accountCurrencies[$accountId] = $this->currencies[$currencyId];
} }

View File

@@ -121,7 +121,7 @@ class PiggyBankEventEnrichment implements EnrichmentInterface
$accountId = (int)$item->account_id; $accountId = (int)$item->account_id;
$currencyId = (int)$item->data; $currencyId = (int)$item->data;
if (!array_key_exists($currencyId, $this->currencies)) { if (!array_key_exists($currencyId, $this->currencies)) {
$this->currencies[$currencyId] = TransactionCurrency::find($currencyId); $this->currencies[$currencyId] = Amount::getTransactionCurrencyById($currencyId);
} }
$this->accountCurrencies[$accountId] = $this->currencies[$currencyId]; $this->accountCurrencies[$accountId] = $this->currencies[$currencyId];
} }

View File

@@ -321,7 +321,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
if ($this->convertToPrimary && null !== $entry->foreign_currency_id && (int)$entry->foreign_currency_id !== $this->primaryCurrency->id) { if ($this->convertToPrimary && null !== $entry->foreign_currency_id && (int)$entry->foreign_currency_id !== $this->primaryCurrency->id) {
// TODO this is very database intensive. // TODO this is very database intensive.
/** @var TransactionCurrency $foreignCurrency */ /** @var TransactionCurrency $foreignCurrency */
$foreignCurrency = TransactionCurrency::find($entry->foreign_currency_id); $foreignCurrency = Amount::getTransactionCurrencyById($entry->foreign_currency_id);
$array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, $entry->amount); $array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
} }
$result[] = $array; $result[] = $array;

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\AccountBalance;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Facades\Amount;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -171,7 +172,7 @@ class AccountBalanceCalculator
*/ */
foreach ($currencies as $currencyId => $balance) { foreach ($currencies as $currencyId => $balance) {
/** @var null|TransactionCurrency $currency */ /** @var null|TransactionCurrency $currency */
$currency = TransactionCurrency::find($currencyId); $currency = Amount::getTransactionCurrencyById($currencyId);
if (null === $currency) { if (null === $currency) {
Log::error(sprintf('Could not find currency #%d, will not save account balance.', $currencyId)); Log::error(sprintf('Could not find currency #%d, will not save account balance.', $currencyId));

View File

@@ -285,7 +285,7 @@ class Steam
$sumOfDay = $this->floatalize($sumOfDay); $sumOfDay = $this->floatalize($sumOfDay);
// find currency of this entry, does not have to exist. // find currency of this entry, does not have to exist.
$currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); $currencies[$entry->transaction_currency_id] ??= Amount::getTransactionCurrencyById($entry->transaction_currency_id);
// make sure this $entry has its own $entryCurrency // make sure this $entry has its own $entryCurrency
/** @var TransactionCurrency $entryCurrency */ /** @var TransactionCurrency $entryCurrency */
@@ -502,7 +502,7 @@ class Steam
return null; return null;
} }
return TransactionCurrency::find((int)$result->data); return Amount::getTransactionCurrencyById((int)$result->data);
} }
private function groupAndSumTransactions(array $array, string $group, string $field): array private function groupAndSumTransactions(array $array, string $group, string $field): array
@@ -524,7 +524,7 @@ class Steam
$singleton = PreferencesSingleton::getInstance(); $singleton = PreferencesSingleton::getInstance();
foreach ($others as $key => $amount) { foreach ($others as $key => $amount) {
$preference = $singleton->getPreference($key); $preference = $singleton->getPreference($key);
$currency = $preference ?? TransactionCurrency::where('code', $key)->first(); $currency = $preference ?? Amount::getTransactionCurrencyByCode($key);
if (null === $currency) { if (null === $currency) {
continue; continue;
} }

View File

@@ -162,9 +162,9 @@ class AmountFormat extends AbstractExtension
static function (string $amount, string $code, ?bool $coloured = null): string { static function (string $amount, string $code, ?bool $coloured = null): string {
$coloured ??= true; $coloured ??= true;
/** @var null|TransactionCurrency $currency */ try {
$currency = TransactionCurrency::whereCode($code)->first(); $currency = Amount::getTransactionCurrencyByCode($code);
if (null === $currency) { } catch(FireflyException) {
Log::error(sprintf('Could not find currency with code "%s". Fallback to primary currency.', $code)); Log::error(sprintf('Could not find currency with code "%s". Fallback to primary currency.', $code));
$currency = Amount::getPrimaryCurrency(); $currency = Amount::getPrimaryCurrency();
Log::error(sprintf('Fallback currency is "%s".', $currency->code)); Log::error(sprintf('Fallback currency is "%s".', $currency->code));

View File

@@ -99,7 +99,7 @@ class General extends AbstractExtension
} }
// for multi currency accounts. // for multi currency accounts.
if ($usePrimary && $key !== $primary->code) { if ($usePrimary && $key !== $primary->code) {
$strings[] = app('amount')->formatAnything(TransactionCurrency::where('code', $key)->first(), $balance, false); $strings[] = app('amount')->formatAnything(Amount::getTransactionCurrencyByCode($key), $balance, false);
} }
} }