mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-02 03:02:18 +00:00
Compare commits
91 Commits
develop-20
...
develop-20
Author | SHA1 | Date | |
---|---|---|---|
|
36d9e5c3fe | ||
|
8d614de67f | ||
|
d17da670ab | ||
|
5bf4df9ad8 | ||
|
07db6b59ce | ||
|
e16f1cf4ee | ||
|
4c80d929ca | ||
|
16364d9859 | ||
|
c24f6acb2c | ||
|
4bd19e0627 | ||
|
69d839997a | ||
|
c02c027f4f | ||
|
b14606625e | ||
|
222d7b56c7 | ||
|
b7f7bf42b2 | ||
|
0cbd64d31a | ||
|
60bdae47c4 | ||
|
ca4b38d905 | ||
|
3674465f53 | ||
|
b951d4130c | ||
|
7992b810fd | ||
|
c1c0afa40b | ||
|
56c9026299 | ||
|
021ddfc36b | ||
|
feabfe54f0 | ||
|
565409b486 | ||
|
f57366da5f | ||
|
064217ccb0 | ||
|
fa3ccbda33 | ||
|
f43aadf02d | ||
|
3b8a4d3e9b | ||
|
3d410556ef | ||
|
f15ca1d0a1 | ||
|
7002463c54 | ||
|
649f876437 | ||
|
3cfd178cbd | ||
|
cefbaafa19 | ||
|
a8c88800c4 | ||
|
9d1a127200 | ||
|
3fdde2d1c8 | ||
|
cdc0b8dd2c | ||
|
1a1e06e6e8 | ||
|
6d39b8468c | ||
|
bdee3947b2 | ||
|
2317037655 | ||
|
dcea6b757b | ||
|
bd7fe92818 | ||
|
850e47d8db | ||
|
96fe62400f | ||
|
5d07fcdcb6 | ||
|
fd5d2d57a8 | ||
|
8e7d42201f | ||
|
f26bd3cb31 | ||
|
36915cdace | ||
|
8a5cecd2a0 | ||
|
78da1b22bb | ||
|
6d970a9794 | ||
|
8bb7739f05 | ||
|
7788bb4b33 | ||
|
2ecb4bb3b7 | ||
|
4a783d3c3c | ||
|
e16645ae87 | ||
|
9d3189be7e | ||
|
07fca78293 | ||
|
82080501c7 | ||
|
d93d6bfc66 | ||
|
a41326ef94 | ||
|
90b77845c3 | ||
|
57af80d820 | ||
|
fc4d5a1dfd | ||
|
8ab9ab8d21 | ||
|
75674b5793 | ||
|
a7d6f26051 | ||
|
eb540ce148 | ||
|
a3077fe43b | ||
|
63bb84d375 | ||
|
e5f5aa628e | ||
|
c54f84dc8e | ||
|
c2e562623c | ||
|
c8d5e8a9dc | ||
|
963f017be3 | ||
|
0e0eeb736f | ||
|
e8d9b8fa49 | ||
|
c166b9242e | ||
|
8ff8efced2 | ||
|
0b4fb9a806 | ||
|
ba9fef9410 | ||
|
f7d94d17cd | ||
|
1fea9c6817 | ||
|
a88c8bedbe | ||
|
fbf3468053 |
169
.ci/php-cs-fixer/composer.lock
generated
169
.ci/php-cs-fixer/composer.lock
generated
@@ -160,16 +160,16 @@
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
"version": "3.0.4",
|
||||
"version": "3.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/xdebug-handler.git",
|
||||
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255"
|
||||
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
|
||||
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -206,7 +206,7 @@
|
||||
"support": {
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/xdebug-handler/issues",
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.4"
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -222,20 +222,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-26T18:29:49+00:00"
|
||||
"time": "2024-05-06T16:37:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.52.1",
|
||||
"version": "v3.56.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc"
|
||||
"reference": "4429303e62a4ce583ddfe64ff5c34c76bcf74931"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/6e77207f0d851862ceeb6da63e6e22c01b1587bc",
|
||||
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4429303e62a4ce583ddfe64ff5c34c76bcf74931",
|
||||
"reference": "4429303e62a4ce583ddfe64ff5c34c76bcf74931",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -259,6 +259,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"facile-it/paraunit": "^1.3 || ^2.0",
|
||||
"infection/infection": "^0.27.11",
|
||||
"justinrainbow/json-schema": "^5.2",
|
||||
"keradus/cli-executor": "^2.1",
|
||||
"mikey179/vfsstream": "^1.6.11",
|
||||
@@ -306,7 +307,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.52.1"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.56.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -314,7 +315,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-19T21:02:43+00:00"
|
||||
"time": "2024-05-07T15:50:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
@@ -538,16 +539,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.0.6",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5"
|
||||
"reference": "c981e0e9380ce9f146416bde3150c79197ce9986"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/fde915cd8e7eb99b3d531d3d5c09531429c3f9e5",
|
||||
"reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/c981e0e9380ce9f146416bde3150c79197ce9986",
|
||||
"reference": "c981e0e9380ce9f146416bde3150c79197ce9986",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -611,7 +612,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.0.6"
|
||||
"source": "https://github.com/symfony/console/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -627,20 +628,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-04-01T11:04:53+00:00"
|
||||
"time": "2024-04-18T09:29:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.4.0",
|
||||
"version": "v3.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
|
||||
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
|
||||
"reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
|
||||
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -649,7 +650,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.4-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
@@ -678,7 +679,7 @@
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -694,20 +695,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-05-23T14:45:45+00:00"
|
||||
"time": "2024-04-18T09:32:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v7.0.3",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "834c28d533dd0636f910909d01b9ff45cc094b5e"
|
||||
"reference": "db2a7fab994d67d92356bb39c367db115d9d30f9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/834c28d533dd0636f910909d01b9ff45cc094b5e",
|
||||
"reference": "834c28d533dd0636f910909d01b9ff45cc094b5e",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/db2a7fab994d67d92356bb39c367db115d9d30f9",
|
||||
"reference": "db2a7fab994d67d92356bb39c367db115d9d30f9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -758,7 +759,7 @@
|
||||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v7.0.3"
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -774,20 +775,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-23T15:02:46+00:00"
|
||||
"time": "2024-04-18T09:29:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
"version": "v3.4.2",
|
||||
"version": "v3.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
|
||||
"reference": "4e64b49bf370ade88e567de29465762e316e4224"
|
||||
"reference": "8f93aec25d41b72493c6ddff14e916177c9efc50"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/4e64b49bf370ade88e567de29465762e316e4224",
|
||||
"reference": "4e64b49bf370ade88e567de29465762e316e4224",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50",
|
||||
"reference": "8f93aec25d41b72493c6ddff14e916177c9efc50",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -797,7 +798,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.4-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
@@ -834,7 +835,7 @@
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.2"
|
||||
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -850,26 +851,27 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-23T14:51:35+00:00"
|
||||
"time": "2024-04-18T09:32:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v7.0.6",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "408105dff4c104454100730bdfd1a9cdd993f04d"
|
||||
"reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/408105dff4c104454100730bdfd1a9cdd993f04d",
|
||||
"reference": "408105dff4c104454100730bdfd1a9cdd993f04d",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/cc168be6fbdcdf3401f50ae863ee3818ed4338f5",
|
||||
"reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-mbstring": "~1.8"
|
||||
"symfony/polyfill-mbstring": "~1.8",
|
||||
"symfony/process": "^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -897,7 +899,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.0.6"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -913,20 +915,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-21T19:37:36+00:00"
|
||||
"time": "2024-04-18T09:29:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v7.0.0",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56"
|
||||
"reference": "4d58f0f4fe95a30d7b538d71197135483560b97c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56",
|
||||
"reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/4d58f0f4fe95a30d7b538d71197135483560b97c",
|
||||
"reference": "4d58f0f4fe95a30d7b538d71197135483560b97c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -961,7 +963,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v7.0.0"
|
||||
"source": "https://github.com/symfony/finder/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -977,20 +979,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-10-31T17:59:56+00:00"
|
||||
"time": "2024-04-28T11:44:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v7.0.0",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "700ff4096e346f54cb628ea650767c8130f1001f"
|
||||
"reference": "23cc173858776ad451e31f053b1c9f47840b2cfa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f",
|
||||
"reference": "700ff4096e346f54cb628ea650767c8130f1001f",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/23cc173858776ad451e31f053b1c9f47840b2cfa",
|
||||
"reference": "23cc173858776ad451e31f053b1c9f47840b2cfa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1028,7 +1030,7 @@
|
||||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.0.0"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1044,7 +1046,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-08-08T10:20:21+00:00"
|
||||
"time": "2024-04-18T09:29:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -1522,16 +1524,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.0.4",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9"
|
||||
"reference": "3839e56b94dd1dbd13235d27504e66baf23faba0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9",
|
||||
"reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/3839e56b94dd1dbd13235d27504e66baf23faba0",
|
||||
"reference": "3839e56b94dd1dbd13235d27504e66baf23faba0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1563,7 +1565,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.0.4"
|
||||
"source": "https://github.com/symfony/process/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1579,25 +1581,26 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-02-22T20:27:20+00:00"
|
||||
"time": "2024-04-18T09:29:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v3.4.2",
|
||||
"version": "v3.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "11bbf19a0fb7b36345861e85c5768844c552906e"
|
||||
"reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/11bbf19a0fb7b36345861e85c5768844c552906e",
|
||||
"reference": "11bbf19a0fb7b36345861e85c5768844c552906e",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f",
|
||||
"reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"psr/container": "^1.1|^2.0"
|
||||
"psr/container": "^1.1|^2.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"ext-psr": "<1.1|>=2"
|
||||
@@ -1605,7 +1608,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.4-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
@@ -1645,7 +1648,7 @@
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.4.2"
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.5.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1661,20 +1664,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-19T21:51:00+00:00"
|
||||
"time": "2024-04-18T09:32:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v7.0.3",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/stopwatch.git",
|
||||
"reference": "983900d6fddf2b0cbaacacbbad07610854bd8112"
|
||||
"reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/983900d6fddf2b0cbaacacbbad07610854bd8112",
|
||||
"reference": "983900d6fddf2b0cbaacacbbad07610854bd8112",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/41a7a24aa1dc82adf46a06bc292d1923acfe6b84",
|
||||
"reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1707,7 +1710,7 @@
|
||||
"description": "Provides a way to profile code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v7.0.3"
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1723,20 +1726,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-23T15:02:46+00:00"
|
||||
"time": "2024-04-18T09:29:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.0.4",
|
||||
"version": "v7.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "f5832521b998b0bec40bee688ad5de98d4cf111b"
|
||||
"reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b",
|
||||
"reference": "f5832521b998b0bec40bee688ad5de98d4cf111b",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/e405b5424dc2528e02e31ba26b83a79fd4eb8f63",
|
||||
"reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1793,7 +1796,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.0.4"
|
||||
"source": "https://github.com/symfony/string/tree/v7.0.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1809,7 +1812,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-02-01T13:17:36+00:00"
|
||||
"time": "2024-04-18T09:29:19+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
19
.ci/phpcs.sh
19
.ci/phpcs.sh
@@ -20,23 +20,8 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# Install composer packages
|
||||
#composer install --no-scripts --no-ansi
|
||||
|
||||
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
|
||||
# enable test .env file.
|
||||
# cp .ci/.env.ci .env
|
||||
|
||||
OUTPUT_FORMAT=txt
|
||||
EXTRA_PARAMS=""
|
||||
|
||||
if [[ $GITHUB_ACTIONS = "true" ]]
|
||||
then
|
||||
OUTPUT_FORMAT=txt
|
||||
EXTRA_PARAMS=""
|
||||
fi
|
||||
|
||||
# clean up php code
|
||||
cd $SCRIPT_DIR/php-cs-fixer
|
||||
composer update --quiet
|
||||
@@ -44,8 +29,8 @@ rm -f .php-cs-fixer.cache
|
||||
PHP_CS_FIXER_IGNORE_ENV=true
|
||||
./vendor/bin/php-cs-fixer fix \
|
||||
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
|
||||
--format=$OUTPUT_FORMAT \
|
||||
--allow-risky=yes $EXTRA_PARAMS
|
||||
--format=txt \
|
||||
--allow-risky=yes
|
||||
|
||||
EXIT_CODE=$?
|
||||
|
||||
|
8
.github/pull_request_template.md
vendored
8
.github/pull_request_template.md
vendored
@@ -1,13 +1,13 @@
|
||||
<!--
|
||||
Thank you for submitting new code to Firefly III, or any of the related projects. Please read the following rules carefully.
|
||||
|
||||
- Do not submit solutions for problems that are not already reported in an issue
|
||||
- Firefly III can't be your learning experience. If you're new to all of this, please go be new somewhere else
|
||||
- Do not open PRs to "discuss" possible solutions or to "get feedback" on your code. I don't have time for that.
|
||||
- Please do not submit solutions for problems that are not already reported in an issue.
|
||||
- Unfortunately, Firefly III can't be your learning experience. If you're new to all of this, please open an issue first.
|
||||
- Please do not open PRs to "discuss" possible solutions or to "get feedback" on your code. I simply don't have time for that.
|
||||
- Pull requests for the MAIN branch will be closed.
|
||||
- DO NOT include translated strings in your PR.
|
||||
|
||||
Perhaps open an issue first, before you open a PR?
|
||||
If it feels necessary to open an issue first, please do so, before you open a PR.
|
||||
|
||||
See also: https://docs.firefly-iii.org/explanation/support/#contributing-code
|
||||
|
||||
|
2
.github/workflows/close-duplicates.yml
vendored
2
.github/workflows/close-duplicates.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
close_duplicates:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: github/command@v1.1.0
|
||||
- uses: github/command@v1.1.1
|
||||
id: command
|
||||
with:
|
||||
allowed_contexts: "issue"
|
||||
|
36
.github/workflows/release.yml
vendored
36
.github/workflows/release.yml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
|
||||
- name: Cleanup translations
|
||||
id: cleanup-transactions
|
||||
uses: JC5/firefly-iii-dev@v38
|
||||
uses: JC5/firefly-iii-dev@main
|
||||
with:
|
||||
action: 'ff3:crowdin-warning'
|
||||
output: ''
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
GH_TOKEN: ''
|
||||
- name: Cleanup changelog
|
||||
id: cleanup-changelog
|
||||
uses: JC5/firefly-iii-dev@v38
|
||||
uses: JC5/firefly-iii-dev@main
|
||||
with:
|
||||
action: 'ff3:changelog'
|
||||
output: ''
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.CHANGELOG_TOKEN }}
|
||||
- name: Extract changelog
|
||||
id: extract-changelog
|
||||
uses: JC5/firefly-iii-dev@v38
|
||||
uses: JC5/firefly-iii-dev@main
|
||||
with:
|
||||
action: 'ff3:extract-changelog'
|
||||
output: 'output'
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
GH_TOKEN: ""
|
||||
- name: Replace version
|
||||
id: replace-version
|
||||
uses: JC5/firefly-iii-dev@v38
|
||||
uses: JC5/firefly-iii-dev@main
|
||||
with:
|
||||
action: 'ff3:version'
|
||||
output: ''
|
||||
@@ -88,7 +88,7 @@ jobs:
|
||||
FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
|
||||
- name: Generate JSON v1
|
||||
id: json-v1
|
||||
uses: JC5/firefly-iii-dev@v38
|
||||
uses: JC5/firefly-iii-dev@main
|
||||
with:
|
||||
action: 'ff3:json-translations v1'
|
||||
output: ''
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
GH_TOKEN: ''
|
||||
- name: Generate JSON v2
|
||||
id: json-v2
|
||||
uses: JC5/firefly-iii-dev@v38
|
||||
uses: JC5/firefly-iii-dev@main
|
||||
with:
|
||||
action: 'ff3:json-translations v2'
|
||||
output: ''
|
||||
@@ -106,7 +106,7 @@ jobs:
|
||||
GH_TOKEN: ''
|
||||
- name: Code cleanup
|
||||
id: code-cleanup
|
||||
uses: JC5/firefly-iii-dev@v38
|
||||
uses: JC5/firefly-iii-dev@main
|
||||
with:
|
||||
action: 'ff3:code'
|
||||
output: ''
|
||||
@@ -122,10 +122,14 @@ jobs:
|
||||
- name: Run CI
|
||||
run: |
|
||||
rm -rf vendor composer.lock
|
||||
composer validate --strict
|
||||
composer update --no-dev --no-scripts --no-plugins -q
|
||||
sudo chown -R runner:docker resources/lang
|
||||
.ci/phpcs.sh
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.PASSPHRASE }}
|
||||
- name: Release
|
||||
run: |
|
||||
# do some configuration
|
||||
@@ -141,7 +145,6 @@ jobs:
|
||||
tarName=FireflyIII-$version.tar.gz
|
||||
|
||||
# update composer (again)
|
||||
composer validate --strict
|
||||
composer update --no-dev --no-scripts --no-plugins
|
||||
composer dump-autoload
|
||||
|
||||
@@ -191,6 +194,10 @@ jobs:
|
||||
sha256sum -b $zipName > $zipName.sha256
|
||||
sha256sum -b $tarName > $tarName.sha256
|
||||
|
||||
# add signatures:
|
||||
gpg --armor --detach-sign $zipName
|
||||
gpg --armor --detach-sign $tarName
|
||||
|
||||
# create a development (nightly) release:
|
||||
if [[ "develop" == "$version" ]]; then
|
||||
echo 'Develop release.'
|
||||
@@ -198,7 +205,7 @@ jobs:
|
||||
rm output.txt
|
||||
echo "Bi-weekly development release of Firefly III with the latest fixes, translations and features. Docker users can find this release under the \`develop\` tag." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible." >> output.txt
|
||||
echo "This release was created on **$(date +'%Y-%m-%d')** and may contain unexpected bugs. Data loss is rare but is not impossible. The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo "* Please read the installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
@@ -221,6 +228,10 @@ jobs:
|
||||
gh release upload $releaseName $zipName.sha256
|
||||
gh release upload $releaseName $tarName.sha256
|
||||
|
||||
# add signatures to release
|
||||
gh release upload $releaseName $zipName.asc
|
||||
gh release upload $releaseName $tarName.asc
|
||||
|
||||
# get current HEAD and add as file to the release
|
||||
HEAD=$(git rev-parse HEAD)
|
||||
echo $HEAD > HEAD.txt
|
||||
@@ -234,6 +245,7 @@ jobs:
|
||||
echo '' >> output.txt
|
||||
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)."
|
||||
|
||||
echo "Create default release."
|
||||
git tag -a $releaseName -m "Here be changelog"
|
||||
@@ -248,6 +260,10 @@ jobs:
|
||||
gh release upload $releaseName $zipName.sha256
|
||||
gh release upload $releaseName $tarName.sha256
|
||||
|
||||
# add signatures to release
|
||||
gh release upload $releaseName $zipName.asc
|
||||
gh release upload $releaseName $tarName.asc
|
||||
|
||||
# get current HEAD and add as file to the release
|
||||
HEAD=$(git rev-parse HEAD)
|
||||
echo $HEAD > HEAD.txt
|
||||
|
193
THANKS.md
Executable file
193
THANKS.md
Executable file
@@ -0,0 +1,193 @@
|
||||
# Thank you! :tada: :heart: :tada:
|
||||
|
||||
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
|
||||
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
||||
|
||||
## 2024
|
||||
- imlonghao
|
||||
- Rahman Yusuf
|
||||
- Michael Thomas
|
||||
- WardenJakx
|
||||
- kuilin
|
||||
- Stevie Robinson
|
||||
- luzpaz
|
||||
- Lemuel Roberto Bonifácio
|
||||
- maureenferreira
|
||||
|
||||
## 2023
|
||||
- tieu1991
|
||||
- Maxco10
|
||||
- zqye
|
||||
- Mateus Pereira
|
||||
- josephbadow
|
||||
- Christian Desktop
|
||||
- Edgars
|
||||
- Hannah K
|
||||
- noxonad
|
||||
- Kaijia Feng
|
||||
- Marc Ordinas i Llopis
|
||||
- Kuba Turek
|
||||
- Julien Stébenne
|
||||
|
||||
## 2022
|
||||
- Johannes Zellner
|
||||
- Janne Heß
|
||||
- charlesteets
|
||||
- Nathan PERIER
|
||||
- Jan Willhaus
|
||||
- canoine
|
||||
- Rick Cuddy
|
||||
- James
|
||||
- Hugo Meyronneinc
|
||||
- naveen
|
||||
- neilnaveen
|
||||
- naveensrinivasan
|
||||
- Federico Micelli
|
||||
- George Hahn
|
||||
|
||||
## 2021
|
||||
- StillLoading
|
||||
- Igor Rzegocki
|
||||
- Lorenzo Breda
|
||||
- Hosh
|
||||
- Flightkick
|
||||
- alex6480
|
||||
- VREEdom
|
||||
- Hamza FADIL
|
||||
- Kasper Læssø Sørensen
|
||||
- Alex
|
||||
- Jeroen De Meerleer
|
||||
- Ruben van Erk
|
||||
- Fabian Zimmermann
|
||||
- Mirko Berger
|
||||
- KaihatsuOnline
|
||||
- MihataBG
|
||||
|
||||
## 2020
|
||||
- Hannes Körber
|
||||
- Julien Cassagne
|
||||
- bu4ak
|
||||
- Viktor Yakovlev
|
||||
- Oliver Kaufmann
|
||||
- Arvind Chembarpu
|
||||
- GrayStrider
|
||||
- psychowood
|
||||
- Hosh Sadiq
|
||||
- emansih
|
||||
- Aniruddha Maru
|
||||
- johnny
|
||||
- sephrat
|
||||
- bpatath
|
||||
- Florian Dupret
|
||||
- Maxim Kurbatov
|
||||
- Lucas Guima
|
||||
- Sandro
|
||||
- Ruben Verhoef
|
||||
- Daniel Idzerda
|
||||
- Calum Smith
|
||||
- Agraphie
|
||||
- Tomer Shvueli
|
||||
- Tomer S
|
||||
|
||||
## 2019
|
||||
- Pascal Jungblut
|
||||
- Justyn Shull
|
||||
- Timendum
|
||||
- Nicolas Lœuillet
|
||||
- Dominic Guhl
|
||||
- Melroy van den Berg
|
||||
- Henning Stein
|
||||
- Jan Klepek
|
||||
- Jonathan
|
||||
- Geoffrey “Frogeye” Preud'homme
|
||||
- Michael Fix
|
||||
- Juraj Mlich
|
||||
- Eddybrando Vásquez
|
||||
- hulloanson
|
||||
- Will Rouesnel
|
||||
- lastlink
|
||||
- Mr. Funk
|
||||
- Simon Taddiken
|
||||
- Joris
|
||||
- Bastiaan Nijkamp
|
||||
|
||||
## 2018
|
||||
- a1ex4
|
||||
- Daniel Quah
|
||||
- Marco Lourenço
|
||||
- Dennis Enderink
|
||||
- Luca Bognolo
|
||||
- Mike Conway
|
||||
- Ben
|
||||
- Mathieu Post
|
||||
- George Hertz
|
||||
- HamuZ HamuZ
|
||||
- David Meiseles
|
||||
- Erik Gelderblom
|
||||
- Luca Vallerini
|
||||
- Clemens Wijnekus
|
||||
- Jacob Weisz
|
||||
- Mateusz Gozdek
|
||||
- anmol26s
|
||||
- Kevin Hellemun
|
||||
- Shashank M Chakravarthy
|
||||
- Nico Schreiner
|
||||
- Paul Sohier
|
||||
- Brenden Conte
|
||||
- Ben Yanke
|
||||
- Andrew Prokhorenkov
|
||||
- devlearner
|
||||
- Kelvin
|
||||
- J'informatique
|
||||
|
||||
## 2017
|
||||
- Victor Mosin
|
||||
- Justin
|
||||
- Hugo van Duijn
|
||||
- Lukas Winkler
|
||||
- Marcin Szymanski
|
||||
- Jens Kat
|
||||
- koziolek
|
||||
- jleeong
|
||||
- Simon Hanna
|
||||
- richard & xeli.eu
|
||||
- Sergey Besedin
|
||||
- Welbert Serra
|
||||
- Joris de Vries
|
||||
- Patrick Kostjens
|
||||
- Enrico Lamperti
|
||||
- Christian Musa
|
||||
- Enno Lohmeier
|
||||
|
||||
## 2016
|
||||
- Sander
|
||||
- Toon Schoenmakers
|
||||
- Telyn
|
||||
- Sander Kleykens
|
||||
- Tom van der Werf
|
||||
- Matthew Peck
|
||||
- Sander Mulders
|
||||
- Bonno Nachtegaal-Karels
|
||||
- Niek Haarman
|
||||
- Edwin
|
||||
- Thijs Alkemade
|
||||
- zjean
|
||||
- Graham Miller
|
||||
- Robert Horlings
|
||||
- leander091
|
||||
|
||||
## 2015
|
||||
- Antonio Spinelli
|
||||
- Colin O'Dell
|
||||
- RonaldvanMeer
|
||||
- Richard Ebbers
|
||||
- Balazs Varkonyi
|
||||
- Niek van der Kooy
|
||||
- Ilya Kil
|
||||
|
||||
## 2014
|
||||
- Stewart Malik
|
||||
- Graham Campbell
|
||||
|
||||
|
||||
Thank you for all your support!
|
@@ -73,7 +73,8 @@ class UpdateController extends Controller
|
||||
$data = $request->getAll();
|
||||
|
||||
// Fixes 8750.
|
||||
foreach ($data['transactions'] as $index => $info) {
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
foreach ($transactions as $index => $info) {
|
||||
unset($data['transactions'][$index]['type']);
|
||||
}
|
||||
|
||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Transformers\PreferenceTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
@@ -84,6 +85,10 @@ class PreferencesController extends Controller
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
|
||||
if ('currencyPreference' === $preference->name) {
|
||||
throw new FireflyException('Please use api/v1/currencies/default instead.');
|
||||
}
|
||||
|
||||
/** @var PreferenceTransformer $transformer */
|
||||
$transformer = app(PreferenceTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
@@ -93,6 +98,32 @@ class PreferencesController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO This endpoint is not documented.
|
||||
*
|
||||
* Return a single preference by name.
|
||||
*/
|
||||
public function showList(Collection $collection): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
$count = $collection->count();
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$preferences = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($preferences, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.preferences.show-list').$this->buildParams());
|
||||
|
||||
/** @var PreferenceTransformer $transformer */
|
||||
$transformer = app(PreferenceTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($preferences, $transformer, self::RESOURCE_KEY);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/storePreference
|
||||
@@ -103,6 +134,11 @@ class PreferencesController extends Controller
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
$data = $request->getAll();
|
||||
|
||||
if ('currencyPreference' === $data['name']) {
|
||||
throw new FireflyException('Please use api/v1/currencies/default instead.');
|
||||
}
|
||||
|
||||
$pref = app('preferences')->set($data['name'], $data['data']);
|
||||
|
||||
/** @var PreferenceTransformer $transformer */
|
||||
@@ -122,6 +158,10 @@ class PreferencesController extends Controller
|
||||
*/
|
||||
public function update(PreferenceUpdateRequest $request, Preference $preference): JsonResponse
|
||||
{
|
||||
if ('currencyPreference' === $preference->name) {
|
||||
throw new FireflyException('Please use api/v1/currencies/default instead.');
|
||||
}
|
||||
|
||||
$manager = $this->getManager();
|
||||
$data = $request->getAll();
|
||||
$pref = app('preferences')->set($preference->name, $data['data']);
|
||||
|
@@ -71,8 +71,9 @@ class StoreRequest extends FormRequest
|
||||
if (is_array($triggers)) {
|
||||
foreach ($triggers as $trigger) {
|
||||
$return[] = [
|
||||
'type' => $trigger['type'],
|
||||
'value' => $trigger['value'],
|
||||
'type' => $trigger['type'] ?? '',
|
||||
'value' => $trigger['value'] ?? null,
|
||||
'prohibited' => $this->convertBoolean((string)($trigger['prohibited'] ?? 'false')),
|
||||
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')),
|
||||
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
|
||||
];
|
||||
|
@@ -81,10 +81,12 @@ class UpdateRequest extends FormRequest
|
||||
if (is_array($triggers)) {
|
||||
foreach ($triggers as $trigger) {
|
||||
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true;
|
||||
$prohibited = array_key_exists('prohibited', $trigger) ? $trigger['prohibited'] : false;
|
||||
$stopProcessing = array_key_exists('stop_processing', $trigger) ? $trigger['stop_processing'] : false;
|
||||
$return[] = [
|
||||
'type' => $trigger['type'],
|
||||
'value' => $trigger['value'],
|
||||
'prohibited' => $prohibited,
|
||||
'active' => $active,
|
||||
'stop_processing' => $stopProcessing,
|
||||
];
|
||||
|
@@ -55,11 +55,7 @@ class AccountController extends Controller
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->adminRepository = app(AdminAccountRepositoryInterface::class);
|
||||
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->adminRepository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->adminRepository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -85,7 +81,7 @@ class AccountController extends Controller
|
||||
$types = $data['types'];
|
||||
$query = $data['query'];
|
||||
$date = $this->parameters->get('date') ?? today(config('app.timezone'));
|
||||
$result = $this->adminRepository->searchAccount((string)$query, $types, $data['limit']);
|
||||
$result = $this->adminRepository->searchAccount((string) $query, $types, $data['limit']);
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$groupedResult = [];
|
||||
$allItems = [];
|
||||
@@ -99,19 +95,19 @@ class AccountController extends Controller
|
||||
$balance = app('steam')->balance($account, $date);
|
||||
$nameWithBalance = sprintf('%s (%s)', $account->name, app('amount')->formatAnything($currency, $balance, false));
|
||||
}
|
||||
$type = (string)trans(sprintf('firefly.%s', $account->accountType->type));
|
||||
$type = (string) trans(sprintf('firefly.%s', $account->accountType->type));
|
||||
$groupedResult[$type] ??= [
|
||||
'group ' => $type,
|
||||
'items' => [],
|
||||
];
|
||||
$allItems[] = [
|
||||
'id' => (string)$account->id,
|
||||
'value' => (string)$account->id,
|
||||
'id' => (string) $account->id,
|
||||
'value' => (string) $account->id,
|
||||
'name' => $account->name,
|
||||
'name_with_balance' => $nameWithBalance,
|
||||
'label' => $nameWithBalance,
|
||||
'type' => $account->accountType->type,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
@@ -123,8 +119,8 @@ class AccountController extends Controller
|
||||
$allItems,
|
||||
static function (array $left, array $right): int {
|
||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
||||
$posLeft = (int)array_search($left['type'], $order, true);
|
||||
$posRight = (int)array_search($right['type'], $order, true);
|
||||
$posLeft = (int) array_search($left['type'], $order, true);
|
||||
$posRight = (int) array_search($right['type'], $order, true);
|
||||
|
||||
return $posLeft - $posRight;
|
||||
}
|
||||
|
@@ -45,11 +45,7 @@ class CategoryController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -45,11 +45,7 @@ class TagController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(TagRepositoryInterface::class);
|
||||
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -45,11 +45,7 @@ class TransactionController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -55,8 +55,7 @@ class AccountController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ namespace FireflyIII\Api\V2\Controllers\Chart;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Chart\BalanceChartRequest;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
@@ -42,6 +43,7 @@ use Illuminate\Support\Collection;
|
||||
class BalanceController extends Controller
|
||||
{
|
||||
use CleansChartData;
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
|
||||
/**
|
||||
* The code is practically a duplicate of ReportController::operations.
|
||||
|
@@ -64,12 +64,9 @@ class BudgetController extends Controller
|
||||
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$this->currency = app('amount')->getDefaultCurrency();
|
||||
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
$this->opsRepository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
$this->opsRepository->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -124,11 +121,11 @@ class BudgetController extends Controller
|
||||
foreach ($rows as $row) {
|
||||
$current = [
|
||||
'label' => $budget->name,
|
||||
'currency_id' => (string)$row['currency_id'],
|
||||
'currency_id' => (string) $row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
'currency_name' => $row['currency_name'],
|
||||
'currency_decimal_places' => $row['currency_decimal_places'],
|
||||
'native_currency_id' => (string)$row['native_currency_id'],
|
||||
'native_currency_id' => (string) $row['native_currency_id'],
|
||||
'native_currency_code' => $row['native_currency_code'],
|
||||
'native_currency_name' => $row['native_currency_name'],
|
||||
'native_currency_decimal_places' => $row['native_currency_decimal_places'],
|
||||
@@ -189,12 +186,12 @@ class BudgetController extends Controller
|
||||
foreach ($array as $currencyId => $block) {
|
||||
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
|
||||
$return[$currencyId] ??= [
|
||||
'currency_id' => (string)$currencyId,
|
||||
'currency_id' => (string) $currencyId,
|
||||
'currency_code' => $block['currency_code'],
|
||||
'currency_name' => $block['currency_name'],
|
||||
'currency_symbol' => $block['currency_symbol'],
|
||||
'currency_decimal_places' => (int)$block['currency_decimal_places'],
|
||||
'native_currency_id' => (string)$this->currency->id,
|
||||
'currency_decimal_places' => (int) $block['currency_decimal_places'],
|
||||
'native_currency_id' => (string) $this->currency->id,
|
||||
'native_currency_code' => $this->currency->code,
|
||||
'native_currency_name' => $this->currency->name,
|
||||
'native_currency_symbol' => $this->currency->symbol,
|
||||
|
@@ -57,10 +57,7 @@ class CategoryController extends Controller
|
||||
function ($request, $next) {
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->accountRepos->setUserGroup($userGroup);
|
||||
}
|
||||
$this->accountRepos->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -100,25 +97,25 @@ class CategoryController extends Controller
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$categoryName = null === $journal['category_name'] ? (string)trans('firefly.no_category') : $journal['category_name'];
|
||||
$categoryName = null === $journal['category_name'] ? (string) trans('firefly.no_category') : $journal['category_name'];
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
$nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount);
|
||||
$key = sprintf('%s-%s', $categoryName, $currency->code);
|
||||
if ((int)$journal['foreign_currency_id'] === $default->id) {
|
||||
if ((int) $journal['foreign_currency_id'] === $default->id) {
|
||||
$nativeAmount = app('steam')->positive($journal['foreign_amount']);
|
||||
}
|
||||
// create arrays
|
||||
$return[$key] ??= [
|
||||
'label' => $categoryName,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'native_currency_id' => (string)$default->id,
|
||||
'native_currency_id' => (string) $default->id,
|
||||
'native_currency_code' => $default->code,
|
||||
'native_currency_name' => $default->name,
|
||||
'native_currency_symbol' => $default->symbol,
|
||||
@@ -138,7 +135,7 @@ class CategoryController extends Controller
|
||||
|
||||
// order by native amount
|
||||
usort($return, static function (array $a, array $b) {
|
||||
return (float)$a['native_amount'] < (float)$b['native_amount'] ? 1 : -1;
|
||||
return (float) $a['native_amount'] < (float) $b['native_amount'] ? 1 : -1;
|
||||
});
|
||||
$converter->summarize();
|
||||
|
||||
|
@@ -122,6 +122,9 @@ class Controller extends BaseController
|
||||
$obj = null;
|
||||
}
|
||||
}
|
||||
if (null !== $date && 'end' === $field) {
|
||||
$obj->endOfDay();
|
||||
}
|
||||
$bag->set($field, $obj);
|
||||
}
|
||||
|
||||
@@ -154,6 +157,9 @@ class Controller extends BaseController
|
||||
{
|
||||
$manager = new Manager();
|
||||
$baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
|
||||
|
||||
// TODO add stuff to path?
|
||||
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$objects = $paginator->getCollection();
|
||||
|
@@ -25,12 +25,12 @@ namespace FireflyIII\Api\V2\Controllers\Model\Account;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\Account\IndexRequest;
|
||||
use FireflyIII\Api\V2\Request\Model\Transaction\InfiniteListRequest;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
@@ -58,21 +58,35 @@ class IndexController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO see autocomplete/accountcontroller for list.
|
||||
* TODO the sort instructions need proper repeatable documentation.
|
||||
* TODO see autocomplete/account controller for list.
|
||||
*/
|
||||
public function index(IndexRequest $request): JsonResponse
|
||||
{
|
||||
$this->repository->resetAccountOrder();
|
||||
$types = $request->getAccountTypes();
|
||||
$instructions = $request->getSortInstructions('accounts');
|
||||
$accounts = $this->repository->getAccountsByType($types, $instructions);
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $accounts->count();
|
||||
$accounts = $accounts->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new AccountTransformer();
|
||||
$types = $request->getAccountTypes();
|
||||
$sorting = $request->getSortInstructions('accounts');
|
||||
$filters = $request->getFilterInstructions('accounts');
|
||||
$accounts = $this->repository->getAccountsByType($types, $sorting, $filters);
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $accounts->count();
|
||||
|
||||
$this->parameters->set('sort', $instructions);
|
||||
// depending on the sort parameters, this list must not be split, because the
|
||||
// order is calculated in the account transformer and by that time it's too late.
|
||||
$first = array_key_first($sorting);
|
||||
$disablePagination = in_array($first, ['last_activity', 'balance', 'balance_difference'], true);
|
||||
Log::debug(sprintf('Will disable pagination in account index v2? %s', var_export($disablePagination, true)));
|
||||
if (!$disablePagination) {
|
||||
$accounts = $accounts->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
}
|
||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new AccountTransformer();
|
||||
|
||||
$this->parameters->set('disablePagination', $disablePagination);
|
||||
$this->parameters->set('pageSize', $pageSize);
|
||||
$this->parameters->set('sort', $sorting);
|
||||
|
||||
$this->parameters->set('filters', $filters);
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
@@ -80,25 +94,4 @@ class IndexController extends Controller
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
|
||||
public function infiniteList(InfiniteListRequest $request): JsonResponse
|
||||
{
|
||||
$this->repository->resetAccountOrder();
|
||||
|
||||
// get accounts of the specified type, and return.
|
||||
$types = $request->getAccountTypes();
|
||||
|
||||
// get from repository
|
||||
$accounts = $this->repository->getAccountsInOrder($types, $request->getSortInstructions('accounts'), $request->getStartRow(), $request->getEndRow());
|
||||
$total = $this->repository->countAccounts($types);
|
||||
$count = $request->getEndRow() - $request->getStartRow();
|
||||
$paginator = new LengthAwarePaginator($accounts, $total, $count, $this->parameters->get('page'));
|
||||
$transformer = new AccountTransformer();
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@@ -45,11 +45,7 @@ class UpdateController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -46,12 +46,7 @@ class IndexController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -46,12 +46,7 @@ class ShowController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -45,11 +45,7 @@ class SumController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -46,11 +46,7 @@ class IndexController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->repository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -52,10 +52,8 @@ class NetWorthController extends Controller
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
if (null !== $userGroup) {
|
||||
$this->netWorth->setUserGroup($userGroup);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
}
|
||||
$this->netWorth->setUserGroup($userGroup);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Chart;
|
||||
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
@@ -39,6 +40,7 @@ class BalanceChartRequest extends FormRequest
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
use ValidatesUserGroupTrait;
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
|
@@ -27,6 +27,7 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\Support\Request\GetFilterInstructions;
|
||||
use FireflyIII\Support\Request\GetSortInstructions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
@@ -40,18 +41,16 @@ class IndexRequest extends FormRequest
|
||||
use AccountFilter;
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
use GetFilterInstructions;
|
||||
use GetSortInstructions;
|
||||
|
||||
public function getAccountTypes(): array
|
||||
{
|
||||
$type = (string)$this->get('type', 'default');
|
||||
$type = (string) $this->get('type', 'default');
|
||||
|
||||
return $this->mapAccountTypes($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*/
|
||||
public function getDate(): Carbon
|
||||
{
|
||||
return $this->getCarbonDate('date');
|
||||
@@ -63,7 +62,9 @@ class IndexRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31|before:end|required_with:end',
|
||||
'end' => 'date|after:1900-01-01|before:2099-12-31|after:start|required_with:start',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -80,7 +80,7 @@ class CreateGroupMemberships extends Command
|
||||
// check if membership exists
|
||||
$userGroup = UserGroup::where('title', $user->email)->first();
|
||||
if (null === $userGroup) {
|
||||
$userGroup = UserGroup::create(['title' => $user->email, 'default_administration' => true]);
|
||||
$userGroup = UserGroup::create(['title' => $user->email]);
|
||||
}
|
||||
|
||||
$userRole = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
|
||||
|
@@ -106,7 +106,7 @@ class ShowController extends Controller
|
||||
$periods = $this->getAccountPeriodOverview($account, $firstTransaction, $end);
|
||||
|
||||
// if layout = v2, overrule the page title.
|
||||
if ('v1' !== config('firefly.layout')) {
|
||||
if ('v1' !== config('view.layout')) {
|
||||
$subTitle = (string)trans('firefly.all_journals_for_account', ['name' => $account->name]);
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,7 @@ use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
@@ -106,6 +107,8 @@ class ForgotPasswordController extends Controller
|
||||
}
|
||||
$host = request()->host();
|
||||
if ($configuredHost !== $host) {
|
||||
Log::error(sprintf('Host header is "%s", APP_URL is "%s".', $host, $configuredHost));
|
||||
|
||||
throw new FireflyException('The Host-header does not match the host in the APP_URL environment variable. Please make sure these match. See also: https://bit.ly/FF3-host-header');
|
||||
}
|
||||
}
|
||||
|
@@ -70,7 +70,7 @@ abstract class Controller extends BaseController
|
||||
$logoutUrl = config('firefly.custom_logout_url');
|
||||
|
||||
// overrule v2 layout back to v1.
|
||||
if ('true' === request()->get('force_default_layout') && 'v2' === config('firefly.layout')) {
|
||||
if ('true' === request()->get('force_default_layout') && 'v2' === config('view.layout')) {
|
||||
app('view')->getFinder()->setPaths([realpath(base_path('resources/views'))]); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
|
@@ -151,8 +151,9 @@ class HomeController extends Controller
|
||||
}
|
||||
|
||||
/** @var Carbon $start */
|
||||
/** @var Carbon $end */
|
||||
$start = session('start', today(config('app.timezone'))->startOfMonth());
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', today(config('app.timezone'))->endOfMonth());
|
||||
$accounts = $repository->getAccountsById($frontpageArray);
|
||||
$today = today(config('app.timezone'));
|
||||
|
@@ -25,6 +25,7 @@ namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Vite;
|
||||
use Barryvdh\Debugbar\Facades\Debugbar;
|
||||
|
||||
/**
|
||||
* Class SecureHeaders
|
||||
@@ -43,6 +44,9 @@ class SecureHeaders
|
||||
// generate and share nonce.
|
||||
$nonce = base64_encode(random_bytes(16));
|
||||
Vite::useCspNonce($nonce);
|
||||
if (class_exists('Barryvdh\Debugbar\Facades\Debugbar')) {
|
||||
Debugbar::getJavascriptRenderer()->setCspNonce($nonce);
|
||||
}
|
||||
app('view')->share('JS_NONCE', $nonce);
|
||||
|
||||
$response = $next($request);
|
||||
@@ -55,14 +59,29 @@ class SecureHeaders
|
||||
"base-uri 'self'",
|
||||
"font-src 'self' data:",
|
||||
sprintf("connect-src 'self' %s", $trackingScriptSrc),
|
||||
sprintf("img-src 'self' 'nonce-%1s'", $nonce),
|
||||
sprintf("img-src 'self' data: 'nonce-%1s' ", $nonce),
|
||||
"manifest-src 'self'",
|
||||
];
|
||||
|
||||
// overrule in development mode
|
||||
if (true === env('IS_LOCAL_DEV')) {
|
||||
$csp = [
|
||||
"default-src 'none'",
|
||||
"object-src 'none'",
|
||||
sprintf("script-src 'unsafe-eval' 'strict-dynamic' 'nonce-%1s' https://firefly.sd.internal/_debugbar/assets", $nonce),
|
||||
"style-src 'unsafe-inline' 'self' https://10.0.0.15:5173/",
|
||||
"base-uri 'self'",
|
||||
"font-src 'self' data: https://10.0.0.15:5173/",
|
||||
sprintf("connect-src 'self' %s https://10.0.0.15:5173/ wss://10.0.0.15:5173/", $trackingScriptSrc),
|
||||
sprintf("img-src 'self' data: 'nonce-%1s'", $nonce),
|
||||
"manifest-src 'self'",
|
||||
];
|
||||
}
|
||||
|
||||
$route = $request->route();
|
||||
$customUrl = '';
|
||||
$authGuard = (string)config('firefly.authentication_guard');
|
||||
$logoutUrl = (string)config('firefly.custom_logout_url');
|
||||
$authGuard = (string) config('firefly.authentication_guard');
|
||||
$logoutUrl = (string) config('firefly.custom_logout_url');
|
||||
if ('remote_user_guard' === $authGuard && '' !== $logoutUrl) {
|
||||
$customUrl = $logoutUrl;
|
||||
}
|
||||
@@ -110,8 +129,8 @@ class SecureHeaders
|
||||
*/
|
||||
private function getTrackingScriptSource(): string
|
||||
{
|
||||
if ('' !== (string)config('firefly.tracker_site_id') && '' !== (string)config('firefly.tracker_url')) {
|
||||
return (string)config('firefly.tracker_url');
|
||||
if ('' !== (string) config('firefly.tracker_site_id') && '' !== (string) config('firefly.tracker_url')) {
|
||||
return (string) config('firefly.tracker_url');
|
||||
}
|
||||
|
||||
return '';
|
||||
|
@@ -29,6 +29,7 @@ use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Illuminate\Bus\Queueable;
|
||||
@@ -100,7 +101,7 @@ class DownloadExchangeRates implements ShouldQueue
|
||||
|
||||
try {
|
||||
$res = $client->get($url);
|
||||
} catch (RequestException $e) {
|
||||
} catch (ConnectException|RequestException $e) {
|
||||
app('log')->warning(sprintf('Trying to grab "%s" resulted in error "%d".', $url, $e->getMessage()));
|
||||
|
||||
return;
|
||||
|
@@ -130,12 +130,12 @@ class MailError extends Job implements ShouldQueue
|
||||
}
|
||||
if (file_exists($file)) {
|
||||
Log::debug(sprintf('Read file in "%s"', $file));
|
||||
$limits = json_decode(file_get_contents($file), true);
|
||||
$limits = json_decode((string)file_get_contents($file), true);
|
||||
}
|
||||
// limit reached?
|
||||
foreach ($types as $type => $info) {
|
||||
Log::debug(sprintf('Now checking limit "%s"', $type), $info);
|
||||
if (!isset($limits[$type])) {
|
||||
if (!array_key_exists($type, $limits)) {
|
||||
Log::debug(sprintf('Limit "%s" reset to zero, did not exist yet.', $type));
|
||||
$limits[$type] = [
|
||||
'time' => time(),
|
||||
|
@@ -98,7 +98,7 @@ class UserGroup extends Model
|
||||
{
|
||||
use ReturnsIntegerIdTrait;
|
||||
|
||||
protected $fillable = ['title', 'default_administration'];
|
||||
protected $fillable = ['title'];
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
|
@@ -295,4 +295,16 @@ class UserGroupRepository implements UserGroupRepositoryInterface
|
||||
$this->user->user_group_id = $userGroup->id;
|
||||
$this->user->save();
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getMembershipsFromGroupId(int $groupId): Collection
|
||||
{
|
||||
return $this->user->groupMemberships()->where('user_group_id', $groupId)->get();
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getById(int $id): ?UserGroup
|
||||
{
|
||||
return UserGroup::find($id);
|
||||
}
|
||||
}
|
||||
|
@@ -36,8 +36,12 @@ interface UserGroupRepositoryInterface
|
||||
{
|
||||
public function destroy(UserGroup $userGroup): void;
|
||||
|
||||
public function getMembershipsFromGroupId(int $groupId): Collection;
|
||||
|
||||
public function get(): Collection;
|
||||
|
||||
public function getById(int $id): ?UserGroup;
|
||||
|
||||
public function getAll(): Collection;
|
||||
|
||||
public function setUser(null|Authenticatable|User $user): void;
|
||||
|
@@ -27,11 +27,14 @@ namespace FireflyIII\Repositories\UserGroups\Account;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Services\Internal\Update\AccountUpdateService;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* Class AccountRepository
|
||||
@@ -121,7 +124,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
if (!in_array($type, $list, true)) {
|
||||
return null;
|
||||
}
|
||||
$currencyId = (int)$this->getMetaValue($account, 'currency_id');
|
||||
$currencyId = (int) $this->getMetaValue($account, 'currency_id');
|
||||
if ($currencyId > 0) {
|
||||
return TransactionCurrency::find($currencyId);
|
||||
}
|
||||
@@ -143,7 +146,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
return null;
|
||||
}
|
||||
if (1 === $result->count()) {
|
||||
return (string)$result->first()->data;
|
||||
return (string) $result->first()->data;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -228,7 +231,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($index !== (int)$account->order) {
|
||||
if ($index !== (int) $account->order) {
|
||||
app('log')->debug(sprintf('Account #%d ("%s"): order should %d be but is %d.', $account->id, $account->name, $index, $account->order));
|
||||
$account->order = $index;
|
||||
$account->save();
|
||||
@@ -238,7 +241,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
}
|
||||
}
|
||||
|
||||
public function getAccountsByType(array $types, ?array $sort = []): Collection
|
||||
public function getAccountsByType(array $types, ?array $sort = [], ?array $filters = []): Collection
|
||||
{
|
||||
$sortable = ['name', 'active']; // TODO yes this is a duplicate array.
|
||||
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
|
||||
@@ -247,6 +250,22 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
|
||||
// process filters
|
||||
// TODO this should be repeatable, it feels like a hack when you do it here.
|
||||
// TODO some fields cannot be filtered using the query, and a second filter must be applied on the collection.
|
||||
foreach ($filters as $column => $value) {
|
||||
// filter on NULL values
|
||||
if (null === $value) {
|
||||
continue;
|
||||
}
|
||||
if ('active' === $column) {
|
||||
$query->where('accounts.active', $value);
|
||||
}
|
||||
if ('name' === $column) {
|
||||
$query->where('accounts.name', 'LIKE', sprintf('%%%s%%', $value));
|
||||
}
|
||||
}
|
||||
|
||||
// add sort parameters. At this point they're filtered to allowed fields to sort by:
|
||||
$hasActiveColumn = array_key_exists('active', $sort);
|
||||
if (count($sort) > 0) {
|
||||
@@ -305,4 +324,64 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
return $service->update($account, $data);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getMetaValues(Collection $accounts, array $fields): Collection
|
||||
{
|
||||
$query = AccountMeta::whereIn('account_id', $accounts->pluck('id')->toArray());
|
||||
if (count($fields) > 0) {
|
||||
$query->whereIn('name', $fields);
|
||||
}
|
||||
|
||||
return $query->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data']);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getAccountTypes(Collection $accounts): Collection
|
||||
{
|
||||
return AccountType::leftJoin('accounts', 'accounts.account_type_id', '=', 'account_types.id')
|
||||
->whereIn('accounts.id', $accounts->pluck('id')->toArray())
|
||||
->get(['accounts.id', 'account_types.type'])
|
||||
;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getLastActivity(Collection $accounts): array
|
||||
{
|
||||
return Transaction::whereIn('account_id', $accounts->pluck('id')->toArray())
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->groupBy('transactions.account_id')
|
||||
->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) as date_max')])->toArray() // @phpstan-ignore-line
|
||||
;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getObjectGroups(Collection $accounts): array
|
||||
{
|
||||
$groupIds = [];
|
||||
$return = [];
|
||||
$set = DB::table('object_groupables')->where('object_groupable_type', Account::class)
|
||||
->whereIn('object_groupable_id', $accounts->pluck('id')->toArray())->get()
|
||||
;
|
||||
|
||||
/** @var \stdClass $row */
|
||||
foreach ($set as $row) {
|
||||
$groupIds[] = $row->object_group_id;
|
||||
}
|
||||
$groupIds = array_unique($groupIds);
|
||||
$groups = ObjectGroup::whereIn('id', $groupIds)->get();
|
||||
|
||||
/** @var \stdClass $row */
|
||||
foreach ($set as $row) {
|
||||
if (!array_key_exists($row->object_groupable_id, $return)) {
|
||||
/** @var null|ObjectGroup $group */
|
||||
$group = $groups->firstWhere('id', '=', $row->object_group_id);
|
||||
if (null !== $group) {
|
||||
$return[$row->object_groupable_id] = ['title' => $group->title, 'order' => $group->order, 'id' => $group->id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
@@ -37,6 +37,12 @@ interface AccountRepositoryInterface
|
||||
{
|
||||
public function countAccounts(array $types): int;
|
||||
|
||||
public function getAccountTypes(Collection $accounts): Collection;
|
||||
|
||||
public function getLastActivity(Collection $accounts): array;
|
||||
|
||||
public function getMetaValues(Collection $accounts, array $fields): Collection;
|
||||
|
||||
public function find(int $accountId): ?Account;
|
||||
|
||||
public function findByAccountNumber(string $number, array $types): ?Account;
|
||||
@@ -49,7 +55,7 @@ interface AccountRepositoryInterface
|
||||
|
||||
public function getAccountsById(array $accountIds): Collection;
|
||||
|
||||
public function getAccountsByType(array $types, ?array $sort = []): Collection;
|
||||
public function getAccountsByType(array $types, ?array $sort = [], ?array $filters = []): Collection;
|
||||
|
||||
/**
|
||||
* Used in the infinite accounts list.
|
||||
@@ -63,6 +69,8 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
public function getMetaValue(Account $account, string $field): ?string;
|
||||
|
||||
public function getObjectGroups(Collection $accounts): array;
|
||||
|
||||
public function getUserGroup(): UserGroup;
|
||||
|
||||
/**
|
||||
|
@@ -80,9 +80,10 @@ class RemoteUserProvider implements UserProvider
|
||||
$roleObject = Role::where('name', 'owner')->first();
|
||||
$user->roles()->attach($roleObject);
|
||||
}
|
||||
// make sure the user gets an administration as well.
|
||||
CreateGroupMemberships::createGroupMembership($user);
|
||||
}
|
||||
// make sure the user gets an administration as well.
|
||||
CreateGroupMemberships::createGroupMembership($user);
|
||||
|
||||
app('log')->debug(sprintf('Going to return user #%d (%s)', $user->id, $user->email));
|
||||
|
||||
return $user;
|
||||
|
@@ -24,12 +24,13 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Support\Http\Api;
|
||||
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Models\GroupMembership;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Trait ValidatesUserGroupTrait
|
||||
@@ -42,63 +43,64 @@ trait ValidatesUserGroupTrait
|
||||
*/
|
||||
protected function validateUserGroup(Request $request): UserGroup
|
||||
{
|
||||
app('log')->debug(sprintf('validateUserGroup: %s', static::class));
|
||||
Log::debug(sprintf('validateUserGroup: %s', static::class));
|
||||
if (!auth()->check()) {
|
||||
app('log')->debug('validateUserGroup: user is not logged in, return NULL.');
|
||||
Log::debug('validateUserGroup: user is not logged in, return NULL.');
|
||||
|
||||
throw new AuthenticationException();
|
||||
}
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$groupId = 0;
|
||||
$user = auth()->user();
|
||||
$groupId = 0;
|
||||
if (!$request->has('user_group_id')) {
|
||||
$groupId = $user->user_group_id;
|
||||
app('log')->debug(sprintf('validateUserGroup: no user group submitted, use default group #%d.', $groupId));
|
||||
Log::debug(sprintf('validateUserGroup: no user group submitted, use default group #%d.', $groupId));
|
||||
}
|
||||
if ($request->has('user_group_id')) {
|
||||
$groupId = (int)$request->get('user_group_id');
|
||||
app('log')->debug(sprintf('validateUserGroup: user group submitted, search for memberships in group #%d.', $groupId));
|
||||
$groupId = (int) $request->get('user_group_id');
|
||||
Log::debug(sprintf('validateUserGroup: user group submitted, search for memberships in group #%d.', $groupId));
|
||||
}
|
||||
|
||||
/** @var null|GroupMembership $membership */
|
||||
$membership = $user->groupMemberships()->where('user_group_id', $groupId)->first();
|
||||
/** @var UserGroupRepositoryInterface $repository */
|
||||
$repository = app(UserGroupRepositoryInterface::class);
|
||||
$repository->setUser($user);
|
||||
$memberships = $repository->getMembershipsFromGroupId($groupId);
|
||||
|
||||
if (null === $membership) {
|
||||
app('log')->debug(sprintf('validateUserGroup: user has no access to group #%d.', $groupId));
|
||||
if (0 === $memberships->count()) {
|
||||
Log::debug(sprintf('validateUserGroup: user has no access to group #%d.', $groupId));
|
||||
|
||||
throw new AuthorizationException((string)trans('validation.no_access_group'));
|
||||
throw new AuthorizationException((string) trans('validation.no_access_group'));
|
||||
}
|
||||
|
||||
// need to get the group from the membership:
|
||||
/** @var null|UserGroup $group */
|
||||
$group = $membership->userGroup;
|
||||
$group = $repository->getById($groupId);
|
||||
if (null === $group) {
|
||||
app('log')->debug(sprintf('validateUserGroup: group #%d does not exist.', $groupId));
|
||||
Log::debug(sprintf('validateUserGroup: group #%d does not exist.', $groupId));
|
||||
|
||||
throw new AuthorizationException((string)trans('validation.belongs_user_or_user_group'));
|
||||
throw new AuthorizationException((string) trans('validation.belongs_user_or_user_group'));
|
||||
}
|
||||
app('log')->debug(sprintf('validateUserGroup: validate access of user to group #%d ("%s").', $groupId, $group->title));
|
||||
$roles = property_exists($this, 'acceptedRoles') ? $this->acceptedRoles : [];
|
||||
Log::debug(sprintf('validateUserGroup: validate access of user to group #%d ("%s").', $groupId, $group->title));
|
||||
$roles = property_exists($this, 'acceptedRoles') ? $this->acceptedRoles : []; // @phpstan-ignore-line
|
||||
if (0 === count($roles)) {
|
||||
app('log')->debug('validateUserGroup: no roles defined, so no access.');
|
||||
Log::debug('validateUserGroup: no roles defined, so no access.');
|
||||
|
||||
throw new AuthorizationException((string)trans('validation.no_accepted_roles_defined'));
|
||||
throw new AuthorizationException((string) trans('validation.no_accepted_roles_defined'));
|
||||
}
|
||||
app('log')->debug(sprintf('validateUserGroup: have %d roles to check.', count($roles)), $roles);
|
||||
Log::debug(sprintf('validateUserGroup: have %d roles to check.', count($roles)), $roles);
|
||||
|
||||
/** @var UserRoleEnum $role */
|
||||
foreach ($roles as $role) {
|
||||
if ($user->hasRoleInGroupOrOwner($group, $role)) {
|
||||
app('log')->debug(sprintf('validateUserGroup: User has role "%s" in group #%d, return the group.', $role->value, $groupId));
|
||||
Log::debug(sprintf('validateUserGroup: User has role "%s" in group #%d, return the group.', $role->value, $groupId));
|
||||
|
||||
return $group;
|
||||
}
|
||||
app('log')->debug(sprintf('validateUserGroup: User does NOT have role "%s" in group #%d, continue searching.', $role->value, $groupId));
|
||||
Log::debug(sprintf('validateUserGroup: User does NOT have role "%s" in group #%d, continue searching.', $role->value, $groupId));
|
||||
}
|
||||
|
||||
app('log')->debug('validateUserGroup: User does NOT have enough rights to access endpoint.');
|
||||
Log::debug('validateUserGroup: User does NOT have enough rights to access endpoint.');
|
||||
|
||||
throw new AuthorizationException((string)trans('validation.belongs_user_or_user_group'));
|
||||
throw new AuthorizationException((string) trans('validation.belongs_user_or_user_group'));
|
||||
}
|
||||
}
|
||||
|
@@ -464,14 +464,15 @@ class Navigation
|
||||
$increment = 'addDay';
|
||||
$format = $this->preferredCarbonFormat($start, $end);
|
||||
$displayFormat = (string)trans('config.month_and_day_js', [], $locale);
|
||||
$diff = $start->diffInMonths($end, true);
|
||||
// increment by month (for year)
|
||||
if ($start->diffInMonths($end, true) > 1) {
|
||||
if ($diff >= 1.0001) {
|
||||
$increment = 'addMonth';
|
||||
$displayFormat = (string)trans('config.month_js');
|
||||
}
|
||||
|
||||
// increment by year (for multi-year)
|
||||
if ($start->diffInMonths($end, true) > 12) {
|
||||
if ($diff >= 12.0001) {
|
||||
$increment = 'addYear';
|
||||
$displayFormat = (string)trans('config.year_js');
|
||||
}
|
||||
@@ -494,11 +495,15 @@ class Navigation
|
||||
public function preferredCarbonFormat(Carbon $start, Carbon $end): string
|
||||
{
|
||||
$format = 'Y-m-d';
|
||||
if ((int)$start->diffInMonths($end, true) > 1) {
|
||||
$diff = $start->diffInMonths($end, true);
|
||||
Log::debug(sprintf('preferredCarbonFormat(%s, %s) = %f', $start->format('Y-m-d'), $end->format('Y-m-d'), $diff));
|
||||
if ($diff >= 1.001) {
|
||||
Log::debug(sprintf('Return Y-m because %s', $diff));
|
||||
$format = 'Y-m';
|
||||
}
|
||||
|
||||
if ((int)$start->diffInMonths($end, true) > 12) {
|
||||
if ($diff >= 12.001) {
|
||||
Log::debug(sprintf('Return Y because %s', $diff));
|
||||
$format = 'Y';
|
||||
}
|
||||
|
||||
|
@@ -44,6 +44,7 @@ class Preferences
|
||||
}
|
||||
|
||||
return Preference::where('user_id', $user->id)
|
||||
->where('name', '!=', 'currencyPreference')
|
||||
->where(function (Builder $q) use ($user): void {
|
||||
$q->whereNull('user_group_id');
|
||||
$q->orWhere('user_group_id', $user->user_group_id);
|
||||
|
@@ -159,9 +159,7 @@ trait ConvertsDataTypes
|
||||
|
||||
if (method_exists($this, 'validateUserGroup')) { // @phpstan-ignore-line
|
||||
$userGroup = $this->validateUserGroup($this);
|
||||
if (null !== $userGroup) {
|
||||
$repository->setUserGroup($userGroup);
|
||||
}
|
||||
$repository->setUserGroup($userGroup);
|
||||
}
|
||||
|
||||
// set administration ID
|
||||
|
77
app/Support/Request/GetFilterInstructions.php
Normal file
77
app/Support/Request/GetFilterInstructions.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/*
|
||||
* GetFilterInstructions.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\Support\Request;
|
||||
|
||||
trait GetFilterInstructions
|
||||
{
|
||||
private const string INVALID_FILTER = '%INVALID_JAMES_%';
|
||||
|
||||
final public function getFilterInstructions(string $key): array
|
||||
{
|
||||
$config = config(sprintf('firefly.filters.allowed.%s', $key));
|
||||
$allowed = array_keys($config);
|
||||
$set = $this->get('filters', []);
|
||||
$result = [];
|
||||
if (0 === count($set)) {
|
||||
return [];
|
||||
}
|
||||
foreach ($set as $info) {
|
||||
$column = $info['column'] ?? 'NOPE';
|
||||
$filterValue = (string) ($info['filter'] ?? self::INVALID_FILTER);
|
||||
if (false === in_array($column, $allowed, true)) {
|
||||
// skip invalid column
|
||||
continue;
|
||||
}
|
||||
$filterType = $config[$column] ?? false;
|
||||
|
||||
switch ($filterType) {
|
||||
default:
|
||||
exit(sprintf('Do not support filter type "%s"', $filterType));
|
||||
|
||||
case 'boolean':
|
||||
$filterValue = $this->booleanInstruction($filterValue);
|
||||
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
break;
|
||||
}
|
||||
$result[$column] = $filterValue;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function booleanInstruction(string $filterValue): ?bool
|
||||
{
|
||||
if ('true' === $filterValue) {
|
||||
return true;
|
||||
}
|
||||
if ('false' === $filterValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -159,6 +159,10 @@ class OperatorQuerySearch implements SearchInterface
|
||||
foreach ($query1->getNodes() as $searchNode) {
|
||||
$this->handleSearchNode($searchNode);
|
||||
}
|
||||
|
||||
// add missing information
|
||||
$this->collector->withBillInformation();
|
||||
|
||||
$this->collector->setSearchWords($this->words);
|
||||
$this->collector->excludeSearchWords($this->prohibitedWords);
|
||||
}
|
||||
|
@@ -49,6 +49,7 @@ class Translation extends AbstractExtension
|
||||
{
|
||||
return [
|
||||
$this->journalLinkTranslation(),
|
||||
$this->laravelTranslation(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -68,4 +69,19 @@ class Translation extends AbstractExtension
|
||||
['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
public function laravelTranslation(): TwigFunction
|
||||
{
|
||||
return new TwigFunction(
|
||||
'__',
|
||||
static function (string $key) {
|
||||
$translation = trans($key);
|
||||
if ($key === $translation) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
return $translation;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -34,8 +34,7 @@ use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
*/
|
||||
class RuleTransformer extends AbstractTransformer
|
||||
{
|
||||
/** @var RuleRepositoryInterface */
|
||||
private $ruleRepository;
|
||||
private RuleRepositoryInterface $ruleRepository;
|
||||
|
||||
/**
|
||||
* CurrencyTransformer constructor.
|
||||
@@ -109,8 +108,16 @@ class RuleTransformer extends AbstractTransformer
|
||||
if ('user_action' === $ruleTrigger->trigger_type) {
|
||||
continue;
|
||||
}
|
||||
$triggerType = (string) $ruleTrigger->trigger_type;
|
||||
$triggerValue = (string)$ruleTrigger->trigger_value;
|
||||
$needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type), true);
|
||||
$prohibited = false;
|
||||
|
||||
if (str_starts_with($triggerType, '-')) {
|
||||
$prohibited = true;
|
||||
$triggerType = substr($triggerType, 1);
|
||||
}
|
||||
|
||||
$needsContext = config(sprintf('search.operators.%s.needs_context', $triggerType), true);
|
||||
if (false === $needsContext) {
|
||||
$triggerValue = 'true';
|
||||
}
|
||||
@@ -119,8 +126,9 @@ class RuleTransformer extends AbstractTransformer
|
||||
'id' => (string)$ruleTrigger->id,
|
||||
'created_at' => $ruleTrigger->created_at->toAtomString(),
|
||||
'updated_at' => $ruleTrigger->updated_at->toAtomString(),
|
||||
'type' => $ruleTrigger->trigger_type,
|
||||
'type' => $triggerType,
|
||||
'value' => $triggerValue,
|
||||
'prohibited' => $prohibited,
|
||||
'order' => $ruleTrigger->order,
|
||||
'active' => $ruleTrigger->active,
|
||||
'stop_processing' => $ruleTrigger->stop_processing,
|
||||
|
@@ -27,13 +27,12 @@ namespace FireflyIII\Transformers\V2;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class AccountTransformer
|
||||
@@ -42,117 +41,64 @@ class AccountTransformer extends AbstractTransformer
|
||||
{
|
||||
private array $accountMeta;
|
||||
private array $accountTypes;
|
||||
private array $balances;
|
||||
private array $fullTypes;
|
||||
private array $balanceDifferences;
|
||||
private array $convertedBalances;
|
||||
private array $currencies;
|
||||
private TransactionCurrency $default;
|
||||
private array $lastActivity;
|
||||
private array $objectGroups;
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
* This method collects meta-data for one or all accounts in the transformer's collection.
|
||||
*/
|
||||
public function collectMetaData(Collection $objects): Collection
|
||||
{
|
||||
// TODO separate methods
|
||||
$this->currencies = [];
|
||||
$this->accountMeta = [];
|
||||
$this->accountTypes = [];
|
||||
$this->lastActivity = [];
|
||||
$this->balances = app('steam')->balancesByAccounts($objects, $this->getDate());
|
||||
$this->convertedBalances = app('steam')->balancesByAccountsConverted($objects, $this->getDate());
|
||||
$this->currencies = [];
|
||||
$this->accountMeta = [];
|
||||
$this->accountTypes = [];
|
||||
$this->fullTypes = [];
|
||||
$this->lastActivity = [];
|
||||
$this->objectGroups = [];
|
||||
$this->convertedBalances = [];
|
||||
$this->balanceDifferences = [];
|
||||
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->default = app('amount')->getDefaultCurrency();
|
||||
Log::debug(sprintf('collectMetaData on %d object(s)', $objects->count()));
|
||||
|
||||
// get currencies:
|
||||
$accountIds = $objects->pluck('id')->toArray();
|
||||
// TODO move query to repository
|
||||
$meta = AccountMeta::whereIn('account_id', $accountIds)
|
||||
->whereIn('name', ['currency_id', 'account_role', 'account_number'])
|
||||
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])
|
||||
;
|
||||
$currencyIds = $meta->where('name', 'currency_id')->pluck('data')->toArray();
|
||||
// first collect all the "heavy" stuff that relies on ALL data to be present.
|
||||
// get last activity:
|
||||
$this->getLastActivity($objects);
|
||||
|
||||
// get balances of all accounts
|
||||
$this->getMetaBalances($objects);
|
||||
|
||||
// get default currency:
|
||||
$this->getDefaultCurrency();
|
||||
|
||||
// collect currency and other meta-data:
|
||||
$this->collectAccountMetaData($objects);
|
||||
|
||||
$currencies = $repository->getByIds($currencyIds);
|
||||
foreach ($currencies as $currency) {
|
||||
$id = $currency->id;
|
||||
$this->currencies[$id] = $currency;
|
||||
}
|
||||
foreach ($meta as $entry) {
|
||||
$id = $entry->account_id;
|
||||
$this->accountMeta[$id][$entry->name] = $entry->data;
|
||||
}
|
||||
// get account types:
|
||||
// select accounts.id, account_types.type from account_types left join accounts on accounts.account_type_id = account_types.id;
|
||||
// TODO move query to repository
|
||||
$accountTypes = AccountType::leftJoin('accounts', 'accounts.account_type_id', '=', 'account_types.id')
|
||||
->whereIn('accounts.id', $accountIds)
|
||||
->get(['accounts.id', 'account_types.type'])
|
||||
;
|
||||
$this->collectAccountTypes($objects);
|
||||
|
||||
/** @var AccountType $row */
|
||||
foreach ($accountTypes as $row) {
|
||||
$this->accountTypes[$row->id] = (string)config(sprintf('firefly.shortNamesByFullName.%s', $row->type));
|
||||
// add balance difference
|
||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
||||
$this->getBalanceDifference($objects, $this->parameters->get('start'), $this->parameters->get('end'));
|
||||
}
|
||||
|
||||
// get last activity
|
||||
// TODO move query to repository
|
||||
$array = Transaction::whereIn('account_id', $accountIds)
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
|
||||
->groupBy('transactions.account_id')
|
||||
->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) as date_max')])->toArray() // @phpstan-ignore-line
|
||||
;
|
||||
foreach ($array as $row) {
|
||||
$this->lastActivity[(int)$row['account_id']] = Carbon::parse($row['date_max'], config('app.timezone'));
|
||||
// get object groups
|
||||
$this->getObjectGroups($objects);
|
||||
|
||||
// sort:
|
||||
$objects = $this->sortAccounts($objects);
|
||||
|
||||
// if pagination is disabled, do it now:
|
||||
if (true === $this->parameters->get('disablePagination')) {
|
||||
$page = (int) $this->parameters->get('page');
|
||||
$size = (int) $this->parameters->get('pageSize');
|
||||
$objects = $objects->slice(($page - 1) * $size, $size);
|
||||
}
|
||||
|
||||
// TODO needs separate method.
|
||||
/** @var null|array $sort */
|
||||
$sort = $this->parameters->get('sort');
|
||||
if (null !== $sort && count($sort) > 0) {
|
||||
foreach ($sort as $column => $direction) {
|
||||
// account_number + iban
|
||||
if ('iban' === $column) {
|
||||
$meta = $this->accountMeta;
|
||||
$objects = $objects->sort(function (Account $left, Account $right) use ($meta, $direction) {
|
||||
$leftIban = trim(sprintf('%s%s', $left->iban, $meta[$left->id]['account_number'] ?? ''));
|
||||
$rightIban = trim(sprintf('%s%s', $right->iban, $meta[$right->id]['account_number'] ?? ''));
|
||||
if ('asc' === $direction) {
|
||||
return strcasecmp($leftIban, $rightIban);
|
||||
}
|
||||
|
||||
return strcasecmp($rightIban, $leftIban);
|
||||
});
|
||||
}
|
||||
if ('balance' === $column) {
|
||||
$balances = $this->convertedBalances;
|
||||
$objects = $objects->sort(function (Account $left, Account $right) use ($balances, $direction) {
|
||||
$leftBalance = (float)($balances[$left->id]['native_balance'] ?? 0);
|
||||
$rightBalance = (float)($balances[$right->id]['native_balance'] ?? 0);
|
||||
if ('asc' === $direction) {
|
||||
return $leftBalance <=> $rightBalance;
|
||||
}
|
||||
|
||||
return $rightBalance <=> $leftBalance;
|
||||
});
|
||||
}
|
||||
if ('last_activity' === $column) {
|
||||
$dates = $this->lastActivity;
|
||||
$objects = $objects->sort(function (Account $left, Account $right) use ($dates, $direction) {
|
||||
$leftDate = $dates[$left->id] ?? Carbon::create(1900, 1, 1, 0, 0, 0);
|
||||
$rightDate = $dates[$right->id] ?? Carbon::create(1900, 1, 1, 0, 0, 0);
|
||||
if ('asc' === $direction) {
|
||||
return $leftDate->gt($rightDate) ? 1 : -1;
|
||||
}
|
||||
|
||||
return $rightDate->gt($leftDate) ? 1 : -1;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// $objects = $objects->sortByDesc('name');
|
||||
return $objects;
|
||||
}
|
||||
|
||||
@@ -171,44 +117,68 @@ class AccountTransformer extends AbstractTransformer
|
||||
*/
|
||||
public function transform(Account $account): array
|
||||
{
|
||||
$id = $account->id;
|
||||
$id = $account->id;
|
||||
|
||||
// various meta
|
||||
$accountRole = $this->accountMeta[$id]['account_role'] ?? null;
|
||||
$accountType = $this->accountTypes[$id];
|
||||
$order = $account->order;
|
||||
$accountRole = $this->accountMeta[$id]['account_role'] ?? null;
|
||||
$accountType = $this->accountTypes[$id];
|
||||
$order = $account->order;
|
||||
|
||||
// liability type
|
||||
$liabilityType = 'liabilities' === $accountType ? $this->fullTypes[$id] : null;
|
||||
$liabilityDirection = $this->accountMeta[$id]['liability_direction'] ?? null;
|
||||
$interest = $this->accountMeta[$id]['interest'] ?? null;
|
||||
$interestPeriod = $this->accountMeta[$id]['interest_period'] ?? null;
|
||||
$currentDebt = $this->accountMeta[$id]['current_debt'] ?? null;
|
||||
|
||||
// no currency? use default
|
||||
$currency = $this->default;
|
||||
if (array_key_exists($id, $this->accountMeta) && 0 !== (int)($this->accountMeta[$id]['currency_id'] ?? 0)) {
|
||||
$currency = $this->currencies[(int)$this->accountMeta[$id]['currency_id']];
|
||||
$currency = $this->default;
|
||||
if (array_key_exists($id, $this->accountMeta) && 0 !== (int) ($this->accountMeta[$id]['currency_id'] ?? 0)) {
|
||||
$currency = $this->currencies[(int) $this->accountMeta[$id]['currency_id']];
|
||||
}
|
||||
// amounts and calculation.
|
||||
$balance = $this->balances[$id] ?? null;
|
||||
$nativeBalance = $this->convertedBalances[$id]['native_balance'] ?? null;
|
||||
$balance = $this->balances[$id]['balance'] ?? null;
|
||||
$nativeBalance = $this->convertedBalances[$id]['native_balance'] ?? null;
|
||||
|
||||
// no order for some accounts:
|
||||
if (!in_array(strtolower($accountType), ['liability', 'liabilities', 'asset'], true)) {
|
||||
$order = null;
|
||||
}
|
||||
|
||||
// object group
|
||||
$objectGroupId = $this->objectGroups[$id]['id'] ?? null;
|
||||
$objectGroupOrder = $this->objectGroups[$id]['order'] ?? null;
|
||||
$objectGroupTitle = $this->objectGroups[$id]['title'] ?? null;
|
||||
|
||||
// balance difference
|
||||
$diffStart = null;
|
||||
$diffEnd = null;
|
||||
$balanceDiff = null;
|
||||
$nativeBalanceDiff = null;
|
||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
||||
$diffStart = $this->parameters->get('start')->toAtomString();
|
||||
$diffEnd = $this->parameters->get('end')->toAtomString();
|
||||
$balanceDiff = $this->balanceDifferences[$id]['balance'] ?? null;
|
||||
$nativeBalanceDiff = $this->balanceDifferences[$id]['native_balance'] ?? null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => (string)$account->id,
|
||||
'id' => (string) $account->id,
|
||||
'created_at' => $account->created_at->toAtomString(),
|
||||
'updated_at' => $account->updated_at->toAtomString(),
|
||||
'active' => $account->active,
|
||||
'order' => $order,
|
||||
'name' => $account->name,
|
||||
'iban' => '' === (string)$account->iban ? null : $account->iban,
|
||||
'iban' => '' === (string) $account->iban ? null : $account->iban,
|
||||
'account_number' => $this->accountMeta[$id]['account_number'] ?? null,
|
||||
'type' => strtolower($accountType),
|
||||
'account_role' => $accountRole,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
|
||||
'native_currency_id' => (string)$this->default->id,
|
||||
'native_currency_id' => (string) $this->default->id,
|
||||
'native_currency_code' => $this->default->code,
|
||||
'native_currency_symbol' => $this->default->symbol,
|
||||
'native_currency_decimal_places' => $this->default->decimal_places,
|
||||
@@ -218,22 +188,34 @@ class AccountTransformer extends AbstractTransformer
|
||||
'native_current_balance' => $nativeBalance,
|
||||
'current_balance_date' => $this->getDate()->endOfDay()->toAtomString(),
|
||||
|
||||
// balance difference
|
||||
'balance_difference' => $balanceDiff,
|
||||
'native_balance_difference' => $nativeBalanceDiff,
|
||||
'balance_difference_start' => $diffStart,
|
||||
'balance_difference_end' => $diffEnd,
|
||||
|
||||
// more meta
|
||||
'last_activity' => array_key_exists($id, $this->lastActivity) ? $this->lastActivity[$id]->toAtomString() : null,
|
||||
|
||||
// liability stuff
|
||||
'liability_type' => $liabilityType,
|
||||
'liability_direction' => $liabilityDirection,
|
||||
'interest' => $interest,
|
||||
'interest_period' => $interestPeriod,
|
||||
'current_debt' => $currentDebt,
|
||||
|
||||
// object group
|
||||
'object_group_id' => null !== $objectGroupId ? (string) $objectGroupId : null,
|
||||
'object_group_order' => $objectGroupOrder,
|
||||
'object_group_title' => $objectGroupTitle,
|
||||
|
||||
// 'notes' => $this->repository->getNoteText($account),
|
||||
// 'monthly_payment_date' => $monthlyPaymentDate,
|
||||
// 'credit_card_type' => $creditCardType,
|
||||
// 'account_number' => $this->repository->getMetaValue($account, 'account_number'),
|
||||
// 'bic' => $this->repository->getMetaValue($account, 'BIC'),
|
||||
// 'virtual_balance' => number_format((float) $account->virtual_balance, $decimalPlaces, '.', ''),
|
||||
// 'opening_balance' => $openingBalance,
|
||||
// 'opening_balance_date' => $openingBalanceDate,
|
||||
// 'liability_type' => $liabilityType,
|
||||
// 'liability_direction' => $liabilityDirection,
|
||||
// 'interest' => $interest,
|
||||
// 'interest_period' => $interestPeriod,
|
||||
// 'current_debt' => $this->repository->getMetaValue($account, 'current_debt'),
|
||||
// 'include_net_worth' => $includeNetWorth,
|
||||
// 'longitude' => $longitude,
|
||||
// 'latitude' => $latitude,
|
||||
@@ -246,4 +228,205 @@ class AccountTransformer extends AbstractTransformer
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function getMetaBalances(Collection $accounts): void
|
||||
{
|
||||
try {
|
||||
$this->convertedBalances = app('steam')->balancesByAccountsConverted($accounts, $this->getDate());
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function getDefaultCurrency(): void
|
||||
{
|
||||
$this->default = app('amount')->getDefaultCurrency();
|
||||
}
|
||||
|
||||
private function collectAccountMetaData(Collection $accounts): void
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$metaFields = $accountRepository->getMetaValues($accounts, ['currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']);
|
||||
$currencyIds = $metaFields->where('name', 'currency_id')->pluck('data')->toArray();
|
||||
|
||||
$currencies = $repository->getByIds($currencyIds);
|
||||
foreach ($currencies as $currency) {
|
||||
$id = $currency->id;
|
||||
$this->currencies[$id] = $currency;
|
||||
}
|
||||
foreach ($metaFields as $entry) {
|
||||
$id = $entry->account_id;
|
||||
$this->accountMeta[$id][$entry->name] = $entry->data;
|
||||
}
|
||||
}
|
||||
|
||||
private function collectAccountTypes(Collection $accounts): void
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$accountTypes = $accountRepository->getAccountTypes($accounts);
|
||||
|
||||
/** @var AccountType $row */
|
||||
foreach ($accountTypes as $row) {
|
||||
$this->accountTypes[$row->id] = (string) config(sprintf('firefly.shortNamesByFullName.%s', $row->type));
|
||||
$this->fullTypes[$row->id] = $row->type;
|
||||
}
|
||||
}
|
||||
|
||||
private function getLastActivity(Collection $accounts): void
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$lastActivity = $accountRepository->getLastActivity($accounts);
|
||||
foreach ($lastActivity as $row) {
|
||||
$this->lastActivity[(int) $row['account_id']] = Carbon::parse($row['date_max'], config('app.timezone'));
|
||||
}
|
||||
}
|
||||
|
||||
private function sortAccounts(Collection $accounts): Collection
|
||||
{
|
||||
/** @var null|array $sort */
|
||||
$sort = $this->parameters->get('sort');
|
||||
|
||||
if (null === $sort || 0 === count($sort)) {
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string $column
|
||||
* @var string $direction
|
||||
*/
|
||||
foreach ($sort as $column => $direction) {
|
||||
// account_number + iban
|
||||
if ('iban' === $column) {
|
||||
$accounts = $this->sortByIban($accounts, $direction);
|
||||
}
|
||||
if ('balance' === $column) {
|
||||
$accounts = $this->sortByBalance($accounts, $direction);
|
||||
}
|
||||
if ('last_activity' === $column) {
|
||||
$accounts = $this->sortByLastActivity($accounts, $direction);
|
||||
}
|
||||
if ('balance_difference' === $column) {
|
||||
$accounts = $this->sortByBalanceDifference($accounts, $direction);
|
||||
}
|
||||
if ('current_debt' === $column) {
|
||||
$accounts = $this->sortByCurrentDebt($accounts, $direction);
|
||||
}
|
||||
}
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
private function sortByIban(Collection $accounts, string $direction): Collection
|
||||
{
|
||||
$meta = $this->accountMeta;
|
||||
|
||||
return $accounts->sort(function (Account $left, Account $right) use ($meta, $direction) {
|
||||
$leftIban = trim(sprintf('%s%s', $left->iban, $meta[$left->id]['account_number'] ?? ''));
|
||||
$rightIban = trim(sprintf('%s%s', $right->iban, $meta[$right->id]['account_number'] ?? ''));
|
||||
if ('asc' === $direction) {
|
||||
return strcasecmp($leftIban, $rightIban);
|
||||
}
|
||||
|
||||
return strcasecmp($rightIban, $leftIban);
|
||||
});
|
||||
}
|
||||
|
||||
private function sortByBalance(Collection $accounts, string $direction): Collection
|
||||
{
|
||||
$balances = $this->convertedBalances;
|
||||
|
||||
return $accounts->sort(function (Account $left, Account $right) use ($balances, $direction) {
|
||||
$leftBalance = (float) ($balances[$left->id]['native_balance'] ?? 0);
|
||||
$rightBalance = (float) ($balances[$right->id]['native_balance'] ?? 0);
|
||||
if ('asc' === $direction) {
|
||||
return $leftBalance <=> $rightBalance;
|
||||
}
|
||||
|
||||
return $rightBalance <=> $leftBalance;
|
||||
});
|
||||
}
|
||||
|
||||
private function sortByLastActivity(Collection $accounts, string $direction): Collection
|
||||
{
|
||||
$dates = $this->lastActivity;
|
||||
|
||||
return $accounts->sort(function (Account $left, Account $right) use ($dates, $direction) {
|
||||
$leftDate = $dates[$left->id] ?? Carbon::create(1900, 1, 1, 0, 0, 0);
|
||||
$rightDate = $dates[$right->id] ?? Carbon::create(1900, 1, 1, 0, 0, 0);
|
||||
if ('asc' === $direction) {
|
||||
return $leftDate->gt($rightDate) ? 1 : -1;
|
||||
}
|
||||
|
||||
return $rightDate->gt($leftDate) ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
private function getBalanceDifference(Collection $accounts, Carbon $start, Carbon $end): void
|
||||
{
|
||||
// collect balances, start and end for both native and converted.
|
||||
// yes the b is usually used for boolean by idiots but here it's for balance.
|
||||
$bStart = [];
|
||||
$bEnd = [];
|
||||
|
||||
try {
|
||||
$bStart = app('steam')->balancesByAccountsConverted($accounts, $start);
|
||||
$bEnd = app('steam')->balancesByAccountsConverted($accounts, $end);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$id = $account->id;
|
||||
if (array_key_exists($id, $bStart) && array_key_exists($id, $bEnd)) {
|
||||
$this->balanceDifferences[$id] = [
|
||||
'balance' => bcsub($bEnd[$id]['balance'], $bStart[$id]['balance']),
|
||||
'native_balance' => bcsub($bEnd[$id]['native_balance'], $bStart[$id]['native_balance']),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function sortByBalanceDifference(Collection $accounts, string $direction): Collection
|
||||
{
|
||||
$balances = $this->balanceDifferences;
|
||||
|
||||
return $accounts->sort(function (Account $left, Account $right) use ($balances, $direction) {
|
||||
$leftBalance = (float) ($balances[$left->id]['native_balance'] ?? 0);
|
||||
$rightBalance = (float) ($balances[$right->id]['native_balance'] ?? 0);
|
||||
if ('asc' === $direction) {
|
||||
return $leftBalance <=> $rightBalance;
|
||||
}
|
||||
|
||||
return $rightBalance <=> $leftBalance;
|
||||
});
|
||||
}
|
||||
|
||||
private function sortByCurrentDebt(Collection $accounts, string $direction): Collection
|
||||
{
|
||||
$amounts = $this->accountMeta;
|
||||
|
||||
return $accounts->sort(function (Account $left, Account $right) use ($amounts, $direction) {
|
||||
$leftCurrent = (float) ($amounts[$left->id]['current_debt'] ?? 0);
|
||||
$rightCurrent = (float) ($amounts[$right->id]['current_debt'] ?? 0);
|
||||
if ('asc' === $direction) {
|
||||
return $leftCurrent <=> $rightCurrent;
|
||||
}
|
||||
|
||||
return $rightCurrent <=> $leftCurrent;
|
||||
});
|
||||
}
|
||||
|
||||
private function getObjectGroups(Collection $accounts): void
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->objectGroups = $accountRepository->getObjectGroups($accounts);
|
||||
}
|
||||
}
|
||||
|
@@ -381,10 +381,7 @@ class User extends Authenticatable
|
||||
$dbRolesTitles = $dbRoles->pluck('title')->toArray();
|
||||
|
||||
/** @var Collection $groupMemberships */
|
||||
$groupMemberships = $this->groupMemberships()
|
||||
->whereIn('user_role_id', $dbRolesIds)
|
||||
->where('user_group_id', $userGroup->id)->get()
|
||||
;
|
||||
$groupMemberships = $this->groupMemberships()->whereIn('user_role_id', $dbRolesIds)->where('user_group_id', $userGroup->id)->get();
|
||||
if (0 === $groupMemberships->count()) {
|
||||
app('log')->error(sprintf(
|
||||
'User #%d "%s" does not have roles %s in user group #%d "%s"',
|
||||
|
26
changelog.md
26
changelog.md
@@ -3,11 +3,33 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## 6.1.15 - 2024-04-24
|
||||
|
||||
## 6.1.14 - 2024-xx-xx
|
||||
### Fixed
|
||||
|
||||
- [Issue 8812](https://github.com/firefly-iii/firefly-iii/issues/8812) (Login with `AUTHENTICATION_GUARD=remote_user_guard` fails due to missing UserGroup) reported by @nebulade
|
||||
|
||||
## 6.1.14 - 2024-04-24
|
||||
|
||||
### Changed
|
||||
- You will have to define again which asset accounts you want to see on the dashboard. Sorry about that.
|
||||
- You may have to define again which asset accounts you want to see on the dashboard. Sorry about that.
|
||||
- Expanded some database models.
|
||||
- Limit the number of error messages Firefly III will send (so Mailgun keeps liking me).
|
||||
- [PR 8746](https://github.com/firefly-iii/firefly-iii/pull/8746) (Set date to now when cloning journal) reported by @imlonghao
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Issue 8748](https://github.com/firefly-iii/firefly-iii/issues/8748) (Release tarballs mistakenly include the `.zip` artifact) reported by @sudoBash418
|
||||
- [Discussion 8750](https://github.com/orgs/firefly-iii/discussions/8750) (API To change transaction fails to find destination_id) started by @soloam
|
||||
- [Issue 8779](https://github.com/firefly-iii/firefly-iii/issues/8779) (Change Password Form not working ≥ 6.1.11) reported by @jemtz-deleon
|
||||
- [Issue 8781](https://github.com/firefly-iii/firefly-iii/issues/8781) (Bill information missing in /api/v1/search/transactions responses) reported by @daanvanberkel
|
||||
- [Issue 8752](https://github.com/firefly-iii/firefly-iii/issues/8752) (Transactions reorder not work (error 404)) reported by @BoGnY
|
||||
- [Issue 8613](https://github.com/firefly-iii/firefly-iii/issues/8613) (Some minor color issues) reported by @rumpff
|
||||
- [Issue 8776](https://github.com/firefly-iii/firefly-iii/issues/8776) (report-data/category/expenses has wrong sums with specific date range) reported by @bouil
|
||||
|
||||
### API
|
||||
|
||||
- [Issue 8804](https://github.com/firefly-iii/firefly-iii/issues/8804) (Unable to create rules with negation via API) reported by @tailg8nj
|
||||
|
||||
## 6.1.13 - 2024-04-01
|
||||
|
||||
|
@@ -101,6 +101,7 @@
|
||||
"psr/log": "<4",
|
||||
"ramsey/uuid": "^4.7",
|
||||
"rcrowe/twigbridge": "^0.14",
|
||||
"twig/twig": "3.8.0",
|
||||
"spatie/laravel-html": "^3.2",
|
||||
"spatie/laravel-ignition": "^2",
|
||||
"spatie/period": "^2.4",
|
||||
|
641
composer.lock
generated
641
composer.lock
generated
File diff suppressed because it is too large
Load Diff
326
config/debugbar.php
Normal file
326
config/debugbar.php
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Debugbar Settings
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Debugbar is enabled by default, when debug is set to true in app.php.
|
||||
| You can override the value by setting enable to true or false instead of null.
|
||||
|
|
||||
| You can provide an array of URI's that must be ignored (eg. 'api/*')
|
||||
|
|
||||
*/
|
||||
|
||||
'enabled' => env('DEBUGBAR_ENABLED', null),
|
||||
'except' => [
|
||||
'telescope*',
|
||||
'horizon*',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Storage settings
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| DebugBar stores data for session/ajax requests.
|
||||
| You can disable this, so the debugbar stores data in headers/session,
|
||||
| but this can cause problems with large data collectors.
|
||||
| By default, file storage (in the storage folder) is used. Redis and PDO
|
||||
| can also be used. For PDO, run the package migrations first.
|
||||
|
|
||||
| Warning: Enabling storage.open will allow everyone to access previous
|
||||
| request, do not enable open storage in publicly available environments!
|
||||
| Specify a callback if you want to limit based on IP or authentication.
|
||||
| Leaving it to null will allow localhost only.
|
||||
*/
|
||||
'storage' => [
|
||||
'enabled' => true,
|
||||
'open' => env('DEBUGBAR_OPEN_STORAGE'), // bool/callback.
|
||||
'driver' => 'file', // redis, file, pdo, socket, custom
|
||||
'path' => storage_path('debugbar'), // For file driver
|
||||
'connection' => null, // Leave null for default connection (Redis/PDO)
|
||||
'provider' => '', // Instance of StorageInterface for custom driver
|
||||
'hostname' => '127.0.0.1', // Hostname to use with the "socket" driver
|
||||
'port' => 2304, // Port to use with the "socket" driver
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Editor
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Choose your preferred editor to use when clicking file name.
|
||||
|
|
||||
| Supported: "phpstorm", "vscode", "vscode-insiders", "vscode-remote",
|
||||
| "vscode-insiders-remote", "vscodium", "textmate", "emacs",
|
||||
| "sublime", "atom", "nova", "macvim", "idea", "netbeans",
|
||||
| "xdebug", "espresso"
|
||||
|
|
||||
*/
|
||||
|
||||
'editor' => env('DEBUGBAR_EDITOR') ?? env('IGNITION_EDITOR', 'phpstorm'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Remote Path Mapping
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If you are using a remote dev server, like Laravel Homestead, Docker, or
|
||||
| even a remote VPS, it will be necessary to specify your path mapping.
|
||||
|
|
||||
| Leaving one, or both of these, empty or null will not trigger the remote
|
||||
| URL changes and Debugbar will treat your editor links as local files.
|
||||
|
|
||||
| "remote_sites_path" is an absolute base path for your sites or projects
|
||||
| in Homestead, Vagrant, Docker, or another remote development server.
|
||||
|
|
||||
| Example value: "/home/vagrant/Code"
|
||||
|
|
||||
| "local_sites_path" is an absolute base path for your sites or projects
|
||||
| on your local computer where your IDE or code editor is running on.
|
||||
|
|
||||
| Example values: "/Users/<name>/Code", "C:\Users\<name>\Documents\Code"
|
||||
|
|
||||
*/
|
||||
|
||||
'remote_sites_path' => env('DEBUGBAR_REMOTE_SITES_PATH'),
|
||||
'local_sites_path' => env('DEBUGBAR_LOCAL_SITES_PATH', env('IGNITION_LOCAL_SITES_PATH')),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Vendors
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Vendor files are included by default, but can be set to false.
|
||||
| This can also be set to 'js' or 'css', to only include javascript or css vendor files.
|
||||
| Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
|
||||
| and for js: jquery and highlight.js
|
||||
| So if you want syntax highlighting, set it to true.
|
||||
| jQuery is set to not conflict with existing jQuery scripts.
|
||||
|
|
||||
*/
|
||||
|
||||
'include_vendors' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Capture Ajax Requests
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
|
||||
| you can use this option to disable sending the data through the headers.
|
||||
|
|
||||
| Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
|
||||
|
|
||||
| Note for your request to be identified as ajax requests they must either send the header
|
||||
| X-Requested-With with the value XMLHttpRequest (most JS libraries send this), or have application/json as a Accept header.
|
||||
|
|
||||
| By default `ajax_handler_auto_show` is set to true allowing ajax requests to be shown automatically in the Debugbar.
|
||||
| Changing `ajax_handler_auto_show` to false will prevent the Debugbar from reloading.
|
||||
*/
|
||||
|
||||
'capture_ajax' => true,
|
||||
'add_ajax_timing' => false,
|
||||
'ajax_handler_auto_show' => true,
|
||||
'ajax_handler_enable_tab' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Error Handler for Deprecated warnings
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When enabled, the Debugbar shows deprecated warnings for Symfony components
|
||||
| in the Messages tab.
|
||||
|
|
||||
*/
|
||||
'error_handler' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Clockwork integration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The Debugbar can emulate the Clockwork headers, so you can use the Chrome
|
||||
| Extension, without the server-side code. It uses Debugbar collectors instead.
|
||||
|
|
||||
*/
|
||||
'clockwork' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DataCollectors
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Enable/disable DataCollectors
|
||||
|
|
||||
*/
|
||||
|
||||
'collectors' => [
|
||||
'phpinfo' => true, // Php version
|
||||
'messages' => true, // Messages
|
||||
'time' => true, // Time Datalogger
|
||||
'memory' => true, // Memory usage
|
||||
'exceptions' => true, // Exception displayer
|
||||
'log' => true, // Logs from Monolog (merged in messages if enabled)
|
||||
'db' => true, // Show database (PDO) queries and bindings
|
||||
'views' => true, // Views with their data
|
||||
'route' => true, // Current route information
|
||||
'auth' => false, // Display Laravel authentication status
|
||||
'gate' => true, // Display Laravel Gate checks
|
||||
'session' => true, // Display session data
|
||||
'symfony_request' => true, // Only one can be enabled..
|
||||
'mail' => true, // Catch mail messages
|
||||
'laravel' => false, // Laravel version and environment
|
||||
'events' => false, // All events fired
|
||||
'default_request' => false, // Regular or special Symfony request logger
|
||||
'logs' => false, // Add the latest log messages
|
||||
'files' => false, // Show the included files
|
||||
'config' => false, // Display config settings
|
||||
'cache' => false, // Display cache events
|
||||
'models' => true, // Display models
|
||||
'livewire' => true, // Display Livewire (when available)
|
||||
'jobs' => false, // Display dispatched jobs
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Extra options
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Configure some DataCollectors
|
||||
|
|
||||
*/
|
||||
|
||||
'options' => [
|
||||
'time' => [
|
||||
'memory_usage' => false, // Calculated by subtracting memory start and end, it may be inaccurate
|
||||
],
|
||||
'messages' => [
|
||||
'trace' => true, // Trace the origin of the debug message
|
||||
],
|
||||
'memory' => [
|
||||
'reset_peak' => false, // run memory_reset_peak_usage before collecting
|
||||
'with_baseline' => false, // Set boot memory usage as memory peak baseline
|
||||
'precision' => 0, // Memory rounding precision
|
||||
],
|
||||
'auth' => [
|
||||
'show_name' => true, // Also show the users name/email in the debugbar
|
||||
'show_guards' => true, // Show the guards that are used
|
||||
],
|
||||
'db' => [
|
||||
'with_params' => true, // Render SQL with the parameters substituted
|
||||
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
|
||||
'backtrace_exclude_paths' => [], // Paths to exclude from backtrace. (in addition to defaults)
|
||||
'timeline' => false, // Add the queries to the timeline
|
||||
'duration_background' => true, // Show shaded background on each query relative to how long it took to execute.
|
||||
'explain' => [ // Show EXPLAIN output on queries
|
||||
'enabled' => false,
|
||||
'types' => ['SELECT'], // Deprecated setting, is always only SELECT
|
||||
],
|
||||
'hints' => false, // Show hints for common mistakes
|
||||
'show_copy' => false, // Show copy button next to the query,
|
||||
'slow_threshold' => false, // Only track queries that last longer than this time in ms
|
||||
'memory_usage' => false, // Show queries memory usage
|
||||
'soft_limit' => 100, // After the soft limit, no parameters/backtrace are captured
|
||||
'hard_limit' => 500, // After the hard limit, queries are ignored
|
||||
],
|
||||
'mail' => [
|
||||
'timeline' => false, // Add mails to the timeline
|
||||
'show_body' => true,
|
||||
],
|
||||
'views' => [
|
||||
'timeline' => false, // Add the views to the timeline (Experimental)
|
||||
'data' => false, // true for all data, 'keys' for only names, false for no parameters.
|
||||
'group' => 50, // Group duplicate views. Pass value to auto-group, or true/false to force
|
||||
'exclude_paths' => [ // Add the paths which you don't want to appear in the views
|
||||
'vendor/filament', // Exclude Filament components by default
|
||||
],
|
||||
],
|
||||
'route' => [
|
||||
'label' => true, // show complete route on bar
|
||||
],
|
||||
'session' => [
|
||||
'hiddens' => [], // hides sensitive values using array paths
|
||||
],
|
||||
'symfony_request' => [
|
||||
'hiddens' => [], // hides sensitive values using array paths, example: request_request.password
|
||||
],
|
||||
'events' => [
|
||||
'data' => false, // collect events data, listeners
|
||||
],
|
||||
'logs' => [
|
||||
'file' => null,
|
||||
],
|
||||
'cache' => [
|
||||
'values' => true, // collect cache values
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Inject Debugbar in Response
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Usually, the debugbar is added just before </body>, by listening to the
|
||||
| Response after the App is done. If you disable this, you have to add them
|
||||
| in your template yourself. See http://phpdebugbar.com/docs/rendering.html
|
||||
|
|
||||
*/
|
||||
|
||||
'inject' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DebugBar route prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Sometimes you want to set route prefix to be used by DebugBar to load
|
||||
| its resources from. Usually the need comes from misconfigured web server or
|
||||
| from trying to overcome bugs like this: http://trac.nginx.org/nginx/ticket/97
|
||||
|
|
||||
*/
|
||||
'route_prefix' => '_debugbar',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DebugBar route middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Additional middleware to run on the Debugbar routes
|
||||
*/
|
||||
'route_middleware' => [],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DebugBar route domain
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| By default DebugBar route served from the same domain that request served.
|
||||
| To override default domain, specify it as a non-empty value.
|
||||
*/
|
||||
'route_domain' => null,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| DebugBar theme
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Switches between light and dark theme. If set to auto it will respect system preferences
|
||||
| Possible values: auto, light, dark
|
||||
*/
|
||||
'theme' => env('DEBUGBAR_THEME', 'auto'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Backtrace stack limit
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| By default, the DebugBar limits the number of frames returned by the 'debug_backtrace()' function.
|
||||
| If you need larger stacktraces, you can increase this number. Setting it to 0 will result in no limit.
|
||||
*/
|
||||
'debug_backtrace_limit' => 50,
|
||||
];
|
@@ -117,8 +117,8 @@ return [
|
||||
'expression_engine' => false,
|
||||
// see cer.php for exchange rates feature flag.
|
||||
],
|
||||
'version' => 'develop/2024-04-08',
|
||||
'api_version' => '2.0.13',
|
||||
'version' => 'develop/2024-05-09',
|
||||
'api_version' => '2.0.14',
|
||||
'db_version' => 24,
|
||||
|
||||
// generic settings
|
||||
@@ -206,7 +206,6 @@ return [
|
||||
|
||||
// web configuration:
|
||||
'trusted_proxies' => env('TRUSTED_PROXIES', ''),
|
||||
'layout' => envNonEmpty('FIREFLY_III_LAYOUT', 'v1'),
|
||||
|
||||
// map configuration
|
||||
'default_location' => [
|
||||
@@ -921,11 +920,25 @@ return [
|
||||
// preselected account lists possibilities:
|
||||
'preselected_accounts' => ['all', 'assets', 'liabilities'],
|
||||
|
||||
// allowed sort columns for API's
|
||||
// allowed filters (search) for APIs
|
||||
'filters' => [
|
||||
'allowed' => [
|
||||
'accounts' => [
|
||||
'name' => 'string',
|
||||
'active' => 'boolean',
|
||||
'iban' => 'iban',
|
||||
'balance' => 'numeric',
|
||||
'last_activity' => 'date',
|
||||
'balance_difference' => 'numeric',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// allowed sort columns for APIs
|
||||
'sorting' => [
|
||||
'allowed' => [
|
||||
'transactions' => ['description', 'amount'],
|
||||
'accounts' => ['name', 'active', 'iban', 'balance', 'last_activity'],
|
||||
'accounts' => ['name', 'active', 'iban', 'balance', 'last_activity', 'balance_difference', 'current_debt'],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@@ -34,11 +34,33 @@ return [
|
||||
'form' => [
|
||||
'title',
|
||||
],
|
||||
'list' => [
|
||||
'drag_and_drop',
|
||||
'active',
|
||||
'name',
|
||||
'type',
|
||||
'number',
|
||||
'liability_type',
|
||||
'current_balance',
|
||||
'last_activity',
|
||||
'amount_due',
|
||||
'balance_difference',
|
||||
'menu',
|
||||
],
|
||||
'validation' => [
|
||||
'bad_type_source',
|
||||
'bad_type_destination',
|
||||
],
|
||||
'firefly' => [
|
||||
'liability_direction_debit_short',
|
||||
'liability_direction_credit_short',
|
||||
'interest_calc_yearly',
|
||||
'interest_calc_',
|
||||
'interest_calc_daily',
|
||||
'interest_calc_monthly',
|
||||
'interest_calc_weekly',
|
||||
'interest_calc_half-year',
|
||||
'interest_calc_quarterly',
|
||||
'spent',
|
||||
'administration_owner',
|
||||
'administration_you',
|
||||
@@ -94,6 +116,19 @@ return [
|
||||
'account_role_savingAsset',
|
||||
'account_role_ccAsset',
|
||||
'account_role_cashWalletAsset',
|
||||
// 'account_column_opt_drag_and_drop',
|
||||
// 'account_column_opt_active',
|
||||
// 'account_column_opt_name',
|
||||
// 'account_column_opt_type',
|
||||
// 'account_column_opt_liability_type',
|
||||
// 'account_column_opt_liability_direction',
|
||||
// 'account_column_opt_liability_interest',
|
||||
// 'account_column_opt_number',
|
||||
// 'account_column_opt_current_balance',
|
||||
// 'account_column_opt_amount_due',
|
||||
// 'account_column_opt_last_activity',
|
||||
// 'account_column_opt_balance_difference',
|
||||
// 'account_column_opt_menu',
|
||||
],
|
||||
],
|
||||
'v1' => [
|
||||
|
@@ -284,7 +284,7 @@ class CreateMainTables extends Migration
|
||||
$table->integer('budget_id', false, true);
|
||||
$table->date('startdate');
|
||||
$table->decimal('amount', 32, 12);
|
||||
$table->string('repeat_freq', 30);
|
||||
$table->string('repeat_freq', 30)->nullable();
|
||||
$table->boolean('repeats')->default(0);
|
||||
$table->foreign('budget_id')->references('id')->on('budgets')->onDelete('cascade');
|
||||
}
|
||||
|
1086
package-lock.json
generated
1086
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -22,95 +22,10 @@ var count = 0;
|
||||
|
||||
$(document).ready(function () {
|
||||
updateListButtons();
|
||||
addSort();
|
||||
$('.clone-transaction').click(cloneTransaction);
|
||||
$('.clone-transaction-and-edit').click(cloneTransactionAndEdit);
|
||||
});
|
||||
|
||||
var fixHelper = function (e, tr) {
|
||||
"use strict";
|
||||
var $originals = tr.children();
|
||||
var $helper = tr.clone();
|
||||
$helper.children().each(function (index) {
|
||||
// Set helper cell sizes to match the original sizes
|
||||
$(this).width($originals.eq(index).width());
|
||||
});
|
||||
return $helper;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function addSort() {
|
||||
if (typeof $(".table-sortable>tbody").sortable !== "undefined") {
|
||||
$('.table-sortable>tbody').sortable(
|
||||
{
|
||||
items: "tr:not(.unsortable)",
|
||||
handle: '.object-handle',
|
||||
stop: sortStop,
|
||||
start: function (event, ui) {
|
||||
// Build a placeholder cell that spans all the cells in the row
|
||||
var cellCount = 0;
|
||||
$('td, th', ui.helper).each(function () {
|
||||
// For each TD or TH try and get it's colspan attribute, and add that or 1 to the total
|
||||
var colspan = 1;
|
||||
var colspanAttr = $(this).attr('colspan');
|
||||
if (colspanAttr > 1) {
|
||||
colspan = colspanAttr;
|
||||
}
|
||||
cellCount += colspan;
|
||||
});
|
||||
|
||||
// Add the placeholder UI - note that this is the item's content, so TD rather than TR
|
||||
ui.placeholder.html('<td colspan="' + cellCount + '"> </td>');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param event
|
||||
* @param ui
|
||||
* @returns {boolean|undefined}
|
||||
*/
|
||||
function sortStop(event, ui) {
|
||||
"use strict";
|
||||
var current = $(ui.item);
|
||||
var thisDate = current.data('date');
|
||||
var originalBG = current.css('backgroundColor');
|
||||
|
||||
|
||||
if (current.prev().data('date') !== thisDate && current.next().data('date') !== thisDate) {
|
||||
// animate something with color:
|
||||
current.animate({backgroundColor: "#d9534f"}, 200, function () {
|
||||
$(this).animate({backgroundColor: originalBG}, 200);
|
||||
return undefined;
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
//return false;
|
||||
// do update
|
||||
var list = $('tr[data-date="' + thisDate + '"]');
|
||||
var submit = [];
|
||||
$.each(list, function (i, v) {
|
||||
var row = $(v);
|
||||
var id = row.data('id');
|
||||
submit.push(id);
|
||||
});
|
||||
|
||||
// do extra animation when done?
|
||||
$.post('transactions/reorder', {items: submit, date: thisDate, _token: token});
|
||||
|
||||
current.animate({backgroundColor: "#5cb85c"}, 200, function () {
|
||||
$(this).animate({backgroundColor: originalBG}, 200);
|
||||
return undefined;
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@@ -103,6 +103,12 @@
|
||||
.skin-firefly-iii .btn-info {
|
||||
color: #fff;
|
||||
}
|
||||
.skin-firefly-iii .btn-danger {
|
||||
color: #fff;
|
||||
}
|
||||
.skin-firefly-iii .btn-warning {
|
||||
color: #fff;
|
||||
}
|
||||
.skin-firefly-iii .btn-default {
|
||||
background-color: #55606a;
|
||||
color: #bec5cb;
|
||||
@@ -251,6 +257,11 @@
|
||||
}
|
||||
.skin-firefly-iii .table > thead > tr > th,
|
||||
.skin-firefly-iii .table > tbody > tr > th,
|
||||
.skin-firefly-iii .table > tfoot > tr > th {
|
||||
border-bottom: 2px #c9d1d9 solid;
|
||||
}
|
||||
.skin-firefly-iii .table > thead > tr > th,
|
||||
.skin-firefly-iii .table > tbody > tr > th,
|
||||
.skin-firefly-iii .table > tfoot > tr > th,
|
||||
.skin-firefly-iii .table > thead > tr > td,
|
||||
.skin-firefly-iii .table > tbody > tr > td,
|
||||
@@ -480,6 +491,7 @@
|
||||
.skin-firefly-iii .nav-tabs-custom > .nav-tabs > li.active > a {
|
||||
border-left-color: #353c42;
|
||||
border-right-color: #353c42;
|
||||
color: #bec5cb;
|
||||
}
|
||||
.skin-firefly-iii .nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a {
|
||||
border-left-color: #353c42;
|
||||
@@ -511,7 +523,7 @@
|
||||
background-color: #272c30;
|
||||
}
|
||||
.skin-firefly-iii .input-group .input-group-addon {
|
||||
border-right: 1px solid #272c30;
|
||||
border: 1px solid #272c30;
|
||||
}
|
||||
.skin-firefly-iii .form-control {
|
||||
border-color: #272c30;
|
||||
|
File diff suppressed because one or more lines are too long
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\u0417\u0430\u0433\u043b\u0430\u0432\u0438\u0435"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u0410\u043a\u0442\u0438\u0432\u0435\u043d \u043b\u0438 \u0435?",
|
||||
"name": "\u0418\u043c\u0435",
|
||||
"type": "\u0412\u0438\u0434",
|
||||
"number": "Account number",
|
||||
"liability_type": "\u0412\u0438\u0434 \u043d\u0430 \u0437\u0430\u0434\u044a\u043b\u0436\u0435\u043d\u0438\u0435\u0442\u043e",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\u0414\u044a\u043b\u0436\u0430 \u0434\u044a\u043b\u0433",
|
||||
"liability_direction_credit_short": "\u0414\u044a\u043b\u0436\u044a\u0442 \u043c\u0438 \u0434\u044a\u043b\u0433",
|
||||
"interest_calc_yearly": "\u0413\u043e\u0434\u0438\u0448\u043d\u043e",
|
||||
"interest_calc_": "\u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430",
|
||||
"interest_calc_daily": "\u041d\u0430 \u0434\u0435\u043d",
|
||||
"interest_calc_monthly": "\u041d\u0430 \u043c\u0435\u0441\u0435\u0446",
|
||||
"interest_calc_weekly": "\u0421\u0435\u0434\u043c\u0438\u0447\u043d\u043e",
|
||||
"interest_calc_half-year": "\u0417\u0430 \u043f\u043e\u043b\u043e\u0432\u0438\u043d \u0433\u043e\u0434\u0438\u043d\u0430",
|
||||
"interest_calc_quarterly": "\u0417\u0430 \u0442\u0440\u0438\u043c\u0435\u0441\u0435\u0447\u0438\u0435",
|
||||
"spent": "\u041f\u043e\u0445\u0430\u0440\u0447\u0435\u043d\u0438",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\u0417\u0430\u0433\u043b\u0430\u0432\u0438\u0435"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u0410\u043a\u0442\u0438\u0432\u0435\u043d \u043b\u0438 \u0435?",
|
||||
"name": "\u0418\u043c\u0435",
|
||||
"type": "\u0412\u0438\u0434",
|
||||
"number": "Account number",
|
||||
"liability_type": "\u0412\u0438\u0434 \u043d\u0430 \u0437\u0430\u0434\u044a\u043b\u0436\u0435\u043d\u0438\u0435\u0442\u043e",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\u0414\u044a\u043b\u0436\u0430 \u0434\u044a\u043b\u0433",
|
||||
"liability_direction_credit_short": "\u0414\u044a\u043b\u0436\u044a\u0442 \u043c\u0438 \u0434\u044a\u043b\u0433",
|
||||
"interest_calc_yearly": "\u0413\u043e\u0434\u0438\u0448\u043d\u043e",
|
||||
"interest_calc_": "\u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430",
|
||||
"interest_calc_daily": "\u041d\u0430 \u0434\u0435\u043d",
|
||||
"interest_calc_monthly": "\u041d\u0430 \u043c\u0435\u0441\u0435\u0446",
|
||||
"interest_calc_weekly": "\u0421\u0435\u0434\u043c\u0438\u0447\u043d\u043e",
|
||||
"interest_calc_half-year": "\u0417\u0430 \u043f\u043e\u043b\u043e\u0432\u0438\u043d \u0433\u043e\u0434\u0438\u043d\u0430",
|
||||
"interest_calc_quarterly": "\u0417\u0430 \u0442\u0440\u0438\u043c\u0435\u0441\u0435\u0447\u0438\u0435",
|
||||
"spent": "\u041f\u043e\u0445\u0430\u0440\u0447\u0435\u043d\u0438",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,28 +9,50 @@
|
||||
"form": {
|
||||
"title": "T\u00edtol"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Arrossega i deixa anar",
|
||||
"active": "Est\u00e0 actiu?",
|
||||
"name": "Nom",
|
||||
"type": "Tipus",
|
||||
"number": "N\u00famero de compte",
|
||||
"liability_type": "Tipus de passiu",
|
||||
"current_balance": "Balan\u00e7 actual",
|
||||
"last_activity": "Darrera activitat",
|
||||
"amount_due": "Import pendent",
|
||||
"balance_difference": "Difer\u00e8ncia de saldo",
|
||||
"menu": "Men\u00fa"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III no pot determinar el tipus de transacci\u00f3 a partir d'aquest compte font.",
|
||||
"bad_type_destination": "Firefly III no pot determinar el tipus de transacci\u00f3 a partir d'aquest compte de dest\u00ed."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Ho dec",
|
||||
"liability_direction_credit_short": "Se'm deu",
|
||||
"interest_calc_yearly": "Per any",
|
||||
"interest_calc_": "desconegut",
|
||||
"interest_calc_daily": "Per dia",
|
||||
"interest_calc_monthly": "Per mes",
|
||||
"interest_calc_weekly": "Per setmana",
|
||||
"interest_calc_half-year": "Cada mig any",
|
||||
"interest_calc_quarterly": "Per quadrimestre",
|
||||
"spent": "Gastat",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_ro": "Read-only",
|
||||
"administration_role_mng_trx": "Manage transactions",
|
||||
"administration_role_mng_meta": "Manage classification and meta-data",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_piggies": "Manage piggy banks",
|
||||
"administration_role_mng_subscriptions": "Manage subscriptions",
|
||||
"administration_role_mng_rules": "Manage rules",
|
||||
"administration_role_mng_recurring": "Manage recurring transactions ",
|
||||
"administration_role_mng_webhooks": "Manage webhooks",
|
||||
"administration_role_mng_currencies": "Manage currencies",
|
||||
"administration_role_view_reports": "View reports",
|
||||
"administration_role_full": "Full access",
|
||||
"new_administration_created": "New financial administration \"{{title}}\" has been created",
|
||||
"administration_owner": "Propietari de l'administraci\u00f3: {{email}}",
|
||||
"administration_you": "El teu rol: {{role}}",
|
||||
"administration_role_owner": "Propietari",
|
||||
"administration_role_ro": "Nom\u00e9s de lectura",
|
||||
"administration_role_mng_trx": "Gestionar transaccions",
|
||||
"administration_role_mng_meta": "Gestionar classificaci\u00f3 i meta-dades",
|
||||
"administration_role_mng_budgets": "Gestionar pressupostos",
|
||||
"administration_role_mng_piggies": "Administra guardioles",
|
||||
"administration_role_mng_subscriptions": "Gestionar subscripcions",
|
||||
"administration_role_mng_rules": "Gestionar normes",
|
||||
"administration_role_mng_recurring": "Gestionar transaccions recurrents ",
|
||||
"administration_role_mng_webhooks": "Gestionar Webhooks",
|
||||
"administration_role_mng_currencies": "Gestionar divises",
|
||||
"administration_role_view_reports": "Veure informes",
|
||||
"administration_role_full": "Acc\u00e9s total",
|
||||
"new_administration_created": "S'ha creat una nova administraci\u00f3 financera \"{{title}}\"",
|
||||
"left": "Queda",
|
||||
"paid": "Pagat",
|
||||
"errors_submission_v2": "Hi ha hagut un error amb el teu enviament. Per favor, comprova els seg\u00fcents errors: {{errorMessage}}",
|
||||
|
@@ -9,28 +9,50 @@
|
||||
"form": {
|
||||
"title": "T\u00edtol"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Arrossega i deixa anar",
|
||||
"active": "Est\u00e0 actiu?",
|
||||
"name": "Nom",
|
||||
"type": "Tipus",
|
||||
"number": "N\u00famero de compte",
|
||||
"liability_type": "Tipus de passiu",
|
||||
"current_balance": "Balan\u00e7 actual",
|
||||
"last_activity": "Darrera activitat",
|
||||
"amount_due": "Import pendent",
|
||||
"balance_difference": "Difer\u00e8ncia de saldo",
|
||||
"menu": "Men\u00fa"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III no pot determinar el tipus de transacci\u00f3 a partir d'aquest compte font.",
|
||||
"bad_type_destination": "Firefly III no pot determinar el tipus de transacci\u00f3 a partir d'aquest compte de dest\u00ed."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Ho dec",
|
||||
"liability_direction_credit_short": "Se'm deu",
|
||||
"interest_calc_yearly": "Per any",
|
||||
"interest_calc_": "desconegut",
|
||||
"interest_calc_daily": "Per dia",
|
||||
"interest_calc_monthly": "Per mes",
|
||||
"interest_calc_weekly": "Per setmana",
|
||||
"interest_calc_half-year": "Cada mig any",
|
||||
"interest_calc_quarterly": "Per quadrimestre",
|
||||
"spent": "Gastat",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_ro": "Read-only",
|
||||
"administration_role_mng_trx": "Manage transactions",
|
||||
"administration_role_mng_meta": "Manage classification and meta-data",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_piggies": "Manage piggy banks",
|
||||
"administration_role_mng_subscriptions": "Manage subscriptions",
|
||||
"administration_role_mng_rules": "Manage rules",
|
||||
"administration_role_mng_recurring": "Manage recurring transactions ",
|
||||
"administration_role_mng_webhooks": "Manage webhooks",
|
||||
"administration_role_mng_currencies": "Manage currencies",
|
||||
"administration_role_view_reports": "View reports",
|
||||
"administration_role_full": "Full access",
|
||||
"new_administration_created": "New financial administration \"{{title}}\" has been created",
|
||||
"administration_owner": "Propietari de l'administraci\u00f3: {{email}}",
|
||||
"administration_you": "El teu rol: {{role}}",
|
||||
"administration_role_owner": "Propietari",
|
||||
"administration_role_ro": "Nom\u00e9s de lectura",
|
||||
"administration_role_mng_trx": "Gestionar transaccions",
|
||||
"administration_role_mng_meta": "Gestionar classificaci\u00f3 i meta-dades",
|
||||
"administration_role_mng_budgets": "Gestionar pressupostos",
|
||||
"administration_role_mng_piggies": "Administra guardioles",
|
||||
"administration_role_mng_subscriptions": "Gestionar subscripcions",
|
||||
"administration_role_mng_rules": "Gestionar normes",
|
||||
"administration_role_mng_recurring": "Gestionar transaccions recurrents ",
|
||||
"administration_role_mng_webhooks": "Gestionar Webhooks",
|
||||
"administration_role_mng_currencies": "Gestionar divises",
|
||||
"administration_role_view_reports": "Veure informes",
|
||||
"administration_role_full": "Acc\u00e9s total",
|
||||
"new_administration_created": "S'ha creat una nova administraci\u00f3 financera \"{{title}}\"",
|
||||
"left": "Queda",
|
||||
"paid": "Pagat",
|
||||
"errors_submission_v2": "Hi ha hagut un error amb el teu enviament. Per favor, comprova els seg\u00fcents errors: {{errorMessage}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "N\u00e1zev"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktivn\u00ed?",
|
||||
"name": "Jm\u00e9no",
|
||||
"type": "Typ",
|
||||
"number": "Account number",
|
||||
"liability_type": "Typ z\u00e1vazku",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Za rok",
|
||||
"interest_calc_": "nezn\u00e1m\u00e9",
|
||||
"interest_calc_daily": "Za den",
|
||||
"interest_calc_monthly": "Za m\u011bs\u00edc",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Utraceno",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "N\u00e1zev"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktivn\u00ed?",
|
||||
"name": "Jm\u00e9no",
|
||||
"type": "Typ",
|
||||
"number": "Account number",
|
||||
"liability_type": "Typ z\u00e1vazku",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Za rok",
|
||||
"interest_calc_": "nezn\u00e1m\u00e9",
|
||||
"interest_calc_daily": "Za den",
|
||||
"interest_calc_monthly": "Za m\u011bs\u00edc",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Utraceno",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Titel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktiv?",
|
||||
"name": "Navn",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "G\u00e6ldstype",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III kan ikke bestemme transaktionstypen baseret p\u00e5 denne kildekonto.",
|
||||
"bad_type_destination": "Firefly III kan ikke bestemme transaktionstypen baseret p\u00e5 denne destinationskonto."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Ejer denne g\u00e6ld",
|
||||
"liability_direction_credit_short": "Ejer denne g\u00e6ld",
|
||||
"interest_calc_yearly": "Pr. \u00e5r",
|
||||
"interest_calc_": "ukendt",
|
||||
"interest_calc_daily": "Pr. dag",
|
||||
"interest_calc_monthly": "Pr. m\u00e5ned",
|
||||
"interest_calc_weekly": "Pr. uge",
|
||||
"interest_calc_half-year": "Hvert halve \u00e5r",
|
||||
"interest_calc_quarterly": "Pr. kvartal",
|
||||
"spent": "Spent",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Titel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktiv?",
|
||||
"name": "Navn",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "G\u00e6ldstype",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III kan ikke bestemme transaktionstypen baseret p\u00e5 denne kildekonto.",
|
||||
"bad_type_destination": "Firefly III kan ikke bestemme transaktionstypen baseret p\u00e5 denne destinationskonto."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Ejer denne g\u00e6ld",
|
||||
"liability_direction_credit_short": "Ejer denne g\u00e6ld",
|
||||
"interest_calc_yearly": "Pr. \u00e5r",
|
||||
"interest_calc_": "ukendt",
|
||||
"interest_calc_daily": "Pr. dag",
|
||||
"interest_calc_monthly": "Pr. m\u00e5ned",
|
||||
"interest_calc_weekly": "Pr. uge",
|
||||
"interest_calc_half-year": "Hvert halve \u00e5r",
|
||||
"interest_calc_quarterly": "Pr. kvartal",
|
||||
"spent": "Spent",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,19 +9,41 @@
|
||||
"form": {
|
||||
"title": "Titel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Ziehen und Ablegen",
|
||||
"active": "Aktiv?",
|
||||
"name": "Name",
|
||||
"type": "Typ",
|
||||
"number": "Kontonummer",
|
||||
"liability_type": "Verbindlichkeitsart",
|
||||
"current_balance": "Aktueller Kontostand",
|
||||
"last_activity": "Letzte Aktivit\u00e4t",
|
||||
"amount_due": "F\u00e4lliger Betrag",
|
||||
"balance_difference": "Saldendifferenz",
|
||||
"menu": "Men\u00fc"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III kann die Buchungsart anhand dieses Quellkontos nicht ermitteln.",
|
||||
"bad_type_destination": "Firefly III kann die Buchungsart anhand dieses Zielkontos nicht ermitteln."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Schuldiger Betrag",
|
||||
"liability_direction_credit_short": "Geschuldeter Betrag",
|
||||
"interest_calc_yearly": "J\u00e4hrlich",
|
||||
"interest_calc_": "Unbekannt",
|
||||
"interest_calc_daily": "T\u00e4glich",
|
||||
"interest_calc_monthly": "Monatlich",
|
||||
"interest_calc_weekly": "Pro Woche",
|
||||
"interest_calc_half-year": "Halbj\u00e4hrlich",
|
||||
"interest_calc_quarterly": "Viertelj\u00e4hrlich",
|
||||
"spent": "Ausgegeben",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Ihre Funktion: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_owner": "Inhaber",
|
||||
"administration_role_ro": "Schreibgesch\u00fctzt",
|
||||
"administration_role_mng_trx": "Buchungen verwalten",
|
||||
"administration_role_mng_meta": "Klassifizierungs- und Metadaten verwalten",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_budgets": "Budgets verwalten",
|
||||
"administration_role_mng_piggies": "Sparschweine verwalten",
|
||||
"administration_role_mng_subscriptions": "Abonnements verwalten",
|
||||
"administration_role_mng_rules": "Regeln verwalten",
|
||||
|
@@ -9,19 +9,41 @@
|
||||
"form": {
|
||||
"title": "Titel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Ziehen und Ablegen",
|
||||
"active": "Aktiv?",
|
||||
"name": "Name",
|
||||
"type": "Typ",
|
||||
"number": "Kontonummer",
|
||||
"liability_type": "Verbindlichkeitsart",
|
||||
"current_balance": "Aktueller Kontostand",
|
||||
"last_activity": "Letzte Aktivit\u00e4t",
|
||||
"amount_due": "F\u00e4lliger Betrag",
|
||||
"balance_difference": "Saldendifferenz",
|
||||
"menu": "Men\u00fc"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III kann die Buchungsart anhand dieses Quellkontos nicht ermitteln.",
|
||||
"bad_type_destination": "Firefly III kann die Buchungsart anhand dieses Zielkontos nicht ermitteln."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Schuldiger Betrag",
|
||||
"liability_direction_credit_short": "Geschuldeter Betrag",
|
||||
"interest_calc_yearly": "J\u00e4hrlich",
|
||||
"interest_calc_": "Unbekannt",
|
||||
"interest_calc_daily": "T\u00e4glich",
|
||||
"interest_calc_monthly": "Monatlich",
|
||||
"interest_calc_weekly": "Pro Woche",
|
||||
"interest_calc_half-year": "Halbj\u00e4hrlich",
|
||||
"interest_calc_quarterly": "Viertelj\u00e4hrlich",
|
||||
"spent": "Ausgegeben",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Ihre Funktion: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_owner": "Inhaber",
|
||||
"administration_role_ro": "Schreibgesch\u00fctzt",
|
||||
"administration_role_mng_trx": "Buchungen verwalten",
|
||||
"administration_role_mng_meta": "Klassifizierungs- und Metadaten verwalten",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_budgets": "Budgets verwalten",
|
||||
"administration_role_mng_piggies": "Sparschweine verwalten",
|
||||
"administration_role_mng_subscriptions": "Abonnements verwalten",
|
||||
"administration_role_mng_rules": "Regeln verwalten",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\u03a4\u03af\u03c4\u03bb\u03bf\u03c2"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u0395\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03cc;",
|
||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1",
|
||||
"type": "\u03a4\u03cd\u03c0\u03bf\u03c2",
|
||||
"number": "Account number",
|
||||
"liability_type": "\u03a4\u03cd\u03c0\u03bf\u03c2 \u03c5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7\u03c2",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "\u03a4\u03bf Firefly III \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03ba\u03b1\u03b8\u03bf\u03c1\u03af\u03c3\u03b5\u03b9 \u03c4\u03bf\u03bd \u03c4\u03cd\u03c0\u03bf \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2 \u03bc\u03b5 \u03b2\u03ac\u03c3\u03b7 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03c0\u03c1\u03bf\u03ad\u03bb\u03b5\u03c5\u03c3\u03b7\u03c2.",
|
||||
"bad_type_destination": "\u03a4\u03bf Firefly III \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03ba\u03b1\u03b8\u03bf\u03c1\u03af\u03c3\u03b5\u03b9 \u03c4\u03bf\u03bd \u03c4\u03cd\u03c0\u03bf \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2 \u03bc\u03b5 \u03b2\u03ac\u03c3\u03b7 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03c0\u03c1\u03bf\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\u039f\u03c6\u03b5\u03af\u03bb\u03c9 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2",
|
||||
"liability_direction_credit_short": "\u039c\u03bf\u03c5 \u03bf\u03c6\u03b5\u03af\u03bb\u03bf\u03c5\u03bd \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2",
|
||||
"interest_calc_yearly": "\u0391\u03bd\u03ac \u03ad\u03c4\u03bf\u03c2",
|
||||
"interest_calc_": "\u03ac\u03b3\u03bd\u03c9\u03c3\u03c4\u03bf",
|
||||
"interest_calc_daily": "\u0391\u03bd\u03ac \u03b7\u03bc\u03ad\u03c1\u03b1",
|
||||
"interest_calc_monthly": "\u0391\u03bd\u03ac \u03bc\u03ae\u03bd\u03b1",
|
||||
"interest_calc_weekly": "\u0391\u03bd\u03ac \u03b5\u03b2\u03b4\u03bf\u03bc\u03ac\u03b4\u03b1",
|
||||
"interest_calc_half-year": "\u0391\u03bd\u03ac \u03b5\u03be\u03ac\u03bc\u03b7\u03bd\u03bf",
|
||||
"interest_calc_quarterly": "\u0391\u03bd\u03ac \u03c4\u03c1\u03af\u03bc\u03b7\u03bd\u03bf",
|
||||
"spent": "\u0394\u03b1\u03c0\u03b1\u03bd\u03ae\u03b8\u03b7\u03ba\u03b1\u03bd",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\u03a4\u03af\u03c4\u03bb\u03bf\u03c2"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u0395\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03cc;",
|
||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1",
|
||||
"type": "\u03a4\u03cd\u03c0\u03bf\u03c2",
|
||||
"number": "Account number",
|
||||
"liability_type": "\u03a4\u03cd\u03c0\u03bf\u03c2 \u03c5\u03c0\u03bf\u03c7\u03c1\u03ad\u03c9\u03c3\u03b7\u03c2",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "\u03a4\u03bf Firefly III \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03ba\u03b1\u03b8\u03bf\u03c1\u03af\u03c3\u03b5\u03b9 \u03c4\u03bf\u03bd \u03c4\u03cd\u03c0\u03bf \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2 \u03bc\u03b5 \u03b2\u03ac\u03c3\u03b7 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03c0\u03c1\u03bf\u03ad\u03bb\u03b5\u03c5\u03c3\u03b7\u03c2.",
|
||||
"bad_type_destination": "\u03a4\u03bf Firefly III \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03ba\u03b1\u03b8\u03bf\u03c1\u03af\u03c3\u03b5\u03b9 \u03c4\u03bf\u03bd \u03c4\u03cd\u03c0\u03bf \u03c3\u03c5\u03bd\u03b1\u03bb\u03bb\u03b1\u03b3\u03ae\u03c2 \u03bc\u03b5 \u03b2\u03ac\u03c3\u03b7 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03c0\u03c1\u03bf\u03bf\u03c1\u03b9\u03c3\u03bc\u03bf\u03cd."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\u039f\u03c6\u03b5\u03af\u03bb\u03c9 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2",
|
||||
"liability_direction_credit_short": "\u039c\u03bf\u03c5 \u03bf\u03c6\u03b5\u03af\u03bb\u03bf\u03c5\u03bd \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c7\u03c1\u03ad\u03bf\u03c2",
|
||||
"interest_calc_yearly": "\u0391\u03bd\u03ac \u03ad\u03c4\u03bf\u03c2",
|
||||
"interest_calc_": "\u03ac\u03b3\u03bd\u03c9\u03c3\u03c4\u03bf",
|
||||
"interest_calc_daily": "\u0391\u03bd\u03ac \u03b7\u03bc\u03ad\u03c1\u03b1",
|
||||
"interest_calc_monthly": "\u0391\u03bd\u03ac \u03bc\u03ae\u03bd\u03b1",
|
||||
"interest_calc_weekly": "\u0391\u03bd\u03ac \u03b5\u03b2\u03b4\u03bf\u03bc\u03ac\u03b4\u03b1",
|
||||
"interest_calc_half-year": "\u0391\u03bd\u03ac \u03b5\u03be\u03ac\u03bc\u03b7\u03bd\u03bf",
|
||||
"interest_calc_quarterly": "\u0391\u03bd\u03ac \u03c4\u03c1\u03af\u03bc\u03b7\u03bd\u03bf",
|
||||
"spent": "\u0394\u03b1\u03c0\u03b1\u03bd\u03ae\u03b8\u03b7\u03ba\u03b1\u03bd",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Title"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Is active?",
|
||||
"name": "Name",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type of liability",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Per year",
|
||||
"interest_calc_": "unknown",
|
||||
"interest_calc_daily": "Per day",
|
||||
"interest_calc_monthly": "Per month",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Spent",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Title"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Is active?",
|
||||
"name": "Name",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type of liability",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Per year",
|
||||
"interest_calc_": "unknown",
|
||||
"interest_calc_daily": "Per day",
|
||||
"interest_calc_monthly": "Per month",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Spent",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Title"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Is active?",
|
||||
"name": "Name",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type of liability",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Per year",
|
||||
"interest_calc_": "unknown",
|
||||
"interest_calc_daily": "Per day",
|
||||
"interest_calc_monthly": "Per month",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Spent",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Title"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Is active?",
|
||||
"name": "Name",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type of liability",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Per year",
|
||||
"interest_calc_": "unknown",
|
||||
"interest_calc_daily": "Per day",
|
||||
"interest_calc_monthly": "Per month",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Spent",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "T\u00edtulo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u00bfEst\u00e1 Activo?",
|
||||
"name": "Nombre",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"liability_type": "Tipo de pasivo",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III no puede determinar el tipo de transacci\u00f3n basado en esta cuenta de origen.",
|
||||
"bad_type_destination": "Firefly III no puede determinar el tipo de transacci\u00f3n basado en esta cuenta de destino."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Tiene esta deuda",
|
||||
"liability_direction_credit_short": "Ten\u00eda esta deuda",
|
||||
"interest_calc_yearly": "Por a\u00f1o",
|
||||
"interest_calc_": "desconocido",
|
||||
"interest_calc_daily": "Por dia",
|
||||
"interest_calc_monthly": "Por mes",
|
||||
"interest_calc_weekly": "Por semana",
|
||||
"interest_calc_half-year": "Por semestre",
|
||||
"interest_calc_quarterly": "Por trimestre",
|
||||
"spent": "Gastado",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "T\u00edtulo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u00bfEst\u00e1 Activo?",
|
||||
"name": "Nombre",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"liability_type": "Tipo de pasivo",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III no puede determinar el tipo de transacci\u00f3n basado en esta cuenta de origen.",
|
||||
"bad_type_destination": "Firefly III no puede determinar el tipo de transacci\u00f3n basado en esta cuenta de destino."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Tiene esta deuda",
|
||||
"liability_direction_credit_short": "Ten\u00eda esta deuda",
|
||||
"interest_calc_yearly": "Por a\u00f1o",
|
||||
"interest_calc_": "desconocido",
|
||||
"interest_calc_daily": "Por dia",
|
||||
"interest_calc_monthly": "Por mes",
|
||||
"interest_calc_weekly": "Por semana",
|
||||
"interest_calc_half-year": "Por semestre",
|
||||
"interest_calc_quarterly": "Por trimestre",
|
||||
"spent": "Gastado",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Otsikko"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktiivinen?",
|
||||
"name": "Nimi",
|
||||
"type": "Tyyppi",
|
||||
"number": "Account number",
|
||||
"liability_type": "Lainatyyppi",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Olen velkaa",
|
||||
"liability_direction_credit_short": "Minulle ollaan velkaa",
|
||||
"interest_calc_yearly": "Vuodessa",
|
||||
"interest_calc_": "tuntematon",
|
||||
"interest_calc_daily": "P\u00e4iv\u00e4ss\u00e4",
|
||||
"interest_calc_monthly": "Kuukaudessa",
|
||||
"interest_calc_weekly": "Viikossa",
|
||||
"interest_calc_half-year": "Puolessa vuodessa",
|
||||
"interest_calc_quarterly": "Nelj\u00e4nnest\u00e4 kohden",
|
||||
"spent": "K\u00e4ytetty",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Otsikko"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktiivinen?",
|
||||
"name": "Nimi",
|
||||
"type": "Tyyppi",
|
||||
"number": "Account number",
|
||||
"liability_type": "Lainatyyppi",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Olen velkaa",
|
||||
"liability_direction_credit_short": "Minulle ollaan velkaa",
|
||||
"interest_calc_yearly": "Vuodessa",
|
||||
"interest_calc_": "tuntematon",
|
||||
"interest_calc_daily": "P\u00e4iv\u00e4ss\u00e4",
|
||||
"interest_calc_monthly": "Kuukaudessa",
|
||||
"interest_calc_weekly": "Viikossa",
|
||||
"interest_calc_half-year": "Puolessa vuodessa",
|
||||
"interest_calc_quarterly": "Nelj\u00e4nnest\u00e4 kohden",
|
||||
"spent": "K\u00e4ytetty",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Titre"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Glisser-d\u00e9poser",
|
||||
"active": "Actif ?",
|
||||
"name": "Nom",
|
||||
"type": "Type",
|
||||
"number": "N\u00b0 de compte",
|
||||
"liability_type": "Type de passif",
|
||||
"current_balance": "Solde actuel",
|
||||
"last_activity": "Activit\u00e9 r\u00e9cente",
|
||||
"amount_due": "Montant d\u00fb",
|
||||
"balance_difference": "Diff\u00e9rence de solde",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III ne peut pas d\u00e9terminer le type de transaction bas\u00e9 sur ce compte source.",
|
||||
"bad_type_destination": "Firefly III ne peut pas d\u00e9terminer le type de transaction bas\u00e9 sur ce compte de destination."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Pr\u00eateur",
|
||||
"liability_direction_credit_short": "Emprunteur",
|
||||
"interest_calc_yearly": "Par an",
|
||||
"interest_calc_": "inconnu",
|
||||
"interest_calc_daily": "Par jour",
|
||||
"interest_calc_monthly": "Par mois",
|
||||
"interest_calc_weekly": "Par semaine",
|
||||
"interest_calc_half-year": "Par semestre",
|
||||
"interest_calc_quarterly": "Par trimestre",
|
||||
"spent": "D\u00e9pens\u00e9",
|
||||
"administration_owner": "Propri\u00e9taire de l'administration : {{email}}",
|
||||
"administration_you": "Votre r\u00f4le : {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Titre"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Glisser-d\u00e9poser",
|
||||
"active": "Actif ?",
|
||||
"name": "Nom",
|
||||
"type": "Type",
|
||||
"number": "N\u00b0 de compte",
|
||||
"liability_type": "Type de passif",
|
||||
"current_balance": "Solde actuel",
|
||||
"last_activity": "Activit\u00e9 r\u00e9cente",
|
||||
"amount_due": "Montant d\u00fb",
|
||||
"balance_difference": "Diff\u00e9rence de solde",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III ne peut pas d\u00e9terminer le type de transaction bas\u00e9 sur ce compte source.",
|
||||
"bad_type_destination": "Firefly III ne peut pas d\u00e9terminer le type de transaction bas\u00e9 sur ce compte de destination."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Pr\u00eateur",
|
||||
"liability_direction_credit_short": "Emprunteur",
|
||||
"interest_calc_yearly": "Par an",
|
||||
"interest_calc_": "inconnu",
|
||||
"interest_calc_daily": "Par jour",
|
||||
"interest_calc_monthly": "Par mois",
|
||||
"interest_calc_weekly": "Par semaine",
|
||||
"interest_calc_half-year": "Par semestre",
|
||||
"interest_calc_quarterly": "Par trimestre",
|
||||
"spent": "D\u00e9pens\u00e9",
|
||||
"administration_owner": "Propri\u00e9taire de l'administration : {{email}}",
|
||||
"administration_you": "Votre r\u00f4le : {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "C\u00edm"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Akt\u00edv?",
|
||||
"name": "N\u00e9v",
|
||||
"type": "T\u00edpus",
|
||||
"number": "Account number",
|
||||
"liability_type": "A k\u00f6telezetts\u00e9g t\u00edpusa",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "A Firefly III nem tudja eld\u00f6nteni a tranzakci\u00f3 t\u00edpus\u00e1t a forr\u00e1ssz\u00e1mla alapj\u00e1n.",
|
||||
"bad_type_destination": "A Firefly III nem tudja eld\u00f6nteni a tranzakci\u00f3 t\u00edpus\u00e1t a c\u00e9lsz\u00e1mla alapj\u00e1n."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "\u00c9vente",
|
||||
"interest_calc_": "ismeretlen",
|
||||
"interest_calc_daily": "Naponta",
|
||||
"interest_calc_monthly": "Havonta",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Elk\u00f6lt\u00f6tt",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "C\u00edm"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Akt\u00edv?",
|
||||
"name": "N\u00e9v",
|
||||
"type": "T\u00edpus",
|
||||
"number": "Account number",
|
||||
"liability_type": "A k\u00f6telezetts\u00e9g t\u00edpusa",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "A Firefly III nem tudja eld\u00f6nteni a tranzakci\u00f3 t\u00edpus\u00e1t a forr\u00e1ssz\u00e1mla alapj\u00e1n.",
|
||||
"bad_type_destination": "A Firefly III nem tudja eld\u00f6nteni a tranzakci\u00f3 t\u00edpus\u00e1t a c\u00e9lsz\u00e1mla alapj\u00e1n."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "\u00c9vente",
|
||||
"interest_calc_": "ismeretlen",
|
||||
"interest_calc_daily": "Naponta",
|
||||
"interest_calc_monthly": "Havonta",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Elk\u00f6lt\u00f6tt",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Judul"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktif?",
|
||||
"name": "Nama",
|
||||
"type": "Jenis",
|
||||
"number": "Account number",
|
||||
"liability_type": "Jenis kewajiban",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Per year",
|
||||
"interest_calc_": "unknown",
|
||||
"interest_calc_daily": "Per day",
|
||||
"interest_calc_monthly": "Per month",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Menghabiskan",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Judul"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Aktif?",
|
||||
"name": "Nama",
|
||||
"type": "Jenis",
|
||||
"number": "Account number",
|
||||
"liability_type": "Jenis kewajiban",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Owed this debt",
|
||||
"interest_calc_yearly": "Per year",
|
||||
"interest_calc_": "unknown",
|
||||
"interest_calc_daily": "Per day",
|
||||
"interest_calc_monthly": "Per month",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half year",
|
||||
"interest_calc_quarterly": "Per quarter",
|
||||
"spent": "Menghabiskan",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -4,23 +4,45 @@
|
||||
"date_time_fns": "do MMMM yyyy @ HH:mm:ss",
|
||||
"month_and_day_fns": "d MMMM y",
|
||||
"does_not_exist": "(config.does_not_exist)",
|
||||
"date_time_fns_short": "MMMM do, yyyy @ HH:mm"
|
||||
"date_time_fns_short": "do MMMM yyyy @ HH:mm"
|
||||
},
|
||||
"form": {
|
||||
"title": "Titolo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Attivo",
|
||||
"name": "Nome",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"liability_type": "Tipo di passivit\u00e0",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III non pu\u00f2 determinare il tipo di transazione in base a questo account sorgente.",
|
||||
"bad_type_destination": "Firefly III non pu\u00f2 determinare il tipo di transazione in base a questo account di destinazione."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Devo questo debito",
|
||||
"liability_direction_credit_short": "Mi devono questo debito",
|
||||
"interest_calc_yearly": "All'anno",
|
||||
"interest_calc_": "sconosciuto",
|
||||
"interest_calc_daily": "Al giorno",
|
||||
"interest_calc_monthly": "Al mese",
|
||||
"interest_calc_weekly": "Settimanale",
|
||||
"interest_calc_half-year": "Semestrale",
|
||||
"interest_calc_quarterly": "Trimestrale",
|
||||
"spent": "Speso",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_ro": "Read-only",
|
||||
"administration_role_mng_trx": "Manage transactions",
|
||||
"administration_role_mng_meta": "Manage classification and meta-data",
|
||||
"administration_role_owner": "Proprietario",
|
||||
"administration_role_ro": "Sola lettura",
|
||||
"administration_role_mng_trx": "Gestisci le transazioni",
|
||||
"administration_role_mng_meta": "Gestisci classificazione e meta-dati",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_piggies": "Manage piggy banks",
|
||||
"administration_role_mng_subscriptions": "Manage subscriptions",
|
||||
@@ -48,7 +70,7 @@
|
||||
"unknown_dest_plain": "Conto di destinazione sconosciuto",
|
||||
"unknown_any_plain": "Conto sconosciuto",
|
||||
"unknown_budget_plain": "Nessun budget",
|
||||
"stored_journal_js": "Successfully created new transaction \"{{description}}\"",
|
||||
"stored_journal_js": "Nuova transazione \"{{description}} \" creata con successo",
|
||||
"wait_loading_transaction": "Attendi il caricamento del modello",
|
||||
"nothing_found": "(nessun risultato)",
|
||||
"wait_loading_data": "Ti preghiamo di attendere il caricamento delle tue informazioni...",
|
||||
|
@@ -4,23 +4,45 @@
|
||||
"date_time_fns": "do MMMM yyyy @ HH:mm:ss",
|
||||
"month_and_day_fns": "d MMMM y",
|
||||
"does_not_exist": "(config.does_not_exist)",
|
||||
"date_time_fns_short": "MMMM do, yyyy @ HH:mm"
|
||||
"date_time_fns_short": "do MMMM yyyy @ HH:mm"
|
||||
},
|
||||
"form": {
|
||||
"title": "Titolo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Attivo",
|
||||
"name": "Nome",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"liability_type": "Tipo di passivit\u00e0",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III non pu\u00f2 determinare il tipo di transazione in base a questo account sorgente.",
|
||||
"bad_type_destination": "Firefly III non pu\u00f2 determinare il tipo di transazione in base a questo account di destinazione."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Devo questo debito",
|
||||
"liability_direction_credit_short": "Mi devono questo debito",
|
||||
"interest_calc_yearly": "All'anno",
|
||||
"interest_calc_": "sconosciuto",
|
||||
"interest_calc_daily": "Al giorno",
|
||||
"interest_calc_monthly": "Al mese",
|
||||
"interest_calc_weekly": "Settimanale",
|
||||
"interest_calc_half-year": "Semestrale",
|
||||
"interest_calc_quarterly": "Trimestrale",
|
||||
"spent": "Speso",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_ro": "Read-only",
|
||||
"administration_role_mng_trx": "Manage transactions",
|
||||
"administration_role_mng_meta": "Manage classification and meta-data",
|
||||
"administration_role_owner": "Proprietario",
|
||||
"administration_role_ro": "Sola lettura",
|
||||
"administration_role_mng_trx": "Gestisci le transazioni",
|
||||
"administration_role_mng_meta": "Gestisci classificazione e meta-dati",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_piggies": "Manage piggy banks",
|
||||
"administration_role_mng_subscriptions": "Manage subscriptions",
|
||||
@@ -48,7 +70,7 @@
|
||||
"unknown_dest_plain": "Conto di destinazione sconosciuto",
|
||||
"unknown_any_plain": "Conto sconosciuto",
|
||||
"unknown_budget_plain": "Nessun budget",
|
||||
"stored_journal_js": "Successfully created new transaction \"{{description}}\"",
|
||||
"stored_journal_js": "Nuova transazione \"{{description}} \" creata con successo",
|
||||
"wait_loading_transaction": "Attendi il caricamento del modello",
|
||||
"nothing_found": "(nessun risultato)",
|
||||
"wait_loading_data": "Ti preghiamo di attendere il caricamento delle tue informazioni...",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\u30bf\u30a4\u30c8\u30eb"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u6709\u52b9",
|
||||
"name": "\u540d\u79f0",
|
||||
"type": "\u7a2e\u5225",
|
||||
"number": "Account number",
|
||||
"liability_type": "\u50b5\u52d9\u7a2e\u5225",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\u3053\u306e\u8ca0\u50b5\u3092\u8ca0\u3046",
|
||||
"liability_direction_credit_short": "\u3053\u306e\u8ca0\u50b5\u3092\u8ca0\u3063\u3066\u3044\u308b",
|
||||
"interest_calc_yearly": "1\u5e74\u3042\u305f\u308a",
|
||||
"interest_calc_": "\u4e0d\u660e",
|
||||
"interest_calc_daily": "1\u65e5\u3042\u305f\u308a",
|
||||
"interest_calc_monthly": "1\u30f6\u6708\u3042\u305f\u308a",
|
||||
"interest_calc_weekly": "1\u9031\u3042\u305f\u308a",
|
||||
"interest_calc_half-year": "\u534a\u5e74\u3042\u305f\u308a",
|
||||
"interest_calc_quarterly": "\u56db\u534a\u671f\u3042\u305f\u308a",
|
||||
"spent": "\u652f\u51fa",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\u30bf\u30a4\u30c8\u30eb"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\u6709\u52b9",
|
||||
"name": "\u540d\u79f0",
|
||||
"type": "\u7a2e\u5225",
|
||||
"number": "Account number",
|
||||
"liability_type": "\u50b5\u52d9\u7a2e\u5225",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\u3053\u306e\u8ca0\u50b5\u3092\u8ca0\u3046",
|
||||
"liability_direction_credit_short": "\u3053\u306e\u8ca0\u50b5\u3092\u8ca0\u3063\u3066\u3044\u308b",
|
||||
"interest_calc_yearly": "1\u5e74\u3042\u305f\u308a",
|
||||
"interest_calc_": "\u4e0d\u660e",
|
||||
"interest_calc_daily": "1\u65e5\u3042\u305f\u308a",
|
||||
"interest_calc_monthly": "1\u30f6\u6708\u3042\u305f\u308a",
|
||||
"interest_calc_weekly": "1\u9031\u3042\u305f\u308a",
|
||||
"interest_calc_half-year": "\u534a\u5e74\u3042\u305f\u308a",
|
||||
"interest_calc_quarterly": "\u56db\u534a\u671f\u3042\u305f\u308a",
|
||||
"spent": "\u652f\u51fa",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\uc81c\ubaa9"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\ud65c\uc131 \uc0c1\ud0dc\uc785\ub2c8\uae4c?",
|
||||
"name": "\uc774\ub984",
|
||||
"type": "\uc720\ud615",
|
||||
"number": "Account number",
|
||||
"liability_type": "\ubd80\ucc44 \uc720\ud615",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\uc774 \ube5a\uc744 \uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4",
|
||||
"liability_direction_credit_short": "\uc774 \ube5a\uc744 \uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4",
|
||||
"interest_calc_yearly": "\uc5f0\uac04",
|
||||
"interest_calc_": "\uc54c \uc218 \uc5c6\uc74c",
|
||||
"interest_calc_daily": "\uc77c\ubcc4",
|
||||
"interest_calc_monthly": "\uc6d4\ubcc4",
|
||||
"interest_calc_weekly": "\uc8fc\ub2f9",
|
||||
"interest_calc_half-year": "\ubc18\uae30\ub2f9",
|
||||
"interest_calc_quarterly": "\ubd84\uae30\ub2f9",
|
||||
"spent": "\uc9c0\ucd9c",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "\uc81c\ubaa9"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "\ud65c\uc131 \uc0c1\ud0dc\uc785\ub2c8\uae4c?",
|
||||
"name": "\uc774\ub984",
|
||||
"type": "\uc720\ud615",
|
||||
"number": "Account number",
|
||||
"liability_type": "\ubd80\ucc44 \uc720\ud615",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "\uc774 \ube5a\uc744 \uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4",
|
||||
"liability_direction_credit_short": "\uc774 \ube5a\uc744 \uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4",
|
||||
"interest_calc_yearly": "\uc5f0\uac04",
|
||||
"interest_calc_": "\uc54c \uc218 \uc5c6\uc74c",
|
||||
"interest_calc_daily": "\uc77c\ubcc4",
|
||||
"interest_calc_monthly": "\uc6d4\ubcc4",
|
||||
"interest_calc_weekly": "\uc8fc\ub2f9",
|
||||
"interest_calc_half-year": "\ubc18\uae30\ub2f9",
|
||||
"interest_calc_quarterly": "\ubd84\uae30\ub2f9",
|
||||
"spent": "\uc9c0\ucd9c",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Tittel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Er aktiv?",
|
||||
"name": "Navn",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type gjeld",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Skylder denne gjelden",
|
||||
"liability_direction_credit_short": "Jeg skuldet denne gjelden",
|
||||
"interest_calc_yearly": "Per \u00e5r",
|
||||
"interest_calc_": "ukjent",
|
||||
"interest_calc_daily": "Per dag",
|
||||
"interest_calc_monthly": "Per m\u00e5ned",
|
||||
"interest_calc_weekly": "Per uke",
|
||||
"interest_calc_half-year": "Per halv\u00e5r",
|
||||
"interest_calc_quarterly": "Per kvartal",
|
||||
"spent": "Brukt",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Tittel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Er aktiv?",
|
||||
"name": "Navn",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type gjeld",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Skylder denne gjelden",
|
||||
"liability_direction_credit_short": "Jeg skuldet denne gjelden",
|
||||
"interest_calc_yearly": "Per \u00e5r",
|
||||
"interest_calc_": "ukjent",
|
||||
"interest_calc_daily": "Per dag",
|
||||
"interest_calc_monthly": "Per m\u00e5ned",
|
||||
"interest_calc_weekly": "Per uke",
|
||||
"interest_calc_half-year": "Per halv\u00e5r",
|
||||
"interest_calc_quarterly": "Per kvartal",
|
||||
"spent": "Brukt",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Titel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Actief?",
|
||||
"name": "Naam",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type passiva",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III kan het transactietype niet bepalen op basis van deze bronrekening.",
|
||||
"bad_type_destination": "Firefly III kan het transactietype niet bepalen op basis van deze doelrekening."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Schuldenaar",
|
||||
"liability_direction_credit_short": "Schuldeiser",
|
||||
"interest_calc_yearly": "Per jaar",
|
||||
"interest_calc_": "onbekend",
|
||||
"interest_calc_daily": "Per dag",
|
||||
"interest_calc_monthly": "Per maand",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half jaar",
|
||||
"interest_calc_quarterly": "Per kwartaal",
|
||||
"spent": "Uitgegeven",
|
||||
"administration_owner": "Grootboekeigenaar: {{email}}",
|
||||
"administration_you": "Jouw rol: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Titel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Actief?",
|
||||
"name": "Naam",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type passiva",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III kan het transactietype niet bepalen op basis van deze bronrekening.",
|
||||
"bad_type_destination": "Firefly III kan het transactietype niet bepalen op basis van deze doelrekening."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Schuldenaar",
|
||||
"liability_direction_credit_short": "Schuldeiser",
|
||||
"interest_calc_yearly": "Per jaar",
|
||||
"interest_calc_": "onbekend",
|
||||
"interest_calc_daily": "Per dag",
|
||||
"interest_calc_monthly": "Per maand",
|
||||
"interest_calc_weekly": "Per week",
|
||||
"interest_calc_half-year": "Per half jaar",
|
||||
"interest_calc_quarterly": "Per kwartaal",
|
||||
"spent": "Uitgegeven",
|
||||
"administration_owner": "Grootboekeigenaar: {{email}}",
|
||||
"administration_you": "Jouw rol: {{role}}",
|
||||
|
@@ -9,11 +9,33 @@
|
||||
"form": {
|
||||
"title": "Tittel"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"active": "Er aktiv?",
|
||||
"name": "Namn",
|
||||
"type": "Type",
|
||||
"number": "Account number",
|
||||
"liability_type": "Type gjeld",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III can't determine the transaction type based on this source account.",
|
||||
"bad_type_destination": "Firefly III can't determine the transaction type based on this destination account."
|
||||
},
|
||||
"firefly": {
|
||||
"liability_direction_debit_short": "Owe this debt",
|
||||
"liability_direction_credit_short": "Jeg skuldet denne gjelda",
|
||||
"interest_calc_yearly": "Per \u00e5r",
|
||||
"interest_calc_": "ukjent",
|
||||
"interest_calc_daily": "Per dag",
|
||||
"interest_calc_monthly": "Per m\u00e5nad",
|
||||
"interest_calc_weekly": "Per veke",
|
||||
"interest_calc_half-year": "Per halv\u00e5r",
|
||||
"interest_calc_quarterly": "Per kvartal",
|
||||
"spent": "Brukt",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user