mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-01-06 02:21:25 +00:00
Compare commits
7 Commits
develop-20
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f909f1d9ff | ||
|
|
55018ca046 | ||
|
|
19c746a865 | ||
|
|
503d2aa786 | ||
|
|
70d83ab501 | ||
|
|
edab602bb7 | ||
|
|
f9bcc4b1fa |
@@ -104,15 +104,20 @@ class AccountController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'id' => (string) $account->id,
|
'id' => (string) $account->id,
|
||||||
'name' => $account->name,
|
'name' => $account->name,
|
||||||
'name_with_balance' => $nameWithBalance,
|
'name_with_balance' => $nameWithBalance,
|
||||||
'type' => $account->accountType->type,
|
'type' => $account->accountType->type,
|
||||||
'currency_id' => (string) $useCurrency->id,
|
'currency_id' => (string) $useCurrency->id,
|
||||||
'currency_name' => $useCurrency->name,
|
'currency_name' => $useCurrency->name,
|
||||||
'currency_code' => $useCurrency->code,
|
'currency_code' => $useCurrency->code,
|
||||||
'currency_symbol' => $useCurrency->symbol,
|
'currency_symbol' => $useCurrency->symbol,
|
||||||
'currency_decimal_places' => $useCurrency->decimal_places,
|
'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,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,25 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
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;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Console\Commands\Correction;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||||
|
use FireflyIII\Enums\TransactionTypeEnum;
|
||||||
use FireflyIII\Models\AutoBudget;
|
use FireflyIII\Models\AutoBudget;
|
||||||
use FireflyIII\Models\AvailableBudget;
|
use FireflyIII\Models\AvailableBudget;
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
@@ -33,8 +34,14 @@ use FireflyIII\Models\CurrencyExchangeRate;
|
|||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\RecurrenceTransaction;
|
use FireflyIII\Models\RecurrenceTransaction;
|
||||||
use FireflyIII\Models\RuleTrigger;
|
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\Console\Command;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class CorrectsAmounts extends Command
|
class CorrectsAmounts extends Command
|
||||||
{
|
{
|
||||||
@@ -45,6 +52,8 @@ class CorrectsAmounts extends Command
|
|||||||
|
|
||||||
public function handle(): int
|
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
|
// auto budgets must be positive
|
||||||
$this->fixAutoBudgets();
|
$this->fixAutoBudgets();
|
||||||
// available budgets must be positive
|
// 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)
|
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
|
||||||
$this->fixRuleTriggers();
|
$this->fixRuleTriggers();
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,4 +192,63 @@ class CorrectsAmounts extends Command
|
|||||||
|
|
||||||
return false;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,25 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
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;
|
namespace FireflyIII\Console\Commands\Correction;
|
||||||
|
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ class AccountController extends Controller
|
|||||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$defaultSet = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
$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);
|
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||||
$frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data;
|
$frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data;
|
||||||
Log::debug('Frontpage preference set is ', $frontpageArray);
|
Log::debug('Frontpage preference set is ', $frontpageArray);
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ class TransactionJournal extends Model
|
|||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function userGroup(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(UserGroup::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function attachments(): MorphMany
|
public function attachments(): MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Attachment::class, 'attachable');
|
return $this->morphMany(Attachment::class, 'attachable');
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ class ExchangeRateConverter
|
|||||||
|
|
||||||
return '1';
|
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);
|
$rate = $this->getRate($from, $to, $date);
|
||||||
|
|
||||||
return '0' === $rate ? '1' : $rate;
|
return '0' === $rate ? '1' : $rate;
|
||||||
@@ -103,7 +108,7 @@ class ExchangeRateConverter
|
|||||||
|
|
||||||
// find in cache
|
// find in cache
|
||||||
if (null !== $res) {
|
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;
|
return $res;
|
||||||
}
|
}
|
||||||
@@ -112,7 +117,7 @@ class ExchangeRateConverter
|
|||||||
$rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d'));
|
$rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d'));
|
||||||
if (null !== $rate) {
|
if (null !== $rate) {
|
||||||
Cache::forever($key, $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;
|
return $rate;
|
||||||
}
|
}
|
||||||
@@ -122,7 +127,7 @@ class ExchangeRateConverter
|
|||||||
if (null !== $rate) {
|
if (null !== $rate) {
|
||||||
$rate = bcdiv('1', $rate);
|
$rate = bcdiv('1', $rate);
|
||||||
Cache::forever($key, $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;
|
return $rate;
|
||||||
}
|
}
|
||||||
@@ -133,14 +138,14 @@ class ExchangeRateConverter
|
|||||||
|
|
||||||
// combined (if present), they can be used to calculate the necessary conversion rate.
|
// combined (if present), they can be used to calculate the necessary conversion rate.
|
||||||
if (0 === bccomp('0', $first) || 0 === bccomp('0', $second)) {
|
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';
|
return '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
$second = bcdiv('1', $second);
|
$second = bcdiv('1', $second);
|
||||||
$rate = bcmul($first, $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);
|
Cache::forever($key, $rate);
|
||||||
|
|
||||||
return $rate;
|
return $rate;
|
||||||
@@ -154,6 +159,8 @@ class ExchangeRateConverter
|
|||||||
private function getFromDB(int $from, int $to, string $date): ?string
|
private function getFromDB(int $from, int $to, string $date): ?string
|
||||||
{
|
{
|
||||||
if ($from === $to) {
|
if ($from === $to) {
|
||||||
|
Log::debug('ExchangeRateConverter: From and to are the same, return "1".');
|
||||||
|
|
||||||
return '1';
|
return '1';
|
||||||
}
|
}
|
||||||
$key = sprintf('cer-%d-%d-%s', $from, $to, $date);
|
$key = sprintf('cer-%d-%d-%s', $from, $to, $date);
|
||||||
@@ -173,7 +180,7 @@ class ExchangeRateConverter
|
|||||||
if ('' === $rate) {
|
if ('' === $rate) {
|
||||||
return null;
|
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;
|
return $rate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ trait ChartGeneration
|
|||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return $cache->get();
|
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();
|
$locale = app('steam')->getLocale();
|
||||||
|
|
||||||
/** @var GeneratorInterface $generator */
|
/** @var GeneratorInterface $generator */
|
||||||
@@ -88,6 +88,7 @@ trait ChartGeneration
|
|||||||
$currentStart = clone $start;
|
$currentStart = clone $start;
|
||||||
$range = Steam::finalAccountBalanceInRange($account, clone $start, clone $end, $this->convertToNative);
|
$range = Steam::finalAccountBalanceInRange($account, clone $start, clone $end, $this->convertToNative);
|
||||||
$previous = array_values($range)[0];
|
$previous = array_values($range)[0];
|
||||||
|
Log::debug(sprintf('Start balance for account #%d ("%s) is', $account->id, $account->name), $previous);
|
||||||
while ($currentStart <= $end) {
|
while ($currentStart <= $end) {
|
||||||
$format = $currentStart->format('Y-m-d');
|
$format = $currentStart->format('Y-m-d');
|
||||||
$label = trim($currentStart->isoFormat((string) trans('config.month_and_day_js', [], $locale)));
|
$label = trim($currentStart->isoFormat((string) trans('config.month_and_day_js', [], $locale)));
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ class Steam
|
|||||||
public function finalAccountBalanceInRange(Account $account, Carbon $start, Carbon $end, bool $convertToNative): array
|
public function finalAccountBalanceInRange(Account $account, Carbon $start, Carbon $end, bool $convertToNative): array
|
||||||
{
|
{
|
||||||
// expand period.
|
// expand period.
|
||||||
$start->subDay()->endOfDay(); // go to END of day to get the balance at the END of the day.
|
$start->startOfDay();
|
||||||
$end->addDay()->startOfDay(); // go to START of day to get the balance at the END of the previous day (see ahead).
|
$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')));
|
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
|
// set up cache
|
||||||
@@ -82,6 +82,7 @@ class Steam
|
|||||||
$currency = $accountCurrency ?? $nativeCurrency;
|
$currency = $accountCurrency ?? $nativeCurrency;
|
||||||
Log::debug(sprintf('Currency is %s', $currency->code));
|
Log::debug(sprintf('Currency is %s', $currency->code));
|
||||||
|
|
||||||
|
|
||||||
// set start balances:
|
// set start balances:
|
||||||
$startBalance[$currency->code] ??= '0';
|
$startBalance[$currency->code] ??= '0';
|
||||||
if ($hasCurrency) {
|
if ($hasCurrency) {
|
||||||
@@ -100,10 +101,11 @@ class Steam
|
|||||||
Log::debug('Final start balance: ', $startBalance);
|
Log::debug('Final start balance: ', $startBalance);
|
||||||
|
|
||||||
// sums up the balance changes per day.
|
// 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()
|
$set = $account->transactions()
|
||||||
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
->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', '>=', $start->format('Y-m-d H:i:s'))
|
||||||
->where('transaction_journals.date', '<', $end->format('Y-m-d H:i:s'))
|
->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s'))
|
||||||
->groupBy('transaction_journals.date')
|
->groupBy('transaction_journals.date')
|
||||||
->groupBy('transactions.transaction_currency_id')
|
->groupBy('transactions.transaction_currency_id')
|
||||||
->orderBy('transaction_journals.date', 'ASC')
|
->orderBy('transaction_journals.date', 'ASC')
|
||||||
|
|||||||
@@ -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
|
- [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 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 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 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 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
|
- [Issue 9789](https://github.com/firefly-iii/firefly-iii/issues/9789) (Can't open expense and revenue accounts view) reported by @puffer-duck
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ return [
|
|||||||
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
||||||
// see cer.php for exchange rates feature flag.
|
// 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.
|
'api_version' => '2.1.0', // field is no longer used.
|
||||||
'db_version' => 25,
|
'db_version' => 25,
|
||||||
|
|
||||||
|
|||||||
142
package-lock.json
generated
142
package-lock.json
generated
@@ -79,9 +79,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/compat-data": {
|
"node_modules/@babel/compat-data": {
|
||||||
"version": "7.26.5",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
|
||||||
"integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==",
|
"integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -89,22 +89,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/core": {
|
"node_modules/@babel/core": {
|
||||||
"version": "7.26.7",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz",
|
||||||
"integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==",
|
"integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.2.0",
|
"@ampproject/remapping": "^2.2.0",
|
||||||
"@babel/code-frame": "^7.26.2",
|
"@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-compilation-targets": "^7.26.5",
|
||||||
"@babel/helper-module-transforms": "^7.26.0",
|
"@babel/helper-module-transforms": "^7.26.0",
|
||||||
"@babel/helpers": "^7.26.7",
|
"@babel/helpers": "^7.26.7",
|
||||||
"@babel/parser": "^7.26.7",
|
"@babel/parser": "^7.26.8",
|
||||||
"@babel/template": "^7.25.9",
|
"@babel/template": "^7.26.8",
|
||||||
"@babel/traverse": "^7.26.7",
|
"@babel/traverse": "^7.26.8",
|
||||||
"@babel/types": "^7.26.7",
|
"@babel/types": "^7.26.8",
|
||||||
|
"@types/gensync": "^1.0.0",
|
||||||
"convert-source-map": "^2.0.0",
|
"convert-source-map": "^2.0.0",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"gensync": "^1.0.0-beta.2",
|
"gensync": "^1.0.0-beta.2",
|
||||||
@@ -130,14 +131,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/generator": {
|
"node_modules/@babel/generator": {
|
||||||
"version": "7.26.5",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz",
|
||||||
"integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
|
"integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.26.5",
|
"@babel/parser": "^7.26.8",
|
||||||
"@babel/types": "^7.26.5",
|
"@babel/types": "^7.26.8",
|
||||||
"@jridgewell/gen-mapping": "^0.3.5",
|
"@jridgewell/gen-mapping": "^0.3.5",
|
||||||
"@jridgewell/trace-mapping": "^0.3.25",
|
"@jridgewell/trace-mapping": "^0.3.25",
|
||||||
"jsesc": "^3.0.2"
|
"jsesc": "^3.0.2"
|
||||||
@@ -442,13 +443,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/parser": {
|
||||||
"version": "7.26.7",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz",
|
||||||
"integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
|
"integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.26.7"
|
"@babel/types": "^7.26.8"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
@@ -667,15 +668,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/plugin-transform-async-generator-functions": {
|
"node_modules/@babel/plugin-transform-async-generator-functions": {
|
||||||
"version": "7.25.9",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
|
||||||
"integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==",
|
"integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"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/helper-remap-async-to-generator": "^7.25.9",
|
||||||
"@babel/traverse": "^7.25.9"
|
"@babel/traverse": "^7.26.8"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -1340,14 +1341,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/plugin-transform-runtime": {
|
"node_modules/@babel/plugin-transform-runtime": {
|
||||||
"version": "7.25.9",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.8.tgz",
|
||||||
"integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==",
|
"integrity": "sha512-H0jlQxFMI0Q8SyGPsj9pO3ygVQRxPkIGytsL3m1Zqca8KrCPpMlvh+e2dxknqdfS8LFwBw+PpiYPD9qy/FPQpA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-module-imports": "^7.25.9",
|
"@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-corejs2": "^0.4.10",
|
||||||
"babel-plugin-polyfill-corejs3": "^0.10.6",
|
"babel-plugin-polyfill-corejs3": "^0.10.6",
|
||||||
"babel-plugin-polyfill-regenerator": "^0.6.1",
|
"babel-plugin-polyfill-regenerator": "^0.6.1",
|
||||||
@@ -1420,13 +1421,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/plugin-transform-template-literals": {
|
"node_modules/@babel/plugin-transform-template-literals": {
|
||||||
"version": "7.25.9",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz",
|
||||||
"integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
|
"integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-plugin-utils": "^7.25.9"
|
"@babel/helper-plugin-utils": "^7.26.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -1519,13 +1520,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/preset-env": {
|
"node_modules/@babel/preset-env": {
|
||||||
"version": "7.26.7",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.8.tgz",
|
||||||
"integrity": "sha512-Ycg2tnXwixaXOVb29rana8HNPgLVBof8qqtNQ9LE22IoyZboQbGSxI6ZySMdW3K5nAe6gu35IaJefUJflhUFTQ==",
|
"integrity": "sha512-um7Sy+2THd697S4zJEfv/U5MHGJzkN2xhtsR3T/SWRbVSic62nbISh51VVfU9JiO/L/Z97QczHTaFVkOU8IzNg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/compat-data": "^7.26.5",
|
"@babel/compat-data": "^7.26.8",
|
||||||
"@babel/helper-compilation-targets": "^7.26.5",
|
"@babel/helper-compilation-targets": "^7.26.5",
|
||||||
"@babel/helper-plugin-utils": "^7.26.5",
|
"@babel/helper-plugin-utils": "^7.26.5",
|
||||||
"@babel/helper-validator-option": "^7.25.9",
|
"@babel/helper-validator-option": "^7.25.9",
|
||||||
@@ -1539,7 +1540,7 @@
|
|||||||
"@babel/plugin-syntax-import-attributes": "^7.26.0",
|
"@babel/plugin-syntax-import-attributes": "^7.26.0",
|
||||||
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
|
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
|
||||||
"@babel/plugin-transform-arrow-functions": "^7.25.9",
|
"@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-async-to-generator": "^7.25.9",
|
||||||
"@babel/plugin-transform-block-scoped-functions": "^7.26.5",
|
"@babel/plugin-transform-block-scoped-functions": "^7.26.5",
|
||||||
"@babel/plugin-transform-block-scoping": "^7.25.9",
|
"@babel/plugin-transform-block-scoping": "^7.25.9",
|
||||||
@@ -1582,7 +1583,7 @@
|
|||||||
"@babel/plugin-transform-shorthand-properties": "^7.25.9",
|
"@babel/plugin-transform-shorthand-properties": "^7.25.9",
|
||||||
"@babel/plugin-transform-spread": "^7.25.9",
|
"@babel/plugin-transform-spread": "^7.25.9",
|
||||||
"@babel/plugin-transform-sticky-regex": "^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-typeof-symbol": "^7.26.7",
|
||||||
"@babel/plugin-transform-unicode-escapes": "^7.25.9",
|
"@babel/plugin-transform-unicode-escapes": "^7.25.9",
|
||||||
"@babel/plugin-transform-unicode-property-regex": "^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/plugin-transform-unicode-sets-regex": "^7.25.9",
|
||||||
"@babel/preset-modules": "0.1.6-no-external-plugins",
|
"@babel/preset-modules": "0.1.6-no-external-plugins",
|
||||||
"babel-plugin-polyfill-corejs2": "^0.4.10",
|
"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",
|
"babel-plugin-polyfill-regenerator": "^0.6.1",
|
||||||
"core-js-compat": "^3.38.1",
|
"core-js-compat": "^3.40.0",
|
||||||
"semver": "^6.3.1"
|
"semver": "^6.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1602,6 +1603,20 @@
|
|||||||
"@babel/core": "^7.0.0-0"
|
"@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": {
|
"node_modules/@babel/preset-env/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
@@ -1640,32 +1655,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.25.9",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz",
|
||||||
"integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
|
"integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.25.9",
|
"@babel/code-frame": "^7.26.2",
|
||||||
"@babel/parser": "^7.25.9",
|
"@babel/parser": "^7.26.8",
|
||||||
"@babel/types": "^7.25.9"
|
"@babel/types": "^7.26.8"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/traverse": {
|
"node_modules/@babel/traverse": {
|
||||||
"version": "7.26.7",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz",
|
||||||
"integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==",
|
"integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.26.2",
|
"@babel/code-frame": "^7.26.2",
|
||||||
"@babel/generator": "^7.26.5",
|
"@babel/generator": "^7.26.8",
|
||||||
"@babel/parser": "^7.26.7",
|
"@babel/parser": "^7.26.8",
|
||||||
"@babel/template": "^7.25.9",
|
"@babel/template": "^7.26.8",
|
||||||
"@babel/types": "^7.26.7",
|
"@babel/types": "^7.26.8",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
},
|
},
|
||||||
@@ -1674,9 +1689,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.26.7",
|
"version": "7.26.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz",
|
||||||
"integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
|
"integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -3032,6 +3047,13 @@
|
|||||||
"@types/send": "*"
|
"@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": {
|
"node_modules/@types/glob": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
||||||
@@ -4448,9 +4470,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001698",
|
"version": "1.0.30001699",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001698.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
|
||||||
"integrity": "sha512-xJ3km2oiG/MbNU8G6zIq6XRZ6HtAOVXsbOrP/blGazi52kc5Yy7b6sDA5O+FbROzRrV7BSTllLHuNvmawYUJjw==",
|
"integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ export default {
|
|||||||
this.totalPages = parseInt(response.data.meta.pagination.total_pages);
|
this.totalPages = parseInt(response.data.meta.pagination.total_pages);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.rates = Object.values(this.tempRates);
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
data-role="input"
|
data-role="input"
|
||||||
type="text"
|
type="text"
|
||||||
v-on:keypress="handleEnter"
|
|
||||||
v-on:submit.prevent>
|
v-on:submit.prevent>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button
|
<button
|
||||||
@@ -217,7 +216,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectedItem: function (e) {
|
selectedItem: function (e) {
|
||||||
// console.log('In SelectedItem()');
|
console.log('In SelectedItem()');
|
||||||
if (typeof this.name === 'undefined') {
|
if (typeof this.name === 'undefined') {
|
||||||
// console.log('Is undefined');
|
// console.log('Is undefined');
|
||||||
return;
|
return;
|
||||||
@@ -239,12 +238,6 @@ export default {
|
|||||||
this.name = '';
|
this.name = '';
|
||||||
// some event?
|
// some event?
|
||||||
this.$emit('clear:value')
|
this.$emit('clear:value')
|
||||||
},
|
|
||||||
handleEnter: function (e) {
|
|
||||||
// TODO feels sloppy. Can be removed.
|
|
||||||
if (e.keyCode === 13) {
|
|
||||||
//e.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -922,6 +922,12 @@ export default {
|
|||||||
allowed_types: this.transactions[index].source_account.allowed_types,
|
allowed_types: this.transactions[index].source_account.allowed_types,
|
||||||
default_allowed_types: ['Asset account', 'Revenue account', 'Loan', 'Debt', 'Mortgage']
|
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.
|
// force types on destination selector.
|
||||||
this.transactions[index].destination_account.allowed_types = window.allowedOpposingTypes.source[model.type];
|
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,
|
allowed_types: this.transactions[index].destination_account.allowed_types,
|
||||||
default_allowed_types: ['Asset account', 'Expense account', 'Loan', 'Debt', 'Mortgage']
|
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.
|
// force types on destination selector.
|
||||||
this.transactions[index].source_account.allowed_types = window.allowedOpposingTypes.destination[model.type];
|
this.transactions[index].source_account.allowed_types = window.allowedOpposingTypes.destination[model.type];
|
||||||
|
|||||||
@@ -155,8 +155,8 @@
|
|||||||
v-bind:title="$t('form.foreign_amount')"
|
v-bind:title="$t('form.foreign_amount')"
|
||||||
></foreign-amount>
|
></foreign-amount>
|
||||||
<reconciled v-show="isReconciled"
|
<reconciled v-show="isReconciled"
|
||||||
v-model="transaction.reconciled"
|
v-model="transaction.reconciled"
|
||||||
:error="transaction.errors.reconciled"
|
:error="transaction.errors.reconciled"
|
||||||
></reconciled>
|
></reconciled>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
@@ -322,6 +322,12 @@ export default {
|
|||||||
currency_decimal_places: model.currency_decimal_places,
|
currency_decimal_places: model.currency_decimal_places,
|
||||||
allowed_types: this.transactions[index].source_account.allowed_types
|
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) {
|
selectedDestinationAccount(index, model) {
|
||||||
if (typeof model === 'string') {
|
if (typeof model === 'string') {
|
||||||
@@ -341,6 +347,12 @@ export default {
|
|||||||
currency_decimal_places: model.currency_decimal_places,
|
currency_decimal_places: model.currency_decimal_places,
|
||||||
allowed_types: this.transactions[index].destination_account.allowed_types
|
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) {
|
clearSource(index) {
|
||||||
// reset source account:
|
// reset source account:
|
||||||
@@ -437,7 +449,7 @@ export default {
|
|||||||
//console.log('EditTransaction: processIncomingGroupRow()');
|
//console.log('EditTransaction: processIncomingGroupRow()');
|
||||||
this.setTransactionType(transaction.type);
|
this.setTransactionType(transaction.type);
|
||||||
|
|
||||||
if(true === transaction.reconciled) {
|
if (true === transaction.reconciled) {
|
||||||
this.isReconciled = true;
|
this.isReconciled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +540,16 @@ export default {
|
|||||||
allowed_types: window.expectedSourceTypes.destination[this.ucFirst(transaction.type)]
|
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 = '';
|
result.foreign_amount.amount = '';
|
||||||
}
|
}
|
||||||
this.transactions.push(result);
|
this.transactions.push(result);
|
||||||
@@ -736,7 +757,7 @@ export default {
|
|||||||
if (parseInt(row.piggy_bank) > 0) {
|
if (parseInt(row.piggy_bank) > 0) {
|
||||||
currentArray.piggy_bank_id = parseInt(row.piggy_bank);
|
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:
|
// drop content from array:
|
||||||
delete currentArray.source_id;
|
delete currentArray.source_id;
|
||||||
delete currentArray.source_name;
|
delete currentArray.source_name;
|
||||||
@@ -748,7 +769,7 @@ export default {
|
|||||||
delete currentArray.currency_id;
|
delete currentArray.currency_id;
|
||||||
currentArray.reconciled = true;
|
currentArray.reconciled = true;
|
||||||
}
|
}
|
||||||
if(true === row.isReconciled) {
|
if (true === row.isReconciled) {
|
||||||
this.isReconciled = false;
|
this.isReconciled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,10 +822,16 @@ export default {
|
|||||||
this.setDefaultErrors();
|
this.setDefaultErrors();
|
||||||
// do message if update or new:
|
// do message if update or new:
|
||||||
if (this.storeAsNew) {
|
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 = '';
|
this.error_message = '';
|
||||||
} else {
|
} 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 = '';
|
this.error_message = '';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -19,205 +19,213 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!--
|
<!--
|
||||||
Show if:
|
Show if:
|
||||||
- one or more currencies.
|
- one or more currencies.
|
||||||
-->
|
-->
|
||||||
<div v-if="this.enabledCurrencies.length >= 1" class="form-group" v-bind:class="{ 'has-error': hasError()}">
|
<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">
|
<div class="col-sm-8 col-sm-offset-4 text-sm">
|
||||||
{{ $t('form.foreign_amount') }}
|
{{ $t('form.foreign_amount') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<select ref="currency_select" class="form-control" name="foreign_currency[]" @input="handleInput">
|
<select ref="currency_select" class="form-control" name="foreign_currency[]" @input="handleInput">
|
||||||
<option
|
<option
|
||||||
v-for="currency in this.enabledCurrencies"
|
v-for="currency in this.enabledCurrencies"
|
||||||
:label="currency.attributes.name"
|
:label="currency.attributes.name"
|
||||||
:selected="parseInt(value.currency_id) === parseInt(currency.id)"
|
:selected="parseInt(value.currency_id) === parseInt(currency.id)"
|
||||||
:value="currency.id"
|
:value="currency.id"
|
||||||
|
|
||||||
>
|
>
|
||||||
{{ currency.attributes.name }}
|
{{ currency.attributes.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input v-if="this.enabledCurrencies.length > 0" ref="amount" :placeholder="this.title" :title="this.title" :value="value.amount" autocomplete="off"
|
<input v-if="this.enabledCurrencies.length > 0" ref="amount" :placeholder="this.title"
|
||||||
class="form-control" name="foreign_amount[]"
|
:title="this.title" :value="value.amount" autocomplete="off"
|
||||||
step="any" type="number" @input="handleInput">
|
class="form-control" name="foreign_amount[]"
|
||||||
<span class="input-group-btn">
|
step="any" type="number" @input="handleInput">
|
||||||
|
<span class="input-group-btn">
|
||||||
<button
|
<button
|
||||||
class="btn btn-default"
|
class="btn btn-default"
|
||||||
tabIndex="-1"
|
tabIndex="-1"
|
||||||
type="button"
|
type="button"
|
||||||
v-on:click="clearAmount"><i class="fa fa-trash-o"></i></button>
|
v-on:click="clearAmount"><i class="fa fa-trash-o"></i></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ul v-for="error in this.error" class="list-unstyled">
|
<ul v-for="error in this.error" class="list-unstyled">
|
||||||
<li class="text-danger">{{ error }}</li>
|
<li class="text-danger">{{ error }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "ForeignAmountSelect",
|
name: "ForeignAmountSelect",
|
||||||
|
|
||||||
props: ['source', 'destination', 'transactionType', 'value', 'error', 'no_currency', 'title',],
|
props: ['source', 'destination', 'transactionType', 'value', 'error', 'no_currency', 'title',],
|
||||||
mounted() {
|
mounted() {
|
||||||
this.liability = false;
|
this.liability = false;
|
||||||
this.loadCurrencies();
|
// 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;
|
||||||
|
|
||||||
},
|
// console.log(srcType + ' (source) is a liability: ' + sourceIsLiability);
|
||||||
data() {
|
// console.log(destType + ' (dest) is a liability: ' + destIsLiability);
|
||||||
return {
|
// console.log('tType: ' + tType);
|
||||||
currencies: [],
|
if (tType === 'transfer' || destIsLiability || sourceIsLiability) {
|
||||||
enabledCurrencies: [],
|
// console.log('Source is liability OR dest is liability, OR transfer. Lock list on currency of destination.');
|
||||||
exclude: null,
|
// console.log('Length of currencies is ' + this.currencies.length);
|
||||||
// liability overrules the drop down list if the source or dest is a liability
|
// console.log(this.currencies);
|
||||||
liability: false
|
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>
|
</script>
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
"is_reconciled": "Ist abgestimmt",
|
"is_reconciled": "Ist abgestimmt",
|
||||||
"split": "Teilen",
|
"split": "Teilen",
|
||||||
"single_split": "Teilen",
|
"single_split": "Teilen",
|
||||||
"not_enough_currencies": "Not enough currencies",
|
"not_enough_currencies": "Nicht gen\u00fcgend W\u00e4hrungen",
|
||||||
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.",
|
"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.",
|
"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_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.",
|
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") wurde aktualisiert.",
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
"is_reconciled": "\u0421\u0432\u0435\u0440\u0435\u043d\u043e",
|
"is_reconciled": "\u0421\u0432\u0435\u0440\u0435\u043d\u043e",
|
||||||
"split": "\u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c",
|
"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",
|
"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": "\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": "If you have just one currency enabled, there is no need to add exchange rates.",
|
"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.",
|
"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_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.",
|
"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.",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use FireflyIII\Support\Search\QueryParser\NodeGroup;
|
|||||||
use FireflyIII\Support\Search\QueryParser\Node;
|
use FireflyIII\Support\Search\QueryParser\Node;
|
||||||
use Tests\integration\TestCase;
|
use Tests\integration\TestCase;
|
||||||
|
|
||||||
abstract class AbstractQueryParserInterfaceParseQueryTest extends TestCase
|
abstract class AbstractQueryParserInterfaceParseQueryTester extends TestCase
|
||||||
{
|
{
|
||||||
abstract protected function createParser(): QueryParserInterface;
|
abstract protected function createParser(): QueryParserInterface;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ use FireflyIII\Support\Search\QueryParser\QueryParserInterface;
|
|||||||
*
|
*
|
||||||
* @coversNothing
|
* @coversNothing
|
||||||
*/
|
*/
|
||||||
final class QueryParserParseQueryTest extends AbstractQueryParserInterfaceParseQueryTest
|
final class QueryParserParseQueryTest extends AbstractQueryParserInterfaceParseQueryTester
|
||||||
{
|
{
|
||||||
protected function createParser(): QueryParserInterface
|
protected function createParser(): QueryParserInterface
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user