mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-29 17:25:20 +00:00
Compare commits
125 Commits
develop-20
...
v6.1.13
Author | SHA1 | Date | |
---|---|---|---|
|
bfa1fcbaf8 | ||
|
56243907c4 | ||
|
5928dd72e6 | ||
|
c6bf0ff1cd | ||
|
19d1cf192b | ||
|
37d7dc7e3e | ||
|
95a3a194b8 | ||
|
3542387188 | ||
|
da1b002a64 | ||
|
46daee28e7 | ||
|
9ade5635d4 | ||
|
e14e80f33c | ||
|
0c824e21c8 | ||
|
fab1c68569 | ||
|
c1534657f2 | ||
|
39841de680 | ||
|
43a720b62b | ||
|
5ec54de29e | ||
|
397e37f344 | ||
|
b6f84c2b99 | ||
|
843f86fc66 | ||
|
0e8e364074 | ||
|
bbccbef578 | ||
|
ee11a8e3a0 | ||
|
e8618047bd | ||
|
f104b76f73 | ||
|
cb701d8506 | ||
|
70a334c56e | ||
|
e6b2db1e29 | ||
|
e8dffa0052 | ||
|
c4f0512f39 | ||
|
3268019d0c | ||
|
a0ef6a1fc8 | ||
|
99d0098b20 | ||
|
a7a54c042c | ||
|
c44e48a793 | ||
|
53b501ca73 | ||
|
322f70bcca | ||
|
35559c077b | ||
|
590ffe7c76 | ||
|
8a2d8f148e | ||
|
4f0e15e07d | ||
|
7463861e0c | ||
|
1e70fa28be | ||
|
26c6ca470b | ||
|
5e54034e0e | ||
|
25873ef734 | ||
|
1092b04b22 | ||
|
01ce74dd72 | ||
|
41430d8386 | ||
|
01eb19169c | ||
|
cfaa7d7c68 | ||
|
14d3312a10 | ||
|
87be478dd8 | ||
|
0b6877a20e | ||
|
7186f0ef60 | ||
|
538933691e | ||
|
46c49ddbd8 | ||
|
bcfb134b6e | ||
|
57981f1cf9 | ||
|
0310186fb7 | ||
|
4dcb38290e | ||
|
2f5c37048b | ||
|
370c8b16ae | ||
|
af0555592a | ||
|
9c07ddaed6 | ||
|
bb7355a566 | ||
|
1d48347f8c | ||
|
060b76ca9c | ||
|
2b2b9b6f7a | ||
|
f3dd05a0c0 | ||
|
47a91aa273 | ||
|
41bc236603 | ||
|
65349451ea | ||
|
e77b6a55a4 | ||
|
2379bcff11 | ||
|
7133156fa1 | ||
|
a59176689d | ||
|
bc2d8f3dfb | ||
|
ddf89a9d5a | ||
|
7daaba17f6 | ||
|
9cb5b1384f | ||
|
7d13263482 | ||
|
d9ff252915 | ||
|
51ba550251 | ||
|
fd21c467ad | ||
|
9aa90650b4 | ||
|
d892257e8b | ||
|
db0dbcfcf1 | ||
|
f591996f04 | ||
|
b08d385586 | ||
|
20ef22f67e | ||
|
c888baf542 | ||
|
8b0af3f666 | ||
|
7043e1e7c0 | ||
|
c5854eba23 | ||
|
ddf1a8cebb | ||
|
7dcaf167e9 | ||
|
b359d51d3a | ||
|
3913fa5086 | ||
|
ab2772abe0 | ||
|
bc7875b17b | ||
|
4938fa9990 | ||
|
84df2c80ee | ||
|
dc17060754 | ||
|
e2fa81dddc | ||
|
182dfc95fe | ||
|
c8979b6c33 | ||
|
ab872e8912 | ||
|
d36b94fabf | ||
|
e3d4ceaecb | ||
|
e3a6e5b788 | ||
|
57235c0e00 | ||
|
2298c3ddaf | ||
|
7224f1be6f | ||
|
1bd3019c16 | ||
|
f0fa21dead | ||
|
845eaed8d7 | ||
|
b3649cd4d0 | ||
|
55f14c587b | ||
|
441a8a8408 | ||
|
060c9648f1 | ||
|
7680c8733f | ||
|
5a0af5c93b | ||
|
f4b066add1 |
40
.ci/php-cs-fixer/composer.lock
generated
40
.ci/php-cs-fixer/composer.lock
generated
@@ -8,16 +8,16 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.1.2",
|
||||
"version": "3.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace"
|
||||
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/4775f35b2d70865807c89d32c8e7385b86eb0ace",
|
||||
"reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||
"reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -59,7 +59,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.1.2"
|
||||
"source": "https://github.com/composer/pcre/tree/3.1.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -75,7 +75,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-07T15:38:35+00:00"
|
||||
"time": "2024-03-19T10:26:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/semver",
|
||||
@@ -160,16 +160,16 @@
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
"version": "3.0.3",
|
||||
"version": "3.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/xdebug-handler.git",
|
||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c"
|
||||
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
|
||||
"reference": "ced299686f41dce890debac69273b47ffe98a40c",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -180,7 +180,7 @@
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.1",
|
||||
"symfony/phpunit-bridge": "^6.0"
|
||||
"phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -204,9 +204,9 @@
|
||||
"performance"
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"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.3"
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -222,20 +222,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-25T21:32:43+00:00"
|
||||
"time": "2024-03-26T18:29:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.51.0",
|
||||
"version": "v3.52.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "127fa74f010da99053e3f5b62672615b72dd6efd"
|
||||
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/127fa74f010da99053e3f5b62672615b72dd6efd",
|
||||
"reference": "127fa74f010da99053e3f5b62672615b72dd6efd",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/6e77207f0d851862ceeb6da63e6e22c01b1587bc",
|
||||
"reference": "6e77207f0d851862ceeb6da63e6e22c01b1587bc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -306,7 +306,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.51.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.52.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -314,7 +314,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-02-28T19:50:06+00:00"
|
||||
"time": "2024-03-19T21:02:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
|
10
.env.example
10
.env.example
@@ -111,7 +111,10 @@ PGSQL_SSL_CERT=null
|
||||
PGSQL_SSL_KEY=null
|
||||
PGSQL_SSL_CRL_FILE=null
|
||||
|
||||
# more PostgreSQL settings
|
||||
# For postgresql 15 and up, setting this to public will no longer work as expected, becasuse the
|
||||
# 'public' schema is without grants. This can be worked around by having a super user grant those
|
||||
# necessary privileges, but in security conscious setups that's not viable.
|
||||
# You will need to set this to the schema you want to use.
|
||||
PGSQL_SCHEMA=public
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached or redis
|
||||
@@ -184,6 +187,11 @@ SEND_REPORT_JOURNALS=true
|
||||
# Since this involves an external service, it's optional and disabled by default.
|
||||
ENABLE_EXTERNAL_MAP=false
|
||||
|
||||
#
|
||||
# Enable or disable exchange rate conversion. This function isn't used yet by Firefly III
|
||||
#
|
||||
ENABLE_EXCHANGE_RATES=false
|
||||
|
||||
# Set this value to true if you want Firefly III to download currency exchange rates
|
||||
# from the internet. These rates are hosted by the creator of Firefly III inside
|
||||
# an Azure Storage Container.
|
||||
|
4
.github/funding.yml
vendored
4
.github/funding.yml
vendored
@@ -1,4 +1,6 @@
|
||||
# These are supported funding model platforms
|
||||
# Firefly III sponsor options
|
||||
|
||||
github: jc5
|
||||
patreon: JC5
|
||||
ko_fi: jamesc5
|
||||
liberapay: JC5
|
||||
|
2
.github/workflows/cleanup.yml
vendored
2
.github/workflows/cleanup.yml
vendored
@@ -7,7 +7,7 @@ permissions:
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
- cron: '0 1 * * *'
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
prune:
|
||||
|
9
.github/workflows/lock.yml
vendored
9
.github/workflows/lock.yml
vendored
@@ -3,7 +3,7 @@ name: 'Issues - Lock old issues'
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
concurrency:
|
||||
group: lock-threads
|
||||
@@ -18,11 +18,12 @@ jobs:
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
discussions: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v5
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-inactive-days: 7
|
||||
pr-inactive-days: 7
|
||||
issue-inactive-days: 21
|
||||
pr-inactive-days: 21
|
||||
discussion-inactive-days: 21
|
||||
log-output: true
|
||||
|
149
.github/workflows/release.yml
vendored
149
.github/workflows/release.yml
vendored
@@ -4,11 +4,11 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to release'
|
||||
description: 'Release "v1.2.3" or "develop"'
|
||||
required: true
|
||||
default: 'develop'
|
||||
schedule:
|
||||
- cron: '15 0 * * MON,THU'
|
||||
- cron: '0 3 * * MON,THU'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
|
||||
- name: Cleanup translations
|
||||
id: cleanup-transactions
|
||||
uses: JC5/firefly-iii-dev@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
with:
|
||||
action: 'ff3:crowdin-warning'
|
||||
output: ''
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
GH_TOKEN: ''
|
||||
- name: Cleanup changelog
|
||||
id: cleanup-changelog
|
||||
uses: JC5/firefly-iii-dev@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
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@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
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@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
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@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
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@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
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@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
with:
|
||||
action: 'ff3:code'
|
||||
output: ''
|
||||
@@ -115,12 +115,12 @@ jobs:
|
||||
GH_TOKEN: ''
|
||||
- name: Build new JS
|
||||
run: |
|
||||
pwd
|
||||
npm install
|
||||
npm update
|
||||
npm run build
|
||||
- name: Build old JS
|
||||
id: old-js
|
||||
uses: JC5/firefly-iii-dev@v34
|
||||
uses: JC5/firefly-iii-dev@v36
|
||||
with:
|
||||
action: 'ff3:old-js'
|
||||
output: ''
|
||||
@@ -136,15 +136,51 @@ jobs:
|
||||
.ci/phpcs.sh
|
||||
- name: Release
|
||||
run: |
|
||||
# do some configuration
|
||||
sudo timedatectl set-timezone Europe/Amsterdam
|
||||
git config user.name github-actions
|
||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||
git config advice.addIgnoredFile false
|
||||
|
||||
# set some variables
|
||||
releaseName=$version
|
||||
originalName=$version
|
||||
zipName=FireflyIII-$version.zip
|
||||
tarName=FireflyIII-$version.tar.gz
|
||||
|
||||
# update composer (again)
|
||||
composer validate --strict
|
||||
composer update --no-dev --no-scripts --no-plugins
|
||||
composer dump-autoload
|
||||
|
||||
# if this is a develop build, slightly different variable names.
|
||||
if [[ "develop" == "$version" ]]; then
|
||||
[[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
|
||||
releaseName=$version-$(date +'%Y%m%d')
|
||||
originalName=$releaseName
|
||||
zipName=FireflyIII-develop.zip
|
||||
tarName=FireflyIII-develop.tar.gz
|
||||
fi
|
||||
|
||||
# in both cases, if the release or tag already exists, add ".1" until it no longer exists.
|
||||
tagFound=true
|
||||
tagCount=1
|
||||
while [ "$tagFound" = true ]
|
||||
do
|
||||
if [ $(git tag -l "$releaseName") ]; then
|
||||
echo "Tag $releaseName exists already."
|
||||
releaseName="$originalName"."$tagCount"
|
||||
echo "Tag for release is now $releaseName"
|
||||
tagCount=$((tagCount+1))
|
||||
else
|
||||
echo "Tag $releaseName does not exist, can continue"
|
||||
tagFound=false
|
||||
fi
|
||||
done
|
||||
echo "Will use tag and release name $releaseName."
|
||||
|
||||
# add all content, except output.txt (this contains the changelog and/or the download instructions)
|
||||
echo 'Add all and reset output.txt'
|
||||
git add -A
|
||||
if test -f "output.txt"; then
|
||||
git reset output.txt
|
||||
@@ -152,19 +188,88 @@ jobs:
|
||||
git commit -m "Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true
|
||||
git push
|
||||
|
||||
# zip and tar everything
|
||||
echo 'Zip and tar...'
|
||||
zip -rq $zipName . -x "*.git*" "*.ci*" "*.github*" "*node_modules*" "*output.txt*"
|
||||
touch $tarName
|
||||
tar --exclude=$tarName --exclude='./.git' --exclude='./.ci' --exclude='./.github' --exclude='./node_modules' --exclude='./output.txt' -czf $tarName .
|
||||
|
||||
# add sha256 sum
|
||||
echo 'Sha sum ...'
|
||||
sha256sum -b $zipName > $zipName.sha256
|
||||
sha256sum -b $tarName > $tarName.sha256
|
||||
|
||||
# create a development (nightly) release:
|
||||
if [[ "develop" == "$version" ]]; then
|
||||
echo "Create nightly release."
|
||||
git tag -a $version-$(date +'%Y%m%d') -m "Nightly development release '$version' on $(date +'%Y-%m-%d')"
|
||||
git push origin $version-$(date +'%Y%m%d')
|
||||
gh release create $version-$(date +'%Y%m%d') -p --verify-tag \
|
||||
-t "Development release for $(date +'%Y-%m-%d')" \
|
||||
-n "Bi-weekly development release of Firefly III with the latest fixes, translations and features. This release was created on **$(date +'%Y-%m-%d')** and may contain bugs. Use at your own risk. Docker users can find this release under the \`develop\` tag."
|
||||
else
|
||||
echo "Create default release."
|
||||
git tag -a $version -m "Here be changelog"
|
||||
git push origin $version
|
||||
gh release create $version -F output.txt -t "$version" --verify-tag
|
||||
echo 'Develop release.'
|
||||
# add text to output.txt (instructions)
|
||||
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 "" >> 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
|
||||
echo "" >> output.txt
|
||||
echo ":warning: Please be careful with this pre-release, as is may not work as expected." >> output.txt
|
||||
|
||||
# create the release:
|
||||
echo "Create nightly release."
|
||||
git tag -a $releaseName -m "Nightly development release '$version' on $(date +'%Y-%m-%d')"
|
||||
git push origin $releaseName
|
||||
gh release create $releaseName -p --verify-tag \
|
||||
-t "Development release for $(date +'%Y-%m-%d')" \
|
||||
-F output.txt
|
||||
|
||||
# add zip file to release.
|
||||
gh release upload $releaseName $zipName
|
||||
gh release upload $releaseName $tarName
|
||||
|
||||
# add sha256 sum to release
|
||||
gh release upload $releaseName $zipName.sha256
|
||||
gh release upload $releaseName $tarName.sha256
|
||||
|
||||
# get current HEAD and add as file to the release
|
||||
HEAD=$(git rev-parse HEAD)
|
||||
echo $HEAD > HEAD.txt
|
||||
gh release upload $releaseName HEAD.txt
|
||||
else
|
||||
echo 'MAIN (real) release'
|
||||
sudo chown -R runner:docker output.txt
|
||||
# add text to output.txt (more instructions)
|
||||
echo '' >> output.txt
|
||||
echo '### Instructions' >> output.txt
|
||||
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 "Create default release."
|
||||
git tag -a $releaseName -m "Here be changelog"
|
||||
git push origin $releaseName
|
||||
gh release create $releaseName -F output.txt -t "$releaseName" --verify-tag
|
||||
|
||||
# add archive files to release
|
||||
gh release upload $releaseName $zipName
|
||||
gh release upload $releaseName $tarName
|
||||
|
||||
# add sha256 sums to release
|
||||
gh release upload $releaseName $zipName.sha256
|
||||
gh release upload $releaseName $tarName.sha256
|
||||
|
||||
# get current HEAD and add as file to the release
|
||||
HEAD=$(git rev-parse HEAD)
|
||||
echo $HEAD > HEAD.txt
|
||||
gh release upload $releaseName HEAD.txt
|
||||
|
||||
# remove all temporary files
|
||||
rm output.txt
|
||||
rm HEAD.txt
|
||||
rm $zipName
|
||||
rm $zipName.sha256
|
||||
rm $tarName
|
||||
rm $tarName.sha256
|
||||
|
||||
# merge main back into develop
|
||||
git checkout develop
|
||||
git merge main
|
||||
git push
|
||||
|
10
.github/workflows/stale.yml
vendored
10
.github/workflows/stale.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: "Issues - Mark and close stale issues"
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
- cron: "0 4 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -18,16 +18,16 @@ jobs:
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: >
|
||||
Hi there!
|
||||
|
||||
Hi there!
|
||||
|
||||
This is an automatic reply. `Share and enjoy`
|
||||
|
||||
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
||||
|
||||
Thank you for your contributions.
|
||||
stale-pr-message: >
|
||||
Hi there!
|
||||
|
||||
Hi there!
|
||||
|
||||
This is an automatic reply. `Share and enjoy`
|
||||
|
||||
This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,3 +7,6 @@ yarn-error.log
|
||||
.env
|
||||
/.ci/php-cs-fixer/vendor
|
||||
coverage.xml
|
||||
|
||||
# ignore generated files.
|
||||
public/build
|
||||
|
@@ -281,7 +281,7 @@ class BasicController extends Controller
|
||||
$spentInCurrency = $row['sum'];
|
||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
||||
|
||||
$days = $today->diffInDays($end) + 1;
|
||||
$days = (int)$today->diffInDays($end, true) + 1;
|
||||
$perDay = '0';
|
||||
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
||||
$perDay = bcdiv($leftToSpend, (string)$days);
|
||||
|
@@ -46,7 +46,7 @@ class DateRequest extends FormRequest
|
||||
{
|
||||
$start = $this->getCarbonDate('start');
|
||||
$end = $this->getCarbonDate('end');
|
||||
if ($start->diffInYears($end) > 5) {
|
||||
if ($start->diffInYears($end, true) > 5) {
|
||||
throw new FireflyException('Date range out of range.');
|
||||
}
|
||||
|
||||
|
79
app/Api/V2/Controllers/Model/Account/UpdateController.php
Normal file
79
app/Api/V2/Controllers/Model/Account/UpdateController.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/*
|
||||
* UpdateController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\Account;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\Account\UpdateRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UpdateController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'accounts';
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$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);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this endpoint is not yet reachable.
|
||||
*/
|
||||
public function update(UpdateRequest $request, Account $account): JsonResponse
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
$data = $request->getUpdateData();
|
||||
$data['type'] = config('firefly.shortNamesByFullName.'.$account->accountType->type);
|
||||
$account = $this->repository->update($account, $data);
|
||||
$account->refresh();
|
||||
app('preferences')->mark();
|
||||
|
||||
$transformer = new AccountTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject('accounts', $account, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
@@ -298,7 +298,7 @@ class BasicController extends Controller
|
||||
app('log')->debug(sprintf('Amount left is %s', $left));
|
||||
|
||||
// how much left per day?
|
||||
$days = $today->diffInDays($end) + 1;
|
||||
$days = (int) $today->diffInDays($end, true) + 1;
|
||||
$perDay = '0';
|
||||
$perDayNative = '0';
|
||||
if (0 !== $days && bccomp($left, '0') > -1) {
|
||||
|
73
app/Api/V2/Controllers/UserGroup/IndexController.php
Normal file
73
app/Api/V2/Controllers/UserGroup/IndexController.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/*
|
||||
* IndexController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\UserGroup;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\Account\IndexRequest;
|
||||
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\UserGroupTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
public const string RESOURCE_KEY = 'user_groups';
|
||||
|
||||
private UserGroupRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(UserGroupRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO see autocomplete/accountcontroller for list.
|
||||
*/
|
||||
public function index(IndexRequest $request): JsonResponse
|
||||
{
|
||||
$administrations = $this->repository->get();
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $administrations->count();
|
||||
$administrations = $administrations->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($administrations, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new UserGroupTransformer();
|
||||
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList(self::RESOURCE_KEY, $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE)
|
||||
;
|
||||
}
|
||||
}
|
116
app/Api/V2/Request/Model/Account/UpdateRequest.php
Normal file
116
app/Api/V2/Request/Model/Account/UpdateRequest.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/*
|
||||
* UpdateRequest.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Model\Account;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Location;
|
||||
use FireflyIII\Rules\IsBoolean;
|
||||
use FireflyIII\Rules\UniqueAccountNumber;
|
||||
use FireflyIII\Rules\UniqueIban;
|
||||
use FireflyIII\Support\Request\AppendsLocationData;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateRequest extends FormRequest
|
||||
{
|
||||
use AppendsLocationData;
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
/**
|
||||
* TODO is a duplicate of the v1 update thing.
|
||||
*/
|
||||
public function getUpdateData(): array
|
||||
{
|
||||
$fields = [
|
||||
'name' => ['name', 'convertString'],
|
||||
'active' => ['active', 'boolean'],
|
||||
'include_net_worth' => ['include_net_worth', 'boolean'],
|
||||
'account_type_name' => ['type', 'convertString'],
|
||||
'virtual_balance' => ['virtual_balance', 'convertString'],
|
||||
'iban' => ['iban', 'convertString'],
|
||||
'BIC' => ['bic', 'convertString'],
|
||||
'account_number' => ['account_number', 'convertString'],
|
||||
'account_role' => ['account_role', 'convertString'],
|
||||
'liability_type' => ['liability_type', 'convertString'],
|
||||
'opening_balance' => ['opening_balance', 'convertString'],
|
||||
'opening_balance_date' => ['opening_balance_date', 'convertDateTime'],
|
||||
'cc_type' => ['credit_card_type', 'convertString'],
|
||||
'cc_monthly_payment_date' => ['monthly_payment_date', 'convertDateTime'],
|
||||
'notes' => ['notes', 'stringWithNewlines'],
|
||||
'interest' => ['interest', 'convertString'],
|
||||
'interest_period' => ['interest_period', 'convertString'],
|
||||
'order' => ['order', 'convertInteger'],
|
||||
'currency_id' => ['currency_id', 'convertInteger'],
|
||||
'currency_code' => ['currency_code', 'convertString'],
|
||||
'liability_direction' => ['liability_direction', 'convertString'],
|
||||
'liability_amount' => ['liability_amount', 'convertString'],
|
||||
'liability_start_date' => ['liability_start_date', 'date'],
|
||||
];
|
||||
$data = $this->getAllData($fields);
|
||||
|
||||
return $this->appendLocationData($data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO is a duplicate of the v1 UpdateRequest method.
|
||||
*
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var Account $account */
|
||||
$account = $this->route()->parameter('account');
|
||||
$accountRoles = implode(',', config('firefly.accountRoles'));
|
||||
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
|
||||
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
|
||||
|
||||
$rules = [
|
||||
'name' => sprintf('min:1|max:1024|uniqueAccountForUser:%d', $account->id),
|
||||
'type' => sprintf('in:%s', $types),
|
||||
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->convertString('type'))],
|
||||
'bic' => 'bic|nullable',
|
||||
'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
|
||||
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
|
||||
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
|
||||
'virtual_balance' => 'numeric|nullable',
|
||||
'order' => 'numeric|nullable',
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
'active' => [new IsBoolean()],
|
||||
'include_net_worth' => [new IsBoolean()],
|
||||
'account_role' => sprintf('in:%s|nullable|required_if:type,asset', $accountRoles),
|
||||
'credit_card_type' => sprintf('in:%s|nullable|required_if:account_role,ccAsset', $ccPaymentTypes),
|
||||
'monthly_payment_date' => 'date|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
|
||||
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage',
|
||||
'liability_direction' => 'required_if:type,liability|in:credit,debit',
|
||||
'interest' => 'required_if:type,liability|min:0|max:100|numeric',
|
||||
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
|
||||
'notes' => 'min:0|max:32768',
|
||||
];
|
||||
|
||||
return Location::requestRules($rules);
|
||||
}
|
||||
}
|
@@ -53,40 +53,40 @@ class ForceDecimalSize extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
|
||||
protected $signature = 'firefly-iii:force-decimal-size';
|
||||
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
|
||||
protected $signature = 'firefly-iii:force-decimal-size';
|
||||
private string $cast;
|
||||
private array $classes
|
||||
= [
|
||||
'accounts' => Account::class,
|
||||
'auto_budgets' => AutoBudget::class,
|
||||
'available_budgets' => AvailableBudget::class,
|
||||
'bills' => Bill::class,
|
||||
'budget_limits' => BudgetLimit::class,
|
||||
'piggy_bank_events' => PiggyBankEvent::class,
|
||||
'piggy_bank_repetitions' => PiggyBankRepetition::class,
|
||||
'piggy_banks' => PiggyBank::class,
|
||||
'recurrences_transactions' => RecurrenceTransaction::class,
|
||||
'transactions' => Transaction::class,
|
||||
];
|
||||
= [
|
||||
'accounts' => Account::class,
|
||||
'auto_budgets' => AutoBudget::class,
|
||||
'available_budgets' => AvailableBudget::class,
|
||||
'bills' => Bill::class,
|
||||
'budget_limits' => BudgetLimit::class,
|
||||
'piggy_bank_events' => PiggyBankEvent::class,
|
||||
'piggy_bank_repetitions' => PiggyBankRepetition::class,
|
||||
'piggy_banks' => PiggyBank::class,
|
||||
'recurrences_transactions' => RecurrenceTransaction::class,
|
||||
'transactions' => Transaction::class,
|
||||
];
|
||||
|
||||
private string $operator;
|
||||
private string $regularExpression;
|
||||
private array $tables
|
||||
= [
|
||||
'accounts' => ['virtual_balance'],
|
||||
'auto_budgets' => ['amount'],
|
||||
'available_budgets' => ['amount'],
|
||||
'bills' => ['amount_min', 'amount_max'],
|
||||
'budget_limits' => ['amount'],
|
||||
'currency_exchange_rates' => ['rate', 'user_rate'],
|
||||
'limit_repetitions' => ['amount'],
|
||||
'piggy_bank_events' => ['amount'],
|
||||
'piggy_bank_repetitions' => ['currentamount'],
|
||||
'piggy_banks' => ['targetamount'],
|
||||
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
||||
'transactions' => ['amount', 'foreign_amount'],
|
||||
];
|
||||
= [
|
||||
'accounts' => ['virtual_balance'],
|
||||
'auto_budgets' => ['amount'],
|
||||
'available_budgets' => ['amount'],
|
||||
'bills' => ['amount_min', 'amount_max'],
|
||||
'budget_limits' => ['amount'],
|
||||
'currency_exchange_rates' => ['rate', 'user_rate'],
|
||||
'limit_repetitions' => ['amount'],
|
||||
'piggy_bank_events' => ['amount'],
|
||||
'piggy_bank_repetitions' => ['currentamount'],
|
||||
'piggy_banks' => ['targetamount'],
|
||||
'recurrences_transactions' => ['amount', 'foreign_amount'],
|
||||
'transactions' => ['amount', 'foreign_amount'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
|
65
app/Console/Commands/System/LaravelPassportKeys.php
Normal file
65
app/Console/Commands/System/LaravelPassportKeys.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* LaravelPassportKeys.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Symfony\Component\Console\Command\Command as CommandAlias;
|
||||
|
||||
class LaravelPassportKeys extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:laravel-passport-keys';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Calls the Laravel "passport:keys" but doesn\'t exit 1.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Artisan::call('passport:keys --no-interaction', []);
|
||||
$result = Artisan::output();
|
||||
if (str_contains($result, 'Encryption keys already exist')) {
|
||||
$this->friendlyInfo('Encryption keys exist already.');
|
||||
|
||||
return CommandAlias::SUCCESS;
|
||||
}
|
||||
$this->friendlyPositive('Encryption keys have been created, nice!');
|
||||
|
||||
return CommandAlias::SUCCESS;
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
/*
|
||||
* ApplyRules.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -16,7 +16,7 @@
|
||||
* 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/>.
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
/*
|
||||
* Cron.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -17,7 +17,7 @@
|
||||
* 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/>.
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
@@ -110,7 +110,7 @@ class AppendBudgetLimitPeriods extends Command
|
||||
return 'daily';
|
||||
}
|
||||
// is weekly
|
||||
if ('1' === $limit->start_date->format('N') && '7' === $limit->end_date->format('N') && 6 === $limit->end_date->diffInDays($limit->start_date)) {
|
||||
if ('1' === $limit->start_date->format('N') && '7' === $limit->end_date->format('N') && 6 === (int)$limit->end_date->diffInDays($limit->start_date, true)) {
|
||||
return 'weekly';
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ class AppendBudgetLimitPeriods extends Command
|
||||
if (
|
||||
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
|
||||
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
|
||||
&& 2 === $limit->start_date->diffInMonths($limit->end_date)
|
||||
&& 2 === (int)$limit->start_date->diffInMonths($limit->end_date, true)
|
||||
) {
|
||||
return 'quarterly';
|
||||
}
|
||||
@@ -139,7 +139,7 @@ class AppendBudgetLimitPeriods extends Command
|
||||
if (
|
||||
in_array($limit->start_date->format('j-n'), $start, true) // start of quarter
|
||||
&& in_array($limit->end_date->format('j-n'), $end, true) // end of quarter
|
||||
&& 5 === $limit->start_date->diffInMonths($limit->end_date)
|
||||
&& 5 === (int)$limit->start_date->diffInMonths($limit->end_date, true)
|
||||
) {
|
||||
return 'half_year';
|
||||
}
|
||||
|
182
app/Console/Commands/Upgrade/MigrateRuleActions.php
Normal file
182
app/Console/Commands/Upgrade/MigrateRuleActions.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* MigrateRuleActions.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class MigrateRuleActions extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
|
||||
public const string CONFIG_NAME = '610_migrate_rule_actions';
|
||||
|
||||
protected $description = 'Migrate rule actions away from expression engine';
|
||||
|
||||
protected $signature = 'firefly-iii:migrate-rule-actions {--F|force : Force the execution of this command.}';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->friendlyInfo('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (false === config('firefly.feature_flags.expression_engine')) {
|
||||
$this->friendlyInfo('Expression engine is not enabled. Nothing to do.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
$this->replaceEqualSign();
|
||||
$this->replaceObsoleteActions();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function isExecuted(): bool
|
||||
{
|
||||
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
|
||||
if (null !== $configVar) {
|
||||
return (bool)$configVar->data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function replaceEqualSign(): void
|
||||
{
|
||||
$count = 0;
|
||||
$actions = RuleAction::get();
|
||||
|
||||
/** @var RuleAction $action */
|
||||
foreach ($actions as $action) {
|
||||
if (str_starts_with($action->action_value, '=')) {
|
||||
$action->action_value = sprintf('%s%s', '\=', substr($action->action_value, 1));
|
||||
$action->save();
|
||||
++$count;
|
||||
}
|
||||
}
|
||||
if ($count > 0) {
|
||||
$this->friendlyInfo(sprintf('Upgrading %d rule action(s) for the new expression engine.', $count));
|
||||
}
|
||||
if (0 === $count) {
|
||||
$this->friendlyInfo('All rule actions are up to date.');
|
||||
}
|
||||
}
|
||||
|
||||
private function replaceObsoleteActions(): void
|
||||
{
|
||||
$obsolete = [
|
||||
'append_description',
|
||||
'prepend_description',
|
||||
'append_notes',
|
||||
'prepend_notes',
|
||||
'append_descr_to_notes',
|
||||
'append_notes_to_descr',
|
||||
'move_descr_to_notes',
|
||||
'move_notes_to_descr',
|
||||
];
|
||||
$actions = RuleAction::whereIn('action_type', $obsolete)->get();
|
||||
|
||||
/** @var RuleAction $action */
|
||||
foreach ($actions as $action) {
|
||||
$oldType = $action->action_type;
|
||||
|
||||
switch ($action->action_type) {
|
||||
default:
|
||||
$this->friendlyError(sprintf('Cannot deal with action type "%s", skip it.', $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'append_description':
|
||||
$action->action_type = 'set_description';
|
||||
$action->action_value = sprintf('=description~"%s"', str_replace('"', '\"', $action->action_value));
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'prepend_description':
|
||||
$action->action_type = 'set_description';
|
||||
$action->action_value = sprintf('="%s"~description', str_replace('"', '\"', $action->action_value));
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'append_notes':
|
||||
$action->action_type = 'set_notes';
|
||||
$action->action_value = sprintf('=notes~"%s"', str_replace('"', '\"', $action->action_value));
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'prepend_notes':
|
||||
$action->action_type = 'set_notes';
|
||||
$action->action_value = sprintf('="%s"~notes', str_replace('"', '\"', $action->action_value));
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'append_descr_to_notes':
|
||||
$action->action_type = 'set_notes';
|
||||
$action->action_value = '=notes~" "~description';
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'append_notes_to_descr':
|
||||
$action->action_type = 'set_description';
|
||||
$action->action_value = '=description~" "~notes';
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'move_descr_to_notes':
|
||||
$action->action_type = 'set_notes';
|
||||
$action->action_value = '=description';
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
|
||||
case 'move_notes_to_descr':
|
||||
$action->action_type = 'set_description';
|
||||
$action->action_value = '=notes';
|
||||
$action->save();
|
||||
$this->friendlyInfo(sprintf('Upgraded action #%d from "%s" to "%s".', $action->id, $oldType, $action->action_type));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -63,6 +63,7 @@ class UpgradeDatabase extends Command
|
||||
'firefly-iii:upgrade-liabilities',
|
||||
'firefly-iii:liabilities-600',
|
||||
'firefly-iii:budget-limit-periods',
|
||||
'firefly-iii:migrate-rule-actions',
|
||||
'firefly-iii:restore-oauth-keys',
|
||||
// also just in case, some integrity commands:
|
||||
'firefly-iii:create-group-memberships',
|
||||
|
@@ -26,11 +26,11 @@ class UpgradeSkeleton extends Command
|
||||
{
|
||||
$start = microtime(true);
|
||||
if ($this->isExecuted() && true !== $this->option('force')) {
|
||||
$this->info('FRIENDLY This command has already been executed.');
|
||||
$this->friendlyInfo('This command has already been executed.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
$this->warn('Congrats, you found the skeleton command. Boo!');
|
||||
$this->friendlyWarning('Congrats, you found the skeleton command. Boo!');
|
||||
|
||||
//$this->markAsExecuted();
|
||||
|
||||
|
@@ -41,7 +41,6 @@ enum UserRoleEnum: string
|
||||
// manage other financial objects:
|
||||
case MANAGE_BUDGETS = 'mng_budgets';
|
||||
case MANAGE_PIGGY_BANKS = 'mng_piggies';
|
||||
case MANAGE_REPETITIONS = 'mng_reps';
|
||||
case MANAGE_SUBSCRIPTIONS = 'mng_subscriptions';
|
||||
case MANAGE_RULES = 'mng_rules';
|
||||
case MANAGE_RECURRING = 'mng_recurring';
|
||||
@@ -51,7 +50,7 @@ enum UserRoleEnum: string
|
||||
// view and generate reports
|
||||
case VIEW_REPORTS = 'view_reports';
|
||||
|
||||
// view memberships. needs FULL to manage them.
|
||||
// view memberships AND roles. needs FULL to manage them.
|
||||
case VIEW_MEMBERSHIPS = 'view_memberships';
|
||||
|
||||
// everything the creator can, except remove/change original creator and delete group
|
||||
|
@@ -40,12 +40,12 @@ class ReportGeneratorFactory
|
||||
{
|
||||
$period = 'Month';
|
||||
// more than two months date difference means year report.
|
||||
if ($start->diffInMonths($end) > 1) {
|
||||
if ($start->diffInMonths($end, true) > 1) {
|
||||
$period = 'Year';
|
||||
}
|
||||
|
||||
// more than one year date difference means multi year report.
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
// more than one year date difference means multi-year report.
|
||||
if ($start->diffInMonths($end, true) > 12) {
|
||||
$period = 'MultiYear';
|
||||
}
|
||||
|
||||
|
@@ -405,7 +405,7 @@ class UserEventHandler
|
||||
}
|
||||
// clean up old entries (6 months)
|
||||
$carbon = Carbon::createFromFormat('Y-m-d H:i:s', $preference[$index]['time']);
|
||||
if (false !== $carbon && $carbon->diffInMonths(today()) > 6) {
|
||||
if (false !== $carbon && $carbon->diffInMonths(today(), true) > 6) {
|
||||
app('log')->debug(sprintf('Entry for %s is very old, remove it.', $row['ip']));
|
||||
unset($preference[$index]);
|
||||
}
|
||||
|
@@ -236,7 +236,9 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
$fileObject->rewind();
|
||||
|
||||
if (0 === $file->getSize()) {
|
||||
throw new FireflyException('Cannot upload empty or non-existent file.');
|
||||
$this->errors->add('attachments', trans('validation.file_zero_length'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$content = (string)$fileObject->fread($file->getSize());
|
||||
|
@@ -75,7 +75,7 @@ class ReconcileController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
* */
|
||||
public function reconcile(Account $account, Carbon $start = null, Carbon $end = null)
|
||||
public function reconcile(Account $account, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
if (!$this->isEditableAccount($account)) {
|
||||
return $this->redirectAccountToAccount($account);
|
||||
|
@@ -75,7 +75,7 @@ class ShowController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
* */
|
||||
public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null)
|
||||
public function show(Request $request, Account $account, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
$objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
|
||||
|
||||
|
@@ -235,12 +235,12 @@ class BudgetLimitController extends Controller
|
||||
new Collection([$budgetLimit->budget]),
|
||||
$budgetLimit->transactionCurrency
|
||||
);
|
||||
$daysLeft = $this->activeDaysLeft($limit->start_date, $limit->end_date);
|
||||
$array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0';
|
||||
$array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
|
||||
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
|
||||
$array['days_left'] = (string)$this->activeDaysLeft($limit->start_date, $limit->end_date);
|
||||
// left per day:
|
||||
$array['left_per_day'] = bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
|
||||
$array['days_left'] = (string)$daysLeft;
|
||||
$array['left_per_day'] = 0 === $daysLeft ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
|
||||
|
||||
// left per day formatted.
|
||||
$array['amount'] = app('steam')->bcround($limit['amount'], $limit->transactionCurrency->decimal_places);
|
||||
|
@@ -85,7 +85,7 @@ class IndexController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
* */
|
||||
public function index(Carbon $start = null, Carbon $end = null)
|
||||
public function index(?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
$this->abRepository->cleanup();
|
||||
app('log')->debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
|
||||
|
@@ -75,7 +75,7 @@ class ShowController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function noBudget(Request $request, Carbon $start = null, Carbon $end = null)
|
||||
public function noBudget(Request $request, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
// @var Carbon $start
|
||||
$start ??= session('start');
|
||||
|
@@ -70,7 +70,7 @@ class NoCategoryController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function show(Request $request, Carbon $start = null, Carbon $end = null)
|
||||
public function show(Request $request, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
app('log')->debug('Start of noCategory()');
|
||||
// @var Carbon $start
|
||||
|
@@ -71,7 +71,7 @@ class ShowController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function show(Request $request, Category $category, Carbon $start = null, Carbon $end = null)
|
||||
public function show(Request $request, Category $category, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
// @var Carbon $start
|
||||
$start ??= session('start', today(config('app.timezone'))->startOfMonth());
|
||||
|
@@ -89,7 +89,7 @@ class HomeController extends Controller
|
||||
$label = $request->get('label');
|
||||
$isCustomRange = false;
|
||||
|
||||
app('log')->debug('Received dateRange', ['start' => $stringStart, 'end' => $stringEnd, 'label' => $request->get('label')]);
|
||||
app('log')->debug('dateRange: Received dateRange', ['start' => $stringStart, 'end' => $stringEnd, 'label' => $request->get('label')]);
|
||||
// check if the label is "everything" or "Custom range" which will betray
|
||||
// a possible problem with the budgets.
|
||||
if ($label === (string)trans('firefly.everything') || $label === (string)trans('firefly.customRange')) {
|
||||
@@ -97,10 +97,10 @@ class HomeController extends Controller
|
||||
app('log')->debug('Range is now marked as "custom".');
|
||||
}
|
||||
|
||||
$diff = $start->diffInDays($end) + 1;
|
||||
$diff = $start->diffInDays($end, true) + 1;
|
||||
|
||||
if ($diff > 50) {
|
||||
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => $diff]));
|
||||
if ($diff > 366) {
|
||||
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => (int)$diff]));
|
||||
}
|
||||
|
||||
$request->session()->put('is_custom_range', $isCustomRange);
|
||||
|
@@ -113,7 +113,7 @@ class BoxController extends Controller
|
||||
$spentAmount = $spent[$currency->id]['sum'] ?? '0';
|
||||
app('log')->debug(sprintf('Spent for default currency for all budgets in this period: %s', $spentAmount));
|
||||
|
||||
$days = $today->between($start, $end) ? $today->diffInDays($start) + 1 : $end->diffInDays($start) + 1;
|
||||
$days = (int)($today->between($start, $end) ? $today->diffInDays($start, true) + 1 : $end->diffInDays($start, true) + 1);
|
||||
app('log')->debug(sprintf('Number of days left: %d', $days));
|
||||
$spentPerDay = bcdiv($spentAmount, (string)$days);
|
||||
app('log')->debug(sprintf('Available to spend per day: %s', $spentPerDay));
|
||||
@@ -130,7 +130,7 @@ class BoxController extends Controller
|
||||
$boxTitle = (string)trans('firefly.left_to_spend');
|
||||
$activeDaysLeft = $this->activeDaysLeft($start, $end); // see method description.
|
||||
$display = 1; // not overspent
|
||||
$leftPerDayAmount = bcdiv($leftToSpendAmount, (string)$activeDaysLeft);
|
||||
$leftPerDayAmount = 0 === (int) $activeDaysLeft ? $leftToSpendAmount : bcdiv($leftToSpendAmount, (string)$activeDaysLeft);
|
||||
app('log')->debug(sprintf('Left to spend per day is %s', $leftPerDayAmount));
|
||||
}
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ class IntroController extends Controller
|
||||
/**
|
||||
* Returns the introduction wizard for a page.
|
||||
*/
|
||||
public function getIntroSteps(string $route, string $specificPage = null): JsonResponse
|
||||
public function getIntroSteps(string $route, ?string $specificPage = null): JsonResponse
|
||||
{
|
||||
app('log')->debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage));
|
||||
$specificPage ??= '';
|
||||
@@ -91,7 +91,7 @@ class IntroController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function postEnable(string $route, string $specialPage = null): JsonResponse
|
||||
public function postEnable(string $route, ?string $specialPage = null): JsonResponse
|
||||
{
|
||||
$specialPage ??= '';
|
||||
$route = str_replace('.', '_', $route);
|
||||
@@ -111,7 +111,7 @@ class IntroController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function postFinished(string $route, string $specialPage = null): JsonResponse
|
||||
public function postFinished(string $route, ?string $specialPage = null): JsonResponse
|
||||
{
|
||||
$specialPage ??= '';
|
||||
$key = 'shown_demo_'.$route;
|
||||
|
@@ -67,7 +67,7 @@ class ReconcileController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function overview(Request $request, Account $account = null, Carbon $start = null, Carbon $end = null): JsonResponse
|
||||
public function overview(Request $request, ?Account $account = null, ?Carbon $start = null, ?Carbon $end = null): JsonResponse
|
||||
{
|
||||
$startBalance = $request->get('startBalance');
|
||||
$endBalance = $request->get('endBalance');
|
||||
@@ -177,7 +177,7 @@ class ReconcileController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function transactions(Account $account, Carbon $start = null, Carbon $end = null)
|
||||
public function transactions(Account $account, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
if (null === $start || null === $end) {
|
||||
throw new FireflyException('Invalid dates submitted.');
|
||||
|
@@ -76,7 +76,7 @@ class CreateController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function create(Request $request, RuleGroup $ruleGroup = null)
|
||||
public function create(Request $request, ?RuleGroup $ruleGroup = null)
|
||||
{
|
||||
$this->createDefaultRuleGroup();
|
||||
$preFilled = [
|
||||
|
@@ -215,7 +215,7 @@ class TagController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function show(Request $request, Tag $tag, Carbon $start = null, Carbon $end = null)
|
||||
public function show(Request $request, Tag $tag, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
// default values:
|
||||
$subTitleIcon = 'fa-tag';
|
||||
@@ -312,6 +312,9 @@ class TagController extends Controller
|
||||
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
|
||||
}
|
||||
if (count($this->attachmentsHelper->getErrors()->get('attachments')) > 0) {
|
||||
$request->session()->flash('error', $this->attachmentsHelper->getErrors()->get('attachments'));
|
||||
}
|
||||
$redirect = redirect($this->getPreviousUrl('tags.create.url'));
|
||||
if (1 === (int)$request->get('create_another')) {
|
||||
session()->put('tags.create.fromStore', true);
|
||||
@@ -347,6 +350,9 @@ class TagController extends Controller
|
||||
if (count($this->attachmentsHelper->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachmentsHelper->getMessages()->get('attachments'));
|
||||
}
|
||||
if (count($this->attachmentsHelper->getErrors()->get('attachments')) > 0) {
|
||||
$request->session()->flash('error', $this->attachmentsHelper->getErrors()->get('attachments'));
|
||||
}
|
||||
$redirect = redirect($this->getPreviousUrl('tags.edit.url'));
|
||||
if (1 === (int)$request->get('return_to_edit')) {
|
||||
session()->put('tags.edit.fromUpdate', true);
|
||||
|
@@ -69,7 +69,7 @@ class IndexController extends Controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function index(Request $request, string $objectType, Carbon $start = null, Carbon $end = null)
|
||||
public function index(Request $request, string $objectType, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
if ('transfers' === $objectType) {
|
||||
$objectType = 'transfer';
|
||||
|
45
app/Http/Controllers/UserGroup/CreateController.php
Normal file
45
app/Http/Controllers/UserGroup/CreateController.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/*
|
||||
* CreateController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\UserGroup;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
class CreateController extends Controller
|
||||
{
|
||||
/**
|
||||
* @return Application|Factory|\Illuminate\Contracts\Foundation\Application|View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$title = (string)trans('firefly.administrations_page_title');
|
||||
$subTitle = (string)trans('firefly.administrations_page_sub_title');
|
||||
$mainTitleIcon = 'fa-book';
|
||||
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
||||
|
||||
return view('administrations.create')->with(compact('title', 'subTitle', 'mainTitleIcon'));
|
||||
}
|
||||
}
|
47
app/Http/Controllers/UserGroup/IndexController.php
Normal file
47
app/Http/Controllers/UserGroup/IndexController.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/*
|
||||
* IndexController.php
|
||||
* Copyright (c) 2024 james@firefly-iii.org.
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\UserGroup;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show all administrations.
|
||||
*
|
||||
* @return Factory|View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$title = (string)trans('firefly.administrations_page_title');
|
||||
$subTitle = (string)trans('firefly.administrations_page_sub_title');
|
||||
$mainTitleIcon = 'fa-book';
|
||||
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
||||
|
||||
return view('administrations.index')->with(compact('title', 'subTitle', 'mainTitleIcon'));
|
||||
}
|
||||
}
|
@@ -34,10 +34,10 @@ class TrustProxies extends Middleware
|
||||
// After...
|
||||
protected $headers
|
||||
= Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
|
||||
/**
|
||||
* TrustProxies constructor.
|
||||
|
@@ -128,7 +128,7 @@ class WarnAboutBills implements ShouldQueue
|
||||
$today = clone $this->date;
|
||||
$carbon = clone $bill->{$field};
|
||||
|
||||
return $today->diffInDays($carbon, false);
|
||||
return (int) $today->diffInDays($carbon);
|
||||
}
|
||||
|
||||
private function sendWarning(Bill $bill, string $field): void
|
||||
|
@@ -122,13 +122,13 @@ class Account extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban'];
|
||||
|
||||
|
@@ -59,9 +59,9 @@ class AccountMeta extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = ['account_id', 'name', 'data'];
|
||||
|
||||
|
@@ -72,9 +72,9 @@ class AccountType extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = ['type'];
|
||||
|
||||
|
@@ -97,11 +97,11 @@ class Attachment extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'uploaded' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'uploaded' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'description', 'size', 'uploaded'];
|
||||
|
||||
|
@@ -80,13 +80,13 @@ class AvailableBudget extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'start_date' => 'date',
|
||||
'end_date' => 'date',
|
||||
'transaction_currency_id' => 'int',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'start_date' => 'date',
|
||||
'end_date' => 'date',
|
||||
'transaction_currency_id' => 'int',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date'];
|
||||
|
||||
|
@@ -114,36 +114,36 @@ class Bill extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'date' => 'date',
|
||||
'end_date' => 'date',
|
||||
'extension_date' => 'date',
|
||||
'skip' => 'int',
|
||||
'automatch' => 'boolean',
|
||||
'active' => 'boolean',
|
||||
'name_encrypted' => 'boolean',
|
||||
'match_encrypted' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'date' => 'date',
|
||||
'end_date' => 'date',
|
||||
'extension_date' => 'date',
|
||||
'skip' => 'int',
|
||||
'automatch' => 'boolean',
|
||||
'active' => 'boolean',
|
||||
'name_encrypted' => 'boolean',
|
||||
'match_encrypted' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable
|
||||
= [
|
||||
'name',
|
||||
'match',
|
||||
'amount_min',
|
||||
'user_id',
|
||||
'user_group_id',
|
||||
'amount_max',
|
||||
'date',
|
||||
'repeat_freq',
|
||||
'skip',
|
||||
'automatch',
|
||||
'active',
|
||||
'transaction_currency_id',
|
||||
'end_date',
|
||||
'extension_date',
|
||||
];
|
||||
'name',
|
||||
'match',
|
||||
'amount_min',
|
||||
'user_id',
|
||||
'user_group_id',
|
||||
'amount_max',
|
||||
'date',
|
||||
'repeat_freq',
|
||||
'skip',
|
||||
'automatch',
|
||||
'active',
|
||||
'transaction_currency_id',
|
||||
'end_date',
|
||||
'extension_date',
|
||||
];
|
||||
|
||||
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
|
||||
|
||||
|
@@ -97,12 +97,12 @@ class Budget extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'name', 'active', 'order', 'user_group_id'];
|
||||
|
||||
|
@@ -74,18 +74,18 @@ class BudgetLimit extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'start_date' => 'date',
|
||||
'end_date' => 'date',
|
||||
'auto_budget' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'start_date' => 'date',
|
||||
'end_date' => 'date',
|
||||
'auto_budget' => 'boolean',
|
||||
];
|
||||
protected $dispatchesEvents
|
||||
= [
|
||||
'created' => Created::class,
|
||||
'updated' => Updated::class,
|
||||
'deleted' => Deleted::class,
|
||||
];
|
||||
'created' => Created::class,
|
||||
'updated' => Updated::class,
|
||||
'deleted' => Deleted::class,
|
||||
];
|
||||
|
||||
protected $fillable = ['budget_id', 'start_date', 'end_date', 'amount', 'transaction_currency_id'];
|
||||
|
||||
|
@@ -86,11 +86,11 @@ class Category extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'name'];
|
||||
|
||||
|
@@ -62,10 +62,10 @@ class Configuration extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
|
||||
/** @var string The table to store the data in */
|
||||
protected $table = 'configuration';
|
||||
|
@@ -82,13 +82,13 @@ class CurrencyExchangeRate extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'int',
|
||||
'from_currency_id' => 'int',
|
||||
'to_currency_id' => 'int',
|
||||
'date' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'int',
|
||||
'from_currency_id' => 'int',
|
||||
'to_currency_id' => 'int',
|
||||
'date' => 'datetime',
|
||||
];
|
||||
protected $fillable = ['user_id', 'from_currency_id', 'to_currency_id', 'date', 'rate'];
|
||||
|
||||
public function fromCurrency(): BelongsTo
|
||||
|
@@ -70,9 +70,9 @@ class InvitedUser extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'expires' => 'datetime',
|
||||
'redeemed' => 'boolean',
|
||||
];
|
||||
'expires' => 'datetime',
|
||||
'redeemed' => 'boolean',
|
||||
];
|
||||
protected $fillable = ['user_id', 'email', 'invite_code', 'expires', 'redeemed'];
|
||||
|
||||
/**
|
||||
|
@@ -72,11 +72,11 @@ class LinkType extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'editable' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'editable' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['name', 'inward', 'outward', 'editable'];
|
||||
|
||||
|
@@ -74,13 +74,13 @@ class Location extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'zoomLevel' => 'int',
|
||||
'latitude' => 'float',
|
||||
'longitude' => 'float',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'zoomLevel' => 'int',
|
||||
'latitude' => 'float',
|
||||
'longitude' => 'float',
|
||||
];
|
||||
|
||||
protected $fillable = ['locatable_id', 'locatable_type', 'latitude', 'longitude', 'zoom_level'];
|
||||
|
||||
|
@@ -69,10 +69,10 @@ class Note extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = ['title', 'text', 'noteable_id', 'noteable_type'];
|
||||
|
||||
|
@@ -79,11 +79,11 @@ class ObjectGroup extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'user_id' => 'integer',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
protected $fillable = ['title', 'order', 'user_id', 'user_group_id'];
|
||||
|
||||
/**
|
||||
|
@@ -92,15 +92,15 @@ class PiggyBank extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => 'date',
|
||||
'order' => 'int',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => 'date',
|
||||
'order' => 'int',
|
||||
'active' => 'boolean',
|
||||
'encrypted' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate', 'active'];
|
||||
|
||||
|
@@ -63,10 +63,10 @@ class PiggyBankEvent extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'date' => 'date',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'date' => 'date',
|
||||
];
|
||||
|
||||
protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount'];
|
||||
|
||||
|
@@ -64,11 +64,11 @@ class PiggyBankRepetition extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => 'date',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => 'date',
|
||||
];
|
||||
|
||||
protected $fillable = ['piggy_bank_id', 'startdate', 'targetdate', 'currentamount'];
|
||||
|
||||
|
@@ -63,10 +63,10 @@ class Preference extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'data' => 'array',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'data' => 'array',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'data', 'name'];
|
||||
|
||||
|
@@ -104,19 +104,19 @@ class Recurrence extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'title' => 'string',
|
||||
'id' => 'int',
|
||||
'description' => 'string',
|
||||
'first_date' => 'date',
|
||||
'repeat_until' => 'date',
|
||||
'latest_date' => 'date',
|
||||
'repetitions' => 'int',
|
||||
'active' => 'bool',
|
||||
'apply_rules' => 'bool',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'title' => 'string',
|
||||
'id' => 'int',
|
||||
'description' => 'string',
|
||||
'first_date' => 'date',
|
||||
'repeat_until' => 'date',
|
||||
'latest_date' => 'date',
|
||||
'repetitions' => 'int',
|
||||
'active' => 'bool',
|
||||
'apply_rules' => 'bool',
|
||||
];
|
||||
|
||||
protected $fillable
|
||||
= ['user_id', 'transaction_type_id', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active'];
|
||||
|
@@ -67,12 +67,12 @@ class RecurrenceMeta extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'name' => 'string',
|
||||
'value' => 'string',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'name' => 'string',
|
||||
'value' => 'string',
|
||||
];
|
||||
|
||||
protected $fillable = ['recurrence_id', 'name', 'value'];
|
||||
|
||||
|
@@ -76,14 +76,14 @@ class RecurrenceRepetition extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'repetition_type' => 'string',
|
||||
'repetition_moment' => 'string',
|
||||
'repetition_skip' => 'int',
|
||||
'weekend' => 'int',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'repetition_type' => 'string',
|
||||
'repetition_moment' => 'string',
|
||||
'repetition_skip' => 'int',
|
||||
'weekend' => 'int',
|
||||
];
|
||||
|
||||
protected $fillable = ['recurrence_id', 'weekend', 'repetition_type', 'repetition_moment', 'repetition_skip'];
|
||||
|
||||
|
@@ -91,25 +91,25 @@ class RecurrenceTransaction extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'amount' => 'string',
|
||||
'foreign_amount' => 'string',
|
||||
'description' => 'string',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'amount' => 'string',
|
||||
'foreign_amount' => 'string',
|
||||
'description' => 'string',
|
||||
];
|
||||
|
||||
protected $fillable
|
||||
= [
|
||||
'recurrence_id',
|
||||
'transaction_currency_id',
|
||||
'foreign_currency_id',
|
||||
'source_id',
|
||||
'destination_id',
|
||||
'amount',
|
||||
'foreign_amount',
|
||||
'description',
|
||||
];
|
||||
'recurrence_id',
|
||||
'transaction_currency_id',
|
||||
'foreign_currency_id',
|
||||
'source_id',
|
||||
'destination_id',
|
||||
'amount',
|
||||
'foreign_amount',
|
||||
'description',
|
||||
];
|
||||
|
||||
/** @var string The table to store the data in */
|
||||
protected $table = 'recurrences_transactions';
|
||||
|
@@ -67,12 +67,12 @@ class RecurrenceTransactionMeta extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'name' => 'string',
|
||||
'value' => 'string',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'name' => 'string',
|
||||
'value' => 'string',
|
||||
];
|
||||
|
||||
protected $fillable = ['rt_id', 'name', 'value'];
|
||||
|
||||
|
@@ -62,9 +62,9 @@ class Role extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = ['name', 'display_name', 'description'];
|
||||
|
||||
|
@@ -95,15 +95,15 @@ class Rule extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'order' => 'int',
|
||||
'stop_processing' => 'boolean',
|
||||
'id' => 'int',
|
||||
'strict' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'order' => 'int',
|
||||
'stop_processing' => 'boolean',
|
||||
'id' => 'int',
|
||||
'strict' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['rule_group_id', 'order', 'active', 'title', 'description', 'user_id', 'strict'];
|
||||
|
||||
|
@@ -69,12 +69,12 @@ class RuleAction extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'order' => 'int',
|
||||
'stop_processing' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'order' => 'int',
|
||||
'stop_processing' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['rule_id', 'action_type', 'action_value', 'order', 'active', 'stop_processing'];
|
||||
|
||||
@@ -85,6 +85,10 @@ class RuleAction extends Model
|
||||
|
||||
return (string)$this->action_value;
|
||||
}
|
||||
if (true === config('firefly.feature_flags.expression_engine') && str_starts_with($this->action_value, '\=')) {
|
||||
// return literal string.
|
||||
return substr($this->action_value, 1);
|
||||
}
|
||||
$expr = new ActionExpression($this->action_value);
|
||||
|
||||
try {
|
||||
|
@@ -85,13 +85,13 @@ class RuleGroup extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'stop_processing' => 'boolean',
|
||||
'order' => 'int',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'stop_processing' => 'boolean',
|
||||
'order' => 'int',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'stop_processing', 'order', 'title', 'description', 'active'];
|
||||
|
||||
|
@@ -66,12 +66,12 @@ class RuleTrigger extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'order' => 'int',
|
||||
'stop_processing' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'active' => 'boolean',
|
||||
'order' => 'int',
|
||||
'stop_processing' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = ['rule_id', 'trigger_type', 'trigger_value', 'order', 'active', 'stop_processing'];
|
||||
|
||||
|
@@ -93,14 +93,14 @@ class Tag extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'date' => 'date',
|
||||
'zoomLevel' => 'int',
|
||||
'latitude' => 'float',
|
||||
'longitude' => 'float',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'date' => 'date',
|
||||
'zoomLevel' => 'int',
|
||||
'latitude' => 'float',
|
||||
'longitude' => 'float',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'description', 'tagMode'];
|
||||
|
||||
|
@@ -99,28 +99,28 @@ class Transaction extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'identifier' => 'int',
|
||||
'encrypted' => 'boolean', // model does not have these fields though
|
||||
'bill_name_encrypted' => 'boolean',
|
||||
'reconciled' => 'boolean',
|
||||
'date' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'identifier' => 'int',
|
||||
'encrypted' => 'boolean', // model does not have these fields though
|
||||
'bill_name_encrypted' => 'boolean',
|
||||
'reconciled' => 'boolean',
|
||||
'date' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable
|
||||
= [
|
||||
'account_id',
|
||||
'transaction_journal_id',
|
||||
'description',
|
||||
'amount',
|
||||
'identifier',
|
||||
'transaction_currency_id',
|
||||
'foreign_currency_id',
|
||||
'foreign_amount',
|
||||
'reconciled',
|
||||
];
|
||||
'account_id',
|
||||
'transaction_journal_id',
|
||||
'description',
|
||||
'amount',
|
||||
'identifier',
|
||||
'transaction_currency_id',
|
||||
'foreign_currency_id',
|
||||
'foreign_amount',
|
||||
'reconciled',
|
||||
];
|
||||
|
||||
protected $hidden = ['encrypted'];
|
||||
|
||||
|
@@ -89,12 +89,12 @@ class TransactionCurrency extends Model
|
||||
public ?bool $userGroupEnabled;
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'decimal_places' => 'int',
|
||||
'enabled' => 'bool',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'decimal_places' => 'int',
|
||||
'enabled' => 'bool',
|
||||
];
|
||||
|
||||
protected $fillable = ['name', 'code', 'symbol', 'decimal_places', 'enabled'];
|
||||
|
||||
|
@@ -78,13 +78,13 @@ class TransactionGroup extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'id' => 'integer',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'title' => 'string',
|
||||
'date' => 'datetime',
|
||||
];
|
||||
'id' => 'integer',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'title' => 'string',
|
||||
'date' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'title'];
|
||||
|
||||
|
@@ -138,32 +138,32 @@ class TransactionJournal extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'date' => 'datetime',
|
||||
'interest_date' => 'date',
|
||||
'book_date' => 'date',
|
||||
'process_date' => 'date',
|
||||
'order' => 'int',
|
||||
'tag_count' => 'int',
|
||||
'encrypted' => 'boolean',
|
||||
'completed' => 'boolean',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
'date' => 'datetime',
|
||||
'interest_date' => 'date',
|
||||
'book_date' => 'date',
|
||||
'process_date' => 'date',
|
||||
'order' => 'int',
|
||||
'tag_count' => 'int',
|
||||
'encrypted' => 'boolean',
|
||||
'completed' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable
|
||||
= [
|
||||
'user_id',
|
||||
'user_group_id',
|
||||
'transaction_type_id',
|
||||
'bill_id',
|
||||
'tag_count',
|
||||
'transaction_currency_id',
|
||||
'description',
|
||||
'completed',
|
||||
'order',
|
||||
'date',
|
||||
];
|
||||
'user_id',
|
||||
'user_group_id',
|
||||
'transaction_type_id',
|
||||
'bill_id',
|
||||
'tag_count',
|
||||
'transaction_currency_id',
|
||||
'description',
|
||||
'completed',
|
||||
'order',
|
||||
'date',
|
||||
];
|
||||
|
||||
protected $hidden = ['encrypted'];
|
||||
|
||||
|
@@ -71,9 +71,9 @@ class TransactionJournalLink extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
/** @var string The table to store the data in */
|
||||
protected $table = 'journal_links';
|
||||
|
@@ -69,10 +69,10 @@ class TransactionJournalMeta extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = ['transaction_journal_id', 'name', 'data', 'hash'];
|
||||
|
||||
|
@@ -73,10 +73,10 @@ class TransactionType extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime',
|
||||
];
|
||||
protected $fillable = ['type'];
|
||||
|
||||
/**
|
||||
|
@@ -93,11 +93,11 @@ class Webhook extends Model
|
||||
|
||||
protected $casts
|
||||
= [
|
||||
'active' => 'boolean',
|
||||
'trigger' => 'integer',
|
||||
'response' => 'integer',
|
||||
'delivery' => 'integer',
|
||||
];
|
||||
'active' => 'boolean',
|
||||
'trigger' => 'integer',
|
||||
'response' => 'integer',
|
||||
'delivery' => 'integer',
|
||||
];
|
||||
protected $fillable = ['active', 'trigger', 'response', 'delivery', 'user_id', 'user_group_id', 'url', 'title', 'secret'];
|
||||
|
||||
public static function getDeliveries(): array
|
||||
|
@@ -25,10 +25,9 @@ namespace FireflyIII\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Passport\Passport;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
|
||||
/**
|
||||
* Class AppServiceProvider
|
||||
@@ -65,9 +64,14 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
return '';
|
||||
});
|
||||
Blade::if('partialroute', function (string $route) {
|
||||
$name = \Route::getCurrentRoute()->getName() ?? '';
|
||||
if (str_contains($name, $route)) {
|
||||
Blade::if('partialroute', function (string $route, string $firstParam = '') {
|
||||
$name = Route::getCurrentRoute()->getName() ?? '';
|
||||
if ('' === $firstParam && str_contains($name, $route)) {
|
||||
return true;
|
||||
}
|
||||
$params = Route::getCurrentRoute()->parameters() ?? [];
|
||||
$objectType = $params['objectType'] ?? '';
|
||||
if ($objectType === $firstParam && str_contains($name, $route)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -80,7 +84,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
Passport::ignoreMigrations();
|
||||
Sanctum::ignoreMigrations();
|
||||
// Passport::ignoreMigrations();
|
||||
// Sanctum::ignoreMigrations();
|
||||
}
|
||||
}
|
||||
|
@@ -122,7 +122,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
||||
$budgetLimit->delete();
|
||||
}
|
||||
|
||||
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection
|
||||
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, ?Carbon $start = null, ?Carbon $end = null): Collection
|
||||
{
|
||||
return $this->getAllBudgetLimits($start, $end)->filter(
|
||||
static function (BudgetLimit $budgetLimit) use ($currency) {
|
||||
@@ -131,7 +131,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
||||
);
|
||||
}
|
||||
|
||||
public function getAllBudgetLimits(Carbon $start = null, Carbon $end = null): Collection
|
||||
public function getAllBudgetLimits(?Carbon $start = null, ?Carbon $end = null): Collection
|
||||
{
|
||||
// both are NULL:
|
||||
if (null === $start && null === $end) {
|
||||
@@ -198,7 +198,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
|
||||
;
|
||||
}
|
||||
|
||||
public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection
|
||||
public function getBudgetLimits(Budget $budget, ?Carbon $start = null, ?Carbon $end = null): Collection
|
||||
{
|
||||
if (null === $end && null === $start) {
|
||||
return $budget->budgetlimits()->with(['transactionCurrency'])->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*']);
|
||||
|
@@ -57,11 +57,11 @@ interface BudgetLimitRepositoryInterface
|
||||
/**
|
||||
* TODO this method is not multi currency aware.
|
||||
*/
|
||||
public function getAllBudgetLimits(Carbon $start = null, Carbon $end = null): Collection;
|
||||
public function getAllBudgetLimits(?Carbon $start = null, ?Carbon $end = null): Collection;
|
||||
|
||||
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection;
|
||||
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, ?Carbon $start = null, ?Carbon $end = null): Collection;
|
||||
|
||||
public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection;
|
||||
public function getBudgetLimits(Budget $budget, ?Carbon $start = null, ?Carbon $end = null): Collection;
|
||||
|
||||
public function setUser(null|Authenticatable|User $user): void;
|
||||
|
||||
|
@@ -132,7 +132,7 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
|
||||
continue;
|
||||
}
|
||||
$total = $limit->start_date->diffInDays($limit->end_date) + 1; // include the day itself.
|
||||
$total = $limit->start_date->diffInDays($limit->end_date, true) + 1; // include the day itself.
|
||||
$days = $this->daysInOverlap($limit, $start, $end);
|
||||
$amount = bcmul(bcdiv($limit->amount, (string)$total), (string)$days);
|
||||
$return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], $amount);
|
||||
@@ -183,21 +183,21 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
// |-----------|
|
||||
// |----------------|
|
||||
if ($start->gte($limit->start_date) && $end->lte($limit->end_date)) {
|
||||
return $start->diffInDays($end) + 1; // add one day
|
||||
return (int) $start->diffInDays($end, true) + 1; // add one day
|
||||
}
|
||||
// limit starts earlier and limit ends first:
|
||||
// |-----------|
|
||||
// |-------|
|
||||
if ($limit->start_date->lte($start) && $limit->end_date->lte($end)) {
|
||||
// return days in the range $start-$limit_end
|
||||
return $start->diffInDays($limit->end_date) + 1; // add one day, the day itself
|
||||
return (int) $start->diffInDays($limit->end_date, true) + 1; // add one day, the day itself
|
||||
}
|
||||
// limit starts later and limit ends earlier
|
||||
// |-----------|
|
||||
// |-------|
|
||||
if ($limit->start_date->gte($start) && $limit->end_date->gte($end)) {
|
||||
// return days in the range $limit_start - $end
|
||||
return $limit->start_date->diffInDays($end) + 1; // add one day, the day itself
|
||||
return (int) $limit->start_date->diffInDays($end, true) + 1; // add one day, the day itself
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -438,7 +438,7 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
*
|
||||
* @param null|int $budgetId |null
|
||||
*/
|
||||
public function find(int $budgetId = null): ?Budget
|
||||
public function find(?int $budgetId = null): ?Budget
|
||||
{
|
||||
return $this->user->budgets()->find($budgetId);
|
||||
}
|
||||
|
@@ -61,7 +61,7 @@ interface BudgetRepositoryInterface
|
||||
|
||||
public function destroyAutoBudget(Budget $budget): void;
|
||||
|
||||
public function find(int $budgetId = null): ?Budget;
|
||||
public function find(?int $budgetId = null): ?Budget;
|
||||
|
||||
public function findBudget(?int $budgetId, ?string $budgetName): ?Budget;
|
||||
|
||||
|
@@ -51,7 +51,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
$total = '0';
|
||||
$count = 0;
|
||||
foreach ($budget->budgetlimits as $limit) {
|
||||
$diff = $limit->start_date->diffInDays($limit->end_date);
|
||||
$diff = (int) $limit->start_date->diffInDays($limit->end_date, true);
|
||||
$diff = 0 === $diff ? 1 : $diff;
|
||||
$amount = $limit->amount;
|
||||
$perDay = bcdiv($amount, (string)$diff);
|
||||
|
@@ -44,7 +44,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
|
||||
return $linkType->transactionJournalLinks()->count();
|
||||
}
|
||||
|
||||
public function destroy(LinkType $linkType, LinkType $moveTo = null): bool
|
||||
public function destroy(LinkType $linkType, ?LinkType $moveTo = null): bool
|
||||
{
|
||||
if (null !== $moveTo) {
|
||||
TransactionJournalLink::where('link_type_id', $linkType->id)->update(['link_type_id' => $moveTo->id]);
|
||||
@@ -113,7 +113,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
|
||||
/**
|
||||
* Returns all the journal links (of a specific type).
|
||||
*/
|
||||
public function getJournalLinks(LinkType $linkType = null): Collection
|
||||
public function getJournalLinks(?LinkType $linkType = null): Collection
|
||||
{
|
||||
$query = TransactionJournalLink::with(['source', 'destination'])
|
||||
->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
|
||||
@@ -225,7 +225,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
|
||||
return LinkType::find($linkTypeId);
|
||||
}
|
||||
|
||||
public function findByName(string $name = null): ?LinkType
|
||||
public function findByName(?string $name = null): ?LinkType
|
||||
{
|
||||
if (null === $name) {
|
||||
return null;
|
||||
|
@@ -37,7 +37,7 @@ interface LinkTypeRepositoryInterface
|
||||
{
|
||||
public function countJournals(LinkType $linkType): int;
|
||||
|
||||
public function destroy(LinkType $linkType, LinkType $moveTo = null): bool;
|
||||
public function destroy(LinkType $linkType, ?LinkType $moveTo = null): bool;
|
||||
|
||||
public function destroyLink(TransactionJournalLink $link): bool;
|
||||
|
||||
@@ -46,7 +46,7 @@ interface LinkTypeRepositoryInterface
|
||||
/**
|
||||
* Find link type by name.
|
||||
*/
|
||||
public function findByName(string $name = null): ?LinkType;
|
||||
public function findByName(?string $name = null): ?LinkType;
|
||||
|
||||
/**
|
||||
* Check if link exists between journals.
|
||||
@@ -65,7 +65,7 @@ interface LinkTypeRepositoryInterface
|
||||
*/
|
||||
public function getJournalIds(LinkType $linkType): array;
|
||||
|
||||
public function getJournalLinks(LinkType $linkType = null): Collection;
|
||||
public function getJournalLinks(?LinkType $linkType = null): Collection;
|
||||
|
||||
/**
|
||||
* Return list of existing connections.
|
||||
|
@@ -301,7 +301,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
if (null !== $piggyBank->targetdate && $repetition->currentamount < $piggyBank->targetamount) {
|
||||
$now = today(config('app.timezone'));
|
||||
$startDate = null !== $piggyBank->startdate && $piggyBank->startdate->gte($now) ? $piggyBank->startdate : $now;
|
||||
$diffInMonths = $startDate->diffInMonths($piggyBank->targetdate, false);
|
||||
$diffInMonths = (int) $startDate->diffInMonths($piggyBank->targetdate);
|
||||
$remainingAmount = bcsub($piggyBank->targetamount, $repetition->currentamount);
|
||||
|
||||
// more than 1 month to go and still need money to save:
|
||||
|
@@ -202,7 +202,7 @@ class RecurringRepository implements RecurringRepositoryInterface
|
||||
/**
|
||||
* Returns the journals created for this recurrence, possibly limited by time.
|
||||
*/
|
||||
public function getJournalCount(Recurrence $recurrence, Carbon $start = null, Carbon $end = null): int
|
||||
public function getJournalCount(Recurrence $recurrence, ?Carbon $start = null, ?Carbon $end = null): int
|
||||
{
|
||||
$query = TransactionJournal::leftJoin('journal_meta', 'journal_meta.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->where('transaction_journals.user_id', $recurrence->user_id)
|
||||
@@ -476,7 +476,7 @@ class RecurringRepository implements RecurringRepositoryInterface
|
||||
if (false === $repDate) {
|
||||
$repDate = clone $today;
|
||||
}
|
||||
$diffInYears = $today->diffInYears($repDate);
|
||||
$diffInYears = (int) $today->diffInYears($repDate, true);
|
||||
$repDate->addYears($diffInYears); // technically not necessary.
|
||||
$string = $repDate->isoFormat((string)trans('config.month_and_day_no_year_js'));
|
||||
|
||||
|
@@ -83,7 +83,7 @@ interface RecurringRepositoryInterface
|
||||
/**
|
||||
* Returns the count of journals created for this recurrence, possibly limited by time.
|
||||
*/
|
||||
public function getJournalCount(Recurrence $recurrence, Carbon $start = null, Carbon $end = null): int;
|
||||
public function getJournalCount(Recurrence $recurrence, ?Carbon $start = null, ?Carbon $end = null): int;
|
||||
|
||||
/**
|
||||
* Get journal ID's for journals created by this recurring transaction.
|
||||
|
@@ -98,6 +98,7 @@ class UserGroupRepository implements UserGroupRepositoryInterface
|
||||
public function get(): Collection
|
||||
{
|
||||
$collection = new Collection();
|
||||
$set = [];
|
||||
$memberships = $this->user->groupMemberships()->get();
|
||||
|
||||
/** @var GroupMembership $membership */
|
||||
@@ -105,9 +106,14 @@ class UserGroupRepository implements UserGroupRepositoryInterface
|
||||
/** @var null|UserGroup $group */
|
||||
$group = $membership->userGroup()->first();
|
||||
if (null !== $group) {
|
||||
$collection->push($group);
|
||||
$groupId = (int)$group->id;
|
||||
if (in_array($groupId, $set, true)) {
|
||||
continue;
|
||||
}
|
||||
$set[$groupId] = $group;
|
||||
}
|
||||
}
|
||||
$collection->push(...$set);
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
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;
|
||||
@@ -239,15 +240,19 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
public function getAccountsByType(array $types, ?array $sort = []): Collection
|
||||
{
|
||||
$sortable = ['name', 'active']; // TODO yes this is a duplicate array.
|
||||
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
|
||||
$query = $this->userGroup->accounts();
|
||||
$sortable = ['name', 'active']; // TODO yes this is a duplicate array.
|
||||
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
|
||||
$query = $this->userGroup->accounts();
|
||||
if (0 !== count($types)) {
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (false === $hasActiveColumn) {
|
||||
$query->orderBy('accounts.active', 'DESC');
|
||||
}
|
||||
foreach ($sort as $column => $direction) {
|
||||
if (in_array($column, $sortable, true)) {
|
||||
$query->orderBy(sprintf('accounts.%s', $column), $direction);
|
||||
@@ -257,9 +262,9 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
if (0 === count($sort)) {
|
||||
if (0 !== count($res)) {
|
||||
$query->orderBy('accounts.order', 'ASC');
|
||||
$query->orderBy('accounts.active', 'DESC');
|
||||
}
|
||||
$query->orderBy('accounts.active', 'DESC');
|
||||
$query->orderBy('accounts.order', 'ASC');
|
||||
$query->orderBy('accounts.name', 'ASC');
|
||||
}
|
||||
|
||||
@@ -291,4 +296,13 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
return $dbQuery->take($limit)->get(['accounts.*']);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function update(Account $account, array $data): Account
|
||||
{
|
||||
/** @var AccountUpdateService $service */
|
||||
$service = app(AccountUpdateService::class);
|
||||
|
||||
return $service->update($account, $data);
|
||||
}
|
||||
}
|
||||
|
@@ -73,4 +73,6 @@ interface AccountRepositoryInterface
|
||||
public function setUser(User $user): void;
|
||||
|
||||
public function setUserGroup(UserGroup $userGroup): void;
|
||||
|
||||
public function update(Account $account, array $data): Account;
|
||||
}
|
||||
|
@@ -40,7 +40,7 @@ class Amount
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function formatAnything(TransactionCurrency $format, string $amount, bool $coloured = null): string
|
||||
public function formatAnything(TransactionCurrency $format, string $amount, ?bool $coloured = null): string
|
||||
{
|
||||
return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ class Amount
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.MissingImport)
|
||||
*/
|
||||
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, bool $coloured = null): string
|
||||
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string
|
||||
{
|
||||
$locale = app('steam')->getLocale();
|
||||
$rounded = app('steam')->bcround($amount, $decimalPlaces);
|
||||
|
@@ -120,4 +120,12 @@ class RemoteUserProvider implements UserProvider
|
||||
|
||||
throw new FireflyException(sprintf('C) Did not implement %s', __METHOD__));
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false): void
|
||||
{
|
||||
app('log')->debug(sprintf('Now at %s', __METHOD__));
|
||||
|
||||
throw new FireflyException(sprintf('Did not implement %s', __METHOD__));
|
||||
}
|
||||
}
|
||||
|
@@ -34,6 +34,10 @@ class EitherConfigKey
|
||||
{
|
||||
public static array $static
|
||||
= [
|
||||
// currency conversion
|
||||
'cer.enabled',
|
||||
|
||||
// firefly iii settings
|
||||
'firefly.version',
|
||||
'firefly.api_version',
|
||||
'firefly.default_location',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user