mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-17 03:49:22 +00:00
Compare commits
17 Commits
v6.1.13
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
746f1fd300 | ||
|
|
9e5faf919f | ||
|
|
cc6cbe6605 | ||
|
|
dc6d708897 | ||
|
|
6189d24b98 | ||
|
|
f6e28dc88f | ||
|
|
75ea035630 | ||
|
|
4cdb14301d | ||
|
|
9f95221ba3 | ||
|
|
e3a67be412 | ||
|
|
5749b642ce | ||
|
|
baff7c67f9 | ||
|
|
ccc005942f | ||
|
|
5b83c33039 | ||
|
|
cc32578c5f | ||
|
|
80f410835b | ||
|
|
b537a3145d |
28
.ci/phpmd/composer.lock
generated
28
.ci/phpmd/composer.lock
generated
@@ -9,16 +9,16 @@
|
|||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "composer/pcre",
|
"name": "composer/pcre",
|
||||||
"version": "3.1.2",
|
"version": "3.1.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/pcre.git",
|
"url": "https://github.com/composer/pcre.git",
|
||||||
"reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace"
|
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/pcre/zipball/4775f35b2d70865807c89d32c8e7385b86eb0ace",
|
"url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||||
"reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace",
|
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/composer/pcre/issues",
|
"issues": "https://github.com/composer/pcre/issues",
|
||||||
"source": "https://github.com/composer/pcre/tree/3.1.2"
|
"source": "https://github.com/composer/pcre/tree/3.1.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -76,20 +76,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-03-07T15:38:35+00:00"
|
"time": "2024-03-19T10:26:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/xdebug-handler",
|
"name": "composer/xdebug-handler",
|
||||||
"version": "3.0.3",
|
"version": "3.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/xdebug-handler.git",
|
"url": "https://github.com/composer/xdebug-handler.git",
|
||||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c"
|
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
|
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c",
|
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.0",
|
"phpstan/phpstan": "^1.0",
|
||||||
"phpstan/phpstan-strict-rules": "^1.1",
|
"phpstan/phpstan-strict-rules": "^1.1",
|
||||||
"symfony/phpunit-bridge": "^6.0"
|
"phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -124,9 +124,9 @@
|
|||||||
"performance"
|
"performance"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"irc": "irc://irc.freenode.org/composer",
|
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||||
"issues": "https://github.com/composer/xdebug-handler/issues",
|
"issues": "https://github.com/composer/xdebug-handler/issues",
|
||||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
|
"source": "https://github.com/composer/xdebug-handler/tree/3.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-02-25T21:32:43+00:00"
|
"time": "2024-03-26T18:29:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pdepend/pdepend",
|
"name": "pdepend/pdepend",
|
||||||
|
|||||||
@@ -83,17 +83,17 @@ class AccountController extends Controller
|
|||||||
// user's preferences
|
// user's preferences
|
||||||
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
||||||
|
|
||||||
/** @var Preference $frontPage */
|
/** @var Preference $frontpage */
|
||||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||||
$default = app('amount')->getDefaultCurrency();
|
$default = app('amount')->getDefaultCurrency();
|
||||||
|
|
||||||
if (!(is_array($frontPage->data) && count($frontPage->data) > 0)) {
|
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
||||||
$frontPage->data = $defaultSet;
|
$frontpage->data = $defaultSet;
|
||||||
$frontPage->save();
|
$frontpage->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get accounts:
|
// get accounts:
|
||||||
$accounts = $this->repository->getAccountsById($frontPage->data);
|
$accounts = $this->repository->getAccountsById($frontpage->data);
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
|
|||||||
@@ -98,14 +98,14 @@ class AccountController extends Controller
|
|||||||
// user's preferences
|
// user's preferences
|
||||||
if (0 === $accounts->count()) {
|
if (0 === $accounts->count()) {
|
||||||
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT])->pluck('id')->toArray();
|
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT])->pluck('id')->toArray();
|
||||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||||
|
|
||||||
if (!(is_array($frontPage->data) && count($frontPage->data) > 0)) {
|
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
||||||
$frontPage->data = $defaultSet;
|
$frontpage->data = $defaultSet;
|
||||||
$frontPage->save();
|
$frontpage->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$accounts = $this->repository->getAccountsById($frontPage->data);
|
$accounts = $this->repository->getAccountsById($frontpage->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// both options are overruled by "preselected"
|
// both options are overruled by "preselected"
|
||||||
|
|||||||
@@ -54,6 +54,14 @@ class UpdateController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function useUserGroup(UserGroup $userGroup): JsonResponse
|
||||||
|
{
|
||||||
|
// group validation is already in place, so can just update the user.
|
||||||
|
$this->repository->useUserGroup($userGroup);
|
||||||
|
|
||||||
|
return response()->json([], 204);
|
||||||
|
}
|
||||||
|
|
||||||
public function update(UpdateRequest $request, UserGroup $userGroup): JsonResponse
|
public function update(UpdateRequest $request, UserGroup $userGroup): JsonResponse
|
||||||
{
|
{
|
||||||
$all = $request->getAll();
|
$all = $request->getAll();
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V2\Request\UserGroup;
|
|||||||
|
|
||||||
use FireflyIII\Enums\UserRoleEnum;
|
use FireflyIII\Enums\UserRoleEnum;
|
||||||
use FireflyIII\Models\UserGroup;
|
use FireflyIII\Models\UserGroup;
|
||||||
|
use FireflyIII\Rules\IsDefaultUserGroupName;
|
||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
@@ -53,7 +54,7 @@ class UpdateRequest extends FormRequest
|
|||||||
$userGroup = $this->route()->parameter('userGroup');
|
$userGroup = $this->route()->parameter('userGroup');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'title' => sprintf('required|min:1|max:255|unique:user_groups,title,%d', $userGroup->id),
|
'title' => ['required', 'min:1', 'max:255', sprintf('unique:user_groups,title,%d', $userGroup->id), new IsDefaultUserGroupName($userGroup)],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ class CorrectDatabase extends Command
|
|||||||
// new!
|
// new!
|
||||||
'firefly-iii:unify-group-accounts',
|
'firefly-iii:unify-group-accounts',
|
||||||
'firefly-iii:trigger-credit-recalculation',
|
'firefly-iii:trigger-credit-recalculation',
|
||||||
|
'firefly-iii:migrate-preferences',
|
||||||
];
|
];
|
||||||
foreach ($commands as $command) {
|
foreach ($commands as $command) {
|
||||||
$this->friendlyLine(sprintf('Now executing command "%s"', $command));
|
$this->friendlyLine(sprintf('Now executing command "%s"', $command));
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class FixFrontpageAccounts extends Command
|
|||||||
|
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
$preference = app('preferences')->getForUser($user, 'frontPageAccounts');
|
$preference = app('preferences')->getForUser($user, 'frontpageAccounts');
|
||||||
if (null !== $preference) {
|
if (null !== $preference) {
|
||||||
$this->fixPreference($preference);
|
$this->fixPreference($preference);
|
||||||
}
|
}
|
||||||
@@ -83,6 +83,6 @@ class FixFrontpageAccounts extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app('preferences')->setForUser($preference->user, 'frontPageAccounts', $fixed);
|
app('preferences')->setForUser($preference->user, 'frontpageAccounts', $fixed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
76
app/Console/Commands/Correction/MigratePreferences.php
Normal file
76
app/Console/Commands/Correction/MigratePreferences.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
/*
|
||||||
|
* MigratePreferences.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\Models\Preference;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||||
|
|
||||||
|
class MigratePreferences extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'firefly-iii:migrate-preferences';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Give Firefly III preferences a user group ID so they can be made administration specific.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$items = config('firefly.admin_specific_prefs');
|
||||||
|
$users = User::get();
|
||||||
|
|
||||||
|
/** @var User $user */
|
||||||
|
foreach ($users as $user) {
|
||||||
|
$count = 0;
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$preference = Preference::where('name', $item)->where('user_id', $user->id)->first();
|
||||||
|
if (null === $preference) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (null !== $preference->user_group_id) {
|
||||||
|
$preference->user_group_id = $user->user_group_id;
|
||||||
|
$preference->save();
|
||||||
|
++$count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($count > 0) {
|
||||||
|
$this->info(sprintf('Migrated %d preference(s) for user #%d ("%s").', $count, $user->id, $user->email));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandAlias::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,7 +80,7 @@ class CreateGroupMemberships extends Command
|
|||||||
// check if membership exists
|
// check if membership exists
|
||||||
$userGroup = UserGroup::where('title', $user->email)->first();
|
$userGroup = UserGroup::where('title', $user->email)->first();
|
||||||
if (null === $userGroup) {
|
if (null === $userGroup) {
|
||||||
$userGroup = UserGroup::create(['title' => $user->email]);
|
$userGroup = UserGroup::create(['title' => $user->email, 'default_administration' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$userRole = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
|
$userRole = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class UpgradeDatabase extends Command
|
|||||||
'firefly-iii:create-group-memberships',
|
'firefly-iii:create-group-memberships',
|
||||||
'firefly-iii:upgrade-group-information',
|
'firefly-iii:upgrade-group-information',
|
||||||
'firefly-iii:upgrade-currency-preferences',
|
'firefly-iii:upgrade-currency-preferences',
|
||||||
|
'firefly-iii:correct-database',
|
||||||
];
|
];
|
||||||
$args = [];
|
$args = [];
|
||||||
if ($this->option('force')) {
|
if ($this->option('force')) {
|
||||||
|
|||||||
@@ -145,13 +145,13 @@ class CreateController extends Controller
|
|||||||
Log::channel('audit')->info('Stored new account.', $data);
|
Log::channel('audit')->info('Stored new account.', $data);
|
||||||
|
|
||||||
// update preferences if necessary:
|
// update preferences if necessary:
|
||||||
$frontPage = app('preferences')->get('frontPageAccounts', [])->data;
|
$frontpage = app('preferences')->get('frontpageAccounts', [])->data;
|
||||||
if (!is_array($frontPage)) {
|
if (!is_array($frontpage)) {
|
||||||
$frontPage = [];
|
$frontpage = [];
|
||||||
}
|
}
|
||||||
if (AccountType::ASSET === $account->accountType->type) {
|
if (AccountType::ASSET === $account->accountType->type) {
|
||||||
$frontPage[] = $account->id;
|
$frontpage[] = $account->id;
|
||||||
app('preferences')->set('frontPageAccounts', $frontPage);
|
app('preferences')->set('frontpageAccounts', $frontpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store attachment(s):
|
// store attachment(s):
|
||||||
|
|||||||
@@ -301,14 +301,14 @@ class AccountController extends Controller
|
|||||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$defaultSet = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray();
|
$defaultSet = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray();
|
||||||
app('log')->debug('Default set is ', $defaultSet);
|
app('log')->debug('Default set is ', $defaultSet);
|
||||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||||
$frontPageArray = !is_array($frontPage->data) ? [] : $frontPage->data;
|
$frontpageArray = !is_array($frontpage->data) ? [] : $frontpage->data;
|
||||||
app('log')->debug('Frontpage preference set is ', $frontPageArray);
|
app('log')->debug('Frontpage preference set is ', $frontpageArray);
|
||||||
if (0 === count($frontPageArray)) {
|
if (0 === count($frontpageArray)) {
|
||||||
app('preferences')->set('frontPageAccounts', $defaultSet);
|
app('preferences')->set('frontpageAccounts', $defaultSet);
|
||||||
app('log')->debug('frontpage set is empty!');
|
app('log')->debug('frontpage set is empty!');
|
||||||
}
|
}
|
||||||
$accounts = $repository->getAccountsById($frontPageArray);
|
$accounts = $repository->getAccountsById($frontpageArray);
|
||||||
|
|
||||||
return response()->json($this->accountBalanceChart($accounts, $start, $end));
|
return response()->json($this->accountBalanceChart($accounts, $start, $end));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,8 +116,8 @@ class CategoryController extends Controller
|
|||||||
return response()->json($cache->get());
|
return response()->json($cache->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
$frontPageGenerator = new FrontpageChartGenerator($start, $end);
|
$frontpageGenerator = new FrontpageChartGenerator($start, $end);
|
||||||
$chartData = $frontPageGenerator->generate();
|
$chartData = $frontpageGenerator->generate();
|
||||||
$data = $this->generator->multiSet($chartData);
|
$data = $this->generator->multiSet($chartData);
|
||||||
$cache->store($data);
|
$cache->store($data);
|
||||||
|
|
||||||
|
|||||||
@@ -129,10 +129,10 @@ class HomeController extends Controller
|
|||||||
}
|
}
|
||||||
$subTitle = (string)trans('firefly.welcome_back');
|
$subTitle = (string)trans('firefly.welcome_back');
|
||||||
$transactions = [];
|
$transactions = [];
|
||||||
$frontPage = app('preferences')->getFresh('frontPageAccounts', $repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray());
|
$frontpage = app('preferences')->getFresh('frontpageAccounts', $repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray());
|
||||||
$frontPageArray = $frontPage->data;
|
$frontpageArray = $frontpage->data;
|
||||||
if (!is_array($frontPageArray)) {
|
if (!is_array($frontpageArray)) {
|
||||||
$frontPageArray = [];
|
$frontpageArray = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
@@ -140,13 +140,13 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
||||||
$accounts = $repository->getAccountsById($frontPageArray);
|
$accounts = $repository->getAccountsById($frontpageArray);
|
||||||
$today = today(config('app.timezone'));
|
$today = today(config('app.timezone'));
|
||||||
|
|
||||||
// sort frontpage accounts by order
|
// sort frontpage accounts by order
|
||||||
$accounts = $accounts->sortBy('order');
|
$accounts = $accounts->sortBy('order');
|
||||||
|
|
||||||
app('log')->debug('Frontpage accounts are ', $frontPageArray);
|
app('log')->debug('Frontpage accounts are ', $frontpageArray);
|
||||||
|
|
||||||
/** @var BillRepositoryInterface $billRepository */
|
/** @var BillRepositoryInterface $billRepository */
|
||||||
$billRepository = app(BillRepositoryInterface::class);
|
$billRepository = app(BillRepositoryInterface::class);
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class NewUserController extends Controller
|
|||||||
|
|
||||||
// store frontpage preferences:
|
// store frontpage preferences:
|
||||||
$accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
$accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
|
||||||
app('preferences')->set('frontPageAccounts', $accounts);
|
app('preferences')->set('frontpageAccounts', $accounts);
|
||||||
|
|
||||||
// mark.
|
// mark.
|
||||||
app('preferences')->mark();
|
app('preferences')->mark();
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ class PreferencesController extends Controller
|
|||||||
/** @var array<int, int> $accountIds */
|
/** @var array<int, int> $accountIds */
|
||||||
$accountIds = $accounts->pluck('id')->toArray();
|
$accountIds = $accounts->pluck('id')->toArray();
|
||||||
$viewRange = app('navigation')->getViewRange(false);
|
$viewRange = app('navigation')->getViewRange(false);
|
||||||
$frontPageAccountsPref = app('preferences')->get('frontPageAccounts', $accountIds);
|
$frontpageAccountsPref = app('preferences')->get('frontpageAccounts', $accountIds);
|
||||||
$frontPageAccounts = $frontPageAccountsPref->data;
|
$frontpageAccounts = $frontpageAccountsPref->data;
|
||||||
if (!is_array($frontPageAccounts)) {
|
if (!is_array($frontpageAccounts)) {
|
||||||
$frontPageAccounts = $accountIds;
|
$frontpageAccounts = $accountIds;
|
||||||
}
|
}
|
||||||
$language = app('steam')->getLanguage();
|
$language = app('steam')->getLanguage();
|
||||||
$languages = config('firefly.languages');
|
$languages = config('firefly.languages');
|
||||||
@@ -128,8 +128,8 @@ class PreferencesController extends Controller
|
|||||||
$locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
|
$locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
|
||||||
// an important fallback is that the frontPageAccount array gets refilled automatically
|
// an important fallback is that the frontPageAccount array gets refilled automatically
|
||||||
// when it turns up empty.
|
// when it turns up empty.
|
||||||
if (0 === count($frontPageAccounts)) {
|
if (0 === count($frontpageAccounts)) {
|
||||||
$frontPageAccounts = $accountIds;
|
$frontpageAccounts = $accountIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for the demo user, the slackUrl is automatically emptied.
|
// for the demo user, the slackUrl is automatically emptied.
|
||||||
@@ -139,7 +139,7 @@ class PreferencesController extends Controller
|
|||||||
$slackUrl = '';
|
$slackUrl = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('preferences.index', compact('language', 'groupedAccounts', 'isDocker', 'frontPageAccounts', 'languages', 'darkMode', 'availableDarkModes', 'notifications', 'slackUrl', 'locales', 'locale', 'tjOptionalFields', 'viewRange', 'customFiscalYear', 'listPageSize', 'fiscalYearStart'));
|
return view('preferences.index', compact('language', 'groupedAccounts', 'isDocker', 'frontpageAccounts', 'languages', 'darkMode', 'availableDarkModes', 'notifications', 'slackUrl', 'locales', 'locale', 'tjOptionalFields', 'viewRange', 'customFiscalYear', 'listPageSize', 'fiscalYearStart'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,12 +155,12 @@ class PreferencesController extends Controller
|
|||||||
public function postIndex(Request $request)
|
public function postIndex(Request $request)
|
||||||
{
|
{
|
||||||
// front page accounts
|
// front page accounts
|
||||||
$frontPageAccounts = [];
|
$frontpageAccounts = [];
|
||||||
if (is_array($request->get('frontPageAccounts')) && count($request->get('frontPageAccounts')) > 0) {
|
if (is_array($request->get('frontpageAccounts')) && count($request->get('frontpageAccounts')) > 0) {
|
||||||
foreach ($request->get('frontPageAccounts') as $id) {
|
foreach ($request->get('frontpageAccounts') as $id) {
|
||||||
$frontPageAccounts[] = (int)$id;
|
$frontpageAccounts[] = (int)$id;
|
||||||
}
|
}
|
||||||
app('preferences')->set('frontPageAccounts', $frontPageAccounts);
|
app('preferences')->set('frontpageAccounts', $frontpageAccounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract notifications:
|
// extract notifications:
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class CreateController extends Controller
|
|||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
$title = (string)trans('firefly.administrations_page_title');
|
$title = (string)trans('firefly.administrations_page_title');
|
||||||
$subTitle = (string)trans('firefly.administrations_page_sub_title');
|
$subTitle = (string)trans('firefly.administrations_page_create_sub_title');
|
||||||
$mainTitleIcon = 'fa-book';
|
$mainTitleIcon = 'fa-book';
|
||||||
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
||||||
|
|
||||||
|
|||||||
46
app/Http/Controllers/UserGroup/EditController.php
Normal file
46
app/Http/Controllers/UserGroup/EditController.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* CreateController.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\UserGroup;
|
||||||
|
|
||||||
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
|
use FireflyIII\Models\UserGroup;
|
||||||
|
use Illuminate\Contracts\View\Factory;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
|
|
||||||
|
class EditController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return Application|Factory|\Illuminate\Contracts\Foundation\Application|View
|
||||||
|
*/
|
||||||
|
public function edit(UserGroup $userGroup)
|
||||||
|
{
|
||||||
|
$title = (string)trans('firefly.administrations_page_title');
|
||||||
|
$subTitle = (string)trans('firefly.administrations_page_edit_sub_title', ['title' => $userGroup->title]);
|
||||||
|
$mainTitleIcon = 'fa-book';
|
||||||
|
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
||||||
|
|
||||||
|
return view('administrations.edit')->with(compact('title', 'subTitle', 'mainTitleIcon'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -110,6 +110,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
* @method static EloquentBuilder|Account whereUserGroupId($value)
|
* @method static EloquentBuilder|Account whereUserGroupId($value)
|
||||||
*
|
*
|
||||||
* @property null|UserGroup $userGroup
|
* @property null|UserGroup $userGroup
|
||||||
|
* @property mixed $account_id
|
||||||
*
|
*
|
||||||
* @mixin Eloquent
|
* @mixin Eloquent
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
* @method static Builder|InvitedUser whereUpdatedAt($value)
|
* @method static Builder|InvitedUser whereUpdatedAt($value)
|
||||||
* @method static Builder|InvitedUser whereUserId($value)
|
* @method static Builder|InvitedUser whereUserId($value)
|
||||||
*
|
*
|
||||||
|
* @property mixed $user_group_id
|
||||||
|
*
|
||||||
* @mixin Eloquent
|
* @mixin Eloquent
|
||||||
*/
|
*/
|
||||||
class InvitedUser extends Model
|
class InvitedUser extends Model
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
* @method static Builder|Preference whereUpdatedAt($value)
|
* @method static Builder|Preference whereUpdatedAt($value)
|
||||||
* @method static Builder|Preference whereUserId($value)
|
* @method static Builder|Preference whereUserId($value)
|
||||||
*
|
*
|
||||||
|
* @property mixed $user_group_id
|
||||||
|
*
|
||||||
* @mixin Eloquent
|
* @mixin Eloquent
|
||||||
*/
|
*/
|
||||||
class Preference extends Model
|
class Preference extends Model
|
||||||
@@ -79,22 +81,39 @@ class Preference extends Model
|
|||||||
{
|
{
|
||||||
if (auth()->check()) {
|
if (auth()->check()) {
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
|
// some preferences do not have an administration ID.
|
||||||
|
// some need it, to make sure the correct one is selected.
|
||||||
|
$userGroupId = (int)$user->user_group_id;
|
||||||
|
$userGroupId = 0 === $userGroupId ? null : $userGroupId;
|
||||||
|
|
||||||
/** @var null|Preference $preference */
|
/** @var null|Preference $preference */
|
||||||
$preference = $user->preferences()->where('name', $value)->first();
|
$preference = null;
|
||||||
|
$items = config('firefly.admin_specific_prefs');
|
||||||
|
if (null !== $userGroupId && in_array($value, $items, true)) {
|
||||||
|
// find a preference with a specific user_group_id
|
||||||
|
$preference = $user->preferences()->where('user_group_id', $userGroupId)->where('name', $value)->first();
|
||||||
|
}
|
||||||
|
if (!in_array($value, $items, true)) {
|
||||||
|
// find any one.
|
||||||
|
$preference = $user->preferences()->where('name', $value)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try again with ID, but this time don't care about the preferred user_group_id
|
||||||
if (null === $preference) {
|
if (null === $preference) {
|
||||||
$preference = $user->preferences()->where('id', (int)$value)->first();
|
$preference = $user->preferences()->where('id', (int)$value)->first();
|
||||||
}
|
}
|
||||||
if (null !== $preference) {
|
if (null !== $preference) {
|
||||||
return $preference;
|
return $preference;
|
||||||
}
|
}
|
||||||
$default = config('firefly.default_preferences');
|
$default = config('firefly.default_preferences');
|
||||||
if (array_key_exists($value, $default)) {
|
if (array_key_exists($value, $default)) {
|
||||||
$preference = new self();
|
$preference = new self();
|
||||||
$preference->name = $value;
|
$preference->name = $value;
|
||||||
$preference->data = $default[$value];
|
$preference->data = $default[$value];
|
||||||
$preference->user_id = (int)$user->id;
|
$preference->user_id = (int)$user->id;
|
||||||
|
$preference->user_group_id = in_array($value, $items, true) ? $userGroupId : null;
|
||||||
$preference->save();
|
$preference->save();
|
||||||
|
|
||||||
return $preference;
|
return $preference;
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ use Illuminate\Database\Query\Builder;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereTransactionTypeId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereTransactionTypeId($value)
|
||||||
*
|
*
|
||||||
* @property null|TransactionType $transactionType
|
* @property null|TransactionType $transactionType
|
||||||
|
* @property mixed $user_id
|
||||||
*
|
*
|
||||||
* @mixin Eloquent
|
* @mixin Eloquent
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class UserGroup extends Model
|
|||||||
{
|
{
|
||||||
use ReturnsIntegerIdTrait;
|
use ReturnsIntegerIdTrait;
|
||||||
|
|
||||||
protected $fillable = ['title'];
|
protected $fillable = ['title', 'default_administration'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||||
|
|||||||
@@ -392,4 +392,28 @@ class UserRepository implements UserRepositoryInterface
|
|||||||
|
|
||||||
return null !== $invitee;
|
return null !== $invitee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\Override]
|
||||||
|
public function getUserGroups(User $user): Collection
|
||||||
|
{
|
||||||
|
$memberships = $user->groupMemberships()->get();
|
||||||
|
$set = [];
|
||||||
|
$collection = new Collection();
|
||||||
|
|
||||||
|
/** @var GroupMembership $membership */
|
||||||
|
foreach ($memberships as $membership) {
|
||||||
|
/** @var null|UserGroup $group */
|
||||||
|
$group = $membership->userGroup()->first();
|
||||||
|
if (null !== $group) {
|
||||||
|
$groupId = (int)$group->id;
|
||||||
|
if (in_array($groupId, $set, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$set[$groupId] = $group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$collection->push(...$set);
|
||||||
|
|
||||||
|
return $collection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ interface UserRepositoryInterface
|
|||||||
|
|
||||||
public function changeStatus(User $user, bool $isBlocked, string $code): bool;
|
public function changeStatus(User $user, bool $isBlocked, string $code): bool;
|
||||||
|
|
||||||
|
public function getUserGroups(User $user): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a count of all users.
|
* Returns a count of all users.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -288,4 +288,11 @@ class UserGroupRepository implements UserGroupRepositoryInterface
|
|||||||
|
|
||||||
return $roles;
|
return $roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[\Override]
|
||||||
|
public function useUserGroup(UserGroup $userGroup): void
|
||||||
|
{
|
||||||
|
$this->user->user_group_id = $userGroup->id;
|
||||||
|
$this->user->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ interface UserGroupRepositoryInterface
|
|||||||
|
|
||||||
public function get(): Collection;
|
public function get(): Collection;
|
||||||
|
|
||||||
|
public function useUserGroup(UserGroup $userGroup): void;
|
||||||
|
|
||||||
public function getAll(): Collection;
|
public function getAll(): Collection;
|
||||||
|
|
||||||
public function setUser(null|Authenticatable|User $user): void;
|
public function setUser(null|Authenticatable|User $user): void;
|
||||||
|
|||||||
@@ -74,5 +74,7 @@ interface AccountRepositoryInterface
|
|||||||
|
|
||||||
public function setUserGroup(UserGroup $userGroup): void;
|
public function setUserGroup(UserGroup $userGroup): void;
|
||||||
|
|
||||||
|
public function getUserGroup(): UserGroup;
|
||||||
|
|
||||||
public function update(Account $account, array $data): Account;
|
public function update(Account $account, array $data): Account;
|
||||||
}
|
}
|
||||||
|
|||||||
63
app/Rules/IsDefaultUserGroupName.php
Normal file
63
app/Rules/IsDefaultUserGroupName.php
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IsTransferAccount.php
|
||||||
|
* Copyright (c) 2020 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\Rules;
|
||||||
|
|
||||||
|
use FireflyIII\Models\UserGroup;
|
||||||
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class IsDefaultUserGroupName
|
||||||
|
*/
|
||||||
|
class IsDefaultUserGroupName implements ValidationRule
|
||||||
|
{
|
||||||
|
private UserGroup $userGroup;
|
||||||
|
|
||||||
|
public function __construct(UserGroup $userGroup)
|
||||||
|
{
|
||||||
|
$this->userGroup = $userGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
|
*/
|
||||||
|
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||||
|
{
|
||||||
|
app('log')->debug(sprintf('Now in %s(%s)', __METHOD__, $value));
|
||||||
|
|
||||||
|
// are you owner of this group and the name is the same? fail.
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
/** @var UserRepositoryInterface $userRepos */
|
||||||
|
$userRepos = app(UserRepositoryInterface::class);
|
||||||
|
|
||||||
|
$roles = $userRepos->getRolesInGroup($user, $this->userGroup->id);
|
||||||
|
if ($this->userGroup->title === $user->email && in_array('owner', $roles, true)) {
|
||||||
|
$fail('validation.administration_owner_rename')->translate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,10 @@ namespace FireflyIII\Support;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Preferences.
|
* Class Preferences.
|
||||||
@@ -40,20 +43,17 @@ class Preferences
|
|||||||
return new Collection();
|
return new Collection();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Preference::where('user_id', $user->id)->get();
|
return Preference::where('user_id', $user->id)
|
||||||
|
->where(function (Builder $q) use ($user): void {
|
||||||
|
$q->whereNull('user_group_id');
|
||||||
|
$q->orWhere('user_group_id', $user->user_group_id);
|
||||||
|
})
|
||||||
|
->get()
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function get(string $name, null|array|bool|int|string $default = null): ?Preference
|
||||||
* @param mixed $default
|
|
||||||
*
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function get(string $name, $default = null): ?Preference
|
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var null|User $user */
|
/** @var null|User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
@@ -66,15 +66,12 @@ class Preferences
|
|||||||
return $this->getForUser($user, $name, $default);
|
return $this->getForUser($user, $name, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
|
public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
// don't care about user group ID, except for some specific preferences.
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
$userGroupId = $this->getUserGroupId($user, $name);
|
||||||
}
|
$preference = Preference::where('user_group_id', $userGroupId)->where('user_id', $user->id)->where('name', $name)->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']);
|
||||||
$preference = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']);
|
|
||||||
if (null !== $preference && null === $preference->data) {
|
if (null !== $preference && null === $preference->data) {
|
||||||
$preference->delete();
|
$preference->delete();
|
||||||
$preference = null;
|
$preference = null;
|
||||||
@@ -92,17 +89,11 @@ class Preferences
|
|||||||
return $this->setForUser($user, $name, $default);
|
return $this->setForUser($user, $name, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function delete(string $name): bool
|
public function delete(string $name): bool
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
||||||
if (\Cache::has($fullName)) {
|
if (Cache::has($fullName)) {
|
||||||
\Cache::forget($fullName);
|
Cache::forget($fullName);
|
||||||
}
|
}
|
||||||
Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete();
|
Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete();
|
||||||
|
|
||||||
@@ -111,29 +102,19 @@ class Preferences
|
|||||||
|
|
||||||
public function forget(User $user, string $name): void
|
public function forget(User $user, string $name): void
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
$key = sprintf('preference%s%s', $user->id, $name);
|
$key = sprintf('preference%s%s', $user->id, $name);
|
||||||
\Cache::forget($key);
|
Cache::forget($key);
|
||||||
\Cache::put($key, '', 5);
|
Cache::put($key, '', 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setForUser(User $user, string $name, null|array|bool|int|string $value): Preference
|
||||||
* @param mixed $value
|
|
||||||
*
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function setForUser(User $user, string $name, $value): Preference
|
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
$fullName = sprintf('preference%s%s', $user->id, $name);
|
$fullName = sprintf('preference%s%s', $user->id, $name);
|
||||||
\Cache::forget($fullName);
|
$groupId = $this->getUserGroupId($user, $name);
|
||||||
|
Cache::forget($fullName);
|
||||||
|
|
||||||
/** @var null|Preference $pref */
|
/** @var null|Preference $pref */
|
||||||
$pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
|
$pref = Preference::where('user_group_id', $groupId)->where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
|
||||||
|
|
||||||
if (null !== $pref && null === $value) {
|
if (null !== $pref && null === $value) {
|
||||||
$pref->delete();
|
$pref->delete();
|
||||||
@@ -144,18 +125,14 @@ class Preferences
|
|||||||
return new Preference();
|
return new Preference();
|
||||||
}
|
}
|
||||||
if (null === $pref) {
|
if (null === $pref) {
|
||||||
$pref = new Preference();
|
$pref = new Preference();
|
||||||
$pref->user_id = (int)$user->id;
|
$pref->user_id = (int)$user->id;
|
||||||
$pref->name = $name;
|
$pref->user_group_id = $groupId;
|
||||||
|
$pref->name = $name;
|
||||||
}
|
}
|
||||||
$pref->data = $value;
|
$pref->data = $value;
|
||||||
|
$pref->save();
|
||||||
try {
|
Cache::forever($fullName, $pref);
|
||||||
$pref->save();
|
|
||||||
} catch (\PDOException $e) {
|
|
||||||
throw new FireflyException(sprintf('Could not save preference: %s', $e->getMessage()), 0, $e);
|
|
||||||
}
|
|
||||||
\Cache::forever($fullName, $pref);
|
|
||||||
|
|
||||||
return $pref;
|
return $pref;
|
||||||
}
|
}
|
||||||
@@ -165,19 +142,25 @@ class Preferences
|
|||||||
return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search.'%')->get();
|
return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search.'%')->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find by name, has no user ID in it, because the method is called from an unauthenticated route any way.
|
||||||
|
*/
|
||||||
public function findByName(string $name): Collection
|
public function findByName(string $name): Collection
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return Preference::where('name', $name)->get();
|
return Preference::where('name', $name)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getArrayForUser(User $user, array $list): array
|
public function getArrayForUser(User $user, array $list): array
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
$preferences = Preference::where('user_id', $user->id)->whereIn('name', $list)->get(['id', 'name', 'data']);
|
$preferences = Preference::where('user_id', $user->id)
|
||||||
|
->where(function (Builder $q) use ($user): void {
|
||||||
|
$q->whereNull('user_group_id');
|
||||||
|
$q->orWhere('user_group_id', $user->user_group_id);
|
||||||
|
})
|
||||||
|
->whereIn('name', $list)
|
||||||
|
->get(['id', 'name', 'data'])
|
||||||
|
;
|
||||||
|
|
||||||
/** @var Preference $preference */
|
/** @var Preference $preference */
|
||||||
foreach ($preferences as $preference) {
|
foreach ($preferences as $preference) {
|
||||||
@@ -192,17 +175,8 @@ class Preferences
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getFresh(string $name, null|array|bool|int|string $default = null): ?Preference
|
||||||
* @param mixed $default
|
|
||||||
*
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function getFresh(string $name, $default = null): ?Preference
|
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var null|User $user */
|
/** @var null|User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
@@ -212,22 +186,6 @@ class Preferences
|
|||||||
return $preference;
|
return $preference;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getFreshForUser($user, $name, $default);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO remove me.
|
|
||||||
*
|
|
||||||
* @param null $default
|
|
||||||
*
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function getFreshForUser(User $user, string $name, $default = null): ?Preference
|
|
||||||
{
|
|
||||||
if ('currencyPreference' === $name) {
|
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getForUser($user, $name, $default);
|
return $this->getForUser($user, $name, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,19 +210,12 @@ class Preferences
|
|||||||
public function mark(): void
|
public function mark(): void
|
||||||
{
|
{
|
||||||
$this->set('lastActivity', microtime());
|
$this->set('lastActivity', microtime());
|
||||||
\Session::forget('first');
|
Session::forget('first');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function set(string $name, null|array|bool|int|string $value): Preference
|
||||||
* @param mixed $value
|
|
||||||
*
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
|
||||||
public function set(string $name, $value): Preference
|
|
||||||
{
|
{
|
||||||
if ('currencyPreference' === $name) {
|
/** @var User $user */
|
||||||
throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
|
|
||||||
}
|
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if (null === $user) {
|
if (null === $user) {
|
||||||
// make new preference, return it:
|
// make new preference, return it:
|
||||||
@@ -275,6 +226,17 @@ class Preferences
|
|||||||
return $pref;
|
return $pref;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->setForUser(auth()->user(), $name, $value);
|
return $this->setForUser($user, $name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getUserGroupId(User $user, string $preferenceName): ?int
|
||||||
|
{
|
||||||
|
$groupId = null;
|
||||||
|
$items = config('firefly.admin_specific_prefs');
|
||||||
|
if (in_array($preferenceName, $items, true)) {
|
||||||
|
$groupId = (int)$user->user_group_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $groupId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,12 +35,15 @@ class PreferenceTransformer extends AbstractTransformer
|
|||||||
*/
|
*/
|
||||||
public function transform(Preference $preference): array
|
public function transform(Preference $preference): array
|
||||||
{
|
{
|
||||||
|
$userGroupId = 0 === $preference->user_group_id ? null : $preference->user_group_id;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $preference->id,
|
'id' => $preference->id,
|
||||||
'created_at' => $preference->created_at->toAtomString(),
|
'created_at' => $preference->created_at->toAtomString(),
|
||||||
'updated_at' => $preference->updated_at->toAtomString(),
|
'updated_at' => $preference->updated_at->toAtomString(),
|
||||||
'name' => $preference->name,
|
'user_group_id' => $userGroupId,
|
||||||
'data' => $preference->data,
|
'name' => $preference->name,
|
||||||
|
'data' => $preference->data,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,13 +84,13 @@ class UserGroupTransformer extends AbstractTransformer
|
|||||||
public function transform(UserGroup $userGroup): array
|
public function transform(UserGroup $userGroup): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $userGroup->id,
|
'id' => $userGroup->id,
|
||||||
'created_at' => $userGroup->created_at->toAtomString(),
|
'created_at' => $userGroup->created_at->toAtomString(),
|
||||||
'updated_at' => $userGroup->updated_at->toAtomString(),
|
'updated_at' => $userGroup->updated_at->toAtomString(),
|
||||||
'in_use' => $this->inUse[$userGroup->id] ?? false,
|
'in_use' => $this->inUse[$userGroup->id] ?? false,
|
||||||
'title' => $userGroup->title,
|
'title' => $userGroup->title,
|
||||||
'can_see_members' => $this->membershipsVisible[$userGroup->id] ?? false,
|
'can_see_members' => $this->membershipsVisible[$userGroup->id] ?? false,
|
||||||
'members' => $this->memberships[$userGroup->id] ?? [],
|
'members' => $this->memberships[$userGroup->id] ?? [],
|
||||||
];
|
];
|
||||||
// if the user has a specific role in this group, then collect the memberships.
|
// if the user has a specific role in this group, then collect the memberships.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
|
||||||
|
## 6.1.14 - 2024-xx-xx
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- You will have to define again which asset accounts you want to see on the dashboard. Sorry about that.
|
||||||
|
|
||||||
## 6.1.13 - 2024-04-01
|
## 6.1.13 - 2024-04-01
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
36
composer.lock
generated
36
composer.lock
generated
@@ -8897,23 +8897,23 @@
|
|||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "barryvdh/laravel-debugbar",
|
"name": "barryvdh/laravel-debugbar",
|
||||||
"version": "v3.12.3",
|
"version": "v3.13.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
||||||
"reference": "aac8f08b73af8c5d2ab6595c8823ddb26d1453f1"
|
"reference": "354a42f3e0b083cdd6f9da5a9d1c0c63b074547a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/aac8f08b73af8c5d2ab6595c8823ddb26d1453f1",
|
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/354a42f3e0b083cdd6f9da5a9d1c0c63b074547a",
|
||||||
"reference": "aac8f08b73af8c5d2ab6595c8823ddb26d1453f1",
|
"reference": "354a42f3e0b083cdd6f9da5a9d1c0c63b074547a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"illuminate/routing": "^9|^10|^11",
|
"illuminate/routing": "^9|^10|^11",
|
||||||
"illuminate/session": "^9|^10|^11",
|
"illuminate/session": "^9|^10|^11",
|
||||||
"illuminate/support": "^9|^10|^11",
|
"illuminate/support": "^9|^10|^11",
|
||||||
"maximebf/debugbar": "~1.21.0",
|
"maximebf/debugbar": "~1.22.0",
|
||||||
"php": "^8.0",
|
"php": "^8.0",
|
||||||
"symfony/finder": "^6|^7"
|
"symfony/finder": "^6|^7"
|
||||||
},
|
},
|
||||||
@@ -8926,7 +8926,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "3.10-dev"
|
"dev-master": "3.13-dev"
|
||||||
},
|
},
|
||||||
"laravel": {
|
"laravel": {
|
||||||
"providers": [
|
"providers": [
|
||||||
@@ -8965,7 +8965,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
|
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
|
||||||
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.12.3"
|
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.13.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -8977,7 +8977,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-03-31T18:35:30+00:00"
|
"time": "2024-04-01T16:39:30+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "barryvdh/laravel-ide-helper",
|
"name": "barryvdh/laravel-ide-helper",
|
||||||
@@ -9606,25 +9606,27 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "maximebf/debugbar",
|
"name": "maximebf/debugbar",
|
||||||
"version": "v1.21.3",
|
"version": "v1.22.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/maximebf/php-debugbar.git",
|
"url": "https://github.com/maximebf/php-debugbar.git",
|
||||||
"reference": "0b407703b08ea0cf6ebc61e267cc96ff7000911b"
|
"reference": "d7b6e1dc2dc85c01ed63ab158b00a7f46abdebcc"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0b407703b08ea0cf6ebc61e267cc96ff7000911b",
|
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/d7b6e1dc2dc85c01ed63ab158b00a7f46abdebcc",
|
||||||
"reference": "0b407703b08ea0cf6ebc61e267cc96ff7000911b",
|
"reference": "d7b6e1dc2dc85c01ed63ab158b00a7f46abdebcc",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.1|^8",
|
"php": "^7.2|^8",
|
||||||
"psr/log": "^1|^2|^3",
|
"psr/log": "^1|^2|^3",
|
||||||
"symfony/var-dumper": "^4|^5|^6|^7"
|
"symfony/var-dumper": "^4|^5|^6|^7"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": ">=7.5.20 <10.0",
|
"dbrekelmans/bdi": "^1",
|
||||||
|
"phpunit/phpunit": "^8|^9",
|
||||||
|
"symfony/panther": "^1|^2.1",
|
||||||
"twig/twig": "^1.38|^2.7|^3.0"
|
"twig/twig": "^1.38|^2.7|^3.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
@@ -9635,7 +9637,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.21-dev"
|
"dev-master": "1.22-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -9666,9 +9668,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/maximebf/php-debugbar/issues",
|
"issues": "https://github.com/maximebf/php-debugbar/issues",
|
||||||
"source": "https://github.com/maximebf/php-debugbar/tree/v1.21.3"
|
"source": "https://github.com/maximebf/php-debugbar/tree/v1.22.1"
|
||||||
},
|
},
|
||||||
"time": "2024-03-12T14:23:07+00:00"
|
"time": "2024-04-01T10:44:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "mockery/mockery",
|
"name": "mockery/mockery",
|
||||||
|
|||||||
@@ -117,9 +117,9 @@ return [
|
|||||||
'expression_engine' => false,
|
'expression_engine' => false,
|
||||||
// see cer.php for exchange rates feature flag.
|
// see cer.php for exchange rates feature flag.
|
||||||
],
|
],
|
||||||
'version' => '6.1.13',
|
'version' => 'develop/2024-04-02',
|
||||||
'api_version' => '2.0.13',
|
'api_version' => '2.0.13',
|
||||||
'db_version' => 23,
|
'db_version' => 24,
|
||||||
|
|
||||||
// generic settings
|
// generic settings
|
||||||
'maxUploadSize' => 1073741824, // 1 GB
|
'maxUploadSize' => 1073741824, // 1 GB
|
||||||
@@ -215,11 +215,14 @@ return [
|
|||||||
'zoom_level' => env('MAP_DEFAULT_ZOOM', '6'),
|
'zoom_level' => env('MAP_DEFAULT_ZOOM', '6'),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// administration specific preferences
|
||||||
|
'admin_specific_prefs' => ['frontpageAccounts', 'lastActivity'],
|
||||||
|
|
||||||
// default user-related values
|
// default user-related values
|
||||||
'darkMode' => 'browser',
|
'darkMode' => 'browser',
|
||||||
'list_length' => 10, // to be removed if v1 is cancelled.
|
'list_length' => 10, // to be removed if v1 is cancelled.
|
||||||
'default_preferences' => [
|
'default_preferences' => [
|
||||||
'frontPageAccounts' => [],
|
'frontpageAccounts' => [],
|
||||||
'listPageSize' => 50,
|
'listPageSize' => 50,
|
||||||
'currencyPreference' => 'EUR',
|
'currencyPreference' => 'EUR',
|
||||||
'language' => 'en_US',
|
'language' => 'en_US',
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use Illuminate\Support\Facades\Schema;
|
|||||||
|
|
||||||
return new class () extends Migration {
|
return new class () extends Migration {
|
||||||
private const string QUERY_ERROR = 'Could not execute query (table "%s", field "%s"): %s';
|
private const string QUERY_ERROR = 'Could not execute query (table "%s", field "%s"): %s';
|
||||||
private const string EXPL = 'If the index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.';
|
private const string EXPL = 'If the index already exists (see error), or if MySQL can\'t do it, this is not an problem. Otherwise, please open a GitHub discussion.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the migrations.
|
* Run the migrations.
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\QueryException;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class () extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Schema::table(
|
||||||
|
'preferences',
|
||||||
|
static function (Blueprint $table): void {
|
||||||
|
if (!Schema::hasColumn('preferences', 'user_group_id')) {
|
||||||
|
$table->bigInteger('user_group_id', false, true)->nullable()->after('user_id');
|
||||||
|
$table->foreign('user_group_id', 'preferences_to_ugi')->references('id')->on('user_groups')->onDelete('set null')->onUpdate('cascade');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (QueryException $e) {
|
||||||
|
app('log')->error(sprintf('Could not execute query: %s', $e->getMessage()));
|
||||||
|
app('log')->error('If the column or index already exists (see error), this is not an problem. Otherwise, please open a GitHub discussion.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void {}
|
||||||
|
};
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"html_language": "nl",
|
"html_language": "nl",
|
||||||
"date_time_fns": "d MMMM yyyy @ HH:mm:ss",
|
"date_time_fns": "d MMMM yyyy @ HH:mm:ss",
|
||||||
"month_and_day_fns": "d MMMM y",
|
"month_and_day_fns": "d MMMM y",
|
||||||
"date_time_fns_short": "MMMM do, yyyy @ HH:mm"
|
"date_time_fns_short": "d MMMM yyyy @ HH:mm"
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"bad_type_source": "Firefly III kan het transactietype niet bepalen op basis van deze bronrekening.",
|
"bad_type_source": "Firefly III kan het transactietype niet bepalen op basis van deze bronrekening.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"html_language": "nl",
|
"html_language": "nl",
|
||||||
"date_time_fns": "d MMMM yyyy @ HH:mm:ss",
|
"date_time_fns": "d MMMM yyyy @ HH:mm:ss",
|
||||||
"month_and_day_fns": "d MMMM y",
|
"month_and_day_fns": "d MMMM y",
|
||||||
"date_time_fns_short": "MMMM do, yyyy @ HH:mm"
|
"date_time_fns_short": "d MMMM yyyy @ HH:mm"
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"bad_type_source": "Firefly III kan het transactietype niet bepalen op basis van deze bronrekening.",
|
"bad_type_source": "Firefly III kan het transactietype niet bepalen op basis van deze bronrekening.",
|
||||||
|
|||||||
@@ -23,15 +23,15 @@ import format from "date-fns/format";
|
|||||||
|
|
||||||
export default class Get {
|
export default class Get {
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// *
|
*
|
||||||
// * @param identifier
|
* @param identifier
|
||||||
// * @param params
|
* @param params
|
||||||
// * @returns {Promise<AxiosResponse<any>>}
|
* @returns {Promise<AxiosResponse<any>>}
|
||||||
// */
|
*/
|
||||||
// show(identifier, params) {
|
show(identifier, params) {
|
||||||
// return api.get('/api/v2/accounts/' + identifier, {params: params});
|
return api.get('/api/v2/user-groups/' + identifier, {params: params});
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
33
resources/assets/v2/api/v2/model/user-group/post.js
Normal file
33
resources/assets/v2/api/v2/model/user-group/post.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* post.js
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {api} from "../../../../boot/axios";
|
||||||
|
|
||||||
|
export default class Post {
|
||||||
|
post(submission) {
|
||||||
|
let url = './api/v2/user-groups';
|
||||||
|
return api.post(url, submission);
|
||||||
|
}
|
||||||
|
|
||||||
|
use(groupId) {
|
||||||
|
let url = './api/v2/user-groups/' + groupId + '/use';
|
||||||
|
return api.post(url, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
28
resources/assets/v2/api/v2/model/user-group/put.js
Normal file
28
resources/assets/v2/api/v2/model/user-group/put.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* post.js
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {api} from "../../../../boot/axios";
|
||||||
|
|
||||||
|
export default class Put {
|
||||||
|
put(submission, params) {
|
||||||
|
let url = '/api/v2/user-groups/' + parseInt(params.id);
|
||||||
|
return api.put(url, submission);
|
||||||
|
}
|
||||||
|
}
|
||||||
111
resources/assets/v2/pages/administrations/create.js
Normal file
111
resources/assets/v2/pages/administrations/create.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* template.js
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../../boot/bootstrap.js';
|
||||||
|
import dates from "../shared/dates.js";
|
||||||
|
import Post from "../../api/v2/model/user-group/post.js";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
|
||||||
|
let administrations = function () {
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
errors: {
|
||||||
|
title: []
|
||||||
|
},
|
||||||
|
|
||||||
|
// notifications
|
||||||
|
notifications: {
|
||||||
|
error: {
|
||||||
|
show: false, text: '', url: '',
|
||||||
|
}, success: {
|
||||||
|
show: false, text: '', url: '',
|
||||||
|
}, wait: {
|
||||||
|
show: false, text: '',
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// state of the form is stored in formState:
|
||||||
|
formStates: {
|
||||||
|
isSubmitting: false,
|
||||||
|
returnHereButton: false,
|
||||||
|
saveAsNewButton: false, // edit form only
|
||||||
|
resetButton: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// form behaviour
|
||||||
|
formBehaviour: {
|
||||||
|
formType: 'create', // or 'update'
|
||||||
|
},
|
||||||
|
changedTitle() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
pageProperties: {},
|
||||||
|
submitForm() {
|
||||||
|
this.errors.title = [];
|
||||||
|
(new Post()).post({title: this.title}).then(response => {
|
||||||
|
if (this.formStates.returnHereButton) {
|
||||||
|
this.notifications.success.show = true;
|
||||||
|
this.notifications.success.text = i18next.t('firefly.new_administration_created', {title: response.data.data.attributes.title});
|
||||||
|
this.notifications.success.url = './administrations';
|
||||||
|
}
|
||||||
|
if (this.formStates.resetButton) {
|
||||||
|
this.title = '';
|
||||||
|
}
|
||||||
|
if (!this.formStates.returnHereButton) {
|
||||||
|
window.location.href = './administrations?user_group_id=' + parseInt(response.data.data.id) + '&message=created';
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.errors.title = error.response.data.errors.title;
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
cancelForm() {
|
||||||
|
window.location.href = './administrations';
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let comps = {administrations, dates};
|
||||||
|
|
||||||
|
function loadPage() {
|
||||||
|
Object.keys(comps).forEach(comp => {
|
||||||
|
console.log(`Loading page component "${comp}"`);
|
||||||
|
let data = comps[comp]();
|
||||||
|
Alpine.data(comp, () => data);
|
||||||
|
});
|
||||||
|
Alpine.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for load until bootstrapped event is received.
|
||||||
|
document.addEventListener('firefly-iii-bootstrapped', () => {
|
||||||
|
console.log('Loaded through event listener.');
|
||||||
|
loadPage();
|
||||||
|
});
|
||||||
|
// or is bootstrapped before event is triggered.
|
||||||
|
if (window.bootstrapped) {
|
||||||
|
console.log('Loaded through window variable.');
|
||||||
|
loadPage();
|
||||||
|
}
|
||||||
121
resources/assets/v2/pages/administrations/edit.js
Normal file
121
resources/assets/v2/pages/administrations/edit.js
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* template.js
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../../boot/bootstrap.js';
|
||||||
|
import dates from "../shared/dates.js";
|
||||||
|
import Post from "../../api/v2/model/user-group/post.js";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import Get from "../../api/v2/model/user-group/get.js";
|
||||||
|
import Put from "../../api/v2/model/user-group/put.js";
|
||||||
|
|
||||||
|
|
||||||
|
let administrations = function () {
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
id: 0,
|
||||||
|
errors: {
|
||||||
|
title: []
|
||||||
|
},
|
||||||
|
|
||||||
|
// notifications
|
||||||
|
notifications: {
|
||||||
|
error: {
|
||||||
|
show: false, text: '', url: '',
|
||||||
|
}, success: {
|
||||||
|
show: false, text: '', url: '',
|
||||||
|
}, wait: {
|
||||||
|
show: false, text: '',
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// state of the form is stored in formState:
|
||||||
|
formStates: {
|
||||||
|
isSubmitting: false,
|
||||||
|
returnHereButton: false,
|
||||||
|
saveAsNewButton: false, // edit form only
|
||||||
|
resetButton: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// form behaviour
|
||||||
|
formBehaviour: {
|
||||||
|
formType: 'update', // or 'update'
|
||||||
|
},
|
||||||
|
changedTitle() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
pageProperties: {},
|
||||||
|
submitForm() {
|
||||||
|
console.log('submitForm');
|
||||||
|
(new Put()).put({title: this.title}, {id: this.id}).then(response => {
|
||||||
|
if (this.formStates.returnHereButton) {
|
||||||
|
this.notifications.success.show = true;
|
||||||
|
this.notifications.success.text = i18next.t('firefly.updated_administration', {title: response.data.data.attributes.title});
|
||||||
|
// TODO needs a better redirect.
|
||||||
|
this.notifications.success.url = './administrations';
|
||||||
|
}
|
||||||
|
if (this.formStates.resetButton) {
|
||||||
|
this.title = '';
|
||||||
|
}
|
||||||
|
if (!this.formStates.returnHereButton) {
|
||||||
|
// TODO needs a better redirect.
|
||||||
|
window.location.href = './administrations?user_group_id=' + parseInt(response.data.data.id) + '&message=updated';
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.errors.title = error.response.data.errors.title;
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
cancelForm() {
|
||||||
|
window.location.href = './administrations';
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
const page = window.location.href.split('/');
|
||||||
|
const groupId = parseInt(page[page.length - 1]);
|
||||||
|
(new Get()).show(groupId, {}).then(response => {
|
||||||
|
this.title = response.data.data.attributes.title;
|
||||||
|
this.id = parseInt(response.data.data.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let comps = {administrations, dates};
|
||||||
|
|
||||||
|
function loadPage() {
|
||||||
|
Object.keys(comps).forEach(comp => {
|
||||||
|
console.log(`Loading page component "${comp}"`);
|
||||||
|
let data = comps[comp]();
|
||||||
|
Alpine.data(comp, () => data);
|
||||||
|
});
|
||||||
|
Alpine.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for load until bootstrapped event is received.
|
||||||
|
document.addEventListener('firefly-iii-bootstrapped', () => {
|
||||||
|
console.log('Loaded through event listener.');
|
||||||
|
loadPage();
|
||||||
|
});
|
||||||
|
// or is bootstrapped before event is triggered.
|
||||||
|
if (window.bootstrapped) {
|
||||||
|
console.log('Loaded through window variable.');
|
||||||
|
loadPage();
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ import '@ag-grid-community/styles/ag-grid.css';
|
|||||||
import '@ag-grid-community/styles/ag-theme-alpine.css';
|
import '@ag-grid-community/styles/ag-theme-alpine.css';
|
||||||
import '../../css/grid-ff3-theme.css';
|
import '../../css/grid-ff3-theme.css';
|
||||||
import Get from "../../api/v2/model/user-group/get.js";
|
import Get from "../../api/v2/model/user-group/get.js";
|
||||||
|
import Post from "../../api/v2/model/user-group/post.js";
|
||||||
|
|
||||||
let index = function () {
|
let index = function () {
|
||||||
return {
|
return {
|
||||||
@@ -53,8 +54,16 @@ let index = function () {
|
|||||||
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
|
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
|
||||||
this.loadAdministrations();
|
this.loadAdministrations();
|
||||||
},
|
},
|
||||||
|
useAdministration(id) {
|
||||||
|
let groupId = parseInt(id);
|
||||||
|
// try to post "use", then reload administrations.
|
||||||
|
(new Post()).use(groupId).then(response => {
|
||||||
|
this.loadAdministrations();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
loadAdministrations() {
|
loadAdministrations() {
|
||||||
|
this.userGroups = [];
|
||||||
this.notifications.wait.show = true;
|
this.notifications.wait.show = true;
|
||||||
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
|
this.notifications.wait.text = i18next.t('firefly.wait_loading_data')
|
||||||
this.accounts = [];
|
this.accounts = [];
|
||||||
@@ -73,16 +82,13 @@ let index = function () {
|
|||||||
membersVisible: current.attributes.can_see_members,
|
membersVisible: current.attributes.can_see_members,
|
||||||
members: [],
|
members: [],
|
||||||
};
|
};
|
||||||
console.log('Processing group #' + group.id + ' (' + group.title + ')' );
|
|
||||||
let memberships = {};
|
let memberships = {};
|
||||||
for (let j = 0; j < current.attributes.members.length; j++) {
|
for (let j = 0; j < current.attributes.members.length; j++) {
|
||||||
let member = current.attributes.members[j];
|
let member = current.attributes.members[j];
|
||||||
console.log('Found member ' + member.user_email, member.you, member.role);
|
|
||||||
if ('owner' === member.role) {
|
if ('owner' === member.role) {
|
||||||
group.owner = i18next.t('firefly.administration_owner', {email: member.user_email});
|
group.owner = i18next.t('firefly.administration_owner', {email: member.user_email});
|
||||||
}
|
}
|
||||||
if (true === member.you && 'owner' === member.role) {
|
if (true === member.you && 'owner' === member.role) {
|
||||||
console.log('You are owner of group ' + group.title );
|
|
||||||
group.isOwner = true;
|
group.isOwner = true;
|
||||||
}
|
}
|
||||||
if (true === member.you) {
|
if (true === member.you) {
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import formatMoney from "../../util/format-money.js";
|
|||||||
import Get from "../../api/v2/model/account/get.js";
|
import Get from "../../api/v2/model/account/get.js";
|
||||||
import {Chart} from 'chart.js';
|
import {Chart} from 'chart.js';
|
||||||
import {getDefaultChartSettings} from "../../support/default-chart-settings.js";
|
import {getDefaultChartSettings} from "../../support/default-chart-settings.js";
|
||||||
import {getColors} from "../../support/get-colors.js";
|
|
||||||
import {getCacheKey} from "../../support/get-cache-key.js";
|
import {getCacheKey} from "../../support/get-cache-key.js";
|
||||||
import {getConfiguration} from "../../store/get-configuration.js";
|
import {getConfiguration} from "../../store/get-configuration.js";
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export default () => ({
|
|||||||
getFreshData() {
|
getFreshData() {
|
||||||
const start = new Date(window.store.get('start'));
|
const start = new Date(window.store.get('start'));
|
||||||
const end = new Date(window.store.get('end'));
|
const end = new Date(window.store.get('end'));
|
||||||
|
// needs user data.
|
||||||
const cacheKey = getCacheKey(PIGGY_CACHE_KEY, start, end);
|
const cacheKey = getCacheKey(PIGGY_CACHE_KEY, start, end);
|
||||||
|
|
||||||
const cacheValid = window.store.get('cacheValid');
|
const cacheValid = window.store.get('cacheValid');
|
||||||
|
|||||||
@@ -24,6 +24,33 @@ import dates from "./shared/dates.js";
|
|||||||
|
|
||||||
let somethings = function() {
|
let somethings = function() {
|
||||||
return {
|
return {
|
||||||
|
// notifications
|
||||||
|
// TODO duplicate code
|
||||||
|
notifications: {
|
||||||
|
error: {
|
||||||
|
show: false, text: '', url: '',
|
||||||
|
}, success: {
|
||||||
|
show: false, text: '', url: '',
|
||||||
|
}, wait: {
|
||||||
|
show: false, text: '',
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// state of the form is stored in formState:
|
||||||
|
// TODO duplicate code
|
||||||
|
formStates: {
|
||||||
|
isSubmitting: false,
|
||||||
|
returnHereButton: false,
|
||||||
|
saveAsNewButton: false, // edit form only
|
||||||
|
resetButton: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// form behaviour
|
||||||
|
// TODO duplicate code
|
||||||
|
formBehaviour: {
|
||||||
|
formType: 'create', // or 'update'
|
||||||
|
},
|
||||||
|
|
||||||
pageProperties: {},
|
pageProperties: {},
|
||||||
functionName() {
|
functionName() {
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ let transactions = function () {
|
|||||||
|
|
||||||
// form behaviour during transaction
|
// form behaviour during transaction
|
||||||
formBehaviour: {
|
formBehaviour: {
|
||||||
formType: 'create', foreignCurrencyEnabled: true,
|
formType: 'create',
|
||||||
|
foreignCurrencyEnabled: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// form data (except transactions) is stored in formData
|
// form data (except transactions) is stored in formData
|
||||||
|
|||||||
@@ -19,9 +19,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {format} from "date-fns";
|
import {format} from "date-fns";
|
||||||
|
import store from "store";
|
||||||
|
|
||||||
function getCacheKey(string, start, end) {
|
function getCacheKey(string, start, end) {
|
||||||
const cacheKey = format(start, 'y-MM-dd') + '_' + format(end, 'y-MM-dd') + '_' + string;
|
const localValue = store.get('lastActivity');
|
||||||
|
const cacheKey = format(start, 'y-MM-dd') + '_' + format(end, 'y-MM-dd') + '_' + string + localValue;
|
||||||
console.log('getCacheKey: ' + cacheKey);
|
console.log('getCacheKey: ' + cacheKey);
|
||||||
return String(cacheKey);
|
return String(cacheKey);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'No tens accés a aquesta administració.',
|
'no_access_user_group' => 'No tens accés a aquesta administració.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Du har ikke de korrekte adgangsrettigheder for denne administration.',
|
'no_access_user_group' => 'Du har ikke de korrekte adgangsrettigheder for denne administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Für diese Verwaltung haben Sie nicht die erforderlichen Zugriffsrechte.',
|
'no_access_user_group' => 'Für diese Verwaltung haben Sie nicht die erforderlichen Zugriffsrechte.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Δεν έχετε τα σωστά δικαιώματα πρόσβασης για αυτή τη διαχείριση.',
|
'no_access_user_group' => 'Δεν έχετε τα σωστά δικαιώματα πρόσβασης για αυτή τη διαχείριση.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -264,6 +264,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Ignore this comment
|
// Ignore this comment
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'No tiene permisos para esta administración.',
|
'no_access_user_group' => 'No tiene permisos para esta administración.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Vous n\'avez pas les droits d\'accès corrects pour cette administration.',
|
'no_access_user_group' => 'Vous n\'avez pas les droits d\'accès corrects pour cette administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Non hai i diritti di accesso corretti per questa amministrazione.',
|
'no_access_user_group' => 'Non hai i diritti di accesso corretti per questa amministrazione.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'この管理のための適切なアクセス権がありません。',
|
'no_access_user_group' => 'この管理のための適切なアクセス権がありません。',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => '이 관리에 대한 올바른 액세스 권한이 없습니다.',
|
'no_access_user_group' => '이 관리에 대한 올바른 액세스 권한이 없습니다.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Du har ikke rettigheter til denne handlingen.',
|
'no_access_user_group' => 'Du har ikke rettigheter til denne handlingen.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ return [
|
|||||||
// 'date_time' => '%B %e, %Y, @ %T',
|
// 'date_time' => '%B %e, %Y, @ %T',
|
||||||
'date_time_js' => 'D MMMM YYYY @ HH:mm:ss',
|
'date_time_js' => 'D MMMM YYYY @ HH:mm:ss',
|
||||||
'date_time_fns' => 'd MMMM yyyy @ HH:mm:ss',
|
'date_time_fns' => 'd MMMM yyyy @ HH:mm:ss',
|
||||||
'date_time_fns_short' => 'MMMM do, yyyy @ HH:mm',
|
'date_time_fns_short' => 'd MMMM yyyy @ HH:mm',
|
||||||
|
|
||||||
// 'specific_day' => '%e %B %Y',
|
// 'specific_day' => '%e %B %Y',
|
||||||
'specific_day_js' => 'D MMMM YYYY',
|
'specific_day_js' => 'D MMMM YYYY',
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ return [
|
|||||||
'fatal_error' => 'Er is een fatale fout opgetreden. Controleer de logbestanden in "storage/logs" of gebruik "docker logs -f [container]" om te zien wat er gebeurde.',
|
'fatal_error' => 'Er is een fatale fout opgetreden. Controleer de logbestanden in "storage/logs" of gebruik "docker logs -f [container]" om te zien wat er gebeurde.',
|
||||||
'maintenance_mode' => 'Firefly III is in onderhoudsmodus.',
|
'maintenance_mode' => 'Firefly III is in onderhoudsmodus.',
|
||||||
'be_right_back' => 'Zo terug!',
|
'be_right_back' => 'Zo terug!',
|
||||||
'check_back' => 'Firefly III is down for some necessary maintenance. Please check back in a second. If you happen to see this message on the demo site, just wait a few minutes. The database is reset every few hours.',
|
'check_back' => 'Firefly III is offline voor hoognodig onderhoud. Kom later terug. Als je dit bericht op de demo site ziet, wacht dan een paar minuten. De database wordt elke paar uur gereset.',
|
||||||
'error_occurred' => 'Oeps! Er is een fout opgetreden.',
|
'error_occurred' => 'Oeps! Er is een fout opgetreden.',
|
||||||
'db_error_occurred' => 'Oeps! Er is een database-fout opgetreden.',
|
'db_error_occurred' => 'Oeps! Er is een database-fout opgetreden.',
|
||||||
'error_not_recoverable' => 'Helaas was deze fout niet te herstellen :(. Firefly III is stuk. De fout is:',
|
'error_not_recoverable' => 'Helaas was deze fout niet te herstellen :(. Firefly III is stuk. De fout is:',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -70,5 +70,5 @@ return [
|
|||||||
'cannot_find_budget' => 'Firefly III kan budget ":name" niet vinden',
|
'cannot_find_budget' => 'Firefly III kan budget ":name" niet vinden',
|
||||||
'cannot_find_category' => 'Firefly III kan categorie ":name" niet vinden',
|
'cannot_find_category' => 'Firefly III kan categorie ":name" niet vinden',
|
||||||
'cannot_set_budget' => 'Firefly III kan budget ":name" niet instellen op een transactie van het type ":type"',
|
'cannot_set_budget' => 'Firefly III kan budget ":name" niet instellen op een transactie van het type ":type"',
|
||||||
'journal_invalid_amount' => 'Firefly III can\'t set amount ":amount" because it is not a valid number.',
|
'journal_invalid_amount' => 'Firefly III kan bedrag ":amount" niet instellen omdat dit geen geldig getal is.',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ return [
|
|||||||
'reconciled_forbidden_field' => 'Deze transactie is al afgestemd, dus je kan ":field" niet wijzigen',
|
'reconciled_forbidden_field' => 'Deze transactie is al afgestemd, dus je kan ":field" niet wijzigen',
|
||||||
'deleted_user' => 'Je kan je niet registreren met dit e-mailadres.',
|
'deleted_user' => 'Je kan je niet registreren met dit e-mailadres.',
|
||||||
'rule_trigger_value' => 'Deze waarde is niet geldig voor de geselecteerde trigger.',
|
'rule_trigger_value' => 'Deze waarde is niet geldig voor de geselecteerde trigger.',
|
||||||
'rule_action_expression' => 'Invalid expression. :error',
|
'rule_action_expression' => 'Ongeldige expressie (foutmelding in het Engels): :error',
|
||||||
'rule_action_value' => 'Deze waarde is niet geldig voor de geselecteerde actie.',
|
'rule_action_value' => 'Deze waarde is niet geldig voor de geselecteerde actie.',
|
||||||
'file_already_attached' => 'Het geuploade bestand ":name" is al gelinkt aan deze transactie.',
|
'file_already_attached' => 'Het geuploade bestand ":name" is al gelinkt aan deze transactie.',
|
||||||
'file_attached' => 'Bestand ":name" is succesvol geüpload.',
|
'file_attached' => 'Bestand ":name" is succesvol geüpload.',
|
||||||
'file_zero' => 'The file is zero bytes in size.',
|
'file_zero' => 'Het bestand is nul bytes.',
|
||||||
'must_exist' => 'Het ID in veld :attribute bestaat niet.',
|
'must_exist' => 'Het ID in veld :attribute bestaat niet.',
|
||||||
'all_accounts_equal' => 'Alle rekeningen in dit veld moeten gelijk zijn.',
|
'all_accounts_equal' => 'Alle rekeningen in dit veld moeten gelijk zijn.',
|
||||||
'group_title_mandatory' => 'Een groepstitel is verplicht wanneer er meer dan één transactie is.',
|
'group_title_mandatory' => 'Een groepstitel is verplicht wanneer er meer dan één transactie is.',
|
||||||
@@ -197,7 +197,7 @@ return [
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'secure_password' => 'This is not a secure password. Please try again. For more information, visit https://bit.ly/FF3-password',
|
'secure_password' => 'Dit is geen veilig wachtwoord. Probeer het nog een keer. Zie ook: https://bit.ly/FF3-password',
|
||||||
'valid_recurrence_rep_type' => 'Dit is geen geldige herhaling voor periodieke transacties.',
|
'valid_recurrence_rep_type' => 'Dit is geen geldige herhaling voor periodieke transacties.',
|
||||||
'valid_recurrence_rep_moment' => 'Ongeldig herhaalmoment voor dit type herhaling.',
|
'valid_recurrence_rep_moment' => 'Ongeldig herhaalmoment voor dit type herhaling.',
|
||||||
'invalid_account_info' => 'Ongeldige rekeninginformatie.',
|
'invalid_account_info' => 'Ongeldige rekeninginformatie.',
|
||||||
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Je hebt niet de juiste toegangsrechten voor deze administratie.',
|
'no_access_user_group' => 'Je hebt niet de juiste toegangsrechten voor deze administratie.',
|
||||||
|
'administration_owner_rename' => 'Je kan je standaardgrootboek niet hernoemen.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Du har ikkje rettigheter til denne handlinga.',
|
'no_access_user_group' => 'Du har ikkje rettigheter til denne handlinga.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Nie masz odpowiednich praw dostępu dla tej administracji.',
|
'no_access_user_group' => 'Nie masz odpowiednich praw dostępu dla tej administracji.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Você não direitos de acesso suficientes para esta administração.',
|
'no_access_user_group' => 'Você não direitos de acesso suficientes para esta administração.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Não tem as permissões de acesso necessárias para esta administração.',
|
'no_access_user_group' => 'Não tem as permissões de acesso necessárias para esta administração.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -300,6 +300,7 @@ return [
|
|||||||
|
|
||||||
// no access to administration:
|
// no access to administration:
|
||||||
'no_access_user_group' => 'Nu aveți drepturile de acces corecte pentru această administrare.',
|
'no_access_user_group' => 'Nu aveți drepturile de acces corecte pentru această administrare.',
|
||||||
|
'administration_owner_rename' => 'You can\'t rename your standard administration.',
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user