mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-01-06 22:21:42 +00:00
Compare commits
20 Commits
branch-v6.
...
branch-v6.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a500de8ab1 | ||
|
|
303548a5fe | ||
|
|
68de905698 | ||
|
|
9240b9868b | ||
|
|
0e2e155cc6 | ||
|
|
bffa0088b4 | ||
|
|
2e993857e8 | ||
|
|
117a376fc3 | ||
|
|
1daffedde0 | ||
|
|
0e8fdd76a6 | ||
|
|
7ff4f29bcb | ||
|
|
9e4cff2b23 | ||
|
|
4aaea89f2c | ||
|
|
4fbf7b38fb | ||
|
|
76075401f9 | ||
|
|
e2a20dd63d | ||
|
|
b52a1f3eb1 | ||
|
|
7fd5a88122 | ||
|
|
1a1baa5cda | ||
|
|
577d671a0c |
6
.ci/php-cs-fixer/composer.lock
generated
6
.ci/php-cs-fixer/composer.lock
generated
@@ -97,13 +97,13 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2023 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/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
use ValidatesUserGroupTrait;
|
||||
public const string RESOURCE_KEY = 'exchange-rates';
|
||||
|
||||
private ExchangeRateRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(ExchangeRateRepositoryInterface::class);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
$piggies = $this->repository->getAll();
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $piggies->count();
|
||||
$piggies = $piggies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($piggies, $count, $pageSize, $this->parameters->get('page'));
|
||||
|
||||
var_dump('here we are');
|
||||
|
||||
$transformer = new ExchangeRateTransformer();
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
76
app/Api/V2/Controllers/Model/ExchangeRate/ShowController.php
Normal file
76
app/Api/V2/Controllers/Model/ExchangeRate/ShowController.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2023 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/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\ExchangeRate;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use FireflyIII\Transformers\V2\ExchangeRateTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
use ValidatesUserGroupTrait;
|
||||
public const string RESOURCE_KEY = 'exchange-rates';
|
||||
|
||||
private ExchangeRateRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(ExchangeRateRepositoryInterface::class);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function show(TransactionCurrency $from, TransactionCurrency $to): JsonResponse
|
||||
{
|
||||
// $piggies = $this->repository->getAll();
|
||||
//
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$rates = $this->repository->getRates($from, $to);
|
||||
$count = $rates->count();
|
||||
$rates = $rates->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($rates, $count, $pageSize, $this->parameters->get('page'));
|
||||
|
||||
$transformer = new ExchangeRateTransformer();
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* IndexController.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\TransactionCurrency;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\TransactionCurrency\IndexRequest;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\CurrencyTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'transaction-currencies';
|
||||
|
||||
private CurrencyRepositoryInterface $repository;
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function index(IndexRequest $request): JsonResponse
|
||||
{
|
||||
$settings = $request->getAll();
|
||||
if (true === $settings['enabled']) {
|
||||
$currencies = $this->repository->get();
|
||||
}
|
||||
if (true !== $settings['enabled']) {
|
||||
$currencies = $this->repository->getAll();
|
||||
}
|
||||
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $currencies->count();
|
||||
|
||||
// depending on the sort parameters, this list must not be split, because the
|
||||
// order is calculated in the account transformer and by that time it's too late.
|
||||
$accounts = $currencies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new CurrencyTransformer();
|
||||
|
||||
$this->parameters->set('pageSize', $pageSize);
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2021 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/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\TransactionCurrency;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\CurrencyTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'transaction-currencies';
|
||||
|
||||
private CurrencyRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function show(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
$groups = $currency->userGroups()->where('user_groups.id', $this->repository->getUserGroup()->id)->get();
|
||||
$enabled = $groups->count() > 0;
|
||||
$default = false;
|
||||
|
||||
/** @var UserGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
$default = 1 === $group->pivot->group_default;
|
||||
}
|
||||
$currency->userGroupEnabled = $enabled;
|
||||
$currency->userGroupDefault = $default;
|
||||
|
||||
|
||||
$transformer = new CurrencyTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject(self::RESOURCE_KEY, $currency, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* IndexRequest.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Model\TransactionCurrency;
|
||||
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\Support\Request\GetFilterInstructions;
|
||||
use FireflyIII\Support\Request\GetSortInstructions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class IndexRequest
|
||||
*
|
||||
* Lots of code stolen from the SingleDateRequest.
|
||||
*/
|
||||
class IndexRequest extends FormRequest
|
||||
{
|
||||
use AccountFilter;
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
use GetFilterInstructions;
|
||||
use GetSortInstructions;
|
||||
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'enabled' => $this->convertBoolean($this->get('enabled')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'enabled' => 'nullable|boolean',
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Class ReportSkeleton
|
||||
@@ -69,135 +70,88 @@ class CorrectAmounts extends Command
|
||||
|
||||
private function fixAutoBudgets(): void
|
||||
{
|
||||
$set = AutoBudget::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
$count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All auto budget amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var AutoBudget $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d auto budget amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixAvailableBudgets(): void
|
||||
{
|
||||
$set = AvailableBudget::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
$count = AvailableBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All available budget amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var AvailableBudget $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d available budget amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixBills(): void
|
||||
{
|
||||
$set = Bill::where('amount_min', '<', 0)->orWhere('amount_max', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
$count = 0;
|
||||
$count += Bill::where('amount_max', '<', 0)->update(['amount_max' => DB::raw('amount_max * -1')]);
|
||||
$count += Bill::where('amount_min', '<', 0)->update(['amount_min' => DB::raw('amount_min * -1')]);
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All bill amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Bill $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount_min = app('steam')->positive($item->amount_min);
|
||||
$item->amount_max = app('steam')->positive($item->amount_max);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d bill amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixBudgetLimits(): void
|
||||
{
|
||||
$set = BudgetLimit::where('amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
$count = BudgetLimit::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All budget limit amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var BudgetLimit $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d budget limit amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixExchangeRates(): void
|
||||
{
|
||||
$set = CurrencyExchangeRate::where('rate', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
$count = CurrencyExchangeRate::where('rate', '<', 0)->update(['rate' => DB::raw('rate * -1')]);
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All currency exchange rates are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var CurrencyExchangeRate $item */
|
||||
foreach ($set as $item) {
|
||||
$item->rate = app('steam')->positive($item->rate);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d currency exchange rate(s).', $count));
|
||||
}
|
||||
|
||||
private function fixPiggyBanks(): void
|
||||
{
|
||||
$set = PiggyBank::where('target_amount', '<', 0)->get();
|
||||
$count = $set->count();
|
||||
$count = PiggyBank::where('target_amount', '<', 0)->update(['target_amount' => DB::raw('target_amount * -1')]);
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All piggy bank amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var PiggyBank $item */
|
||||
foreach ($set as $item) {
|
||||
$item->target_amount = app('steam')->positive($item->target_amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d piggy bank amount(s).', $count));
|
||||
}
|
||||
|
||||
private function fixRecurrences(): void
|
||||
{
|
||||
$set = RecurrenceTransaction::where('amount', '<', 0)
|
||||
->orWhere('foreign_amount', '<', 0)
|
||||
->get()
|
||||
;
|
||||
$count = $set->count();
|
||||
$count = 0;
|
||||
$count += RecurrenceTransaction::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
|
||||
$count += RecurrenceTransaction::where('foreign_amount', '<', 0)->update(['foreign_amount' => DB::raw('foreign_amount * -1')]);
|
||||
if (0 === $count) {
|
||||
$this->friendlyPositive('All recurring transaction amounts are positive.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var RecurrenceTransaction $item */
|
||||
foreach ($set as $item) {
|
||||
$item->amount = app('steam')->positive($item->amount);
|
||||
$item->foreign_amount = app('steam')->positive($item->foreign_amount);
|
||||
$item->save();
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d recurring transaction amount(s).', $count));
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreach loop is unavoidable here.
|
||||
*/
|
||||
private function fixRuleTriggers(): void
|
||||
{
|
||||
$set = RuleTrigger::whereIn('trigger_type', ['amount_less', 'amount_more', 'amount_is'])->get();
|
||||
@@ -205,21 +159,9 @@ class CorrectAmounts extends Command
|
||||
|
||||
/** @var RuleTrigger $item */
|
||||
foreach ($set as $item) {
|
||||
// basic check:
|
||||
$check = 0;
|
||||
|
||||
try {
|
||||
$check = bccomp((string)$item->trigger_value, '0');
|
||||
} catch (\ValueError $e) {
|
||||
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
|
||||
$item->rule->active = false;
|
||||
$item->rule->save();
|
||||
$item->forceDelete();
|
||||
}
|
||||
if (-1 === $check) {
|
||||
$result = $this->fixRuleTrigger($item);
|
||||
if (true === $result) {
|
||||
++$fixed;
|
||||
$item->trigger_value = app('steam')->positive($item->trigger_value);
|
||||
$item->save();
|
||||
}
|
||||
}
|
||||
if (0 === $fixed) {
|
||||
@@ -229,4 +171,26 @@ class CorrectAmounts extends Command
|
||||
}
|
||||
$this->friendlyInfo(sprintf('Corrected %d rule trigger amount(s).', $fixed));
|
||||
}
|
||||
|
||||
private function fixRuleTrigger(RuleTrigger $item): bool
|
||||
{
|
||||
try {
|
||||
$check = bccomp((string) $item->trigger_value, '0');
|
||||
} catch (\ValueError $e) {
|
||||
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
|
||||
$item->rule->active = false;
|
||||
$item->rule->save();
|
||||
$item->forceDelete();
|
||||
|
||||
return false;
|
||||
}
|
||||
if (-1 === $check) {
|
||||
$item->trigger_value = app('steam')->positive($item->trigger_value);
|
||||
$item->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class CorrectDatabase extends Command
|
||||
'firefly-iii:fix-long-descriptions',
|
||||
'firefly-iii:fix-recurring-transactions',
|
||||
'firefly-iii:upgrade-group-information',
|
||||
'firefly-iii:fix-transaction-types',
|
||||
// 'firefly-iii:fix-transaction-types', // very resource heavy.
|
||||
'firefly-iii:fix-frontpage-accounts',
|
||||
// new!
|
||||
'firefly-iii:unify-group-accounts',
|
||||
|
||||
@@ -10,6 +10,7 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class CorrectionSkeleton extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
protected $description = 'DESCRIPTION HERE';
|
||||
|
||||
protected $signature = 'firefly-iii:CORR_COMMAND';
|
||||
|
||||
@@ -32,6 +32,7 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class FixTransactionTypes
|
||||
@@ -50,6 +51,7 @@ class FixTransactionTypes extends Command
|
||||
{
|
||||
$count = 0;
|
||||
$journals = $this->collectJournals();
|
||||
Log::debug(sprintf('In FixTransactionTypes, found %d journals.', $journals->count()));
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
|
||||
@@ -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\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
@@ -54,7 +55,7 @@ class FixUnevenAmount extends Command
|
||||
$this->matchCurrencies();
|
||||
if (config('firefly.feature_flags.running_balance_column')) {
|
||||
$this->friendlyInfo('Will recalculate transaction running balance columns. This may take a LONG time. Please be patient.');
|
||||
AccountBalanceCalculator::recalculateAll(true);
|
||||
AccountBalanceCalculator::recalculateAll(false);
|
||||
$this->friendlyInfo('Done recalculating transaction running balance columns.');
|
||||
}
|
||||
|
||||
@@ -240,6 +241,9 @@ class FixUnevenAmount extends Command
|
||||
Log::debug('convertOldStyleTransfers()');
|
||||
// select transactions with a foreign amount and a foreign currency. and it's a transfer. and they are different.
|
||||
$transactions = Transaction::distinct()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id')
|
||||
->where('transaction_types.type', TransactionTypeEnum::TRANSFER->value)
|
||||
->whereNotNull('foreign_currency_id')
|
||||
->whereNotNull('foreign_amount')->get(['transactions.transaction_journal_id'])
|
||||
;
|
||||
|
||||
229
app/Console/Commands/Correction/RecalculateNativeAmounts.php
Normal file
229
app/Console/Commands/Correction/RecalculateNativeAmounts.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* RecalculateNativeAmounts.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;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Handlers\Observer\TransactionObserver;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder as DatabaseBuilder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class RecalculateNativeAmounts extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'Recalculate native amounts for all objects.';
|
||||
|
||||
protected $signature = 'firefly-iii:recalculate-native-amounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
Log::debug('Will update all native amounts. This may take some time.');
|
||||
$this->friendlyWarning('Recalculating native amounts for all objects. This may take some time!');
|
||||
|
||||
/** @var UserGroupRepositoryInterface $repository */
|
||||
$repository = app(UserGroupRepositoryInterface::class);
|
||||
|
||||
/** @var UserGroup $userGroup */
|
||||
foreach ($repository->getAll() as $userGroup) {
|
||||
$this->recalculateForGroup($userGroup);
|
||||
}
|
||||
$this->friendlyInfo('Recalculated all native amounts.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function recalculateForGroup(UserGroup $userGroup): void
|
||||
{
|
||||
Log::debug(sprintf('Now recalculating for user group #%d', $userGroup->id));
|
||||
$this->recalculateAccounts($userGroup);
|
||||
|
||||
// do a check with the group's currency so we can skip some stuff.
|
||||
Preferences::mark();
|
||||
$currency = app('amount')->getDefaultCurrencyByUserGroup($userGroup);
|
||||
|
||||
$this->recalculatePiggyBanks($userGroup, $currency);
|
||||
$this->recalculateBudgets($userGroup, $currency);
|
||||
$this->recalculateAvailableBudgets($userGroup, $currency);
|
||||
$this->recalculateBills($userGroup, $currency);
|
||||
$this->calculateTransactions($userGroup, $currency);
|
||||
|
||||
}
|
||||
|
||||
private function recalculateAccounts(UserGroup $userGroup): void
|
||||
{
|
||||
$set = $userGroup->accounts()->where(function (EloquentBuilder $q): void {
|
||||
$q->whereNotNull('virtual_balance');
|
||||
$q->orWhere('virtual_balance', '!=', '');
|
||||
})->get();
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
$account->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d accounts', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculatePiggyBanks(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$repository = app(PiggyBankRepositoryInterface::class);
|
||||
$repository->setUserGroup($userGroup);
|
||||
$set = $repository->getPiggyBanks();
|
||||
$set = $set->filter(
|
||||
static function (PiggyBank $piggyBank) use ($currency) {
|
||||
return $currency->id !== $piggyBank->transaction_currency_id;
|
||||
}
|
||||
);
|
||||
foreach ($set as $piggyBank) {
|
||||
$piggyBank->encrypted = false;
|
||||
$piggyBank->save();
|
||||
|
||||
foreach ($piggyBank->accounts as $account) {
|
||||
$account->pivot->native_current_amount = null;
|
||||
if (0 !== bccomp($account->pivot->current_amount, '0')) {
|
||||
$account->pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $currency, today(), $account->pivot->current_amount);
|
||||
}
|
||||
$account->pivot->save();
|
||||
}
|
||||
$this->recalculatePiggyBankEvents($piggyBank);
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d piggy banks.', $set->count()));
|
||||
|
||||
}
|
||||
|
||||
private function recalculatePiggyBankEvents(PiggyBank $piggyBank): void
|
||||
{
|
||||
$set = $piggyBank->piggyBankEvents()->get();
|
||||
$set->each(
|
||||
static function (PiggyBankEvent $event): void {
|
||||
$event->touch();
|
||||
}
|
||||
);
|
||||
Log::debug(sprintf('Recalculated %d piggy bank events.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateBudgets(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $userGroup->budgets()->get();
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($set as $budget) {
|
||||
$this->recalculateBudgetLimits($budget, $currency);
|
||||
$this->recalculateAutoBudgets($budget, $currency);
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d budgets.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateBudgetLimits(Budget $budget, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $budget->budgetlimits()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($set as $limit) {
|
||||
Log::debug(sprintf('Will now touch BL #%d', $limit->id));
|
||||
$limit->touch();
|
||||
Log::debug(sprintf('Done with touch BL #%d', $limit->id));
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d budget limits.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateAutoBudgets(Budget $budget, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $budget->autoBudgets()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var AutoBudget $autoBudget */
|
||||
foreach ($set as $autoBudget) {
|
||||
$autoBudget->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d auto budgets.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateBills(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
$set = $userGroup->bills()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($set as $bill) {
|
||||
$bill->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d bills.', $set->count()));
|
||||
}
|
||||
|
||||
private function recalculateAvailableBudgets(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
Log::debug('Start with available budgets.');
|
||||
$set = $userGroup->availableBudgets()->where('transaction_currency_id', '!=', $currency->id)->get();
|
||||
|
||||
/** @var AvailableBudget $budget */
|
||||
foreach ($set as $budget) {
|
||||
$budget->touch();
|
||||
}
|
||||
Log::debug(sprintf('Recalculated %d available budgets.', $set->count()));
|
||||
}
|
||||
|
||||
private function calculateTransactions(UserGroup $userGroup, TransactionCurrency $currency): void
|
||||
{
|
||||
// custom query because of the potential size of this update.
|
||||
$set = DB::table('transactions')
|
||||
->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.user_group_id', $userGroup->id)
|
||||
->where(static function (DatabaseBuilder $q) use ($currency): void {
|
||||
$q->whereNot('transactions.transaction_currency_id', $currency->id)
|
||||
->orWhereNot('transactions.foreign_currency_id', $currency->id)
|
||||
;
|
||||
})
|
||||
->get(['transactions.id'])
|
||||
;
|
||||
TransactionObserver::$recalculate = false;
|
||||
foreach ($set as $item) {
|
||||
// here we are.
|
||||
$transaction = Transaction::find($item->id);
|
||||
$transaction->touch();
|
||||
}
|
||||
TransactionObserver::$recalculate = true;
|
||||
Log::debug(sprintf('Recalculated %d transactions.', $set->count()));
|
||||
}
|
||||
}
|
||||
@@ -98,12 +98,12 @@ class UpgradeMultiPiggyBanks extends Command
|
||||
|
||||
// update piggy bank to have a currency.
|
||||
$piggyBank->transaction_currency_id = $currency->id;
|
||||
$piggyBank->save();
|
||||
$piggyBank->saveQuietly();
|
||||
|
||||
// store current amount in account association.
|
||||
$piggyBank->accounts()->sync([$piggyBank->account->id => ['current_amount' => $repetition->current_amount]]);
|
||||
$piggyBank->account_id = null;
|
||||
$piggyBank->save();
|
||||
$piggyBank->saveQuietly();
|
||||
|
||||
// remove all repetitions (no longer used)
|
||||
$piggyBank->piggyBankRepetitions()->delete();
|
||||
|
||||
@@ -34,15 +34,13 @@ class DetectedNewIPAddress extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public string $ipAddress;
|
||||
public User $user;
|
||||
|
||||
/**
|
||||
* Create a new event instance. This event is triggered when a new user registers.
|
||||
*/
|
||||
public function __construct(User $user, string $ipAddress)
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->ipAddress = $ipAddress;
|
||||
$this->user = $user;
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
||||
|
||||
40
app/Events/Model/Account/Updated.php
Normal file
40
app/Events/Model/Account/Updated.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Updated.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events\Model\Account;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class Updated
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public Account $account;
|
||||
|
||||
public function __construct(Account $account)
|
||||
{
|
||||
$this->account = $account;
|
||||
}
|
||||
}
|
||||
43
app/Events/Preferences/UserGroupChangedDefaultCurrency.php
Normal file
43
app/Events/Preferences/UserGroupChangedDefaultCurrency.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* UserGroupChangedDefaultCurrency.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events\Preferences;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UserGroupChangedDefaultCurrency extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public UserGroup $userGroup;
|
||||
|
||||
public function __construct(UserGroup $userGroup)
|
||||
{
|
||||
Log::debug('User group changed default currency.');
|
||||
$this->userGroup = $userGroup;
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ class PiggyBankFactory
|
||||
|
||||
try {
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = PiggyBank::create($piggyBankData);
|
||||
$piggyBank = PiggyBank::createQuietly($piggyBankData);
|
||||
} catch (QueryException $e) {
|
||||
app('log')->error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyBankData);
|
||||
|
||||
@@ -103,7 +103,6 @@ class PiggyBankFactory
|
||||
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
|
||||
if (null !== $objectGroup) {
|
||||
$piggyBank->objectGroups()->sync([$objectGroup->id]);
|
||||
$piggyBank->save();
|
||||
}
|
||||
}
|
||||
// try also with ID
|
||||
@@ -112,10 +111,12 @@ class PiggyBankFactory
|
||||
$objectGroup = $this->findObjectGroupById($objectGroupId);
|
||||
if (null !== $objectGroup) {
|
||||
$piggyBank->objectGroups()->sync([$objectGroup->id]);
|
||||
$piggyBank->save();
|
||||
}
|
||||
}
|
||||
|
||||
Log::debug('Touch piggy bank');
|
||||
$piggyBank->encrypted = false;
|
||||
$piggyBank->save();
|
||||
$piggyBank->touch();
|
||||
return $piggyBank;
|
||||
}
|
||||
|
||||
@@ -184,7 +185,7 @@ class PiggyBankFactory
|
||||
$order = $data['order'];
|
||||
}
|
||||
$piggyBank->order = $order;
|
||||
$piggyBank->save();
|
||||
$piggyBank->saveQuietly();
|
||||
return $piggyBank;
|
||||
|
||||
}
|
||||
|
||||
135
app/Handlers/Events/PreferencesEventHandler.php
Normal file
135
app/Handlers/Events/PreferencesEventHandler.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* PreferencesEventHandler.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\Preferences\UserGroupChangedDefaultCurrency;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PreferencesEventHandler
|
||||
{
|
||||
public function resetNativeAmounts(UserGroupChangedDefaultCurrency $event): void
|
||||
{
|
||||
// Reset the native amounts for all objects that have it.
|
||||
Log::debug('Resetting native amounts for all objects.');
|
||||
|
||||
$tables = [
|
||||
// !!! this array is also in the migration
|
||||
'accounts' => ['native_virtual_balance'],
|
||||
'available_budgets' => ['native_amount'],
|
||||
'bills' => ['native_amount_min', 'native_amount_max'],
|
||||
// 'transactions' => ['native_amount', 'native_foreign_amount']
|
||||
];
|
||||
foreach ($tables as $table => $columns) {
|
||||
foreach ($columns as $column) {
|
||||
Log::debug(sprintf('Resetting column %s in table %s.', $column, $table));
|
||||
DB::table($table)->where('user_group_id', $event->userGroup->id)->update([$column => null]);
|
||||
}
|
||||
}
|
||||
$this->resetPiggyBanks($event->userGroup);
|
||||
$this->resetBudgets($event->userGroup);
|
||||
$this->resetTransactions($event->userGroup);
|
||||
}
|
||||
|
||||
private function resetPiggyBanks(UserGroup $userGroup): void
|
||||
{
|
||||
$repository = app(PiggyBankRepositoryInterface::class);
|
||||
$repository->setUserGroup($userGroup);
|
||||
$piggyBanks = $repository->getPiggyBanks();
|
||||
|
||||
/** @var PiggyBank $piggyBank */
|
||||
foreach ($piggyBanks as $piggyBank) {
|
||||
if (null !== $piggyBank->native_target_amount) {
|
||||
Log::debug(sprintf('Resetting native_target_amount for piggy bank #%d.', $piggyBank->id));
|
||||
$piggyBank->native_target_amount = null;
|
||||
$piggyBank->saveQuietly();
|
||||
}
|
||||
foreach ($piggyBank->accounts as $account) {
|
||||
if (null !== $account->pivot->native_current_amount) {
|
||||
Log::debug(sprintf('Resetting native_current_amount for piggy bank #%d and account #%d.', $piggyBank->id, $account->id));
|
||||
$account->pivot->native_current_amount = null;
|
||||
$account->pivot->save();
|
||||
}
|
||||
}
|
||||
foreach ($piggyBank->piggyBankEvents as $event) {
|
||||
if (null !== $event->native_amount) {
|
||||
Log::debug(sprintf('Resetting native_amount for piggy bank #%d and event #%d.', $piggyBank->id, $event->id));
|
||||
$event->native_amount = null;
|
||||
$event->saveQuietly();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function resetBudgets(UserGroup $userGroup): void
|
||||
{
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$repository->setUserGroup($userGroup);
|
||||
$set = $repository->getBudgets();
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($set as $budget) {
|
||||
foreach ($budget->autoBudgets as $autoBudget) {
|
||||
if (null !== $autoBudget->native_amount) {
|
||||
if (null !== $autoBudget->native_amount) {
|
||||
Log::debug(sprintf('Resetting native_amount for budget #%d and auto budget #%d.', $budget->id, $autoBudget->id));
|
||||
$autoBudget->native_amount = null;
|
||||
$autoBudget->saveQuietly();
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($budget->budgetlimits as $limit) {
|
||||
if (null !== $limit->native_amount) {
|
||||
Log::debug(sprintf('Resetting native_amount for budget #%d and budget limit #%d.', $budget->id, $limit->id));
|
||||
$limit->native_amount = null;
|
||||
$limit->saveQuietly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function resetTransactions(UserGroup $userGroup): void
|
||||
{
|
||||
// custom query because of the potential size of this update.
|
||||
$success = DB::table('transactions')
|
||||
->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.user_group_id', $userGroup->id)
|
||||
->where(static function (Builder $q): void {
|
||||
$q->whereNotNull('native_amount')
|
||||
->orWhereNotNull('native_foreign_amount')
|
||||
;
|
||||
})
|
||||
->update(['native_amount' => null, 'native_foreign_amount' => null])
|
||||
;
|
||||
Log::debug(sprintf('Updated %d transactions.', $success));
|
||||
}
|
||||
}
|
||||
@@ -187,14 +187,13 @@ class UserEventHandler
|
||||
*/
|
||||
public function notifyNewIPAddress(DetectedNewIPAddress $event): void
|
||||
{
|
||||
$user = $event->user;
|
||||
$ipAddress = $event->ipAddress;
|
||||
$user = $event->user;
|
||||
|
||||
if ($user->hasRole('demo')) {
|
||||
return; // do not email demo user.
|
||||
}
|
||||
|
||||
$list = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
|
||||
$list = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
|
||||
if (!is_array($list)) {
|
||||
$list = [];
|
||||
}
|
||||
@@ -203,7 +202,7 @@ class UserEventHandler
|
||||
foreach ($list as $index => $entry) {
|
||||
if (false === $entry['notified']) {
|
||||
try {
|
||||
Notification::send($user, new UserLogin($ipAddress));
|
||||
Notification::send($user, new UserLogin());
|
||||
} catch (\Exception $e) { // @phpstan-ignore-line
|
||||
$message = $e->getMessage();
|
||||
if (str_contains($message, 'Bcc')) {
|
||||
@@ -428,7 +427,7 @@ class UserEventHandler
|
||||
app('preferences')->setForUser($user, 'login_ip_history', $preference);
|
||||
|
||||
if (false === $inArray && true === $send) {
|
||||
event(new DetectedNewIPAddress($user, $ip));
|
||||
event(new DetectedNewIPAddress($user));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class AccountObserver
|
||||
@@ -53,4 +56,35 @@ class AccountObserver
|
||||
$account->notes()->delete();
|
||||
$account->locations()->delete();
|
||||
}
|
||||
|
||||
public function created(Account $account): void
|
||||
{
|
||||
Log::debug('Observe "created" of an account.');
|
||||
$this->updateNativeAmount($account);
|
||||
}
|
||||
|
||||
public function updated(Account $account): void
|
||||
{
|
||||
Log::debug('Observe "updated" of an account.');
|
||||
$this->updateNativeAmount($account);
|
||||
}
|
||||
|
||||
private function updateNativeAmount(Account $account): void
|
||||
{
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$currency = $repository->getAccountCurrency($account);
|
||||
if (null !== $currency && $currency->id !== $userCurrency->id && '' !== (string) $account->virtual_balance && 0 !== bccomp($account->virtual_balance, '0')) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$account->native_virtual_balance = $converter->convert($currency, $userCurrency, today(), $account->virtual_balance);
|
||||
|
||||
}
|
||||
if ('' === (string) $account->virtual_balance || ('' !== (string) $account->virtual_balance && 0 === bccomp($account->virtual_balance, '0'))) {
|
||||
$account->virtual_balance = null;
|
||||
$account->native_virtual_balance = null;
|
||||
}
|
||||
$account->saveQuietly();
|
||||
Log::debug('Account native virtual balance is updated.');
|
||||
}
|
||||
}
|
||||
|
||||
57
app/Handlers/Observer/AutoBudgetObserver.php
Normal file
57
app/Handlers/Observer/AutoBudgetObserver.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* AutoBudgetObserver.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AutoBudgetObserver
|
||||
{
|
||||
public function updated(AutoBudget $autoBudget): void
|
||||
{
|
||||
Log::debug('Observe "updated" of an auto budget.');
|
||||
$this->updateNativeAmount($autoBudget);
|
||||
}
|
||||
|
||||
public function created(AutoBudget $autoBudget): void
|
||||
{
|
||||
Log::debug('Observe "created" of an auto budget.');
|
||||
$this->updateNativeAmount($autoBudget);
|
||||
}
|
||||
|
||||
private function updateNativeAmount(AutoBudget $autoBudget): void
|
||||
{
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($autoBudget->budget->user->userGroup);
|
||||
$autoBudget->native_amount = null;
|
||||
if ($autoBudget->transactionCurrency->id !== $userCurrency->id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$autoBudget->native_amount = $converter->convert($autoBudget->transactionCurrency, $userCurrency, today(), $autoBudget->amount);
|
||||
}
|
||||
$autoBudget->saveQuietly();
|
||||
Log::debug('Auto budget native amount is updated.');
|
||||
}
|
||||
}
|
||||
57
app/Handlers/Observer/AvailableBudgetObserver.php
Normal file
57
app/Handlers/Observer/AvailableBudgetObserver.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* AutoBudgetObserver.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AvailableBudgetObserver
|
||||
{
|
||||
public function updated(AvailableBudget $availableBudget): void
|
||||
{
|
||||
Log::debug('Observe "updated" of an available budget.');
|
||||
$this->updateNativeAmount($availableBudget);
|
||||
}
|
||||
|
||||
public function created(AvailableBudget $availableBudget): void
|
||||
{
|
||||
Log::debug('Observe "created" of an available budget.');
|
||||
$this->updateNativeAmount($availableBudget);
|
||||
}
|
||||
|
||||
private function updateNativeAmount(AvailableBudget $availableBudget): void
|
||||
{
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($availableBudget->user->userGroup);
|
||||
$availableBudget->native_amount = null;
|
||||
if ($availableBudget->transactionCurrency->id !== $userCurrency->id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$availableBudget->native_amount = $converter->convert($availableBudget->transactionCurrency, $userCurrency, today(), $availableBudget->amount);
|
||||
}
|
||||
$availableBudget->saveQuietly();
|
||||
Log::debug('Available budget native amount is updated.');
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,8 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class BillObserver
|
||||
@@ -38,4 +40,31 @@ class BillObserver
|
||||
}
|
||||
$bill->notes()->delete();
|
||||
}
|
||||
|
||||
public function updated(Bill $bill): void
|
||||
{
|
||||
Log::debug('Observe "updated" of a bill.');
|
||||
$this->updateNativeAmount($bill);
|
||||
}
|
||||
|
||||
public function created(Bill $bill): void
|
||||
{
|
||||
Log::debug('Observe "created" of a bill.');
|
||||
$this->updateNativeAmount($bill);
|
||||
}
|
||||
|
||||
private function updateNativeAmount(Bill $bill): void
|
||||
{
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($bill->user->userGroup);
|
||||
$bill->native_amount_min = null;
|
||||
$bill->native_amount_max = null;
|
||||
if ($bill->transactionCurrency->id !== $userCurrency->id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$bill->native_amount_min = $converter->convert($bill->transactionCurrency, $userCurrency, today(), $bill->amount_min);
|
||||
$bill->native_amount_max = $converter->convert($bill->transactionCurrency, $userCurrency, today(), $bill->amount_max);
|
||||
}
|
||||
$bill->saveQuietly();
|
||||
Log::debug('Bill native amounts are updated.');
|
||||
}
|
||||
}
|
||||
|
||||
57
app/Handlers/Observer/BudgetLimitObserver.php
Normal file
57
app/Handlers/Observer/BudgetLimitObserver.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* BudgetLimitObserver.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class BudgetLimitObserver
|
||||
{
|
||||
public function updated(BudgetLimit $budgetLimit): void
|
||||
{
|
||||
Log::debug('Observe "updated" of a budget limit.');
|
||||
$this->updateNativeAmount($budgetLimit);
|
||||
}
|
||||
|
||||
public function created(BudgetLimit $budgetLimit): void
|
||||
{
|
||||
Log::debug('Observe "created" of a budget limit.');
|
||||
$this->updateNativeAmount($budgetLimit);
|
||||
}
|
||||
|
||||
private function updateNativeAmount(BudgetLimit $budgetLimit): void
|
||||
{
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($budgetLimit->budget->user->userGroup);
|
||||
$budgetLimit->native_amount = null;
|
||||
if ($budgetLimit->transactionCurrency->id !== $userCurrency->id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$budgetLimit->native_amount = $converter->convert($budgetLimit->transactionCurrency, $userCurrency, today(), $budgetLimit->amount);
|
||||
}
|
||||
$budgetLimit->saveQuietly();
|
||||
Log::debug('Budget limit native amounts are updated.');
|
||||
}
|
||||
}
|
||||
57
app/Handlers/Observer/PiggyBankEventObserver.php
Normal file
57
app/Handlers/Observer/PiggyBankEventObserver.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* AutoBudgetObserver.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PiggyBankEventObserver
|
||||
{
|
||||
public function updated(PiggyBankEvent $event): void
|
||||
{
|
||||
Log::debug('Observe "updated" of a piggy bank event.');
|
||||
$this->updateNativeAmount($event);
|
||||
}
|
||||
|
||||
public function created(PiggyBankEvent $event): void
|
||||
{
|
||||
Log::debug('Observe "created" of a piggy bank event.');
|
||||
$this->updateNativeAmount($event);
|
||||
}
|
||||
|
||||
private function updateNativeAmount(PiggyBankEvent $event): void
|
||||
{
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($event->piggyBank->accounts()->first()->user->userGroup);
|
||||
$event->native_amount = null;
|
||||
if ($event->piggyBank->transactionCurrency->id !== $userCurrency->id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$event->native_amount = $converter->convert($event->piggyBank->transactionCurrency, $userCurrency, today(), $event->amount);
|
||||
}
|
||||
$event->saveQuietly();
|
||||
Log::debug('Piggy bank event native amount is updated.');
|
||||
}
|
||||
}
|
||||
@@ -25,25 +25,46 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class PiggyBankObserver
|
||||
*/
|
||||
class PiggyBankObserver
|
||||
{
|
||||
public function updated(PiggyBank $piggyBank): void
|
||||
{
|
||||
Log::debug('Observe "updated" of a piggy bank.');
|
||||
$this->updateNativeAmount($piggyBank);
|
||||
}
|
||||
|
||||
public function created(PiggyBank $piggyBank): void
|
||||
{
|
||||
app('log')->debug('Observe "created" of a piggy bank. DO NOTHING.');
|
||||
Log::debug('Observe "created" of a piggy bank.');
|
||||
$this->updateNativeAmount($piggyBank);
|
||||
}
|
||||
|
||||
// $repetition = new PiggyBankRepetition();
|
||||
// $repetition->piggyBank()->associate($piggyBank);
|
||||
// $repetition->start_date = $piggyBank->start_date;
|
||||
// $repetition->start_date_tz = $piggyBank->start_date->format('e');
|
||||
// $repetition->target_date = $piggyBank->target_date;
|
||||
// $repetition->target_date_tz = $piggyBank->target_date?->format('e');
|
||||
// $repetition->current_amount = '0';
|
||||
// $repetition->save();
|
||||
private function updateNativeAmount(PiggyBank $piggyBank): void
|
||||
{
|
||||
$group = $piggyBank->accounts()->first()?->user->userGroup;
|
||||
if (null === $group) {
|
||||
Log::debug(sprintf('No account(s) yet for piggy bank #%d.', $piggyBank->id));
|
||||
|
||||
return;
|
||||
}
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($group);
|
||||
if (null === $userCurrency) {
|
||||
return;
|
||||
}
|
||||
$piggyBank->native_target_amount = null;
|
||||
if ($piggyBank->transactionCurrency->id !== $userCurrency->id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$piggyBank->native_target_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $piggyBank->target_amount);
|
||||
}
|
||||
$piggyBank->saveQuietly();
|
||||
Log::debug('Piggy bank native target amount is updated.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -32,6 +33,8 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class TransactionObserver
|
||||
{
|
||||
public static bool $recalculate = true;
|
||||
|
||||
public function deleting(?Transaction $transaction): void
|
||||
{
|
||||
app('log')->debug('Observe "deleting" of a transaction.');
|
||||
@@ -41,22 +44,46 @@ class TransactionObserver
|
||||
public function updated(Transaction $transaction): void
|
||||
{
|
||||
Log::debug('Observe "updated" of a transaction.');
|
||||
if (config('firefly.feature_flags.running_balance_column')) {
|
||||
if (config('firefly.feature_flags.running_balance_column') && self::$recalculate) {
|
||||
if (1 === bccomp($transaction->amount, '0')) {
|
||||
Log::debug('Trigger recalculateForJournal');
|
||||
AccountBalanceCalculator::recalculateForJournal($transaction->transactionJournal);
|
||||
}
|
||||
}
|
||||
$this->updateNativeAmount($transaction);
|
||||
}
|
||||
|
||||
public function created(Transaction $transaction): void
|
||||
{
|
||||
Log::debug('Observe "created" of a transaction.');
|
||||
if (config('firefly.feature_flags.running_balance_column')) {
|
||||
if (1 === bccomp($transaction->amount, '0')) {
|
||||
if (1 === bccomp($transaction->amount, '0') && self::$recalculate) {
|
||||
Log::debug('Trigger recalculateForJournal');
|
||||
AccountBalanceCalculator::recalculateForJournal($transaction->transactionJournal);
|
||||
}
|
||||
}
|
||||
$this->updateNativeAmount($transaction);
|
||||
}
|
||||
|
||||
private function updateNativeAmount(Transaction $transaction): void
|
||||
{
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($transaction->transactionJournal->user->userGroup);
|
||||
$transaction->native_amount = null;
|
||||
$transaction->native_foreign_amount = null;
|
||||
// first normal amount
|
||||
if ($transaction->transactionCurrency->id !== $userCurrency->id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$transaction->native_amount = $converter->convert($transaction->transactionCurrency, $userCurrency, $transaction->transactionJournal->date, $transaction->amount);
|
||||
}
|
||||
// then foreign amount
|
||||
if ($transaction->foreignCurrency?->id !== $userCurrency->id && null !== $transaction->foreign_amount && null !== $transaction->foreignCurrency) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$transaction->native_foreign_amount = $converter->convert($transaction->foreignCurrency, $userCurrency, $transaction->transactionJournal->date, $transaction->foreign_amount);
|
||||
}
|
||||
|
||||
$transaction->saveQuietly();
|
||||
Log::debug('Transaction native amounts are updated.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +463,6 @@ class GroupCollector implements GroupCollectorInterface
|
||||
$this->query->orWhereIn('transaction_journals.transaction_group_id', $groupIds);
|
||||
}
|
||||
$result = $this->query->get($this->fields);
|
||||
|
||||
// now to parse this into an array.
|
||||
$collection = $this->parseArray($result);
|
||||
|
||||
@@ -1049,6 +1048,7 @@ class GroupCollector implements GroupCollectorInterface
|
||||
->whereNull('transaction_groups.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('source.deleted_at')
|
||||
->whereNotNull('transaction_groups.id')
|
||||
->whereNull('destination.deleted_at')
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
|
||||
60
app/Http/Controllers/ExchangeRates/IndexController.php
Normal file
60
app/Http/Controllers/ExchangeRates/IndexController.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* IndexController.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\ExchangeRates;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
/**
|
||||
* AttachmentController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// translations:
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-exchange');
|
||||
app('view')->share('title', (string) trans('firefly.header_exchange_rates'));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function index(): View
|
||||
{
|
||||
return view('exchange-rates.index');
|
||||
}
|
||||
|
||||
public function rates(TransactionCurrency $from, TransactionCurrency $to): View
|
||||
{
|
||||
return view('exchange-rates.rates', compact('from', 'to'));
|
||||
}
|
||||
}
|
||||
@@ -70,10 +70,8 @@ class IndexController extends Controller
|
||||
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
|
||||
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
||||
$collection = $this->repository->getAll();
|
||||
$total = $collection->count();
|
||||
$collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
|
||||
|
||||
// order so default is on top:
|
||||
// order so default and enabled are on top:
|
||||
$collection = $collection->sortBy(
|
||||
static function (TransactionCurrency $currency) {
|
||||
$default = true === $currency->userGroupDefault ? 0 : 1;
|
||||
@@ -82,6 +80,8 @@ class IndexController extends Controller
|
||||
return sprintf('%s-%s-%s', $default, $enabled, $currency->code);
|
||||
}
|
||||
);
|
||||
$total = $collection->count();
|
||||
$collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
|
||||
|
||||
$currencies = new LengthAwarePaginator($collection, $total, $pageSize, $page);
|
||||
$currencies->setPath(route('currencies.index'));
|
||||
|
||||
@@ -117,7 +117,7 @@ class PiggyBank extends Model
|
||||
|
||||
public function accounts(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Account::class)->withPivot('current_amount');
|
||||
return $this->belongsToMany(Account::class)->withPivot(['current_amount', 'native_current_amount']);
|
||||
}
|
||||
|
||||
public function piggyBankRepetitions(): HasMany
|
||||
|
||||
@@ -40,10 +40,10 @@ class TransactionCurrency extends Model
|
||||
use ReturnsIntegerIdTrait;
|
||||
use SoftDeletes;
|
||||
|
||||
public ?bool $userGroupDefault;
|
||||
public ?bool $userGroupEnabled;
|
||||
public ?bool $userGroupDefault = null;
|
||||
public ?bool $userGroupEnabled = null;
|
||||
protected $casts
|
||||
= [
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
@@ -51,7 +51,7 @@ class TransactionCurrency extends Model
|
||||
'enabled' => 'bool',
|
||||
];
|
||||
|
||||
protected $fillable = ['name', 'code', 'symbol', 'decimal_places', 'enabled'];
|
||||
protected $fillable = ['name', 'code', 'symbol', 'decimal_places', 'enabled'];
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
|
||||
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@@ -150,7 +151,7 @@ class UserGroup extends Model
|
||||
*/
|
||||
public function piggyBanks(): HasManyThrough
|
||||
{
|
||||
return $this->hasManyThrough(PiggyBank::class, Account::class);
|
||||
throw new FireflyException('This user group method is EOL.');
|
||||
}
|
||||
|
||||
public function recurrences(): HasMany
|
||||
|
||||
@@ -27,10 +27,12 @@ namespace FireflyIII\Notifications\Admin;
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -59,8 +61,13 @@ class UnknownUserLoginAttempt extends Notification
|
||||
*/
|
||||
public function toMail(OwnerNotifiable $notifiable): MailMessage
|
||||
{
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return new MailMessage()
|
||||
->markdown('emails.owner.unknown-user', ['address' => $this->address])
|
||||
->markdown('emails.owner.unknown-user', ['address' => $this->address, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])
|
||||
->subject((string) trans('email.unknown_user_subject'))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -28,11 +28,13 @@ use FireflyIII\Models\InvitedUser;
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -66,8 +68,14 @@ class UserInvitation extends Notification
|
||||
*/
|
||||
public function toMail(OwnerNotifiable $notifiable)
|
||||
{
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
|
||||
return (new MailMessage())
|
||||
->markdown('emails.invitation-created', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email])
|
||||
->markdown('emails.invitation-created', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])
|
||||
->subject((string) trans('email.invitation_created_subject'))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -27,12 +27,14 @@ namespace FireflyIII\Notifications\Admin;
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -66,8 +68,13 @@ class UserRegistration extends Notification
|
||||
*/
|
||||
public function toMail(OwnerNotifiable $notifiable)
|
||||
{
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())
|
||||
->markdown('emails.registered-admin', ['email' => $this->user->email, 'id' => $this->user->id])
|
||||
->markdown('emails.registered-admin', ['email' => $this->user->email, 'id' => $this->user->id, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])
|
||||
->subject((string) trans('email.registered_subject_admin'))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -59,9 +61,13 @@ class DisabledMFANotification extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.disabled_mfa_subject');
|
||||
$subject = (string) trans('email.disabled_mfa_subject');
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.disabled-mfa', ['user' => $this->user])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.disabled-mfa', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
public function toNtfy(User $notifiable): Message
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -59,9 +61,13 @@ class EnabledMFANotification extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.enabled_mfa_subject');
|
||||
$subject = (string) trans('email.enabled_mfa_subject');
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.enabled-mfa', ['user' => $this->user])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.enabled-mfa', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
public function toNtfy(User $notifiable): Message
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -61,9 +63,13 @@ class MFABackupFewLeftNotification extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.mfa_few_backups_left_subject', ['count' => $this->count]);
|
||||
$subject = (string) trans('email.mfa_few_backups_left_subject', ['count' => $this->count]);
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.few-backup-codes', ['user' => $this->user, 'count' => $this->count])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.few-backup-codes', ['user' => $this->user, 'count' => $this->count, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -59,9 +61,13 @@ class MFABackupNoLeftNotification extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.mfa_no_backups_left_subject');
|
||||
$subject = (string) trans('email.mfa_no_backups_left_subject');
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.no-backup-codes', ['user' => $this->user])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.no-backup-codes', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -58,9 +60,13 @@ class MFAManyFailedAttemptsNotification extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.mfa_many_failed_subject', ['count' => $this->count]);
|
||||
$subject = (string) trans('email.mfa_many_failed_subject', ['count' => $this->count]);
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.many-failed-attempts', ['user' => $this->user, 'count' => $this->count])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.many-failed-attempts', ['user' => $this->user, 'count' => $this->count, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -59,9 +61,13 @@ class MFAUsedBackupCodeNotification extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.used_backup_code_subject');
|
||||
$subject = (string) trans('email.used_backup_code_subject');
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.used-backup-code', ['user' => $this->user])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.used-backup-code', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -59,9 +61,13 @@ class NewBackupCodesNotification extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.new_backup_codes_subject');
|
||||
$subject = (string) trans('email.new_backup_codes_subject');
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.new-backup-codes', ['user' => $this->user])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.new-backup-codes', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -56,9 +58,13 @@ class UserFailedLoginAttempt extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$subject = (string) trans('email.failed_login_subject');
|
||||
$subject = (string) trans('email.failed_login_subject');
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())->markdown('emails.security.failed-login', ['user' => $this->user])->subject($subject);
|
||||
return (new MailMessage())->markdown('emails.security.failed-login', ['user' => $this->user, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])->subject($subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\User;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -54,8 +56,13 @@ class NewAccessToken extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())
|
||||
->markdown('emails.token-created')
|
||||
->markdown('emails.token-created', ['ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])
|
||||
->subject((string) trans('email.access_token_created_subject'))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications\User;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -42,13 +43,6 @@ class UserLogin extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
private string $ip;
|
||||
|
||||
public function __construct(string $ip)
|
||||
{
|
||||
$this->ip = $ip;
|
||||
}
|
||||
|
||||
public function toArray(User $notifiable)
|
||||
{
|
||||
return [
|
||||
@@ -60,21 +54,26 @@ class UserLogin extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())
|
||||
->markdown('emails.new-ip', ['time' => $time, 'ipAddress' => $this->ip, 'host' => $this->getHost()])
|
||||
->markdown('emails.new-ip', ['ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])
|
||||
->subject((string) trans('email.login_from_new_ip'))
|
||||
;
|
||||
}
|
||||
|
||||
public function toNtfy(User $notifiable): Message
|
||||
{
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$settings = ReturnsSettings::getSettings('ntfy', 'user', $notifiable);
|
||||
$message = new Message();
|
||||
$message->topic($settings['ntfy_topic']);
|
||||
$message->title((string) trans('email.login_from_new_ip'));
|
||||
$message->body((string) trans('email.slack_login_from_new_ip', ['host' => $this->getHost(), 'ip' => $this->ip]));
|
||||
$message->body((string) trans('email.slack_login_from_new_ip', ['ip' => $ip, 'host' => $host]));
|
||||
|
||||
return $message;
|
||||
}
|
||||
@@ -84,7 +83,10 @@ class UserLogin extends Notification
|
||||
*/
|
||||
public function toPushover(User $notifiable): PushoverMessage
|
||||
{
|
||||
return PushoverMessage::create((string) trans('email.slack_login_from_new_ip', ['host' => $this->getHost(), 'ip' => $this->ip]))
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
|
||||
return PushoverMessage::create((string) trans('email.slack_login_from_new_ip', ['ip' => $ip, 'host' => $host]))
|
||||
->title((string) trans('email.login_from_new_ip'))
|
||||
;
|
||||
}
|
||||
@@ -94,7 +96,10 @@ class UserLogin extends Notification
|
||||
*/
|
||||
public function toSlack(User $notifiable)
|
||||
{
|
||||
return new SlackMessage()->content((string) trans('email.slack_login_from_new_ip', ['host' => $this->getHost(), 'ip' => $this->ip]));
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
|
||||
return new SlackMessage()->content((string) trans('email.slack_login_from_new_ip', ['ip' => $ip, 'host' => $host]));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,21 +109,4 @@ class UserLogin extends Notification
|
||||
{
|
||||
return ReturnsAvailableChannels::returnChannels('user', $notifiable);
|
||||
}
|
||||
|
||||
private function getHost(): string
|
||||
{
|
||||
$host = '';
|
||||
|
||||
try {
|
||||
$hostName = app('steam')->getHostName($this->ip);
|
||||
} catch (FireflyException $e) {
|
||||
app('log')->error($e->getMessage());
|
||||
$hostName = $this->ip;
|
||||
}
|
||||
if ($hostName !== $this->ip) {
|
||||
$host = $hostName;
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@ namespace FireflyIII\Notifications\User;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Messages\SlackMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use NotificationChannels\Pushover\PushoverMessage;
|
||||
use Ntfy\Message;
|
||||
|
||||
@@ -62,8 +64,13 @@ class UserNewPassword extends Notification
|
||||
*/
|
||||
public function toMail(User $notifiable)
|
||||
{
|
||||
$ip = Request::ip();
|
||||
$host = Steam::getHostName($ip);
|
||||
$userAgent = Request::userAgent();
|
||||
$time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
|
||||
|
||||
return (new MailMessage())
|
||||
->markdown('emails.password', ['url' => $this->url])
|
||||
->markdown('emails.password', ['url' => $this->url, 'ip' => $ip, 'host' => $host, 'userAgent' => $userAgent, 'time' => $time])
|
||||
->subject((string) trans('email.reset_pw_subject'))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ use FireflyIII\Repositories\Currency\CurrencyRepository;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepository as GroupCurrencyRepository;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface as GroupCurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepository;
|
||||
use FireflyIII\Repositories\UserGroups\ExchangeRate\ExchangeRateRepositoryInterface;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
@@ -71,5 +73,13 @@ class CurrencyServiceProvider extends ServiceProvider
|
||||
return $repository;
|
||||
}
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
ExchangeRateRepositoryInterface::class,
|
||||
static function (Application $app) {
|
||||
// @var ExchangeRateRepository $repository
|
||||
return app(ExchangeRateRepository::class);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
|
||||
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
|
||||
use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject;
|
||||
use FireflyIII\Events\NewVersionAvailable;
|
||||
use FireflyIII\Events\Preferences\UserGroupChangedDefaultCurrency;
|
||||
use FireflyIII\Events\RegisteredUser;
|
||||
use FireflyIII\Events\RequestedNewPassword;
|
||||
use FireflyIII\Events\RequestedReportOnJournals;
|
||||
@@ -59,9 +60,13 @@ use FireflyIII\Events\UserChangedEmail;
|
||||
use FireflyIII\Events\WarnUserAboutBill;
|
||||
use FireflyIII\Handlers\Observer\AccountObserver;
|
||||
use FireflyIII\Handlers\Observer\AttachmentObserver;
|
||||
use FireflyIII\Handlers\Observer\AutoBudgetObserver;
|
||||
use FireflyIII\Handlers\Observer\AvailableBudgetObserver;
|
||||
use FireflyIII\Handlers\Observer\BillObserver;
|
||||
use FireflyIII\Handlers\Observer\BudgetLimitObserver;
|
||||
use FireflyIII\Handlers\Observer\BudgetObserver;
|
||||
use FireflyIII\Handlers\Observer\CategoryObserver;
|
||||
use FireflyIII\Handlers\Observer\PiggyBankEventObserver;
|
||||
use FireflyIII\Handlers\Observer\PiggyBankObserver;
|
||||
use FireflyIII\Handlers\Observer\RecurrenceObserver;
|
||||
use FireflyIII\Handlers\Observer\RecurrenceTransactionObserver;
|
||||
@@ -75,10 +80,14 @@ use FireflyIII\Handlers\Observer\WebhookMessageObserver;
|
||||
use FireflyIII\Handlers\Observer\WebhookObserver;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\AutoBudget;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\Rule;
|
||||
@@ -247,6 +256,10 @@ class EventServiceProvider extends ServiceProvider
|
||||
MFAManyFailedAttempts::class => [
|
||||
'FireflyIII\Handlers\Events\Security\MFAHandler@sendMFAFailedAttemptsMail',
|
||||
],
|
||||
// preferences
|
||||
UserGroupChangedDefaultCurrency::class => [
|
||||
'FireflyIII\Handlers\Events\PreferencesEventHandler@resetNativeAmounts',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -260,11 +273,15 @@ class EventServiceProvider extends ServiceProvider
|
||||
private function registerObservers(): void
|
||||
{
|
||||
Attachment::observe(new AttachmentObserver());
|
||||
PiggyBank::observe(new PiggyBankObserver());
|
||||
Account::observe(new AccountObserver());
|
||||
AutoBudget::observe(new AutoBudgetObserver());
|
||||
AvailableBudget::observe(new AvailableBudgetObserver());
|
||||
Bill::observe(new BillObserver());
|
||||
Budget::observe(new BudgetObserver());
|
||||
BudgetLimit::observe(new BudgetLimitObserver());
|
||||
Category::observe(new CategoryObserver());
|
||||
PiggyBank::observe(new PiggyBankObserver());
|
||||
PiggyBankEvent::observe(new PiggyBankEventObserver());
|
||||
Recurrence::observe(new RecurrenceObserver());
|
||||
RecurrenceTransaction::observe(new RecurrenceTransactionObserver());
|
||||
Rule::observe(new RuleObserver());
|
||||
|
||||
@@ -90,6 +90,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
return CurrencyExchangeRate::create(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'from_currency_id' => $fromCurrency->id,
|
||||
'to_currency_id' => $toCurrency->id,
|
||||
'date' => $date,
|
||||
|
||||
@@ -33,7 +33,7 @@ use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
@@ -59,9 +59,19 @@ trait ModifiesPiggyBanks
|
||||
|
||||
public function removeAmount(PiggyBank $piggyBank, Account $account, string $amount, ?TransactionJournal $journal = null): bool
|
||||
{
|
||||
$currentAmount = $this->getCurrentAmount($piggyBank, $account);
|
||||
$pivot = $piggyBank->accounts()->where('accounts.id', $account->id)->first()->pivot;
|
||||
$pivot->current_amount = bcsub($currentAmount, $amount);
|
||||
$currentAmount = $this->getCurrentAmount($piggyBank, $account);
|
||||
$pivot = $piggyBank->accounts()->where('accounts.id', $account->id)->first()->pivot;
|
||||
$pivot->current_amount = bcsub($currentAmount, $amount);
|
||||
$pivot->native_current_amount = null;
|
||||
|
||||
// also update native_current_amount.
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
||||
if ($userCurrency->id !== $piggyBank->transaction_currency_id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount);
|
||||
}
|
||||
|
||||
$pivot->save();
|
||||
|
||||
Log::debug('ChangedAmount: removeAmount [a]: Trigger change for negative amount.');
|
||||
@@ -90,9 +100,19 @@ trait ModifiesPiggyBanks
|
||||
|
||||
public function addAmount(PiggyBank $piggyBank, Account $account, string $amount, ?TransactionJournal $journal = null): bool
|
||||
{
|
||||
$currentAmount = $this->getCurrentAmount($piggyBank, $account);
|
||||
$pivot = $piggyBank->accounts()->where('accounts.id', $account->id)->first()->pivot;
|
||||
$pivot->current_amount = bcadd($currentAmount, $amount);
|
||||
$currentAmount = $this->getCurrentAmount($piggyBank, $account);
|
||||
$pivot = $piggyBank->accounts()->where('accounts.id', $account->id)->first()->pivot;
|
||||
$pivot->current_amount = bcadd($currentAmount, $amount);
|
||||
$pivot->native_current_amount = null;
|
||||
|
||||
// also update native_current_amount.
|
||||
$userCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
|
||||
if ($userCurrency->id !== $piggyBank->transaction_currency_id) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$converter->setIgnoreSettings(true);
|
||||
$pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount);
|
||||
}
|
||||
|
||||
$pivot->save();
|
||||
|
||||
Log::debug('ChangedAmount: addAmount [b]: Trigger change for positive amount.');
|
||||
@@ -255,12 +275,12 @@ trait ModifiesPiggyBanks
|
||||
{
|
||||
$piggyBank = $this->updateProperties($piggyBank, $data);
|
||||
if (array_key_exists('notes', $data)) {
|
||||
$this->updateNote($piggyBank, (string)$data['notes']);
|
||||
$this->updateNote($piggyBank, (string) $data['notes']);
|
||||
}
|
||||
|
||||
// update the order of the piggy bank:
|
||||
$oldOrder = $piggyBank->order;
|
||||
$newOrder = (int)($data['order'] ?? $oldOrder);
|
||||
$newOrder = (int) ($data['order'] ?? $oldOrder);
|
||||
if ($oldOrder !== $newOrder) {
|
||||
$this->setOrder($piggyBank, $newOrder);
|
||||
}
|
||||
@@ -289,7 +309,7 @@ trait ModifiesPiggyBanks
|
||||
|
||||
// update using name:
|
||||
if (array_key_exists('object_group_title', $data)) {
|
||||
$objectGroupTitle = (string)$data['object_group_title'];
|
||||
$objectGroupTitle = (string) $data['object_group_title'];
|
||||
if ('' !== $objectGroupTitle) {
|
||||
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
|
||||
if (null !== $objectGroup) {
|
||||
@@ -305,7 +325,7 @@ trait ModifiesPiggyBanks
|
||||
|
||||
// try also with ID:
|
||||
if (array_key_exists('object_group_id', $data)) {
|
||||
$objectGroupId = (int)($data['object_group_id'] ?? 0);
|
||||
$objectGroupId = (int) ($data['object_group_id'] ?? 0);
|
||||
if (0 !== $objectGroupId) {
|
||||
$objectGroup = $this->findObjectGroupById($objectGroupId);
|
||||
if (null !== $objectGroup) {
|
||||
|
||||
@@ -242,7 +242,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
return $room;
|
||||
}
|
||||
|
||||
// amount is negative and $currentamount is smaller than $amount
|
||||
// amount is negative and $currentAmount is smaller than $amount
|
||||
if (-1 === bccomp($amount, '0') && 1 === bccomp($compare, $amount)) {
|
||||
app('log')->debug(sprintf('Max amount to remove is %f', $repetition->current_amount));
|
||||
app('log')->debug(sprintf('Cannot remove %f from piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
|
||||
@@ -42,4 +42,13 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
->get()
|
||||
;
|
||||
}
|
||||
|
||||
public function getBudgets(): Collection
|
||||
{
|
||||
return $this->userGroup->budgets()
|
||||
->orderBy('order', 'ASC')
|
||||
->orderBy('name', 'ASC')
|
||||
->get()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ interface BudgetRepositoryInterface
|
||||
{
|
||||
public function getActiveBudgets(): Collection;
|
||||
|
||||
public function getBudgets(): Collection;
|
||||
|
||||
public function setUser(User $user): void;
|
||||
|
||||
public function setUserGroup(UserGroup $userGroup): void;
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\UserGroups\Currency;
|
||||
|
||||
use FireflyIII\Events\Preferences\UserGroupChangedDefaultCurrency;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\TransactionCurrencyFactory;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
@@ -38,6 +39,7 @@ use FireflyIII\Services\Internal\Destroy\CurrencyDestroyService;
|
||||
use FireflyIII\Services\Internal\Update\CurrencyUpdateService;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class CurrencyRepository
|
||||
@@ -77,7 +79,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
}
|
||||
|
||||
// is being used in accounts:
|
||||
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string)$currency->id))->count();
|
||||
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string) $currency->id))->count();
|
||||
if ($meta > 0) {
|
||||
app('log')->info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
|
||||
|
||||
@@ -85,7 +87,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
}
|
||||
|
||||
// second search using integer check.
|
||||
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((int)$currency->id))->count();
|
||||
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((int) $currency->id))->count();
|
||||
if ($meta > 0) {
|
||||
app('log')->info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
|
||||
|
||||
@@ -179,7 +181,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
return $entry->id === $current->id;
|
||||
});
|
||||
$isDefault = $local->contains(static function (TransactionCurrency $entry) use ($current) {
|
||||
return 1 === (int)$entry->pivot->group_default && $entry->id === $current->id;
|
||||
return 1 === (int) $entry->pivot->group_default && $entry->id === $current->id;
|
||||
});
|
||||
$current->userGroupEnabled = $hasId;
|
||||
$current->userGroupDefault = $isDefault;
|
||||
@@ -193,7 +195,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
$all = $this->userGroup->currencies()->orderBy('code', 'ASC')->withPivot(['group_default'])->get();
|
||||
$all->map(static function (TransactionCurrency $current) {
|
||||
$current->userGroupEnabled = true;
|
||||
$current->userGroupDefault = 1 === (int)$current->pivot->group_default;
|
||||
$current->userGroupDefault = 1 === (int) $current->pivot->group_default;
|
||||
|
||||
return $current;
|
||||
});
|
||||
@@ -260,10 +262,10 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
public function findCurrencyNull(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
|
||||
{
|
||||
app('log')->debug('Now in findCurrencyNull()');
|
||||
$result = $this->find((int)$currencyId);
|
||||
$result = $this->find((int) $currencyId);
|
||||
if (null === $result) {
|
||||
app('log')->debug(sprintf('Searching for currency with code %s...', $currencyCode));
|
||||
$result = $this->findByCode((string)$currencyCode);
|
||||
$result = $this->findByCode((string) $currencyCode);
|
||||
}
|
||||
if (null !== $result && false === $result->enabled) {
|
||||
app('log')->debug(sprintf('Also enabled currency %s', $result->code));
|
||||
@@ -308,12 +310,18 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
|
||||
public function makeDefault(TransactionCurrency $currency): void
|
||||
{
|
||||
$current = app('amount')->getDefaultCurrencyByUserGroup($this->userGroup);
|
||||
app('log')->debug(sprintf('Enabled + made default currency %s for user #%d', $currency->code, $this->userGroup->id));
|
||||
$this->userGroup->currencies()->detach($currency->id);
|
||||
foreach ($this->userGroup->currencies()->get() as $item) {
|
||||
$this->userGroup->currencies()->updateExistingPivot($item->id, ['group_default' => false]);
|
||||
}
|
||||
$this->userGroup->currencies()->syncWithoutDetaching([$currency->id => ['group_default' => true]]);
|
||||
if ($current->id !== $currency->id) {
|
||||
Log::debug('Trigger on a different default currency.');
|
||||
// clear all native amounts through an event.
|
||||
event(new UserGroupChangedDefaultCurrency($this->userGroup));
|
||||
}
|
||||
}
|
||||
|
||||
public function searchCurrency(string $search, int $limit): Collection
|
||||
@@ -354,9 +362,6 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
if (false === $enabled && true === $default) {
|
||||
$enabled = true;
|
||||
}
|
||||
if (false === $default) {
|
||||
app('log')->warning(sprintf('Set default=false will NOT do anything for currency %s', $currency->code));
|
||||
}
|
||||
|
||||
// update currency with current user specific settings
|
||||
$currency->refreshForUser($this->user);
|
||||
@@ -375,12 +380,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
|
||||
// currency must be made default.
|
||||
if (true === $default) {
|
||||
app('log')->debug(sprintf('Enabled + made default currency %s for user #%d', $currency->code, $this->userGroup->id));
|
||||
$this->userGroup->currencies()->detach($currency->id);
|
||||
foreach ($this->userGroup->currencies()->get() as $item) {
|
||||
$this->userGroup->currencies()->updateExistingPivot($item->id, ['group_default' => false]);
|
||||
}
|
||||
$this->userGroup->currencies()->syncWithoutDetaching([$currency->id => ['group_default' => true]]);
|
||||
$this->makeDefault($currency);
|
||||
}
|
||||
|
||||
/** @var CurrencyUpdateService $service */
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ExchangeRateRepository.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\UserGroups\ExchangeRate;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ExchangeRateRepository implements ExchangeRateRepositoryInterface
|
||||
{
|
||||
use UserGroupTrait;
|
||||
|
||||
#[\Override]
|
||||
public function getRates(TransactionCurrency $from, TransactionCurrency $to): Collection
|
||||
{
|
||||
return
|
||||
$this->userGroup->currencyExchangeRates()
|
||||
->where(function (Builder $q) use ($from, $to): void {
|
||||
$q->where('from_currency_id', $from->id)
|
||||
->orWhere('to_currency_id', $to->id)
|
||||
;
|
||||
})
|
||||
->orWhere(function (Builder $q) use ($from, $to): void {
|
||||
$q->where('from_currency_id', $to->id)
|
||||
->orWhere('to_currency_id', $from->id)
|
||||
;
|
||||
})
|
||||
->orderBy('date', 'DESC')->get()
|
||||
;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* ExchangeRateRepositoryInterface.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/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\UserGroups\ExchangeRate;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
interface ExchangeRateRepositoryInterface
|
||||
{
|
||||
public function getRates(TransactionCurrency $from, TransactionCurrency $to): Collection;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\UserGroups\PiggyBank;
|
||||
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
@@ -36,14 +37,15 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
|
||||
public function getPiggyBanks(): Collection
|
||||
{
|
||||
return $this->userGroup->piggyBanks()
|
||||
return PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||
->where('accounts.user_group_id', $this->userGroup->id)
|
||||
->with(
|
||||
[
|
||||
'account',
|
||||
'objectGroups',
|
||||
]
|
||||
)
|
||||
->orderBy('order', 'ASC')->get()
|
||||
->orderBy('piggy_banks.order', 'ASC')->distinct()->get(['piggy_banks.*'])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,10 +43,16 @@ class ExchangeRateConverter
|
||||
private bool $noPreparedRates = false;
|
||||
private array $prepared = [];
|
||||
private int $queryCount = 0;
|
||||
private bool $ignoreSettings = false;
|
||||
|
||||
public function setIgnoreSettings(bool $ignoreSettings): void
|
||||
{
|
||||
$this->ignoreSettings = $ignoreSettings;
|
||||
}
|
||||
|
||||
public function enabled(): bool
|
||||
{
|
||||
return false !== config('cer.enabled');
|
||||
return false !== config('cer.enabled') || true === $this->ignoreSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +167,7 @@ class ExchangeRateConverter
|
||||
|
||||
/** @var null|CurrencyExchangeRate $result */
|
||||
$result = auth()->user()
|
||||
->currencyExchangeRates()
|
||||
?->currencyExchangeRates()
|
||||
->where('from_currency_id', $from)
|
||||
->where('to_currency_id', $to)
|
||||
->where('date', '<=', $date)
|
||||
|
||||
@@ -243,7 +243,7 @@ class AccountBalanceCalculator
|
||||
$object->balance = $balance[0];
|
||||
$object->date = $balance[1];
|
||||
$object->date_tz = $balance[1]?->format('e');
|
||||
$object->save();
|
||||
$object->saveQuietly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ class Navigation
|
||||
public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon
|
||||
{
|
||||
$date = clone $theDate;
|
||||
Log::debug(sprintf('Now in startOfPeriod("%s", "%s")', $date->toIso8601String(), $repeatFreq));
|
||||
// Log::debug(sprintf('Now in startOfPeriod("%s", "%s")', $date->toIso8601String(), $repeatFreq));
|
||||
$functionMap = [
|
||||
'1D' => 'startOfDay',
|
||||
'daily' => 'startOfDay',
|
||||
@@ -186,25 +186,25 @@ class Navigation
|
||||
|
||||
if (array_key_exists($repeatFreq, $functionMap)) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
Log::debug(sprintf('Function is ->%s()', $function));
|
||||
// Log::debug(sprintf('Function is ->%s()', $function));
|
||||
if (array_key_exists($function, $parameterMap)) {
|
||||
Log::debug(sprintf('Parameter map, function becomes ->%s(%s)', $function, implode(', ', $parameterMap[$function])));
|
||||
// Log::debug(sprintf('Parameter map, function becomes ->%s(%s)', $function, implode(', ', $parameterMap[$function])));
|
||||
$date->{$function}($parameterMap[$function][0]); // @phpstan-ignore-line
|
||||
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
$date->{$function}(); // @phpstan-ignore-line
|
||||
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
|
||||
return $date;
|
||||
}
|
||||
if ('half-year' === $repeatFreq || '6M' === $repeatFreq) {
|
||||
$skipTo = $date->month > 7 ? 6 : 0;
|
||||
$date->startOfYear()->addMonths($skipTo);
|
||||
Log::debug(sprintf('Custom call for "%s": addMonths(%d)', $repeatFreq, $skipTo));
|
||||
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
// Log::debug(sprintf('Custom call for "%s": addMonths(%d)', $repeatFreq, $skipTo));
|
||||
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
|
||||
return $date;
|
||||
}
|
||||
@@ -220,13 +220,13 @@ class Navigation
|
||||
default => null,
|
||||
};
|
||||
if (null !== $result) {
|
||||
Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
// Log::debug(sprintf('Result is "%s"', $date->toIso8601String()));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ('custom' === $repeatFreq) {
|
||||
Log::debug(sprintf('Custom, result is "%s"', $date->toIso8601String()));
|
||||
// Log::debug(sprintf('Custom, result is "%s"', $date->toIso8601String()));
|
||||
|
||||
return $date; // the date is already at the start.
|
||||
}
|
||||
@@ -238,7 +238,7 @@ class Navigation
|
||||
public function endOfPeriod(Carbon $end, string $repeatFreq): Carbon
|
||||
{
|
||||
$currentEnd = clone $end;
|
||||
Log::debug(sprintf('Now in endOfPeriod("%s", "%s").', $currentEnd->toIso8601String(), $repeatFreq));
|
||||
// Log::debug(sprintf('Now in endOfPeriod("%s", "%s").', $currentEnd->toIso8601String(), $repeatFreq));
|
||||
|
||||
$functionMap = [
|
||||
'1D' => 'endOfDay',
|
||||
@@ -327,7 +327,7 @@ class Navigation
|
||||
if (in_array($repeatFreq, $subDay, true)) {
|
||||
$currentEnd->subDay();
|
||||
}
|
||||
Log::debug(sprintf('Final result: %s', $currentEnd->toIso8601String()));
|
||||
// Log::debug(sprintf('Final result: %s', $currentEnd->toIso8601String()));
|
||||
|
||||
return $currentEnd;
|
||||
}
|
||||
|
||||
@@ -770,13 +770,20 @@ class Steam
|
||||
*/
|
||||
public function getHostName(string $ipAddress): string
|
||||
{
|
||||
$host = '';
|
||||
|
||||
try {
|
||||
$hostName = gethostbyaddr($ipAddress);
|
||||
} catch (\Exception $e) { // intentional generic exception
|
||||
throw new FireflyException($e->getMessage(), 0, $e);
|
||||
} catch (\Exception $e) {
|
||||
app('log')->error($e->getMessage());
|
||||
$hostName = $ipAddress;
|
||||
}
|
||||
|
||||
return (string) $hostName;
|
||||
if ('' !== (string) $hostName && $hostName !== $ipAddress) {
|
||||
$host = $hostName;
|
||||
}
|
||||
|
||||
return (string) $host;
|
||||
}
|
||||
|
||||
public function getLastActivities(array $accounts): array
|
||||
|
||||
73
app/Transformers/V2/ExchangeRateTransformer.php
Normal file
73
app/Transformers/V2/ExchangeRateTransformer.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* AccountTransformer.php
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Transformers\V2;
|
||||
|
||||
use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class AccountTransformer
|
||||
*/
|
||||
class ExchangeRateTransformer extends AbstractTransformer
|
||||
{
|
||||
/**
|
||||
* This method collects meta-data for one or all accounts in the transformer's collection.
|
||||
*/
|
||||
public function collectMetaData(Collection $objects): Collection
|
||||
{
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the account.
|
||||
*/
|
||||
public function transform(CurrencyExchangeRate $rate): array
|
||||
{
|
||||
return [
|
||||
'id' => (string) $rate->id,
|
||||
'created_at' => $rate->created_at->toAtomString(),
|
||||
'updated_at' => $rate->updated_at->toAtomString(),
|
||||
|
||||
'from_currency_id' => (string) $rate->fromCurrency->id,
|
||||
'from_currency_code' => $rate->fromCurrency->code,
|
||||
'from_currency_symbol' => $rate->fromCurrency->symbol,
|
||||
'from_currency_decimal_places' => $rate->fromCurrency->decimal_places,
|
||||
|
||||
'to_currency_id' => (string) $rate->toCurrency->id,
|
||||
'to_currency_code' => $rate->toCurrency->code,
|
||||
'to_currency_symbol' => $rate->toCurrency->symbol,
|
||||
'to_currency_decimal_places' => $rate->toCurrency->decimal_places,
|
||||
|
||||
'rate' => $rate->rate,
|
||||
'date' => $rate->date->toAtomString(),
|
||||
'links' => [
|
||||
[
|
||||
'rel' => 'self',
|
||||
'uri' => sprintf('/exchange-rates/%s', $rate->id),
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
94
composer.lock
generated
94
composer.lock
generated
@@ -545,12 +545,12 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Diglactic\\Breadcrumbs\\ServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Breadcrumbs": "Diglactic\\Breadcrumbs\\Breadcrumbs"
|
||||
}
|
||||
},
|
||||
"providers": [
|
||||
"Diglactic\\Breadcrumbs\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -3938,16 +3938,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/oauth2-server",
|
||||
"version": "8.5.4",
|
||||
"version": "8.5.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/oauth2-server.git",
|
||||
"reference": "ab7714d073844497fd222d5d0a217629089936bc"
|
||||
"reference": "cc8778350f905667e796b3c2364a9d3bd7a73518"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/ab7714d073844497fd222d5d0a217629089936bc",
|
||||
"reference": "ab7714d073844497fd222d5d0a217629089936bc",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/cc8778350f905667e796b3c2364a9d3bd7a73518",
|
||||
"reference": "cc8778350f905667e796b3c2364a9d3bd7a73518",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4014,7 +4014,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/oauth2-server/issues",
|
||||
"source": "https://github.com/thephpleague/oauth2-server/tree/8.5.4"
|
||||
"source": "https://github.com/thephpleague/oauth2-server/tree/8.5.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4022,7 +4022,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-08-25T22:35:12+00:00"
|
||||
"time": "2024-12-20T23:06:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/uri",
|
||||
@@ -4439,16 +4439,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.8.2",
|
||||
"version": "3.8.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947"
|
||||
"reference": "f01cfa96468f4c38325f507ab81a4f1d2cd93cfe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e1268cdbc486d97ce23fef2c666dc3c6b6de9947",
|
||||
"reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/f01cfa96468f4c38325f507ab81a4f1d2cd93cfe",
|
||||
"reference": "f01cfa96468f4c38325f507ab81a4f1d2cd93cfe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4480,10 +4480,6 @@
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev",
|
||||
"dev-2.x": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Carbon\\Laravel\\ServiceProvider"
|
||||
@@ -4493,6 +4489,10 @@
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-2.x": "2.x-dev",
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -4541,7 +4541,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-07T17:46:48+00:00"
|
||||
"time": "2024-12-21T18:03:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
@@ -10363,31 +10363,33 @@
|
||||
},
|
||||
{
|
||||
"name": "tijsverkoyen/css-to-inline-styles",
|
||||
"version": "v2.2.7",
|
||||
"version": "v2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
|
||||
"reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb"
|
||||
"reference": "0d72ac1c00084279c1816675284073c5a337c20d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb",
|
||||
"reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb",
|
||||
"url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0d72ac1c00084279c1816675284073c5a337c20d",
|
||||
"reference": "0d72ac1c00084279c1816675284073c5a337c20d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"php": "^5.5 || ^7.0 || ^8.0",
|
||||
"symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
|
||||
"php": "^7.4 || ^8.0",
|
||||
"symfony/css-selector": "^5.4 || ^6.0 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10"
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^8.5.21 || ^9.5.10"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.2.x-dev"
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -10410,9 +10412,9 @@
|
||||
"homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
|
||||
"support": {
|
||||
"issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
|
||||
"source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7"
|
||||
"source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.3.0"
|
||||
},
|
||||
"time": "2023-12-08T13:03:43+00:00"
|
||||
"time": "2024-12-21T16:25:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
@@ -11229,13 +11231,13 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -11670,16 +11672,16 @@
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
"version": "v1.23.4",
|
||||
"version": "v1.23.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/maximebf/php-debugbar.git",
|
||||
"reference": "0815f47bdd867b816b4bf2ca1c7bd7f89e1527ca"
|
||||
"url": "https://github.com/php-debugbar/php-debugbar.git",
|
||||
"reference": "eeabd61a1f19ba5dcd5ac4585a477130ee03ce25"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0815f47bdd867b816b4bf2ca1c7bd7f89e1527ca",
|
||||
"reference": "0815f47bdd867b816b4bf2ca1c7bd7f89e1527ca",
|
||||
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/eeabd61a1f19ba5dcd5ac4585a477130ee03ce25",
|
||||
"reference": "eeabd61a1f19ba5dcd5ac4585a477130ee03ce25",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -11731,10 +11733,10 @@
|
||||
"debugbar"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/maximebf/php-debugbar/issues",
|
||||
"source": "https://github.com/maximebf/php-debugbar/tree/v1.23.4"
|
||||
"issues": "https://github.com/php-debugbar/php-debugbar/issues",
|
||||
"source": "https://github.com/php-debugbar/php-debugbar/tree/v1.23.5"
|
||||
},
|
||||
"time": "2024-12-05T10:36:51+00:00"
|
||||
"time": "2024-12-15T19:20:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
@@ -12825,16 +12827,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "10.5.39",
|
||||
"version": "10.5.40",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "4e89eff200b801db58f3d580ad7426431949eaa9"
|
||||
"reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4e89eff200b801db58f3d580ad7426431949eaa9",
|
||||
"reference": "4e89eff200b801db58f3d580ad7426431949eaa9",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6ddda95af52f69c1e0c7b4f977cccb58048798c",
|
||||
"reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -12906,7 +12908,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.39"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.40"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -12922,7 +12924,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-11T10:51:07+00:00"
|
||||
"time": "2024-12-21T05:49:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
|
||||
@@ -270,6 +270,10 @@ return [
|
||||
'response',
|
||||
'visit_webhook_url',
|
||||
'reset_webhook_secret',
|
||||
'header_exchange_rates',
|
||||
'exchange_rates_intro',
|
||||
'exchange_rates_from_to',
|
||||
'exchange_rates_intro_rates',
|
||||
],
|
||||
'form' => [
|
||||
'url',
|
||||
@@ -286,6 +290,8 @@ return [
|
||||
'webhook_response',
|
||||
'webhook_trigger',
|
||||
'webhook_delivery',
|
||||
'from_currency_to_currency',
|
||||
'to_currency_from_currency',
|
||||
],
|
||||
'list' => [
|
||||
'active',
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
private array $tables = [
|
||||
// !!! this array is also in PreferencesEventHandler + RecalculateNativeAmountsCommand
|
||||
'accounts' => ['native_virtual_balance'], // works.
|
||||
'account_piggy_bank' => ['native_current_amount'], // works
|
||||
'auto_budgets' => ['native_amount'], // works
|
||||
'available_budgets' => ['native_amount'], // works
|
||||
'bills' => ['native_amount_min', 'native_amount_max'], // works
|
||||
'budget_limits' => ['native_amount'], // works
|
||||
'piggy_bank_events' => ['native_amount'], // works
|
||||
'piggy_banks' => ['native_target_amount'], // works
|
||||
'transactions' => ['native_amount', 'native_foreign_amount'], // works
|
||||
|
||||
// TODO button to recalculate all native amounts on selected pages?
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
foreach ($this->tables as $table => $fields) {
|
||||
foreach ($fields as $field) {
|
||||
Schema::table($table, static function (Blueprint $table) use ($field): void {
|
||||
// add amount column
|
||||
$table->decimal($field, 32, 12)->nullable();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
foreach ($this->tables as $table => $fields) {
|
||||
foreach ($fields as $field) {
|
||||
Schema::table($table, static function (Blueprint $table) use ($field): void {
|
||||
// add amount column
|
||||
$table->dropColumn($field);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
241
package-lock.json
generated
241
package-lock.json
generated
@@ -44,9 +44,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ag-grid-community/styles": {
|
||||
"version": "33.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@ag-grid-community/styles/-/styles-33.0.2.tgz",
|
||||
"integrity": "sha512-oMUdolN8l34k6ubLQm3AiO53SqB59YbPDSanVDrwiN7xIq5NGczVQ2Yks032XWqa0bMYkLU9L9opCBSCwZdKsg==",
|
||||
"version": "33.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@ag-grid-community/styles/-/styles-33.0.3.tgz",
|
||||
"integrity": "sha512-1bXrYoVj5TIpLvyjgXHvKnYrC0/JvrdGDdJ3mYfT58GulDt1iNQqhjxMnZB+sxMdQoOc681jmKTGcWzOEDE1Dw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
@@ -2574,9 +2574,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz",
|
||||
"integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz",
|
||||
"integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -2588,9 +2588,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz",
|
||||
"integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz",
|
||||
"integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2602,9 +2602,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz",
|
||||
"integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz",
|
||||
"integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2616,9 +2616,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz",
|
||||
"integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz",
|
||||
"integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2630,9 +2630,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz",
|
||||
"integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz",
|
||||
"integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2644,9 +2644,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz",
|
||||
"integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz",
|
||||
"integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2658,9 +2658,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz",
|
||||
"integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz",
|
||||
"integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -2672,9 +2672,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz",
|
||||
"integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz",
|
||||
"integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -2686,9 +2686,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz",
|
||||
"integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz",
|
||||
"integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2700,9 +2700,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz",
|
||||
"integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz",
|
||||
"integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2714,9 +2714,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz",
|
||||
"integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz",
|
||||
"integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -2728,9 +2728,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz",
|
||||
"integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz",
|
||||
"integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -2742,9 +2742,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz",
|
||||
"integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz",
|
||||
"integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -2756,9 +2756,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz",
|
||||
"integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz",
|
||||
"integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -2770,9 +2770,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz",
|
||||
"integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz",
|
||||
"integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2784,9 +2784,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz",
|
||||
"integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz",
|
||||
"integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2798,9 +2798,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz",
|
||||
"integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz",
|
||||
"integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2812,9 +2812,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz",
|
||||
"integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz",
|
||||
"integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -2826,9 +2826,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz",
|
||||
"integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz",
|
||||
"integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -4431,9 +4431,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001689",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001689.tgz",
|
||||
"integrity": "sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==",
|
||||
"version": "1.0.30001690",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
|
||||
"integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -5646,9 +5646,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.74",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz",
|
||||
"integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==",
|
||||
"version": "1.5.75",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz",
|
||||
"integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -5703,9 +5703,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.17.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz",
|
||||
"integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -6932,9 +6932,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/i18next": {
|
||||
"version": "24.1.2",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-24.1.2.tgz",
|
||||
"integrity": "sha512-th/075GW0Ub1gYDMHLiZXMGSfGv1aP1VqjT3fma/12hNHCNlH8oJMftvlDzycT/R+KoULWk+xLU8H1JRwV85qw==",
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.0.tgz",
|
||||
"integrity": "sha512-ArJJTS1lV6lgKH7yEf4EpgNZ7+THl7bsGxxougPYiXRTJ/Fe1j08/TBpV9QsXCIYVfdE/HWG/xLezJ5DOlfBOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -7219,9 +7219,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz",
|
||||
"integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==",
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -7442,9 +7442,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-stable-stringify": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.2.0.tgz",
|
||||
"integrity": "sha512-ex8jk9BZHBolvbd5cRnAgwyaYcYB0qZldy1e+LCOdcF6+AUmVZ6LcGUMzsRTW83QMeu+GxZGrcLqxqrgfXGvIw==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.2.1.tgz",
|
||||
"integrity": "sha512-Lp6HbbBgosLmJbjx0pBLbgvx68FaFU1sdkmBuckmhhJ88kL13OA51CDtR2yJB50eCNMH9wRqtQNNiAqQH4YXnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -7845,9 +7845,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz",
|
||||
"integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -8368,15 +8368,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/object.assign": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
|
||||
"integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
|
||||
"integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.5",
|
||||
"call-bind": "^1.0.8",
|
||||
"call-bound": "^1.0.3",
|
||||
"define-properties": "^1.2.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"es-object-atoms": "^1.0.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"object-keys": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -9843,9 +9845,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.9",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz",
|
||||
"integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==",
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -9856,6 +9858,9 @@
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
@@ -9940,9 +9945,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz",
|
||||
"integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==",
|
||||
"version": "4.29.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz",
|
||||
"integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -9956,25 +9961,25 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.28.1",
|
||||
"@rollup/rollup-android-arm64": "4.28.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.28.1",
|
||||
"@rollup/rollup-darwin-x64": "4.28.1",
|
||||
"@rollup/rollup-freebsd-arm64": "4.28.1",
|
||||
"@rollup/rollup-freebsd-x64": "4.28.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.28.1",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.28.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.28.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.28.1",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.28.1",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.28.1",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.28.1",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.28.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.28.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.28.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.28.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.28.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.28.1",
|
||||
"@rollup/rollup-android-arm-eabi": "4.29.1",
|
||||
"@rollup/rollup-android-arm64": "4.29.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.29.1",
|
||||
"@rollup/rollup-darwin-x64": "4.29.1",
|
||||
"@rollup/rollup-freebsd-arm64": "4.29.1",
|
||||
"@rollup/rollup-freebsd-x64": "4.29.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.29.1",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.29.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.29.1",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.29.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.29.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.29.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.29.1",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@@ -10051,9 +10056,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sass/node_modules/chokidar": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.2.tgz",
|
||||
"integrity": "sha512-/b57FK+bblSU+dfewfFe0rT1YjVDfOmeLQwCAuC+vwvgLkXboATqqmy+Ipux6JrF6L5joe5CBnFOw+gLWH6yKg==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -11250,13 +11255,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.3.tgz",
|
||||
"integrity": "sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==",
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.5.tgz",
|
||||
"integrity": "sha512-akD5IAH/ID5imgue2DYhzsEwCi0/4VKY31uhMLEYJwPP4TiUp8pL5PIK+Wo7H8qT8JY9i+pVfPydcFPYD1EL7g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.24.0",
|
||||
"esbuild": "0.24.0",
|
||||
"postcss": "^8.4.49",
|
||||
"rollup": "^4.23.0"
|
||||
},
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"/build/webhooks/create.js": "/build/webhooks/create.js",
|
||||
"/build/webhooks/edit.js": "/build/webhooks/edit.js",
|
||||
"/build/webhooks/show.js": "/build/webhooks/show.js",
|
||||
"/build/exchange-rates/index.js": "/build/exchange-rates/index.js",
|
||||
"/build/exchange-rates/rates.js": "/build/exchange-rates/rates.js",
|
||||
"/public/v1/js/app.js": "/public/v1/js/app.js",
|
||||
"/public/v1/js/app.js.LICENSE.txt": "/public/v1/js/app.js.LICENSE.txt",
|
||||
"/public/v1/js/app_vue.js": "/public/v1/js/app_vue.js",
|
||||
@@ -16,6 +18,10 @@
|
||||
"/public/v1/js/create_transaction.js.LICENSE.txt": "/public/v1/js/create_transaction.js.LICENSE.txt",
|
||||
"/public/v1/js/edit_transaction.js": "/public/v1/js/edit_transaction.js",
|
||||
"/public/v1/js/edit_transaction.js.LICENSE.txt": "/public/v1/js/edit_transaction.js.LICENSE.txt",
|
||||
"/public/v1/js/exchange-rates/index.js": "/public/v1/js/exchange-rates/index.js",
|
||||
"/public/v1/js/exchange-rates/index.js.LICENSE.txt": "/public/v1/js/exchange-rates/index.js.LICENSE.txt",
|
||||
"/public/v1/js/exchange-rates/rates.js": "/public/v1/js/exchange-rates/rates.js",
|
||||
"/public/v1/js/exchange-rates/rates.js.LICENSE.txt": "/public/v1/js/exchange-rates/rates.js.LICENSE.txt",
|
||||
"/public/v1/js/ff/accounts/create.js": "/public/v1/js/ff/accounts/create.js",
|
||||
"/public/v1/js/ff/accounts/edit-reconciliation.js": "/public/v1/js/ff/accounts/edit-reconciliation.js",
|
||||
"/public/v1/js/ff/accounts/edit.js": "/public/v1/js/ff/accounts/edit.js",
|
||||
|
||||
97
resources/assets/v1/src/components/exchange-rates/Index.vue
Normal file
97
resources/assets/v1/src/components/exchange-rates/Index.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<!--
|
||||
- Index.vue
|
||||
- Copyright (c) 2022 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/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ $t('firefly.header_exchange_rates') }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ $t('firefly.exchange_rates_intro') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="box box-default" v-for="currency in currencies" :key="currency.id">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ currency.name }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<ul v-if="currencies.length > 0">
|
||||
<li v-for="sub in currencies" :key="sub.id" v-show="sub.id !== currency.id">
|
||||
<a :href="'exchange-rates/' + currency.code + '/' + sub.code" :title="$t('firefly.exchange_rates_from_to', {from: currency.name, to: sub.name})">{{ $t('firefly.exchange_rates_from_to', {from: currency.name, to: sub.name}) }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Index",
|
||||
data() {
|
||||
return {
|
||||
currencies: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getCurrencies();
|
||||
},
|
||||
methods: {
|
||||
getCurrencies: function () {
|
||||
this.currencies = [];
|
||||
this.downloadCurrencies(1);
|
||||
},
|
||||
downloadCurrencies: function (page) {
|
||||
axios.get("./api/v2/currencies?enabled=1&page=" + page).then((response) => {
|
||||
for (let i in response.data.data) {
|
||||
if (response.data.data.hasOwnProperty(i)) {
|
||||
let current = response.data.data[i];
|
||||
let currency = {
|
||||
id: current.id,
|
||||
name: current.attributes.name,
|
||||
code: current.attributes.code,
|
||||
};
|
||||
this.currencies.push(currency);
|
||||
}
|
||||
}
|
||||
|
||||
if (response.data.meta.pagination.current_page < response.data.meta.pagination.total_pages) {
|
||||
this.downloadCurrencies(parseInt(response.data.meta.pagination.current_page) + 1);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
109
resources/assets/v1/src/components/exchange-rates/Rates.vue
Normal file
109
resources/assets/v1/src/components/exchange-rates/Rates.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<!--
|
||||
- Rates.vue
|
||||
- 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/.
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ $t('firefly.header_exchange_rates_rates') }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ $t('firefly.exchange_rates_intro_rates') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ $t('firefly.header_exchange_rates_table') }}</h3>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
<table class="table table-responsive table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('form.date') }}</th>
|
||||
<th v-html="$t('form.from_currency_to_currency', {from: from.code, to: to.code})"></th>
|
||||
<th v-html="$t('form.to_currency_from_currency', {from: from.code, to: to.code})"></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "Rates",
|
||||
data() {
|
||||
return {
|
||||
rates: [],
|
||||
from_code: '',
|
||||
to_code: '',
|
||||
from: {
|
||||
name: ''
|
||||
},
|
||||
to: {
|
||||
name: ''
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
// get from and to code from URL
|
||||
let parts = window.location.href.split('/');
|
||||
this.from_code = parts[parts.length - 2].substring(0, 3);
|
||||
this.to_code = parts[parts.length - 1].substring(0, 3);
|
||||
console.log('From: ' + this.from_code + ' To: ' + this.to_code);
|
||||
this.downloadCurrencies();
|
||||
},
|
||||
methods: {
|
||||
downloadCurrencies: function() {
|
||||
axios.get("./api/v2/currencies/" + this.from_code).then((response) => {
|
||||
this.from = {
|
||||
id: response.data.data.id,
|
||||
code: response.data.data.attributes.code,
|
||||
name: response.data.data.attributes.name,
|
||||
}
|
||||
});
|
||||
axios.get("./api/v2/currencies/" + this.to_code).then((response) => {
|
||||
console.log(response.data.data);
|
||||
this.to = {
|
||||
id: response.data.data.id,
|
||||
code: response.data.data.attributes.code,
|
||||
name: response.data.data.attributes.name,
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
39
resources/assets/v1/src/exchange-rates/index.js
Normal file
39
resources/assets/v1/src/exchange-rates/index.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* edit_transactions.js
|
||||
* Copyright (c) 2019 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/>.
|
||||
*/
|
||||
|
||||
import Index from "../components/exchange-rates/Index";
|
||||
|
||||
/**
|
||||
* First we will load Axios via bootstrap.js
|
||||
* jquery and bootstrap-sass preloaded in app.js
|
||||
* vue, uiv and vuei18n are in app_vue.js
|
||||
*/
|
||||
|
||||
require('../bootstrap');
|
||||
const i18n = require('../i18n');
|
||||
|
||||
let props = {};
|
||||
const app = new Vue({
|
||||
i18n,
|
||||
el: "#exchange_rates_index",
|
||||
render: (createElement) => {
|
||||
return createElement(Index, {props: props})
|
||||
},
|
||||
});
|
||||
39
resources/assets/v1/src/exchange-rates/rates.js
Normal file
39
resources/assets/v1/src/exchange-rates/rates.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* edit_transactions.js
|
||||
* Copyright (c) 2019 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/>.
|
||||
*/
|
||||
|
||||
import Rates from "../components/exchange-rates/Rates";
|
||||
|
||||
/**
|
||||
* First we will load Axios via bootstrap.js
|
||||
* jquery and bootstrap-sass preloaded in app.js
|
||||
* vue, uiv and vuei18n are in app_vue.js
|
||||
*/
|
||||
|
||||
require('../bootstrap');
|
||||
const i18n = require('../i18n');
|
||||
|
||||
let props = {};
|
||||
const app = new Vue({
|
||||
i18n,
|
||||
el: "#exchange_rates_rates",
|
||||
render: (createElement) => {
|
||||
return createElement(Rates, {props: props})
|
||||
},
|
||||
});
|
||||
1
resources/assets/v1/src/locales/.json
Normal file
1
resources/assets/v1/src/locales/.json
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Response",
|
||||
"visit_webhook_url": "Visit webhook URL",
|
||||
"reset_webhook_secret": "Reset webhook secret"
|
||||
"reset_webhook_secret": "Reset webhook secret",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "\u0412\u044a\u0442\u0440\u0435\u0448\u043d\u0430 \u0440\u0435\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "\u0410\u043a\u0442\u0438\u0432\u0435\u043d \u043b\u0438 \u0435?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Registres",
|
||||
"response": "Resposta",
|
||||
"visit_webhook_url": "Visitar l'URL del webhook",
|
||||
"reset_webhook_secret": "Reiniciar el secret del webhook"
|
||||
"reset_webhook_secret": "Reiniciar el secret del webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Refer\u00e8ncia interna",
|
||||
"webhook_response": "Resposta",
|
||||
"webhook_trigger": "Activador",
|
||||
"webhook_delivery": "Lliurament"
|
||||
"webhook_delivery": "Lliurament",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Est\u00e0 actiu?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logy",
|
||||
"response": "Odpov\u011b\u010f",
|
||||
"visit_webhook_url": "Nav\u0161t\u00edvit URL webhooku",
|
||||
"reset_webhook_secret": "Restartovat tajn\u00fd kl\u00ed\u010d webhooku"
|
||||
"reset_webhook_secret": "Restartovat tajn\u00fd kl\u00ed\u010d webhooku",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Intern\u00ed reference",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Spou\u0161t\u011b\u010d",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Aktivn\u00ed?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Svar",
|
||||
"visit_webhook_url": "Bes\u00f8g webhook-URL",
|
||||
"reset_webhook_secret": "Nulstil webhook-hemmelighed"
|
||||
"reset_webhook_secret": "Nulstil webhook-hemmelighed",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Intern reference",
|
||||
"webhook_response": "Svar",
|
||||
"webhook_trigger": "Udl\u00f8ser",
|
||||
"webhook_delivery": "Levering"
|
||||
"webhook_delivery": "Levering",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Aktiv?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Protokolle",
|
||||
"response": "Antwort",
|
||||
"visit_webhook_url": "Webhook-URL besuchen",
|
||||
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen"
|
||||
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
|
||||
"header_exchange_rates": "Wechselkurse",
|
||||
"exchange_rates_intro": "Firefly III unterst\u00fctzt das Herunterladen und Verwenden von Wechselkursen. Lesen Sie mehr dar\u00fcber in <a href=\u201ehttps:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\u201c>der Dokumentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Interne Referenz",
|
||||
"webhook_response": "Antwort",
|
||||
"webhook_trigger": "Ausl\u00f6ser",
|
||||
"webhook_delivery": "Zustellung"
|
||||
"webhook_delivery": "Zustellung",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Aktiv?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2 (Logs)",
|
||||
"response": "\u0391\u03c0\u03cc\u03ba\u03c1\u03b9\u03c3\u03b7",
|
||||
"visit_webhook_url": "\u0395\u03c0\u03b9\u03c3\u03ba\u03b5\u03c6\u03b8\u03b5\u03af\u03c4\u03b5 \u03c4\u03bf URL \u03c4\u03bf\u03c5 webhook",
|
||||
"reset_webhook_secret": "\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03bc\u03c5\u03c3\u03c4\u03b9\u03ba\u03bf\u03cd webhook"
|
||||
"reset_webhook_secret": "\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03bc\u03c5\u03c3\u03c4\u03b9\u03ba\u03bf\u03cd webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "\u0395\u03c3\u03c9\u03c4\u03b5\u03c1\u03b9\u03ba\u03ae \u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac",
|
||||
"webhook_response": "\u0391\u03c0\u03cc\u03ba\u03c1\u03b9\u03c3\u03b7",
|
||||
"webhook_trigger": "\u0395\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7",
|
||||
"webhook_delivery": "\u03a0\u03b1\u03c1\u03ac\u03b4\u03bf\u03c3\u03b7"
|
||||
"webhook_delivery": "\u03a0\u03b1\u03c1\u03ac\u03b4\u03bf\u03c3\u03b7",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "\u0395\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03cc;",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Response",
|
||||
"visit_webhook_url": "Visit webhook URL",
|
||||
"reset_webhook_secret": "Reset webhook secret"
|
||||
"reset_webhook_secret": "Reset webhook secret",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Internal reference",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Is active?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Response",
|
||||
"visit_webhook_url": "Visit webhook URL",
|
||||
"reset_webhook_secret": "Reset webhook secret"
|
||||
"reset_webhook_secret": "Reset webhook secret",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Internal reference",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Is active?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Registros",
|
||||
"response": "Respuesta",
|
||||
"visit_webhook_url": "Visita la URL del webhook",
|
||||
"reset_webhook_secret": "Restablecer secreto del webhook"
|
||||
"reset_webhook_secret": "Restablecer secreto del webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Referencia interna",
|
||||
"webhook_response": "Respuesta",
|
||||
"webhook_trigger": "Disparador",
|
||||
"webhook_delivery": "Entrega"
|
||||
"webhook_delivery": "Entrega",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "\u00bfEst\u00e1 Activo?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Response",
|
||||
"visit_webhook_url": "Visit webhook URL",
|
||||
"reset_webhook_secret": "Reset webhook secret"
|
||||
"reset_webhook_secret": "Reset webhook secret",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL-osoite",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Sis\u00e4inen viite",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Aktiivinen?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Journaux",
|
||||
"response": "R\u00e9ponse",
|
||||
"visit_webhook_url": "Visiter l'URL du webhook",
|
||||
"reset_webhook_secret": "R\u00e9initialiser le secret du webhook"
|
||||
"reset_webhook_secret": "R\u00e9initialiser le secret du webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "Liens",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "R\u00e9f\u00e9rence interne",
|
||||
"webhook_response": "R\u00e9ponse",
|
||||
"webhook_trigger": "D\u00e9clencheur",
|
||||
"webhook_delivery": "Distribution"
|
||||
"webhook_delivery": "Distribution",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Actif ?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Napl\u00f3k",
|
||||
"response": "V\u00e1lasz",
|
||||
"visit_webhook_url": "Webhook URL megl\u00e1togat\u00e1sa",
|
||||
"reset_webhook_secret": "Webhook titok vissza\u00e1ll\u00edt\u00e1sa"
|
||||
"reset_webhook_secret": "Webhook titok vissza\u00e1ll\u00edt\u00e1sa",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Bels\u0151 hivatkoz\u00e1s",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Akt\u00edv?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Response",
|
||||
"visit_webhook_url": "Visit webhook URL",
|
||||
"reset_webhook_secret": "Reset webhook secret"
|
||||
"reset_webhook_secret": "Reset webhook secret",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Referensi internal",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Aktif?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Log",
|
||||
"response": "Risposta",
|
||||
"visit_webhook_url": "Visita URL webhook",
|
||||
"reset_webhook_secret": "Reimposta il segreto del webhook"
|
||||
"reset_webhook_secret": "Reimposta il segreto del webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Riferimento interno",
|
||||
"webhook_response": "Risposta",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Consegna"
|
||||
"webhook_delivery": "Consegna",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Attivo",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "\u30ed\u30b0",
|
||||
"response": "\u30ec\u30b9\u30dd\u30f3\u30b9",
|
||||
"visit_webhook_url": "Webhook\u306eURL\u3092\u958b\u304f",
|
||||
"reset_webhook_secret": "Webhook\u306e\u30b7\u30fc\u30af\u30ec\u30c3\u30c8\u3092\u30ea\u30bb\u30c3\u30c8"
|
||||
"reset_webhook_secret": "Webhook\u306e\u30b7\u30fc\u30af\u30ec\u30c3\u30c8\u3092\u30ea\u30bb\u30c3\u30c8",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "\u5185\u90e8\u53c2\u7167",
|
||||
"webhook_response": "\u30ec\u30b9\u30dd\u30f3\u30b9",
|
||||
"webhook_trigger": "\u30c8\u30ea\u30ac\u30fc",
|
||||
"webhook_delivery": "\u914d\u4fe1"
|
||||
"webhook_delivery": "\u914d\u4fe1",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "\u6709\u52b9",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "\ub85c\uadf8",
|
||||
"response": "\uc751\ub2f5",
|
||||
"visit_webhook_url": "\uc6f9\ud6c5 URL \ubc29\ubb38",
|
||||
"reset_webhook_secret": "\uc6f9\ud6c5 \uc2dc\ud06c\ub9bf \uc7ac\uc124\uc815"
|
||||
"reset_webhook_secret": "\uc6f9\ud6c5 \uc2dc\ud06c\ub9bf \uc7ac\uc124\uc815",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "\ub0b4\ubd80 \ucc38\uc870",
|
||||
"webhook_response": "\uc751\ub2f5",
|
||||
"webhook_trigger": "\ud2b8\ub9ac\uac70",
|
||||
"webhook_delivery": "\uc804\ub2ec"
|
||||
"webhook_delivery": "\uc804\ub2ec",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "\ud65c\uc131 \uc0c1\ud0dc\uc785\ub2c8\uae4c?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logger",
|
||||
"response": "Respons",
|
||||
"visit_webhook_url": "Bes\u00f8k URL til webhook",
|
||||
"reset_webhook_secret": "Tilbakestill Webhook n\u00f8kkel"
|
||||
"reset_webhook_secret": "Tilbakestill Webhook n\u00f8kkel",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "Nettadresse",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Intern referanse",
|
||||
"webhook_response": "Respons",
|
||||
"webhook_trigger": "Utl\u00f8ser",
|
||||
"webhook_delivery": "Levering"
|
||||
"webhook_delivery": "Levering",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Er aktiv?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logboeken",
|
||||
"response": "Reactie",
|
||||
"visit_webhook_url": "Bezoek URL van webhook",
|
||||
"reset_webhook_secret": "Reset webhook-geheim"
|
||||
"reset_webhook_secret": "Reset webhook-geheim",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Interne verwijzing",
|
||||
"webhook_response": "Reactie",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Bericht"
|
||||
"webhook_delivery": "Bericht",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Actief?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logger",
|
||||
"response": "Respons",
|
||||
"visit_webhook_url": "Bes\u00f8k URL til webhook",
|
||||
"reset_webhook_secret": "Tilbakestill Webhook hemmelegheit"
|
||||
"reset_webhook_secret": "Tilbakestill Webhook hemmelegheit",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "Nettadresse",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Intern referanse",
|
||||
"webhook_response": "Respons",
|
||||
"webhook_trigger": "Utl\u00f8ser",
|
||||
"webhook_delivery": "Levering"
|
||||
"webhook_delivery": "Levering",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Er aktiv?",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"flash_success": "Sukces!",
|
||||
"close": "Zamknij",
|
||||
"select_dest_account": "Please select or type a valid destination account name",
|
||||
"select_source_account": "Please select or type a valid source account name",
|
||||
"select_source_account": "Wybierz lub wpisz prawid\u0142ow\u0105 nazw\u0119 konta \u017ar\u00f3d\u0142owego",
|
||||
"split_transaction_title": "Opis podzielonej transakcji",
|
||||
"errors_submission": "Co\u015b posz\u0142o nie tak w czasie zapisu. Prosz\u0119, sprawd\u017a b\u0142\u0119dy poni\u017cej.",
|
||||
"split": "Podziel",
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logi",
|
||||
"response": "Odpowied\u017a",
|
||||
"visit_webhook_url": "Odwied\u017a adres URL webhooka",
|
||||
"reset_webhook_secret": "Resetuj sekret webhooka"
|
||||
"reset_webhook_secret": "Resetuj sekret webhooka",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Wewn\u0119trzny numer",
|
||||
"webhook_response": "Odpowied\u017a",
|
||||
"webhook_trigger": "Wyzwalacz",
|
||||
"webhook_delivery": "Dor\u0119czenie"
|
||||
"webhook_delivery": "Dor\u0119czenie",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Jest aktywny?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Registros",
|
||||
"response": "Resposta",
|
||||
"visit_webhook_url": "Acesse a URL do webhook",
|
||||
"reset_webhook_secret": "Redefinir chave do webhook"
|
||||
"reset_webhook_secret": "Redefinir chave do webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Refer\u00eancia interna",
|
||||
"webhook_response": "Resposta",
|
||||
"webhook_trigger": "Gatilho",
|
||||
"webhook_delivery": "Entrega"
|
||||
"webhook_delivery": "Entrega",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Est\u00e1 ativo?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Respostas",
|
||||
"visit_webhook_url": "Ir para URL do webhook",
|
||||
"reset_webhook_secret": "Redefinir segredo webhook"
|
||||
"reset_webhook_secret": "Redefinir segredo webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Refer\u00eancia interna",
|
||||
"webhook_response": "Resposta",
|
||||
"webhook_trigger": "Gatilho",
|
||||
"webhook_delivery": "Entrega"
|
||||
"webhook_delivery": "Entrega",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Esta ativo?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Jurnale",
|
||||
"response": "R\u0103spuns",
|
||||
"visit_webhook_url": "Vizita\u0163i URL-ul webhook",
|
||||
"reset_webhook_secret": "Resetare secret webhook"
|
||||
"reset_webhook_secret": "Resetare secret webhook",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Referin\u021b\u0103 intern\u0103",
|
||||
"webhook_response": "R\u0103spuns",
|
||||
"webhook_trigger": "Declan\u0219ator",
|
||||
"webhook_delivery": "Livrare"
|
||||
"webhook_delivery": "Livrare",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Este activ?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "\u041b\u043e\u0433\u0438",
|
||||
"response": "\u041e\u0442\u0432\u0435\u0442",
|
||||
"visit_webhook_url": "\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u044c URL \u0432\u0435\u0431\u0445\u0443\u043a\u0430",
|
||||
"reset_webhook_secret": ""
|
||||
"reset_webhook_secret": "",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "\u0421\u0441\u044b\u043b\u043a\u0430",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u0441\u0441\u044b\u043b\u043a\u0430",
|
||||
"webhook_response": "\u041e\u0442\u0432\u0435\u0442",
|
||||
"webhook_trigger": "\u0421\u043e\u0431\u044b\u0442\u0438\u044f",
|
||||
"webhook_delivery": "\u0414\u043e\u0441\u0442\u0430\u0432\u043a\u0430"
|
||||
"webhook_delivery": "\u0414\u043e\u0441\u0442\u0430\u0432\u043a\u0430",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "\u0410\u043a\u0442\u0438\u0432\u0435\u043d?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Logs",
|
||||
"response": "Response",
|
||||
"visit_webhook_url": "Visit webhook URL",
|
||||
"reset_webhook_secret": "Reset webhook secret"
|
||||
"reset_webhook_secret": "Reset webhook secret",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Intern\u00e1 referencia",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Trigger",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Akt\u00edvne?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Dnevniki",
|
||||
"response": "Odziv",
|
||||
"visit_webhook_url": "Obi\u0161\u010dite URL webhooka",
|
||||
"reset_webhook_secret": "Ponastavi skrivno kodo webhooka"
|
||||
"reset_webhook_secret": "Ponastavi skrivno kodo webhooka",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "URL",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Notranji sklic",
|
||||
"webhook_response": "Odziv",
|
||||
"webhook_trigger": "Spro\u017eilec",
|
||||
"webhook_delivery": "Dostava"
|
||||
"webhook_delivery": "Dostava",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "Aktiviran?",
|
||||
|
||||
@@ -129,7 +129,11 @@
|
||||
"logs": "Loggar",
|
||||
"response": "Svar",
|
||||
"visit_webhook_url": "Visit webhook URL",
|
||||
"reset_webhook_secret": "Reset webhook secret"
|
||||
"reset_webhook_secret": "Reset webhook secret",
|
||||
"header_exchange_rates": "Exchange rates",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates."
|
||||
},
|
||||
"form": {
|
||||
"url": "L\u00e4nk",
|
||||
@@ -145,7 +149,9 @@
|
||||
"internal_reference": "Intern referens",
|
||||
"webhook_response": "Response",
|
||||
"webhook_trigger": "Utl\u00f6sare",
|
||||
"webhook_delivery": "Delivery"
|
||||
"webhook_delivery": "Delivery",
|
||||
"from_currency_to_currency": "{from} → {to}",
|
||||
"to_currency_from_currency": "{to} → {from}"
|
||||
},
|
||||
"list": {
|
||||
"active": "\u00c4r aktiv?",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user