Compare commits

..

7 Commits

Author SHA1 Message Date
github-actions
f909f1d9ff Auto commit for release 'develop' on 2025-02-09 2025-02-09 06:14:15 +01:00
James Cole
55018ca046 Remove duplicate copyright statement. 2025-02-09 06:10:46 +01:00
github-actions
19c746a865 Auto commit for release 'v6.2.5' on 2025-02-09 2025-02-09 06:08:12 +01:00
James Cole
503d2aa786 Rename class to stop phpunit complaining. 2025-02-09 05:57:47 +01:00
James Cole
70d83ab501 Fix #9784 2025-02-09 05:52:18 +01:00
James Cole
edab602bb7 Fix #9784 2025-02-09 05:26:37 +01:00
James Cole
f9bcc4b1fa Extra code for #9747 2025-02-08 10:51:52 +01:00
21 changed files with 442 additions and 328 deletions

View File

@@ -104,15 +104,20 @@ class AccountController extends Controller
}
$return[] = [
'id' => (string) $account->id,
'name' => $account->name,
'name_with_balance' => $nameWithBalance,
'type' => $account->accountType->type,
'currency_id' => (string) $useCurrency->id,
'currency_name' => $useCurrency->name,
'currency_code' => $useCurrency->code,
'currency_symbol' => $useCurrency->symbol,
'currency_decimal_places' => $useCurrency->decimal_places,
'id' => (string) $account->id,
'name' => $account->name,
'name_with_balance' => $nameWithBalance,
'type' => $account->accountType->type,
'currency_id' => (string) $useCurrency->id,
'currency_name' => $useCurrency->name,
'currency_code' => $useCurrency->code,
'currency_symbol' => $useCurrency->symbol,
'currency_decimal_places' => $useCurrency->decimal_places,
'account_currency_id' => (string) $currency->id,
'account_currency_name' => $currency->name,
'account_currency_code' => $currency->code,
'account_currency_symbol' => $currency->symbol,
'account_currency_decimal_places' => $currency->decimal_places,
];
}

View File

@@ -21,25 +21,6 @@
*/
declare(strict_types=1);
/*
* ConvertDatesToUTC.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
namespace FireflyIII\Console\Commands\Correction;

View File

@@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Models\AutoBudget;
use FireflyIII\Models\AvailableBudget;
use FireflyIII\Models\Bill;
@@ -33,8 +34,14 @@ use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class CorrectsAmounts extends Command
{
@@ -45,6 +52,8 @@ class CorrectsAmounts extends Command
public function handle(): int
{
// transfers must not have foreign currency info if both accounts have the same currency.
$this->correctTransfers();
// auto budgets must be positive
$this->fixAutoBudgets();
// available budgets must be positive
@@ -62,6 +71,7 @@ class CorrectsAmounts extends Command
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
$this->fixRuleTriggers();
return 0;
}
@@ -182,4 +192,63 @@ class CorrectsAmounts extends Command
return false;
}
private function correctTransfers(): void
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$type = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first();
$journals = TransactionJournal::where('transaction_type_id', $type->id)->get();
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$repository->setUser($journal->user);
$native = Amount::getNativeCurrencyByUserGroup($journal->userGroup);
/** @var null|Transaction $source */
$source = $journal->transactions()->where('amount', '<', 0)->first();
/** @var null|Transaction $destination */
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $source || null === $destination) {
continue;
}
if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) {
continue;
}
$sourceAccount = $source->account;
$destAccount = $destination->account;
if (null === $sourceAccount || null === $destAccount) {
continue;
}
$sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $native;
$destCurrency = $repository->getAccountCurrency($destAccount) ?? $native;
if ($sourceCurrency->id === $destCurrency->id) {
Log::debug('Both accounts have the same currency. Removing foreign currency info.');
$source->foreign_currency_id = null;
$source->foreign_amount = null;
$source->save();
$destination->foreign_currency_id = null;
$destination->foreign_amount = null;
$destination->save();
continue;
}
// validate source
if ($destCurrency->id !== $source->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code));
$source->foreign_currency_id = $destCurrency->id;
$source->save();
}
// validate destination:
if ($sourceCurrency->id !== $destination->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code));
$destination->foreign_currency_id = $sourceCurrency->id;
$destination->save();
}
}
}
}

View File

@@ -21,25 +21,6 @@
*/
declare(strict_types=1);
/*
* AddTimezonesToDates.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
namespace FireflyIII\Console\Commands\Correction;

View File

@@ -335,7 +335,7 @@ class AccountController extends Controller
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
$defaultSet = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
Log::debug('Default set is ', $defaultSet);
// Log::debug('Default set is ', $defaultSet);
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
$frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data;
Log::debug('Frontpage preference set is ', $frontpageArray);

View File

@@ -112,6 +112,11 @@ class TransactionJournal extends Model
return $this->belongsTo(User::class);
}
public function userGroup(): BelongsTo
{
return $this->belongsTo(UserGroup::class);
}
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');

View File

@@ -88,6 +88,11 @@ class ExchangeRateConverter
return '1';
}
if ($from->id === $to->id) {
Log::debug('ExchangeRateConverter: From and to are the same, return "1".');
return '1';
}
$rate = $this->getRate($from, $to, $date);
return '0' === $rate ? '1' : $rate;
@@ -103,7 +108,7 @@ class ExchangeRateConverter
// find in cache
if (null !== $res) {
Log::debug(sprintf('ExchangeRateConverter: Return cached rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
Log::debug(sprintf('ExchangeRateConverter: Return cached rate from %s to %s on %s.', $from->code, $to->code, $date->format('Y-m-d')));
return $res;
}
@@ -112,7 +117,7 @@ class ExchangeRateConverter
$rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d'));
if (null !== $rate) {
Cache::forever($key, $rate);
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from %s to %s on %s.', $from->code, $to->code, $date->format('Y-m-d')));
return $rate;
}
@@ -122,7 +127,7 @@ class ExchangeRateConverter
if (null !== $rate) {
$rate = bcdiv('1', $rate);
Cache::forever($key, $rate);
Log::debug(sprintf('ExchangeRateConverter: Return inverse DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
Log::debug(sprintf('ExchangeRateConverter: Return inverse DB rate from %s to %s on %s.', $from->code, $to->code, $date->format('Y-m-d')));
return $rate;
}
@@ -133,14 +138,14 @@ class ExchangeRateConverter
// combined (if present), they can be used to calculate the necessary conversion rate.
if (0 === bccomp('0', $first) || 0 === bccomp('0', $second)) {
Log::warning(sprintf('$first is "%s" and $second is "%s"', $first, $second));
Log::warning(sprintf('There is not enough information to convert %s to %s on date %s', $from->code, $to->code, $date->format('Y-m-d')));
return '1';
}
$second = bcdiv('1', $second);
$rate = bcmul($first, $second);
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from %s to %s on %s.', $from->code, $to->code, $date->format('Y-m-d')));
Cache::forever($key, $rate);
return $rate;
@@ -154,6 +159,8 @@ class ExchangeRateConverter
private function getFromDB(int $from, int $to, string $date): ?string
{
if ($from === $to) {
Log::debug('ExchangeRateConverter: From and to are the same, return "1".');
return '1';
}
$key = sprintf('cer-%d-%d-%s', $from, $to, $date);
@@ -173,7 +180,7 @@ class ExchangeRateConverter
if ('' === $rate) {
return null;
}
Log::debug(sprintf('ExchangeRateConverter: Found !cached! rate from #%d to #%d on %s.', $from, $to, $date));
Log::debug(sprintf('ExchangeRateConverter: Found cached rate from #%d to #%d on %s.', $from, $to, $date));
return $rate;
}

View File

@@ -58,7 +58,7 @@ trait ChartGeneration
if ($cache->has()) {
return $cache->get();
}
app('log')->debug('Regenerate chart.account.account-balance-chart from scratch.');
Log::debug('Regenerate chart.account.account-balance-chart from scratch.');
$locale = app('steam')->getLocale();
/** @var GeneratorInterface $generator */
@@ -88,6 +88,7 @@ trait ChartGeneration
$currentStart = clone $start;
$range = Steam::finalAccountBalanceInRange($account, clone $start, clone $end, $this->convertToNative);
$previous = array_values($range)[0];
Log::debug(sprintf('Start balance for account #%d ("%s) is', $account->id, $account->name), $previous);
while ($currentStart <= $end) {
$format = $currentStart->format('Y-m-d');
$label = trim($currentStart->isoFormat((string) trans('config.month_and_day_js', [], $locale)));

View File

@@ -59,8 +59,8 @@ class Steam
public function finalAccountBalanceInRange(Account $account, Carbon $start, Carbon $end, bool $convertToNative): array
{
// expand period.
$start->subDay()->endOfDay(); // go to END of day to get the balance at the END of the day.
$end->addDay()->startOfDay(); // go to START of day to get the balance at the END of the previous day (see ahead).
$start->startOfDay();
$end->endOfDay();
Log::debug(sprintf('finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
// set up cache
@@ -82,6 +82,7 @@ class Steam
$currency = $accountCurrency ?? $nativeCurrency;
Log::debug(sprintf('Currency is %s', $currency->code));
// set start balances:
$startBalance[$currency->code] ??= '0';
if ($hasCurrency) {
@@ -100,10 +101,11 @@ class Steam
Log::debug('Final start balance: ', $startBalance);
// sums up the balance changes per day.
Log::debug(sprintf('Date >= %s and <= %s', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
$set = $account->transactions()
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transaction_journals.date', '>', $start->format('Y-m-d H:i:s'))
->where('transaction_journals.date', '<', $end->format('Y-m-d H:i:s'))
->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s'))
->groupBy('transaction_journals.date')
->groupBy('transactions.transaction_currency_id')
->orderBy('transaction_journals.date', 'ASC')

View File

@@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- [Discussion 9780](https://github.com/orgs/firefly-iii/discussions/9780) (Rules or webhook precedence?) started by @joeshmoe57
- [Issue 9781](https://github.com/firefly-iii/firefly-iii/issues/9781) (Search key `has_any_external_url:false` returns all transactions) reported by @joeshmoe57
- [Issue 9783](https://github.com/firefly-iii/firefly-iii/issues/9783) (Subscriptions: Make "Not expected this period" and "expected x days from now" different colors) reported by @SteffoSpieler
- [Issue 9784](https://github.com/firefly-iii/firefly-iii/issues/9784) (Transfers with external currency not considered for account balance?) reported by @pvieira84
- [Issue 9786](https://github.com/firefly-iii/firefly-iii/issues/9786) (The error 500 information page has non-clickable links to github and the debug page) reported by @tjmv
- [Issue 9787](https://github.com/firefly-iii/firefly-iii/issues/9787) (Twig general template error formatting TransactionCurrency on main page) reported by @tjmv
- [Issue 9789](https://github.com/firefly-iii/firefly-iii/issues/9789) (Can't open expense and revenue accounts view) reported by @puffer-duck

View File

@@ -81,7 +81,7 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2025-02-08',
'version' => 'develop/2025-02-09',
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 25,

142
package-lock.json generated
View File

@@ -79,9 +79,9 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
"integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
"integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -89,22 +89,23 @@
}
},
"node_modules/@babel/core": {
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz",
"integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz",
"integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.5",
"@babel/generator": "^7.26.8",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-module-transforms": "^7.26.0",
"@babel/helpers": "^7.26.7",
"@babel/parser": "^7.26.7",
"@babel/template": "^7.25.9",
"@babel/traverse": "^7.26.7",
"@babel/types": "^7.26.7",
"@babel/parser": "^7.26.8",
"@babel/template": "^7.26.8",
"@babel/traverse": "^7.26.8",
"@babel/types": "^7.26.8",
"@types/gensync": "^1.0.0",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -130,14 +131,14 @@
}
},
"node_modules/@babel/generator": {
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
"integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz",
"integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.26.5",
"@babel/types": "^7.26.5",
"@babel/parser": "^7.26.8",
"@babel/types": "^7.26.8",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -442,13 +443,13 @@
}
},
"node_modules/@babel/parser": {
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
"integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz",
"integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.26.7"
"@babel/types": "^7.26.8"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -667,15 +668,15 @@
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz",
"integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
"integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/helper-plugin-utils": "^7.26.5",
"@babel/helper-remap-async-to-generator": "^7.25.9",
"@babel/traverse": "^7.25.9"
"@babel/traverse": "^7.26.8"
},
"engines": {
"node": ">=6.9.0"
@@ -1340,14 +1341,14 @@
}
},
"node_modules/@babel/plugin-transform-runtime": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz",
"integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.8.tgz",
"integrity": "sha512-H0jlQxFMI0Q8SyGPsj9pO3ygVQRxPkIGytsL3m1Zqca8KrCPpMlvh+e2dxknqdfS8LFwBw+PpiYPD9qy/FPQpA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/helper-plugin-utils": "^7.26.5",
"babel-plugin-polyfill-corejs2": "^0.4.10",
"babel-plugin-polyfill-corejs3": "^0.10.6",
"babel-plugin-polyfill-regenerator": "^0.6.1",
@@ -1420,13 +1421,13 @@
}
},
"node_modules/@babel/plugin-transform-template-literals": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
"integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz",
"integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
"@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1519,13 +1520,13 @@
}
},
"node_modules/@babel/preset-env": {
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.7.tgz",
"integrity": "sha512-Ycg2tnXwixaXOVb29rana8HNPgLVBof8qqtNQ9LE22IoyZboQbGSxI6ZySMdW3K5nAe6gu35IaJefUJflhUFTQ==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.8.tgz",
"integrity": "sha512-um7Sy+2THd697S4zJEfv/U5MHGJzkN2xhtsR3T/SWRbVSic62nbISh51VVfU9JiO/L/Z97QczHTaFVkOU8IzNg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.26.5",
"@babel/compat-data": "^7.26.8",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-plugin-utils": "^7.26.5",
"@babel/helper-validator-option": "^7.25.9",
@@ -1539,7 +1540,7 @@
"@babel/plugin-syntax-import-attributes": "^7.26.0",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
"@babel/plugin-transform-arrow-functions": "^7.25.9",
"@babel/plugin-transform-async-generator-functions": "^7.25.9",
"@babel/plugin-transform-async-generator-functions": "^7.26.8",
"@babel/plugin-transform-async-to-generator": "^7.25.9",
"@babel/plugin-transform-block-scoped-functions": "^7.26.5",
"@babel/plugin-transform-block-scoping": "^7.25.9",
@@ -1582,7 +1583,7 @@
"@babel/plugin-transform-shorthand-properties": "^7.25.9",
"@babel/plugin-transform-spread": "^7.25.9",
"@babel/plugin-transform-sticky-regex": "^7.25.9",
"@babel/plugin-transform-template-literals": "^7.25.9",
"@babel/plugin-transform-template-literals": "^7.26.8",
"@babel/plugin-transform-typeof-symbol": "^7.26.7",
"@babel/plugin-transform-unicode-escapes": "^7.25.9",
"@babel/plugin-transform-unicode-property-regex": "^7.25.9",
@@ -1590,9 +1591,9 @@
"@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
"@babel/preset-modules": "0.1.6-no-external-plugins",
"babel-plugin-polyfill-corejs2": "^0.4.10",
"babel-plugin-polyfill-corejs3": "^0.10.6",
"babel-plugin-polyfill-corejs3": "^0.11.0",
"babel-plugin-polyfill-regenerator": "^0.6.1",
"core-js-compat": "^3.38.1",
"core-js-compat": "^3.40.0",
"semver": "^6.3.1"
},
"engines": {
@@ -1602,6 +1603,20 @@
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
"integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-define-polyfill-provider": "^0.6.3",
"core-js-compat": "^3.40.0"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/@babel/preset-env/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -1640,32 +1655,32 @@
}
},
"node_modules/@babel/template": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
"integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz",
"integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/types": "^7.25.9"
"@babel/code-frame": "^7.26.2",
"@babel/parser": "^7.26.8",
"@babel/types": "^7.26.8"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz",
"integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz",
"integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.26.2",
"@babel/generator": "^7.26.5",
"@babel/parser": "^7.26.7",
"@babel/template": "^7.25.9",
"@babel/types": "^7.26.7",
"@babel/generator": "^7.26.8",
"@babel/parser": "^7.26.8",
"@babel/template": "^7.26.8",
"@babel/types": "^7.26.8",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1674,9 +1689,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.26.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
"integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
"version": "7.26.8",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz",
"integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3032,6 +3047,13 @@
"@types/send": "*"
}
},
"node_modules/@types/gensync": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz",
"integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
@@ -4448,9 +4470,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001698",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001698.tgz",
"integrity": "sha512-xJ3km2oiG/MbNU8G6zIq6XRZ6HtAOVXsbOrP/blGazi52kc5Yy7b6sDA5O+FbROzRrV7BSTllLHuNvmawYUJjw==",
"version": "1.0.30001699",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
"integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==",
"dev": true,
"funding": [
{

View File

@@ -381,7 +381,7 @@ export default {
this.totalPages = parseInt(response.data.meta.pagination.total_pages);
this.loading = false;
this.rates = Object.values(this.tempRates);
console.log('Do not download more pages. Now on page ' + this.page + ' of ' + this.totalPages);
// console.log('Do not download more pages. Now on page ' + this.page + ' of ' + this.totalPages);
});
}
},

View File

@@ -36,7 +36,6 @@
class="form-control"
data-role="input"
type="text"
v-on:keypress="handleEnter"
v-on:submit.prevent>
<span class="input-group-btn">
<button
@@ -217,7 +216,7 @@ export default {
}
},
selectedItem: function (e) {
// console.log('In SelectedItem()');
console.log('In SelectedItem()');
if (typeof this.name === 'undefined') {
// console.log('Is undefined');
return;
@@ -239,12 +238,6 @@ export default {
this.name = '';
// some event?
this.$emit('clear:value')
},
handleEnter: function (e) {
// TODO feels sloppy. Can be removed.
if (e.keyCode === 13) {
//e.preventDefault();
}
}
}
}

View File

@@ -922,6 +922,12 @@ export default {
allowed_types: this.transactions[index].source_account.allowed_types,
default_allowed_types: ['Asset account', 'Revenue account', 'Loan', 'Debt', 'Mortgage']
};
if(model.hasOwnProperty('account_currency_id') && null !== model.account_currency_id) {
this.transactions[index].source_account.currency_id = model.account_currency_id;
this.transactions[index].source_account.currency_name = model.account_currency_name;
this.transactions[index].source_account.currency_code = model.account_currency_code;
this.transactions[index].source_account.currency_decimal_places = model.account_currency_decimal_places;
}
// force types on destination selector.
this.transactions[index].destination_account.allowed_types = window.allowedOpposingTypes.source[model.type];
@@ -946,6 +952,12 @@ export default {
allowed_types: this.transactions[index].destination_account.allowed_types,
default_allowed_types: ['Asset account', 'Expense account', 'Loan', 'Debt', 'Mortgage']
};
if(model.hasOwnProperty('account_currency_id') && null !== model.account_currency_id) {
this.transactions[index].destination_account.currency_id = model.account_currency_id;
this.transactions[index].destination_account.currency_name = model.account_currency_name;
this.transactions[index].destination_account.currency_code = model.account_currency_code;
this.transactions[index].destination_account.currency_decimal_places = model.account_currency_decimal_places;
}
// force types on destination selector.
this.transactions[index].source_account.allowed_types = window.allowedOpposingTypes.destination[model.type];

View File

@@ -155,8 +155,8 @@
v-bind:title="$t('form.foreign_amount')"
></foreign-amount>
<reconciled v-show="isReconciled"
v-model="transaction.reconciled"
:error="transaction.errors.reconciled"
v-model="transaction.reconciled"
:error="transaction.errors.reconciled"
></reconciled>
</div>
<div class="col-lg-4">
@@ -322,6 +322,12 @@ export default {
currency_decimal_places: model.currency_decimal_places,
allowed_types: this.transactions[index].source_account.allowed_types
};
if(model.hasOwnProperty('account_currency_id') && null !== model.account_currency_id) {
this.transactions[index].source_account.currency_id = model.account_currency_id;
this.transactions[index].source_account.currency_name = model.account_currency_name;
this.transactions[index].source_account.currency_code = model.account_currency_code;
this.transactions[index].source_account.currency_decimal_places = model.account_currency_decimal_places;
}
},
selectedDestinationAccount(index, model) {
if (typeof model === 'string') {
@@ -341,6 +347,12 @@ export default {
currency_decimal_places: model.currency_decimal_places,
allowed_types: this.transactions[index].destination_account.allowed_types
};
if(model.hasOwnProperty('account_currency_id') && null !== model.account_currency_id) {
this.transactions[index].destination_account.currency_id = model.account_currency_id;
this.transactions[index].destination_account.currency_name = model.account_currency_name;
this.transactions[index].destination_account.currency_code = model.account_currency_code;
this.transactions[index].destination_account.currency_decimal_places = model.account_currency_decimal_places;
}
},
clearSource(index) {
// reset source account:
@@ -437,7 +449,7 @@ export default {
//console.log('EditTransaction: processIncomingGroupRow()');
this.setTransactionType(transaction.type);
if(true === transaction.reconciled) {
if (true === transaction.reconciled) {
this.isReconciled = true;
}
@@ -528,7 +540,16 @@ export default {
allowed_types: window.expectedSourceTypes.destination[this.ucFirst(transaction.type)]
}
};
if(null === transaction.foreign_amount) {
// if transaction type is transfer, the destination currency_id etc. MUST match the actual account currency info.
if ('transfer' === transaction.type && null !== transaction.foreign_currency_code) {
result.destination_account.currency_id = transaction.foreign_currency_id;
result.destination_account.currency_name = transaction.foreign_currency_name;
result.destination_account.currency_code = transaction.foreign_currency_code;
result.destination_account.currency_decimal_places = transaction.foreign_currency_decimal_places;
}
if (null === transaction.foreign_amount) {
result.foreign_amount.amount = '';
}
this.transactions.push(result);
@@ -736,7 +757,7 @@ export default {
if (parseInt(row.piggy_bank) > 0) {
currentArray.piggy_bank_id = parseInt(row.piggy_bank);
}
if(this.isReconciled && !this.storeAsNew && true === row.reconciled) {
if (this.isReconciled && !this.storeAsNew && true === row.reconciled) {
// drop content from array:
delete currentArray.source_id;
delete currentArray.source_name;
@@ -748,7 +769,7 @@ export default {
delete currentArray.currency_id;
currentArray.reconciled = true;
}
if(true === row.isReconciled) {
if (true === row.isReconciled) {
this.isReconciled = false;
}
@@ -801,10 +822,16 @@ export default {
this.setDefaultErrors();
// do message if update or new:
if (this.storeAsNew) {
this.success_message = this.$t('firefly.transaction_new_stored_link', {ID: groupId, title: this.escapeHtml(title)});
this.success_message = this.$t('firefly.transaction_new_stored_link', {
ID: groupId,
title: this.escapeHtml(title)
});
this.error_message = '';
} else {
this.success_message = this.$t('firefly.transaction_updated_link', {ID: groupId, title: this.escapeHtml(title)});
this.success_message = this.$t('firefly.transaction_updated_link', {
ID: groupId,
title: this.escapeHtml(title)
});
this.error_message = '';
}
} else {

View File

@@ -19,205 +19,213 @@
-->
<template>
<!--
Show if:
- one or more currencies.
-->
<div v-if="this.enabledCurrencies.length >= 1" class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-8 col-sm-offset-4 text-sm">
{{ $t('form.foreign_amount') }}
</div>
<div class="col-sm-4">
<select ref="currency_select" class="form-control" name="foreign_currency[]" @input="handleInput">
<option
v-for="currency in this.enabledCurrencies"
:label="currency.attributes.name"
:selected="parseInt(value.currency_id) === parseInt(currency.id)"
:value="currency.id"
<!--
Show if:
- one or more currencies.
-->
<div v-if="this.enabledCurrencies.length >= 1" class="form-group" v-bind:class="{ 'has-error': hasError()}">
<div class="col-sm-8 col-sm-offset-4 text-sm">
{{ $t('form.foreign_amount') }}
</div>
<div class="col-sm-4">
<select ref="currency_select" class="form-control" name="foreign_currency[]" @input="handleInput">
<option
v-for="currency in this.enabledCurrencies"
:label="currency.attributes.name"
:selected="parseInt(value.currency_id) === parseInt(currency.id)"
:value="currency.id"
>
{{ currency.attributes.name }}
</option>
</select>
</div>
<div class="col-sm-8">
<div class="input-group">
<input v-if="this.enabledCurrencies.length > 0" ref="amount" :placeholder="this.title" :title="this.title" :value="value.amount" autocomplete="off"
class="form-control" name="foreign_amount[]"
step="any" type="number" @input="handleInput">
<span class="input-group-btn">
>
{{ currency.attributes.name }}
</option>
</select>
</div>
<div class="col-sm-8">
<div class="input-group">
<input v-if="this.enabledCurrencies.length > 0" ref="amount" :placeholder="this.title"
:title="this.title" :value="value.amount" autocomplete="off"
class="form-control" name="foreign_amount[]"
step="any" type="number" @input="handleInput">
<span class="input-group-btn">
<button
class="btn btn-default"
tabIndex="-1"
type="button"
v-on:click="clearAmount"><i class="fa fa-trash-o"></i></button>
</span>
</div>
<ul v-for="error in this.error" class="list-unstyled">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
<ul v-for="error in this.error" class="list-unstyled">
<li class="text-danger">{{ error }}</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ForeignAmountSelect",
name: "ForeignAmountSelect",
props: ['source', 'destination', 'transactionType', 'value', 'error', 'no_currency', 'title',],
mounted() {
this.liability = false;
this.loadCurrencies();
props: ['source', 'destination', 'transactionType', 'value', 'error', 'no_currency', 'title',],
mounted() {
this.liability = false;
// console.log('I am mounted with a ' + this.transactionType + ' transaction type and currency id!');
// console.log(this.value);
this.loadCurrencies();
},
data() {
return {
currencies: [],
enabledCurrencies: [],
exclude: null,
// liability overrules the drop-down list if the source or dest is a liability
liability: false
}
},
watch: {
source: function () {
// console.log('ForeignAmountSelect watch source');
this.changeData();
},
destination: function () {
// console.log('ForeignAmountSelect watch destination');
this.changeData();
},
transactionType: function () {
// console.log('ForeignAmountSelect watch transaction type (is now ' + this.transactionType + ')');
this.changeData();
}
},
methods: {
clearAmount: function () {
this.$refs.amount.value = '';
this.$emit('input', this.$refs.amount.value);
// some event?
this.$emit('clear:amount')
},
hasError: function () {
//console.log('ForeignAmountSelect hasError');
return this.error.length > 0;
},
handleInput(e) {
// console.log('ForeignAmountSelect handleInput');
let obj = {
amount: this.$refs.amount.value,
currency_id: this.$refs.currency_select.value,
};
// console.log(obj);
this.$emit('input', obj
);
},
changeData: function () {
// console.log('ForeignAmountSelect changeData');
this.enabledCurrencies = [];
let destType = this.destination.type ? this.destination.type.toLowerCase() : 'invalid';
let srcType = this.source.type ? this.source.type.toLowerCase() : 'invalid';
let tType = this.transactionType ? this.transactionType.toLowerCase() : 'invalid';
let liabilities = ['loan', 'debt', 'mortgage'];
let sourceIsLiability = liabilities.indexOf(srcType) !== -1;
let destIsLiability = liabilities.indexOf(destType) !== -1;
},
data() {
return {
currencies: [],
enabledCurrencies: [],
exclude: null,
// liability overrules the drop down list if the source or dest is a liability
liability: false
// console.log(srcType + ' (source) is a liability: ' + sourceIsLiability);
// console.log(destType + ' (dest) is a liability: ' + destIsLiability);
// console.log('tType: ' + tType);
if (tType === 'transfer' || destIsLiability || sourceIsLiability) {
// console.log('Source is liability OR dest is liability, OR transfer. Lock list on currency of destination.');
// console.log('Length of currencies is ' + this.currencies.length);
// console.log(this.currencies);
this.liability = true;
// lock dropdown list on currencyID of destination.
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (
parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id)
) {
// console.log('Enable currency!!');
// console.log(this.destination);
// console.log(this.currencies[key]);
this.enabledCurrencies.push(this.currencies[key]);
}
}
}
// console.log('Enabled currencies length is now ' + this.enabledCurrencies.length);
return;
}
// if type is withdrawal, list all but skip the source account ID.
if (tType === 'withdrawal' && this.source && false === sourceIsLiability) {
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (this.source.currency_id !== this.currencies[key].id) {
this.enabledCurrencies.push(this.currencies[key]);
}
}
}
return;
}
// if type is deposit, list all but skip the source account ID.
if (tType === 'deposit' && this.destination) {
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (this.destination.currency_id !== this.currencies[key].id) {
this.enabledCurrencies.push(this.currencies[key]);
}
}
}
return;
}
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
this.enabledCurrencies.push(this.currencies[key]);
}
}
},
loadCurrencies: function () {
// console.log('loadCurrencies');
// reset list of currencies:
this.currencies = [
{
id: 0,
attributes: {
name: this.no_currency,
enabled: true
},
}
];
this.enabledCurrencies = [
{
attributes: {
name: this.no_currency,
enabled: true
},
id: 0,
}
];
this.getCurrencies(1);
},
getCurrencies: function (page) {
let url = document.getElementsByTagName('base')[0].href + "api/v1/currencies?page=" + page;
axios.get(url, {}).then((res) => {
for (const key in res.data.data) {
if (res.data.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (res.data.data[key].attributes.enabled) {
// console.log(res.data.data[key].attributes);
this.currencies.push(res.data.data[key]);
this.enabledCurrencies.push(res.data.data[key]);
}
}
}
if (res.data.meta.pagination.current_page < res.data.meta.pagination.total_pages) {
this.getCurrencies(res.data.meta.pagination.current_page + 1);
return;
}
this.changeData();
});
}
}
},
watch: {
source: function () {
//console.log('ForeignAmountSelect watch source');
this.changeData();
},
destination: function () {
//console.log('ForeignAmountSelect watch destination');
this.changeData();
},
transactionType: function () {
//console.log('ForeignAmountSelect watch transaction type (is now ' + this.transactionType + ')');
this.changeData();
}
},
methods: {
clearAmount: function () {
this.$refs.amount.value = '';
this.$emit('input', this.$refs.amount.value);
// some event?
this.$emit('clear:amount')
},
hasError: function () {
//console.log('ForeignAmountSelect hasError');
return this.error.length > 0;
},
handleInput(e) {
//console.log('ForeignAmountSelect handleInput');
let obj = {
amount: this.$refs.amount.value,
currency_id: this.$refs.currency_select.value,
};
// console.log(obj);
this.$emit('input', obj
);
},
changeData: function () {
// console.log('ForeignAmountSelect changeData');
this.enabledCurrencies = [];
let destType = this.destination.type ? this.destination.type.toLowerCase() : 'invalid';
let srcType = this.source.type ? this.source.type.toLowerCase() : 'invalid';
let tType = this.transactionType ? this.transactionType.toLowerCase() : 'invalid';
let liabilities = ['loan', 'debt', 'mortgage'];
let sourceIsLiability = liabilities.indexOf(srcType) !== -1;
let destIsLiability = liabilities.indexOf(destType) !== -1;
// console.log(srcType + ' (source) is a liability: ' + sourceIsLiability);
// console.log(destType + ' (dest) is a liability: ' + destIsLiability);
if (tType === 'transfer' || destIsLiability || sourceIsLiability) {
// console.log('Source is liability OR dest is liability, OR transfer. Lock list on currency of destination.');
// console.log('Length of currencies is ' + this.currencies.length);
// console.log(this.currencies);
this.liability = true;
// lock dropdown list on currencyID of destination.
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
// console.log('this.currencies[key].id = ' + this.currencies[key].id);
// console.log('this.destination.currency_id = ' + this.destination.currency_id);
if (parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id)) {
this.enabledCurrencies.push(this.currencies[key]);
}
}
}
// console.log('Enabled currencies length is now ' + this.enabledCurrencies.length);
return;
}
// if type is withdrawal, list all but skip the source account ID.
if (tType === 'withdrawal' && this.source && false === sourceIsLiability) {
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (this.source.currency_id !== this.currencies[key].id) {
this.enabledCurrencies.push(this.currencies[key]);
}
}
}
return;
}
// if type is deposit, list all but skip the source account ID.
if (tType === 'deposit' && this.destination) {
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (this.destination.currency_id !== this.currencies[key].id) {
this.enabledCurrencies.push(this.currencies[key]);
}
}
}
return;
}
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
this.enabledCurrencies.push(this.currencies[key]);
}
}
},
loadCurrencies: function () {
// reset list of currencies:
this.currencies = [
{
id: 0,
attributes: {
name: this.no_currency,
enabled: true
},
}
];
this.enabledCurrencies = [
{
attributes: {
name: this.no_currency,
enabled: true
},
id: 0,
}
];
this.getCurrencies(1);
},
getCurrencies: function(page) {
// console.log('loadCurrencies on page ' + page);
let url = document.getElementsByTagName('base')[0].href + "api/v1/currencies?page=" + page;
axios.get(url, {}).then((res) => {
for (const key in res.data.data) {
if (res.data.data.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (res.data.data[key].attributes.enabled) {
// console.log(res.data.data[key].attributes);
this.currencies.push(res.data.data[key]);
this.enabledCurrencies.push(res.data.data[key]);
}
}
}
if(res.data.meta.pagination.current_page < res.data.meta.pagination.total_pages) {
this.getCurrencies(res.data.meta.pagination.current_page + 1);
}
});
}
}
}
</script>

View File

@@ -18,8 +18,8 @@
"is_reconciled": "Ist abgestimmt",
"split": "Teilen",
"single_split": "Teilen",
"not_enough_currencies": "Not enough currencies",
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.",
"not_enough_currencies": "Nicht gen\u00fcgend W\u00e4hrungen",
"not_enough_currencies_enabled": "Wenn Sie nur eine W\u00e4hrung aktiviert haben, ist es nicht erforderlich, Wechselkurse hinzuzuf\u00fcgen.",
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Buchung #{ID} (\"{title}\")<\/a> wurde gespeichert.",
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> wurde gespeichert.",
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") wurde aktualisiert.",

View File

@@ -18,8 +18,8 @@
"is_reconciled": "\u0421\u0432\u0435\u0440\u0435\u043d\u043e",
"split": "\u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c",
"single_split": "\u0420\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f",
"not_enough_currencies": "Not enough currencies",
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.",
"not_enough_currencies": "\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0435\u0434\u0438\u043d\u0438\u0446 \u0432\u0430\u043b\u044e\u0442",
"not_enough_currencies_enabled": "\u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0432\u0430\u043b\u044e\u0442\u0430, \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0443\u0440\u0441\u044b \u0432\u0430\u043b\u044e\u0442.",
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f #{ID} (\"{title}\")<\/a> \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430.",
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">\u0412\u0435\u0431-\u0445\u0443\u043a #{ID} (\"{title}\")<\/a> \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d.",
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">\u0412\u0435\u0431-\u0445\u0443\u043a #{ID} (\"{title}\")<\/a> \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d.",

View File

@@ -11,7 +11,7 @@ use FireflyIII\Support\Search\QueryParser\NodeGroup;
use FireflyIII\Support\Search\QueryParser\Node;
use Tests\integration\TestCase;
abstract class AbstractQueryParserInterfaceParseQueryTest extends TestCase
abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase
{
abstract protected function createParser(): QueryParserInterface;

View File

@@ -16,7 +16,7 @@ use FireflyIII\Support\Search\QueryParser\QueryParserInterface;
*
* @coversNothing
*/
final class QueryParserParseQueryTest extends AbstractQueryParserInterfaceParseQueryTest
final class QueryParserParseQueryTest extends AbstractQueryParserInterfaceParseQueryTester
{
protected function createParser(): QueryParserInterface
{